/**
 * GF.2 — install / check the opensquid-managed git `pre-commit` + `pre-push` hooks.
 *
 * PGB.1 (T-fix-pushgate-bypass): installation is a pure GATE-FIRST composition.
 * The previous installer APPENDED the gate call to a foreign hook — unsound for any
 * foreign hook that ends in `exec`/`exit` (the repo's own PP.1 quality hook does:
 * `exec pnpm prepush` made the appended gate block unreachable dead code, which is
 * how a code push bypassed the flow gate on 2026-06-10). `composeHook` now prepends
 * the managed block directly after the shebang, so the gate ALWAYS runs first and
 * the foreign body keeps its exact semantics afterward. It also REPAIRS any layout
 * where managed lines exist elsewhere (today's dead-block file), idempotently.
 *
 * The hooks carry the `@opensquid managed hook` MARKER so `opensquid doctor git-hooks`
 * can recognise them. `checkGitHooks` additionally detects `unreachable` — marker
 * present but a process-terminating line (`exec`/`exit`) precedes it. Installation is
 * OPT-IN (explicit `opensquid gate install`), never automatic; a foreign hook body is
 * preserved verbatim, never clobbered.
 *
 * Imported by: src/setup/cli/gate.ts (install), src/setup/cli/doctor.ts (check).
 */
export declare const OPENSQUID_HOOK_MARKER = "@opensquid managed hook";
type HookBoundary = 'commit' | 'push' | 'attest';
export type GitHookState = 'installed' | 'missing' | 'foreign' | 'unreachable';
export interface GitHookStatus {
    name: string;
    state: GitHookState;
}
/**
 * Pure: compose an existing hook body (or null/empty) into the canonical gate-first
 * layout: shebang → managed block → foreign body verbatim. Strips ALL prior managed
 * lines wherever they sit, so it both installs and repairs (e.g. a gate block left
 * dead below a foreign `exec`). A foreign line that itself invokes `opensquid gate
 * <boundary>` is treated as managed and stripped — keeping it would double-run the
 * gate. Idempotent: composeHook(composeHook(x)) === composeHook(x).
 */
export declare function composeHook(existing: string | null, boundary: HookBoundary): string;
/** Marker present but a terminal line precedes it → the managed gate can never run. */
export declare function isMarkerUnreachable(content: string): boolean;
/** Install (idempotent) both hooks into `<repoRoot>/.git/hooks` via gate-first
 *  composition. A foreign body is preserved verbatim BELOW the gate; a broken layout
 *  (dead managed block) is repaired. `installed` = the file is purely managed;
 *  `foreign` = a user body rides below the gate. */
export declare function installGitHooks(repoRoot: string): Promise<GitHookStatus[]>;
/** Report installation state without writing. `missing` = no hook; `foreign` = a hook
 *  exists but carries no opensquid marker; `unreachable` = the marker exists but a
 *  preceding `exec`/`exit` makes the gate dead code; `installed` = the gate runs. */
export declare function checkGitHooks(repoRoot: string): Promise<GitHookStatus[]>;
export {};
//# sourceMappingURL=git-hooks.d.ts.map