diff --git a/src/ccs.ts b/src/ccs.ts index eb6f2d11..ff210f8f 100644 --- a/src/ccs.ts +++ b/src/ccs.ts @@ -228,7 +228,8 @@ async function main(): Promise { // Special case: doctor command if (firstArg === 'doctor' || firstArg === '--doctor') { - await handleDoctorCommand(); + const shouldFix = args.includes('--fix') || args.includes('-f'); + await handleDoctorCommand(shouldFix); return; } diff --git a/src/commands/doctor-command.ts b/src/commands/doctor-command.ts index 5d5ff175..6f4c7c65 100644 --- a/src/commands/doctor-command.ts +++ b/src/commands/doctor-command.ts @@ -6,14 +6,20 @@ /** * Handle doctor command + * @param shouldFix - If true, attempt to fix detected issues */ -export async function handleDoctorCommand(): Promise { +export async function handleDoctorCommand(shouldFix = false): Promise { const DoctorModule = await import('../management/doctor'); const Doctor = DoctorModule.default; const doctor = new Doctor(); await doctor.runAllChecks(); + // Attempt to fix issues if --fix flag provided + if (shouldFix) { + await doctor.fixIssues(); + } + // Exit with error code if unhealthy process.exit(doctor.isHealthy() ? 0 : 1); } diff --git a/src/commands/sync-command.ts b/src/commands/sync-command.ts index 33244096..bb2c60c0 100644 --- a/src/commands/sync-command.ts +++ b/src/commands/sync-command.ts @@ -31,6 +31,15 @@ export async function handleSyncCommand(): Promise { const manager = new ClaudeSymlinkManager(); manager.install(false); + console.log(''); + + // Repair shared symlinks (~/.ccs/shared/ → ~/.claude/) + // This fixes symlinks broken by Claude CLI's atomic writes (e.g., toggle thinking) + const SharedManager = (await import('../management/shared-manager')).default; + const sharedManager = new SharedManager(); + sharedManager.ensureSharedDirectories(); + console.log(colored('[OK]', 'green') + ' Shared symlinks verified'); + console.log(''); console.log(colored('[OK] Sync complete!', 'green')); console.log(''); diff --git a/src/management/doctor.ts b/src/management/doctor.ts index af25862a..3dfaee1b 100644 --- a/src/management/doctor.ts +++ b/src/management/doctor.ts @@ -955,6 +955,49 @@ class Doctor { ); } + /** + * Fix detected issues + * Currently fixes: shared symlinks broken by Claude CLI's atomic writes + */ + async fixIssues(): Promise { + console.log(''); + console.log(header('ATTEMPTING FIXES')); + console.log(''); + + let fixed = 0; + + // Fix shared symlinks (settings.json broken by Claude CLI toggle thinking, etc.) + const sharedSettings = path.join(this.homedir, '.ccs', 'shared', 'settings.json'); + if (fs.existsSync(sharedSettings)) { + try { + const stats = fs.lstatSync(sharedSettings); + if (!stats.isSymbolicLink()) { + const spinner = ora('Fixing shared settings.json symlink').start(); + try { + // Import and use SharedManager to fix symlinks + const SharedManagerModule = await import('./shared-manager'); + const SharedManager = SharedManagerModule.default; + const sharedManager = new SharedManager(); + sharedManager.ensureSharedDirectories(); + spinner.succeed(ok('Fixed') + ' Shared settings.json symlink restored'); + fixed++; + } catch (err) { + spinner.fail(fail('Failed') + ` Could not fix: ${(err as Error).message}`); + } + } + } catch (_err) { + // Ignore stat errors + } + } + + if (fixed > 0) { + console.log(''); + console.log(ok(`[OK] Fixed ${fixed} issue(s)`)); + } else { + console.log(info('[i] No fixable issues detected')); + } + } + /** * Check if the health check results are healthy */