export interface CommitResult {
    ok: boolean;
    sha?: string;
    message?: string;
    filesCommitted: number;
    error?: string;
}
export interface BranchOptions {
    cwd?: string;
    /** Default 30s — git operations should be fast. */
    timeoutMs?: number;
}
export declare class GitOps {
    private cwd;
    constructor(cwd?: string);
    /** Returns the current branch name, or 'HEAD' when detached. */
    getCurrentBranch(): Promise<string>;
    /** Returns absolute paths of files modified/staged but not yet committed. */
    getDirtyFiles(): Promise<string[]>;
    /** True iff the working tree has no uncommitted changes (staged or unstaged). */
    isClean(): Promise<boolean>;
    /** Returns true when on a protected branch (main/master/etc.). */
    isOnProtectedBranch(): Promise<boolean>;
    /**
     * Create AND checkout a new branch from the current HEAD.
     * Refuses if a branch with the same name already exists.
     */
    createBranch(name: string): Promise<{
        ok: boolean;
        error?: string;
    }>;
    /**
     * Stage the listed paths. Errors if any path is absent from the working
     * tree. Paths can be absolute or cwd-relative.
     */
    stageFiles(paths: string[]): Promise<{
        ok: boolean;
        error?: string;
    }>;
    /**
     * Create a commit with the supplied message. Requires staged changes
     * (or it errors with `nothing_to_commit`). Returns the commit SHA on
     * success.
     */
    commit(message: string): Promise<CommitResult>;
    /**
     * Slugify a story id + title into a branch name.
     * Example: ('1.1', '[BUG] Fix the gateway') → 'story-1.1-bug-fix-the-gateway'
     */
    static branchNameFromStory(storyId: string, title: string): string;
    /**
     * v1.18.0 — Push the current branch to a remote. THIS IS THE @VORTEX
     * ESCAPE HATCH — only `openlife ship` should call it. Refuses to push
     * to a protected branch, refuses if no upstream tracking is set, and
     * refuses without --upstream when current branch has no remote.
     *
     * Anyone else calling this gets `gitops_refused: not_authorized` —
     * the caller must set _pushAuthorized=true BEFORE the call and
     * reset to false immediately after (try/finally pattern).
     */
    push(opts?: {
        remote?: string;
        setUpstream?: boolean;
    }): Promise<{
        ok: boolean;
        remote: string;
        branch: string;
        error?: string;
    }>;
    /**
     * v1.18.0 — Authorize a single push operation. Returns a `release`
     * function the caller MUST invoke in a finally block. Pattern:
     *
     *   const release = GitOps._authorizePush();
     *   try { await gitops.push(...); } finally { release(); }
     *
     * The flag is module-level so anyone holding it during the call
     * window can push. Use sparingly. ShipCommand is the only sanctioned
     * caller today.
     */
    static _authorizePush(): () => void;
    /** Exposed for tests so they can override the protected list. */
    static _protectedBranches(): string[];
}
