mirror of
https://github.com/tiennm99/ccs.git
synced 2026-08-14 12:25:27 +00:00
fix(doctor): repair shared settings.json symlink broken by claude cli
claude cli's atomic writes (toggle thinking, etc.) replace symlinks with regular files, breaking the settings sync chain. this adds: - `ccs doctor --fix` to detect and repair broken shared symlinks - `ccs sync` now also repairs shared symlinks automatically fixes #57
This commit is contained in:
+2
-1
@@ -228,7 +228,8 @@ async function main(): Promise<void> {
|
|||||||
|
|
||||||
// Special case: doctor command
|
// Special case: doctor command
|
||||||
if (firstArg === 'doctor' || firstArg === '--doctor') {
|
if (firstArg === 'doctor' || firstArg === '--doctor') {
|
||||||
await handleDoctorCommand();
|
const shouldFix = args.includes('--fix') || args.includes('-f');
|
||||||
|
await handleDoctorCommand(shouldFix);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,20 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle doctor command
|
* Handle doctor command
|
||||||
|
* @param shouldFix - If true, attempt to fix detected issues
|
||||||
*/
|
*/
|
||||||
export async function handleDoctorCommand(): Promise<void> {
|
export async function handleDoctorCommand(shouldFix = false): Promise<void> {
|
||||||
const DoctorModule = await import('../management/doctor');
|
const DoctorModule = await import('../management/doctor');
|
||||||
const Doctor = DoctorModule.default;
|
const Doctor = DoctorModule.default;
|
||||||
const doctor = new Doctor();
|
const doctor = new Doctor();
|
||||||
|
|
||||||
await doctor.runAllChecks();
|
await doctor.runAllChecks();
|
||||||
|
|
||||||
|
// Attempt to fix issues if --fix flag provided
|
||||||
|
if (shouldFix) {
|
||||||
|
await doctor.fixIssues();
|
||||||
|
}
|
||||||
|
|
||||||
// Exit with error code if unhealthy
|
// Exit with error code if unhealthy
|
||||||
process.exit(doctor.isHealthy() ? 0 : 1);
|
process.exit(doctor.isHealthy() ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ export async function handleSyncCommand(): Promise<void> {
|
|||||||
const manager = new ClaudeSymlinkManager();
|
const manager = new ClaudeSymlinkManager();
|
||||||
manager.install(false);
|
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('');
|
||||||
console.log(colored('[OK] Sync complete!', 'green'));
|
console.log(colored('[OK] Sync complete!', 'green'));
|
||||||
console.log('');
|
console.log('');
|
||||||
|
|||||||
@@ -955,6 +955,49 @@ class Doctor {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fix detected issues
|
||||||
|
* Currently fixes: shared symlinks broken by Claude CLI's atomic writes
|
||||||
|
*/
|
||||||
|
async fixIssues(): Promise<void> {
|
||||||
|
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
|
* Check if the health check results are healthy
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user