export interface MergeResult { outcome: "created" | "merged" | "already-present" | "error"; warning?: string; } interface HookEntry { type: "command"; command: string; timeout: number; } interface SessionStartGroup { hooks: HookEntry[]; } interface MatcherGroup { matcher: string; hooks: HookEntry[]; } export interface ForgeSettingsHooks { SessionStart: SessionStartGroup[]; PreToolUse: MatcherGroup[]; PostToolUse: MatcherGroup[]; PermissionRequest: MatcherGroup[]; } /** * Returns the canonical Forge hooks block for project .claude/settings.json. * * All commands point at $CLAUDE_PROJECT_DIR/.forge/tools/hooks/.cjs * (CLAUDE_PROJECT_DIR is a Claude Code runtime env var; not resolved at build time). * * Hook list mirrors forge/forge/hooks/hooks.json, with commands re-targeted * from ${CLAUDE_PLUGIN_ROOT}/hooks/ to $CLAUDE_PROJECT_DIR/.forge/tools/hooks/. */ export declare function buildForgeHooksBlock(): ForgeSettingsHooks; /** * Merge Forge hooks into the project .claude/settings.json with merge-not-clobber semantics. * * Rules: * 1. File absent → create with { "hooks": }. * 2. File present, valid JSON, no hooks key → add hooks key, preserve all other keys. * 3. File present, valid JSON, hooks key with all Forge entries already present → "already-present" (no-op). * 4. File present, valid JSON, hooks key with unrelated or missing Forge entries → * merge Forge entries, preserve all existing non-Forge entries. * 5. File present, malformed JSON → "error", file never overwritten. * 6. Write failure → "error" with descriptive warning. */ export declare function mergeForgeHooks(settingsPath: string): MergeResult; export {};