/** * Destructive-git guard: refuses model-issued shell commands that would throw * away the user's uncommitted work. * * Checkpoints only capture edits made through write/edit, so one * `git reset --hard` from the shell would otherwise lose work with no undo. * * Two phases: * 1. {@link findDestructiveGitCommands} — pure parse. A small quote-aware shell * scanner splits the command into simple commands (through `&&`/`;`/`||`/ * pipes, subshells, `$(…)`/backticks, `if`/`for`/`while` bodies), unwraps * `bash -c`/`sh -c`/`eval` scripts and exec wrappers (`sudo`, `env`, * `timeout`, `nohup`, `xargs`, …), follows `cd` and `git -C`, and classifies * each git invocation. * 2. {@link checkDestructiveGit} — context. Discarding commands are blocked * only when `git status` in the target directory shows something they would * destroy; a clean tree passes. Plain force-push is always blocked. * * Fails OPEN on guard errors (git missing, timeout): the guard is a seatbelt * against an agent mistake, not a sandbox, and must never wedge the bash tool. */ type DestructiveGitKind = "reset-hard" | "checkout-paths" | "restore-worktree" | "clean" | "stash-drop" | "stash-clear" | "branch-force-delete" | "force-push"; export interface DestructiveGitMatch { kind: DestructiveGitKind; /** The git invocation as parsed, for the block message. */ display: string; /** Directory git would run in (after `cd` and `git -C`). */ dir: string; /** `--git-dir=`/`--work-tree=` globals to forward to inspection commands. */ gitArgs: string[]; /** Pathspecs limiting what is discarded; empty means the whole tree. */ pathspecs: string[]; /** checkout with one operand that may be a branch rather than a path. */ maybeRef?: string; /** clean: also/only removes ignored files (`-x` / `-X`). */ ignored?: "also" | "only"; /** clean: `-d` also removes untracked directories. */ directories?: boolean; /** branch -D targets; stash drop target. */ refs: string[]; } /** Basename of a command word, `.exe` stripped (`/usr/bin/git`, `git.exe`). */ export declare function commandName(word: string): string; /** * Expand the home and working-directory forms a model writes in paths: * `~`, `$HOME`/`${HOME}` (any case, which also covers PowerShell `$home`), * `$env:USERPROFILE`/`$env:HOME`, cmd `%USERPROFILE%`, and `$PWD`/`${PWD}`. Other variables stay * literal, so they resolve to a harmless relative path. */ export declare function expandShellPath(p: string, cwd: string): string; /** One simple command found in a shell string, after unwrapping. */ export interface ShellInvocation { /** {@link commandName} of the command word. */ name: string; args: readonly string[]; /** Directory it would run in after any earlier `cd` in the same script. */ cwd: string; /** Run by `xargs`, which appends operands read from stdin. */ viaXargs: boolean; } /** * Every simple command in `command` whose name satisfies `wanted`, in source * order, after splitting on `&&`/`;`/`||`/pipes, entering subshells, * substitutions and `if`/`for`/`while` bodies, unwrapping `bash -c`/`eval`/ * `pwsh -c` scripts and exec wrappers (`sudo`, `env`, `timeout`, `xargs`, …), * and following `cd`. Pure: nothing is executed. */ export declare function walkShell(command: string, cwd: string, wanted: (name: string) => boolean): ShellInvocation[]; /** * Parse `command` and return every git invocation in it that can destroy * work, with the directory each would run in. Pure apart from `existsSync` * for ambiguous `git checkout `. */ export declare function findDestructiveGitCommands(command: string, cwd: string): DestructiveGitMatch[]; export interface DestructiveGitCheckOptions { /** The tool's working directory. */ cwd: string; /** * The shell's real current directory when it can differ from `cwd` * (persistent session shell after a `cd`). Only called when the command * contains a destructive git invocation. */ resolveCwd?: () => Promise; } /** * Returns a block message for the model when `command` would destroy * uncommitted work (or force-push), or null to let it run. */ export declare function checkDestructiveGit(command: string, options: DestructiveGitCheckOptions): Promise; export {};