diff --git a/apps/ui/eslint.config.mjs b/apps/ui/eslint.config.mjs index 6db837e3..6cf025de 100644 --- a/apps/ui/eslint.config.mjs +++ b/apps/ui/eslint.config.mjs @@ -14,8 +14,13 @@ const eslintConfig = defineConfig([ require: 'readonly', __dirname: 'readonly', __filename: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', }, }, + rules: { + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }], + }, }, { files: ['**/*.ts', '**/*.tsx'], @@ -45,6 +50,8 @@ const eslintConfig = defineConfig([ confirm: 'readonly', getComputedStyle: 'readonly', requestAnimationFrame: 'readonly', + cancelAnimationFrame: 'readonly', + alert: 'readonly', // DOM Element Types HTMLElement: 'readonly', HTMLInputElement: 'readonly', @@ -56,6 +63,8 @@ const eslintConfig = defineConfig([ HTMLParagraphElement: 'readonly', HTMLImageElement: 'readonly', Element: 'readonly', + SVGElement: 'readonly', + SVGSVGElement: 'readonly', // Event Types Event: 'readonly', KeyboardEvent: 'readonly', @@ -64,14 +73,24 @@ const eslintConfig = defineConfig([ CustomEvent: 'readonly', ClipboardEvent: 'readonly', WheelEvent: 'readonly', + MouseEvent: 'readonly', + UIEvent: 'readonly', + MediaQueryListEvent: 'readonly', DataTransfer: 'readonly', // Web APIs ResizeObserver: 'readonly', AbortSignal: 'readonly', + AbortController: 'readonly', + IntersectionObserver: 'readonly', Audio: 'readonly', + HTMLAudioElement: 'readonly', ScrollBehavior: 'readonly', URL: 'readonly', URLSearchParams: 'readonly', + XMLHttpRequest: 'readonly', + Response: 'readonly', + RequestInit: 'readonly', + RequestCache: 'readonly', // Timers setTimeout: 'readonly', setInterval: 'readonly', @@ -90,6 +109,8 @@ const eslintConfig = defineConfig([ Electron: 'readonly', // Console console: 'readonly', + // Vite defines + __APP_VERSION__: 'readonly', }, }, plugins: { @@ -99,6 +120,13 @@ const eslintConfig = defineConfig([ ...ts.configs.recommended.rules, '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/ban-ts-comment': [ + 'error', + { + 'ts-nocheck': 'allow-with-description', + minimumDescriptionLength: 10, + }, + ], }, }, globalIgnores([ diff --git a/apps/ui/scripts/kill-test-servers.mjs b/apps/ui/scripts/kill-test-servers.mjs index 677f39e7..b24d608c 100644 --- a/apps/ui/scripts/kill-test-servers.mjs +++ b/apps/ui/scripts/kill-test-servers.mjs @@ -29,7 +29,7 @@ async function killProcessOnPort(port) { try { await execAsync(`kill -9 ${pid}`); console.log(`[KillTestServers] Killed process ${pid}`); - } catch (error) { + } catch (_error) { // Process might have already exited } } @@ -47,7 +47,7 @@ async function killProcessOnPort(port) { await new Promise((resolve) => setTimeout(resolve, 500)); return; } - } catch (error) { + } catch (_error) { // No process on port, which is fine } } diff --git a/apps/ui/src/components/codex-usage-popover.tsx b/apps/ui/src/components/codex-usage-popover.tsx index 430ccdfa..04482548 100644 --- a/apps/ui/src/components/codex-usage-popover.tsx +++ b/apps/ui/src/components/codex-usage-popover.tsx @@ -68,7 +68,6 @@ export function CodexUsagePopover() { // Use React Query for data fetching with automatic polling const { data: codexUsage, - isLoading, isFetching, error: queryError, dataUpdatedAt, diff --git a/apps/ui/src/components/dialogs/file-browser-dialog.tsx b/apps/ui/src/components/dialogs/file-browser-dialog.tsx index 53c20daa..61587cf0 100644 --- a/apps/ui/src/components/dialogs/file-browser-dialog.tsx +++ b/apps/ui/src/components/dialogs/file-browser-dialog.tsx @@ -40,8 +40,6 @@ interface FileBrowserDialogProps { initialPath?: string; } -const MAX_RECENT_FOLDERS = 5; - export function FileBrowserDialog({ open, onOpenChange, diff --git a/apps/ui/src/components/layout/project-switcher/components/notification-bell.tsx b/apps/ui/src/components/layout/project-switcher/components/notification-bell.tsx index adcd7b64..8217865d 100644 --- a/apps/ui/src/components/layout/project-switcher/components/notification-bell.tsx +++ b/apps/ui/src/components/layout/project-switcher/components/notification-bell.tsx @@ -3,7 +3,7 @@ */ import { useCallback } from 'react'; -import { Bell, Check, Trash2, ExternalLink } from 'lucide-react'; +import { Bell, Check, Trash2 } from 'lucide-react'; import { useNavigate } from '@tanstack/react-router'; import { useNotificationsStore } from '@/store/notifications-store'; import { useLoadNotifications, useNotificationEvents } from '@/hooks/use-notification-events'; diff --git a/apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx b/apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx index 0df4ab8c..249aa6a1 100644 --- a/apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx +++ b/apps/ui/src/components/layout/project-switcher/components/project-context-menu.tsx @@ -199,7 +199,6 @@ export function ProjectContextMenu({ } = useAppStore(); const [showRemoveDialog, setShowRemoveDialog] = useState(false); const [showThemeSubmenu, setShowThemeSubmenu] = useState(false); - const [removeConfirmed, setRemoveConfirmed] = useState(false); const themeSubmenuRef = useRef(null); const closeTimeoutRef = useRef | null>(null); @@ -331,7 +330,6 @@ export function ProjectContextMenu({ toast.success('Project removed', { description: `${project.name} has been removed from your projects list`, }); - setRemoveConfirmed(true); }, [moveProjectToTrash, project.id, project.name]); const handleDialogClose = useCallback( @@ -340,8 +338,6 @@ export function ProjectContextMenu({ // Close the context menu when dialog closes (whether confirmed or cancelled) // This prevents the context menu from reappearing after dialog interaction if (!isOpen) { - // Reset confirmation state - setRemoveConfirmed(false); // Always close the context menu when dialog closes onClose(); } diff --git a/apps/ui/src/components/shared/model-override-trigger.tsx b/apps/ui/src/components/shared/model-override-trigger.tsx index 70e9f261..2c21ecea 100644 --- a/apps/ui/src/components/shared/model-override-trigger.tsx +++ b/apps/ui/src/components/shared/model-override-trigger.tsx @@ -1,8 +1,4 @@ -import * as React from 'react'; -import { Settings2 } from 'lucide-react'; import { cn } from '@/lib/utils'; -import { Button } from '@/components/ui/button'; -import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { useAppStore } from '@/store/app-store'; import type { ModelAlias, CursorModelId, PhaseModelKey, PhaseModelEntry } from '@automaker/types'; import { PhaseModelSelector } from '@/components/views/settings-view/model-defaults/phase-model-selector'; @@ -74,12 +70,6 @@ export function ModelOverrideTrigger({ lg: 'h-10 w-10', }; - const iconSizes = { - sm: 'w-3.5 h-3.5', - md: 'w-4 h-4', - lg: 'w-5 h-5', - }; - // For icon variant, wrap PhaseModelSelector and hide text/chevron with CSS if (variant === 'icon') { return ( diff --git a/apps/ui/src/components/shared/use-model-override.ts b/apps/ui/src/components/shared/use-model-override.ts index 1a3efe2a..bd0027f1 100644 --- a/apps/ui/src/components/shared/use-model-override.ts +++ b/apps/ui/src/components/shared/use-model-override.ts @@ -37,16 +37,6 @@ function normalizeEntry(entry: PhaseModelEntry | string): PhaseModelEntry { return entry; } -/** - * Extract model string from PhaseModelEntry or string - */ -function extractModel(entry: PhaseModelEntry | string): ModelId { - if (typeof entry === 'string') { - return entry as ModelId; - } - return entry.model; -} - /** * Hook for managing model overrides per phase * diff --git a/apps/ui/src/components/ui/collapsible.tsx b/apps/ui/src/components/ui/collapsible.tsx index dfe74fc4..9605c4e4 100644 --- a/apps/ui/src/components/ui/collapsible.tsx +++ b/apps/ui/src/components/ui/collapsible.tsx @@ -1,4 +1,3 @@ -import * as React from 'react'; import * as CollapsiblePrimitive from '@radix-ui/react-collapsible'; const Collapsible = CollapsiblePrimitive.Root; diff --git a/apps/ui/src/components/ui/log-viewer.tsx b/apps/ui/src/components/ui/log-viewer.tsx index 65426f8b..2f338f2d 100644 --- a/apps/ui/src/components/ui/log-viewer.tsx +++ b/apps/ui/src/components/ui/log-viewer.tsx @@ -1,4 +1,4 @@ -import { useState, useMemo, useEffect, useRef } from 'react'; +import { useState, useMemo, useRef } from 'react'; import { ChevronDown, ChevronRight, @@ -21,7 +21,6 @@ import { X, Filter, Circle, - Play, } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; import { cn } from '@/lib/utils'; diff --git a/apps/ui/src/components/ui/task-progress-panel.tsx b/apps/ui/src/components/ui/task-progress-panel.tsx index 58174d66..b936cb9b 100644 --- a/apps/ui/src/components/ui/task-progress-panel.tsx +++ b/apps/ui/src/components/ui/task-progress-panel.tsx @@ -36,7 +36,7 @@ export function TaskProgressPanel({ const [tasks, setTasks] = useState([]); const [isExpanded, setIsExpanded] = useState(defaultExpanded); const [isLoading, setIsLoading] = useState(true); - const [currentTaskId, setCurrentTaskId] = useState(null); + const [, setCurrentTaskId] = useState(null); // Load initial tasks from feature's planSpec const loadInitialTasks = useCallback(async () => { @@ -236,7 +236,7 @@ export function TaskProgressPanel({
- {tasks.map((task, index) => { + {tasks.map((task, _index) => { const isActive = task.status === 'in_progress'; const isCompleted = task.status === 'completed'; const isPending = task.status === 'pending'; diff --git a/apps/ui/src/components/usage-popover.tsx b/apps/ui/src/components/usage-popover.tsx index e2991a1d..5d8acb0b 100644 --- a/apps/ui/src/components/usage-popover.tsx +++ b/apps/ui/src/components/usage-popover.tsx @@ -25,8 +25,6 @@ type UsageError = { message: string; }; -// Fixed refresh interval (45 seconds) -const REFRESH_INTERVAL_SECONDS = 45; const CLAUDE_SESSION_WINDOW_HOURS = 5; // Helper to format reset time for Codex @@ -229,15 +227,6 @@ export function UsagePopover() { // Calculate max percentage for header button const claudeSessionPercentage = claudeUsage?.sessionPercentage || 0; - const codexMaxPercentage = codexUsage?.rateLimits - ? Math.max( - codexUsage.rateLimits.primary?.usedPercent || 0, - codexUsage.rateLimits.secondary?.usedPercent || 0 - ) - : 0; - - const isStale = activeTab === 'claude' ? isClaudeStale : isCodexStale; - const getProgressBarColor = (percentage: number) => { if (percentage >= 80) return 'bg-red-500'; if (percentage >= 50) return 'bg-yellow-500'; diff --git a/apps/ui/src/components/views/agent-tools-view.tsx b/apps/ui/src/components/views/agent-tools-view.tsx index 48c3f92d..254f4e2d 100644 --- a/apps/ui/src/components/views/agent-tools-view.tsx +++ b/apps/ui/src/components/views/agent-tools-view.tsx @@ -5,17 +5,7 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/com import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { - FileText, - FolderOpen, - Terminal, - CheckCircle, - XCircle, - Play, - File, - Pencil, - Wrench, -} from 'lucide-react'; +import { Terminal, CheckCircle, XCircle, Play, File, Pencil, Wrench } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; import { cn } from '@/lib/utils'; import { getElectronAPI } from '@/lib/electron'; @@ -29,13 +19,6 @@ interface ToolResult { timestamp: Date; } -interface ToolExecution { - tool: string; - input: string; - result: ToolResult | null; - isRunning: boolean; -} - export function AgentToolsView() { const { currentProject } = useAppStore(); const api = getElectronAPI(); diff --git a/apps/ui/src/components/views/agent-view.tsx b/apps/ui/src/components/views/agent-view.tsx index 1278601c..2ec22eb3 100644 --- a/apps/ui/src/components/views/agent-view.tsx +++ b/apps/ui/src/components/views/agent-view.tsx @@ -63,7 +63,6 @@ export function AgentView() { sendMessage, clearHistory, stopExecution, - error: agentError, serverQueue, addToServerQueue, removeFromServerQueue, diff --git a/apps/ui/src/components/views/board-view.tsx b/apps/ui/src/components/views/board-view.tsx index 8a53fc6f..dcb6ead6 100644 --- a/apps/ui/src/components/views/board-view.tsx +++ b/apps/ui/src/components/views/board-view.tsx @@ -1,5 +1,5 @@ -// @ts-nocheck -import { useEffect, useState, useCallback, useMemo, useRef } from 'react'; +// @ts-nocheck - dnd-kit type incompatibilities with collision detection and complex state management +import { useEffect, useState, useCallback, useMemo } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { DndContext, @@ -29,16 +29,13 @@ class DialogAwarePointerSensor extends PointerSensor { import { useAppStore, Feature } from '@/store/app-store'; import { getElectronAPI } from '@/lib/electron'; import { getHttpApiClient } from '@/lib/http-api-client'; -import type { AutoModeEvent } from '@/types/electron'; -import type { ModelAlias, CursorModelId, BacklogPlanResult } from '@automaker/types'; +import type { BacklogPlanResult } from '@automaker/types'; import { pathsEqual } from '@/lib/utils'; import { toast } from 'sonner'; -import { getBlockingDependencies } from '@automaker/dependency-resolver'; import { BoardBackgroundModal } from '@/components/dialogs/board-background-modal'; import { Spinner } from '@/components/ui/spinner'; import { useShallow } from 'zustand/react/shallow'; import { useAutoMode } from '@/hooks/use-auto-mode'; -import { useKeyboardShortcutsConfig } from '@/hooks/use-keyboard-shortcuts'; import { useWindowState } from '@/hooks/use-window-state'; // Board-view specific imports import { BoardHeader } from './board-view/board-header'; @@ -97,8 +94,6 @@ const logger = createLogger('Board'); export function BoardView() { const { currentProject, - maxConcurrency: legacyMaxConcurrency, - setMaxConcurrency: legacySetMaxConcurrency, defaultSkipTests, specCreatingForProject, setSpecCreatingForProject, @@ -109,9 +104,6 @@ export function BoardView() { setCurrentWorktree, getWorktrees, setWorktrees, - useWorktrees, - enableDependencyBlocking, - skipVerificationInAutoMode, planUseSelectedWorktreeBranch, addFeatureUseSelectedWorktreeBranch, isPrimaryWorktreeBranch, @@ -120,8 +112,6 @@ export function BoardView() { } = useAppStore( useShallow((state) => ({ currentProject: state.currentProject, - maxConcurrency: state.maxConcurrency, - setMaxConcurrency: state.setMaxConcurrency, defaultSkipTests: state.defaultSkipTests, specCreatingForProject: state.specCreatingForProject, setSpecCreatingForProject: state.setSpecCreatingForProject, @@ -132,9 +122,6 @@ export function BoardView() { setCurrentWorktree: state.setCurrentWorktree, getWorktrees: state.getWorktrees, setWorktrees: state.setWorktrees, - useWorktrees: state.useWorktrees, - enableDependencyBlocking: state.enableDependencyBlocking, - skipVerificationInAutoMode: state.skipVerificationInAutoMode, planUseSelectedWorktreeBranch: state.planUseSelectedWorktreeBranch, addFeatureUseSelectedWorktreeBranch: state.addFeatureUseSelectedWorktreeBranch, isPrimaryWorktreeBranch: state.isPrimaryWorktreeBranch, @@ -151,12 +138,9 @@ export function BoardView() { // Subscribe to worktreePanelVisibleByProject to trigger re-renders when it changes const worktreePanelVisibleByProject = useAppStore((state) => state.worktreePanelVisibleByProject); // Subscribe to showInitScriptIndicatorByProject to trigger re-renders when it changes - const showInitScriptIndicatorByProject = useAppStore( - (state) => state.showInitScriptIndicatorByProject - ); + useAppStore((state) => state.showInitScriptIndicatorByProject); const getShowInitScriptIndicator = useAppStore((state) => state.getShowInitScriptIndicator); const getDefaultDeleteBranch = useAppStore((state) => state.getDefaultDeleteBranch); - const shortcuts = useKeyboardShortcutsConfig(); const { features: hookFeatures, isLoading, @@ -535,8 +519,6 @@ export function BoardView() { handleMoveBackToInProgress, handleOpenFollowUp, handleSendFollowUp, - handleCommitFeature, - handleMergeFeature, handleCompleteFeature, handleUnarchiveFeature, handleViewOutput, diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/agent-info-panel.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/agent-info-panel.tsx index 3a21fd26..20e1823c 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/agent-info-panel.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/agent-info-panel.tsx @@ -2,12 +2,7 @@ import { memo, useEffect, useState, useMemo, useRef } from 'react'; import { Feature, ThinkingLevel, ParsedTask } from '@/store/app-store'; import type { ReasoningEffort } from '@automaker/types'; import { getProviderFromModel } from '@/lib/utils'; -import { - AgentTaskInfo, - parseAgentContext, - formatModelName, - DEFAULT_MODEL, -} from '@/lib/agent-context-parser'; +import { parseAgentContext, formatModelName, DEFAULT_MODEL } from '@/lib/agent-context-parser'; import { cn } from '@/lib/utils'; import type { AutoModeEvent } from '@/types/electron'; import { Brain, ListTodo, Sparkles, Expand, CheckCircle2, Circle, Wrench } from 'lucide-react'; diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx index 0151a798..9348a321 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/card-actions.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - optional callback prop typing with feature status narrowing import { memo } from 'react'; import { Feature } from '@/store/app-store'; import { Button } from '@/components/ui/button'; @@ -36,7 +36,7 @@ interface CardActionsProps { export const CardActions = memo(function CardActions({ feature, isCurrentAutoTask, - hasContext, + hasContext: _hasContext, shortcutKey, isSelectionMode = false, onEdit, diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/card-badges.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/card-badges.tsx index 90b709c2..4f543a90 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/card-badges.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/card-badges.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - badge component prop variations with conditional rendering import { memo, useEffect, useMemo, useState } from 'react'; import { Feature, useAppStore } from '@/store/app-store'; import { cn } from '@/lib/utils'; diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/card-content-sections.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/card-content-sections.tsx index 5b2229d8..1846c3a5 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/card-content-sections.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/card-content-sections.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - content section prop typing with feature data extraction import { memo } from 'react'; import { Feature } from '@/store/app-store'; import { GitBranch, GitPullRequest, ExternalLink } from 'lucide-react'; diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx index 87a26cdf..793c3191 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/card-header.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - header component props with optional handlers and status variants import { memo, useState } from 'react'; import { Feature } from '@/store/app-store'; import { cn } from '@/lib/utils'; diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx index d6198f36..a332f305 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - dnd-kit draggable/droppable ref combination type incompatibilities import React, { memo, useLayoutEffect, useState, useCallback } from 'react'; import { useDraggable, useDroppable } from '@dnd-kit/core'; import { cn } from '@/lib/utils'; diff --git a/apps/ui/src/components/views/board-view/components/kanban-card/summary-dialog.tsx b/apps/ui/src/components/views/board-view/components/kanban-card/summary-dialog.tsx index 11e98663..1fed1310 100644 --- a/apps/ui/src/components/views/board-view/components/kanban-card/summary-dialog.tsx +++ b/apps/ui/src/components/views/board-view/components/kanban-card/summary-dialog.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - dialog state typing with feature summary extraction import { Feature } from '@/store/app-store'; import { AgentTaskInfo } from '@/lib/agent-context-parser'; import { diff --git a/apps/ui/src/components/views/board-view/components/list-view/list-row.tsx b/apps/ui/src/components/views/board-view/components/list-view/list-row.tsx index 32b0f445..2c5474f9 100644 --- a/apps/ui/src/components/views/board-view/components/list-view/list-row.tsx +++ b/apps/ui/src/components/views/board-view/components/list-view/list-row.tsx @@ -1,6 +1,4 @@ -// TODO: Remove @ts-nocheck after fixing BaseFeature's index signature issue -// The `[key: string]: unknown` in BaseFeature causes property access type errors -// @ts-nocheck +// @ts-nocheck - BaseFeature index signature causes property access type errors import { memo, useCallback, useState, useEffect } from 'react'; import { cn } from '@/lib/utils'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; diff --git a/apps/ui/src/components/views/board-view/components/list-view/list-view.tsx b/apps/ui/src/components/views/board-view/components/list-view/list-view.tsx index 6622161e..0a08b127 100644 --- a/apps/ui/src/components/views/board-view/components/list-view/list-view.tsx +++ b/apps/ui/src/components/views/board-view/components/list-view/list-view.tsx @@ -8,7 +8,7 @@ import type { PipelineConfig, FeatureStatusWithPipeline } from '@automaker/types import { ListHeader } from './list-header'; import { ListRow, sortFeatures } from './list-row'; import { createRowActionHandlers, type RowActionHandlers } from './row-actions'; -import { getStatusLabel, getStatusOrder } from './status-badge'; +import { getStatusOrder } from './status-badge'; import { getColumnsWithPipeline } from '../../constants'; import type { SortConfig, SortColumn } from '../../hooks/use-list-view-state'; diff --git a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx index 6fa66061..b8dd8776 100644 --- a/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/add-feature-dialog.tsx @@ -1,6 +1,5 @@ -// @ts-nocheck +// @ts-nocheck - feature data building with conditional fields and model type inference import { useState, useEffect, useRef } from 'react'; -import { createLogger } from '@automaker/utils/logger'; import { Dialog, DialogContent, @@ -27,18 +26,10 @@ import { useNavigate } from '@tanstack/react-router'; import { toast } from 'sonner'; import { cn } from '@/lib/utils'; import { modelSupportsThinking } from '@/lib/utils'; -import { - useAppStore, - ModelAlias, - ThinkingLevel, - FeatureImage, - PlanningMode, - Feature, -} from '@/store/app-store'; +import { useAppStore, ThinkingLevel, FeatureImage, PlanningMode, Feature } from '@/store/app-store'; import type { ReasoningEffort, PhaseModelEntry, AgentModel } from '@automaker/types'; import { supportsReasoningEffort } from '@automaker/types'; import { - TestingTabContent, PrioritySelector, WorkModeSelector, PlanningModeSelect, @@ -57,8 +48,6 @@ import { type AncestorContext, } from '@automaker/dependency-resolver'; -const logger = createLogger('AddFeatureDialog'); - /** * Determines the default work mode based on global settings and current worktree selection. * diff --git a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx index 6db3df66..a074ceb8 100644 --- a/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx @@ -282,7 +282,7 @@ export function AgentOutputModal({ } if (newContent) { - setOutput((prev) => `${prev}${newContent}`); + setStreamedContent((prev) => prev + newContent); } }); diff --git a/apps/ui/src/components/views/board-view/dialogs/completed-features-modal.tsx b/apps/ui/src/components/views/board-view/dialogs/completed-features-modal.tsx index d56a221c..adc0ef1b 100644 --- a/apps/ui/src/components/views/board-view/dialogs/completed-features-modal.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/completed-features-modal.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - completed features filtering and grouping with status transitions import { Dialog, DialogContent, diff --git a/apps/ui/src/components/views/board-view/dialogs/dependency-tree-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/dependency-tree-dialog.tsx index 7c2364be..f31323b3 100644 --- a/apps/ui/src/components/views/board-view/dialogs/dependency-tree-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/dependency-tree-dialog.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - dependency tree visualization with recursive feature relationships import { useState, useEffect } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Feature } from '@/store/app-store'; diff --git a/apps/ui/src/components/views/board-view/dialogs/edit-feature-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/edit-feature-dialog.tsx index 61a20878..e7a6b5ec 100644 --- a/apps/ui/src/components/views/board-view/dialogs/edit-feature-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/edit-feature-dialog.tsx @@ -1,6 +1,5 @@ -// @ts-nocheck +// @ts-nocheck - form state management with partial feature updates and validation import { useState, useEffect } from 'react'; -import { createLogger } from '@automaker/utils/logger'; import { Dialog, DialogContent, @@ -26,11 +25,10 @@ import { GitBranch, Cpu, FolderKanban, Settings2 } from 'lucide-react'; import { useNavigate } from '@tanstack/react-router'; import { toast } from 'sonner'; import { cn, modelSupportsThinking } from '@/lib/utils'; -import { Feature, ModelAlias, ThinkingLevel, useAppStore, PlanningMode } from '@/store/app-store'; +import { Feature, ModelAlias, ThinkingLevel, PlanningMode } from '@/store/app-store'; import type { ReasoningEffort, PhaseModelEntry, DescriptionHistoryEntry } from '@automaker/types'; import { migrateModelId } from '@automaker/types'; import { - TestingTabContent, PrioritySelector, WorkModeSelector, PlanningModeSelect, @@ -45,8 +43,6 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip import { DependencyTreeDialog } from './dependency-tree-dialog'; import { supportsReasoningEffort } from '@automaker/types'; -const logger = createLogger('EditFeatureDialog'); - interface EditFeatureDialogProps { feature: Feature | null; onClose: () => void; diff --git a/apps/ui/src/components/views/board-view/dialogs/follow-up-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/follow-up-dialog.tsx index 6df1eea0..f249ff97 100644 --- a/apps/ui/src/components/views/board-view/dialogs/follow-up-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/follow-up-dialog.tsx @@ -1,5 +1,3 @@ -import { useState } from 'react'; -import { createLogger } from '@automaker/utils/logger'; import { Dialog, DialogContent, @@ -18,14 +16,7 @@ import { } from '@/components/ui/description-image-dropzone'; import { MessageSquare } from 'lucide-react'; import { Feature } from '@/store/app-store'; -import { - EnhanceWithAI, - EnhancementHistoryButton, - type EnhancementMode, - type BaseHistoryEntry, -} from '../shared'; - -const logger = createLogger('FollowUpDialog'); +import { EnhanceWithAI, EnhancementHistoryButton, type BaseHistoryEntry } from '../shared'; /** * A single entry in the follow-up prompt history diff --git a/apps/ui/src/components/views/board-view/dialogs/mass-edit-dialog.tsx b/apps/ui/src/components/views/board-view/dialogs/mass-edit-dialog.tsx index a1f0609f..c8cb7e42 100644 --- a/apps/ui/src/components/views/board-view/dialogs/mass-edit-dialog.tsx +++ b/apps/ui/src/components/views/board-view/dialogs/mass-edit-dialog.tsx @@ -11,7 +11,6 @@ import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Label } from '@/components/ui/label'; import { AlertCircle } from 'lucide-react'; -import { modelSupportsThinking } from '@/lib/utils'; import { Feature, ModelAlias, ThinkingLevel, PlanningMode } from '@/store/app-store'; import { TestingTabContent, @@ -22,7 +21,7 @@ import { } from '../shared'; import type { WorkMode } from '../shared'; import { PhaseModelSelector } from '@/components/views/settings-view/model-defaults/phase-model-selector'; -import { isCursorModel, type PhaseModelEntry } from '@automaker/types'; +import type { PhaseModelEntry } from '@automaker/types'; import { cn } from '@/lib/utils'; interface MassEditDialogProps { @@ -240,8 +239,6 @@ export function MassEditDialog({ }; const hasAnyApply = Object.values(applyState).some(Boolean); - const isCurrentModelCursor = isCursorModel(model); - const modelAllowsThinking = !isCurrentModelCursor && modelSupportsThinking(model); return ( !open && onClose()}> diff --git a/apps/ui/src/components/views/board-view/hooks/use-board-actions.ts b/apps/ui/src/components/views/board-view/hooks/use-board-actions.ts index 9cd5bea8..ebd80591 100644 --- a/apps/ui/src/components/views/board-view/hooks/use-board-actions.ts +++ b/apps/ui/src/components/views/board-view/hooks/use-board-actions.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - feature update logic with partial updates and image/file handling import { useCallback } from 'react'; import { Feature, diff --git a/apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts b/apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts index 6505da2a..508cb948 100644 --- a/apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts +++ b/apps/ui/src/components/views/board-view/hooks/use-board-column-features.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - column filtering logic with dependency resolution and status mapping import { useMemo, useCallback } from 'react'; import { Feature, useAppStore } from '@/store/app-store'; import { @@ -51,7 +51,6 @@ export function useBoardColumnFeatures({ // Determine the effective worktree path and branch for filtering // If currentWorktreePath is null, we're on the main worktree - const effectiveWorktreePath = currentWorktreePath || projectPath; // Use the branch name from the selected worktree // If we're selecting main (currentWorktreePath is null), currentWorktreeBranch // should contain the main branch's actual name, defaulting to "main" diff --git a/apps/ui/src/components/views/board-view/hooks/use-board-drag-drop.ts b/apps/ui/src/components/views/board-view/hooks/use-board-drag-drop.ts index 10b7d1ba..c41f4c0d 100644 --- a/apps/ui/src/components/views/board-view/hooks/use-board-drag-drop.ts +++ b/apps/ui/src/components/views/board-view/hooks/use-board-drag-drop.ts @@ -23,7 +23,7 @@ interface UseBoardDragDropProps { export function useBoardDragDrop({ features, - currentProject, + currentProject: _currentProject, runningAutoTasks, persistFeatureUpdate, handleStartImplementation, diff --git a/apps/ui/src/components/views/board-view/shared/model-constants.ts b/apps/ui/src/components/views/board-view/shared/model-constants.ts index 83c75827..c56ad46a 100644 --- a/apps/ui/src/components/views/board-view/shared/model-constants.ts +++ b/apps/ui/src/components/views/board-view/shared/model-constants.ts @@ -1,4 +1,3 @@ -import type { ModelAlias } from '@/store/app-store'; import type { ModelProvider, ThinkingLevel, ReasoningEffort } from '@automaker/types'; import { CURSOR_MODEL_MAP, diff --git a/apps/ui/src/components/views/board-view/shared/model-selector.tsx b/apps/ui/src/components/views/board-view/shared/model-selector.tsx index 79a8c227..a40623ea 100644 --- a/apps/ui/src/components/views/board-view/shared/model-selector.tsx +++ b/apps/ui/src/components/views/board-view/shared/model-selector.tsx @@ -1,13 +1,12 @@ -// @ts-nocheck +// @ts-nocheck - model selector with provider-specific model options and validation import { Label } from '@/components/ui/label'; import { Badge } from '@/components/ui/badge'; import { Brain, AlertTriangle } from 'lucide-react'; import { AnthropicIcon, CursorIcon, OpenAIIcon } from '@/components/ui/provider-icon'; import { cn } from '@/lib/utils'; -import type { ModelAlias } from '@/store/app-store'; import { useAppStore } from '@/store/app-store'; import { useSetupStore } from '@/store/setup-store'; -import { getModelProvider, PROVIDER_PREFIXES, stripProviderPrefix } from '@automaker/types'; +import { getModelProvider } from '@automaker/types'; import type { ModelProvider } from '@automaker/types'; import { CLAUDE_MODELS, CURSOR_MODELS, ModelOption } from './model-constants'; import { useEffect } from 'react'; diff --git a/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx b/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx index a6d7ef59..4d26efcb 100644 --- a/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx +++ b/apps/ui/src/components/views/board-view/worktree-panel/components/dev-server-logs-panel.tsx @@ -12,7 +12,6 @@ import { GitBranch, } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; -import { cn } from '@/lib/utils'; import { XtermLogViewer, type XtermLogViewerRef } from '@/components/ui/xterm-log-viewer'; import { useDevServerLogs } from '../hooks/use-dev-server-logs'; import type { WorktreeInfo } from '../types'; diff --git a/apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx b/apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx index 22710e6c..7b1d96df 100644 --- a/apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx +++ b/apps/ui/src/components/views/board-view/worktree-panel/components/worktree-actions-dropdown.tsx @@ -161,7 +161,7 @@ export function WorktreeActionsDropdown({ : null; // Get available terminals for the "Open In Terminal" submenu - const { terminals, hasExternalTerminals } = useAvailableTerminals(); + const { terminals } = useAvailableTerminals(); // Use shared hook for effective default terminal (null = integrated terminal) const effectiveDefaultTerminal = useEffectiveDefaultTerminal(terminals); diff --git a/apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx b/apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx index 6d376ea5..f3aebce6 100644 --- a/apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx +++ b/apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx @@ -514,7 +514,7 @@ export function WorktreePanel({ } else { toast.error(result.error || 'Failed to push changes'); } - } catch (error) { + } catch { toast.error('Failed to push changes'); } }, diff --git a/apps/ui/src/components/views/code-view.tsx b/apps/ui/src/components/views/code-view.tsx index ce80bc23..1aa70165 100644 --- a/apps/ui/src/components/views/code-view.tsx +++ b/apps/ui/src/components/views/code-view.tsx @@ -4,7 +4,7 @@ import { useAppStore } from '@/store/app-store'; import { getElectronAPI } from '@/lib/electron'; import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; -import { File, Folder, FolderOpen, ChevronRight, ChevronDown, Code } from 'lucide-react'; +import { File, Folder, FolderOpen, ChevronRight, ChevronDown, Code, RefreshCw } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; import { cn } from '@/lib/utils'; diff --git a/apps/ui/src/components/views/context-view.tsx b/apps/ui/src/components/views/context-view.tsx index b186e0c1..512a69e8 100644 --- a/apps/ui/src/components/views/context-view.tsx +++ b/apps/ui/src/components/views/context-view.tsx @@ -103,12 +103,6 @@ export function ContextView() { // File input ref for import const fileInputRef = useRef(null); - // Get images directory path - const getImagesPath = useCallback(() => { - if (!currentProject) return null; - return `${currentProject.path}/.automaker/images`; - }, [currentProject]); - // Keyboard shortcuts for this view const contextShortcuts: KeyboardShortcut[] = useMemo( () => [ diff --git a/apps/ui/src/components/views/github-issues-view.tsx b/apps/ui/src/components/views/github-issues-view.tsx index 986ad65c..e41d415b 100644 --- a/apps/ui/src/components/views/github-issues-view.tsx +++ b/apps/ui/src/components/views/github-issues-view.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - GitHub issues view with issue selection and feature creation flow import { useState, useCallback, useMemo } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { CircleDot, RefreshCw, SearchX } from 'lucide-react'; @@ -43,9 +43,6 @@ export function GitHubIssuesView() { // Model override for validation const validationModelOverride = useModelOverride({ phase: 'validationModel' }); - // Extract model string for API calls (backward compatibility) - const validationModelString = validationModelOverride.effectiveModel; - const { openIssues, closedIssues, loading, refreshing, error, refresh } = useGithubIssues(); const { validatingIssues, cachedValidations, handleValidateIssue, handleViewCachedValidation } = diff --git a/apps/ui/src/components/views/github-issues-view/components/issues-list-header.tsx b/apps/ui/src/components/views/github-issues-view/components/issues-list-header.tsx index 5b599c4e..9d7c49c0 100644 --- a/apps/ui/src/components/views/github-issues-view/components/issues-list-header.tsx +++ b/apps/ui/src/components/views/github-issues-view/components/issues-list-header.tsx @@ -1,7 +1,6 @@ import { CircleDot, RefreshCw } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Spinner } from '@/components/ui/spinner'; -import { cn } from '@/lib/utils'; import type { IssuesStateFilter } from '../types'; import { IssuesFilterControls } from './issues-filter-controls'; diff --git a/apps/ui/src/components/views/github-issues-view/hooks/use-issue-validation.ts b/apps/ui/src/components/views/github-issues-view/hooks/use-issue-validation.ts index 788a9efe..111c1f2d 100644 --- a/apps/ui/src/components/views/github-issues-view/hooks/use-issue-validation.ts +++ b/apps/ui/src/components/views/github-issues-view/hooks/use-issue-validation.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - GitHub issue validation with Electron API integration and async state import { useState, useEffect, useCallback, useRef } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { @@ -17,17 +17,6 @@ import { useValidateIssue, useMarkValidationViewed } from '@/hooks/mutations'; const logger = createLogger('IssueValidation'); -/** - * Extract model string from PhaseModelEntry or string (handles both formats) - */ -function extractModel(entry: PhaseModelEntry | string | undefined): ModelId | undefined { - if (!entry) return undefined; - if (typeof entry === 'string') { - return entry as ModelId; - } - return entry.model; -} - interface UseIssueValidationOptions { selectedIssue: GitHubIssue | null; showValidationDialog: boolean; diff --git a/apps/ui/src/components/views/graph-view-page.tsx b/apps/ui/src/components/views/graph-view-page.tsx index 3bb1f306..0f6d7d24 100644 --- a/apps/ui/src/components/views/graph-view-page.tsx +++ b/apps/ui/src/components/views/graph-view-page.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - graph view page with feature filtering and visualization state import { useState, useCallback, useMemo, useEffect } from 'react'; import { useAppStore, Feature } from '@/store/app-store'; import { useShallow } from 'zustand/react/shallow'; @@ -9,12 +9,7 @@ import { AgentOutputModal, BacklogPlanDialog, } from './board-view/dialogs'; -import { - useBoardFeatures, - useBoardActions, - useBoardBackground, - useBoardPersistence, -} from './board-view/hooks'; +import { useBoardFeatures, useBoardActions, useBoardPersistence } from './board-view/hooks'; import { useWorktrees } from './board-view/worktree-panel/hooks'; import { useAutoMode } from '@/hooks/use-auto-mode'; import { pathsEqual } from '@/lib/utils'; @@ -242,7 +237,7 @@ export function GraphViewPage() { const [followUpFeature, setFollowUpFeature] = useState(null); const [followUpPrompt, setFollowUpPrompt] = useState(''); const [followUpImagePaths, setFollowUpImagePaths] = useState([]); - const [followUpPreviewMap, setFollowUpPreviewMap] = useState>(new Map()); + const [, setFollowUpPreviewMap] = useState>(new Map()); // In-progress features for shortcuts const inProgressFeaturesForShortcuts = useMemo(() => { diff --git a/apps/ui/src/components/views/graph-view/components/graph-controls.tsx b/apps/ui/src/components/views/graph-view/components/graph-controls.tsx index cea4d3f5..2a5adb55 100644 --- a/apps/ui/src/components/views/graph-view/components/graph-controls.tsx +++ b/apps/ui/src/components/views/graph-view/components/graph-controls.tsx @@ -1,16 +1,7 @@ import { useReactFlow, Panel } from '@xyflow/react'; import { Button } from '@/components/ui/button'; import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip'; -import { - ZoomIn, - ZoomOut, - Maximize2, - Lock, - Unlock, - GitBranch, - ArrowRight, - ArrowDown, -} from 'lucide-react'; +import { ZoomIn, ZoomOut, Maximize2, Lock, Unlock, ArrowRight, ArrowDown } from 'lucide-react'; import { cn } from '@/lib/utils'; interface GraphControlsProps { diff --git a/apps/ui/src/components/views/graph-view/graph-canvas.tsx b/apps/ui/src/components/views/graph-view/graph-canvas.tsx index 1286a745..a0cf9388 100644 --- a/apps/ui/src/components/views/graph-view/graph-canvas.tsx +++ b/apps/ui/src/components/views/graph-view/graph-canvas.tsx @@ -175,9 +175,7 @@ function GraphCanvasInner({ mql.addEventListener('change', update); return () => mql.removeEventListener('change', update); } - // eslint-disable-next-line deprecation/deprecation mql.addListener(update); - // eslint-disable-next-line deprecation/deprecation return () => mql.removeListener(update); }, [effectiveTheme]); diff --git a/apps/ui/src/components/views/graph-view/hooks/use-graph-layout.ts b/apps/ui/src/components/views/graph-view/hooks/use-graph-layout.ts index 462465a8..e3634bd4 100644 --- a/apps/ui/src/components/views/graph-view/hooks/use-graph-layout.ts +++ b/apps/ui/src/components/views/graph-view/hooks/use-graph-layout.ts @@ -1,6 +1,5 @@ import { useCallback, useMemo, useRef } from 'react'; import dagre from 'dagre'; -import { Node, Edge } from '@xyflow/react'; import { TaskNode, DependencyEdge } from './use-graph-nodes'; const NODE_WIDTH = 280; diff --git a/apps/ui/src/components/views/interview-view.tsx b/apps/ui/src/components/views/interview-view.tsx index b30d285a..5771103f 100644 --- a/apps/ui/src/components/views/interview-view.tsx +++ b/apps/ui/src/components/views/interview-view.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - interview flow state machine with dynamic question handling import { useState, useCallback, useRef, useEffect } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { useAppStore, Feature } from '@/store/app-store'; diff --git a/apps/ui/src/components/views/notifications-view.tsx b/apps/ui/src/components/views/notifications-view.tsx index 08386c55..93269990 100644 --- a/apps/ui/src/components/views/notifications-view.tsx +++ b/apps/ui/src/components/views/notifications-view.tsx @@ -2,13 +2,13 @@ * Notifications View - Full page view for all notifications */ -import { useEffect, useCallback } from 'react'; +import { useCallback } from 'react'; import { useAppStore } from '@/store/app-store'; import { useNotificationsStore } from '@/store/notifications-store'; import { useLoadNotifications, useNotificationEvents } from '@/hooks/use-notification-events'; import { getHttpApiClient } from '@/lib/http-api-client'; import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; +import { Card, CardContent, CardDescription, CardTitle } from '@/components/ui/card'; import { Bell, Check, CheckCheck, Trash2, ExternalLink } from 'lucide-react'; import { Spinner } from '@/components/ui/spinner'; import { useNavigate } from '@tanstack/react-router'; @@ -42,8 +42,6 @@ export function NotificationsView() { unreadCount, isLoading, error, - setNotifications, - setUnreadCount, markAsRead, dismissNotification, markAllAsRead, diff --git a/apps/ui/src/components/views/overview/running-agents-panel.tsx b/apps/ui/src/components/views/overview/running-agents-panel.tsx index fc91170d..2266f128 100644 --- a/apps/ui/src/components/views/overview/running-agents-panel.tsx +++ b/apps/ui/src/components/views/overview/running-agents-panel.tsx @@ -9,10 +9,8 @@ import { useNavigate } from '@tanstack/react-router'; import { useAppStore } from '@/store/app-store'; import { initializeProject } from '@/lib/project-init'; import { toast } from 'sonner'; -import { cn } from '@/lib/utils'; import type { ProjectStatus } from '@automaker/types'; import { Bot, Activity, GitBranch, ArrowRight } from 'lucide-react'; -import { Button } from '@/components/ui/button'; interface RunningAgentsPanelProps { projects: ProjectStatus[]; diff --git a/apps/ui/src/components/views/project-settings-view/commands-section.tsx b/apps/ui/src/components/views/project-settings-view/commands-section.tsx index 6577c07c..b7cb3138 100644 --- a/apps/ui/src/components/views/project-settings-view/commands-section.tsx +++ b/apps/ui/src/components/views/project-settings-view/commands-section.tsx @@ -1,5 +1,4 @@ import { useState, useEffect, useCallback, type KeyboardEvent } from 'react'; -import { Label } from '@/components/ui/label'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { Terminal, Save, RotateCcw, Info, X, Play, FlaskConical } from 'lucide-react'; diff --git a/apps/ui/src/components/views/project-settings-view/project-identity-section.tsx b/apps/ui/src/components/views/project-settings-view/project-identity-section.tsx index 669b7879..6020411e 100644 --- a/apps/ui/src/components/views/project-settings-view/project-identity-section.tsx +++ b/apps/ui/src/components/views/project-settings-view/project-identity-section.tsx @@ -97,7 +97,7 @@ export function ProjectIdentitySection({ project }: ProjectIdentitySectionProps) description: result.error || 'Please try again.', }); } - } catch (error) { + } catch { toast.error('Failed to upload icon', { description: 'Network error. Please try again.', }); diff --git a/apps/ui/src/components/views/project-settings-view/project-models-section.tsx b/apps/ui/src/components/views/project-settings-view/project-models-section.tsx index 1a150500..65bf9516 100644 --- a/apps/ui/src/components/views/project-settings-view/project-models-section.tsx +++ b/apps/ui/src/components/views/project-settings-view/project-models-section.tsx @@ -86,8 +86,6 @@ const MEMORY_TASKS: PhaseConfig[] = [ }, ]; -const ALL_PHASES = [...QUICK_TASKS, ...VALIDATION_TASKS, ...GENERATION_TASKS, ...MEMORY_TASKS]; - /** * Default feature model override section for per-project settings. */ diff --git a/apps/ui/src/components/views/running-agents-view.tsx b/apps/ui/src/components/views/running-agents-view.tsx index 4265650b..b7a8171b 100644 --- a/apps/ui/src/components/views/running-agents-view.tsx +++ b/apps/ui/src/components/views/running-agents-view.tsx @@ -12,7 +12,6 @@ import { Spinner } from '@/components/ui/spinner'; import { getElectronAPI, type RunningAgent } from '@/lib/electron'; import { useAppStore } from '@/store/app-store'; import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { useNavigate } from '@tanstack/react-router'; import { AgentOutputModal } from './board-view/dialogs/agent-output-modal'; import { useRunningAgents } from '@/hooks/queries'; diff --git a/apps/ui/src/components/views/settings-view.tsx b/apps/ui/src/components/views/settings-view.tsx index ece08878..ff1b6a8c 100644 --- a/apps/ui/src/components/views/settings-view.tsx +++ b/apps/ui/src/components/views/settings-view.tsx @@ -58,8 +58,6 @@ export function SettingsView() { setDefaultRequirePlanApproval, defaultFeatureModel, setDefaultFeatureModel, - autoLoadClaudeMd, - setAutoLoadClaudeMd, promptCustomization, setPromptCustomization, skipSandboxWarning, diff --git a/apps/ui/src/components/views/settings-view/api-keys/api-keys-section.tsx b/apps/ui/src/components/views/settings-view/api-keys/api-keys-section.tsx index caf745b1..9f5fd0ec 100644 --- a/apps/ui/src/components/views/settings-view/api-keys/api-keys-section.tsx +++ b/apps/ui/src/components/views/settings-view/api-keys/api-keys-section.tsx @@ -14,8 +14,7 @@ import { toast } from 'sonner'; export function ApiKeysSection() { const { apiKeys, setApiKeys } = useAppStore(); - const { claudeAuthStatus, setClaudeAuthStatus, codexAuthStatus, setCodexAuthStatus } = - useSetupStore(); + const { claudeAuthStatus, setClaudeAuthStatus, setCodexAuthStatus } = useSetupStore(); const [isDeletingAnthropicKey, setIsDeletingAnthropicKey] = useState(false); const [isDeletingOpenaiKey, setIsDeletingOpenaiKey] = useState(false); @@ -45,7 +44,7 @@ export function ApiKeysSection() { } else { toast.error(result.error || 'Failed to delete API key'); } - } catch (error) { + } catch { toast.error('Failed to delete API key'); } finally { setIsDeletingAnthropicKey(false); @@ -73,7 +72,7 @@ export function ApiKeysSection() { } else { toast.error(result.error || 'Failed to delete API key'); } - } catch (error) { + } catch { toast.error('Failed to delete API key'); } finally { setIsDeletingOpenaiKey(false); diff --git a/apps/ui/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts b/apps/ui/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts index 6cff2f83..0290ec9e 100644 --- a/apps/ui/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts +++ b/apps/ui/src/components/views/settings-view/api-keys/hooks/use-api-key-management.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - API key management state with validation and persistence import { useState, useEffect } from 'react'; import { createLogger } from '@automaker/utils/logger'; import { useAppStore } from '@/store/app-store'; diff --git a/apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx b/apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx index 99d55ad0..c51e8c92 100644 --- a/apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx +++ b/apps/ui/src/components/views/settings-view/appearance/appearance-section.tsx @@ -12,7 +12,6 @@ import { cn } from '@/lib/utils'; import { useAppStore } from '@/store/app-store'; import { FontSelector } from '@/components/shared'; import type { Theme } from '../shared/types'; -import type { SidebarStyle } from '@automaker/types'; interface AppearanceSectionProps { effectiveTheme: Theme; diff --git a/apps/ui/src/components/views/settings-view/cli-status/gemini-cli-status.tsx b/apps/ui/src/components/views/settings-view/cli-status/gemini-cli-status.tsx index 8e94e705..5fc3da32 100644 --- a/apps/ui/src/components/views/settings-view/cli-status/gemini-cli-status.tsx +++ b/apps/ui/src/components/views/settings-view/cli-status/gemini-cli-status.tsx @@ -1,7 +1,7 @@ import { Button } from '@/components/ui/button'; import { SkeletonPulse } from '@/components/ui/skeleton'; import { Spinner } from '@/components/ui/spinner'; -import { CheckCircle2, AlertCircle, RefreshCw, Key } from 'lucide-react'; +import { CheckCircle2, AlertCircle, RefreshCw } from 'lucide-react'; import { cn } from '@/lib/utils'; import type { CliStatus } from '../shared/types'; import { GeminiIcon } from '@/components/ui/provider-icon'; diff --git a/apps/ui/src/components/views/settings-view/components/settings-navigation.tsx b/apps/ui/src/components/views/settings-view/components/settings-navigation.tsx index 4017dc6b..ffe1c12c 100644 --- a/apps/ui/src/components/views/settings-view/components/settings-navigation.tsx +++ b/apps/ui/src/components/views/settings-view/components/settings-navigation.tsx @@ -3,7 +3,7 @@ import { ChevronDown, ChevronRight, X } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import type { Project } from '@/lib/electron'; -import type { NavigationItem, NavigationGroup } from '../config/navigation'; +import type { NavigationItem } from '../config/navigation'; import { GLOBAL_NAV_GROUPS } from '../config/navigation'; import type { SettingsViewId } from '../hooks/use-settings-view'; import { useAppStore } from '@/store/app-store'; @@ -189,7 +189,7 @@ function NavItemWithSubItems({ export function SettingsNavigation({ activeSection, - currentProject, + currentProject: _currentProject, onNavigate, isOpen = true, onClose, diff --git a/apps/ui/src/components/views/settings-view/hooks/use-cursor-permissions.ts b/apps/ui/src/components/views/settings-view/hooks/use-cursor-permissions.ts index a7327686..d641347b 100644 --- a/apps/ui/src/components/views/settings-view/hooks/use-cursor-permissions.ts +++ b/apps/ui/src/components/views/settings-view/hooks/use-cursor-permissions.ts @@ -1,4 +1,4 @@ -import { useState, useCallback, useEffect } from 'react'; +import { useState, useCallback } from 'react'; import { useCursorPermissionsQuery, type CursorPermissionsData } from '@/hooks/queries'; import { useApplyCursorProfile, useCopyCursorConfig } from '@/hooks/mutations'; diff --git a/apps/ui/src/components/views/settings-view/mcp-servers/components/mcp-server-header.tsx b/apps/ui/src/components/views/settings-view/mcp-servers/components/mcp-server-header.tsx index 8caf3bca..69277db5 100644 --- a/apps/ui/src/components/views/settings-view/mcp-servers/components/mcp-server-header.tsx +++ b/apps/ui/src/components/views/settings-view/mcp-servers/components/mcp-server-header.tsx @@ -1,7 +1,6 @@ import { Plug, RefreshCw, Download, Code, FileJson, Plus } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Spinner } from '@/components/ui/spinner'; -import { cn } from '@/lib/utils'; interface MCPServerHeaderProps { isRefreshing: boolean; diff --git a/apps/ui/src/components/views/settings-view/mcp-servers/dialogs/security-warning-dialog.tsx b/apps/ui/src/components/views/settings-view/mcp-servers/dialogs/security-warning-dialog.tsx index 62249814..a36f00b0 100644 --- a/apps/ui/src/components/views/settings-view/mcp-servers/dialogs/security-warning-dialog.tsx +++ b/apps/ui/src/components/views/settings-view/mcp-servers/dialogs/security-warning-dialog.tsx @@ -27,7 +27,7 @@ export function SecurityWarningDialog({ onOpenChange, onConfirm, serverType, - serverName, + _serverName, command, args, url, diff --git a/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx b/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx index d9adc44f..20420388 100644 --- a/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx +++ b/apps/ui/src/components/views/settings-view/model-defaults/phase-model-selector.tsx @@ -16,7 +16,6 @@ import type { ClaudeModelAlias, } from '@automaker/types'; import { - stripProviderPrefix, STANDALONE_CURSOR_MODELS, getModelGroup, isGroupSelected, @@ -567,7 +566,7 @@ export function PhaseModelSelector({ const isCopilotDisabled = disabledProviders.includes('copilot'); // Group models (filtering out disabled providers) - const { favorites, claude, cursor, codex, gemini, copilot, opencode } = useMemo(() => { + const { favorites, claude, codex, gemini, copilot, opencode } = useMemo(() => { const favs: typeof CLAUDE_MODELS = []; const cModels: typeof CLAUDE_MODELS = []; const curModels: typeof CURSOR_MODELS = []; @@ -651,7 +650,6 @@ export function PhaseModelSelector({ return { favorites: favs, claude: cModels, - cursor: curModels, codex: codModels, gemini: gemModels, copilot: copModels, @@ -2117,7 +2115,7 @@ export function PhaseModelSelector({ {opencodeSections.length > 0 && ( - {opencodeSections.map((section, sectionIndex) => ( + {opencodeSections.map((section, _sectionIndex) => (
{section.label} diff --git a/apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx b/apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx index 57b432d0..08f7da20 100644 --- a/apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx +++ b/apps/ui/src/components/views/settings-view/providers/claude-settings-tab.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - Claude settings form with CLI status and authentication state import { useAppStore } from '@/store/app-store'; import { useSetupStore } from '@/store/setup-store'; import { useCliStatus } from '../hooks/use-cli-status'; diff --git a/apps/ui/src/components/views/settings-view/providers/claude-settings-tab/subagents-section.tsx b/apps/ui/src/components/views/settings-view/providers/claude-settings-tab/subagents-section.tsx index d1f1bf76..1632e87a 100644 --- a/apps/ui/src/components/views/settings-view/providers/claude-settings-tab/subagents-section.tsx +++ b/apps/ui/src/components/views/settings-view/providers/claude-settings-tab/subagents-section.tsx @@ -24,7 +24,6 @@ export function SubagentsSection() { const { subagentsWithScope, isLoading: isLoadingAgents, - hasProject, refreshFilesystemAgents, } = useSubagents(); const { diff --git a/apps/ui/src/components/views/settings-view/providers/codex-settings-tab.tsx b/apps/ui/src/components/views/settings-view/providers/codex-settings-tab.tsx index 0b0936ce..3a4cda15 100644 --- a/apps/ui/src/components/views/settings-view/providers/codex-settings-tab.tsx +++ b/apps/ui/src/components/views/settings-view/providers/codex-settings-tab.tsx @@ -16,18 +16,13 @@ const logger = createLogger('CodexSettings'); export function CodexSettingsTab() { const { codexAutoLoadAgents, - codexSandboxMode, - codexApprovalPolicy, codexEnableWebSearch, codexEnableImages, enabledCodexModels, codexDefaultModel, setCodexAutoLoadAgents, - setCodexSandboxMode, - setCodexApprovalPolicy, setCodexEnableWebSearch, setCodexEnableImages, - setEnabledCodexModels, setCodexDefaultModel, toggleCodexModel, } = useAppStore(); diff --git a/apps/ui/src/components/views/settings-view/providers/cursor-settings-tab.tsx b/apps/ui/src/components/views/settings-view/providers/cursor-settings-tab.tsx index 2400285e..408b371e 100644 --- a/apps/ui/src/components/views/settings-view/providers/cursor-settings-tab.tsx +++ b/apps/ui/src/components/views/settings-view/providers/cursor-settings-tab.tsx @@ -44,7 +44,7 @@ export function CursorSettingsTab() { try { setCursorDefaultModel(model); toast.success('Default model updated'); - } catch (error) { + } catch { toast.error('Failed to update default model'); } finally { setIsSaving(false); @@ -55,7 +55,7 @@ export function CursorSettingsTab() { setIsSaving(true); try { toggleCursorModel(model, enabled); - } catch (error) { + } catch { toast.error('Failed to update models'); } finally { setIsSaving(false); diff --git a/apps/ui/src/components/views/settings-view/providers/opencode-model-configuration.tsx b/apps/ui/src/components/views/settings-view/providers/opencode-model-configuration.tsx index 6ecce79c..969f2fb8 100644 --- a/apps/ui/src/components/views/settings-view/providers/opencode-model-configuration.tsx +++ b/apps/ui/src/components/views/settings-view/providers/opencode-model-configuration.tsx @@ -23,13 +23,8 @@ import { OPENCODE_MODELS, OPENCODE_MODEL_CONFIG_MAP } from '@automaker/types'; import type { OpenCodeProviderInfo } from '../cli-status/opencode-cli-status'; import { OpenCodeIcon, - DeepSeekIcon, - QwenIcon, - NovaIcon, AnthropicIcon, OpenRouterIcon, - MistralIcon, - MetaIcon, GeminiIcon, OpenAIIcon, GrokIcon, @@ -226,8 +221,6 @@ export function OpencodeModelConfiguration({ const selectableStaticModelIds = allStaticModelIds.filter( (modelId) => modelId !== opencodeDefaultModel ); - const allDynamicModelIds = dynamicModels.map((model) => model.id); - const hasDynamicModels = allDynamicModelIds.length > 0; const staticSelectState = getSelectionState(selectableStaticModelIds, enabledOpencodeModels); // Order: Free tier first, then Claude, then others diff --git a/apps/ui/src/components/views/setup-view/steps/claude-setup-step.tsx b/apps/ui/src/components/views/setup-view/steps/claude-setup-step.tsx index 127b88ef..b864bfdb 100644 --- a/apps/ui/src/components/views/setup-view/steps/claude-setup-step.tsx +++ b/apps/ui/src/components/views/setup-view/steps/claude-setup-step.tsx @@ -38,11 +38,6 @@ interface ClaudeSetupStepProps { onSkip: () => void; } -interface ClaudeSetupContentProps { - /** Hide header and navigation for embedded use */ - embedded?: boolean; -} - type VerificationStatus = 'idle' | 'verifying' | 'verified' | 'error'; // Claude Setup Step @@ -272,12 +267,6 @@ export function ClaudeSetupStep({ onNext, onBack, onSkip }: ClaudeSetupStepProps const isApiKeyVerified = apiKeyVerificationStatus === 'verified'; const isReady = isCliVerified || isApiKeyVerified; - const getAuthMethodLabel = () => { - if (isApiKeyVerified) return 'API Key'; - if (isCliVerified) return 'Claude CLI'; - return null; - }; - // Helper to get status badge for CLI const getCliStatusBadge = () => { if (cliVerificationStatus === 'verified') { diff --git a/apps/ui/src/components/views/setup-view/steps/cli-setup-step.tsx b/apps/ui/src/components/views/setup-view/steps/cli-setup-step.tsx index 4a113211..cc17f390 100644 --- a/apps/ui/src/components/views/setup-view/steps/cli-setup-step.tsx +++ b/apps/ui/src/components/views/setup-view/steps/cli-setup-step.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - CLI setup wizard with step validation and setup store state import { useState, useEffect, useCallback } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; diff --git a/apps/ui/src/components/views/setup-view/steps/codex-setup-step.tsx b/apps/ui/src/components/views/setup-view/steps/codex-setup-step.tsx index 438ed57f..9d7f5750 100644 --- a/apps/ui/src/components/views/setup-view/steps/codex-setup-step.tsx +++ b/apps/ui/src/components/views/setup-view/steps/codex-setup-step.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - Codex setup wizard with Electron API integration import { useMemo, useCallback } from 'react'; import { useSetupStore } from '@/store/setup-store'; import { getElectronAPI } from '@/lib/electron'; diff --git a/apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx b/apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx index 1a934732..2f41fbc8 100644 --- a/apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx +++ b/apps/ui/src/components/views/setup-view/steps/providers-setup-step.tsx @@ -229,8 +229,6 @@ function ClaudeContent() { claudeAuthStatus?.method === 'api_key_env'; const isCliAuthenticated = claudeAuthStatus?.method === 'cli_authenticated'; - const isApiKeyAuthenticated = - claudeAuthStatus?.method === 'api_key' || claudeAuthStatus?.method === 'api_key_env'; const isReady = claudeCliStatus?.installed && claudeAuthStatus?.authenticated; return ( @@ -803,7 +801,6 @@ function CodexContent() { }; const isReady = codexCliStatus?.installed && codexAuthStatus?.authenticated; - const hasApiKey = !!apiKeys.openai || codexAuthStatus?.method === 'api_key'; return ( diff --git a/apps/ui/src/components/views/spec-view/components/edit-mode/features-section.tsx b/apps/ui/src/components/views/spec-view/components/edit-mode/features-section.tsx index ad82a4d7..b27ec3e4 100644 --- a/apps/ui/src/components/views/spec-view/components/edit-mode/features-section.tsx +++ b/apps/ui/src/components/views/spec-view/components/edit-mode/features-section.tsx @@ -32,6 +32,7 @@ function featureToInternal(feature: Feature): FeatureWithId { } function internalToFeature(internal: FeatureWithId): Feature { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { _id, _locationIds, ...feature } = internal; return feature; } diff --git a/apps/ui/src/components/views/spec-view/components/edit-mode/roadmap-section.tsx b/apps/ui/src/components/views/spec-view/components/edit-mode/roadmap-section.tsx index b13f35e7..c5d6ddd4 100644 --- a/apps/ui/src/components/views/spec-view/components/edit-mode/roadmap-section.tsx +++ b/apps/ui/src/components/views/spec-view/components/edit-mode/roadmap-section.tsx @@ -27,6 +27,7 @@ function phaseToInternal(phase: RoadmapPhase): PhaseWithId { } function internalToPhase(internal: PhaseWithId): RoadmapPhase { + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { _id, ...phase } = internal; return phase; } diff --git a/apps/ui/src/components/views/terminal-view.tsx b/apps/ui/src/components/views/terminal-view.tsx index df01e59f..f49117e9 100644 --- a/apps/ui/src/components/views/terminal-view.tsx +++ b/apps/ui/src/components/views/terminal-view.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; +import React, { useState, useEffect, useCallback, useRef } from 'react'; import { useNavigate } from '@tanstack/react-router'; import { createLogger } from '@automaker/utils/logger'; import { @@ -58,7 +58,7 @@ import { defaultDropAnimationSideEffects, } from '@dnd-kit/core'; import { cn } from '@/lib/utils'; -import { apiFetch, apiGet, apiPost, apiDeleteRaw, getAuthHeaders } from '@/lib/api-fetch'; +import { apiFetch, apiGet, apiPost, apiDeleteRaw } from '@/lib/api-fetch'; import { getApiKey } from '@/lib/http-api-client'; const logger = createLogger('Terminal'); @@ -244,7 +244,6 @@ export function TerminalView({ initialCwd, initialBranch, initialMode, nonce }: reorderTerminalTabs, moveTerminalToTab, setTerminalPanelFontSize, - setTerminalTabLayout, toggleTerminalMaximized, saveTerminalLayout, getPersistedTerminalLayout, diff --git a/apps/ui/src/components/views/terminal-view/terminal-panel.tsx b/apps/ui/src/components/views/terminal-view/terminal-panel.tsx index ce6359c8..94fa1940 100644 --- a/apps/ui/src/components/views/terminal-view/terminal-panel.tsx +++ b/apps/ui/src/components/views/terminal-view/terminal-panel.tsx @@ -45,7 +45,6 @@ import { matchesShortcutWithCode } from '@/hooks/use-keyboard-shortcuts'; import { getTerminalTheme, TERMINAL_FONT_OPTIONS, - DEFAULT_TERMINAL_FONT, getTerminalFontFamily, } from '@/config/terminal-themes'; import { DEFAULT_FONT_VALUE } from '@/config/ui-font-options'; @@ -102,7 +101,6 @@ interface TerminalPanelProps { type XTerminal = InstanceType; type XFitAddon = InstanceType; type XSearchAddon = InstanceType; -type XWebLinksAddon = InstanceType; export function TerminalPanel({ sessionId, @@ -285,8 +283,8 @@ export function TerminalPanel({ // - CSI sequences: \x1b[...letter // - OSC sequences: \x1b]...ST // - Other escape sequences: \x1b followed by various characters - // eslint-disable-next-line no-control-regex return text.replace( + // eslint-disable-next-line no-control-regex /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]|\x1b[>=<]|\x1b[78HM]|\x1b#[0-9]|\x1b./g, '' ); @@ -670,8 +668,6 @@ export function TerminalPanel({ while ((match = filePathRegex.exec(lineText)) !== null) { const fullMatch = match[1]; const filePath = match[2]; - const lineNum = match[3] ? parseInt(match[3], 10) : undefined; - const colNum = match[4] ? parseInt(match[4], 10) : undefined; // Skip common false positives (URLs, etc.) if ( diff --git a/apps/ui/src/hooks/mutations/use-github-mutations.ts b/apps/ui/src/hooks/mutations/use-github-mutations.ts index 29395cb3..29f8d1c2 100644 --- a/apps/ui/src/hooks/mutations/use-github-mutations.ts +++ b/apps/ui/src/hooks/mutations/use-github-mutations.ts @@ -45,8 +45,6 @@ interface ValidateIssueInput { * ``` */ export function useValidateIssue(projectPath: string) { - const queryClient = useQueryClient(); - return useMutation({ mutationFn: async (input: ValidateIssueInput) => { const { issue, model, thinkingLevel, reasoningEffort, comments, linkedPRs } = input; diff --git a/apps/ui/src/hooks/mutations/use-worktree-mutations.ts b/apps/ui/src/hooks/mutations/use-worktree-mutations.ts index ec8dd6e0..d31f0d42 100644 --- a/apps/ui/src/hooks/mutations/use-worktree-mutations.ts +++ b/apps/ui/src/hooks/mutations/use-worktree-mutations.ts @@ -93,7 +93,7 @@ export function useCommitWorktree() { } return result.result; }, - onSuccess: (_, { worktreePath }) => { + onSuccess: (_, { worktreePath: _worktreePath }) => { // Invalidate all worktree queries since we don't know the project path queryClient.invalidateQueries({ queryKey: ['worktrees'] }); toast.success('Changes committed'); diff --git a/apps/ui/src/hooks/use-electron-agent.ts b/apps/ui/src/hooks/use-electron-agent.ts index f2e3489a..be13069c 100644 --- a/apps/ui/src/hooks/use-electron-agent.ts +++ b/apps/ui/src/hooks/use-electron-agent.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - Electron IPC boundary typing with stream events and message queuing import { useState, useEffect, useCallback, useRef } from 'react'; import type { Message, StreamEvent } from '@/types/electron'; import { useMessageQueue } from './use-message-queue'; @@ -161,16 +161,15 @@ export function useElectronAgent({ ); // Message queue for queuing messages when agent is busy - const { queuedMessages, isProcessingQueue, addToQueue, clearQueue, processNext } = - useMessageQueue({ - onProcessNext: async (queuedMessage) => { - await sendMessageDirectly( - queuedMessage.content, - queuedMessage.images, - queuedMessage.textFiles - ); - }, - }); + const { queuedMessages, isProcessingQueue, clearQueue, processNext } = useMessageQueue({ + onProcessNext: async (queuedMessage) => { + await sendMessageDirectly( + queuedMessage.content, + queuedMessage.images, + queuedMessage.textFiles + ); + }, + }); // Initialize connection and load history useEffect(() => { diff --git a/apps/ui/src/hooks/use-event-recency.ts b/apps/ui/src/hooks/use-event-recency.ts index d3a56139..6faa3df1 100644 --- a/apps/ui/src/hooks/use-event-recency.ts +++ b/apps/ui/src/hooks/use-event-recency.ts @@ -6,7 +6,7 @@ * through WebSocket (indicating the connection is healthy). */ -import { useEffect, useCallback } from 'react'; +import { useCallback } from 'react'; import { create } from 'zustand'; /** diff --git a/apps/ui/src/hooks/use-responsive-kanban.ts b/apps/ui/src/hooks/use-responsive-kanban.ts index 3c1c5efb..5f153986 100644 --- a/apps/ui/src/hooks/use-responsive-kanban.ts +++ b/apps/ui/src/hooks/use-responsive-kanban.ts @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - responsive breakpoint logic with layout state calculations import { useState, useEffect, useLayoutEffect, useCallback, useRef } from 'react'; import { useAppStore } from '@/store/app-store'; diff --git a/apps/ui/src/hooks/use-settings-migration.ts b/apps/ui/src/hooks/use-settings-migration.ts index fb9c9c1c..bf63f7bd 100644 --- a/apps/ui/src/hooks/use-settings-migration.ts +++ b/apps/ui/src/hooks/use-settings-migration.ts @@ -53,17 +53,6 @@ interface MigrationState { error: string | null; } -/** - * localStorage keys that may contain settings to migrate - */ -const LOCALSTORAGE_KEYS = [ - 'automaker-storage', - 'automaker-setup', - 'worktree-panel-collapsed', - 'file-browser-recent-folders', - 'automaker:lastProjectDir', -] as const; - // NOTE: We intentionally do NOT clear any localStorage keys after migration. // This allows users to switch back to older versions of Automaker that relied on localStorage. // The `localStorageMigrated` flag in server settings prevents re-migration on subsequent app loads. @@ -136,7 +125,7 @@ export function parseLocalStorageSettings(): Partial | null { const cacheProjectCount = cached?.projects?.length ?? 0; logger.info(`[CACHE_LOADED] projects=${cacheProjectCount}, theme=${cached?.theme}`); return cached; - } catch (e) { + } catch { logger.warn('Failed to parse settings cache, falling back to old storage'); } } else { diff --git a/apps/ui/src/hooks/use-settings-sync.ts b/apps/ui/src/hooks/use-settings-sync.ts index 5ca61d40..c9729805 100644 --- a/apps/ui/src/hooks/use-settings-sync.ts +++ b/apps/ui/src/hooks/use-settings-sync.ts @@ -34,7 +34,6 @@ import { migratePhaseModelEntry, type GlobalSettings, type CursorModelId, - type OpencodeModelId, type CodexModelId, type GeminiModelId, type CopilotModelId, diff --git a/apps/ui/src/lib/electron.ts b/apps/ui/src/lib/electron.ts index 812def33..a98bc2c9 100644 --- a/apps/ui/src/lib/electron.ts +++ b/apps/ui/src/lib/electron.ts @@ -1037,7 +1037,8 @@ if (typeof window !== 'undefined') { } // Mock API for development/fallback when no backend is available -const getMockElectronAPI = (): ElectronAPI => { +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const _getMockElectronAPI = (): ElectronAPI => { return { ping: async () => 'pong (mock)', @@ -1456,7 +1457,7 @@ function createMockSetupAPI(): SetupAPI { }; }, - storeApiKey: async (provider: string, apiKey: string) => { + storeApiKey: async (provider: string, _apiKey: string) => { console.log('[Mock] Storing API key for:', provider); // In mock mode, we just pretend to store it (it's already in the app store) return { success: true }; @@ -1511,12 +1512,12 @@ function createMockSetupAPI(): SetupAPI { }; }, - onInstallProgress: (callback) => { + onInstallProgress: (_callback) => { // Mock progress events return () => {}; }, - onAuthProgress: (callback) => { + onAuthProgress: (_callback) => { // Mock auth events return () => {}; }, @@ -1955,7 +1956,7 @@ function createMockWorktreeAPI(): WorktreeAPI { }; }, - onDevServerLogEvent: (callback) => { + onDevServerLogEvent: (_callback) => { console.log('[Mock] Subscribing to dev server log events'); // Return unsubscribe function return () => { @@ -2007,7 +2008,7 @@ function createMockWorktreeAPI(): WorktreeAPI { }; }, - onInitScriptEvent: (callback) => { + onInitScriptEvent: (_callback) => { console.log('[Mock] Subscribing to init script events'); // Return unsubscribe function return () => { @@ -2067,7 +2068,7 @@ function createMockWorktreeAPI(): WorktreeAPI { }; }, - onTestRunnerEvent: (callback) => { + onTestRunnerEvent: (_callback) => { console.log('[Mock] Subscribing to test runner events'); // Return unsubscribe function return () => { @@ -2212,7 +2213,7 @@ function createMockAutoModeAPI(): AutoModeAPI { return { success: true, passes: true }; }, - resumeFeature: async (projectPath: string, featureId: string, useWorktrees?: boolean) => { + resumeFeature: async (projectPath: string, featureId: string, _useWorktrees?: boolean) => { if (mockRunningFeatures.has(featureId)) { return { success: false, @@ -2348,7 +2349,7 @@ function createMockAutoModeAPI(): AutoModeAPI { featureId: string, prompt: string, imagePaths?: string[], - useWorktrees?: boolean + _useWorktrees?: boolean ) => { if (mockRunningFeatures.has(featureId)) { return { @@ -2703,7 +2704,7 @@ function emitSpecRegenerationEvent(event: SpecRegenerationEvent) { async function simulateSpecCreation( projectPath: string, projectOverview: string, - generateFeatures = true + _generateFeatures = true ) { mockSpecRegenerationPhase = 'initialization'; emitSpecRegenerationEvent({ diff --git a/apps/ui/src/lib/file-picker.ts b/apps/ui/src/lib/file-picker.ts index e7c4631b..f3dc6bf9 100644 --- a/apps/ui/src/lib/file-picker.ts +++ b/apps/ui/src/lib/file-picker.ts @@ -62,7 +62,7 @@ export async function openDirectoryPicker(): Promise { + input.addEventListener('change', () => { changeEventFired = true; if (focusTimeout) { clearTimeout(focusTimeout); diff --git a/apps/ui/src/lib/utils.ts b/apps/ui/src/lib/utils.ts index a0dd8d44..d8cfff6d 100644 --- a/apps/ui/src/lib/utils.ts +++ b/apps/ui/src/lib/utils.ts @@ -1,7 +1,6 @@ import { clsx, type ClassValue } from 'clsx'; import { twMerge } from 'tailwind-merge'; import type { ModelAlias, ModelProvider } from '@/store/app-store'; -import { CODEX_MODEL_CONFIG_MAP, codexModelHasThinking } from '@automaker/types'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); diff --git a/apps/ui/src/main.ts b/apps/ui/src/main.ts index 4d093106..45744130 100644 --- a/apps/ui/src/main.ts +++ b/apps/ui/src/main.ts @@ -28,8 +28,6 @@ import { // Electron app bundle operations setElectronAppPaths, electronAppExists, - electronAppReadFileSync, - electronAppStatSync, electronAppStat, electronAppReadFile, // System path operations @@ -108,10 +106,6 @@ async function findAvailablePort(preferredPort: number): Promise { // Calculation: 4 columns × 280px + 3 gaps × 20px + 40px padding = 1220px board content // With sidebar expanded (288px): 1220 + 288 = 1508px // Minimum window dimensions - reduced to allow smaller windows since kanban now supports horizontal scrolling -const SIDEBAR_EXPANDED = 288; -const SIDEBAR_COLLAPSED = 64; - -const MIN_WIDTH_EXPANDED = 800; // Reduced - horizontal scrolling handles overflow const MIN_WIDTH_COLLAPSED = 600; // Reduced - horizontal scrolling handles overflow const MIN_HEIGHT = 500; // Reduced to allow more flexibility const DEFAULT_WIDTH = 1600; diff --git a/apps/ui/src/routes/__root.tsx b/apps/ui/src/routes/__root.tsx index 1bb006c5..283ff990 100644 --- a/apps/ui/src/routes/__root.tsx +++ b/apps/ui/src/routes/__root.tsx @@ -185,14 +185,10 @@ function RootLayoutContent() { // Load project settings when switching projects useProjectSettingsLoader(); - // Check if we're in compact mode (< 1240px) - const isCompact = useIsCompact(); - const isSetupRoute = location.pathname === '/setup'; const isLoginRoute = location.pathname === '/login'; const isLoggedOutRoute = location.pathname === '/logged-out'; const isDashboardRoute = location.pathname === '/dashboard'; - const isBoardRoute = location.pathname === '/board'; const isRootRoute = location.pathname === '/'; const [autoOpenStatus, setAutoOpenStatus] = useState(AUTO_OPEN_STATUS.idle); const autoOpenCandidate = selectAutoOpenProject(currentProject, projects, projectHistory); @@ -259,11 +255,8 @@ function RootLayoutContent() { // Get effective theme and fonts for the current project // Note: theme/fontFamilySans/fontFamilyMono are destructured above to ensure re-renders when they change - // eslint-disable-next-line @typescript-eslint/no-unused-vars void theme; // Used for subscription - // eslint-disable-next-line @typescript-eslint/no-unused-vars void fontFamilySans; // Used for subscription - // eslint-disable-next-line @typescript-eslint/no-unused-vars void fontFamilyMono; // Used for subscription const effectiveFontSans = getEffectiveFontSans(); const effectiveFontMono = getEffectiveFontMono(); diff --git a/apps/ui/src/store/app-store.ts b/apps/ui/src/store/app-store.ts index d1b47cd3..6c73d5cc 100644 --- a/apps/ui/src/store/app-store.ts +++ b/apps/ui/src/store/app-store.ts @@ -1731,7 +1731,7 @@ export const useAppStore = create()((set, get) => ({ }, upsertAndSetCurrentProject: (path, name, theme) => { - const { projects, trashedProjects, currentProject, theme: globalTheme } = get(); + const { projects, trashedProjects } = get(); const existingProject = projects.find((p) => p.path === path); let project: Project; @@ -2108,6 +2108,7 @@ export const useAppStore = create()((set, get) => ({ let newOverrides: typeof currentOverrides; if (entry === null) { // Remove the override (use global) + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { [phase]: _, ...rest } = currentOverrides; newOverrides = rest; } else { @@ -4367,6 +4368,7 @@ export const useAppStore = create()((set, get) => ({ clearInitScriptState: (projectPath, branch) => { const key = `${projectPath}::${branch}`; + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { [key]: _, ...rest } = get().initScriptState; set({ initScriptState: rest }); }, diff --git a/apps/ui/src/store/notifications-store.ts b/apps/ui/src/store/notifications-store.ts index 278f645d..8dfe13d7 100644 --- a/apps/ui/src/store/notifications-store.ts +++ b/apps/ui/src/store/notifications-store.ts @@ -62,7 +62,7 @@ const initialState: NotificationsState = { // ============================================================================ export const useNotificationsStore = create( - (set, get) => ({ + (set, _get) => ({ ...initialState, // Data management diff --git a/apps/ui/src/store/test-runners-store.ts b/apps/ui/src/store/test-runners-store.ts index 29a4cb6f..b763c15a 100644 --- a/apps/ui/src/store/test-runners-store.ts +++ b/apps/ui/src/store/test-runners-store.ts @@ -155,6 +155,7 @@ export const useTestRunnersStore = create const finishedAt = new Date().toISOString(); // Remove from active sessions since it's no longer running + // eslint-disable-next-line @typescript-eslint/no-unused-vars const { [session.worktreePath]: _, ...remainingActive } = state.activeSessionByWorktree; return { diff --git a/apps/ui/tests/features/feature-manual-review-flow.spec.ts b/apps/ui/tests/features/feature-manual-review-flow.spec.ts index be776d60..10c044d9 100644 --- a/apps/ui/tests/features/feature-manual-review-flow.spec.ts +++ b/apps/ui/tests/features/feature-manual-review-flow.spec.ts @@ -62,19 +62,6 @@ test.describe('Feature Manual Review Flow', () => { const featureDir = path.join(automakerDir, 'features', featureId); fs.mkdirSync(featureDir, { recursive: true }); - const feature = { - id: featureId, - description: 'Test feature for manual review flow', - category: 'test', - status: 'waiting_approval', - skipTests: true, - model: 'sonnet', - thinkingLevel: 'none', - createdAt: new Date().toISOString(), - branchName: '', - priority: 2, - }; - // Note: Feature is created via HTTP API in the test itself, not in beforeAll // This ensures the feature exists when the board view loads it }); diff --git a/apps/ui/tests/projects/new-project-creation.spec.ts b/apps/ui/tests/projects/new-project-creation.spec.ts index 07d5bc3b..018068c4 100644 --- a/apps/ui/tests/projects/new-project-creation.spec.ts +++ b/apps/ui/tests/projects/new-project-creation.spec.ts @@ -6,14 +6,12 @@ import { test, expect } from '@playwright/test'; import * as fs from 'fs'; -import * as path from 'path'; import { createTempDirPath, cleanupTempDir, setupWelcomeView, authenticateForTests, handleLoginScreenIfPresent, - waitForNetworkIdle, } from '../utils'; const TEST_TEMP_DIR = createTempDirPath('project-creation-test'); diff --git a/apps/ui/tests/projects/open-existing-project.spec.ts b/apps/ui/tests/projects/open-existing-project.spec.ts index 4d8db61f..8dc1fce8 100644 --- a/apps/ui/tests/projects/open-existing-project.spec.ts +++ b/apps/ui/tests/projects/open-existing-project.spec.ts @@ -17,7 +17,6 @@ import { setupWelcomeView, authenticateForTests, handleLoginScreenIfPresent, - waitForNetworkIdle, } from '../utils'; // Create unique temp dir for this test run diff --git a/apps/ui/tests/utils/project/setup.ts b/apps/ui/tests/utils/project/setup.ts index 344e84fe..6ce62e73 100644 --- a/apps/ui/tests/utils/project/setup.ts +++ b/apps/ui/tests/utils/project/setup.ts @@ -620,7 +620,7 @@ export async function setupMockMultipleProjects( projectCount: number = 3 ): Promise { await page.addInitScript((count: number) => { - const mockProjects = []; + const mockProjects: TestProject[] = []; for (let i = 0; i < count; i++) { mockProjects.push({ id: `test-project-${i + 1}`,