From affbc48cbea29bd7ab056f542f7bfd1937b55c16 Mon Sep 17 00:00:00 2001 From: AndyMik90 Date: Thu, 18 Dec 2025 14:49:07 +0100 Subject: [PATCH] fix ESLint warnings and failing tests --- auto-claude-ui/e2e/flows.e2e.ts | 10 +- auto-claude-ui/e2e/playwright.config.ts | 2 +- auto-claude-ui/eslint.config.mjs | 2 +- .../__tests__/integration/ipc-bridge.test.ts | 4 +- auto-claude-ui/src/__tests__/setup.ts | 2 +- .../src/main/__tests__/ipc-handlers.test.ts | 28 ++ .../main/__tests__/ipc-handlers.test.ts.bak | 463 ------------------ .../src/main/agent/agent-manager.ts | 15 +- .../src/main/agent/agent-process.ts | 29 +- auto-claude-ui/src/main/agent/agent-queue.ts | 19 - auto-claude-ui/src/main/app-updater.ts | 48 +- .../src/main/changelog/changelog-service.ts | 2 +- .../src/main/changelog/generator.ts | 2 +- .../src/main/changelog/git-integration.ts | 2 +- auto-claude-ui/src/main/changelog/parser.ts | 2 +- .../src/main/changelog/version-suggester.ts | 4 +- .../src/main/claude-profile-manager.ts | 12 +- .../src/main/claude-profile/profile-scorer.ts | 6 +- .../src/main/claude-profile/profile-utils.ts | 2 +- .../src/main/claude-profile/usage-monitor.ts | 35 +- auto-claude-ui/src/main/docker-service.ts | 8 +- auto-claude-ui/src/main/index.ts | 20 +- auto-claude-ui/src/main/insights-service.ts | 5 +- .../src/main/insights/insights-executor.ts | 2 +- .../ipc-handlers/agent-events-handlers.ts | 11 +- .../main/ipc-handlers/app-update-handlers.ts | 4 +- .../main/ipc-handlers/changelog-handlers.ts | 3 +- .../context/memory-data-handlers.ts | 2 +- .../context/memory-status-handlers.ts | 2 +- .../context/project-context-handlers.ts | 7 +- .../src/main/ipc-handlers/env-handlers.ts | 14 +- .../ipc-handlers/github/oauth-handlers.ts | 4 +- .../ipc-handlers/github/release-handlers.ts | 2 +- .../ipc-handlers/ideation/session-manager.ts | 2 +- .../ipc-handlers/ideation/task-converter.ts | 2 +- auto-claude-ui/src/main/ipc-handlers/index.ts | 2 +- .../src/main/ipc-handlers/linear-handlers.ts | 12 +- .../src/main/ipc-handlers/project-handlers.ts | 28 +- .../src/main/ipc-handlers/roadmap-handlers.ts | 1 - .../main/ipc-handlers/settings-handlers.ts | 16 +- .../ipc-handlers/task/archive-handlers.ts | 8 +- .../main/ipc-handlers/task/crud-handlers.ts | 20 +- .../ipc-handlers/task/execution-handlers.ts | 40 +- .../ipc-handlers/task/worktree-handlers.ts | 24 +- .../main/ipc-handlers/terminal-handlers.ts | 16 +- auto-claude-ui/src/main/log-service.ts | 33 +- .../src/main/project-initializer.ts | 4 +- auto-claude-ui/src/main/project-store.ts | 16 +- auto-claude-ui/src/main/python-env-manager.ts | 23 +- .../src/main/rate-limit-detector.ts | 16 +- auto-claude-ui/src/main/task-log-service.ts | 14 +- .../src/main/terminal-name-generator.ts | 2 +- .../src/main/terminal-session-store.ts | 10 +- .../terminal/claude-integration-handler.ts | 27 +- .../src/main/terminal/pty-daemon-client.ts | 40 +- .../src/main/terminal/pty-daemon.ts | 22 +- .../src/main/terminal/pty-manager.ts | 6 +- .../src/main/terminal/session-handler.ts | 4 +- .../src/main/terminal/session-persistence.ts | 14 +- .../src/main/terminal/terminal-lifecycle.ts | 5 +- auto-claude-ui/src/main/title-generator.ts | 10 +- .../src/main/updater/file-operations.ts | 2 +- .../src/main/updater/http-client.ts | 2 +- .../src/main/updater/update-installer.ts | 2 +- .../src/preload/api/modules/ipc-utils.ts | 6 +- auto-claude-ui/src/preload/api/project-api.ts | 15 +- .../src/preload/api/terminal-api.ts | 17 +- auto-claude-ui/src/renderer/App.tsx | 4 +- .../renderer/__tests__/TaskEditDialog.test.ts | 2 +- .../renderer/components/AddFeatureDialog.tsx | 4 +- .../components/AppUpdateNotification.tsx | 6 +- .../renderer/components/EnvConfigModal.tsx | 2 +- .../src/renderer/components/GitSetupModal.tsx | 2 +- .../components/ProactiveSwapListener.tsx | 12 +- .../renderer/components/ProjectSettings.tsx | 4 +- .../src/renderer/components/Sidebar.tsx | 8 +- .../src/renderer/components/Terminal.tsx | 2 +- .../src/renderer/components/TerminalGrid.tsx | 20 +- .../src/renderer/components/WelcomeScreen.tsx | 2 +- .../src/renderer/components/Worktrees.tsx | 10 +- .../RoadmapGenerationProgress.test.tsx | 4 +- .../components/changelog/Changelog.tsx | 2 +- .../changelog/hooks/useChangelog.ts | 16 +- .../changelog/hooks/useImageUpload.ts | 2 +- .../ideation/GenerationProgressScreen.tsx | 2 +- .../renderer/components/ideation/IdeaCard.tsx | 3 +- .../components/ideation/IdeationFilters.tsx | 3 +- .../components/ideation/IdeationHeader.tsx | 2 +- .../linear-import/hooks/useLinearIssues.ts | 8 +- .../project-settings/AutoBuildIntegration.tsx | 2 +- .../project-settings/GeneralSettings.tsx | 2 +- .../project-settings/GitHubOAuthFlow.tsx | 7 +- .../project-settings/IntegrationSettings.tsx | 1 + .../project-settings/ProjectSettings.tsx | 2 +- .../renderer/components/roadmap/PhaseCard.tsx | 2 +- .../components/settings/AdvancedSettings.tsx | 10 +- .../settings/ProjectSettingsContent.tsx | 8 +- .../settings/common/InitializationGuard.tsx | 2 +- .../integrations/GitHubIntegration.tsx | 8 +- .../task-detail/TaskDetailPanel.tsx | 16 +- .../task-detail/hooks/useTaskDetail.ts | 20 +- .../task-review/WorkspaceStatus.tsx | 2 +- .../components/terminal/TaskSelector.tsx | 5 +- .../components/terminal/TerminalTitle.tsx | 2 +- .../components/terminal/useAutoNaming.ts | 2 +- .../components/terminal/useTerminalEvents.ts | 2 +- .../renderer/components/terminal/useXterm.ts | 1 - .../src/renderer/hooks/useProjectSettings.ts | 2 +- .../src/renderer/lib/browser-mock.ts | 9 +- .../src/renderer/lib/buffer-persistence.ts | 18 +- .../src/renderer/lib/mocks/changelog-mock.ts | 4 +- .../renderer/lib/mocks/infrastructure-mock.ts | 8 +- .../src/renderer/lib/mocks/insights-mock.ts | 6 +- .../renderer/lib/mocks/integration-mock.ts | 2 +- .../src/renderer/lib/mocks/roadmap-mock.ts | 4 +- .../src/renderer/lib/mocks/settings-mock.ts | 2 +- .../src/renderer/lib/mocks/task-mock.ts | 4 +- .../src/renderer/lib/mocks/terminal-mock.ts | 12 +- .../src/renderer/lib/scroll-controller.ts | 8 +- .../renderer/lib/terminal-buffer-manager.ts | 2 +- .../src/renderer/lib/webgl-context-manager.ts | 18 +- .../src/renderer/stores/changelog-store.ts | 4 +- .../src/renderer/stores/context-store.ts | 4 +- .../src/renderer/stores/ideation-store.ts | 2 +- .../src/renderer/stores/insights-store.ts | 2 +- auto-claude-ui/src/shared/types/ipc.ts | 1 - .../src/shared/utils/debug-logger.ts | 2 +- 127 files changed, 527 insertions(+), 1035 deletions(-) delete mode 100644 auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts.bak diff --git a/auto-claude-ui/e2e/flows.e2e.ts b/auto-claude-ui/e2e/flows.e2e.ts index 1702d5ee..64dab8a4 100644 --- a/auto-claude-ui/e2e/flows.e2e.ts +++ b/auto-claude-ui/e2e/flows.e2e.ts @@ -9,7 +9,7 @@ * To run: npx playwright test --config=e2e/playwright.config.ts */ import { test, expect, _electron as electron, ElectronApplication, Page } from '@playwright/test'; -import { mkdirSync, rmSync, existsSync, writeFileSync } from 'fs'; +import { mkdirSync, rmSync, existsSync, writeFileSync, readFileSync } from 'fs'; import path from 'path'; // Test data directory @@ -269,13 +269,13 @@ test.describe('E2E Flow Verification (Mock-based)', () => { 'implementation_plan.json' ); - const plan = JSON.parse(require('fs').readFileSync(planPath, 'utf-8')); + const plan = JSON.parse(readFileSync(planPath, 'utf-8')); plan.phases[0].chunks[0].status = 'in_progress'; writeFileSync(planPath, JSON.stringify(plan, null, 2)); // Verify update - const updatedPlan = JSON.parse(require('fs').readFileSync(planPath, 'utf-8')); + const updatedPlan = JSON.parse(readFileSync(planPath, 'utf-8')); expect(updatedPlan.phases[0].chunks[0].status).toBe('in_progress'); cleanupTestEnvironment(); @@ -298,7 +298,7 @@ test.describe('E2E Flow Verification (Mock-based)', () => { expect(existsSync(qaReportPath)).toBe(true); - const content = require('fs').readFileSync(qaReportPath, 'utf-8'); + const content = readFileSync(qaReportPath, 'utf-8'); expect(content).toContain('APPROVED'); cleanupTestEnvironment(); @@ -324,7 +324,7 @@ test.describe('E2E Flow Verification (Mock-based)', () => { expect(existsSync(fixRequestPath)).toBe(true); - const content = require('fs').readFileSync(fixRequestPath, 'utf-8'); + const content = readFileSync(fixRequestPath, 'utf-8'); expect(content).toContain('REJECTED'); expect(content).toContain('Needs more tests'); diff --git a/auto-claude-ui/e2e/playwright.config.ts b/auto-claude-ui/e2e/playwright.config.ts index c4d85477..54648c37 100644 --- a/auto-claude-ui/e2e/playwright.config.ts +++ b/auto-claude-ui/e2e/playwright.config.ts @@ -1,7 +1,7 @@ /** * Playwright configuration for Electron E2E tests */ -import { defineConfig, devices } from '@playwright/test'; +import { defineConfig } from '@playwright/test'; export default defineConfig({ testDir: '.', diff --git a/auto-claude-ui/eslint.config.mjs b/auto-claude-ui/eslint.config.mjs index f3e92cda..d90ae77f 100644 --- a/auto-claude-ui/eslint.config.mjs +++ b/auto-claude-ui/eslint.config.mjs @@ -31,7 +31,7 @@ export default tseslint.config( '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'warn', - '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }], '@typescript-eslint/no-empty-object-type': 'off', '@typescript-eslint/no-unsafe-function-type': 'off', diff --git a/auto-claude-ui/src/__tests__/integration/ipc-bridge.test.ts b/auto-claude-ui/src/__tests__/integration/ipc-bridge.test.ts index 80d4532d..641f8e96 100644 --- a/auto-claude-ui/src/__tests__/integration/ipc-bridge.test.ts +++ b/auto-claude-ui/src/__tests__/integration/ipc-bridge.test.ts @@ -3,7 +3,6 @@ * Tests IPC messages flow between main and renderer */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { EventEmitter } from 'events'; // Mock ipcRenderer for renderer-side tests const mockIpcRenderer = { @@ -285,7 +284,8 @@ describe('IPC Bridge Integration', () => { const getAppVersion = electronAPI['getAppVersion'] as () => Promise; await getAppVersion(); - expect(mockIpcRenderer.invoke).toHaveBeenCalledWith('app:version'); + // getAppVersion now uses the app-update channel (from AppUpdateAPI which is spread last) + expect(mockIpcRenderer.invoke).toHaveBeenCalledWith('app-update:get-version'); }); }); }); diff --git a/auto-claude-ui/src/__tests__/setup.ts b/auto-claude-ui/src/__tests__/setup.ts index 62621712..9129c5e9 100644 --- a/auto-claude-ui/src/__tests__/setup.ts +++ b/auto-claude-ui/src/__tests__/setup.ts @@ -12,7 +12,7 @@ export const TEST_DATA_DIR = '/tmp/auto-claude-ui-tests'; beforeEach(() => { // Use a unique subdirectory per test to avoid race conditions in parallel tests const testId = `test-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; - const testDir = path.join(TEST_DATA_DIR, testId); + const _testDir = path.join(TEST_DATA_DIR, testId); try { if (existsSync(TEST_DATA_DIR)) { diff --git a/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts b/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts index c4981ac2..8025a905 100644 --- a/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts +++ b/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts @@ -11,6 +11,34 @@ import path from 'path'; const TEST_DIR = '/tmp/ipc-handlers-test'; const TEST_PROJECT_PATH = path.join(TEST_DIR, 'test-project'); +// Mock electron-updater before importing +vi.mock('electron-updater', () => ({ + autoUpdater: { + autoDownload: true, + autoInstallOnAppQuit: true, + on: vi.fn(), + checkForUpdates: vi.fn(() => Promise.resolve(null)), + downloadUpdate: vi.fn(() => Promise.resolve()), + quitAndInstall: vi.fn() + } +})); + +// Mock @electron-toolkit/utils before importing +vi.mock('@electron-toolkit/utils', () => ({ + is: { + dev: true, + windows: process.platform === 'win32', + macos: process.platform === 'darwin', + linux: process.platform === 'linux' + }, + electronApp: { + setAppUserModelId: vi.fn() + }, + optimizer: { + watchWindowShortcuts: vi.fn() + } +})); + // Mock modules before importing vi.mock('electron', () => { const mockIpcMain = new (class extends EventEmitter { diff --git a/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts.bak b/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts.bak deleted file mode 100644 index fd3ba925..00000000 --- a/auto-claude-ui/src/main/__tests__/ipc-handlers.test.ts.bak +++ /dev/null @@ -1,463 +0,0 @@ -/** - * Unit tests for IPC handlers - * Tests all IPC communication patterns between main and renderer processes - */ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; -import { EventEmitter } from 'events'; -import { mkdirSync, writeFileSync, rmSync, existsSync } from 'fs'; -import path from 'path'; - -// Test data directory -const TEST_DIR = '/tmp/ipc-handlers-test'; -const TEST_PROJECT_PATH = path.join(TEST_DIR, 'test-project'); - -// Mock modules before importing -vi.mock('electron', () => { - const mockIpcMain = new (class extends EventEmitter { - private handlers: Map = new Map(); - - handle(channel: string, handler: Function): void { - this.handlers.set(channel, handler); - } - - removeHandler(channel: string): void { - this.handlers.delete(channel); - } - - async invokeHandler(channel: string, event: unknown, ...args: unknown[]): Promise { - const handler = this.handlers.get(channel); - if (handler) { - return handler(event, ...args); - } - throw new Error(`No handler for channel: ${channel}`); - } - - getHandler(channel: string): Function | undefined { - return this.handlers.get(channel); - } - })(); - - return { - app: { - getPath: vi.fn((name: string) => { - if (name === 'userData') return path.join(TEST_DIR, 'userData'); - return TEST_DIR; - }), - getVersion: vi.fn(() => '0.1.0'), - isPackaged: false - }, - ipcMain: mockIpcMain, - dialog: { - showOpenDialog: vi.fn(() => Promise.resolve({ canceled: false, filePaths: [TEST_PROJECT_PATH] })) - }, - BrowserWindow: class { - webContents = { send: vi.fn() }; - } - }; -}); - -// Setup test project structure -function setupTestProject(): void { - mkdirSync(TEST_PROJECT_PATH, { recursive: true }); - mkdirSync(path.join(TEST_PROJECT_PATH, 'auto-claude', 'specs'), { recursive: true }); -} - -// Cleanup test directories -function cleanupTestDirs(): void { - if (existsSync(TEST_DIR)) { - rmSync(TEST_DIR, { recursive: true, force: true }); - } -} - -describe('IPC Handlers', () => { - let ipcMain: EventEmitter & { - handlers: Map; - invokeHandler: (channel: string, event: unknown, ...args: unknown[]) => Promise; - getHandler: (channel: string) => Function | undefined; - }; - let mockMainWindow: { webContents: { send: ReturnType } }; - let mockAgentManager: EventEmitter & { - startSpecCreation: ReturnType; - startTaskExecution: ReturnType; - startQAProcess: ReturnType; - killTask: ReturnType; - configure: ReturnType; - }; - let mockTerminalManager: { - create: ReturnType; - destroy: ReturnType; - write: ReturnType; - resize: ReturnType; - invokeClaude: ReturnType; - killAll: ReturnType; - }; - - beforeEach(async () => { - cleanupTestDirs(); - setupTestProject(); - mkdirSync(path.join(TEST_DIR, 'userData', 'store'), { recursive: true }); - - // Get mocked ipcMain - const electron = await import('electron'); - ipcMain = electron.ipcMain as unknown as typeof ipcMain; - - // Create mock window - mockMainWindow = { - webContents: { send: vi.fn() } - }; - - // Create mock agent manager - mockAgentManager = Object.assign(new EventEmitter(), { - startSpecCreation: vi.fn(), - startTaskExecution: vi.fn(), - startQAProcess: vi.fn(), - killTask: vi.fn(), - configure: vi.fn() - }); - - // Create mock terminal manager - mockTerminalManager = { - create: vi.fn(() => Promise.resolve({ success: true })), - destroy: vi.fn(() => Promise.resolve({ success: true })), - write: vi.fn(), - resize: vi.fn(), - invokeClaude: vi.fn(), - killAll: vi.fn(() => Promise.resolve()) - }; - - // Need to reset modules to re-register handlers - vi.resetModules(); - }); - - afterEach(() => { - cleanupTestDirs(); - vi.clearAllMocks(); - }); - - describe('project:add handler', () => { - it('should return error for non-existent path', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('project:add', {}, '/nonexistent/path'); - - expect(result).toEqual({ - success: false, - error: 'Directory does not exist' - }); - }); - - it('should successfully add an existing project', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - - expect(result).toHaveProperty('success', true); - expect(result).toHaveProperty('data'); - const data = (result as { data: { path: string; name: string } }).data; - expect(data.path).toBe(TEST_PROJECT_PATH); - expect(data.name).toBe('test-project'); - }); - - it('should return existing project if already added', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add project twice - const result1 = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const result2 = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - - const data1 = (result1 as { data: { id: string } }).data; - const data2 = (result2 as { data: { id: string } }).data; - expect(data1.id).toBe(data2.id); - }); - }); - - describe('project:list handler', () => { - it('should return empty array when no projects', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('project:list', {}); - - expect(result).toEqual({ - success: true, - data: [] - }); - }); - - it('should return all added projects', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project - await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - - const result = await ipcMain.invokeHandler('project:list', {}); - - expect(result).toHaveProperty('success', true); - const data = (result as { data: unknown[] }).data; - expect(data).toHaveLength(1); - }); - }); - - describe('project:remove handler', () => { - it('should return false for non-existent project', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('project:remove', {}, 'nonexistent-id'); - - expect(result).toEqual({ success: false }); - }); - - it('should successfully remove an existing project', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project first - const addResult = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const projectId = (addResult as { data: { id: string } }).data.id; - - // Remove it - const removeResult = await ipcMain.invokeHandler('project:remove', {}, projectId); - - expect(removeResult).toEqual({ success: true }); - - // Verify it's gone - const listResult = await ipcMain.invokeHandler('project:list', {}); - const data = (listResult as { data: unknown[] }).data; - expect(data).toHaveLength(0); - }); - }); - - describe('project:updateSettings handler', () => { - it('should return error for non-existent project', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler( - 'project:updateSettings', - {}, - 'nonexistent-id', - { parallelEnabled: true } - ); - - expect(result).toEqual({ - success: false, - error: 'Project not found' - }); - }); - - it('should successfully update project settings', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project first - const addResult = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const projectId = (addResult as { data: { id: string } }).data.id; - - // Update settings - const result = await ipcMain.invokeHandler( - 'project:updateSettings', - {}, - projectId, - { parallelEnabled: true, maxWorkers: 4 } - ); - - expect(result).toEqual({ success: true }); - }); - }); - - describe('task:list handler', () => { - it('should return empty array for project with no specs', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project first - const addResult = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const projectId = (addResult as { data: { id: string } }).data.id; - - const result = await ipcMain.invokeHandler('task:list', {}, projectId); - - expect(result).toEqual({ - success: true, - data: [] - }); - }); - - it('should return tasks when specs exist', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project first - const addResult = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const projectId = (addResult as { data: { id: string } }).data.id; - - // Create a spec directory with implementation plan - const specDir = path.join(TEST_PROJECT_PATH, 'auto-claude', 'specs', '001-test-feature'); - mkdirSync(specDir, { recursive: true }); - writeFileSync(path.join(specDir, 'implementation_plan.json'), JSON.stringify({ - feature: 'Test Feature', - workflow_type: 'feature', - services_involved: [], - phases: [{ - phase: 1, - name: 'Test Phase', - type: 'implementation', - subtasks: [{ id: 'subtask-1', description: 'Test subtask', status: 'pending' }] - }], - final_acceptance: [], - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - spec_file: '' - })); - - const result = await ipcMain.invokeHandler('task:list', {}, projectId); - - expect(result).toHaveProperty('success', true); - const data = (result as { data: unknown[] }).data; - expect(data).toHaveLength(1); - }); - }); - - describe('task:create handler', () => { - it('should return error for non-existent project', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler( - 'task:create', - {}, - 'nonexistent-id', - 'Test Task', - 'Test description' - ); - - expect(result).toEqual({ - success: false, - error: 'Project not found' - }); - }); - - it('should create task and start spec creation', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - // Add a project first - const addResult = await ipcMain.invokeHandler('project:add', {}, TEST_PROJECT_PATH); - const projectId = (addResult as { data: { id: string } }).data.id; - - const result = await ipcMain.invokeHandler( - 'task:create', - {}, - projectId, - 'Test Task', - 'Test description' - ); - - expect(result).toHaveProperty('success', true); - expect(mockAgentManager.startSpecCreation).toHaveBeenCalled(); - }); - }); - - describe('settings:get handler', () => { - it('should return default settings when no settings file exists', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('settings:get', {}); - - expect(result).toHaveProperty('success', true); - const data = (result as { data: { theme: string } }).data; - expect(data).toHaveProperty('theme', 'system'); - }); - }); - - describe('settings:save handler', () => { - it('should save settings successfully', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler( - 'settings:save', - {}, - { theme: 'dark', defaultModel: 'opus' } - ); - - expect(result).toEqual({ success: true }); - - // Verify settings were saved - const getResult = await ipcMain.invokeHandler('settings:get', {}); - const data = (getResult as { data: { theme: string; defaultModel: string } }).data; - expect(data.theme).toBe('dark'); - expect(data.defaultModel).toBe('opus'); - }); - - it('should configure agent manager when paths change', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - await ipcMain.invokeHandler( - 'settings:save', - {}, - { pythonPath: '/usr/bin/python3' } - ); - - expect(mockAgentManager.configure).toHaveBeenCalledWith('/usr/bin/python3', undefined); - }); - }); - - describe('app:version handler', () => { - it('should return app version', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - const result = await ipcMain.invokeHandler('app:version', {}); - - expect(result).toBe('0.1.0'); - }); - }); - - describe('Agent Manager event forwarding', () => { - it('should forward log events to renderer', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - mockAgentManager.emit('log', 'task-1', 'Test log message'); - - expect(mockMainWindow.webContents.send).toHaveBeenCalledWith( - 'task:log', - 'task-1', - 'Test log message' - ); - }); - - it('should forward error events to renderer', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - mockAgentManager.emit('error', 'task-1', 'Test error message'); - - expect(mockMainWindow.webContents.send).toHaveBeenCalledWith( - 'task:error', - 'task-1', - 'Test error message' - ); - }); - - it('should forward exit events with status change', async () => { - const { setupIpcHandlers } = await import('../ipc-handlers'); - setupIpcHandlers(mockAgentManager as never, mockTerminalManager as never, () => mockMainWindow as never); - - mockAgentManager.emit('exit', 'task-1', 0); - - expect(mockMainWindow.webContents.send).toHaveBeenCalledWith( - 'task:statusChange', - 'task-1', - 'ai_review' - ); - }); - }); -}); diff --git a/auto-claude-ui/src/main/agent/agent-manager.ts b/auto-claude-ui/src/main/agent/agent-manager.ts index ef68171b..aee9bafe 100644 --- a/auto-claude-ui/src/main/agent/agent-manager.ts +++ b/auto-claude-ui/src/main/agent/agent-manager.ts @@ -6,9 +6,6 @@ import { AgentEvents } from './agent-events'; import { AgentProcessManager } from './agent-process'; import { AgentQueueManager } from './agent-queue'; import { - AgentManagerEvents, - ExecutionProgressData, - ProcessType, SpecCreationMetadata, TaskExecutionOptions, IdeationConfig @@ -44,8 +41,7 @@ export class AgentManager extends EventEmitter { this.queueManager = new AgentQueueManager(this.state, this.events, this.processManager, this); // Listen for auto-swap restart events - this.on('auto-swap-restart-task', (taskId: string, newProfileId: string) => { - console.log('[AgentManager] Auto-swap restart:', taskId, newProfileId); + this.on('auto-swap-restart-task', (taskId: string, _newProfileId: string) => { this.restartTask(taskId); }); @@ -64,14 +60,12 @@ export class AgentManager extends EventEmitter { // If task completed successfully, always clean up if (code === 0) { this.taskExecutionContext.delete(taskId); - console.log('[AgentManager] Cleaned up context for completed task:', taskId); return; } // If task failed and hit max retries, clean up if (context.swapCount >= 2) { this.taskExecutionContext.delete(taskId); - console.log('[AgentManager] Cleaned up context for max-retry task:', taskId); } // Otherwise keep context for potential restart }, 1000); // Delay to allow restart logic to run first @@ -142,21 +136,16 @@ export class AgentManager extends EventEmitter { specId: string, options: TaskExecutionOptions = {} ): void { - console.log('[AgentManager] startTaskExecution called for:', taskId, specId); - const autoBuildSource = this.processManager.getAutoBuildSourcePath(); if (!autoBuildSource) { - console.log('[AgentManager] ERROR: Auto-build source path not found'); this.emit('error', taskId, 'Auto-build source path not found. Please configure it in App Settings.'); return; } const runPath = path.join(autoBuildSource, 'run.py'); - console.log('[AgentManager] runPath:', runPath); if (!existsSync(runPath)) { - console.log('[AgentManager] ERROR: Run script not found at:', runPath); this.emit('error', taskId, `Run script not found at: ${runPath}`); return; } @@ -183,7 +172,6 @@ export class AgentManager extends EventEmitter { // Store context for potential restart this.storeTaskContext(taskId, projectPath, specId, options, false); - console.log('[AgentManager] Spawning process with args:', args); this.processManager.spawnProcess(taskId, autoBuildSource, args, combinedEnv, 'task-execution'); } @@ -329,7 +317,6 @@ export class AgentManager extends EventEmitter { } context.swapCount++; - console.log('[AgentManager] Restarting task:', taskId, 'swap count:', context.swapCount); // Kill current process this.killTask(taskId); diff --git a/auto-claude-ui/src/main/agent/agent-process.ts b/auto-claude-ui/src/main/agent/agent-process.ts index d55b57e8..baaf26b8 100644 --- a/auto-claude-ui/src/main/agent/agent-process.ts +++ b/auto-claude-ui/src/main/agent/agent-process.ts @@ -1,4 +1,4 @@ -import { spawn, ChildProcess } from 'child_process'; +import { spawn } from 'child_process'; import path from 'path'; import { existsSync, readFileSync } from 'fs'; import { app } from 'electron'; @@ -100,14 +100,11 @@ export class AgentProcessManager { loadAutoBuildEnv(): Record { const autoBuildSource = this.getAutoBuildSourcePath(); if (!autoBuildSource) { - console.log('[loadAutoBuildEnv] No auto-build source path found'); return {}; } const envPath = path.join(autoBuildSource, '.env'); - console.log('[loadAutoBuildEnv] Looking for .env at:', envPath); if (!existsSync(envPath)) { - console.log('[loadAutoBuildEnv] .env file does not exist'); return {}; } @@ -161,11 +158,6 @@ export class AgentProcessManager { // Generate unique spawn ID for this process instance const spawnId = this.state.generateSpawnId(); - console.log('[spawnProcess] Spawning with pythonPath:', this.pythonPath); - console.log('[spawnProcess] cwd:', cwd); - console.log('[spawnProcess] processType:', processType); - console.log('[spawnProcess] spawnId:', spawnId); - // Get active Claude profile environment (CLAUDE_CONFIG_DIR if not default) const profileEnv = getProfileEnv(); @@ -181,8 +173,6 @@ export class AgentProcessManager { } }); - console.log('[spawnProcess] Process spawned, pid:', childProcess.pid); - this.state.addProcess(taskId, { taskId, process: childProcess, @@ -245,7 +235,6 @@ export class AgentProcessManager { // Handle stdout - explicitly decode as UTF-8 for cross-platform Unicode support childProcess.stdout?.on('data', (data: Buffer) => { const log = data.toString('utf8'); - console.log('[spawnProcess] stdout:', log.substring(0, 200)); this.emitter.emit('log', taskId, log); processLog(log); }); @@ -253,7 +242,6 @@ export class AgentProcessManager { // Handle stderr - explicitly decode as UTF-8 for cross-platform Unicode support childProcess.stderr?.on('data', (data: Buffer) => { const log = data.toString('utf8'); - console.log('[spawnProcess] stderr:', log.substring(0, 200)); // Some Python output goes to stderr (like progress bars) // so we treat it as log, not error this.emitter.emit('log', taskId, log); @@ -262,13 +250,11 @@ export class AgentProcessManager { // Handle process exit childProcess.on('exit', (code: number | null) => { - console.log('[spawnProcess] Process exited with code:', code, 'spawnId:', spawnId); this.state.deleteProcess(taskId); // Check if this specific spawn was killed (vs exited naturally) // If killed, don't emit exit event to prevent race condition with new process if (this.state.wasSpawnKilled(spawnId)) { - console.log('[spawnProcess] Process was killed, skipping exit event for spawnId:', spawnId); this.state.clearKilledSpawn(spawnId); return; } @@ -277,26 +263,15 @@ export class AgentProcessManager { if (code !== 0) { const rateLimitDetection = detectRateLimit(allOutput); if (rateLimitDetection.isRateLimited) { - console.log('[spawnProcess] Rate limit detected in task output:', { - taskId, - resetTime: rateLimitDetection.resetTime, - limitType: rateLimitDetection.limitType, - suggestedProfile: rateLimitDetection.suggestedProfile?.name - }); - // Check if auto-swap is enabled const profileManager = getClaudeProfileManager(); const autoSwitchSettings = profileManager.getAutoSwitchSettings(); if (autoSwitchSettings.enabled && autoSwitchSettings.autoSwitchOnRateLimit) { - console.log('[spawnProcess] Reactive auto-swap enabled'); - const currentProfileId = rateLimitDetection.profileId; const bestProfile = profileManager.getBestAvailableProfile(currentProfileId); if (bestProfile) { - console.log('[spawnProcess] Reactive swap to:', bestProfile.name); - // Switch active profile profileManager.setActiveProfile(bestProfile.id); @@ -342,7 +317,7 @@ export class AgentProcessManager { // Handle process error childProcess.on('error', (err: Error) => { - console.log('[spawnProcess] Process error:', err.message); + console.error('[AgentProcess] Process error:', err.message); this.state.deleteProcess(taskId); this.emitter.emit('execution-progress', taskId, { diff --git a/auto-claude-ui/src/main/agent/agent-queue.ts b/auto-claude-ui/src/main/agent/agent-queue.ts index 7dd6cdd4..9fa8ba48 100644 --- a/auto-claude-ui/src/main/agent/agent-queue.ts +++ b/auto-claude-ui/src/main/agent/agent-queue.ts @@ -182,15 +182,11 @@ export class AgentQueueManager { for (const line of lines) { const trimmed = line.trim(); if (trimmed.length > 0) { - console.log('[Ideation]', trimmed); this.emitter.emit('ideation-log', projectId, trimmed); } } }; - console.log('[Ideation] Starting ideation process with args:', args); - console.log('[Ideation] CWD:', cwd); - // Track completed types for progress calculation const completedTypes = new Set(); const totalTypes = 7; // Default all types @@ -209,7 +205,6 @@ export class AgentQueueManager { if (typeCompleteMatch) { const [, ideationType, ideasCount] = typeCompleteMatch; completedTypes.add(ideationType); - console.log(`[Ideation] Type complete: ${ideationType} with ${ideasCount} ideas`); // Emit event for UI to load this type's ideas immediately this.emitter.emit('ideation-type-complete', projectId, ideationType, parseInt(ideasCount, 10)); @@ -219,7 +214,6 @@ export class AgentQueueManager { if (typeFailedMatch) { const [, ideationType] = typeFailedMatch; completedTypes.add(ideationType); - console.log(`[Ideation] Type failed: ${ideationType}`); this.emitter.emit('ideation-type-failed', projectId, ideationType); } @@ -260,8 +254,6 @@ export class AgentQueueManager { // Handle process exit childProcess.on('exit', (code: number | null) => { - console.log('[Ideation] Process exited with code:', code); - // Get the stored project path before deleting from map const processInfo = this.state.getProcess(projectId); const storedProjectPath = processInfo?.projectPath; @@ -297,7 +289,6 @@ export class AgentQueueManager { if (existsSync(ideationFilePath)) { const content = readFileSync(ideationFilePath, 'utf-8'); const session = JSON.parse(content); - console.log('[Ideation] Emitting ideation-complete with session data'); this.emitter.emit('ideation-complete', projectId, session); } else { console.warn('[Ideation] ideation.json not found at:', ideationFilePath); @@ -346,10 +337,6 @@ export class AgentQueueManager { // Get Python path from process manager (uses venv if configured) const pythonPath = this.processManager.getPythonPath(); - console.log('[Roadmap] Starting roadmap process with args:', args); - console.log('[Roadmap] CWD:', cwd); - console.log('[Roadmap] Python path:', pythonPath); - const childProcess = spawn(pythonPath, args, { cwd, env: { @@ -382,7 +369,6 @@ export class AgentQueueManager { for (const line of lines) { const trimmed = line.trim(); if (trimmed.length > 0) { - console.log('[Roadmap]', trimmed); this.emitter.emit('roadmap-log', projectId, trimmed); } } @@ -426,8 +412,6 @@ export class AgentQueueManager { // Handle process exit childProcess.on('exit', (code: number | null) => { - console.log('[Roadmap] Process exited with code:', code); - // Get the stored project path before deleting from map const processInfo = this.state.getProcess(projectId); const storedProjectPath = processInfo?.projectPath; @@ -445,7 +429,6 @@ export class AgentQueueManager { } if (code === 0) { - console.log('[Roadmap] Roadmap generation completed successfully'); this.emitter.emit('roadmap-progress', projectId, { phase: 'complete', progress: 100, @@ -464,7 +447,6 @@ export class AgentQueueManager { if (existsSync(roadmapFilePath)) { const content = readFileSync(roadmapFilePath, 'utf-8'); const roadmap = JSON.parse(content); - console.log('[Roadmap] Emitting roadmap-complete with roadmap data'); this.emitter.emit('roadmap-complete', projectId, roadmap); } else { console.warn('[Roadmap] roadmap.json not found at:', roadmapFilePath); @@ -474,7 +456,6 @@ export class AgentQueueManager { } } } else { - console.error('[Roadmap] Roadmap generation failed with exit code:', code); this.emitter.emit('roadmap-error', projectId, `Roadmap generation failed with exit code ${code}`); } }); diff --git a/auto-claude-ui/src/main/app-updater.ts b/auto-claude-ui/src/main/app-updater.ts index 74cfbf1b..eff694d4 100644 --- a/auto-claude-ui/src/main/app-updater.ts +++ b/auto-claude-ui/src/main/app-updater.ts @@ -33,10 +33,10 @@ autoUpdater.autoInstallOnAppQuit = true; // Automatically install on app quit // Enable more verbose logging in debug mode if (DEBUG_UPDATER) { autoUpdater.logger = { - info: (msg: string) => console.log('[app-updater:debug]', msg), + info: (msg: string) => console.warn('[app-updater:debug]', msg), warn: (msg: string) => console.warn('[app-updater:debug]', msg), error: (msg: string) => console.error('[app-updater:debug]', msg), - debug: (msg: string) => console.log('[app-updater:debug]', msg) + debug: (msg: string) => console.warn('[app-updater:debug]', msg) }; } @@ -54,13 +54,13 @@ export function initializeAppUpdater(window: BrowserWindow): void { mainWindow = window; // Log updater configuration - console.log('[app-updater] ========================================'); - console.log('[app-updater] Initializing app auto-updater'); - console.log('[app-updater] App packaged:', app.isPackaged); - console.log('[app-updater] Current version:', autoUpdater.currentVersion.version); - console.log('[app-updater] Auto-download enabled:', autoUpdater.autoDownload); - console.log('[app-updater] Debug mode:', DEBUG_UPDATER); - console.log('[app-updater] ========================================'); + console.warn('[app-updater] ========================================'); + console.warn('[app-updater] Initializing app auto-updater'); + console.warn('[app-updater] App packaged:', app.isPackaged); + console.warn('[app-updater] Current version:', autoUpdater.currentVersion.version); + console.warn('[app-updater] Auto-download enabled:', autoUpdater.autoDownload); + console.warn('[app-updater] Debug mode:', DEBUG_UPDATER); + console.warn('[app-updater] ========================================'); // ============================================ // Event Handlers @@ -68,7 +68,7 @@ export function initializeAppUpdater(window: BrowserWindow): void { // Update available - new version found autoUpdater.on('update-available', (info) => { - console.log('[app-updater] Update available:', info.version); + console.warn('[app-updater] Update available:', info.version); if (mainWindow) { mainWindow.webContents.send(IPC_CHANNELS.APP_UPDATE_AVAILABLE, { version: info.version, @@ -80,7 +80,7 @@ export function initializeAppUpdater(window: BrowserWindow): void { // Update downloaded - ready to install autoUpdater.on('update-downloaded', (info) => { - console.log('[app-updater] Update downloaded:', info.version); + console.warn('[app-updater] Update downloaded:', info.version); if (mainWindow) { mainWindow.webContents.send(IPC_CHANNELS.APP_UPDATE_DOWNLOADED, { version: info.version, @@ -92,7 +92,7 @@ export function initializeAppUpdater(window: BrowserWindow): void { // Download progress autoUpdater.on('download-progress', (progress) => { - console.log(`[app-updater] Download progress: ${progress.percent.toFixed(2)}%`); + console.warn(`[app-updater] Download progress: ${progress.percent.toFixed(2)}%`); if (mainWindow) { mainWindow.webContents.send(IPC_CHANNELS.APP_UPDATE_PROGRESS, { percent: progress.percent, @@ -116,16 +116,16 @@ export function initializeAppUpdater(window: BrowserWindow): void { // No update available autoUpdater.on('update-not-available', (info) => { - console.log('[app-updater] ✓ No updates available - you are on the latest version'); - console.log('[app-updater] Current version:', info.version); + console.warn('[app-updater] No updates available - you are on the latest version'); + console.warn('[app-updater] Current version:', info.version); if (DEBUG_UPDATER) { - console.log('[app-updater:debug] Full info:', JSON.stringify(info, null, 2)); + console.warn('[app-updater:debug] Full info:', JSON.stringify(info, null, 2)); } }); // Checking for updates autoUpdater.on('checking-for-update', () => { - console.log('[app-updater] 🔍 Checking for updates...'); + console.warn('[app-updater] Checking for updates...'); }); // ============================================ @@ -134,10 +134,10 @@ export function initializeAppUpdater(window: BrowserWindow): void { // Check for updates 3 seconds after launch const INITIAL_DELAY = 3000; - console.log(`[app-updater] Will check for updates in ${INITIAL_DELAY / 1000} seconds...`); + console.warn(`[app-updater] Will check for updates in ${INITIAL_DELAY / 1000} seconds...`); setTimeout(() => { - console.log('[app-updater] 🚀 Performing initial update check'); + console.warn('[app-updater] Performing initial update check'); autoUpdater.checkForUpdates().catch((error) => { console.error('[app-updater] ❌ Initial update check failed:', error.message); if (DEBUG_UPDATER) { @@ -148,10 +148,10 @@ export function initializeAppUpdater(window: BrowserWindow): void { // Check for updates every 4 hours const FOUR_HOURS = 4 * 60 * 60 * 1000; - console.log(`[app-updater] Periodic checks scheduled every ${FOUR_HOURS / 1000 / 60 / 60} hours`); + console.warn(`[app-updater] Periodic checks scheduled every ${FOUR_HOURS / 1000 / 60 / 60} hours`); setInterval(() => { - console.log('[app-updater] 🔄 Performing periodic update check'); + console.warn('[app-updater] Performing periodic update check'); autoUpdater.checkForUpdates().catch((error) => { console.error('[app-updater] ❌ Periodic update check failed:', error.message); if (DEBUG_UPDATER) { @@ -160,7 +160,7 @@ export function initializeAppUpdater(window: BrowserWindow): void { }); }, FOUR_HOURS); - console.log('[app-updater] ✓ Auto-updater initialized successfully'); + console.warn('[app-updater] Auto-updater initialized successfully'); } /** @@ -169,7 +169,7 @@ export function initializeAppUpdater(window: BrowserWindow): void { */ export async function checkForUpdates(): Promise { try { - console.log('[app-updater] Manual update check requested'); + console.warn('[app-updater] Manual update check requested'); const result = await autoUpdater.checkForUpdates(); if (!result) { @@ -199,7 +199,7 @@ export async function checkForUpdates(): Promise { */ export async function downloadUpdate(): Promise { try { - console.log('[app-updater] Manual update download requested'); + console.warn('[app-updater] Manual update download requested'); await autoUpdater.downloadUpdate(); } catch (error) { console.error('[app-updater] Manual update download failed:', error); @@ -212,7 +212,7 @@ export async function downloadUpdate(): Promise { * Called from IPC handler when user confirms installation */ export function quitAndInstall(): void { - console.log('[app-updater] Quitting and installing update'); + console.warn('[app-updater] Quitting and installing update'); autoUpdater.quitAndInstall(false, true); } diff --git a/auto-claude-ui/src/main/changelog/changelog-service.ts b/auto-claude-ui/src/main/changelog/changelog-service.ts index a5cf5b87..fce22be7 100644 --- a/auto-claude-ui/src/main/changelog/changelog-service.ts +++ b/auto-claude-ui/src/main/changelog/changelog-service.ts @@ -119,7 +119,7 @@ export class ChangelogService extends EventEmitter { */ private debug(...args: unknown[]): void { if (this.isDebugEnabled()) { - console.log('[ChangelogService]', ...args); + console.warn('[ChangelogService]', ...args); } } diff --git a/auto-claude-ui/src/main/changelog/generator.ts b/auto-claude-ui/src/main/changelog/generator.ts index 3e4769a9..c51249f8 100644 --- a/auto-claude-ui/src/main/changelog/generator.ts +++ b/auto-claude-ui/src/main/changelog/generator.ts @@ -34,7 +34,7 @@ export class ChangelogGenerator extends EventEmitter { private debug(...args: unknown[]): void { if (this.debugEnabled) { - console.log('[ChangelogGenerator]', ...args); + console.warn('[ChangelogGenerator]', ...args); } } diff --git a/auto-claude-ui/src/main/changelog/git-integration.ts b/auto-claude-ui/src/main/changelog/git-integration.ts index f7e56cd3..a9dbff56 100644 --- a/auto-claude-ui/src/main/changelog/git-integration.ts +++ b/auto-claude-ui/src/main/changelog/git-integration.ts @@ -13,7 +13,7 @@ import { parseGitLogOutput } from './parser'; */ function debug(enabled: boolean, ...args: unknown[]): void { if (enabled) { - console.log('[GitIntegration]', ...args); + console.warn('[GitIntegration]', ...args); } } diff --git a/auto-claude-ui/src/main/changelog/parser.ts b/auto-claude-ui/src/main/changelog/parser.ts index baabb1f4..3a952756 100644 --- a/auto-claude-ui/src/main/changelog/parser.ts +++ b/auto-claude-ui/src/main/changelog/parser.ts @@ -9,7 +9,7 @@ export function extractSpecOverview(spec: string): string { // Handle both Unix (\n) and Windows (\r\n) line endings const lines = spec.split(/\r?\n/); let inOverview = false; - let overview: string[] = []; + const overview: string[] = []; for (const line of lines) { // Start capturing at Overview heading diff --git a/auto-claude-ui/src/main/changelog/version-suggester.ts b/auto-claude-ui/src/main/changelog/version-suggester.ts index ebb945f6..571080a7 100644 --- a/auto-claude-ui/src/main/changelog/version-suggester.ts +++ b/auto-claude-ui/src/main/changelog/version-suggester.ts @@ -28,7 +28,7 @@ export class VersionSuggester { private debug(...args: unknown[]): void { if (this.debugEnabled) { - console.log('[VersionSuggester]', ...args); + console.warn('[VersionSuggester]', ...args); } } @@ -51,7 +51,7 @@ export class VersionSuggester { // Build environment const spawnEnv = this.buildSpawnEnvironment(); - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { const childProcess = spawn(this.pythonPath, ['-c', script], { cwd: this.autoBuildSourcePath, env: spawnEnv diff --git a/auto-claude-ui/src/main/claude-profile-manager.ts b/auto-claude-ui/src/main/claude-profile-manager.ts index 2ee76152..275d3b05 100644 --- a/auto-claude-ui/src/main/claude-profile-manager.ts +++ b/auto-claude-ui/src/main/claude-profile-manager.ts @@ -240,7 +240,7 @@ export class ClaudeProfileManager { profile.name = newName.trim(); this.save(); - console.log('[ClaudeProfileManager] Renamed profile:', profileId, 'to:', newName); + console.warn('[ClaudeProfileManager] Renamed profile:', profileId, 'to:', newName); return true; } @@ -317,7 +317,7 @@ export class ClaudeProfileManager { this.save(); const isEncrypted = profile.oauthToken.startsWith('enc:'); - console.log('[ClaudeProfileManager] Set OAuth token for profile:', profile.name, { + console.warn('[ClaudeProfileManager] Set OAuth token for profile:', profile.name, { email: email || '(not captured)', encrypted: isEncrypted, tokenLength: token.length @@ -350,14 +350,14 @@ export class ClaudeProfileManager { const decryptedToken = decryptToken(profile.oauthToken); if (decryptedToken) { env.CLAUDE_CODE_OAUTH_TOKEN = decryptedToken; - console.log('[ClaudeProfileManager] Using OAuth token for profile:', profile.name); + console.warn('[ClaudeProfileManager] Using OAuth token for profile:', profile.name); } else { console.warn('[ClaudeProfileManager] Failed to decrypt token for profile:', profile.name); } } else if (profile?.configDir && !profile.isDefault) { // Fallback to configDir for backward compatibility env.CLAUDE_CONFIG_DIR = profile.configDir; - console.log('[ClaudeProfileManager] Using configDir for profile:', profile.name); + console.warn('[ClaudeProfileManager] Using configDir for profile:', profile.name); } return env; @@ -376,7 +376,7 @@ export class ClaudeProfileManager { profile.usage = usage; this.save(); - console.log('[ClaudeProfileManager] Updated usage for', profile.name, ':', usage); + console.warn('[ClaudeProfileManager] Updated usage for', profile.name, ':', usage); return usage; } @@ -392,7 +392,7 @@ export class ClaudeProfileManager { const event = recordRateLimitEventImpl(profile, resetTimeStr); this.save(); - console.log('[ClaudeProfileManager] Recorded rate limit event for', profile.name, ':', event); + console.warn('[ClaudeProfileManager] Recorded rate limit event for', profile.name, ':', event); return event; } diff --git a/auto-claude-ui/src/main/claude-profile/profile-scorer.ts b/auto-claude-ui/src/main/claude-profile/profile-scorer.ts index 42d14309..fc0f8ecc 100644 --- a/auto-claude-ui/src/main/claude-profile/profile-scorer.ts +++ b/auto-claude-ui/src/main/claude-profile/profile-scorer.ts @@ -86,12 +86,12 @@ export function getBestAvailableProfile( // Return the best candidate if it has a positive score const best = scoredProfiles[0]; if (best && best.score > 0) { - console.log('[ProfileScorer] Best available profile:', best.profile.name, 'score:', best.score); + console.warn('[ProfileScorer] Best available profile:', best.profile.name, 'score:', best.score); return best.profile; } // All profiles are rate-limited or have issues - console.log('[ProfileScorer] No good profile available, all are rate-limited or have issues'); + console.warn('[ProfileScorer] No good profile available, all are rate-limited or have issues'); return null; } @@ -143,7 +143,7 @@ export function shouldProactivelySwitch( * Get profiles sorted by availability (best first) */ export function getProfilesSortedByAvailability(profiles: ClaudeProfile[]): ClaudeProfile[] { - const now = new Date(); + const _now = new Date(); return [...profiles].sort((a, b) => { // Not rate-limited profiles first diff --git a/auto-claude-ui/src/main/claude-profile/profile-utils.ts b/auto-claude-ui/src/main/claude-profile/profile-utils.ts index d2593f87..557d8fae 100644 --- a/auto-claude-ui/src/main/claude-profile/profile-utils.ts +++ b/auto-claude-ui/src/main/claude-profile/profile-utils.ts @@ -117,7 +117,7 @@ export function hasValidToken(profile: ClaudeProfile): boolean { const oneYearAgo = new Date(); oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1); if (new Date(profile.tokenCreatedAt) < oneYearAgo) { - console.log('[ProfileUtils] Token expired for profile:', profile.name); + console.warn('[ProfileUtils] Token expired for profile:', profile.name); return false; } } diff --git a/auto-claude-ui/src/main/claude-profile/usage-monitor.ts b/auto-claude-ui/src/main/claude-profile/usage-monitor.ts index 1c57b044..14bba744 100644 --- a/auto-claude-ui/src/main/claude-profile/usage-monitor.ts +++ b/auto-claude-ui/src/main/claude-profile/usage-monitor.ts @@ -22,7 +22,7 @@ export class UsageMonitor extends EventEmitter { private constructor() { super(); - console.log('[UsageMonitor] Initialized'); + console.warn('[UsageMonitor] Initialized'); } static getInstance(): UsageMonitor { @@ -40,17 +40,17 @@ export class UsageMonitor extends EventEmitter { const settings = profileManager.getAutoSwitchSettings(); if (!settings.enabled || !settings.proactiveSwapEnabled) { - console.log('[UsageMonitor] Proactive monitoring disabled'); + console.warn('[UsageMonitor] Proactive monitoring disabled'); return; } if (this.intervalId) { - console.log('[UsageMonitor] Already running'); + console.warn('[UsageMonitor] Already running'); return; } const interval = settings.usageCheckInterval || 30000; - console.log('[UsageMonitor] Starting with interval:', interval, 'ms'); + console.warn('[UsageMonitor] Starting with interval:', interval, 'ms'); // Check immediately this.checkUsageAndSwap(); @@ -68,7 +68,7 @@ export class UsageMonitor extends EventEmitter { if (this.intervalId) { clearInterval(this.intervalId); this.intervalId = null; - console.log('[UsageMonitor] Stopped'); + console.warn('[UsageMonitor] Stopped'); } } @@ -94,14 +94,14 @@ export class UsageMonitor extends EventEmitter { const activeProfile = profileManager.getActiveProfile(); if (!activeProfile) { - console.log('[UsageMonitor] No active profile'); + console.warn('[UsageMonitor] No active profile'); return; } // Fetch current usage (hybrid approach) const usage = await this.fetchUsage(activeProfile.id, activeProfile.oauthToken); if (!usage) { - console.log('[UsageMonitor] Failed to fetch usage'); + console.warn('[UsageMonitor] Failed to fetch usage'); return; } @@ -116,7 +116,7 @@ export class UsageMonitor extends EventEmitter { const weeklyExceeded = usage.weeklyPercent >= settings.weeklyThreshold; if (sessionExceeded || weeklyExceeded) { - console.log('[UsageMonitor] Threshold exceeded:', { + console.warn('[UsageMonitor] Threshold exceeded:', { sessionPercent: usage.sessionPercent, sessionThreshold: settings.sessionThreshold, weeklyPercent: usage.weeklyPercent, @@ -154,12 +154,12 @@ export class UsageMonitor extends EventEmitter { if (this.useApiMethod && oauthToken) { const apiUsage = await this.fetchUsageViaAPI(oauthToken, profileId, profile.name); if (apiUsage) { - console.log('[UsageMonitor] Successfully fetched via API'); + console.warn('[UsageMonitor] Successfully fetched via API'); return apiUsage; } // API failed - switch to CLI method for future calls - console.log('[UsageMonitor] API method failed, falling back to CLI'); + console.warn('[UsageMonitor] API method failed, falling back to CLI'); this.useApiMethod = false; } @@ -191,7 +191,12 @@ export class UsageMonitor extends EventEmitter { return null; } - const data: any = await response.json(); + const data = await response.json() as { + five_hour_utilization?: number; + seven_day_utilization?: number; + five_hour_reset_at?: string; + seven_day_reset_at?: string; + }; // Expected response format: // { @@ -232,7 +237,7 @@ export class UsageMonitor extends EventEmitter { // CLI-based usage fetching is not implemented yet. // The API method should handle most cases. If we need CLI fallback, // we would need to spawn a Claude process with /usage command and parse the output. - console.log('[UsageMonitor] CLI fallback not implemented, API method should be used'); + console.warn('[UsageMonitor] CLI fallback not implemented, API method should be used'); return null; } @@ -256,7 +261,7 @@ export class UsageMonitor extends EventEmitter { const diffDays = Math.floor(diffHours / 24); const remainingHours = diffHours % 24; return `${diffDays}d ${remainingHours}h`; - } catch (error) { + } catch (_error) { return isoTimestamp; } } @@ -272,7 +277,7 @@ export class UsageMonitor extends EventEmitter { const bestProfile = profileManager.getBestAvailableProfile(currentProfileId); if (!bestProfile) { - console.log('[UsageMonitor] No alternative profile for proactive swap'); + console.warn('[UsageMonitor] No alternative profile for proactive swap'); this.emit('proactive-swap-failed', { reason: 'no_alternative', currentProfile: currentProfileId @@ -280,7 +285,7 @@ export class UsageMonitor extends EventEmitter { return; } - console.log('[UsageMonitor] Proactive swap:', { + console.warn('[UsageMonitor] Proactive swap:', { from: currentProfileId, to: bestProfile.id, reason: limitType diff --git a/auto-claude-ui/src/main/docker-service.ts b/auto-claude-ui/src/main/docker-service.ts index f5d1346a..6b01f0aa 100644 --- a/auto-claude-ui/src/main/docker-service.ts +++ b/auto-claude-ui/src/main/docker-service.ts @@ -158,7 +158,7 @@ export async function checkFalkorDBStatus(port: number = FALKORDB_DEFAULT_PORT): /** * Check if FalkorDB is responding to connections */ -async function checkFalkorDBHealth(port: number): Promise { +async function checkFalkorDBHealth(_port: number): Promise { try { // Try to ping FalkorDB using redis-cli (FalkorDB uses Redis protocol) // Since we may not have redis-cli, we'll check if the port is listening @@ -482,10 +482,10 @@ export async function validateOpenAIApiKey( timeout: 15000, }; - const req = https.request(options, (res: any) => { + const req = https.request(options, (res: { statusCode: number; on: (event: string, callback: (chunk: Buffer) => void) => void }) => { let data = ''; - res.on('data', (chunk: any) => { + res.on('data', (chunk: Buffer) => { data += chunk; }); @@ -533,7 +533,7 @@ export async function validateOpenAIApiKey( }); }); - req.on('error', (error: any) => { + req.on('error', (error: Error) => { resolve({ success: false, message: `Connection error: ${error.message}`, diff --git a/auto-claude-ui/src/main/index.ts b/auto-claude-ui/src/main/index.ts index a6d973e7..bd7b4d9a 100644 --- a/auto-claude-ui/src/main/index.ts +++ b/auto-claude-ui/src/main/index.ts @@ -137,23 +137,23 @@ app.whenReady().then(() => { // Start the usage monitor const usageMonitor = getUsageMonitor(); usageMonitor.start(); - console.log('[main] Usage monitor initialized and started'); + console.warn('[main] Usage monitor initialized and started'); // Initialize app auto-updater (only in production, or when DEBUG_UPDATER is set) const forceUpdater = process.env.DEBUG_UPDATER === 'true'; if (app.isPackaged || forceUpdater) { initializeAppUpdater(mainWindow); - console.log('[main] App auto-updater initialized'); + console.warn('[main] App auto-updater initialized'); if (forceUpdater && !app.isPackaged) { - console.log('[main] ⚠️ Updater forced in dev mode via DEBUG_UPDATER=true'); - console.log('[main] ⚠️ Note: Updates won\'t actually work in dev mode'); + console.warn('[main] Updater forced in dev mode via DEBUG_UPDATER=true'); + console.warn('[main] Note: Updates won\'t actually work in dev mode'); } } else { - console.log('[main] ========================================'); - console.log('[main] App auto-updater DISABLED (development mode)'); - console.log('[main] To test updater logging, set DEBUG_UPDATER=true'); - console.log('[main] Note: Actual updates only work in packaged builds'); - console.log('[main] ========================================'); + console.warn('[main] ========================================'); + console.warn('[main] App auto-updater DISABLED (development mode)'); + console.warn('[main] To test updater logging, set DEBUG_UPDATER=true'); + console.warn('[main] Note: Actual updates only work in packaged builds'); + console.warn('[main] ========================================'); } } @@ -177,7 +177,7 @@ app.on('before-quit', async () => { // Stop usage monitor const usageMonitor = getUsageMonitor(); usageMonitor.stop(); - console.log('[main] Usage monitor stopped'); + console.warn('[main] Usage monitor stopped'); // Kill all running agent processes if (agentManager) { diff --git a/auto-claude-ui/src/main/insights-service.ts b/auto-claude-ui/src/main/insights-service.ts index ab8bcc19..3a76d00d 100644 --- a/auto-claude-ui/src/main/insights-service.ts +++ b/auto-claude-ui/src/main/insights-service.ts @@ -2,10 +2,7 @@ import { EventEmitter } from 'events'; import type { InsightsSession, InsightsSessionSummary, - InsightsChatMessage, - InsightsChatStatus, - InsightsStreamChunk, - InsightsToolUsage + InsightsChatMessage } from '../shared/types'; import { InsightsConfig } from './insights/config'; import { InsightsPaths } from './insights/paths'; diff --git a/auto-claude-ui/src/main/insights/insights-executor.ts b/auto-claude-ui/src/main/insights/insights-executor.ts index cd960169..cf45fa90 100644 --- a/auto-claude-ui/src/main/insights/insights-executor.ts +++ b/auto-claude-ui/src/main/insights/insights-executor.ts @@ -251,7 +251,7 @@ export class InsightsExecutor extends EventEmitter { private handleRateLimit(projectId: string, output: string): void { const rateLimitDetection = detectRateLimit(output); if (rateLimitDetection.isRateLimited) { - console.log('[Insights] Rate limit detected:', { + console.warn('[Insights] Rate limit detected:', { projectId, resetTime: rateLimitDetection.resetTime, limitType: rateLimitDetection.limitType, diff --git a/auto-claude-ui/src/main/ipc-handlers/agent-events-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/agent-events-handlers.ts index f2466036..0d88fbae 100644 --- a/auto-claude-ui/src/main/ipc-handlers/agent-events-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/agent-events-handlers.ts @@ -1,16 +1,13 @@ -import { ipcMain } from 'electron'; import type { BrowserWindow } from 'electron'; import path from 'path'; import { existsSync, readFileSync, writeFileSync } from 'fs'; import { IPC_CHANNELS, getSpecsDir, AUTO_BUILD_PATHS } from '../../shared/constants'; import type { - IPCResult, SDKRateLimitInfo, Task, TaskStatus, Project, - ImplementationPlan, - ExecutionProgress + ImplementationPlan } from '../../shared/types'; import { AgentManager } from '../agent'; import type { ProcessType, ExecutionProgressData } from '../agent'; @@ -82,7 +79,7 @@ export function registerAgenteventsHandlers( } else if (processType === 'spec-creation') { // Pure spec creation (shouldn't happen with current flow, but handle it) // Stay in backlog/planning - console.log(`[Task ${taskId}] Spec creation completed with code ${code}`); + console.warn(`[Task ${taskId}] Spec creation completed with code ${code}`); return; } else { // Unknown process type @@ -130,7 +127,7 @@ export function registerAgenteventsHandlers( plan.planStatus = 'review'; plan.updated_at = new Date().toISOString(); writeFileSync(planPath, JSON.stringify(plan, null, 2)); - console.log(`[Task ${taskId}] Persisted status '${newStatus}' to implementation_plan.json`); + console.warn(`[Task ${taskId}] Persisted status '${newStatus}' to implementation_plan.json`); } } } @@ -141,7 +138,7 @@ export function registerAgenteventsHandlers( // Send notifications based on task completion status if (task && project) { const taskTitle = task.title || task.specId; - + if (code === 0) { // Task completed successfully - ready for review notificationService.notifyReviewNeeded(taskTitle, project.id, taskId); diff --git a/auto-claude-ui/src/main/ipc-handlers/app-update-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/app-update-handlers.ts index 12e61c18..1d0b963e 100644 --- a/auto-claude-ui/src/main/ipc-handlers/app-update-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/app-update-handlers.ts @@ -19,7 +19,7 @@ import { * Register all app-update-related IPC handlers */ export function registerAppUpdateHandlers(): void { - console.log('[IPC] Registering app update handlers'); + console.warn('[IPC] Registering app update handlers'); // ============================================ // App Update Operations @@ -102,5 +102,5 @@ export function registerAppUpdateHandlers(): void { } ); - console.log('[IPC] App update handlers registered successfully'); + console.warn('[IPC] App update handlers registered successfully'); } diff --git a/auto-claude-ui/src/main/ipc-handlers/changelog-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/changelog-handlers.ts index c337d353..5329708a 100644 --- a/auto-claude-ui/src/main/ipc-handlers/changelog-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/changelog-handlers.ts @@ -1,8 +1,7 @@ import { ipcMain } from 'electron'; import type { BrowserWindow } from 'electron'; import path from 'path'; -import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs'; -import { execSync } from 'child_process'; +import { existsSync, mkdirSync, writeFileSync } from 'fs'; import { IPC_CHANNELS, getSpecsDir } from '../../shared/constants'; import type { IPCResult, diff --git a/auto-claude-ui/src/main/ipc-handlers/context/memory-data-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/context/memory-data-handlers.ts index 2786987f..34c39ef6 100644 --- a/auto-claude-ui/src/main/ipc-handlers/context/memory-data-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/context/memory-data-handlers.ts @@ -155,7 +155,7 @@ export function searchFileBasedMemories( * Register memory data handlers */ export function registerMemoryDataHandlers( - getMainWindow: () => BrowserWindow | null + _getMainWindow: () => BrowserWindow | null ): void { // Get all memories ipcMain.handle( diff --git a/auto-claude-ui/src/main/ipc-handlers/context/memory-status-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/context/memory-status-handlers.ts index 3b3f568c..2dea6252 100644 --- a/auto-claude-ui/src/main/ipc-handlers/context/memory-status-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/context/memory-status-handlers.ts @@ -109,7 +109,7 @@ export function buildMemoryStatus( * Register memory status handlers */ export function registerMemoryStatusHandlers( - getMainWindow: () => BrowserWindow | null + _getMainWindow: () => BrowserWindow | null ): void { ipcMain.handle( IPC_CHANNELS.CONTEXT_MEMORY_STATUS, diff --git a/auto-claude-ui/src/main/ipc-handlers/context/project-context-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/context/project-context-handlers.ts index 9f1f4b1c..d1624260 100644 --- a/auto-claude-ui/src/main/ipc-handlers/context/project-context-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/context/project-context-handlers.ts @@ -13,10 +13,7 @@ import type { import { projectStore } from '../../project-store'; import { getFalkorDBService } from '../../falkordb-service'; import { - getAutoBuildSourcePath, - loadProjectEnvVars, - isGraphitiEnabled, - getGraphitiConnectionDetails + getAutoBuildSourcePath } from './utils'; import { loadGraphitiStateFromSpecs, @@ -83,7 +80,7 @@ async function loadRecentMemories( * Register project context handlers */ export function registerProjectContextHandlers( - getMainWindow: () => BrowserWindow | null + _getMainWindow: () => BrowserWindow | null ): void { // Get full project context ipcMain.handle( diff --git a/auto-claude-ui/src/main/ipc-handlers/env-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/env-handlers.ts index 9c6039d7..0093600a 100644 --- a/auto-claude-ui/src/main/ipc-handlers/env-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/env-handlers.ts @@ -5,7 +5,7 @@ import type { IPCResult, ProjectEnvConfig, ClaudeAuthResult, AppSettings } from import path from 'path'; import { app } from 'electron'; import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { execSync, spawn } from 'child_process'; +import { spawn } from 'child_process'; import { projectStore } from '../project-store'; import { parseEnvFile } from './utils'; @@ -14,7 +14,7 @@ import { parseEnvFile } from './utils'; * Register all env-related IPC handlers */ export function registerEnvHandlers( - getMainWindow: () => BrowserWindow | null + _getMainWindow: () => BrowserWindow | null ): void { // ============================================ // Environment Configuration Operations @@ -85,7 +85,7 @@ export function registerEnvHandlers( } // Generate content with sections - let content = `# Auto Claude Framework Environment Variables + const content = `# Auto Claude Framework Environment Variables # Managed by Auto Claude UI # Claude Code OAuth Token (REQUIRED) @@ -304,15 +304,15 @@ ${existingVars['GRAPHITI_DATABASE'] ? `GRAPHITI_DATABASE=${existingVars['GRAPHIT shell: true }); - let stdout = ''; - let stderr = ''; + let _stdout = ''; + let _stderr = ''; proc.stdout?.on('data', (data: Buffer) => { - stdout += data.toString(); + _stdout += data.toString(); }); proc.stderr?.on('data', (data: Buffer) => { - stderr += data.toString(); + _stderr += data.toString(); }); proc.on('close', (code: number | null) => { diff --git a/auto-claude-ui/src/main/ipc-handlers/github/oauth-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/github/oauth-handlers.ts index d5e9c3fb..2b451478 100644 --- a/auto-claude-ui/src/main/ipc-handlers/github/oauth-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/github/oauth-handlers.ts @@ -14,9 +14,9 @@ const DEBUG = process.env.DEBUG === 'true' || process.env.NODE_ENV === 'developm function debugLog(message: string, data?: unknown): void { if (DEBUG) { if (data !== undefined) { - console.log(`[GitHub OAuth] ${message}`, data); + console.warn(`[GitHub OAuth] ${message}`, data); } else { - console.log(`[GitHub OAuth] ${message}`); + console.warn(`[GitHub OAuth] ${message}`); } } } diff --git a/auto-claude-ui/src/main/ipc-handlers/github/release-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/github/release-handlers.ts index 431359fe..120ae63f 100644 --- a/auto-claude-ui/src/main/ipc-handlers/github/release-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/github/release-handlers.ts @@ -237,7 +237,7 @@ export function registerSuggestVersion(): void { commitCount: commits.length } }; - } catch (error) { + } catch (_error) { // Fallback to patch bump on error const currentVersion = getCurrentVersion(project.path); const [major, minor, patch] = currentVersion.split('.').map(Number); diff --git a/auto-claude-ui/src/main/ipc-handlers/ideation/session-manager.ts b/auto-claude-ui/src/main/ipc-handlers/ideation/session-manager.ts index fe4b6921..72299dbe 100644 --- a/auto-claude-ui/src/main/ipc-handlers/ideation/session-manager.ts +++ b/auto-claude-ui/src/main/ipc-handlers/ideation/session-manager.ts @@ -35,7 +35,7 @@ export async function getIdeationSession( try { // Transform snake_case to camelCase for frontend - const enabledTypes = (rawIdeation.config?.enabled_types || rawIdeation.config?.enabledTypes || []) as any[]; + const enabledTypes = (rawIdeation.config?.enabled_types || rawIdeation.config?.enabledTypes || []) as unknown[]; const session: IdeationSession = { id: rawIdeation.id || `ideation-${Date.now()}`, diff --git a/auto-claude-ui/src/main/ipc-handlers/ideation/task-converter.ts b/auto-claude-ui/src/main/ipc-handlers/ideation/task-converter.ts index addc764c..c0895fba 100644 --- a/auto-claude-ui/src/main/ipc-handlers/ideation/task-converter.ts +++ b/auto-claude-ui/src/main/ipc-handlers/ideation/task-converter.ts @@ -160,7 +160,7 @@ function buildTaskMetadata(idea: RawIdea): TaskMetadata { function createSpecFiles( specDir: string, idea: RawIdea, - taskDescription: string + _taskDescription: string ): void { // Create the spec directory mkdirSync(specDir, { recursive: true }); diff --git a/auto-claude-ui/src/main/ipc-handlers/index.ts b/auto-claude-ui/src/main/ipc-handlers/index.ts index 38b65b54..afb75336 100644 --- a/auto-claude-ui/src/main/ipc-handlers/index.ts +++ b/auto-claude-ui/src/main/ipc-handlers/index.ts @@ -98,7 +98,7 @@ export function setupIpcHandlers( // App auto-update handlers registerAppUpdateHandlers(); - console.log('[IPC] All handler modules registered successfully'); + console.warn('[IPC] All handler modules registered successfully'); } // Re-export all individual registration functions for potential custom usage diff --git a/auto-claude-ui/src/main/ipc-handlers/linear-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/linear-handlers.ts index add15160..07fadd16 100644 --- a/auto-claude-ui/src/main/ipc-handlers/linear-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/linear-handlers.ts @@ -1,10 +1,9 @@ import { ipcMain } from 'electron'; import type { BrowserWindow } from 'electron'; import { IPC_CHANNELS, getSpecsDir, AUTO_BUILD_PATHS } from '../../shared/constants'; -import type { IPCResult, LinearIssue, LinearTeam, LinearProject, LinearImportResult, LinearSyncStatus, Project, Task, TaskMetadata } from '../../shared/types'; +import type { IPCResult, LinearIssue, LinearTeam, LinearProject, LinearImportResult, LinearSyncStatus, Project, TaskMetadata } from '../../shared/types'; import path from 'path'; import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'fs'; -import { spawn } from 'child_process'; import { projectStore } from '../project-store'; import { parseEnvFile } from './utils'; @@ -16,7 +15,7 @@ import { AgentManager } from '../agent'; */ export function registerLinearHandlers( agentManager: AgentManager, - getMainWindow: () => BrowserWindow | null + _getMainWindow: () => BrowserWindow | null ): void { // ============================================ // Linear Integration Operations @@ -115,7 +114,8 @@ export function registerLinearHandlers( if (data.teams.nodes.length > 0) { teamName = data.teams.nodes[0].name; - const countQuery = ` + // Note: These queries are kept as documentation for future API reference + const _countQuery = ` query($teamId: String!) { team(id: $teamId) { issues { @@ -125,7 +125,7 @@ export function registerLinearHandlers( } `; // Get approximate count - const issuesQuery = ` + const _issuesQuery = ` query($teamId: String!) { issues(filter: { team: { id: { eq: $teamId } } }, first: 0) { pageInfo { @@ -134,6 +134,8 @@ export function registerLinearHandlers( } } `; + void _countQuery; + void _issuesQuery; // Simple count estimation - get first 250 issues const countData = await linearGraphQL(apiKey, ` diff --git a/auto-claude-ui/src/main/ipc-handlers/project-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/project-handlers.ts index 230fcadd..ad5fb883 100644 --- a/auto-claude-ui/src/main/ipc-handlers/project-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/project-handlers.ts @@ -140,12 +140,12 @@ const detectAutoBuildSourcePath = (): string | null => { const debug = process.env.AUTO_CLAUDE_DEBUG === '1' || process.env.AUTO_CLAUDE_DEBUG === 'true'; if (debug) { - console.log('[project-handlers:detectAutoBuildSourcePath] Platform:', process.platform); - console.log('[project-handlers:detectAutoBuildSourcePath] Is dev:', is.dev); - console.log('[project-handlers:detectAutoBuildSourcePath] __dirname:', __dirname); - console.log('[project-handlers:detectAutoBuildSourcePath] app.getAppPath():', app.getAppPath()); - console.log('[project-handlers:detectAutoBuildSourcePath] process.cwd():', process.cwd()); - console.log('[project-handlers:detectAutoBuildSourcePath] Checking paths:', possiblePaths); + console.warn('[project-handlers:detectAutoBuildSourcePath] Platform:', process.platform); + console.warn('[project-handlers:detectAutoBuildSourcePath] Is dev:', is.dev); + console.warn('[project-handlers:detectAutoBuildSourcePath] __dirname:', __dirname); + console.warn('[project-handlers:detectAutoBuildSourcePath] app.getAppPath():', app.getAppPath()); + console.warn('[project-handlers:detectAutoBuildSourcePath] process.cwd():', process.cwd()); + console.warn('[project-handlers:detectAutoBuildSourcePath] Checking paths:', possiblePaths); } for (const p of possiblePaths) { @@ -154,11 +154,11 @@ const detectAutoBuildSourcePath = (): string | null => { const exists = existsSync(p) && existsSync(markerPath); if (debug) { - console.log(`[project-handlers:detectAutoBuildSourcePath] Checking ${p}: ${exists ? '✓ FOUND' : '✗ not found'}`); + console.warn(`[project-handlers:detectAutoBuildSourcePath] Checking ${p}: ${exists ? '✓ FOUND' : '✗ not found'}`); } if (exists) { - console.log(`[project-handlers:detectAutoBuildSourcePath] Auto-detected source path: ${p}`); + console.warn(`[project-handlers:detectAutoBuildSourcePath] Auto-detected source path: ${p}`); return p; } } @@ -197,7 +197,7 @@ const configureServicesWithPython = ( autoBuildPath: string, agentManager: AgentManager ): void => { - console.log('[IPC] Configuring services with Python:', pythonPath); + console.warn('[IPC] Configuring services with Python:', pythonPath); agentManager.configure(pythonPath, autoBuildPath); changelogService.configure(pythonPath, autoBuildPath); insightsService.configure(pythonPath, autoBuildPath); @@ -213,7 +213,7 @@ const initializePythonEnvironment = async ( ): Promise => { const autoBuildSource = getAutoBuildSourcePath(); if (!autoBuildSource) { - console.log('[IPC] Auto-build source not found, skipping Python env init'); + console.warn('[IPC] Auto-build source not found, skipping Python env init'); return { ready: false, pythonPath: null, @@ -223,7 +223,7 @@ const initializePythonEnvironment = async ( }; } - console.log('[IPC] Initializing Python environment...'); + console.warn('[IPC] Initializing Python environment...'); const status = await pythonEnvManager.initialize(autoBuildSource); if (status.ready && status.pythonPath) { @@ -280,11 +280,11 @@ export function registerProjectHandlers( // If a folder was deleted, reset autoBuildPath so UI prompts for reinitialization const resetIds = projectStore.validateProjects(); if (resetIds.length > 0) { - console.log('[IPC] PROJECT_LIST: Detected missing .auto-claude folders for', resetIds.length, 'project(s)'); + console.warn('[IPC] PROJECT_LIST: Detected missing .auto-claude folders for', resetIds.length, 'project(s)'); } const projects = projectStore.getProjects(); - console.log('[IPC] PROJECT_LIST returning', projects.length, 'projects'); + console.warn('[IPC] PROJECT_LIST returning', projects.length, 'projects'); return { success: true, data: projects }; } ); @@ -332,7 +332,7 @@ export function registerProjectHandlers( // Initialize Python environment on startup (non-blocking) initializePythonEnvironment(pythonEnvManager, agentManager).then((status) => { - console.log('[IPC] Python environment initialized:', status); + console.warn('[IPC] Python environment initialized:', status); }); // IPC handler to get Python environment status diff --git a/auto-claude-ui/src/main/ipc-handlers/roadmap-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/roadmap-handlers.ts index 2829fdc7..86bad572 100644 --- a/auto-claude-ui/src/main/ipc-handlers/roadmap-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/roadmap-handlers.ts @@ -5,7 +5,6 @@ import type { IPCResult, Roadmap, RoadmapFeature, RoadmapFeatureStatus, RoadmapG import path from 'path'; import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs'; import { projectStore } from '../project-store'; -import { fileWatcher } from '../file-watcher'; import { AgentManager } from '../agent'; diff --git a/auto-claude-ui/src/main/ipc-handlers/settings-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/settings-handlers.ts index a724731f..bee8b1d3 100644 --- a/auto-claude-ui/src/main/ipc-handlers/settings-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/settings-handlers.ts @@ -51,12 +51,12 @@ const detectAutoBuildSourcePath = (): string | null => { const debug = process.env.AUTO_CLAUDE_DEBUG === '1' || process.env.AUTO_CLAUDE_DEBUG === 'true'; if (debug) { - console.log('[detectAutoBuildSourcePath] Platform:', process.platform); - console.log('[detectAutoBuildSourcePath] Is dev:', is.dev); - console.log('[detectAutoBuildSourcePath] __dirname:', __dirname); - console.log('[detectAutoBuildSourcePath] app.getAppPath():', app.getAppPath()); - console.log('[detectAutoBuildSourcePath] process.cwd():', process.cwd()); - console.log('[detectAutoBuildSourcePath] Checking paths:', possiblePaths); + console.warn('[detectAutoBuildSourcePath] Platform:', process.platform); + console.warn('[detectAutoBuildSourcePath] Is dev:', is.dev); + console.warn('[detectAutoBuildSourcePath] __dirname:', __dirname); + console.warn('[detectAutoBuildSourcePath] app.getAppPath():', app.getAppPath()); + console.warn('[detectAutoBuildSourcePath] process.cwd():', process.cwd()); + console.warn('[detectAutoBuildSourcePath] Checking paths:', possiblePaths); } for (const p of possiblePaths) { @@ -65,11 +65,11 @@ const detectAutoBuildSourcePath = (): string | null => { const exists = existsSync(p) && existsSync(markerPath); if (debug) { - console.log(`[detectAutoBuildSourcePath] Checking ${p}: ${exists ? '✓ FOUND' : '✗ not found'}`); + console.warn(`[detectAutoBuildSourcePath] Checking ${p}: ${exists ? '✓ FOUND' : '✗ not found'}`); } if (exists) { - console.log(`[detectAutoBuildSourcePath] Auto-detected source path: ${p}`); + console.warn(`[detectAutoBuildSourcePath] Auto-detected source path: ${p}`); return p; } } diff --git a/auto-claude-ui/src/main/ipc-handlers/task/archive-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/task/archive-handlers.ts index 9f0dc55b..48b29b9e 100644 --- a/auto-claude-ui/src/main/ipc-handlers/task/archive-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/task/archive-handlers.ts @@ -18,12 +18,12 @@ export function registerTaskArchiveHandlers(): void { taskIds: string[], version?: string ): Promise> => { - console.log('[IPC] TASK_ARCHIVE called with projectId:', projectId, 'taskIds:', taskIds); + console.warn('[IPC] TASK_ARCHIVE called with projectId:', projectId, 'taskIds:', taskIds); const result = projectStore.archiveTasks(projectId, taskIds, version); if (result) { - console.log('[IPC] TASK_ARCHIVE success'); + console.warn('[IPC] TASK_ARCHIVE success'); return { success: true, data: true }; } else { console.error('[IPC] TASK_ARCHIVE failed'); @@ -38,12 +38,12 @@ export function registerTaskArchiveHandlers(): void { ipcMain.handle( IPC_CHANNELS.TASK_UNARCHIVE, async (_, projectId: string, taskIds: string[]): Promise> => { - console.log('[IPC] TASK_UNARCHIVE called with projectId:', projectId, 'taskIds:', taskIds); + console.warn('[IPC] TASK_UNARCHIVE called with projectId:', projectId, 'taskIds:', taskIds); const result = projectStore.unarchiveTasks(projectId, taskIds); if (result) { - console.log('[IPC] TASK_UNARCHIVE success'); + console.warn('[IPC] TASK_UNARCHIVE success'); return { success: true, data: true }; } else { console.error('[IPC] TASK_UNARCHIVE failed'); diff --git a/auto-claude-ui/src/main/ipc-handlers/task/crud-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/task/crud-handlers.ts index 49696a87..aa1a4246 100644 --- a/auto-claude-ui/src/main/ipc-handlers/task/crud-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/task/crud-handlers.ts @@ -1,6 +1,6 @@ import { ipcMain } from 'electron'; import { IPC_CHANNELS, AUTO_BUILD_PATHS, getSpecsDir } from '../../../shared/constants'; -import type { IPCResult, Task, TaskMetadata, Project } from '../../../shared/types'; +import type { IPCResult, Task, TaskMetadata } from '../../../shared/types'; import path from 'path'; import { existsSync, readFileSync, writeFileSync, readdirSync, mkdirSync } from 'fs'; import { projectStore } from '../../project-store'; @@ -18,9 +18,9 @@ export function registerTaskCRUDHandlers(agentManager: AgentManager): void { ipcMain.handle( IPC_CHANNELS.TASK_LIST, async (_, projectId: string): Promise> => { - console.log('[IPC] TASK_LIST called with projectId:', projectId); + console.warn('[IPC] TASK_LIST called with projectId:', projectId); const tasks = projectStore.getTasks(projectId); - console.log('[IPC] TASK_LIST returning', tasks.length, 'tasks'); + console.warn('[IPC] TASK_LIST returning', tasks.length, 'tasks'); return { success: true, data: tasks }; } ); @@ -45,17 +45,17 @@ export function registerTaskCRUDHandlers(agentManager: AgentManager): void { // Auto-generate title if empty using Claude AI let finalTitle = title; if (!title || !title.trim()) { - console.log('[TASK_CREATE] Title is empty, generating with Claude AI...'); + console.warn('[TASK_CREATE] Title is empty, generating with Claude AI...'); try { const generatedTitle = await titleGenerator.generateTitle(description); if (generatedTitle) { finalTitle = generatedTitle; - console.log('[TASK_CREATE] Generated title:', finalTitle); + console.warn('[TASK_CREATE] Generated title:', finalTitle); } else { // Fallback: create title from first line of description finalTitle = description.split('\n')[0].substring(0, 60); if (finalTitle.length === 60) finalTitle += '...'; - console.log('[TASK_CREATE] AI generation failed, using fallback:', finalTitle); + console.warn('[TASK_CREATE] AI generation failed, using fallback:', finalTitle); } } catch (err) { console.error('[TASK_CREATE] Title generation error:', err); @@ -226,7 +226,7 @@ export function registerTaskCRUDHandlers(agentManager: AgentManager): void { try { if (existsSync(specDir)) { await rm(specDir, { recursive: true, force: true }); - console.log(`[TASK_DELETE] Deleted spec directory: ${specDir}`); + console.warn(`[TASK_DELETE] Deleted spec directory: ${specDir}`); } return { success: true }; } catch (error) { @@ -269,17 +269,17 @@ export function registerTaskCRUDHandlers(agentManager: AgentManager): void { if (updates.title !== undefined && !updates.title.trim()) { // Get description to use for title generation const descriptionToUse = updates.description ?? task.description; - console.log('[TASK_UPDATE] Title is empty, generating with Claude AI...'); + console.warn('[TASK_UPDATE] Title is empty, generating with Claude AI...'); try { const generatedTitle = await titleGenerator.generateTitle(descriptionToUse); if (generatedTitle) { finalTitle = generatedTitle; - console.log('[TASK_UPDATE] Generated title:', finalTitle); + console.warn('[TASK_UPDATE] Generated title:', finalTitle); } else { // Fallback: create title from first line of description finalTitle = descriptionToUse.split('\n')[0].substring(0, 60); if (finalTitle.length === 60) finalTitle += '...'; - console.log('[TASK_UPDATE] AI generation failed, using fallback:', finalTitle); + console.warn('[TASK_UPDATE] AI generation failed, using fallback:', finalTitle); } } catch (err) { console.error('[TASK_UPDATE] Title generation error:', err); diff --git a/auto-claude-ui/src/main/ipc-handlers/task/execution-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/task/execution-handlers.ts index aaade6a0..ff1e19d3 100644 --- a/auto-claude-ui/src/main/ipc-handlers/task/execution-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/task/execution-handlers.ts @@ -21,10 +21,10 @@ export function registerTaskExecutionHandlers( ipcMain.on( IPC_CHANNELS.TASK_START, (_, taskId: string, _options?: TaskStartOptions) => { - console.log('[TASK_START] Received request for taskId:', taskId); + console.warn('[TASK_START] Received request for taskId:', taskId); const mainWindow = getMainWindow(); if (!mainWindow) { - console.log('[TASK_START] No main window found'); + console.warn('[TASK_START] No main window found'); return; } @@ -32,7 +32,7 @@ export function registerTaskExecutionHandlers( const { task, project } = findTaskAndProject(taskId); if (!task || !project) { - console.log('[TASK_START] Task or project not found for taskId:', taskId); + console.warn('[TASK_START] Task or project not found for taskId:', taskId); mainWindow.webContents.send( IPC_CHANNELS.TASK_ERROR, taskId, @@ -44,7 +44,7 @@ export function registerTaskExecutionHandlers( // Check git status - Auto Claude requires git for worktree-based builds const gitStatus = checkGitStatus(project.path); if (!gitStatus.isGitRepo) { - console.log('[TASK_START] Project is not a git repository:', project.path); + console.warn('[TASK_START] Project is not a git repository:', project.path); mainWindow.webContents.send( IPC_CHANNELS.TASK_ERROR, taskId, @@ -53,7 +53,7 @@ export function registerTaskExecutionHandlers( return; } if (!gitStatus.hasCommits) { - console.log('[TASK_START] Git repository has no commits:', project.path); + console.warn('[TASK_START] Git repository has no commits:', project.path); mainWindow.webContents.send( IPC_CHANNELS.TASK_ERROR, taskId, @@ -62,7 +62,7 @@ export function registerTaskExecutionHandlers( return; } - console.log('[TASK_START] Found task:', task.specId, 'status:', task.status, 'subtasks:', task.subtasks.length); + console.warn('[TASK_START] Found task:', task.specId, 'status:', task.status, 'subtasks:', task.subtasks.length); // Start file watcher for this task const specsBaseDir = getSpecsDir(project.autoBuildPath); @@ -82,7 +82,7 @@ export function registerTaskExecutionHandlers( const needsSpecCreation = !hasSpec; const needsImplementation = hasSpec && task.subtasks.length === 0; - console.log('[TASK_START] hasSpec:', hasSpec, 'needsSpecCreation:', needsSpecCreation, 'needsImplementation:', needsImplementation); + console.warn('[TASK_START] hasSpec:', hasSpec, 'needsSpecCreation:', needsSpecCreation, 'needsImplementation:', needsImplementation); // Get base branch from project settings for worktree creation const baseBranch = project.settings?.mainBranch; @@ -90,7 +90,7 @@ export function registerTaskExecutionHandlers( if (needsSpecCreation) { // No spec file - need to run spec_runner.py to create the spec const taskDescription = task.description || task.title; - console.log('[TASK_START] Starting spec creation for:', task.specId, 'in:', specDir); + console.warn('[TASK_START] Starting spec creation for:', task.specId, 'in:', specDir); // Start spec creation process - pass the existing spec directory // so spec_runner uses it instead of creating a new one @@ -105,7 +105,7 @@ export function registerTaskExecutionHandlers( // Use default description } - console.log('[TASK_START] Starting task execution (no subtasks) for:', task.specId); + console.warn('[TASK_START] Starting task execution (no subtasks) for:', task.specId); // Start task execution which will create the implementation plan // Note: No parallel mode for planning phase - parallel only makes sense with multiple subtasks agentManager.startTaskExecution( @@ -121,7 +121,7 @@ export function registerTaskExecutionHandlers( } else { // Task has subtasks, start normal execution // Note: Parallel execution is handled internally by the agent, not via CLI flags - console.log('[TASK_START] Starting task execution (has subtasks) for:', task.specId); + console.warn('[TASK_START] Starting task execution (has subtasks) for:', task.specId); agentManager.startTaskExecution( taskId, @@ -313,7 +313,7 @@ export function registerTaskExecutionHandlers( // Check git status before auto-starting const gitStatusCheck = checkGitStatus(project.path); if (!gitStatusCheck.isGitRepo || !gitStatusCheck.hasCommits) { - console.log('[TASK_UPDATE_STATUS] Git check failed, cannot auto-start task'); + console.warn('[TASK_UPDATE_STATUS] Git check failed, cannot auto-start task'); if (mainWindow) { mainWindow.webContents.send( IPC_CHANNELS.TASK_ERROR, @@ -324,7 +324,7 @@ export function registerTaskExecutionHandlers( return { success: false, error: gitStatusCheck.error || 'Git repository required' }; } - console.log('[TASK_UPDATE_STATUS] Auto-starting task:', taskId); + console.warn('[TASK_UPDATE_STATUS] Auto-starting task:', taskId); // Start file watcher for this task fileWatcher.watch(taskId, specDir); @@ -335,16 +335,16 @@ export function registerTaskExecutionHandlers( const needsSpecCreation = !hasSpec; const needsImplementation = hasSpec && task.subtasks.length === 0; - console.log('[TASK_UPDATE_STATUS] hasSpec:', hasSpec, 'needsSpecCreation:', needsSpecCreation, 'needsImplementation:', needsImplementation); + console.warn('[TASK_UPDATE_STATUS] hasSpec:', hasSpec, 'needsSpecCreation:', needsSpecCreation, 'needsImplementation:', needsImplementation); if (needsSpecCreation) { // No spec file - need to run spec_runner.py to create the spec const taskDescription = task.description || task.title; - console.log('[TASK_UPDATE_STATUS] Starting spec creation for:', task.specId); + console.warn('[TASK_UPDATE_STATUS] Starting spec creation for:', task.specId); agentManager.startSpecCreation(task.specId, project.path, taskDescription, specDir, task.metadata); } else if (needsImplementation) { // Spec exists but no subtasks - run run.py to create implementation plan and execute - console.log('[TASK_UPDATE_STATUS] Starting task execution (no subtasks) for:', task.specId); + console.warn('[TASK_UPDATE_STATUS] Starting task execution (no subtasks) for:', task.specId); agentManager.startTaskExecution( taskId, project.path, @@ -357,7 +357,7 @@ export function registerTaskExecutionHandlers( } else { // Task has subtasks, start normal execution // Note: Parallel execution is handled internally by the agent - console.log('[TASK_UPDATE_STATUS] Starting task execution (has subtasks) for:', task.specId); + console.warn('[TASK_UPDATE_STATUS] Starting task execution (has subtasks) for:', task.specId); agentManager.startTaskExecution( taskId, project.path, @@ -538,7 +538,7 @@ export function registerTaskExecutionHandlers( // Check git status before auto-restarting const gitStatusForRestart = checkGitStatus(project.path); if (!gitStatusForRestart.isGitRepo || !gitStatusForRestart.hasCommits) { - console.log('[Recovery] Git check failed, cannot auto-restart task'); + console.warn('[Recovery] Git check failed, cannot auto-restart task'); // Recovery succeeded but we can't restart without git return { success: true, @@ -577,11 +577,11 @@ export function registerTaskExecutionHandlers( if (needsSpecCreation) { // No spec file - need to run spec_runner.py to create the spec const taskDescription = task.description || task.title; - console.log(`[Recovery] Starting spec creation for: ${task.specId}`); + console.warn(`[Recovery] Starting spec creation for: ${task.specId}`); agentManager.startSpecCreation(task.specId, project.path, taskDescription, specDirForWatcher, task.metadata); } else { // Spec exists - run task execution - console.log(`[Recovery] Starting task execution for: ${task.specId}`); + console.warn(`[Recovery] Starting task execution for: ${task.specId}`); agentManager.startTaskExecution( taskId, project.path, @@ -594,7 +594,7 @@ export function registerTaskExecutionHandlers( } autoRestarted = true; - console.log(`[Recovery] Auto-restarted task ${taskId}`); + console.warn(`[Recovery] Auto-restarted task ${taskId}`); } catch (restartError) { console.error('Failed to auto-restart task after recovery:', restartError); // Recovery succeeded but restart failed - still report success diff --git a/auto-claude-ui/src/main/ipc-handlers/task/worktree-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/task/worktree-handlers.ts index bc424886..c606c4d4 100644 --- a/auto-claude-ui/src/main/ipc-handlers/task/worktree-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/task/worktree-handlers.ts @@ -1,5 +1,5 @@ import { ipcMain, BrowserWindow } from 'electron'; -import { IPC_CHANNELS, AUTO_BUILD_PATHS, getSpecsDir } from '../../../shared/constants'; +import { IPC_CHANNELS, AUTO_BUILD_PATHS } from '../../../shared/constants'; import type { IPCResult, WorktreeStatus, WorktreeDiff, WorktreeDiffFile, WorktreeMergeResult, WorktreeDiscardResult, WorktreeListResult, WorktreeListItem } from '../../../shared/types'; import path from 'path'; import { existsSync, readdirSync, statSync } from 'fs'; @@ -226,11 +226,11 @@ export function registerWorktreeHandlers( async (_, taskId: string, options?: { noCommit?: boolean }): Promise> => { // Always log merge operations for debugging const debug = (...args: unknown[]) => { - console.log('[MERGE DEBUG]', ...args); + console.warn('[MERGE DEBUG]', ...args); }; try { - console.log('[MERGE] Handler called with taskId:', taskId, 'options:', options); + console.warn('[MERGE] Handler called with taskId:', taskId, 'options:', options); debug('Starting merge for taskId:', taskId, 'options:', options); // Ensure Python environment is ready @@ -501,11 +501,11 @@ export function registerWorktreeHandlers( ipcMain.handle( IPC_CHANNELS.TASK_WORKTREE_MERGE_PREVIEW, async (_, taskId: string): Promise> => { - console.log('[IPC] TASK_WORKTREE_MERGE_PREVIEW called with taskId:', taskId); + console.warn('[IPC] TASK_WORKTREE_MERGE_PREVIEW called with taskId:', taskId); try { // Ensure Python environment is ready if (!pythonEnvManager.isEnvReady()) { - console.log('[IPC] Python environment not ready, initializing...'); + console.warn('[IPC] Python environment not ready, initializing...'); const autoBuildSource = getEffectiveSourcePath(); if (autoBuildSource) { const status = await pythonEnvManager.initialize(autoBuildSource); @@ -524,7 +524,7 @@ export function registerWorktreeHandlers( console.error('[IPC] Task not found:', taskId); return { success: false, error: 'Task not found' }; } - console.log('[IPC] Found task:', task.specId, 'project:', project.name); + console.warn('[IPC] Found task:', task.specId, 'project:', project.name); // Check for uncommitted changes in the main project let hasUncommittedChanges = false; @@ -541,7 +541,7 @@ export function registerWorktreeHandlers( .filter(line => line.trim()) .map(line => line.substring(3).trim()); // Remove status prefix (e.g., "M ", " M ", "?? ") hasUncommittedChanges = uncommittedFiles.length > 0; - console.log('[IPC] Uncommitted changes detected:', uncommittedFiles.length, 'files'); + console.warn('[IPC] Uncommitted changes detected:', uncommittedFiles.length, 'files'); } } catch (e) { console.error('[IPC] Failed to check git status:', e); @@ -562,7 +562,7 @@ export function registerWorktreeHandlers( ]; const pythonPath = pythonEnvManager.getPythonPath() || 'python3'; - console.log('[IPC] Running merge preview:', pythonPath, args.join(' ')); + console.warn('[IPC] Running merge preview:', pythonPath, args.join(' ')); // Get profile environment for consistency const previewProfileEnv = getProfileEnv(); @@ -579,22 +579,22 @@ export function registerWorktreeHandlers( previewProcess.stdout.on('data', (data: Buffer) => { const chunk = data.toString(); stdout += chunk; - console.log('[IPC] merge-preview stdout:', chunk); + console.warn('[IPC] merge-preview stdout:', chunk); }); previewProcess.stderr.on('data', (data: Buffer) => { const chunk = data.toString(); stderr += chunk; - console.log('[IPC] merge-preview stderr:', chunk); + console.warn('[IPC] merge-preview stderr:', chunk); }); previewProcess.on('close', (code: number) => { - console.log('[IPC] merge-preview process exited with code:', code); + console.warn('[IPC] merge-preview process exited with code:', code); if (code === 0) { try { // Parse JSON output from Python const result = JSON.parse(stdout.trim()); - console.log('[IPC] merge-preview result:', JSON.stringify(result, null, 2)); + console.warn('[IPC] merge-preview result:', JSON.stringify(result, null, 2)); resolve({ success: true, data: { diff --git a/auto-claude-ui/src/main/ipc-handlers/terminal-handlers.ts b/auto-claude-ui/src/main/ipc-handlers/terminal-handlers.ts index 26c39ffc..6e9ecb65 100644 --- a/auto-claude-ui/src/main/ipc-handlers/terminal-handlers.ts +++ b/auto-claude-ui/src/main/ipc-handlers/terminal-handlers.ts @@ -208,7 +208,7 @@ export function registerTerminalHandlers( const { mkdirSync, existsSync } = await import('fs'); if (!existsSync(profile.configDir)) { mkdirSync(profile.configDir, { recursive: true }); - console.log('[IPC] Created config directory:', profile.configDir); + console.warn('[IPC] Created config directory:', profile.configDir); } } @@ -217,7 +217,7 @@ export function registerTerminalHandlers( const terminalId = `claude-login-${profileId}-${Date.now()}`; const homeDir = process.env.HOME || process.env.USERPROFILE || '/tmp'; - console.log('[IPC] Initializing Claude profile:', { + console.warn('[IPC] Initializing Claude profile:', { profileId, profileName: profile.name, configDir: profile.configDir, @@ -240,7 +240,7 @@ export function registerTerminalHandlers( loginCommand = 'claude setup-token'; } - console.log('[IPC] Sending login command to terminal:', loginCommand); + console.warn('[IPC] Sending login command to terminal:', loginCommand); // Write the login command to the terminal terminalManager.write(terminalId, `${loginCommand}\r`); @@ -255,12 +255,12 @@ export function registerTerminalHandlers( }); } - return { - success: true, - data: { + return { + success: true, + data: { terminalId, message: `A terminal has been opened to authenticate "${profile.name}". Complete the OAuth flow in your browser, then copy the token shown in the terminal.` - } + } }; } catch (error) { console.error('[IPC] Failed to initialize Claude profile:', error); @@ -569,5 +569,5 @@ export function initializeUsageMonitorForwarding(mainWindow: BrowserWindow): voi mainWindow.webContents.send(IPC_CHANNELS.PROACTIVE_SWAP_NOTIFICATION, notification); }); - console.log('[terminal-handlers] Usage monitor event forwarding initialized'); + console.warn('[terminal-handlers] Usage monitor event forwarding initialized'); } diff --git a/auto-claude-ui/src/main/log-service.ts b/auto-claude-ui/src/main/log-service.ts index 5fe51bfc..58ba24b7 100644 --- a/auto-claude-ui/src/main/log-service.ts +++ b/auto-claude-ui/src/main/log-service.ts @@ -17,7 +17,7 @@ export interface LogEntry { /** * Service for persisting and retrieving task execution logs - * + * * Log files are stored in {specDir}/logs/ with format: * - session-{ISO-timestamp}.log - Raw log output per execution session * - latest.log - Copy of most recent session's logs @@ -26,7 +26,7 @@ export class LogService { private activeSessions: Map = new Map(); private logBuffers: Map = new Map(); private flushIntervals: Map = new Map(); - + // Flush logs to disk every 2 seconds to balance performance vs data safety private readonly FLUSH_INTERVAL_MS = 2000; // Maximum log file size before rotation (10MB) @@ -39,7 +39,7 @@ export class LogService { */ startSession(taskId: string, specDir: string): string { const logsDir = path.join(specDir, 'logs'); - + // Ensure logs directory exists if (!existsSync(logsDir)) { mkdirSync(logsDir, { recursive: true }); @@ -60,7 +60,7 @@ export class LogService { '='.repeat(80), '' ].join('\n'); - + writeFileSync(logFile, header); // Track active session @@ -82,7 +82,7 @@ export class LogService { // Clean up old sessions this.cleanupOldSessions(logsDir); - console.log(`[LogService] Started session ${sessionId} for task ${taskId}`); + console.warn(`[LogService] Started session ${sessionId} for task ${taskId}`); return sessionId; } @@ -120,7 +120,7 @@ export class LogService { private flushBuffer(taskId: string): void { const session = this.activeSessions.get(taskId); const buffer = this.logBuffers.get(taskId); - + if (!session || !buffer || buffer.length === 0) { return; } @@ -150,7 +150,7 @@ export class LogService { const now = new Date(); const duration = now.getTime() - session.startedAt.getTime(); const durationStr = this.formatDuration(duration); - + const footer = [ '', '='.repeat(80), @@ -181,7 +181,7 @@ export class LogService { this.activeSessions.delete(taskId); this.logBuffers.delete(taskId); - console.log(`[LogService] Ended session for task ${taskId}, exit code: ${exitCode}`); + console.warn(`[LogService] Ended session for task ${taskId}, exit code: ${exitCode}`); } /** @@ -189,7 +189,7 @@ export class LogService { */ getSessions(specDir: string): LogSession[] { const logsDir = path.join(specDir, 'logs'); - + if (!existsSync(logsDir)) { return []; } @@ -203,7 +203,7 @@ export class LogService { const filePath = path.join(logsDir, file); const stats = statSync(filePath); const sessionId = file.replace('session-', '').replace('.log', ''); - + // Parse session ID back to date const dateStr = sessionId.replace(/-/g, (match, offset) => { // Replace first 2 dashes with actual dashes, rest with colons @@ -211,7 +211,7 @@ export class LogService { if (offset === 10) return 'T'; return ':'; }).replace(/-(\d{3})Z$/, '.$1Z'); - + const startedAt = new Date(dateStr); // Count lines (approximate) @@ -233,7 +233,7 @@ export class LogService { */ loadSessionLogs(specDir: string, sessionId?: string): string { const logsDir = path.join(specDir, 'logs'); - + if (!existsSync(logsDir)) { return ''; } @@ -289,17 +289,17 @@ export class LogService { // Keep MAX_SESSIONS_TO_KEEP, delete the rest const toDelete = files.slice(this.MAX_SESSIONS_TO_KEEP); - + for (const file of toDelete) { const filePath = path.join(logsDir, file); try { require('fs').unlinkSync(filePath); - console.log(`[LogService] Deleted old log session: ${file}`); - } catch (e) { + console.warn(`[LogService] Deleted old log session: ${file}`); + } catch (_e) { // Ignore deletion errors } } - } catch (error) { + } catch (_error) { // Ignore cleanup errors } } @@ -339,4 +339,3 @@ export class LogService { // Singleton instance export const logService = new LogService(); - diff --git a/auto-claude-ui/src/main/project-initializer.ts b/auto-claude-ui/src/main/project-initializer.ts index 2ba339ac..c18a621a 100644 --- a/auto-claude-ui/src/main/project-initializer.ts +++ b/auto-claude-ui/src/main/project-initializer.ts @@ -10,9 +10,9 @@ const DEBUG = process.env.AUTO_CLAUDE_DEBUG === 'true' || process.env.AUTO_CLAUD function debug(message: string, data?: Record): void { if (DEBUG) { if (data) { - console.log(`[ProjectInitializer] ${message}`, JSON.stringify(data, null, 2)); + console.warn(`[ProjectInitializer] ${message}`, JSON.stringify(data, null, 2)); } else { - console.log(`[ProjectInitializer] ${message}`); + console.warn(`[ProjectInitializer] ${message}`); } } } diff --git a/auto-claude-ui/src/main/project-store.ts b/auto-claude-ui/src/main/project-store.ts index 2b380562..e77207fb 100644 --- a/auto-claude-ui/src/main/project-store.ts +++ b/auto-claude-ui/src/main/project-store.ts @@ -145,13 +145,13 @@ export class ProjectStore { // Check if the project path still exists if (!existsSync(project.path)) { - console.log(`[ProjectStore] Project path no longer exists: ${project.path}`); + console.warn(`[ProjectStore] Project path no longer exists: ${project.path}`); continue; // Don't reset - let user handle this case } // Check if .auto-claude folder still exists if (!isInitialized(project.path)) { - console.log(`[ProjectStore] .auto-claude folder missing for project "${project.name}" at ${project.path}`); + console.warn(`[ProjectStore] .auto-claude folder missing for project "${project.name}" at ${project.path}`); project.autoBuildPath = ''; project.updatedAt = new Date(); resetProjectIds.push(project.id); @@ -161,7 +161,7 @@ export class ProjectStore { if (hasChanges) { this.save(); - console.log(`[ProjectStore] Reset ${resetProjectIds.length} project(s) due to missing .auto-claude folder`); + console.warn(`[ProjectStore] Reset ${resetProjectIds.length} project(s) due to missing .auto-claude folder`); } return resetProjectIds; @@ -194,18 +194,18 @@ export class ProjectStore { * Get tasks for a project by scanning specs directory */ getTasks(projectId: string): Task[] { - console.log('[ProjectStore] getTasks called with projectId:', projectId); + console.warn('[ProjectStore] getTasks called with projectId:', projectId); const project = this.getProject(projectId); if (!project) { - console.log('[ProjectStore] Project not found for id:', projectId); + console.warn('[ProjectStore] Project not found for id:', projectId); return []; } - console.log('[ProjectStore] Found project:', project.name, 'autoBuildPath:', project.autoBuildPath); + console.warn('[ProjectStore] Found project:', project.name, 'autoBuildPath:', project.autoBuildPath); // Get specs directory path const specsBaseDir = getSpecsDir(project.autoBuildPath); const specsDir = path.join(project.path, specsBaseDir); - console.log('[ProjectStore] specsDir:', specsDir, 'exists:', existsSync(specsDir)); + console.warn('[ProjectStore] specsDir:', specsDir, 'exists:', existsSync(specsDir)); if (!existsSync(specsDir)) return []; const tasks: Task[] = []; @@ -312,7 +312,7 @@ export class ProjectStore { } } - console.log('[ProjectStore] Returning', tasks.length, 'tasks out of', specDirs.filter(d => d.isDirectory() && d.name !== '.gitkeep').length, 'spec directories'); + console.warn('[ProjectStore] Returning', tasks.length, 'tasks out of', specDirs.filter(d => d.isDirectory() && d.name !== '.gitkeep').length, 'spec directories'); return tasks; } diff --git a/auto-claude-ui/src/main/python-env-manager.ts b/auto-claude-ui/src/main/python-env-manager.ts index 0fc9d50f..75fcdc4e 100644 --- a/auto-claude-ui/src/main/python-env-manager.ts +++ b/auto-claude-ui/src/main/python-env-manager.ts @@ -1,5 +1,5 @@ import { spawn, execSync } from 'child_process'; -import { existsSync, readFileSync } from 'fs'; +import { existsSync } from 'fs'; import path from 'path'; import { EventEmitter } from 'events'; @@ -147,7 +147,7 @@ export class PythonEnvManager extends EventEmitter { } this.emit('status', 'Creating Python virtual environment...'); - console.log('[PythonEnvManager] Creating venv with:', systemPython); + console.warn('[PythonEnvManager] Creating venv with:', systemPython); return new Promise((resolve) => { const venvPath = path.join(this.autoBuildSourcePath!, '.venv'); @@ -163,7 +163,7 @@ export class PythonEnvManager extends EventEmitter { proc.on('close', (code) => { if (code === 0) { - console.log('[PythonEnvManager] Venv created successfully'); + console.warn('[PythonEnvManager] Venv created successfully'); resolve(true); } else { console.error('[PythonEnvManager] Failed to create venv:', stderr); @@ -200,7 +200,7 @@ export class PythonEnvManager extends EventEmitter { } this.emit('status', 'Installing Python dependencies (this may take a minute)...'); - console.log('[PythonEnvManager] Installing dependencies from:', requirementsPath); + console.warn('[PythonEnvManager] Installing dependencies from:', requirementsPath); return new Promise((resolve) => { const proc = spawn(venvPip, ['install', '-r', requirementsPath], { @@ -228,7 +228,7 @@ export class PythonEnvManager extends EventEmitter { proc.on('close', (code) => { if (code === 0) { - console.log('[PythonEnvManager] Dependencies installed successfully'); + console.warn('[PythonEnvManager] Dependencies installed successfully'); this.emit('status', 'Dependencies installed successfully'); resolve(true); } else { @@ -264,12 +264,12 @@ export class PythonEnvManager extends EventEmitter { this.isInitializing = true; this.autoBuildSourcePath = autoBuildSourcePath; - console.log('[PythonEnvManager] Initializing with path:', autoBuildSourcePath); + console.warn('[PythonEnvManager] Initializing with path:', autoBuildSourcePath); try { // Check if venv exists if (!this.venvExists()) { - console.log('[PythonEnvManager] Venv not found, creating...'); + console.warn('[PythonEnvManager] Venv not found, creating...'); const created = await this.createVenv(); if (!created) { this.isInitializing = false; @@ -282,13 +282,13 @@ export class PythonEnvManager extends EventEmitter { }; } } else { - console.log('[PythonEnvManager] Venv already exists'); + console.warn('[PythonEnvManager] Venv already exists'); } // Check if deps are installed const depsInstalled = await this.checkDepsInstalled(); if (!depsInstalled) { - console.log('[PythonEnvManager] Dependencies not installed, installing...'); + console.warn('[PythonEnvManager] Dependencies not installed, installing...'); const installed = await this.installDeps(); if (!installed) { this.isInitializing = false; @@ -301,7 +301,7 @@ export class PythonEnvManager extends EventEmitter { }; } } else { - console.log('[PythonEnvManager] Dependencies already installed'); + console.warn('[PythonEnvManager] Dependencies already installed'); } this.pythonPath = this.getVenvPythonPath(); @@ -309,7 +309,7 @@ export class PythonEnvManager extends EventEmitter { this.isInitializing = false; this.emit('ready', this.pythonPath); - console.log('[PythonEnvManager] Ready with Python path:', this.pythonPath); + console.warn('[PythonEnvManager] Ready with Python path:', this.pythonPath); return { ready: true, @@ -362,4 +362,3 @@ export class PythonEnvManager extends EventEmitter { // Singleton instance export const pythonEnvManager = new PythonEnvManager(); - diff --git a/auto-claude-ui/src/main/rate-limit-detector.ts b/auto-claude-ui/src/main/rate-limit-detector.ts index 97257df3..fc0c0cf0 100644 --- a/auto-claude-ui/src/main/rate-limit-detector.ts +++ b/auto-claude-ui/src/main/rate-limit-detector.ts @@ -144,7 +144,7 @@ export function getProfileEnv(profileId?: string): Record { ? profileManager.getProfile(profileId) : profileManager.getActiveProfile(); - console.log('[getProfileEnv] Active profile:', { + console.warn('[getProfileEnv] Active profile:', { profileId: profile?.id, profileName: profile?.name, email: profile?.email, @@ -154,19 +154,19 @@ export function getProfileEnv(profileId?: string): Record { }); if (!profile) { - console.log('[getProfileEnv] No profile found, using defaults'); + console.warn('[getProfileEnv] No profile found, using defaults'); return {}; } // Prefer OAuth token (instant switching, no browser auth needed) // Use profile manager to get decrypted token if (profile.oauthToken) { - const decryptedToken = profileId + const decryptedToken = profileId ? profileManager.getProfileToken(profileId) : profileManager.getActiveProfileToken(); - + if (decryptedToken) { - console.log('[getProfileEnv] Using OAuth token for profile:', profile.name); + console.warn('[getProfileEnv] Using OAuth token for profile:', profile.name); return { CLAUDE_CODE_OAUTH_TOKEN: decryptedToken }; @@ -177,20 +177,20 @@ export function getProfileEnv(profileId?: string): Record { // Fallback: If default profile, no env vars needed if (profile.isDefault) { - console.log('[getProfileEnv] Using default profile (no env vars)'); + console.warn('[getProfileEnv] Using default profile (no env vars)'); return {}; } // Fallback: Use configDir for profiles without OAuth token (legacy) if (profile.configDir) { - console.log('[getProfileEnv] Using configDir fallback for profile:', profile.name); + console.warn('[getProfileEnv] Using configDir fallback for profile:', profile.name); console.warn('[getProfileEnv] WARNING: Profile has no OAuth token. Run "claude setup-token" and save the token to enable instant switching.'); return { CLAUDE_CONFIG_DIR: profile.configDir }; } - console.log('[getProfileEnv] Profile has no auth method configured'); + console.warn('[getProfileEnv] Profile has no auth method configured'); return {}; } diff --git a/auto-claude-ui/src/main/task-log-service.ts b/auto-claude-ui/src/main/task-log-service.ts index 5b159bdc..8cd46a63 100644 --- a/auto-claude-ui/src/main/task-log-service.ts +++ b/auto-claude-ui/src/main/task-log-service.ts @@ -1,5 +1,5 @@ import path from 'path'; -import { existsSync, readFileSync, watchFile, unwatchFile, FSWatcher } from 'fs'; +import { existsSync, readFileSync, watchFile } from 'fs'; import { EventEmitter } from 'events'; import type { TaskLogs, TaskLogPhase, TaskLogStreamChunk, TaskPhaseLog } from '../shared/types'; @@ -189,7 +189,7 @@ export class TaskLogService extends EventEmitter { if (existsSync(mainLogFile)) { try { lastMainContent = readFileSync(mainLogFile, 'utf-8'); - } catch (e) { + } catch (_e) { // Ignore parse errors on initial load } } @@ -200,7 +200,7 @@ export class TaskLogService extends EventEmitter { if (existsSync(worktreeLogFile)) { try { lastWorktreeContent = readFileSync(worktreeLogFile, 'utf-8'); - } catch (e) { + } catch (_e) { // Ignore parse errors on initial load } } @@ -225,7 +225,7 @@ export class TaskLogService extends EventEmitter { lastMainContent = currentContent; mainChanged = true; } - } catch (error) { + } catch (_error) { // Ignore read/parse errors } } @@ -240,7 +240,7 @@ export class TaskLogService extends EventEmitter { lastWorktreeContent = currentContent; worktreeChanged = true; } - } catch (error) { + } catch (_error) { // Ignore read/parse errors } } @@ -262,7 +262,7 @@ export class TaskLogService extends EventEmitter { }, this.POLL_INTERVAL_MS); this.pollIntervals.set(specId, pollInterval); - console.log(`[TaskLogService] Started watching ${specId} (main: ${specDir}${worktreeSpecDir ? `, worktree: ${worktreeSpecDir}` : ''})`); + console.warn(`[TaskLogService] Started watching ${specId} (main: ${specDir}${worktreeSpecDir ? `, worktree: ${worktreeSpecDir}` : ''})`); } /** @@ -274,7 +274,7 @@ export class TaskLogService extends EventEmitter { clearInterval(interval); this.pollIntervals.delete(specId); this.watchedPaths.delete(specId); - console.log(`[TaskLogService] Stopped watching ${specId}`); + console.warn(`[TaskLogService] Stopped watching ${specId}`); } } diff --git a/auto-claude-ui/src/main/terminal-name-generator.ts b/auto-claude-ui/src/main/terminal-name-generator.ts index d7f9153b..6d6c794c 100644 --- a/auto-claude-ui/src/main/terminal-name-generator.ts +++ b/auto-claude-ui/src/main/terminal-name-generator.ts @@ -12,7 +12,7 @@ const DEBUG = process.env.AUTO_CLAUDE_DEBUG === 'true' || process.env.AUTO_CLAUD function debug(...args: unknown[]): void { if (DEBUG) { - console.log('[TerminalNameGenerator]', ...args); + console.warn('[TerminalNameGenerator]', ...args); } } diff --git a/auto-claude-ui/src/main/terminal-session-store.ts b/auto-claude-ui/src/main/terminal-session-store.ts index 03babd52..b3637756 100644 --- a/auto-claude-ui/src/main/terminal-session-store.ts +++ b/auto-claude-ui/src/main/terminal-session-store.ts @@ -100,7 +100,7 @@ export class TerminalSessionStore { // Migrate from v1 to v2 structure if (data.version === 1 && data.sessions) { - console.log('[TerminalSessionStore] Migrating from v1 to v2 structure'); + console.warn('[TerminalSessionStore] Migrating from v1 to v2 structure'); const today = getDateString(); const migratedData: SessionData = { version: STORE_VERSION, @@ -115,7 +115,7 @@ export class TerminalSessionStore { return data as SessionData; } - console.log('[TerminalSessionStore] Version mismatch, resetting sessions'); + console.warn('[TerminalSessionStore] Version mismatch, resetting sessions'); return { version: STORE_VERSION, sessionsByDate: {} }; } } catch (error) { @@ -155,7 +155,7 @@ export class TerminalSessionStore { } if (removedCount > 0) { - console.log(`[TerminalSessionStore] Cleaned up sessions from ${removedCount} old dates`); + console.warn(`[TerminalSessionStore] Cleaned up sessions from ${removedCount} old dates`); this.save(); } } @@ -225,7 +225,7 @@ export class TerminalSessionStore { if (dates.length > 0) { const mostRecentDate = dates[0]; - console.log(`[TerminalSessionStore] No sessions today, using sessions from ${mostRecentDate}`); + console.warn(`[TerminalSessionStore] No sessions today, using sessions from ${mostRecentDate}`); return this.data.sessionsByDate[mostRecentDate][projectPath] || []; } @@ -361,7 +361,7 @@ export class TerminalSessionStore { session.claudeSessionId = claudeSessionId; session.isClaudeMode = true; this.save(); - console.log('[TerminalSessionStore] Saved Claude session ID:', claudeSessionId, 'for terminal:', terminalId); + console.warn('[TerminalSessionStore] Saved Claude session ID:', claudeSessionId, 'for terminal:', terminalId); } } diff --git a/auto-claude-ui/src/main/terminal/claude-integration-handler.ts b/auto-claude-ui/src/main/terminal/claude-integration-handler.ts index cc2ea8ef..059212a6 100644 --- a/auto-claude-ui/src/main/terminal/claude-integration-handler.ts +++ b/auto-claude-ui/src/main/terminal/claude-integration-handler.ts @@ -6,7 +6,6 @@ import * as os from 'os'; import * as fs from 'fs'; import * as path from 'path'; -import type { BrowserWindow } from 'electron'; import { IPC_CHANNELS } from '../../shared/constants'; import { getClaudeProfileManager } from '../claude-profile-manager'; import * as OutputParser from './output-parser'; @@ -39,14 +38,14 @@ export function handleRateLimit( } lastNotifiedRateLimitReset.set(terminal.id, resetTime); - console.log('[ClaudeIntegration] Rate limit detected, reset:', resetTime); + console.warn('[ClaudeIntegration] Rate limit detected, reset:', resetTime); const profileManager = getClaudeProfileManager(); const currentProfileId = terminal.claudeProfileId || 'default'; try { const rateLimitEvent = profileManager.recordRateLimitEvent(currentProfileId, resetTime); - console.log('[ClaudeIntegration] Recorded rate limit event:', rateLimitEvent.type); + console.warn('[ClaudeIntegration] Recorded rate limit event:', rateLimitEvent.type); } catch (err) { console.error('[ClaudeIntegration] Failed to record rate limit event:', err); } @@ -68,9 +67,9 @@ export function handleRateLimit( } if (autoSwitchSettings.enabled && autoSwitchSettings.autoSwitchOnRateLimit && bestProfile) { - console.log('[ClaudeIntegration] Auto-switching to profile:', bestProfile.name); - switchProfileCallback(terminal.id, bestProfile.id).then(result => { - console.log('[ClaudeIntegration] Auto-switch completed'); + console.warn('[ClaudeIntegration] Auto-switching to profile:', bestProfile.name); + switchProfileCallback(terminal.id, bestProfile.id).then(_result => { + console.warn('[ClaudeIntegration] Auto-switch completed'); }).catch(err => { console.error('[ClaudeIntegration] Auto-switch failed:', err); }); @@ -90,7 +89,7 @@ export function handleOAuthToken( return; } - console.log('[ClaudeIntegration] OAuth token detected, length:', token.length); + console.warn('[ClaudeIntegration] OAuth token detected, length:', token.length); const email = OutputParser.extractEmail(terminal.outputBuffer); const profileIdMatch = terminal.id.match(/claude-login-(profile-\d+)-/); @@ -101,7 +100,7 @@ export function handleOAuthToken( const success = profileManager.setProfileToken(profileId, token, email || undefined); if (success) { - console.log('[ClaudeIntegration] OAuth token auto-saved to profile:', profileId); + console.warn('[ClaudeIntegration] OAuth token auto-saved to profile:', profileId); const win = getWindow(); if (win) { @@ -117,7 +116,7 @@ export function handleOAuthToken( console.error('[ClaudeIntegration] Failed to save OAuth token to profile:', profileId); } } else { - console.log('[ClaudeIntegration] OAuth token detected but not in a profile login terminal'); + console.warn('[ClaudeIntegration] OAuth token detected but not in a profile login terminal'); const win = getWindow(); if (win) { win.webContents.send(IPC_CHANNELS.TERMINAL_OAUTH_TOKEN, { @@ -140,7 +139,7 @@ export function handleClaudeSessionId( getWindow: WindowGetter ): void { terminal.claudeSessionId = sessionId; - console.log('[ClaudeIntegration] Captured Claude session ID:', sessionId); + console.warn('[ClaudeIntegration] Captured Claude session ID:', sessionId); if (terminal.projectPath) { SessionHandler.updateClaudeSessionId(terminal.projectPath, terminal.id, sessionId); @@ -187,17 +186,17 @@ export function invokeClaude( fs.writeFileSync(tempFile, `export CLAUDE_CODE_OAUTH_TOKEN="${token}"\n`, { mode: 0o600 }); terminal.pty.write(`${cwdCommand}source "${tempFile}" && rm -f "${tempFile}" && claude\r`); - console.log('[ClaudeIntegration] Switching to Claude profile:', activeProfile.name, '(via secure temp file)'); + console.warn('[ClaudeIntegration] Switching to Claude profile:', activeProfile.name, '(via secure temp file)'); return; } else if (activeProfile.configDir) { terminal.pty.write(`${cwdCommand}CLAUDE_CONFIG_DIR="${activeProfile.configDir}" claude\r`); - console.log('[ClaudeIntegration] Using Claude profile:', activeProfile.name, 'config:', activeProfile.configDir); + console.warn('[ClaudeIntegration] Using Claude profile:', activeProfile.name, 'config:', activeProfile.configDir); return; } } if (activeProfile && !activeProfile.isDefault) { - console.log('[ClaudeIntegration] Using Claude profile:', activeProfile.name, '(from terminal environment)'); + console.warn('[ClaudeIntegration] Using Claude profile:', activeProfile.name, '(from terminal environment)'); } terminal.pty.write(`${cwdCommand}claude\r`); @@ -265,7 +264,7 @@ export async function switchClaudeProfile( return { success: false, error: 'Profile not found' }; } - console.log('[ClaudeIntegration] Switching to Claude profile:', profile.name); + console.warn('[ClaudeIntegration] Switching to Claude profile:', profile.name); if (terminal.isClaudeMode) { terminal.pty.write('\x03'); diff --git a/auto-claude-ui/src/main/terminal/pty-daemon-client.ts b/auto-claude-ui/src/main/terminal/pty-daemon-client.ts index 7edbc885..3e0bd0f1 100644 --- a/auto-claude-ui/src/main/terminal/pty-daemon-client.ts +++ b/auto-claude-ui/src/main/terminal/pty-daemon-client.ts @@ -15,7 +15,20 @@ const SOCKET_PATH = ? `\\\\.\\pipe\\auto-claude-pty-${process.getuid?.() || 'default'}` : `/tmp/auto-claude-pty-${process.getuid?.() || 'default'}.sock`; -type ResponseHandler = (response: any) => void; +interface DaemonResponseData { + exitCode?: number; + signal?: number; +} + +interface DaemonResponse { + requestId?: string; + type: string; + id?: string; + data?: string | DaemonResponseData; + error?: string; +} + +type ResponseHandler = (response: DaemonResponse) => void; interface PtyConfig { shell: string; @@ -62,13 +75,13 @@ class PtyDaemonClient { try { // Try to connect to existing daemon await this.tryConnect(); - console.log('[PtyDaemonClient] Connected to existing daemon'); + console.warn('[PtyDaemonClient] Connected to existing daemon'); } catch { // Spawn daemon and connect - console.log('[PtyDaemonClient] Spawning new daemon...'); + console.warn('[PtyDaemonClient] Spawning new daemon...'); await this.spawnDaemon(); await this.tryConnect(); - console.log('[PtyDaemonClient] Connected to new daemon'); + console.warn('[PtyDaemonClient] Connected to new daemon'); } finally { this.isConnecting = false; this.reconnectAttempts = 0; @@ -119,7 +132,7 @@ class PtyDaemonClient { // Unref so parent can exit independently this.daemonProcess.unref(); - console.log(`[PtyDaemonClient] Spawned daemon process (PID: ${this.daemonProcess.pid})`); + console.warn(`[PtyDaemonClient] Spawned daemon process (PID: ${this.daemonProcess.pid})`); // Wait for daemon to start listening await new Promise((resolve) => setTimeout(resolve, 1000)); @@ -154,7 +167,7 @@ class PtyDaemonClient { }); this.socket.on('close', () => { - console.log('[PtyDaemonClient] Disconnected from daemon'); + console.warn('[PtyDaemonClient] Disconnected from daemon'); this.socket = null; if (!this.isShuttingDown) { this.attemptReconnect(); @@ -169,7 +182,7 @@ class PtyDaemonClient { /** * Handle response from daemon */ - private handleResponse(response: any): void { + private handleResponse(response: DaemonResponse): void { // Handle request-response pattern if (response.requestId) { const handler = this.pendingRequests.get(response.requestId); @@ -183,7 +196,7 @@ class PtyDaemonClient { // Handle streaming data if (response.type === 'data' && response.id) { const handler = this.dataHandlers.get(response.id); - if (handler) { + if (handler && typeof response.data === 'string') { handler(response.data); } return; @@ -192,8 +205,9 @@ class PtyDaemonClient { // Handle exit events if (response.type === 'exit' && response.id) { const handler = this.exitHandlers.get(response.id); - if (handler) { - handler(response.data.exitCode, response.data.signal); + if (handler && typeof response.data === 'object' && response.data !== null) { + const exitData = response.data as DaemonResponseData; + handler(exitData.exitCode ?? 0, exitData.signal); } return; } @@ -213,7 +227,7 @@ class PtyDaemonClient { this.reconnectAttempts++; const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 10000); - console.log( + console.warn( `[PtyDaemonClient] Reconnect attempt ${this.reconnectAttempts} in ${delay}ms...` ); @@ -227,7 +241,7 @@ class PtyDaemonClient { /** * Send a request and wait for response */ - private async request(msg: any): Promise { + private async request(msg: Record): Promise { await this.connect(); if (!this.socket) { @@ -258,7 +272,7 @@ class PtyDaemonClient { /** * Send a message without expecting a response */ - private send(msg: any): void { + private send(msg: Record): void { if (!this.socket) { console.warn('[PtyDaemonClient] Cannot send - not connected'); return; diff --git a/auto-claude-ui/src/main/terminal/pty-daemon.ts b/auto-claude-ui/src/main/terminal/pty-daemon.ts index d447f0c1..9c430efc 100644 --- a/auto-claude-ui/src/main/terminal/pty-daemon.ts +++ b/auto-claude-ui/src/main/terminal/pty-daemon.ts @@ -56,14 +56,14 @@ interface DaemonMessage { | 'get-buffer' | 'ping'; id?: string; - data?: any; + data?: unknown; requestId?: string; } interface DaemonResponse { type: 'created' | 'list' | 'buffer' | 'data' | 'exit' | 'error' | 'pong'; id?: string; - data?: any; + data?: unknown; requestId?: string; error?: string; } @@ -102,9 +102,9 @@ class PtyDaemon { this.handleConnection(socket); }); - this.server.on('error', (err) => { + this.server.on('error', (err: NodeJS.ErrnoException) => { console.error('[PTY Daemon] Server error:', err); - if ((err as any).code === 'EADDRINUSE') { + if (err.code === 'EADDRINUSE') { console.error('[PTY Daemon] Address in use - another daemon may be running'); process.exit(1); } @@ -172,20 +172,22 @@ class PtyDaemon { break; case 'create': { - const id = this.createPty(msg.data); + const id = this.createPty(msg.data as PtyConfig); this.send(socket, { type: 'created', id, requestId: msg.requestId }); break; } case 'write': if (!msg.id) throw new Error('Missing PTY id'); - this.writeToPty(msg.id, msg.data); + this.writeToPty(msg.id, msg.data as string); break; - case 'resize': + case 'resize': { if (!msg.id) throw new Error('Missing PTY id'); - this.resizePty(msg.id, msg.data.cols, msg.data.rows); + const resizeData = msg.data as { cols: number; rows: number }; + this.resizePty(msg.id, resizeData.cols, resizeData.rows); break; + } case 'kill': if (!msg.id) throw new Error('Missing PTY id'); @@ -221,7 +223,7 @@ class PtyDaemon { } default: - throw new Error(`Unknown message type: ${(msg as any).type}`); + throw new Error(`Unknown message type: ${(msg as DaemonMessage).type}`); } } catch (error) { const errorMsg = error instanceof Error ? error.message : String(error); @@ -428,7 +430,7 @@ class PtyDaemon { socket.write(JSON.stringify(response) + '\n'); } catch { // Socket may be closed, ignore - console.debug('[PTY Daemon] Failed to send response (socket closed?)'); + console.warn('[PTY Daemon] Failed to send response (socket closed?)'); } } diff --git a/auto-claude-ui/src/main/terminal/pty-manager.ts b/auto-claude-ui/src/main/terminal/pty-manager.ts index 203eb888..26c61855 100644 --- a/auto-claude-ui/src/main/terminal/pty-manager.ts +++ b/auto-claude-ui/src/main/terminal/pty-manager.ts @@ -5,7 +5,7 @@ import * as pty from 'node-pty'; import * as os from 'os'; -import type { TerminalProcess, WindowGetter, TerminalOperationResult } from './types'; +import type { TerminalProcess, WindowGetter } from './types'; import { IPC_CHANNELS } from '../../shared/constants'; import { getClaudeProfileManager } from '../claude-profile-manager'; @@ -24,7 +24,7 @@ export function spawnPtyProcess( const shellArgs = process.platform === 'win32' ? [] : ['-l']; - console.log('[PtyManager] Spawning shell:', shell, shellArgs); + console.warn('[PtyManager] Spawning shell:', shell, shellArgs); return pty.spawn(shell, shellArgs, { name: 'xterm-256color', @@ -69,7 +69,7 @@ export function setupPtyHandlers( // Handle terminal exit ptyProcess.onExit(({ exitCode }) => { - console.log('[PtyManager] Terminal exited:', id, 'code:', exitCode); + console.warn('[PtyManager] Terminal exited:', id, 'code:', exitCode); const win = getWindow(); if (win) { diff --git a/auto-claude-ui/src/main/terminal/session-handler.ts b/auto-claude-ui/src/main/terminal/session-handler.ts index 7ba70a81..9ac08fe5 100644 --- a/auto-claude-ui/src/main/terminal/session-handler.ts +++ b/auto-claude-ui/src/main/terminal/session-handler.ts @@ -6,7 +6,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as os from 'os'; -import type { TerminalProcess, WindowGetter, SessionCaptureResult } from './types'; +import type { TerminalProcess, WindowGetter } from './types'; import { getTerminalSessionStore, type TerminalSession } from '../terminal-session-store'; import { IPC_CHANNELS } from '../../shared/constants'; import { debugLog, debugError } from '../../shared/utils/debug-logger'; @@ -115,7 +115,7 @@ export function persistSession(terminal: TerminalProcess): void { * Persist all active sessions */ export function persistAllSessions(terminals: Map): void { - const store = getTerminalSessionStore(); + const _store = getTerminalSessionStore(); terminals.forEach((terminal) => { if (terminal.projectPath) { diff --git a/auto-claude-ui/src/main/terminal/session-persistence.ts b/auto-claude-ui/src/main/terminal/session-persistence.ts index 6a45d432..35f26168 100644 --- a/auto-claude-ui/src/main/terminal/session-persistence.ts +++ b/auto-claude-ui/src/main/terminal/session-persistence.ts @@ -49,7 +49,7 @@ class SessionPersistence { const sessions = this.loadSessions(); this.isInitialized = true; - console.log(`[SessionPersistence] Initialized with ${sessions.length} sessions`); + console.warn(`[SessionPersistence] Initialized with ${sessions.length} sessions`); return this.getRecoveryInfo(); } @@ -90,7 +90,7 @@ class SessionPersistence { validSessions.forEach((s) => this.sessions.set(s.id, s)); - console.log( + console.warn( `[SessionPersistence] Loaded ${validSessions.length} valid sessions, cleaned ${staleSessions.length} stale sessions` ); return validSessions; @@ -188,7 +188,7 @@ class SessionPersistence { fs.writeFileSync(bufferPath, serializedBuffer, 'utf8'); session.bufferFile = bufferFile; this.saveSession(session); - console.debug(`[SessionPersistence] Saved buffer for session ${sessionId} (${serializedBuffer.length} bytes)`); + console.warn(`[SessionPersistence] Saved buffer for session ${sessionId} (${serializedBuffer.length} bytes)`); } catch (error) { console.error(`[SessionPersistence] Failed to save buffer for ${sessionId}:`, error); } @@ -223,7 +223,7 @@ class SessionPersistence { if (fs.existsSync(bufferPath)) { try { fs.unlinkSync(bufferPath); - console.debug(`[SessionPersistence] Deleted buffer file: ${bufferFile}`); + console.warn(`[SessionPersistence] Deleted buffer file: ${bufferFile}`); } catch (error) { console.error(`[SessionPersistence] Failed to delete buffer file ${bufferFile}:`, error); } @@ -266,7 +266,7 @@ class SessionPersistence { try { fs.writeFileSync(SESSIONS_FILE, JSON.stringify(data, null, 2), 'utf8'); - console.debug(`[SessionPersistence] Saved ${data.sessions.length} sessions to disk`); + console.warn(`[SessionPersistence] Saved ${data.sessions.length} sessions to disk`); } catch (error) { console.error('[SessionPersistence] Failed to save sessions:', error); } @@ -296,7 +296,7 @@ class SessionPersistence { } if (cleanedCount > 0) { - console.log(`[SessionPersistence] Cleaned up ${cleanedCount} orphaned buffer files`); + console.warn(`[SessionPersistence] Cleaned up ${cleanedCount} orphaned buffer files`); } } catch (error) { console.error('[SessionPersistence] Failed to cleanup orphaned buffers:', error); @@ -309,7 +309,7 @@ export const sessionPersistence = new SessionPersistence(); // Hook into app lifecycle app.on('before-quit', () => { - console.log('[SessionPersistence] App quitting, saving sessions...'); + console.warn('[SessionPersistence] App quitting, saving sessions...'); sessionPersistence.saveNow(); }); diff --git a/auto-claude-ui/src/main/terminal/terminal-lifecycle.ts b/auto-claude-ui/src/main/terminal/terminal-lifecycle.ts index fd433faf..d0ee85fb 100644 --- a/auto-claude-ui/src/main/terminal/terminal-lifecycle.ts +++ b/auto-claude-ui/src/main/terminal/terminal-lifecycle.ts @@ -9,7 +9,6 @@ import { IPC_CHANNELS } from '../../shared/constants'; import type { TerminalSession } from '../terminal-session-store'; import * as PtyManager from './pty-manager'; import * as SessionHandler from './session-handler'; -import * as TerminalEventHandler from './terminal-event-handler'; import type { TerminalProcess, WindowGetter, @@ -226,8 +225,8 @@ export async function destroyAllTerminals( * Sessions are only removed when explicitly destroyed by user action via destroyTerminal(). */ function handleTerminalExit( - terminal: TerminalProcess, - terminals: Map + _terminal: TerminalProcess, + _terminals: Map ): void { // Don't remove session - let it persist for restoration } diff --git a/auto-claude-ui/src/main/title-generator.ts b/auto-claude-ui/src/main/title-generator.ts index 9085604a..f1e98ec2 100644 --- a/auto-claude-ui/src/main/title-generator.ts +++ b/auto-claude-ui/src/main/title-generator.ts @@ -12,7 +12,7 @@ const DEBUG = process.env.AUTO_CLAUDE_DEBUG === 'true' || process.env.AUTO_CLAUD function debug(...args: unknown[]): void { if (DEBUG) { - console.log('[TitleGenerator]', ...args); + console.warn('[TitleGenerator]', ...args); } } @@ -144,7 +144,7 @@ export class TitleGenerator extends EventEmitter { let output = ''; let errorOutput = ''; const timeout = setTimeout(() => { - console.log('[TitleGenerator] Title generation timed out after 60s'); + console.warn('[TitleGenerator] Title generation timed out after 60s'); childProcess.kill(); resolve(null); }, 60000); // 60 second timeout for SDK initialization + API call @@ -169,7 +169,7 @@ export class TitleGenerator extends EventEmitter { const combinedOutput = `${output}\n${errorOutput}`; const rateLimitDetection = detectRateLimit(combinedOutput); if (rateLimitDetection.isRateLimited) { - console.log('[TitleGenerator] Rate limit detected:', { + console.warn('[TitleGenerator] Rate limit detected:', { resetTime: rateLimitDetection.resetTime, limitType: rateLimitDetection.limitType, suggestedProfile: rateLimitDetection.suggestedProfile?.name @@ -180,7 +180,7 @@ export class TitleGenerator extends EventEmitter { } // Always log failures to help diagnose issues - console.log('[TitleGenerator] Title generation failed', { + console.warn('[TitleGenerator] Title generation failed', { code, errorOutput: errorOutput.substring(0, 500), output: output.substring(0, 200), @@ -192,7 +192,7 @@ export class TitleGenerator extends EventEmitter { childProcess.on('error', (err) => { clearTimeout(timeout); - console.log('[TitleGenerator] Process error:', err.message); + console.warn('[TitleGenerator] Process error:', err.message); resolve(null); }); }); diff --git a/auto-claude-ui/src/main/updater/file-operations.ts b/auto-claude-ui/src/main/updater/file-operations.ts index 215c92b2..b948631d 100644 --- a/auto-claude-ui/src/main/updater/file-operations.ts +++ b/auto-claude-ui/src/main/updater/file-operations.ts @@ -75,7 +75,7 @@ export function copyDirectoryRecursive( const destPath = path.join(dest, entry.name); // Skip certain files/directories - if (SKIP_FILES.includes(entry.name as any)) { + if (SKIP_FILES.includes(entry.name as (typeof SKIP_FILES)[number])) { continue; } diff --git a/auto-claude-ui/src/main/updater/http-client.ts b/auto-claude-ui/src/main/updater/http-client.ts index 4e2cb946..8d8a91da 100644 --- a/auto-claude-ui/src/main/updater/http-client.ts +++ b/auto-claude-ui/src/main/updater/http-client.ts @@ -36,7 +36,7 @@ export function fetchJson(url: string): Promise { response.on('end', () => { try { resolve(JSON.parse(data) as T); - } catch (e) { + } catch (_e) { reject(new Error('Failed to parse JSON response')); } }); diff --git a/auto-claude-ui/src/main/updater/update-installer.ts b/auto-claude-ui/src/main/updater/update-installer.ts index ef490e2b..17196b2a 100644 --- a/auto-claude-ui/src/main/updater/update-installer.ts +++ b/auto-claude-ui/src/main/updater/update-installer.ts @@ -8,7 +8,7 @@ import { app } from 'electron'; import { GITHUB_CONFIG, PRESERVE_FILES } from './config'; import { downloadFile, fetchJson } from './http-client'; import { parseVersionFromTag } from './version-manager'; -import { getUpdateCachePath, getUpdateTargetPath, getBundledSourcePath } from './path-resolver'; +import { getUpdateCachePath, getUpdateTargetPath } from './path-resolver'; import { extractTarball, copyDirectoryRecursive, preserveFiles, restoreFiles, cleanTargetDirectory } from './file-operations'; import { getCachedRelease, setCachedRelease, clearCachedRelease } from './update-checker'; import { GitHubRelease, AutoBuildUpdateResult, UpdateProgressCallback, UpdateMetadata } from './types'; diff --git a/auto-claude-ui/src/preload/api/modules/ipc-utils.ts b/auto-claude-ui/src/preload/api/modules/ipc-utils.ts index 82c6e7e0..cd845176 100644 --- a/auto-claude-ui/src/preload/api/modules/ipc-utils.ts +++ b/auto-claude-ui/src/preload/api/modules/ipc-utils.ts @@ -12,7 +12,7 @@ export type IpcListenerCleanup = () => void; * @param callback - The callback function to execute when event is received * @returns Cleanup function to remove the listener */ -export function createIpcListener( +export function createIpcListener( channel: string, callback: (...args: T) => void ): IpcListenerCleanup { @@ -32,7 +32,7 @@ export function createIpcListener( * @param args - Arguments to pass to the IPC handler * @returns Promise with the typed result */ -export function invokeIpc(channel: string, ...args: any[]): Promise { +export function invokeIpc(channel: string, ...args: unknown[]): Promise { return ipcRenderer.invoke(channel, ...args); } @@ -42,6 +42,6 @@ export function invokeIpc(channel: string, ...args: any[]): Promise { * @param channel - The IPC channel to send to * @param args - Arguments to pass to the IPC handler */ -export function sendIpc(channel: string, ...args: any[]): void { +export function sendIpc(channel: string, ...args: unknown[]): void { ipcRenderer.send(channel, ...args); } diff --git a/auto-claude-ui/src/preload/api/project-api.ts b/auto-claude-ui/src/preload/api/project-api.ts index e8a8955d..cd7f8cca 100644 --- a/auto-claude-ui/src/preload/api/project-api.ts +++ b/auto-claude-ui/src/preload/api/project-api.ts @@ -6,11 +6,6 @@ import type { IPCResult, InitializationResult, AutoBuildVersionInfo, - ProjectContextData, - ProjectIndex, - GraphitiMemoryStatus, - ContextSearchResult, - MemoryEpisode, ProjectEnvConfig, ClaudeAuthResult, InfrastructureStatus, @@ -33,11 +28,11 @@ export interface ProjectAPI { checkProjectVersion: (projectId: string) => Promise>; // Context Operations - getProjectContext: (projectId: string) => Promise; - refreshProjectIndex: (projectId: string) => Promise; - getMemoryStatus: (projectId: string) => Promise; - searchMemories: (projectId: string, query: string) => Promise; - getRecentMemories: (projectId: string, limit?: number) => Promise; + getProjectContext: (projectId: string) => Promise>; + refreshProjectIndex: (projectId: string) => Promise>; + getMemoryStatus: (projectId: string) => Promise>; + searchMemories: (projectId: string, query: string) => Promise>; + getRecentMemories: (projectId: string, limit?: number) => Promise>; // Environment Configuration getProjectEnv: (projectId: string) => Promise>; diff --git a/auto-claude-ui/src/preload/api/terminal-api.ts b/auto-claude-ui/src/preload/api/terminal-api.ts index 260f9138..b7fb00c5 100644 --- a/auto-claude-ui/src/preload/api/terminal-api.ts +++ b/auto-claude-ui/src/preload/api/terminal-api.ts @@ -5,9 +5,18 @@ import type { TerminalCreateOptions, RateLimitInfo, ClaudeProfile, - ClaudeProfileSettings + ClaudeProfileSettings, + ClaudeUsageSnapshot } from '../../shared/types'; +/** Type for proactive swap notification events */ +interface ProactiveSwapNotification { + fromProfile: { id: string; name: string }; + toProfile: { id: string; name: string }; + reason: string; + usageSnapshot: ClaudeUsageSnapshot; +} + export interface TerminalAPI { // Terminal Operations createTerminal: (options: TerminalCreateOptions) => Promise; @@ -67,7 +76,7 @@ export interface TerminalAPI { // Usage Monitoring (Proactive Account Switching) requestUsageUpdate: () => Promise>; onUsageUpdated: (callback: (usage: import('../../shared/types').ClaudeUsageSnapshot) => void) => () => void; - onProactiveSwapNotification: (callback: (notification: any) => void) => () => void; + onProactiveSwapNotification: (callback: (notification: ProactiveSwapNotification) => void) => () => void; } export const createTerminalAPI = (): TerminalAPI => ({ @@ -294,9 +303,9 @@ export const createTerminalAPI = (): TerminalAPI => ({ }, onProactiveSwapNotification: ( - callback: (notification: any) => void + callback: (notification: ProactiveSwapNotification) => void ): (() => void) => { - const handler = (_event: Electron.IpcRendererEvent, notification: any): void => { + const handler = (_event: Electron.IpcRendererEvent, notification: ProactiveSwapNotification): void => { callback(notification); }; ipcRenderer.on(IPC_CHANNELS.PROACTIVE_SWAP_NOTIFICATION, handler); diff --git a/auto-claude-ui/src/renderer/App.tsx b/auto-claude-ui/src/renderer/App.tsx index d1d0a727..1c8f8fc4 100644 --- a/auto-claude-ui/src/renderer/App.tsx +++ b/auto-claude-ui/src/renderer/App.tsx @@ -118,7 +118,7 @@ export function App() { useEffect(() => { // When an update is downloaded and ready to install, open settings to updates section const cleanupDownloaded = window.electronAPI.onAppUpdateDownloaded(() => { - console.log('[App] Update downloaded, opening settings to updates section'); + console.warn('[App] Update downloaded, opening settings to updates section'); setSettingsInitialSection('updates'); setIsSettingsDialogOpen(true); }); @@ -206,7 +206,7 @@ export function App() { setSelectedTask(updatedTask); } } - }, [tasks, selectedTask?.id, selectedTask?.specId]); + }, [tasks, selectedTask?.id, selectedTask?.specId, selectedTask]); const handleTaskClick = (task: Task) => { setSelectedTask(task); diff --git a/auto-claude-ui/src/renderer/__tests__/TaskEditDialog.test.ts b/auto-claude-ui/src/renderer/__tests__/TaskEditDialog.test.ts index b751901d..0c3b5863 100644 --- a/auto-claude-ui/src/renderer/__tests__/TaskEditDialog.test.ts +++ b/auto-claude-ui/src/renderer/__tests__/TaskEditDialog.test.ts @@ -6,7 +6,7 @@ */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { useTaskStore, persistUpdateTask } from '../stores/task-store'; -import type { Task, TaskStatus, ElectronAPI } from '../../shared/types'; +import type { Task, TaskStatus } from '../../shared/types'; // Helper to create test tasks function createTestTask(overrides: Partial = {}): Task { diff --git a/auto-claude-ui/src/renderer/components/AddFeatureDialog.tsx b/auto-claude-ui/src/renderer/components/AddFeatureDialog.tsx index 08208f3d..c10ce0b2 100644 --- a/auto-claude-ui/src/renderer/components/AddFeatureDialog.tsx +++ b/auto-claude-ui/src/renderer/components/AddFeatureDialog.tsx @@ -43,9 +43,7 @@ import { } from './ui/select'; import { useRoadmapStore } from '../stores/roadmap-store'; import { - ROADMAP_PRIORITY_LABELS, - ROADMAP_COMPLEXITY_COLORS, - ROADMAP_IMPACT_COLORS + ROADMAP_PRIORITY_LABELS } from '../../shared/constants'; import type { RoadmapPhase, diff --git a/auto-claude-ui/src/renderer/components/AppUpdateNotification.tsx b/auto-claude-ui/src/renderer/components/AppUpdateNotification.tsx index d2787ab7..2238aee3 100644 --- a/auto-claude-ui/src/renderer/components/AppUpdateNotification.tsx +++ b/auto-claude-ui/src/renderer/components/AppUpdateNotification.tsx @@ -3,8 +3,7 @@ import { Download, RefreshCw, CheckCircle2, - AlertCircle, - ExternalLink + AlertCircle } from 'lucide-react'; import { Button } from './ui/button'; import { Progress } from './ui/progress'; @@ -18,7 +17,6 @@ import { } from './ui/dialog'; import type { AppUpdateAvailableEvent, - AppUpdateDownloadedEvent, AppUpdateProgress } from '../../shared/types'; @@ -87,7 +85,7 @@ export function AppUpdateNotification() { // Listen for update downloaded event useEffect(() => { - const cleanup = window.electronAPI.onAppUpdateDownloaded((info) => { + const cleanup = window.electronAPI.onAppUpdateDownloaded((_info) => { setIsDownloading(false); setIsDownloaded(true); setDownloadProgress(null); diff --git a/auto-claude-ui/src/renderer/components/EnvConfigModal.tsx b/auto-claude-ui/src/renderer/components/EnvConfigModal.tsx index 755f1f04..ea26bf63 100644 --- a/auto-claude-ui/src/renderer/components/EnvConfigModal.tsx +++ b/auto-claude-ui/src/renderer/components/EnvConfigModal.tsx @@ -44,7 +44,7 @@ export function EnvConfigModal({ }: EnvConfigModalProps) { const [token, setToken] = useState(''); const [showToken, setShowToken] = useState(false); - const [isLoading, setIsLoading] = useState(false); + const [_isLoading, _setIsLoading] = useState(false); const [isChecking, setIsChecking] = useState(true); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); diff --git a/auto-claude-ui/src/renderer/components/GitSetupModal.tsx b/auto-claude-ui/src/renderer/components/GitSetupModal.tsx index 16ac15a6..a1186103 100644 --- a/auto-claude-ui/src/renderer/components/GitSetupModal.tsx +++ b/auto-claude-ui/src/renderer/components/GitSetupModal.tsx @@ -33,7 +33,7 @@ export function GitSetupModal({ const [step, setStep] = useState<'info' | 'initializing' | 'success'>('info'); const needsGitInit = gitStatus && !gitStatus.isGitRepo; - const needsCommit = gitStatus && gitStatus.isGitRepo && !gitStatus.hasCommits; + const _needsCommit = gitStatus && gitStatus.isGitRepo && !gitStatus.hasCommits; const handleInitializeGit = async () => { if (!project) return; diff --git a/auto-claude-ui/src/renderer/components/ProactiveSwapListener.tsx b/auto-claude-ui/src/renderer/components/ProactiveSwapListener.tsx index dd393cc1..b68ec925 100644 --- a/auto-claude-ui/src/renderer/components/ProactiveSwapListener.tsx +++ b/auto-claude-ui/src/renderer/components/ProactiveSwapListener.tsx @@ -12,8 +12,7 @@ import { Button } from './ui/button'; interface SwapNotification { fromProfile: string; toProfile: string; - reason: 'proactive' | 'reactive'; - limitType: 'session' | 'weekly'; + reason: string; timestamp: Date; } @@ -22,12 +21,11 @@ export function ProactiveSwapListener() { const [isVisible, setIsVisible] = useState(false); useEffect(() => { - const unsubscribe = window.electronAPI.onProactiveSwapNotification((data: any) => { + const unsubscribe = window.electronAPI.onProactiveSwapNotification((data) => { const notif: SwapNotification = { - fromProfile: data.fromProfile, - toProfile: data.toProfile, + fromProfile: data.fromProfile.name, + toProfile: data.toProfile.name, reason: data.reason, - limitType: data.limitType, timestamp: new Date() }; @@ -69,7 +67,7 @@ export function ProactiveSwapListener() { {notification.toProfile}
- ({notification.limitType} usage threshold reached) + ({notification.reason} swap)

