refactor(uninstall): stop modifying global settings.json

- remove removeHookConfig() call from uninstallWebSearchHook()

- add removeMigrationMarker() cleanup

- update postuninstall.js to only clean CCS files

- global ~/.claude/settings.json is never touched
This commit is contained in:
kaitranntt
2026-01-25 20:26:27 -05:00
parent 0099ab5a1c
commit ba1fb7eeb3
2 changed files with 28 additions and 41 deletions
+18 -38
View File
@@ -2,7 +2,9 @@
/** /**
* CCS Postuninstall Script * CCS Postuninstall Script
* *
* Cleans up WebSearch hook from ~/.claude/settings.json after npm uninstall. * Cleans up CCS-specific files after npm uninstall.
* Does NOT touch global ~/.claude/settings.json (hooks are per-profile now).
*
* Self-contained, no external dependencies. * Self-contained, no external dependencies.
*/ */
@@ -10,51 +12,29 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const os = require('os'); const os = require('os');
const SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json'); const CCS_DIR = path.join(os.homedir(), '.ccs');
const HOOKS_DIR = path.join(CCS_DIR, 'hooks');
const MIGRATION_MARKER = path.join(CCS_DIR, '.hook-migrated');
function cleanupHook() { function cleanupCcsFiles() {
try { try {
if (!fs.existsSync(SETTINGS_PATH)) { // Remove WebSearch hook file
return; // Nothing to clean const hookPath = path.join(HOOKS_DIR, 'websearch-transformer.cjs');
if (fs.existsSync(hookPath)) {
fs.unlinkSync(hookPath);
} }
const content = fs.readFileSync(SETTINGS_PATH, 'utf8'); // Remove migration marker (so fresh install re-runs migration)
let settings; if (fs.existsSync(MIGRATION_MARKER)) {
try { fs.unlinkSync(MIGRATION_MARKER);
settings = JSON.parse(content);
} catch {
return; // Malformed JSON, don't touch
} }
const hooks = settings.hooks; // Note: Do NOT touch ~/.claude/settings.json
if (!hooks?.PreToolUse) { // Per-profile hooks in ~/.ccs/*.settings.json will be cleaned up
return; // No hooks to remove // when the user removes ~/.ccs/ directory.
}
const originalLength = hooks.PreToolUse.length;
hooks.PreToolUse = hooks.PreToolUse.filter((h) => {
if (h.matcher !== 'WebSearch') return true;
const command = h.hooks?.[0]?.command;
if (!command) return true;
return !command.includes('.ccs/hooks/websearch-transformer');
});
if (hooks.PreToolUse.length === originalLength) {
return; // Nothing changed
}
// Clean up empty structures
if (hooks.PreToolUse.length === 0) {
delete hooks.PreToolUse;
}
if (Object.keys(hooks).length === 0) {
delete settings.hooks;
}
fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2), 'utf8');
} catch { } catch {
// Silent fail - not critical // Silent fail - not critical
} }
} }
cleanupHook(); cleanupCcsFiles();
+10 -3
View File
@@ -11,7 +11,8 @@ import * as path from 'path';
import * as os from 'os'; import * as os from 'os';
import { info, warn } from '../ui'; import { info, warn } from '../ui';
import { getWebSearchConfig } from '../../config/unified-config-loader'; import { getWebSearchConfig } from '../../config/unified-config-loader';
import { getHookPath, ensureHookConfig, removeHookConfig } from './hook-config'; import { getHookPath, ensureHookConfig } from './hook-config';
import { removeMigrationMarker } from './profile-hook-injector';
// Re-export from hook-config for backward compatibility // Re-export from hook-config for backward compatibility
export { getHookPath, getWebSearchHookConfig } from './hook-config'; export { getHookPath, getWebSearchHookConfig } from './hook-config';
@@ -102,6 +103,9 @@ export function installWebSearchHook(): boolean {
/** /**
* Uninstall WebSearch hook from ~/.ccs/hooks/ * Uninstall WebSearch hook from ~/.ccs/hooks/
* *
* Note: Does NOT touch global ~/.claude/settings.json.
* Profile-specific hooks are removed when ~/.ccs/ is deleted.
*
* @returns true if hook uninstalled successfully * @returns true if hook uninstalled successfully
*/ */
export function uninstallWebSearchHook(): boolean { export function uninstallWebSearchHook(): boolean {
@@ -115,8 +119,11 @@ export function uninstallWebSearchHook(): boolean {
} }
} }
// Remove from settings.json // Remove migration marker (so fresh install re-runs migration)
removeHookConfig(); removeMigrationMarker();
// Note: Do NOT call removeHookConfig() - global settings should not be touched.
// Per-profile hooks in ~/.ccs/*.settings.json are cleaned up when ~/.ccs/ is deleted.
return true; return true;
} catch (error) { } catch (error) {