import type { ToolResultMessage } from "@earendil-works/pi-ai"; /** * Decide whether the turn just performed a file mutation worth checkpointing. * * This is a fast heuristic. It checks `toolResults` to see whether any tool * that may mutate files was invoked. Callers should still verify with * `git status` that the working tree actually changed before creating a checkpoint * commit. * * @param toolResults - Tool results emitted in `turn_end`. */ export declare function shouldCreateCheckpointCommit(toolResults: ToolResultMessage[]): boolean; /** * Detect a `git ... commit` invocation inside a shell command. * * @returns `true` when any segment contains a `git ... commit` invocation. */ export declare function shouldBlockGitCommit(command: string): boolean; /** * Detect a `git ... push` invocation inside a shell command. * * Pushing before `agent_end` ships raw checkpoint commits to the remote, * which then diverge from the reorganised history pi-autocommit creates * afterwards. * * @returns `true` when any segment contains a `git ... push` invocation. */ export declare function shouldBlockGitPush(command: string): boolean; /** * Detect a `git ... reset --hard` invocation inside a shell command. * * `git reset --soft` / `--mixed` (the default) only move HEAD and staging and * are left alone — agents legitimately use them to inspect and rewind history. * `--hard` additionally destroys the working tree, which can wipe changes made * in the current turn before the next checkpoint captures them. * * @returns `true` when any segment contains a `git ... reset` invocation and a * `--hard` flag. */ export declare function shouldBlockGitHardReset(command: string): boolean; /** * Detect a `git ... ` invocation that would interleave a foreign commit * into the checkpoint run (merge, cherry-pick, rebase), returning the matched * verb, or `null` when none is found. * * `git merge --squash` is excluded: it stages the merged changes without * creating a commit, so it cannot interleave history — the staged changes flow * through the normal turn_end checkpoint instead. This is the blessed way to * integrate a worktree branch whose tip may still hold un-reorganised * checkpoints (e.g. a delegated agent that crashed before `agent_end`). * * The other three rewrite or append history at HEAD: the merged/cherry-picked/ * rebased commits are not checkpoints, so `countCheckpointCommits` stops at * them and the checkpoints below are silently dropped from automatic * reorganisation. `rebase` additionally leaves the repo in a half-finished * state on conflict. * * @returns The matched verb, or `null`. */ export declare function blockedInterleavingVerb(command: string): string | null; /** * Whether a merge/cherry-pick invocation is safe to allow without a guard * block because HEAD holds no checkpoint commit to interleave into. * * Called by the `tool_call` handler when `blockedInterleavingVerb` matched * "merge" or "cherry-pick". When HEAD's subject is not a checkpoint there is * no checkpoint run at the top of the branch, so the foreign commit cannot * strand any checkpoints below it. A `null` headSubject (HEAD unresolved) is * treated conservatively as "block" so an unreadable repo is not silently * allowed to break the checkpoint run. */ export declare function interleavingAllowedWithoutCheckpoints(blocked: string | null, headSubject: string | null, marker: string): boolean; /** * Build the user-facing block reason for a blocked git operation. * * Explains why the operation is blocked and how to disable the guard * (`/autocommit-enable false`). Written in Japanese when `japanese` is true, * English otherwise. When `enable` is false the guard is inert and none of * these operations are blocked. */ export declare function buildBlockReason(blocked: string, japanese: boolean): string; /** * Decide whether the commit reorganiser should be skipped at `agent_end`. * * Returns `true` when the HEAD commit captured at `agent_start` matches the * current HEAD. This means the agent run produced no commits, so there is * nothing to reorganise. * * A `null` baseline (e.g., HEAD could not be read at `agent_start`) is treated * as "unknown", so the reorganiser proceeds with its normal behaviour rather * than risk silently skipping a real reorganisation. */ export declare function shouldSkipReorganisation(baselineHead: string | null, currentHead: string | null): boolean; //# sourceMappingURL=commit-policy.d.ts.map