/** * Shadow-git undo (opencode pattern, OK-5 feature floor). * * A second git repository whose GIT_DIR lives at `/.openkai/shadow.git` * (gitignored) and whose work tree IS the project directory. Snapshots are * full-tree commits taken before gated mutations; undo walks the shadow * HEAD back and restores the work tree — the operator's real git history is * never touched. * * Ported semantics from opencode's `packages/opencode/src/snapshot/index.ts`: * separate git dir, `objects/info/alternates` pointing at the project repo * (object sharing, no duplication), full-tree snapshot commits. Differences: * no 2 MiB file cap and no 7-day prune yet (recorded as follow-ups; the * shadow dir is local state the operator can delete). * * Two hard-won boundary rules: * 1. The child env strips every inherited GIT_* variable before applying * the shadow identity — an inherited GIT_INDEX_FILE/GIT_DIR would * redirect shadow ops into the operator's real repo. * 2. Snapshots use `git add -A -f` with an explicit `.openkai` pathspec * exclude, so GITIGNORED mutations (.env, dist/) are captured and * undo() can restore them — undo that silently skips the very files a * gated run is most likely to touch is not undo. */ export interface ShadowSnapshot { sha: string; message: string; } /** The read-only diff view (E017 S1 `/diff`): base snapshot + unified diff + untracked names. */ export interface ShadowDiff { /** The snapshot sha the diff is computed against. */ base: string; /** `git diff ` over the work tree (tracked modifications). */ diff: string; /** Files in the work tree that no snapshot tracks (names only). */ untracked: string[]; } export declare class ShadowGitError extends Error { readonly name = "ShadowGitError"; } export declare class ShadowGit { readonly cwd: string; readonly gitDir: string; constructor(cwd: string); private git; private head; /** Idempotent: initialises the shadow repo + alternates on first use. */ init(): Promise; /** * Commit the full current tree. Returns the snapshot sha, or the current * HEAD unchanged when the tree is clean (snapshots are idempotent). * * `add -A -f` is deliberate: undo must restore what a gated mutation * changed, and mutations do not respect .gitignore — a builder that edits * `.env` or writes into `dist/` must be undoable. The pathspec exclude on * `.openkai` replaces the protection -f strips from the info/exclude rule * (verified: -f overrides BOTH .gitignore and info/exclude, so without the * pathspec the shadow would snapshot its own object store). */ snapshot(message: string): Promise; /** * Walk the shadow HEAD back one snapshot and restore the work tree to it: * tracked content is checked out; files created after the target snapshot * are deleted. Returns the restored sha. Throws when there is nothing to * undo. Redo is out of scope: a new snapshot after an undo starts a new line. */ undo(): Promise; /** Snapshot history, newest first. */ history(limit?: number): Promise; /** * Read-only diff of the work tree against a snapshot (default: the latest * shadow HEAD) — the `/diff` viewer's seam (E017 S1, ren's TUI research: * the missing diff viewer). Returns undefined when no snapshot exists yet. * * Two read-only git calls, no index mutation: `diff ` covers files * the snapshots track (including force-added gitignored mutations — .env, * dist/), and `ls-files --others` LISTS files no snapshot has ever * captured (names only, standard ignore rules — a brand-new gitignored * file is invisible here until the next snapshot; recorded limitation). */ diff(base?: string): Promise; } //# sourceMappingURL=shadow.d.ts.map