#!/usr/bin/env node /** * `mnemonik-claude-code-hooks install` — wires the dispatcher into * Claude Code settings without clobbering the user's existing config. * * What it does: * 1. Copies the dispatcher and its shared runtime dependency to a stable, * content-addressed ~/.mnemonik/hooks directory. * 2. Reads (or creates) ~/.claude/settings.json by default. * Use --scope=project to target .claude/settings.json at the cwd. * 3. Merges PreToolUse/PostToolUse entries pointing at `node `, * removing any prior mnemonik-managed entries first so re-running the * installer is idempotent. * 4. Writes the file back, preserving any unrelated user config. * * Installer mechanics use Node 20 builtins only; the copied dispatcher keeps * its exact resolved @mnemonik/shared dependency. */ type InstallTarget = 'host' | 'project'; interface SettingsHooksEntry { type: 'command'; command: string; statusMessage?: string; timeout?: number; [k: string]: unknown; } interface SettingsHookGroup { matcher?: string; hooks?: SettingsHooksEntry[]; [k: string]: unknown; } interface StatusLineConfig { type: 'command'; command: string; padding?: number; } interface ClaudeSettings { hooks?: { PreToolUse?: SettingsHookGroup[]; PostToolUse?: SettingsHookGroup[]; SessionStart?: SettingsHookGroup[]; SubagentStart?: SettingsHookGroup[]; Stop?: SettingsHookGroup[]; PreCompact?: SettingsHookGroup[]; SessionEnd?: SettingsHookGroup[]; UserPromptSubmit?: SettingsHookGroup[]; [k: string]: unknown; }; statusLine?: StatusLineConfig; [k: string]: unknown; } /** * Apply the exact Mnemonik hook registration used by the production installer. * Callers may supply a different command (the harness points at its worktree * build), but event coverage, matchers, timeouts and status messages stay owned * here so a fixture cannot silently drift from production. */ declare function applyMnemonikHookSettings(settings: ClaudeSettings, command: string): ClaudeSettings; /** * Decide the statusLine wiring without touching disk. NEVER clobbers a user's * existing custom statusline: writes when the key is absent or when the old * value is explicitly Mnemonik-owned, and only when the executable is built. * `set` is the new config (or null to leave settings untouched). */ declare function statusLineDecision(existing: StatusLineConfig | undefined, statuslinePath: string, built: boolean): { set: StatusLineConfig | null; note: string; }; declare function buildHookEntry(dispatcher: string, statusMessage?: string): SettingsHooksEntry; declare function isMnemonikEntry(entry: SettingsHookGroup, currentDispatcher?: string): boolean; declare function patchHookGroup(groups: SettingsHookGroup[] | undefined, matcher: string | null, entry: SettingsHooksEntry): SettingsHookGroup[]; declare function readSettings(path: string): Promise<{ settings: ClaudeSettings; raw: string | null; }>; declare function parseArgs(argv: string[]): { target: InstallTarget; }; declare function removeMnemonikHooks(settings: ClaudeSettings, currentDispatcher?: string): boolean; declare function resolveTargetPath(target: InstallTarget, cwd: string, env?: Partial>): string; declare function main(argv: string[]): Promise; declare function runProxyCommand(argv: string[]): Promise; export { readSettings, removeMnemonikHooks, applyMnemonikHookSettings, buildHookEntry, isMnemonikEntry, main, parseArgs, patchHookGroup, resolveTargetPath, runProxyCommand, statusLineDecision, };