/**
 * Tagged-merge writer for `.codex/hooks.json`.
 *
 * Codex's hooks parser is not configured with `deny_unknown_fields` (verified
 * against `codex-rs/config/src/hook_config.rs`), so Lisa can attach
 * `_lisaManaged: true` and `_lisaId: "..."` marker fields to individual hook
 * entries. On every install the merger:
 *
 *   1. Reads the existing hooks.json (if any)
 *   2. Strips every entry where `_lisaManaged === true`
 *   3. Appends the current Lisa hook set with markers attached
 *   4. Preserves all entries the host added (no `_lisaManaged` marker)
 *
 * This mirrors the pattern Lisa uses for `enabledPlugins` deep-merge in
 * `.claude/settings.json` — ownership is keyed on a marker field instead of
 * a key path.
 * @module codex/hooks-merger
 */
/** Markers attached to every Lisa-owned hook entry */
export declare const LISA_MANAGED_MARKER: "_lisaManaged";
export declare const LISA_ID_MARKER: "_lisaId";
/** A single hook handler entry (innermost: type/command/timeout/etc.) */
export interface HookHandler {
    readonly type: string;
    readonly command?: string;
    readonly timeout?: number;
    readonly statusMessage?: string;
    /** Lisa ownership marker (set on Lisa-owned entries only) */
    readonly [LISA_MANAGED_MARKER]?: boolean;
    /** Stable identifier so logs can name the hook */
    readonly [LISA_ID_MARKER]?: string;
}
/** A matcher group: a regex matcher + an array of handlers it triggers */
export interface MatcherGroup {
    readonly matcher: string;
    readonly hooks: readonly HookHandler[];
}
/** All hook events Codex understands */
export type CodexHookEvent = "PreToolUse" | "PostToolUse" | "UserPromptSubmit" | "Stop" | "SessionStart" | "PermissionRequest";
/** The shape of `.codex/hooks.json` */
export interface HooksFile {
    readonly hooks?: Readonly<Partial<Record<CodexHookEvent, readonly MatcherGroup[]>>>;
}
/** A Lisa-owned hook to be installed (mutable input — markers added by merger) */
export interface LisaHookSpec {
    /** Stable identifier; goes into `_lisaId` so logs can name the hook */
    readonly id: string;
    /** Codex hook event the entry applies to */
    readonly event: CodexHookEvent;
    /** Matcher regex for `matcher` field (use "" for events that don't match) */
    readonly matcher: string;
    /** Shell command to run */
    readonly command: string;
    /** Optional timeout in seconds (Codex default is 600) */
    readonly timeout?: number;
    /** Optional human-readable status message */
    readonly statusMessage?: string;
}
/**
 * Merge Lisa's current hook set into an existing hooks.json document,
 * preserving any host-authored entries.
 * @param existing - Parsed hooks.json (or {} if none)
 * @param lisaHooks - Lisa-owned hook specs to install
 * @returns New HooksFile object with Lisa entries replaced and host entries preserved
 */
export declare function mergeLisaHooks(existing: HooksFile, lisaHooks: readonly LisaHookSpec[]): HooksFile;
/**
 * Serialize a HooksFile to JSON suitable for writing to disk. Two-space
 * indent, trailing newline.
 * @param file - Hooks file to serialize
 * @returns JSON string ending with a newline
 */
export declare function serializeHooksFile(file: HooksFile): string;
/**
 * Type guard: parse raw JSON into a HooksFile, validating only the shape we
 * touch. We do NOT reject unknown fields since Codex's parser allows them
 * and we want to preserve host extensions on round-trip.
 * @param raw - Untrusted JSON string from disk
 * @returns Parsed HooksFile
 */
export declare function parseHooksFile(raw: string): HooksFile;
//# sourceMappingURL=hooks-merger.d.ts.map