/**
 * Idempotent writer for Claude Code's `settings.json` hook block (G.1 Part B).
 *
 * Writes opensquid's anti-drift hook entries (one per event in
 * `OPENSQUID_BIN_FOR_EVENT`: PreToolUse, PostToolUse, UserPromptSubmit, Stop,
 * SessionEnd, SessionStart) while preserving every non-opensquid hook entry
 * verbatim.
 *
 * Three recognition rules identify entries the writer OWNS (all three live in
 * `isOpensquidHookEntry` — the ONE ownership predicate, also consumed by
 * doctor's managed-filter + spawn gate and the flow-health check):
 *   1. `'@opensquid': true` marker on the inner hook entry — every entry the
 *      writer adds carries this.
 *   2. `LEGACY_OPENSQUID_PATTERN` regex — the broken ancient
 *      `node <abs>/opensquid/dist/index.js anti-drift <event>` shape (G.1).
 *   3. Bin-name basename match (`isOpensquidHookCommand`) — bare modern
 *      `opensquid-hook-*` commands written before the marker contract existed
 *      (T-FIX-WIZARD-HOOK-RECOGNITION: these used to be "preserved" as
 *      third-party, so every wizard re-run DUPLICATED every hook).
 *
 * A `.bak` snapshot is written before any mutation. The marker contract is
 * the FIRST line of defense; .bak is the last. Audit phase MUST verify
 * every opensquid-written entry carries the marker.
 *
 * Engine-vocabulary discipline: this module is the ONLY G.1 file that names
 * Claude Code's hook event types. `discovery.ts` + `bootstrap.ts` are
 * harness-agnostic.
 *
 * Imported by: src/setup/cli/hooks.ts.
 */
export declare const OPENSQUID_BIN_FOR_EVENT: {
    readonly PreToolUse: "opensquid-hook-pretooluse";
    readonly PostToolUse: "opensquid-hook-posttooluse";
    readonly UserPromptSubmit: "opensquid-hook-userpromptsubmit";
    readonly Stop: "opensquid-hook-stop";
    readonly SessionEnd: "opensquid-hook-sessionend";
    readonly SessionStart: "opensquid-hook-sessionstart";
};
export type ClaudeEvent = keyof typeof OPENSQUID_BIN_FOR_EVENT;
export declare const PRETOOLUSE_HOOK_TIMEOUT_S = 360;
interface HookCommandEntry {
    type: string;
    command?: string;
    '@opensquid'?: boolean;
    [k: string]: unknown;
}
interface HookGroup {
    matcher?: string;
    hooks?: HookCommandEntry[];
    [k: string]: unknown;
}
interface SettingsJson {
    hooks?: Partial<Record<string, HookGroup[]>>;
    [k: string]: unknown;
}
export declare const LEGACY_OPENSQUID_PATTERN: RegExp;
/** Is this command string one of opensquid's hook binaries (any path, any era)? */
export declare const isOpensquidHookCommand: (command: string) => boolean;
/** Is this inner hook entry opensquid-owned (marker OR command shape)? */
export declare const isOpensquidHookEntry: (h: HookCommandEntry) => boolean;
export interface WriteResult {
    /** Number of fresh opensquid entries added — one per `OPENSQUID_BIN_FOR_EVENT` key. */
    added: number;
    /**
     * Number of groups that had opensquid-owned entries removed — wholly-owned
     * groups dropped OR owned entries excised from a mixed group (a mixed group
     * increments BOTH `replaced` and `preserved`: ours left, the group survived).
     */
    replaced: number;
    /** Number of hook groups preserved (verbatim, or minus excised owned entries). */
    preserved: number;
    /** Path to the `.bak` snapshot written before mutation. */
    backupPath: string;
}
/**
 * Pure projection — disk-untouched. Used by both the writer and `--dry-run`.
 * Input JSON is deep-cloned (JSON round-trip; safe because settings.json
 * never contains Date/Set/Map/functions), so callers' objects don't mutate.
 */
export declare function projectOpensquidHooks(input: SettingsJson): {
    output: SettingsJson;
    added: number;
    replaced: number;
    preserved: number;
};
/**
 * Write opensquid's hook entries to `settingsPath`. Creates a `.bak` snapshot
 * (`{}` if the file didn't exist). Same 2-space JSON indentation as the live
 * file so `diff <file>.bak <file>` highlights only the hook changes.
 */
export declare function writeOpensquidHooks(settingsPath: string): Promise<WriteResult>;
/** ENOENT → `{}` (first-run case). All other errors propagate. */
export declare function readSettingsJson(settingsPath: string): Promise<SettingsJson>;
export {};
//# sourceMappingURL=settings-writer.d.ts.map