/** * hook install/remove service. * * Writes the auto-compact PreToolUse hook into the consumer * project's `.claude/settings.local.json` so the next Bash or Task * tool call from the running Claude Code session reads * `CLAUDE_CONTEXT_USAGE_PERCENT` and, at ratio ≥ 0.95, in-band fires * `claude --compact` against the current runner (not a child process). * * Idempotency contract: * - install is idempotent — calling `installAutoCompactHook` * twice produces a byte-identical file (after stripping the * magic comment). The on-disk matcher entry is the single * source of truth. * - remove is idempotent — calling `removeAutoCompactHook` when * the hook is absent is a no-op. * - other PreToolUse entries are untouched on install AND remove. * * Magic comment marker: `peaks:auto-compact-hook-do-not-edit`. The * comment sits next to the matcher entry so a human reading the file * sees the boundary; an automated diff/remove op keys off the marker * + the `matcher` regex. * * Pure data + minimal IO: `installAutoCompactHook` and * `removeAutoCompactHook` accept `settingsPath` so callers can pick * `.claude/settings.local.json` (default) or pass an explicit path * for tests. The functions write to disk via `fs.writeFileSync` so * the on-disk file matches the in-memory template byte-for-byte * (modulo the magic comment which is excluded from the data * structure; see `AUTO_COMPACT_HOOK_MATCHER`). */ /** * Stable matcher for the auto-compact hook. Single source of truth * — `install` and `remove` both key off this constant so the * invariants can't drift between the two paths. */ export declare const AUTO_COMPACT_HOOK_MATCHER = "Bash|Task"; /** * Stable command the hook fires. Wraps `peaks code auto-compact` so the * heavy lifting (ratio probe + in-band `claude --compact` spawn) * lives in the CLI surface, not inlined into the hook. * * `--project .` is LOAD-BEARING, not decoration. `--project` is a * `.requiredOption` on `peaks code auto-compact`, and a hook has no way * to prompt for a missing required option. Without this argument the * hook exited with `error: required option '--project ' not * specified` on EVERY matching tool call — a non-blocking failure, so * the hook looked installed while the zero-human-intervention * auto-compact contract never once fired. `.` is promoted to the git * root by `resolveCanonicalProjectRoot`, the same convention the * `post-compact-detect` hook already documents in its own option help. * * `npx peaks` is deliberately omitted: the project-local install * puts `peaks` on PATH inside the consumer repo (postinstall step), * so the unqualified command works in the same shell the runner * is using. */ export declare const AUTO_COMPACT_HOOK_COMMAND = "peaks code auto-compact --project ."; /** * Magic comment marker that fences the auto-compatchook block. * Both install (writes the marker) and remove (matches on it) use * this string so the comment is the only place the boundary lives. */ export declare const AUTO_COMPACT_HOOK_MARKER = "peaks:auto-compact-hook-do-not-edit"; /** * Default on-disk location — kept here (not in claude-settings-template) * because the auto-compact hook is a separate install surface from * the fact-forcing gate bypass template. * * This is Claude Code's path, and it is a DEFAULT only. A caller that * resolved an IDE adapter MUST pass the adapter-declared location as * `settingsPath`: * `join(projectRoot, adapter.settings.dirName, adapter.settings.localSettingsFileName)`. * The default remains for callers with no adapter in hand (and keeps the * claude-code byte-stability contract); it is not a claim that every IDE * stores local settings at `.claude/settings.local.json`. */ export declare const AUTO_COMPACT_HOOK_SETTINGS_PATH = ".claude/settings.local.json"; /** * Result envelope for `installAutoCompactHook`. */ export type AutoCompactHookInstallResult = { readonly action: 'installed'; readonly settingsPath: string; } | { readonly action: 'already-installed'; readonly settingsPath: string; } | { readonly action: 'updated'; readonly settingsPath: string; }; /** * Result envelope for `removeAutoCompactHook`. */ export type AutoCompactHookRemoveResult = { readonly action: 'removed'; readonly settingsPath: string; } | { readonly action: 'absent'; readonly settingsPath: string; }; /** * Install the auto-compact PreToolUse hook. Idempotent: a re-run * returns `action: 'already-installed'` and does NOT re-write the * file (preserves any unrelated edits the user has made to other * entries). */ export declare function installAutoCompactHook(input: { readonly projectRoot: string; readonly settingsPath?: string | undefined; }): AutoCompactHookInstallResult; /** * Remove the auto-compact PreToolUse hook. Idempotent: missing hook * returns `action: 'absent'` without re-writing the file. * * Other PreToolUse entries are left untouched. The settings file * structure is preserved (top-level keys like `permissions` are not * deleted). */ export declare function removeAutoCompactHook(input: { readonly projectRoot: string; readonly settingsPath?: string | undefined; }): AutoCompactHookRemoveResult;