diff --git a/ccw/src/commands/install.ts b/ccw/src/commands/install.ts index 47b46528..7ec232e9 100644 --- a/ccw/src/commands/install.ts +++ b/ccw/src/commands/install.ts @@ -306,15 +306,17 @@ export async function installCommand(options: InstallOptions): Promise { info(` Files in manifest: ${existingManifest.files?.length || 0}`); info(` Installed: ${new Date(existingManifest.installation_date).toLocaleDateString()}`); - const { backup } = await inquirer.prompt([{ - type: 'confirm', - name: 'backup', - message: 'Create backup before reinstalling?', - default: true - }]); + if (!options.force) { + const { backup } = await inquirer.prompt([{ + type: 'confirm', + name: 'backup', + message: 'Create backup before reinstalling?', + default: true + }]); - if (backup) { - await createBackup(existingManifest); + if (backup) { + await createBackup(existingManifest); + } } // Clean based on manifest records @@ -495,7 +497,7 @@ export async function installCommand(options: InstallOptions): Promise { }); // Install Git Bash fix on Windows - if (platform() === 'win32') { + if (platform() === 'win32' && !options.force) { console.log(''); const { installFix } = await inquirer.prompt([{ type: 'confirm', diff --git a/ccw/src/tools/cli-executor-core.ts b/ccw/src/tools/cli-executor-core.ts index 1c4bf6d2..8a7d8094 100644 --- a/ccw/src/tools/cli-executor-core.ts +++ b/ccw/src/tools/cli-executor-core.ts @@ -35,29 +35,6 @@ import { saveConversation } from './cli-executor-state.js'; -// Debug logging for history save investigation (Iteration 4) -const DEBUG_SESSION_ID = 'DBG-parallel-ccw-cli-test-2026-03-07'; -const DEBUG_LOG_PATH = path.join(process.cwd(), '.workflow', '.debug', DEBUG_SESSION_ID, 'debug-save.log'); - -// Ensure debug log directory exists -try { - const debugDir = path.dirname(DEBUG_LOG_PATH); - if (!fs.existsSync(debugDir)) { - fs.mkdirSync(debugDir, { recursive: true }); - } -} catch (err) { - // Ignore directory creation errors -} - -function writeDebugLog(event: string, data: Record): void { - try { - const logEntry = JSON.stringify({ event, ...data, timestamp: new Date().toISOString() }) + '\n'; - fs.appendFileSync(DEBUG_LOG_PATH, logEntry, 'utf8'); - } catch (err) { - // Silently ignore logging errors - } -} - // Track all running child processes for cleanup on interruption (multi-process support) const runningChildProcesses = new Set(); @@ -1296,11 +1273,8 @@ async function executeCliTool( }; // Try to save conversation to history try { - writeDebugLog('BEFORE_SAVE_CONV', { conversationId: conversation.id, workingDir, tool }); saveConversation(workingDir, conversation); - writeDebugLog('AFTER_SAVE_CONV', { conversationId: conversation.id, workingDir, tool }); } catch (err) { - writeDebugLog('SAVE_CONV_OUTER_ERROR', { conversationId: conversation.id, workingDir, tool, error: (err as Error).message, stack: (err as Error).stack }); // Non-fatal: continue even if history save fails console.error('[CLI Executor] Failed to save history:', (err as Error).message); } diff --git a/ccw/src/tools/cli-executor-state.ts b/ccw/src/tools/cli-executor-state.ts index 9e19d9ff..27bb375e 100644 --- a/ccw/src/tools/cli-executor-state.ts +++ b/ccw/src/tools/cli-executor-state.ts @@ -9,29 +9,6 @@ import type { CliOutputUnit } from './cli-output-converter.js'; import * as fs from 'fs'; import * as path from 'path'; -// Debug logging for history save investigation (Iteration 4) -const DEBUG_SESSION_ID = 'DBG-parallel-ccw-cli-test-2026-03-07'; -const DEBUG_LOG_PATH = path.join(process.cwd(), '.workflow', '.debug', DEBUG_SESSION_ID, 'debug-save.log'); - -// Ensure debug log directory exists -try { - const debugDir = path.dirname(DEBUG_LOG_PATH); - if (!fs.existsSync(debugDir)) { - fs.mkdirSync(debugDir, { recursive: true }); - } -} catch (err) { - // Ignore directory creation errors -} - -function writeDebugLog(event: string, data: Record): void { - try { - const logEntry = JSON.stringify({ event, ...data, timestamp: new Date().toISOString() }) + '\n'; - fs.appendFileSync(DEBUG_LOG_PATH, logEntry, 'utf8'); - } catch (err) { - // Silently ignore logging errors - } -} - // Lazy-loaded SQLite store module let sqliteStoreModule: typeof import('./cli-history-store.js') | null = null; @@ -39,10 +16,8 @@ let sqliteStoreModule: typeof import('./cli-history-store.js') | null = null; * Get or initialize SQLite store (async) */ export async function getSqliteStore(baseDir: string) { - writeDebugLog('GET_STORE', { baseDir, baseDirType: typeof baseDir, moduleInitialized: sqliteStoreModule !== null }); if (!sqliteStoreModule) { sqliteStoreModule = await import('./cli-history-store.js'); - writeDebugLog('MODULE_LOADED', { baseDir }); } return sqliteStoreModule.getHistoryStore(baseDir); } @@ -163,20 +138,15 @@ async function saveConversationAsync(baseDir: string, conversation: Conversation * @param baseDir - Project base directory (NOT historyDir) */ export function saveConversation(baseDir: string, conversation: ConversationRecord): void { - writeDebugLog('SAVE_CONV_START', { baseDir, conversationId: conversation.id, moduleInitialized: sqliteStoreModule !== null }); try { const store = getSqliteStoreSync(baseDir); - writeDebugLog('SAVE_CONV_SYNC', { baseDir, conversationId: conversation.id }); // Fire and forget - don't block on async save in sync context store.saveConversation(conversation).catch(err => { - writeDebugLog('SAVE_CONV_ERROR', { baseDir, conversationId: conversation.id, error: err.message, stack: err.stack }); console.error('[CLI Executor] Failed to save conversation:', err.message); }); } catch (err) { - writeDebugLog('SAVE_CONV_FALLBACK_ASYNC', { baseDir, conversationId: conversation.id, error: (err as Error).message }); // If sync not available, queue for async save saveConversationAsync(baseDir, conversation).catch(err => { - writeDebugLog('SAVE_CONV_ASYNC_ERROR', { baseDir, conversationId: conversation.id, error: err.message, stack: err.stack }); console.error('[CLI Executor] Failed to save conversation:', err.message); }); } diff --git a/ccw/src/tools/cli-history-store.ts b/ccw/src/tools/cli-history-store.ts index 4cb37a02..10c8911e 100644 --- a/ccw/src/tools/cli-history-store.ts +++ b/ccw/src/tools/cli-history-store.ts @@ -11,29 +11,6 @@ import { getDiscoverer, getNativeSessions } from './native-session-discovery.js' import { StoragePaths, ensureStorageDir, getProjectId, getCCWHome } from '../config/storage-paths.js'; import { createOutputParser, flattenOutputUnits, type CliOutputUnit } from './cli-output-converter.js'; -// Debug logging for history save investigation (Iteration 4) -const DEBUG_SESSION_ID = 'DBG-parallel-ccw-cli-test-2026-03-07'; -const DEBUG_LOG_PATH = join(process.cwd(), '.workflow', '.debug', DEBUG_SESSION_ID, 'debug-save.log'); - -// Ensure debug log directory exists -try { - const debugDir = dirname(DEBUG_LOG_PATH); - if (!existsSync(debugDir)) { - mkdirSync(debugDir, { recursive: true }); - } -} catch (err) { - // Ignore directory creation errors -} - -function writeDebugLog(event: string, data: Record): void { - try { - const logEntry = JSON.stringify({ event, ...data, timestamp: new Date().toISOString() }) + '\n'; - appendFileSync(DEBUG_LOG_PATH, logEntry, 'utf8'); - } catch (err) { - // Silently ignore logging errors - } -} - function reconstructFinalOutputFromStdout(rawStdout: string, canTrustStdout: boolean): string | undefined { if (!canTrustStdout || !rawStdout.trim()) { return undefined; @@ -154,29 +131,22 @@ export class CliHistoryStore { private projectPath: string; constructor(baseDir: string) { - writeDebugLog('STORE_CONSTRUCT_START', { baseDir }); this.projectPath = baseDir; // Use centralized storage path const paths = StoragePaths.project(baseDir); const historyDir = paths.cliHistory; - writeDebugLog('STORAGE_PATHS', { baseDir, historyDir, historyDb: paths.historyDb }); ensureStorageDir(historyDir); this.dbPath = paths.historyDb; - writeDebugLog('DB_INSTANCE_CREATE', { dbPath: this.dbPath }); this.db = new Database(this.dbPath); - writeDebugLog('DB_INSTANCE_CREATED', { dbPath: this.dbPath }); this.db.pragma('journal_mode = WAL'); this.db.pragma('synchronous = NORMAL'); this.db.pragma('busy_timeout = 10000'); // Wait up to 10 seconds for locks (increased for write-heavy scenarios) this.db.pragma('wal_autocheckpoint = 1000'); // Optimize WAL checkpointing - writeDebugLog('INIT_SCHEMA_START', { dbPath: this.dbPath }); this.initSchema(); - writeDebugLog('INIT_SCHEMA_COMPLETE', { dbPath: this.dbPath }); this.migrateFromJson(historyDir); - writeDebugLog('STORE_CONSTRUCT_COMPLETE', { baseDir, dbPath: this.dbPath }); } /**