diff --git a/src/App.tsx b/src/App.tsx index d96b7bac7..a03c07915 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react"; -import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw"; +import { RefreshCw } from "lucide-react"; import "./styles/base.css"; import "./styles/ds-tokens.css"; import "./styles/ds-modal.css"; @@ -2166,7 +2166,7 @@ function MainApp() { isLoadingLocalUsage, localUsageError, onRefreshLocalUsage: () => { - refreshLocalUsage()?.catch(() => {}); + refreshLocalUsage()?.catch((err) => console.debug("refreshLocalUsage failed", err)); }, usageMetric, onUsageMetricChange: setUsageMetric, diff --git a/src/features/app/components/LaunchScriptButton.tsx b/src/features/app/components/LaunchScriptButton.tsx index 8e2d82f2d..8c97a70e1 100644 --- a/src/features/app/components/LaunchScriptButton.tsx +++ b/src/features/app/components/LaunchScriptButton.tsx @@ -1,4 +1,4 @@ -import Play from "lucide-react/dist/esm/icons/play"; +import { Play } from "lucide-react"; import type { LaunchScriptIconId } from "../../../types"; import { PopoverSurface } from "../../design-system/components/popover/PopoverPrimitives"; import { useMenuController } from "../hooks/useMenuController"; diff --git a/src/features/app/components/MainHeader.tsx b/src/features/app/components/MainHeader.tsx index f8bce2506..80a8f90cd 100644 --- a/src/features/app/components/MainHeader.tsx +++ b/src/features/app/components/MainHeader.tsx @@ -1,7 +1,5 @@ import { useEffect, useMemo, useRef, useState } from "react"; -import Check from "lucide-react/dist/esm/icons/check"; -import Copy from "lucide-react/dist/esm/icons/copy"; -import Terminal from "lucide-react/dist/esm/icons/terminal"; +import { Check, Copy, Terminal } from "lucide-react"; import { revealItemInDir } from "@tauri-apps/plugin-opener"; import type { BranchInfo, OpenAppTarget, WorkspaceInfo } from "../../../types"; import type { ReactNode } from "react"; diff --git a/src/features/app/components/MainHeaderActions.tsx b/src/features/app/components/MainHeaderActions.tsx index a115c2a25..3a7e842f2 100644 --- a/src/features/app/components/MainHeaderActions.tsx +++ b/src/features/app/components/MainHeaderActions.tsx @@ -1,6 +1,5 @@ import { memo } from "react"; -import AlignLeft from "lucide-react/dist/esm/icons/align-left"; -import Columns2 from "lucide-react/dist/esm/icons/columns-2"; +import { AlignLeft, Columns2 } from "lucide-react"; import type { SidebarToggleProps } from "../../layout/components/SidebarToggleControls"; import { RightPanelCollapseButton, diff --git a/src/features/app/components/OpenAppMenu.tsx b/src/features/app/components/OpenAppMenu.tsx index fd53d18a9..9c9f5ffd5 100644 --- a/src/features/app/components/OpenAppMenu.tsx +++ b/src/features/app/components/OpenAppMenu.tsx @@ -1,5 +1,5 @@ import { useMemo } from "react"; -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; +import { ChevronDown } from "lucide-react"; import { revealItemInDir } from "@tauri-apps/plugin-opener"; import * as Sentry from "@sentry/react"; import { openWorkspaceIn } from "../../../services/tauri"; diff --git a/src/features/app/components/Sidebar.tsx b/src/features/app/components/Sidebar.tsx index 53ce98a06..23a71c085 100644 --- a/src/features/app/components/Sidebar.tsx +++ b/src/features/app/components/Sidebar.tsx @@ -10,11 +10,7 @@ import type { import { createPortal } from "react-dom"; import { memo, useCallback, useEffect, useMemo, useState } from "react"; import type { MouseEvent, RefObject } from "react"; -import { FolderOpen } from "lucide-react"; -import Copy from "lucide-react/dist/esm/icons/copy"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import Plus from "lucide-react/dist/esm/icons/plus"; -import X from "lucide-react/dist/esm/icons/x"; +import { Copy, FolderOpen, GitBranch, Plus, X } from "lucide-react"; import { PopoverMenuItem, PopoverSurface, diff --git a/src/features/app/components/SidebarCornerActions.tsx b/src/features/app/components/SidebarCornerActions.tsx index df5a2fc38..91c132090 100644 --- a/src/features/app/components/SidebarCornerActions.tsx +++ b/src/features/app/components/SidebarCornerActions.tsx @@ -1,7 +1,4 @@ -import ScrollText from "lucide-react/dist/esm/icons/scroll-text"; -import Settings from "lucide-react/dist/esm/icons/settings"; -import User from "lucide-react/dist/esm/icons/user"; -import X from "lucide-react/dist/esm/icons/x"; +import { ScrollText, Settings, User, X } from "lucide-react"; import { useEffect } from "react"; import { MenuTrigger, diff --git a/src/features/app/components/SidebarHeader.tsx b/src/features/app/components/SidebarHeader.tsx index b3c2a5752..ad4c275d8 100644 --- a/src/features/app/components/SidebarHeader.tsx +++ b/src/features/app/components/SidebarHeader.tsx @@ -1,12 +1,4 @@ -import ArrowDownUp from "lucide-react/dist/esm/icons/arrow-down-up"; -import BetweenHorizontalStart from "lucide-react/dist/esm/icons/between-horizontal-start"; -import Calendar from "lucide-react/dist/esm/icons/calendar"; -import FolderPlus from "lucide-react/dist/esm/icons/folder-plus"; -import FolderTree from "lucide-react/dist/esm/icons/folder-tree"; -import ListFilter from "lucide-react/dist/esm/icons/list-filter"; -import ListTree from "lucide-react/dist/esm/icons/list-tree"; -import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw"; -import Search from "lucide-react/dist/esm/icons/search"; +import { ArrowDownUp, BetweenHorizontalStart, Calendar, FolderPlus, FolderTree, ListFilter, ListTree, RefreshCw, Search } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; import type { ThreadListOrganizeMode, ThreadListSortKey } from "../../../types"; import { diff --git a/src/features/app/components/TabBar.tsx b/src/features/app/components/TabBar.tsx index 66c199736..3ed2659e1 100644 --- a/src/features/app/components/TabBar.tsx +++ b/src/features/app/components/TabBar.tsx @@ -1,9 +1,5 @@ import type { ReactNode } from "react"; -import FolderKanban from "lucide-react/dist/esm/icons/folder-kanban"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import House from "lucide-react/dist/esm/icons/house"; -import MessagesSquare from "lucide-react/dist/esm/icons/messages-square"; -import TerminalSquare from "lucide-react/dist/esm/icons/terminal-square"; +import { FolderKanban, GitBranch, House, MessagesSquare, TerminalSquare } from "lucide-react"; type TabKey = "home" | "projects" | "codex" | "git" | "log"; diff --git a/src/features/app/components/TabletNav.tsx b/src/features/app/components/TabletNav.tsx index 625d51b37..6b60c443f 100644 --- a/src/features/app/components/TabletNav.tsx +++ b/src/features/app/components/TabletNav.tsx @@ -1,7 +1,5 @@ import type { ReactNode } from "react"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import MessagesSquare from "lucide-react/dist/esm/icons/messages-square"; -import TerminalSquare from "lucide-react/dist/esm/icons/terminal-square"; +import { GitBranch, MessagesSquare, TerminalSquare } from "lucide-react"; type TabletNavTab = "codex" | "git" | "log"; diff --git a/src/features/app/components/WorktreeSection.tsx b/src/features/app/components/WorktreeSection.tsx index e96024966..cc35008ea 100644 --- a/src/features/app/components/WorktreeSection.tsx +++ b/src/features/app/components/WorktreeSection.tsx @@ -1,4 +1,4 @@ -import Layers from "lucide-react/dist/esm/icons/layers"; +import { Layers } from "lucide-react"; import type { MouseEvent, ReactNode } from "react"; import type { ThreadSummary, WorkspaceInfo } from "../../../types"; diff --git a/src/features/app/utils/launchScriptIcons.ts b/src/features/app/utils/launchScriptIcons.ts index 62b5c60fc..27e7a36be 100644 --- a/src/features/app/utils/launchScriptIcons.ts +++ b/src/features/app/utils/launchScriptIcons.ts @@ -1,20 +1,7 @@ import type { LucideIcon } from "lucide-react"; import type { LaunchScriptIconId } from "../../../types"; export type { LaunchScriptIconId } from "../../../types"; -import Play from "lucide-react/dist/esm/icons/play"; -import Hammer from "lucide-react/dist/esm/icons/hammer"; -import Bug from "lucide-react/dist/esm/icons/bug"; -import Wrench from "lucide-react/dist/esm/icons/wrench"; -import TerminalSquare from "lucide-react/dist/esm/icons/terminal-square"; -import Code2 from "lucide-react/dist/esm/icons/code-2"; -import Server from "lucide-react/dist/esm/icons/server"; -import Database from "lucide-react/dist/esm/icons/database"; -import Package from "lucide-react/dist/esm/icons/package"; -import TestTube2 from "lucide-react/dist/esm/icons/test-tube-2"; -import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import Settings from "lucide-react/dist/esm/icons/settings"; -import Search from "lucide-react/dist/esm/icons/search"; +import { Bug, Code2, Database, GitBranch, Hammer, Package, Play, RefreshCw, Search, Server, Settings, TerminalSquare, TestTube2, Wrench } from "lucide-react"; export const DEFAULT_LAUNCH_SCRIPT_ICON: LaunchScriptIconId = "play"; diff --git a/src/features/collaboration/hooks/useCollaborationModes.ts b/src/features/collaboration/hooks/useCollaborationModes.ts index bb241e1a2..7306d69bb 100644 --- a/src/features/collaboration/hooks/useCollaborationModes.ts +++ b/src/features/collaboration/hooks/useCollaborationModes.ts @@ -50,13 +50,14 @@ export function useCollaborationModes({ const workspaceId = activeWorkspace?.id ?? null; const isConnected = Boolean(activeWorkspace?.connected); - const extractModeList = useCallback((response: any): any[] => { + const extractModeList = useCallback((response: unknown): unknown[] => { + const res = response as Record | null | undefined; const candidates = [ - response?.result?.data, - response?.result?.modes, - response?.result, - response?.data, - response?.modes, + (res?.result as Record | undefined)?.data, + (res?.result as Record | undefined)?.modes, + res?.result, + res?.data, + res?.modes, response, ]; for (const candidate of candidates) { @@ -64,12 +65,14 @@ export function useCollaborationModes({ return candidate; } if (candidate && typeof candidate === "object") { - const nested = (candidate as any).data ?? (candidate as any).modes; + const rec = candidate as Record; + const nested = rec.data ?? rec.modes; if (Array.isArray(nested)) { return nested; } if (nested && typeof nested === "object") { - const deep = (nested as any).data ?? (nested as any).modes; + const nestedRec = nested as Record; + const deep = nestedRec.data ?? nestedRec.modes; if (Array.isArray(deep)) { return deep; } @@ -110,25 +113,26 @@ export function useCollaborationModes({ }); const rawData = extractModeList(response); const data: CollaborationModeOption[] = rawData - .map((item: any) => { + .map((item: unknown) => { if (!item || typeof item !== "object") { return null; } - const modeId = String(item.mode ?? item.name ?? "").trim(); + const rec = item as Record; + const modeId = String(rec.mode ?? rec.name ?? "").trim(); if (!modeId) { return null; } const settings = - item.settings && typeof item.settings === "object" - ? item.settings + rec.settings && typeof rec.settings === "object" + ? (rec.settings as Record) : { - model: item.model ?? null, + model: rec.model ?? null, reasoning_effort: - item.reasoning_effort ?? item.reasoningEffort ?? null, + rec.reasoning_effort ?? rec.reasoningEffort ?? null, developer_instructions: - item.developer_instructions ?? - item.developerInstructions ?? + rec.developer_instructions ?? + rec.developerInstructions ?? null, }; @@ -137,10 +141,10 @@ export function useCollaborationModes({ const developerInstructions = settings.developer_instructions ?? null; const labelSource = - typeof item.label === "string" && item.label.trim() - ? item.label - : typeof item.name === "string" && item.name.trim() - ? item.name + typeof rec.label === "string" && rec.label.trim() + ? rec.label + : typeof rec.name === "string" && rec.name.trim() + ? rec.name : modeId; const option: CollaborationModeOption = { @@ -152,7 +156,7 @@ export function useCollaborationModes({ developerInstructions: developerInstructions ? String(developerInstructions) : null, - value: item as Record, + value: rec as Record, }; return option; }) diff --git a/src/features/composer/components/ComposerAttachments.tsx b/src/features/composer/components/ComposerAttachments.tsx index f2934f57e..a9da9fee6 100644 --- a/src/features/composer/components/ComposerAttachments.tsx +++ b/src/features/composer/components/ComposerAttachments.tsx @@ -1,6 +1,5 @@ import { convertFileSrc } from "@tauri-apps/api/core"; -import Image from "lucide-react/dist/esm/icons/image"; -import X from "lucide-react/dist/esm/icons/x"; +import { Image, X } from "lucide-react"; type ComposerAttachmentsProps = { attachments: string[]; diff --git a/src/features/composer/components/ComposerInput.tsx b/src/features/composer/components/ComposerInput.tsx index a07d023c3..4eb0e37f1 100644 --- a/src/features/composer/components/ComposerInput.tsx +++ b/src/features/composer/components/ComposerInput.tsx @@ -7,22 +7,7 @@ import type { SyntheticEvent, } from "react"; import type { AutocompleteItem } from "../hooks/useComposerAutocomplete"; -import ImagePlus from "lucide-react/dist/esm/icons/image-plus"; -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronUp from "lucide-react/dist/esm/icons/chevron-up"; -import Mic from "lucide-react/dist/esm/icons/mic"; -import Square from "lucide-react/dist/esm/icons/square"; -import X from "lucide-react/dist/esm/icons/x"; -import Brain from "lucide-react/dist/esm/icons/brain"; -import GitFork from "lucide-react/dist/esm/icons/git-fork"; -import PlusCircle from "lucide-react/dist/esm/icons/plus-circle"; -import Plus from "lucide-react/dist/esm/icons/plus"; -import Info from "lucide-react/dist/esm/icons/info"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; -import ScrollText from "lucide-react/dist/esm/icons/scroll-text"; -import Wrench from "lucide-react/dist/esm/icons/wrench"; -import FileText from "lucide-react/dist/esm/icons/file-text"; -import Plug from "lucide-react/dist/esm/icons/plug"; +import { Brain, ChevronDown, ChevronUp, FileText, GitFork, ImagePlus, Info, Mic, Plug, Plus, PlusCircle, RotateCcw, ScrollText, Square, Wrench, X } from "lucide-react"; import { useComposerImageDrop } from "../hooks/useComposerImageDrop"; import { PopoverMenuItem, diff --git a/src/features/design-system/components/panel/PanelPrimitives.tsx b/src/features/design-system/components/panel/PanelPrimitives.tsx index 29706bc62..850806b99 100644 --- a/src/features/design-system/components/panel/PanelPrimitives.tsx +++ b/src/features/design-system/components/panel/PanelPrimitives.tsx @@ -1,5 +1,5 @@ import type { ComponentPropsWithoutRef, ReactNode } from "react"; -import ChevronRight from "lucide-react/dist/esm/icons/chevron-right"; +import { ChevronRight } from "lucide-react"; import { joinClassNames } from "../classNames"; type PanelFrameProps = { diff --git a/src/features/files/components/FilePreviewPopover.tsx b/src/features/files/components/FilePreviewPopover.tsx index d05784410..0acd33341 100644 --- a/src/features/files/components/FilePreviewPopover.tsx +++ b/src/features/files/components/FilePreviewPopover.tsx @@ -1,6 +1,6 @@ import { useMemo } from "react"; import type { CSSProperties, MouseEvent } from "react"; -import X from "lucide-react/dist/esm/icons/x"; +import { X } from "lucide-react"; import { highlightLine, languageFromPath } from "../../../utils/syntax"; import { OpenAppMenu } from "../../app/components/OpenAppMenu"; import { PopoverSurface } from "../../design-system/components/popover/PopoverPrimitives"; diff --git a/src/features/files/components/FileTreePanel.tsx b/src/features/files/components/FileTreePanel.tsx index 8040365f5..4ab4f655b 100644 --- a/src/features/files/components/FileTreePanel.tsx +++ b/src/features/files/components/FileTreePanel.tsx @@ -7,12 +7,7 @@ import { Menu, MenuItem } from "@tauri-apps/api/menu"; import { LogicalPosition } from "@tauri-apps/api/dpi"; import { getCurrentWindow } from "@tauri-apps/api/window"; import { revealItemInDir } from "@tauri-apps/plugin-opener"; -import Plus from "lucide-react/dist/esm/icons/plus"; -import ChevronsUpDown from "lucide-react/dist/esm/icons/chevrons-up-down"; -import File from "lucide-react/dist/esm/icons/file"; -import Folder from "lucide-react/dist/esm/icons/folder"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import Search from "lucide-react/dist/esm/icons/search"; +import { ChevronsUpDown, File, Folder, GitBranch, Plus, Search } from "lucide-react"; import type { PanelTabId } from "../../layout/components/PanelTabs"; import { PanelShell } from "../../layout/components/PanelShell"; import { diff --git a/src/features/git/components/GitDiffPanel.tsx b/src/features/git/components/GitDiffPanel.tsx index 523450546..14fcf448b 100644 --- a/src/features/git/components/GitDiffPanel.tsx +++ b/src/features/git/components/GitDiffPanel.tsx @@ -5,10 +5,7 @@ import { LogicalPosition } from "@tauri-apps/api/dpi"; import { getCurrentWindow } from "@tauri-apps/api/window"; import { ask } from "@tauri-apps/plugin-dialog"; import { openUrl } from "@tauri-apps/plugin-opener"; -import FileText from "lucide-react/dist/esm/icons/file-text"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import ScrollText from "lucide-react/dist/esm/icons/scroll-text"; -import Search from "lucide-react/dist/esm/icons/search"; +import { FileText, GitBranch, ScrollText, Search } from "lucide-react"; import { useCallback, useEffect, useMemo, useState } from "react"; import type { PanelTabId } from "../../layout/components/PanelTabs"; import { PanelShell } from "../../layout/components/PanelShell"; diff --git a/src/features/git/components/GitDiffPanelModeContent.tsx b/src/features/git/components/GitDiffPanelModeContent.tsx index e9f229f90..5e8e5eea2 100644 --- a/src/features/git/components/GitDiffPanelModeContent.tsx +++ b/src/features/git/components/GitDiffPanelModeContent.tsx @@ -2,13 +2,7 @@ import type { GitHubIssue, GitHubPullRequest, GitLogEntry } from "../../../types import type { MouseEvent as ReactMouseEvent } from "react"; import { useCallback, useEffect, useState } from "react"; import { openUrl } from "@tauri-apps/plugin-opener"; -import ArrowLeftRight from "lucide-react/dist/esm/icons/arrow-left-right"; -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronRight from "lucide-react/dist/esm/icons/chevron-right"; -import Download from "lucide-react/dist/esm/icons/download"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; -import RotateCw from "lucide-react/dist/esm/icons/rotate-cw"; -import Upload from "lucide-react/dist/esm/icons/upload"; +import { ArrowLeftRight, ChevronDown, ChevronRight, Download, RotateCcw, RotateCw, Upload } from "lucide-react"; import { formatRelativeTime } from "../../../utils/time"; import { MagicSparkleIcon, diff --git a/src/features/git/components/GitDiffPanelShared.tsx b/src/features/git/components/GitDiffPanelShared.tsx index 03b32b871..a3ba8f2b9 100644 --- a/src/features/git/components/GitDiffPanelShared.tsx +++ b/src/features/git/components/GitDiffPanelShared.tsx @@ -1,11 +1,6 @@ import type { GitLogEntry } from "../../../types"; import type { MouseEvent as ReactMouseEvent } from "react"; -import Check from "lucide-react/dist/esm/icons/check"; -import Minus from "lucide-react/dist/esm/icons/minus"; -import Plus from "lucide-react/dist/esm/icons/plus"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; -import Upload from "lucide-react/dist/esm/icons/upload"; -import X from "lucide-react/dist/esm/icons/x"; +import { Check, Minus, Plus, RotateCcw, Upload, X } from "lucide-react"; import { MagicSparkleIcon } from "../../shared/components/MagicSparkleIcon"; import { formatRelativeTime } from "../../../utils/time"; import { diff --git a/src/features/git/components/GitDiffViewer.tsx b/src/features/git/components/GitDiffViewer.tsx index ff152e58c..b58aef71c 100644 --- a/src/features/git/components/GitDiffViewer.tsx +++ b/src/features/git/components/GitDiffViewer.tsx @@ -3,8 +3,7 @@ import { ask } from "@tauri-apps/plugin-dialog"; import { useVirtualizer } from "@tanstack/react-virtual"; import type { SelectedLineRange } from "@pierre/diffs"; import { WorkerPoolContextProvider } from "@pierre/diffs/react"; -import GitCommitHorizontal from "lucide-react/dist/esm/icons/git-commit-horizontal"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; +import { GitCommitHorizontal, RotateCcw } from "lucide-react"; import type { ParsedDiffLine } from "../../../utils/diff"; import { workerFactory } from "../../../utils/diffsWorker"; import type { diff --git a/src/features/git/components/GitDiffViewerDiffCard.tsx b/src/features/git/components/GitDiffViewerDiffCard.tsx index 0ccabf349..45a947b6d 100644 --- a/src/features/git/components/GitDiffViewerDiffCard.tsx +++ b/src/features/git/components/GitDiffViewerDiffCard.tsx @@ -6,7 +6,7 @@ import { type SelectedLineRange, } from "@pierre/diffs"; import { FileDiff } from "@pierre/diffs/react"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; +import { RotateCcw } from "lucide-react"; import type { PullRequestReviewAction, PullRequestReviewIntent, diff --git a/src/features/git/components/ImageDiffCard.tsx b/src/features/git/components/ImageDiffCard.tsx index da150036d..12c81e320 100644 --- a/src/features/git/components/ImageDiffCard.tsx +++ b/src/features/git/components/ImageDiffCard.tsx @@ -1,6 +1,5 @@ import { memo, useMemo } from "react"; -import ImageOff from "lucide-react/dist/esm/icons/image-off"; -import RotateCcw from "lucide-react/dist/esm/icons/rotate-ccw"; +import { ImageOff, RotateCcw } from "lucide-react"; import { splitPath } from "./GitDiffPanel.utils"; type ImageDiffCardProps = { diff --git a/src/features/git/hooks/useGitLog.ts b/src/features/git/hooks/useGitLog.ts index 9e9d00ba4..71bc7ff0a 100644 --- a/src/features/git/hooks/useGitLog.ts +++ b/src/features/git/hooks/useGitLog.ts @@ -101,7 +101,7 @@ export function useGitLog( } void refresh(); const interval = window.setInterval(() => { - refresh().catch(() => {}); + refresh().catch((err) => console.debug("git log refresh failed", err)); }, REFRESH_INTERVAL_MS); return () => { window.clearInterval(interval); diff --git a/src/features/git/hooks/useGitRemote.ts b/src/features/git/hooks/useGitRemote.ts index 06e47b4b6..d8d877039 100644 --- a/src/features/git/hooks/useGitRemote.ts +++ b/src/features/git/hooks/useGitRemote.ts @@ -63,7 +63,7 @@ export function useGitRemote(activeWorkspace: WorkspaceInfo | null) { return; } - refresh()?.catch(() => {}); + refresh()?.catch((err) => console.debug("git remote refresh failed", err)); }, [refresh, workspaceId]); return { ...state, refresh }; diff --git a/src/features/git/hooks/useGitStatus.ts b/src/features/git/hooks/useGitStatus.ts index 2c6fba88c..a8beaf00a 100644 --- a/src/features/git/hooks/useGitStatus.ts +++ b/src/features/git/hooks/useGitStatus.ts @@ -106,7 +106,7 @@ export function useGitStatus(activeWorkspace: WorkspaceInfo | null) { } const fetchStatus = () => { - refresh()?.catch(() => {}); + refresh()?.catch((err) => console.debug("git status refresh failed", err)); }; fetchStatus(); diff --git a/src/features/home/components/Home.tsx b/src/features/home/components/Home.tsx index f94e38df9..6d71d6d23 100644 --- a/src/features/home/components/Home.tsx +++ b/src/features/home/components/Home.tsx @@ -1,4 +1,4 @@ -import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw"; +import { RefreshCw } from "lucide-react"; import type { LocalUsageSnapshot } from "../../../types"; import { formatRelativeTime } from "../../../utils/time"; diff --git a/src/features/home/hooks/useLocalUsage.ts b/src/features/home/hooks/useLocalUsage.ts index 2c60ebb89..0a9422919 100644 --- a/src/features/home/hooks/useLocalUsage.ts +++ b/src/features/home/hooks/useLocalUsage.ts @@ -60,9 +60,9 @@ export function useLocalUsage(enabled: boolean, workspacePath: string | null) { if (!enabled) { return; } - refresh()?.catch(() => {}); + refresh()?.catch((err) => console.debug("local usage refresh failed", err)); const interval = window.setInterval(() => { - refresh()?.catch(() => {}); + refresh()?.catch((err) => console.debug("local usage refresh failed", err)); }, REFRESH_INTERVAL_MS); return () => { window.clearInterval(interval); diff --git a/src/features/layout/components/PanelTabs.tsx b/src/features/layout/components/PanelTabs.tsx index 162e1059d..27582b595 100644 --- a/src/features/layout/components/PanelTabs.tsx +++ b/src/features/layout/components/PanelTabs.tsx @@ -1,7 +1,5 @@ import { useRef, type KeyboardEvent, type ReactNode } from "react"; -import Folder from "lucide-react/dist/esm/icons/folder"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import ScrollText from "lucide-react/dist/esm/icons/scroll-text"; +import { Folder, GitBranch, ScrollText } from "lucide-react"; export type PanelTabId = "git" | "files" | "prompts"; diff --git a/src/features/layout/components/SidebarToggleControls.tsx b/src/features/layout/components/SidebarToggleControls.tsx index 5fe3c8578..af8ae0ca0 100644 --- a/src/features/layout/components/SidebarToggleControls.tsx +++ b/src/features/layout/components/SidebarToggleControls.tsx @@ -1,7 +1,4 @@ -import PanelLeftClose from "lucide-react/dist/esm/icons/panel-left-close"; -import PanelLeftOpen from "lucide-react/dist/esm/icons/panel-left-open"; -import PanelRightClose from "lucide-react/dist/esm/icons/panel-right-close"; -import PanelRightOpen from "lucide-react/dist/esm/icons/panel-right-open"; +import { PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen } from "lucide-react"; export type SidebarToggleProps = { isCompact: boolean; diff --git a/src/features/layout/components/WindowCaptionControls.tsx b/src/features/layout/components/WindowCaptionControls.tsx index 33fa1231f..2ca3159d3 100644 --- a/src/features/layout/components/WindowCaptionControls.tsx +++ b/src/features/layout/components/WindowCaptionControls.tsx @@ -1,7 +1,4 @@ -import Copy from "lucide-react/dist/esm/icons/copy"; -import Minus from "lucide-react/dist/esm/icons/minus"; -import Square from "lucide-react/dist/esm/icons/square"; -import X from "lucide-react/dist/esm/icons/x"; +import { Copy, Minus, Square, X } from "lucide-react"; import { isTauri } from "@tauri-apps/api/core"; import { getCurrentWindow } from "@tauri-apps/api/window"; import { useEffect, useState } from "react"; diff --git a/src/features/layout/hooks/layoutNodes/buildPrimaryNodes.tsx b/src/features/layout/hooks/layoutNodes/buildPrimaryNodes.tsx index d4958f910..215ecc5b1 100644 --- a/src/features/layout/hooks/layoutNodes/buildPrimaryNodes.tsx +++ b/src/features/layout/hooks/layoutNodes/buildPrimaryNodes.tsx @@ -1,4 +1,4 @@ -import ArrowLeft from "lucide-react/dist/esm/icons/arrow-left"; +import { ArrowLeft } from "lucide-react"; import { Sidebar } from "../../../app/components/Sidebar"; import { Home } from "../../../home/components/Home"; import { MainHeader } from "../../../app/components/MainHeader"; diff --git a/src/features/messages/components/MessageRows.tsx b/src/features/messages/components/MessageRows.tsx index 5d4094362..4aef1983e 100644 --- a/src/features/messages/components/MessageRows.tsx +++ b/src/features/messages/components/MessageRows.tsx @@ -1,19 +1,7 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; import type { MouseEvent } from "react"; import { createPortal } from "react-dom"; -import Brain from "lucide-react/dist/esm/icons/brain"; -import Check from "lucide-react/dist/esm/icons/check"; -import Copy from "lucide-react/dist/esm/icons/copy"; -import Diff from "lucide-react/dist/esm/icons/diff"; -import FileDiffIcon from "lucide-react/dist/esm/icons/file-diff"; -import FileText from "lucide-react/dist/esm/icons/file-text"; -import Image from "lucide-react/dist/esm/icons/image"; -import Quote from "lucide-react/dist/esm/icons/quote"; -import Search from "lucide-react/dist/esm/icons/search"; -import Terminal from "lucide-react/dist/esm/icons/terminal"; -import Users from "lucide-react/dist/esm/icons/users"; -import Wrench from "lucide-react/dist/esm/icons/wrench"; -import X from "lucide-react/dist/esm/icons/x"; +import { Brain, Check, Copy, Diff, FileDiffIcon, FileText, Image, Quote, Search, Terminal, Users, Wrench, X } from "lucide-react"; import { exportMarkdownFile } from "@services/tauri"; import { pushErrorToast } from "@services/toasts"; import type { ConversationItem } from "../../../types"; diff --git a/src/features/messages/components/Messages.tsx b/src/features/messages/components/Messages.tsx index 93ef2e356..79989c640 100644 --- a/src/features/messages/components/Messages.tsx +++ b/src/features/messages/components/Messages.tsx @@ -7,8 +7,7 @@ import { useRef, useState, } from "react"; -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronUp from "lucide-react/dist/esm/icons/chevron-up"; +import { ChevronDown, ChevronUp } from "lucide-react"; import type { ConversationItem, OpenAppTarget, diff --git a/src/features/mobile/components/MobileServerSetupWizard.tsx b/src/features/mobile/components/MobileServerSetupWizard.tsx index d1afa5e5b..1d6cbda09 100644 --- a/src/features/mobile/components/MobileServerSetupWizard.tsx +++ b/src/features/mobile/components/MobileServerSetupWizard.tsx @@ -1,5 +1,5 @@ import "../../../styles/mobile-setup-wizard.css"; -import X from "lucide-react/dist/esm/icons/x"; +import { X } from "lucide-react"; import { ModalShell } from "../../design-system/components/modal/ModalShell"; export type MobileServerSetupWizardProps = { diff --git a/src/features/prompts/components/PromptPanel.tsx b/src/features/prompts/components/PromptPanel.tsx index 2335ab4a8..30a7424f5 100644 --- a/src/features/prompts/components/PromptPanel.tsx +++ b/src/features/prompts/components/PromptPanel.tsx @@ -16,10 +16,7 @@ import { import { Menu, MenuItem } from "@tauri-apps/api/menu"; import { LogicalPosition } from "@tauri-apps/api/dpi"; import { getCurrentWindow } from "@tauri-apps/api/window"; -import MoreHorizontal from "lucide-react/dist/esm/icons/more-horizontal"; -import Plus from "lucide-react/dist/esm/icons/plus"; -import ScrollText from "lucide-react/dist/esm/icons/scroll-text"; -import Search from "lucide-react/dist/esm/icons/search"; +import { MoreHorizontal, Plus, ScrollText, Search } from "lucide-react"; type PromptPanelProps = { prompts: CustomPromptOption[]; diff --git a/src/features/prompts/hooks/useCustomPrompts.ts b/src/features/prompts/hooks/useCustomPrompts.ts index b9d4931cd..93d29313f 100644 --- a/src/features/prompts/hooks/useCustomPrompts.ts +++ b/src/features/prompts/hooks/useCustomPrompts.ts @@ -61,18 +61,19 @@ export function useCustomPrompts({ activeWorkspace, onDebug }: UseCustomPromptsO label: "prompts/list response", payload: response, }); - const responsePayload = response as any; - let rawPrompts: any[] = []; + const responsePayload = response as Record | undefined; + let rawPrompts: unknown[] = []; if (Array.isArray(response)) { rawPrompts = response; } else if (Array.isArray(responsePayload?.prompts)) { rawPrompts = responsePayload.prompts; - } else if (Array.isArray(responsePayload?.result?.prompts)) { - rawPrompts = responsePayload.result.prompts; + } else if (Array.isArray((responsePayload?.result as Record | undefined)?.prompts)) { + rawPrompts = (responsePayload!.result as Record).prompts as unknown[]; } else if (Array.isArray(responsePayload?.result)) { - rawPrompts = responsePayload.result; + rawPrompts = responsePayload.result as unknown[]; } - const data: CustomPromptOption[] = rawPrompts.map((item: any) => { + const data: CustomPromptOption[] = rawPrompts.map((rawItem: unknown) => { + const item = rawItem as Record; let argumentHint: string | undefined; if (item.argumentHint) { argumentHint = String(item.argumentHint); diff --git a/src/features/settings/components/SettingsNav.tsx b/src/features/settings/components/SettingsNav.tsx index 9e51920b0..5dd3de24d 100644 --- a/src/features/settings/components/SettingsNav.tsx +++ b/src/features/settings/components/SettingsNav.tsx @@ -1,16 +1,4 @@ -import LayoutGrid from "lucide-react/dist/esm/icons/layout-grid"; -import SlidersHorizontal from "lucide-react/dist/esm/icons/sliders-horizontal"; -import Mic from "lucide-react/dist/esm/icons/mic"; -import Keyboard from "lucide-react/dist/esm/icons/keyboard"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import TerminalSquare from "lucide-react/dist/esm/icons/terminal-square"; -import FileText from "lucide-react/dist/esm/icons/file-text"; -import FlaskConical from "lucide-react/dist/esm/icons/flask-conical"; -import ExternalLink from "lucide-react/dist/esm/icons/external-link"; -import Layers from "lucide-react/dist/esm/icons/layers"; -import ServerCog from "lucide-react/dist/esm/icons/server-cog"; -import Bot from "lucide-react/dist/esm/icons/bot"; -import Info from "lucide-react/dist/esm/icons/info"; +import { Bot, ExternalLink, FileText, FlaskConical, GitBranch, Info, Keyboard, Layers, LayoutGrid, Mic, ServerCog, SlidersHorizontal, TerminalSquare } from "lucide-react"; import { PanelNavItem, PanelNavList } from "@/features/design-system/components/panel/PanelPrimitives"; import type { CodexSection } from "./settingsTypes"; diff --git a/src/features/settings/components/SettingsView.tsx b/src/features/settings/components/SettingsView.tsx index 62327c2a8..0808ed84f 100644 --- a/src/features/settings/components/SettingsView.tsx +++ b/src/features/settings/components/SettingsView.tsx @@ -1,5 +1,4 @@ -import ChevronLeft from "lucide-react/dist/esm/icons/chevron-left"; -import X from "lucide-react/dist/esm/icons/x"; +import { ChevronLeft, X } from "lucide-react"; import type { AppSettings, CodexDoctorResult, diff --git a/src/features/settings/components/sections/SettingsCodexSection.tsx b/src/features/settings/components/sections/SettingsCodexSection.tsx index a522b3ac1..0826a1a2a 100644 --- a/src/features/settings/components/sections/SettingsCodexSection.tsx +++ b/src/features/settings/components/sections/SettingsCodexSection.tsx @@ -1,5 +1,5 @@ import { useEffect, useMemo, useRef } from "react"; -import Stethoscope from "lucide-react/dist/esm/icons/stethoscope"; +import { Stethoscope } from "lucide-react"; import type { Dispatch, SetStateAction } from "react"; import type { AppSettings, diff --git a/src/features/settings/components/sections/SettingsOpenAppsSection.tsx b/src/features/settings/components/sections/SettingsOpenAppsSection.tsx index c3c37ffc6..885987c26 100644 --- a/src/features/settings/components/sections/SettingsOpenAppsSection.tsx +++ b/src/features/settings/components/sections/SettingsOpenAppsSection.tsx @@ -1,6 +1,4 @@ -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronUp from "lucide-react/dist/esm/icons/chevron-up"; -import Trash2 from "lucide-react/dist/esm/icons/trash-2"; +import { ChevronDown, ChevronUp, Trash2 } from "lucide-react"; import { SettingsSection } from "@/features/design-system/components/settings/SettingsPrimitives"; import type { OpenAppTarget } from "@/types"; import { diff --git a/src/features/settings/components/sections/SettingsProjectsSection.tsx b/src/features/settings/components/sections/SettingsProjectsSection.tsx index e95cc8cd2..563bce2ec 100644 --- a/src/features/settings/components/sections/SettingsProjectsSection.tsx +++ b/src/features/settings/components/sections/SettingsProjectsSection.tsx @@ -1,6 +1,4 @@ -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronUp from "lucide-react/dist/esm/icons/chevron-up"; -import Trash2 from "lucide-react/dist/esm/icons/trash-2"; +import { ChevronDown, ChevronUp, Trash2 } from "lucide-react"; import type { Dispatch, SetStateAction } from "react"; import { SettingsSection, diff --git a/src/features/settings/components/sections/SettingsServerSection.tsx b/src/features/settings/components/sections/SettingsServerSection.tsx index 7a1139d6b..48358834a 100644 --- a/src/features/settings/components/sections/SettingsServerSection.tsx +++ b/src/features/settings/components/sections/SettingsServerSection.tsx @@ -1,6 +1,6 @@ import { useMemo, useState } from "react"; import type { Dispatch, SetStateAction } from "react"; -import X from "lucide-react/dist/esm/icons/x"; +import { X } from "lucide-react"; import type { AppSettings, TailscaleDaemonCommandPreview, diff --git a/src/features/shared/components/FileEditorCard.tsx b/src/features/shared/components/FileEditorCard.tsx index 01ba16784..27a7edcf0 100644 --- a/src/features/shared/components/FileEditorCard.tsx +++ b/src/features/shared/components/FileEditorCard.tsx @@ -1,6 +1,5 @@ import type { ReactNode } from "react"; -import RefreshCw from "lucide-react/dist/esm/icons/refresh-cw"; -import Save from "lucide-react/dist/esm/icons/save"; +import { RefreshCw, Save } from "lucide-react"; type FileEditorCardClassNames = { container: string; diff --git a/src/features/shared/hooks/useFileEditor.ts b/src/features/shared/hooks/useFileEditor.ts index 12577a6c7..d68c2aaa4 100644 --- a/src/features/shared/hooks/useFileEditor.ts +++ b/src/features/shared/hooks/useFileEditor.ts @@ -140,7 +140,7 @@ export function useFileEditor({ if (!key) { return; } - refresh().catch(() => {}); + refresh().catch((err) => console.debug("file editor refresh failed", err)); }, [key, refresh]); const isDirty = useMemo(() => state.content !== lastLoadedContentRef.current, [state.content]); diff --git a/src/features/threads/hooks/useThreadTurnEvents.ts b/src/features/threads/hooks/useThreadTurnEvents.ts index 94c34f7a5..484a09d3f 100644 --- a/src/features/threads/hooks/useThreadTurnEvents.ts +++ b/src/features/threads/hooks/useThreadTurnEvents.ts @@ -236,7 +236,7 @@ export function useThreadTurnEvents({ if (pendingInterruptsRef.current.has(threadId)) { pendingInterruptsRef.current.delete(threadId); if (turnId) { - void interruptTurnService(workspaceId, threadId, turnId).catch(() => {}); + void interruptTurnService(workspaceId, threadId, turnId).catch((err) => console.debug("interrupt turn failed", err)); } return; } diff --git a/src/features/workspaces/components/WorkspaceHomeRunControls.tsx b/src/features/workspaces/components/WorkspaceHomeRunControls.tsx index 421f3dd41..b11a27fbf 100644 --- a/src/features/workspaces/components/WorkspaceHomeRunControls.tsx +++ b/src/features/workspaces/components/WorkspaceHomeRunControls.tsx @@ -1,11 +1,7 @@ import { useCallback } from "react"; import type { ModelOption, WorkspaceInfo } from "../../../types"; import type { WorkspaceRunMode } from "../hooks/useWorkspaceHome"; -import Laptop from "lucide-react/dist/esm/icons/laptop"; -import GitBranch from "lucide-react/dist/esm/icons/git-branch"; -import ChevronDown from "lucide-react/dist/esm/icons/chevron-down"; -import ChevronRight from "lucide-react/dist/esm/icons/chevron-right"; -import Cpu from "lucide-react/dist/esm/icons/cpu"; +import { ChevronDown, ChevronRight, Cpu, GitBranch, Laptop } from "lucide-react"; import { PopoverMenuItem, SplitActionMenu, diff --git a/src/features/workspaces/hooks/useWorkspaceCrud.ts b/src/features/workspaces/hooks/useWorkspaceCrud.ts index f2fe84bd5..2f778d297 100644 --- a/src/features/workspaces/hooks/useWorkspaceCrud.ts +++ b/src/features/workspaces/hooks/useWorkspaceCrud.ts @@ -2,6 +2,7 @@ import { useCallback } from "react"; import type { Dispatch, MutableRefObject, SetStateAction } from "react"; import * as Sentry from "@sentry/react"; import type { DebugEntry, WorkspaceInfo, WorkspaceSettings } from "../../../types"; +import { pushErrorToast } from "../../../services/toasts"; import { addWorkspace as addWorkspaceService, addWorkspaceFromGitUrl as addWorkspaceFromGitUrlService, @@ -337,12 +338,17 @@ export function useWorkspaceCrud({ ), ); } catch (error) { + const message = error instanceof Error ? error.message : String(error); onDebug?.({ id: `${Date.now()}-client-connect-workspace-error`, timestamp: Date.now(), source: "error", label: "workspace/connect error", - payload: error instanceof Error ? error.message : String(error), + payload: message, + }); + pushErrorToast({ + title: "Workspace connection failed", + message, }); throw error; } diff --git a/src/features/workspaces/hooks/useWorkspaceDropZone.ts b/src/features/workspaces/hooks/useWorkspaceDropZone.ts index 155cc82ac..389987157 100644 --- a/src/features/workspaces/hooks/useWorkspaceDropZone.ts +++ b/src/features/workspaces/hooks/useWorkspaceDropZone.ts @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import type { DragEvent } from "react"; import { subscribeWindowDragDrop } from "../../../services/dragDrop"; +import { pushErrorToast } from "../../../services/toasts"; function isDragFileTransfer(types: readonly string[] | undefined) { if (!types || types.length === 0) { @@ -77,9 +78,11 @@ export function useWorkspaceDropZone({ const result = onDropPaths(paths); void Promise.resolve(result).catch((error) => { console.error("Failed to handle workspace drop paths", error); + pushErrorToast({ title: "Drop failed", message: String(error) }); }); } catch (error) { console.error("Failed to handle workspace drop paths", error); + pushErrorToast({ title: "Drop failed", message: String(error) }); } }, [onDropPaths], diff --git a/src/features/workspaces/hooks/useWorkspaceFiles.ts b/src/features/workspaces/hooks/useWorkspaceFiles.ts index bb68c86ae..033f5b72c 100644 --- a/src/features/workspaces/hooks/useWorkspaceFiles.ts +++ b/src/features/workspaces/hooks/useWorkspaceFiles.ts @@ -135,7 +135,7 @@ export function useWorkspaceFiles({ if (document.visibilityState === "hidden") { return; } - refreshFiles().catch(() => {}); + refreshFiles().catch((err) => console.debug("workspace files refresh failed", err)); }, refreshInterval); return () => { diff --git a/src/lucide-icons.d.ts b/src/lucide-icons.d.ts deleted file mode 100644 index f9b4872ef..000000000 --- a/src/lucide-icons.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module "lucide-react/dist/esm/icons/*" { - import type { LucideIcon } from "lucide-react"; - const icon: LucideIcon; - export default icon; -}