diff --git a/auto-claude-ui/src/renderer/components/ProjectSettings.tsx b/auto-claude-ui/src/renderer/components/ProjectSettings.tsx index a5706310..8ea9c3cd 100644 --- a/auto-claude-ui/src/renderer/components/ProjectSettings.tsx +++ b/auto-claude-ui/src/renderer/components/ProjectSettings.tsx @@ -53,7 +53,7 @@ export function ProjectSettings({ project, open, onOpenChange }: ProjectSettings updateEnvConfig, isLoadingEnv, envError, - setEnvError, + setEnvError: _setEnvError, isSavingEnv, } = useEnvironmentConfig(project.id, project.autoBuildPath, open); @@ -313,7 +313,7 @@ export function ProjectSettings({ project, open, onOpenChange }: ProjectSettings onOpenChange={setShowLinearImportModal} onImportComplete={(result) => { // Optionally refresh or notify - console.log('Import complete:', result); + console.warn('Import complete:', result); }} /> diff --git a/auto-claude-ui/src/renderer/components/Sidebar.tsx b/auto-claude-ui/src/renderer/components/Sidebar.tsx index f0eb41e8..75b05965 100644 --- a/auto-claude-ui/src/renderer/components/Sidebar.tsx +++ b/auto-claude-ui/src/renderer/components/Sidebar.tsx @@ -108,7 +108,7 @@ export function Sidebar({ const [showGitSetupModal, setShowGitSetupModal] = useState(false); const [gitStatus, setGitStatus] = useState(null); const [pendingProject, setPendingProject] = useState(null); - const [versionInfo, setVersionInfo] = useState(null); + const [_versionInfo, setVersionInfo] = useState(null); const [isInitializing, setIsInitializing] = useState(false); const selectedProject = projects.find((p) => p.id === selectedProjectId); @@ -216,7 +216,7 @@ export function Sidebar({ setPendingProject(null); }; - const handleUpdate = async () => { + const _handleUpdate = async () => { if (!selectedProjectId) return; setIsInitializing(true); @@ -231,7 +231,7 @@ export function Sidebar({ } }; - const handleSkipUpdate = () => { + const _handleSkipUpdate = () => { setShowUpdateDialog(false); setVersionInfo(null); }; @@ -250,7 +250,7 @@ export function Sidebar({ } }; - const handleRemoveProject = async (projectId: string, e: React.MouseEvent) => { + const _handleRemoveProject = async (projectId: string, e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); await removeProject(projectId); diff --git a/auto-claude-ui/src/renderer/components/Terminal.tsx b/auto-claude-ui/src/renderer/components/Terminal.tsx index 90dff964..f286d836 100644 --- a/auto-claude-ui/src/renderer/components/Terminal.tsx +++ b/auto-claude-ui/src/renderer/components/Terminal.tsx @@ -48,7 +48,7 @@ export function Terminal({ // Initialize xterm with command tracking const { terminalRef, - xtermRef, + xtermRef: _xtermRef, write, writeln, focus, diff --git a/auto-claude-ui/src/renderer/components/TerminalGrid.tsx b/auto-claude-ui/src/renderer/components/TerminalGrid.tsx index 6ab0c46a..0499a00b 100644 --- a/auto-claude-ui/src/renderer/components/TerminalGrid.tsx +++ b/auto-claude-ui/src/renderer/components/TerminalGrid.tsx @@ -93,10 +93,10 @@ export function TerminalGrid({ projectPath, onNewTaskClick }: TerminalGridProps) const sessionsResult = await window.electronAPI.getTerminalSessionsForDate(date, projectPath); const sessionsToRestore = sessionsResult.success ? sessionsResult.data || [] : []; - console.log(`[TerminalGrid] Found ${sessionsToRestore.length} sessions to restore from ${date}`); + console.warn(`[TerminalGrid] Found ${sessionsToRestore.length} sessions to restore from ${date}`); if (sessionsToRestore.length === 0) { - console.log('[TerminalGrid] No sessions found for this date'); + console.warn('[TerminalGrid] No sessions found for this date'); setIsRestoring(false); return; } @@ -119,7 +119,7 @@ export function TerminalGrid({ projectPath, onNewTaskClick }: TerminalGridProps) ); if (result.success && result.data) { - console.log(`[TerminalGrid] Main process restored ${result.data.restored} sessions from ${date}`); + console.warn(`[TerminalGrid] Main process restored ${result.data.restored} sessions from ${date}`); // Add each successfully restored session to the renderer's terminal store for (const sessionResult of result.data.sessions) { @@ -127,7 +127,7 @@ export function TerminalGrid({ projectPath, onNewTaskClick }: TerminalGridProps) // Find the full session data const fullSession = sessionsToRestore.find(s => s.id === sessionResult.id); if (fullSession) { - console.log(`[TerminalGrid] Adding restored terminal to store: ${fullSession.id}`); + console.warn(`[TerminalGrid] Adding restored terminal to store: ${fullSession.id}`); addRestoredTerminal(fullSession); } } @@ -162,6 +162,11 @@ export function TerminalGrid({ projectPath, onNewTaskClick }: TerminalGridProps) isDirectory: boolean; } | null>(null); + const handleCloseTerminal = useCallback((id: string) => { + window.electronAPI.destroyTerminal(id); + removeTerminal(id); + }, [removeTerminal]); + // Handle keyboard shortcut for new terminal useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { @@ -181,12 +186,7 @@ export function TerminalGrid({ projectPath, onNewTaskClick }: TerminalGridProps) window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); - }, [addTerminal, canAddTerminal, projectPath, activeTerminalId]); - - const handleCloseTerminal = useCallback((id: string) => { - window.electronAPI.destroyTerminal(id); - removeTerminal(id); - }, [removeTerminal]); + }, [addTerminal, canAddTerminal, projectPath, activeTerminalId, handleCloseTerminal]); const handleAddTerminal = useCallback(() => { if (canAddTerminal()) { diff --git a/auto-claude-ui/src/renderer/components/WelcomeScreen.tsx b/auto-claude-ui/src/renderer/components/WelcomeScreen.tsx index 4e6e4b38..efaa919d 100644 --- a/auto-claude-ui/src/renderer/components/WelcomeScreen.tsx +++ b/auto-claude-ui/src/renderer/components/WelcomeScreen.tsx @@ -83,7 +83,7 @@ export function WelcomeScreen({
- {recentProjects.map((project, index) => ( + {recentProjects.map((project, _index) => (
') .replace(/\n/g, '
'); - + return result; }, [markdown]); return ( -
@@ -79,7 +79,7 @@ export function AdvancedSettings({ settings, onSettingsChange, section, version // Electron app update state const [appUpdateInfo, setAppUpdateInfo] = useState(null); - const [isCheckingAppUpdate, setIsCheckingAppUpdate] = useState(false); + const [_isCheckingAppUpdate, setIsCheckingAppUpdate] = useState(false); const [isDownloadingAppUpdate, setIsDownloadingAppUpdate] = useState(false); const [appDownloadProgress, setAppDownloadProgress] = useState(null); const [isAppUpdateDownloaded, setIsAppUpdateDownloaded] = useState(false); @@ -329,7 +329,7 @@ export function AdvancedSettings({ settings, onSettingsChange, section, version
)} - + {sourceUpdateCheck.releaseUrl && (