fix: address PR review — shebang, double-escaping, data loss, uninstall scope

- Add shebang banner to NPX CLI esbuild config so npx claude-mem works
- Remove manual backslash pre-escaping in WindsurfHooksInstaller (JSON.stringify handles it)
- Scope cache deletion to claude-mem only, not entire vendor namespace
- Use getWorkerPort() in OpenCodeInstaller instead of hard-coded 37777
- Throw on corrupt JSON in readJsonSafe/readGeminiSettings/Windsurf to prevent data loss
- Fix Cursor install stub to warn instead of silently succeeding
- Fix Gemini uninstall to remove individual hooks within groups, not whole groups
- Update tests for new corrupt-file-throws behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-04-04 13:49:14 -07:00
parent cdffdba97a
commit ae6915b88e
9 changed files with 53 additions and 61 deletions
@@ -213,11 +213,7 @@ function buildHookCommand(bunPath: string, workerServicePath: string, eventName:
const hookCommand = eventToCommand[eventName] ?? 'observation';
// Escape backslashes for JSON on Windows
const escapedBunPath = bunPath.replace(/\\/g, '\\\\');
const escapedWorkerPath = workerServicePath.replace(/\\/g, '\\\\');
return `"${escapedBunPath}" "${escapedWorkerPath}" hook windsurf ${hookCommand}`;
return `"${bunPath}" "${workerServicePath}" hook windsurf ${hookCommand}`;
}
/**
@@ -240,10 +236,7 @@ function mergeAndWriteHooksJson(
existingConfig.hooks = {};
}
} catch (error) {
logger.error('WINDSURF', 'Corrupt hooks.json, starting fresh', {
path: WINDSURF_HOOKS_JSON_PATH,
}, error as Error);
existingConfig = { hooks: {} };
throw new Error(`Corrupt hooks.json at ${WINDSURF_HOOKS_JSON_PATH}, refusing to overwrite`);
}
}
@@ -410,9 +403,7 @@ export function uninstallWindsurfHooks(): number {
console.log(` Removed claude-mem entries from hooks.json (other hooks preserved)`);
}
} catch (error) {
// Corrupt file — just remove it
unlinkSync(WINDSURF_HOOKS_JSON_PATH);
console.log(` Removed corrupt hooks.json`);
console.log(` Warning: could not parse hooks.json — leaving file intact to preserve other hooks`);
}
} else {
console.log(` No hooks.json found`);