@oscharko-dev/keiko-tools 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/git-commit-intent-node.d.ts +7 -0
  3. package/dist/git-commit-intent-node.d.ts.map +1 -0
  4. package/dist/git-commit-intent-node.js +42 -0
  5. package/dist/git-merge-gateway.d.ts +95 -0
  6. package/dist/git-merge-gateway.d.ts.map +1 -0
  7. package/dist/git-merge-gateway.js +536 -0
  8. package/dist/git-merge-node.d.ts +17 -0
  9. package/dist/git-merge-node.d.ts.map +1 -0
  10. package/dist/git-merge-node.js +243 -0
  11. package/dist/git-mutation-adapter.d.ts +51 -0
  12. package/dist/git-mutation-adapter.d.ts.map +1 -0
  13. package/dist/git-mutation-adapter.js +207 -0
  14. package/dist/git-mutation-evidence.d.ts +23 -0
  15. package/dist/git-mutation-evidence.d.ts.map +1 -0
  16. package/dist/git-mutation-evidence.js +283 -0
  17. package/dist/git-mutation-node.d.ts +22 -0
  18. package/dist/git-mutation-node.d.ts.map +1 -0
  19. package/dist/git-mutation-node.js +145 -0
  20. package/dist/git-mutation-orchestrator.d.ts +92 -0
  21. package/dist/git-mutation-orchestrator.d.ts.map +1 -0
  22. package/dist/git-mutation-orchestrator.js +321 -0
  23. package/dist/git-mutation-preflight.d.ts +35 -0
  24. package/dist/git-mutation-preflight.d.ts.map +1 -0
  25. package/dist/git-mutation-preflight.js +226 -0
  26. package/dist/git-mutation-taxonomy.d.ts +15 -0
  27. package/dist/git-mutation-taxonomy.d.ts.map +1 -0
  28. package/dist/git-mutation-taxonomy.js +102 -0
  29. package/dist/git-pr-gateway.d.ts +101 -0
  30. package/dist/git-pr-gateway.d.ts.map +1 -0
  31. package/dist/git-pr-gateway.js +487 -0
  32. package/dist/git-pr-node.d.ts +17 -0
  33. package/dist/git-pr-node.d.ts.map +1 -0
  34. package/dist/git-pr-node.js +173 -0
  35. package/dist/git-publish-gateway.d.ts +72 -0
  36. package/dist/git-publish-gateway.d.ts.map +1 -0
  37. package/dist/git-publish-gateway.js +423 -0
  38. package/dist/git-publish-node.d.ts +17 -0
  39. package/dist/git-publish-node.d.ts.map +1 -0
  40. package/dist/git-publish-node.js +107 -0
  41. package/dist/git-worktree-adapter.d.ts +78 -0
  42. package/dist/git-worktree-adapter.d.ts.map +1 -0
  43. package/dist/git-worktree-adapter.js +300 -0
  44. package/dist/git-worktree-snapshot-node.d.ts +31 -0
  45. package/dist/git-worktree-snapshot-node.d.ts.map +1 -0
  46. package/dist/git-worktree-snapshot-node.js +189 -0
  47. package/dist/index.d.ts +9 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +37 -0
  50. package/package.json +9 -5
@@ -0,0 +1,78 @@
1
+ import type { CommandRule, SandboxPolicy } from "./types.js";
2
+ import { type ExecutableResolver, type HomeProvider, type SpawnFn } from "./exec.js";
3
+ import type { WorkspaceInfo } from "@oscharko-dev/keiko-workspace";
4
+ export declare const GIT_WORKTREE_COMMAND_RULES: readonly CommandRule[];
5
+ export declare class GitWorktreeOperandError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ export declare class GitWorktreeSpawnError extends Error {
9
+ constructor(message: string);
10
+ }
11
+ export declare function isSafeGitRefName(value: string): boolean;
12
+ export declare function isSafeWorktreePathOperand(value: string): boolean;
13
+ export interface AddWorktreeOperands {
14
+ readonly worktreePath: string;
15
+ readonly taskBranch: string;
16
+ readonly baseRef: string;
17
+ }
18
+ export declare function buildAddWorktreeArgv(operands: AddWorktreeOperands): readonly string[];
19
+ export interface AddExistingBranchOperands {
20
+ readonly worktreePath: string;
21
+ readonly branch: string;
22
+ }
23
+ export declare function buildAddExistingBranchArgv(operands: AddExistingBranchOperands): readonly string[];
24
+ export declare function buildListWorktreesArgv(): readonly string[];
25
+ export interface RemoveWorktreeOperands {
26
+ readonly worktreePath: string;
27
+ readonly force: boolean;
28
+ }
29
+ export declare function buildRemoveWorktreeArgv(operands: RemoveWorktreeOperands): readonly string[];
30
+ export declare function buildPruneWorktreesArgv(): readonly string[];
31
+ export declare function buildWorktreeStatusArgv(): readonly string[];
32
+ export declare function buildShowToplevelArgv(): readonly string[];
33
+ export declare function buildRefResolvesArgv(ref: string): readonly string[];
34
+ export declare function buildLocalBranchExistsArgv(branch: string): readonly string[];
35
+ export interface WorktreeListEntry {
36
+ readonly path: string;
37
+ readonly head?: string;
38
+ readonly branch?: string;
39
+ readonly bare: boolean;
40
+ readonly detached: boolean;
41
+ readonly locked: boolean;
42
+ }
43
+ export declare function parseWorktreeListPorcelain(stdout: string): readonly WorktreeListEntry[];
44
+ export interface WorktreeOperationResult {
45
+ readonly ok: boolean;
46
+ readonly exitCode: number | null;
47
+ readonly durationMs: number;
48
+ readonly timedOut: boolean;
49
+ readonly truncated: boolean;
50
+ }
51
+ export interface WorktreeStatusResult {
52
+ readonly ok: boolean;
53
+ readonly dirty: boolean;
54
+ }
55
+ export interface GitWorktreeAdapter {
56
+ readonly resolveRepositoryRoot: () => Promise<string | undefined>;
57
+ readonly refResolves: (ref: string) => Promise<boolean>;
58
+ readonly localBranchExists: (branch: string) => Promise<boolean>;
59
+ readonly listWorktrees: () => Promise<readonly WorktreeListEntry[]>;
60
+ readonly worktreeStatus: () => Promise<WorktreeStatusResult>;
61
+ readonly addWorktree: (operands: AddWorktreeOperands) => Promise<WorktreeOperationResult>;
62
+ readonly addWorktreeForExistingBranch: (operands: AddExistingBranchOperands) => Promise<WorktreeOperationResult>;
63
+ readonly removeWorktree: (operands: RemoveWorktreeOperands) => Promise<WorktreeOperationResult>;
64
+ readonly pruneWorktrees: () => Promise<WorktreeOperationResult>;
65
+ }
66
+ export interface NodeGitWorktreeAdapterDeps {
67
+ readonly workspace: WorkspaceInfo;
68
+ readonly processEnv?: NodeJS.ProcessEnv | undefined;
69
+ readonly now?: (() => number) | undefined;
70
+ readonly spawn?: SpawnFn | undefined;
71
+ readonly policy?: SandboxPolicy | undefined;
72
+ readonly resolveExecutable?: ExecutableResolver | undefined;
73
+ readonly home?: HomeProvider | undefined;
74
+ readonly signal?: AbortSignal | undefined;
75
+ readonly timeoutMs?: number | undefined;
76
+ }
77
+ export declare function createNodeGitWorktreeAdapter(deps: NodeGitWorktreeAdapterDeps): GitWorktreeAdapter;
78
+ //# sourceMappingURL=git-worktree-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-worktree-adapter.d.ts","sourceRoot":"","sources":["../src/git-worktree-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,300 @@
1
+ // Narrow managed-worktree adapter for governed task workspaces (Issue #445, Epic #443).
2
+ //
3
+ // This is the ONLY authority for the `git worktree` lifecycle. It runs strictly through the SAME
4
+ // no-shell, allowlist-only spawn boundary as the read snapshot reader and the #470 mutation kernel
5
+ // (keiko-tools `runCommand`), but with its OWN dedicated command allowlist that is STRUCTURALLY
6
+ // SEPARATE from `GIT_MUTATION_COMMAND_RULES`. Its allowlist permits only the git `worktree` verb plus
7
+ // the read-only `rev-parse` / `show-ref` inspection verbs — it can NEVER reach `branch`, `switch`,
8
+ // `commit`, `add`, `restore`, `push`, `merge`, `pull`, `fetch`, or any other write subcommand. This
9
+ // is the AC5 property: the adapter does not widen terminal Git mutation authority and cannot
10
+ // duplicate the #470 branch/commit/publish/PR/merge execution surface.
11
+ //
12
+ // Every operand (branch name, base ref, worktree path) is validated BEFORE argv construction, so a
13
+ // value can never masquerade as a flag or smuggle a shell metacharacter. The worktree path supplied
14
+ // by the caller is an ABSOLUTE path the server has already proven realpath-contained inside the
15
+ // Keiko-owned managed root; the adapter additionally rejects any operand that begins with `-`.
16
+ //
17
+ // Output is content-free to the caller: operation results carry exit code / duration / flags only.
18
+ // `listWorktrees` parses `--porcelain` output into structured entries whose paths stay in-process for
19
+ // idempotency and drift inference and are never persisted into evidence (mirrors `readStagedPaths`).
20
+ import { isAbsolute } from "node:path";
21
+ import { DEFAULT_SANDBOX_POLICY } from "./types.js";
22
+ import { nodeSpawnFn, runCommand, } from "./exec.js";
23
+ // The dedicated worktree-lifecycle allowlist. `worktree` covers add/list/remove/prune (the second
24
+ // token is fixed by the builder, never caller-supplied); `rev-parse` and `show-ref` are read-only
25
+ // inspection used for repository-root resolution, base-ref resolvability, and branch-conflict
26
+ // detection. No write subcommand is reachable. Defense-in-depth `denyFlags` block the global flags
27
+ // that would shift git's cwd, git-dir, or config (`-C`, `-c`, `--git-dir`, …) before subcommand
28
+ // resolution, and `valueFlags` ensure such a flag's value can never be reinterpreted as the verb.
29
+ export const GIT_WORKTREE_COMMAND_RULES = Object.freeze([
30
+ {
31
+ executable: "git",
32
+ // `status` (#448) is the read-only working-tree probe for live dirty detection. Like `rev-parse`
33
+ // and `show-ref` it cannot mutate, so adding it keeps the structural separation from
34
+ // GIT_MUTATION_COMMAND_RULES (no write subcommand is reachable) while letting the cleanup gate see
35
+ // uncommitted/untracked work before removing a worktree.
36
+ allowedSubcommands: Object.freeze(["worktree", "rev-parse", "show-ref", "status"]),
37
+ valueFlags: Object.freeze([
38
+ "-C",
39
+ "-c",
40
+ "--git-dir",
41
+ "--work-tree",
42
+ "--namespace",
43
+ "--exec-path",
44
+ ]),
45
+ denyFlags: Object.freeze([
46
+ "-C",
47
+ "-c",
48
+ "--config-env",
49
+ "--git-dir",
50
+ "--work-tree",
51
+ "--namespace",
52
+ "--exec-path",
53
+ ]),
54
+ },
55
+ ]);
56
+ // Thrown by the pure argv builders when an operand fails validation BEFORE any spawn. The server
57
+ // maps this to a content-free `unsafe-path` / `invalid-request` failure rather than leaking the
58
+ // offending value.
59
+ export class GitWorktreeOperandError extends Error {
60
+ constructor(message) {
61
+ super(message);
62
+ this.name = "GitWorktreeOperandError";
63
+ }
64
+ }
65
+ // Thrown when a worktree command fails to spawn. A non-zero EXIT is NOT an exception — it is returned
66
+ // as `{ ok: false, exitCode }` so the caller can classify it (e.g. branch conflict vs. dirty target).
67
+ export class GitWorktreeSpawnError extends Error {
68
+ constructor(message) {
69
+ super(message);
70
+ this.name = "GitWorktreeSpawnError";
71
+ }
72
+ }
73
+ // ─── Operand validation (pure) ───────────────────────────────────────────────────────────────────
74
+ function hasControlOrNul(value) {
75
+ // Reject NUL and any C0 control character (incl. newline/tab) — none are legal in a git ref or in
76
+ // a path operand we are willing to pass to git. Iterating code points avoids a control-character
77
+ // regex literal.
78
+ for (let index = 0; index < value.length; index += 1) {
79
+ if (value.charCodeAt(index) <= 0x1f)
80
+ return true;
81
+ }
82
+ return false;
83
+ }
84
+ const UNSAFE_REF_PREFIXES = ["-", "/", "."];
85
+ const UNSAFE_REF_SUFFIXES = ["/", ".", ".lock"];
86
+ const UNSAFE_REF_SUBSTRINGS = ["..", "//", "@{"];
87
+ // Conservative git ref-name allowlist. Stricter than `git check-ref-format` on purpose: refs Keiko
88
+ // creates are server-derived, so we only need to accept the deterministic shape we emit and reject
89
+ // anything that could be an option, a path traversal, or a refspec/glob metacharacter.
90
+ export function isSafeGitRefName(value) {
91
+ if (value.length === 0 || value.length > 255 || hasControlOrNul(value))
92
+ return false;
93
+ if (UNSAFE_REF_PREFIXES.some((prefix) => value.startsWith(prefix)))
94
+ return false;
95
+ if (UNSAFE_REF_SUFFIXES.some((suffix) => value.endsWith(suffix)))
96
+ return false;
97
+ if (UNSAFE_REF_SUBSTRINGS.some((part) => value.includes(part)))
98
+ return false;
99
+ // Allowed: letters, digits, and a bounded punctuation set used by our `keiko/task/<id>` scheme.
100
+ if (!/^[A-Za-z0-9._\-/]+$/u.test(value))
101
+ return false;
102
+ // No git ref metacharacters: space ~ ^ : ? * [ \ are excluded by the allowlist above; this also
103
+ // rejects them defensively for readers of this predicate.
104
+ return !/[~^:?*[\\ ]/u.test(value);
105
+ }
106
+ // A worktree path operand must be an absolute path with no control bytes and must not begin with a
107
+ // dash (so it cannot be parsed as an option). Containment inside the managed root is enforced by the
108
+ // server BEFORE this adapter is called; this is the last-line argv guard, and it self-documents the
109
+ // absolute-path invariant rather than relying on every caller to supply one.
110
+ export function isSafeWorktreePathOperand(value) {
111
+ if (value.length === 0 || value.length > 4096)
112
+ return false;
113
+ if (hasControlOrNul(value))
114
+ return false;
115
+ if (value.startsWith("-"))
116
+ return false;
117
+ return isAbsolute(value);
118
+ }
119
+ function requireSafeRef(value, label) {
120
+ if (!isSafeGitRefName(value)) {
121
+ throw new GitWorktreeOperandError(`unsafe ${label}`);
122
+ }
123
+ return value;
124
+ }
125
+ function requireSafePath(value, label) {
126
+ if (!isSafeWorktreePathOperand(value)) {
127
+ throw new GitWorktreeOperandError(`unsafe ${label}`);
128
+ }
129
+ return value;
130
+ }
131
+ // `git worktree add -b <taskBranch> <path> <baseRef>` — atomically creates the dedicated task branch
132
+ // from the approved base ref AND the managed worktree in one governed call. `--no-track` keeps the
133
+ // new branch local-only (no implicit upstream); publish/track stays owned by #470.
134
+ export function buildAddWorktreeArgv(operands) {
135
+ const branch = requireSafeRef(operands.taskBranch, "task branch name");
136
+ const base = requireSafeRef(operands.baseRef, "base ref");
137
+ const path = requireSafePath(operands.worktreePath, "worktree path");
138
+ return ["worktree", "add", "--no-track", "-b", branch, path, base];
139
+ }
140
+ // `git worktree add <path> <branch>` — reattaches an EXISTING managed branch to a fresh worktree
141
+ // directory. Used only for retry-safe completion of a partially provisioned workspace whose branch
142
+ // already exists but whose worktree directory is missing.
143
+ export function buildAddExistingBranchArgv(operands) {
144
+ const branch = requireSafeRef(operands.branch, "branch name");
145
+ const path = requireSafePath(operands.worktreePath, "worktree path");
146
+ return ["worktree", "add", path, branch];
147
+ }
148
+ export function buildListWorktreesArgv() {
149
+ return ["worktree", "list", "--porcelain"];
150
+ }
151
+ // `git worktree remove [--force] <path>` — removes a managed worktree directory. Used for retry-safe
152
+ // rollback of partial provisioning; `--force` is required to remove a worktree that git considers
153
+ // dirty (a half-created checkout), and is server-decided, never caller-supplied.
154
+ export function buildRemoveWorktreeArgv(operands) {
155
+ const path = requireSafePath(operands.worktreePath, "worktree path");
156
+ return operands.force ? ["worktree", "remove", "--force", path] : ["worktree", "remove", path];
157
+ }
158
+ export function buildPruneWorktreesArgv() {
159
+ return ["worktree", "prune"];
160
+ }
161
+ // `git status --porcelain` — the read-only working-tree probe (#448). Exit 0 with any output means the
162
+ // worktree has uncommitted OR untracked changes (the conservative signal for a deletion gate). The
163
+ // porcelain lines themselves never leave the adapter: the caller receives only a `dirty` boolean.
164
+ export function buildWorktreeStatusArgv() {
165
+ return ["status", "--porcelain"];
166
+ }
167
+ export function buildShowToplevelArgv() {
168
+ return ["rev-parse", "--show-toplevel"];
169
+ }
170
+ // `git rev-parse --verify --quiet <ref>^{commit}` — exit 0 iff the ref resolves to a commit. Used to
171
+ // confirm the approved base branch exists/resolves before provisioning.
172
+ export function buildRefResolvesArgv(ref) {
173
+ const safe = requireSafeRef(ref, "base ref");
174
+ return ["rev-parse", "--verify", "--quiet", `${safe}^{commit}`];
175
+ }
176
+ // `git show-ref --verify --quiet refs/heads/<branch>` — exit 0 iff a LOCAL branch of that exact name
177
+ // exists. Used to detect a branch-name conflict before creating the task branch.
178
+ export function buildLocalBranchExistsArgv(branch) {
179
+ const safe = requireSafeRef(branch, "branch name");
180
+ return ["show-ref", "--verify", "--quiet", `refs/heads/${safe}`];
181
+ }
182
+ function blockToEntry(block) {
183
+ if (block === null)
184
+ return undefined;
185
+ return {
186
+ path: block.path,
187
+ ...(block.head !== undefined ? { head: block.head } : {}),
188
+ ...(block.branch !== undefined ? { branch: block.branch } : {}),
189
+ bare: block.bare,
190
+ detached: block.detached,
191
+ locked: block.locked,
192
+ };
193
+ }
194
+ // Applies one non-`worktree` attribute line to the current block. Unknown lines are ignored.
195
+ function applyAttributeLine(block, line) {
196
+ if (line.startsWith("HEAD "))
197
+ block.head = line.slice("HEAD ".length);
198
+ else if (line.startsWith("branch "))
199
+ block.branch = line.slice("branch ".length);
200
+ else if (line === "bare")
201
+ block.bare = true;
202
+ else if (line === "detached")
203
+ block.detached = true;
204
+ else if (line.startsWith("locked"))
205
+ block.locked = true;
206
+ }
207
+ // Parses `git worktree list --porcelain`. Blocks are separated by a blank line; each block starts
208
+ // with `worktree <path>` followed by optional `HEAD <sha>`, `branch <ref>`, and the bare/detached/
209
+ // locked markers.
210
+ export function parseWorktreeListPorcelain(stdout) {
211
+ const entries = [];
212
+ let block = null;
213
+ for (const raw of stdout.split("\n")) {
214
+ const line = raw.replace(/\r$/u, "");
215
+ if (line.startsWith("worktree ")) {
216
+ const previous = blockToEntry(block);
217
+ if (previous !== undefined)
218
+ entries.push(previous);
219
+ block = { path: line.slice("worktree ".length), bare: false, detached: false, locked: false };
220
+ }
221
+ else if (line.length === 0) {
222
+ const previous = blockToEntry(block);
223
+ if (previous !== undefined)
224
+ entries.push(previous);
225
+ block = null;
226
+ }
227
+ else if (block !== null) {
228
+ applyAttributeLine(block, line);
229
+ }
230
+ }
231
+ const last = blockToEntry(block);
232
+ if (last !== undefined)
233
+ entries.push(last);
234
+ return entries;
235
+ }
236
+ function buildAdapterContext(deps) {
237
+ return {
238
+ runDeps: {
239
+ workspace: deps.workspace,
240
+ policy: deps.policy ?? DEFAULT_SANDBOX_POLICY,
241
+ commandRules: GIT_WORKTREE_COMMAND_RULES,
242
+ spawn: deps.spawn ?? nodeSpawnFn,
243
+ processEnv: deps.processEnv ?? process.env,
244
+ now: deps.now ?? Date.now,
245
+ ...(deps.resolveExecutable !== undefined
246
+ ? { resolveExecutable: deps.resolveExecutable }
247
+ : {}),
248
+ ...(deps.home !== undefined ? { home: deps.home } : {}),
249
+ },
250
+ signal: deps.signal ?? new AbortController().signal,
251
+ timeoutMs: deps.timeoutMs,
252
+ };
253
+ }
254
+ async function runGit(ctx, argv) {
255
+ try {
256
+ return await runCommand({ command: "git", args: argv, cwd: undefined, timeoutMs: ctx.timeoutMs, signal: ctx.signal }, ctx.runDeps);
257
+ }
258
+ catch (error) {
259
+ throw new GitWorktreeSpawnError(`git ${argv[0] ?? "?"} failed to run: ${error instanceof Error ? error.name : "unknown"}`);
260
+ }
261
+ }
262
+ function toOperationResult(result) {
263
+ return {
264
+ ok: result.exitCode === 0,
265
+ exitCode: result.exitCode,
266
+ durationMs: result.durationMs,
267
+ timedOut: result.timedOut,
268
+ truncated: result.truncated,
269
+ };
270
+ }
271
+ export function createNodeGitWorktreeAdapter(deps) {
272
+ const ctx = buildAdapterContext(deps);
273
+ return {
274
+ resolveRepositoryRoot: async () => {
275
+ const result = await runGit(ctx, buildShowToplevelArgv());
276
+ if (result.exitCode !== 0)
277
+ return undefined;
278
+ const top = result.stdout.split(/\r?\n/u)[0]?.trim();
279
+ return top !== undefined && top.length > 0 ? top : undefined;
280
+ },
281
+ refResolves: async (ref) => (await runGit(ctx, buildRefResolvesArgv(ref))).exitCode === 0,
282
+ localBranchExists: async (branch) => (await runGit(ctx, buildLocalBranchExistsArgv(branch))).exitCode === 0,
283
+ listWorktrees: async () => {
284
+ const result = await runGit(ctx, buildListWorktreesArgv());
285
+ if (result.exitCode !== 0)
286
+ return [];
287
+ return parseWorktreeListPorcelain(result.stdout);
288
+ },
289
+ worktreeStatus: async () => {
290
+ const result = await runGit(ctx, buildWorktreeStatusArgv());
291
+ if (result.exitCode !== 0)
292
+ return { ok: false, dirty: false };
293
+ return { ok: true, dirty: result.stdout.trim().length > 0 };
294
+ },
295
+ addWorktree: async (operands) => toOperationResult(await runGit(ctx, buildAddWorktreeArgv(operands))),
296
+ addWorktreeForExistingBranch: async (operands) => toOperationResult(await runGit(ctx, buildAddExistingBranchArgv(operands))),
297
+ removeWorktree: async (operands) => toOperationResult(await runGit(ctx, buildRemoveWorktreeArgv(operands))),
298
+ pruneWorktrees: async () => toOperationResult(await runGit(ctx, buildPruneWorktreesArgv())),
299
+ };
300
+ }
@@ -0,0 +1,31 @@
1
+ import type { WorkspaceInfo } from "@oscharko-dev/keiko-workspace";
2
+ import type { CommandRule, SandboxPolicy } from "./types.js";
3
+ import { type ExecutableResolver, type HomeProvider, type SpawnFn } from "./exec.js";
4
+ import type { GitWorktreeSnapshot } from "./git-mutation-preflight.js";
5
+ export declare const GIT_WORKTREE_READ_COMMAND_RULES: readonly CommandRule[];
6
+ export interface NodeGitWorktreeReaderDeps {
7
+ readonly workspace: WorkspaceInfo;
8
+ readonly processEnv?: NodeJS.ProcessEnv | undefined;
9
+ readonly now?: (() => number) | undefined;
10
+ readonly spawn?: SpawnFn | undefined;
11
+ readonly policy?: SandboxPolicy | undefined;
12
+ readonly resolveExecutable?: ExecutableResolver | undefined;
13
+ readonly home?: HomeProvider | undefined;
14
+ readonly signal?: AbortSignal | undefined;
15
+ readonly timeoutMs?: number | undefined;
16
+ }
17
+ export declare class GitWorktreeReadError extends Error {
18
+ constructor(message: string);
19
+ }
20
+ /**
21
+ * Reads the live worktree into a content-free `GitWorktreeSnapshot` via read-only git inspection.
22
+ * `operationInProgress` is not probed by this reader (it affects only advisory preflight findings for
23
+ * the local branch/stage/commit flow); abort/recovery flows that require it are out of #475 scope.
24
+ */
25
+ export declare function readGitWorktreeSnapshot(deps: NodeGitWorktreeReaderDeps): Promise<GitWorktreeSnapshot>;
26
+ /**
27
+ * Reads the relative paths currently staged for commit (`git diff --cached --name-only`). Used by the
28
+ * server for commit-intent scope inference; the paths stay in-process and are never persisted.
29
+ */
30
+ export declare function readStagedPaths(deps: NodeGitWorktreeReaderDeps): Promise<readonly string[]>;
31
+ //# sourceMappingURL=git-worktree-snapshot-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-worktree-snapshot-node.d.ts","sourceRoot":"","sources":["../src/git-worktree-snapshot-node.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAiB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE5E,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,YAAY,EAEjB,KAAK,OAAO,EACb,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAIvE,eAAO,MAAM,+BAA+B,EAAE,SAAS,WAAW,EA2BhE,CAAC;AAEH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AA6BD,qBAAa,oBAAqB,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAInC;AA6FD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAoB9B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,yBAAyB,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAIjG"}
@@ -0,0 +1,189 @@
1
+ // Read-only worktree snapshot reader for governed local Git flows (Issue #475, Epic #470).
2
+ //
3
+ // The #472 mutation kernel is PURE over an injected `GitWorktreeSnapshot`: it never reads the live
4
+ // repository itself. For the end-user-visible local flows (#475) the SERVER must build a TRUSTWORTHY
5
+ // snapshot from the real worktree before driving the kernel — a client must not be able to assert,
6
+ // e.g., a staged-file count that would slip a commit past preflight. This module is that reader.
7
+ //
8
+ // It runs ONLY read-only `git` inspection (status / rev-parse / branch / remote / diff) through the
9
+ // SAME no-shell spawn boundary as the mutation adapter, but with its OWN dedicated allowlist that is
10
+ // STRUCTURALLY SEPARATE from `GIT_MUTATION_COMMAND_RULES` — it can never reach a write subcommand, and
11
+ // the mutation rules can never reach a read subcommand. No generic exec, no shell, no direct FS.
12
+ //
13
+ // Output is content-free by construction (counts, flags, branch/remote NAMES only) for the snapshot;
14
+ // `readStagedPaths` additionally returns the staged relative paths, which stay inside the server for
15
+ // scope inference and are never persisted into evidence.
16
+ import { DEFAULT_SANDBOX_POLICY } from "./types.js";
17
+ import { nodeSpawnFn, runCommand, } from "./exec.js";
18
+ // The dedicated READ-ONLY allowlist. Mirrors the mutation rules' defence-in-depth flag denials but
19
+ // permits only inspection subcommands — no `branch <name>`, no `add`, no `commit`, no network verb.
20
+ export const GIT_WORKTREE_READ_COMMAND_RULES = Object.freeze([
21
+ {
22
+ executable: "git",
23
+ allowedSubcommands: Object.freeze(["status", "rev-parse", "branch", "remote", "diff"]),
24
+ valueFlags: Object.freeze([
25
+ "-C",
26
+ "-c",
27
+ "--git-dir",
28
+ "--work-tree",
29
+ "--namespace",
30
+ "--exec-path",
31
+ ]),
32
+ denyFlags: Object.freeze([
33
+ "-C",
34
+ "-c",
35
+ "--config-env",
36
+ "--git-dir",
37
+ "--work-tree",
38
+ "--namespace",
39
+ "--exec-path",
40
+ "--ext-diff",
41
+ "--textconv",
42
+ "--no-index",
43
+ "--contents",
44
+ "--output",
45
+ ]),
46
+ },
47
+ ]);
48
+ function buildReadContext(deps) {
49
+ return {
50
+ runDeps: {
51
+ workspace: deps.workspace,
52
+ policy: deps.policy ?? DEFAULT_SANDBOX_POLICY,
53
+ commandRules: GIT_WORKTREE_READ_COMMAND_RULES,
54
+ spawn: deps.spawn ?? nodeSpawnFn,
55
+ processEnv: deps.processEnv ?? process.env,
56
+ now: deps.now ?? Date.now,
57
+ ...(deps.resolveExecutable !== undefined
58
+ ? { resolveExecutable: deps.resolveExecutable }
59
+ : {}),
60
+ ...(deps.home !== undefined ? { home: deps.home } : {}),
61
+ },
62
+ signal: deps.signal ?? new AbortController().signal,
63
+ timeoutMs: deps.timeoutMs,
64
+ };
65
+ }
66
+ // Thrown when a read-only inspection command exits non-zero (e.g. not a git repository). The caller
67
+ // translates this into a content-free server error rather than leaking git's stderr.
68
+ export class GitWorktreeReadError extends Error {
69
+ constructor(message) {
70
+ super(message);
71
+ this.name = "GitWorktreeReadError";
72
+ }
73
+ }
74
+ async function runRead(ctx, argv) {
75
+ let result;
76
+ try {
77
+ result = await runCommand({ command: "git", args: argv, cwd: undefined, timeoutMs: ctx.timeoutMs, signal: ctx.signal }, ctx.runDeps);
78
+ }
79
+ catch {
80
+ throw new GitWorktreeReadError(`git ${argv[0] ?? "?"} failed to run`);
81
+ }
82
+ if (result.exitCode !== 0) {
83
+ throw new GitWorktreeReadError(`git ${argv[0] ?? "?"} exited ${String(result.exitCode)}`);
84
+ }
85
+ return result.stdout;
86
+ }
87
+ function parseAheadBehind(value, counts) {
88
+ // Format: "+<ahead> -<behind>"
89
+ for (const token of value.trim().split(/\s+/)) {
90
+ const n = Number.parseInt(token.slice(1), 10);
91
+ if (token.startsWith("+") && Number.isFinite(n))
92
+ counts.ahead = Math.max(0, n);
93
+ if (token.startsWith("-") && Number.isFinite(n))
94
+ counts.behind = Math.max(0, n);
95
+ }
96
+ }
97
+ function applyHeaderLine(line, counts) {
98
+ if (line.startsWith("# branch.head ")) {
99
+ const head = line.slice("# branch.head ".length).trim();
100
+ if (head === "(detached)")
101
+ counts.headDetached = true;
102
+ else
103
+ counts.currentBranchName = head;
104
+ }
105
+ else if (line.startsWith("# branch.upstream ")) {
106
+ counts.hasUpstream = true;
107
+ }
108
+ else if (line.startsWith("# branch.ab ")) {
109
+ parseAheadBehind(line.slice("# branch.ab ".length), counts);
110
+ }
111
+ }
112
+ // A "1"/"2" entry carries a two-char XY status field after the type token: X = index (staged), Y =
113
+ // worktree (unstaged). A "." in a slot means "unmodified there".
114
+ function applyChangedEntry(line, counts) {
115
+ const xy = line.slice(2, 4);
116
+ const staged = xy[0] ?? ".";
117
+ const worktree = xy[1] ?? ".";
118
+ if (staged !== ".")
119
+ counts.staged += 1;
120
+ if (worktree !== ".")
121
+ counts.unstaged += 1;
122
+ }
123
+ function parsePorcelain(stdout) {
124
+ const counts = {
125
+ headDetached: false,
126
+ currentBranchName: undefined,
127
+ staged: 0,
128
+ unstaged: 0,
129
+ untracked: 0,
130
+ hasUpstream: false,
131
+ ahead: 0,
132
+ behind: 0,
133
+ };
134
+ for (const line of stdout.split("\n")) {
135
+ if (line.length === 0)
136
+ continue;
137
+ if (line.startsWith("# "))
138
+ applyHeaderLine(line, counts);
139
+ else if (line.startsWith("1 ") || line.startsWith("2 "))
140
+ applyChangedEntry(line, counts);
141
+ else if (line.startsWith("u "))
142
+ counts.unstaged += 1; // unmerged path: needs resolution
143
+ else if (line.startsWith("? "))
144
+ counts.untracked += 1;
145
+ }
146
+ return counts;
147
+ }
148
+ function parseLines(stdout) {
149
+ return stdout
150
+ .split("\n")
151
+ .map((l) => l.trim())
152
+ .filter((l) => l.length > 0);
153
+ }
154
+ // ─── Public reader ───────────────────────────────────────────────────────────────────────────
155
+ /**
156
+ * Reads the live worktree into a content-free `GitWorktreeSnapshot` via read-only git inspection.
157
+ * `operationInProgress` is not probed by this reader (it affects only advisory preflight findings for
158
+ * the local branch/stage/commit flow); abort/recovery flows that require it are out of #475 scope.
159
+ */
160
+ export async function readGitWorktreeSnapshot(deps) {
161
+ const ctx = buildReadContext(deps);
162
+ const [statusOut, branchOut, remoteOut] = await Promise.all([
163
+ runRead(ctx, ["status", "--porcelain=v2", "--branch"]),
164
+ runRead(ctx, ["branch", "--list", "--format=%(refname:short)"]),
165
+ runRead(ctx, ["remote"]),
166
+ ]);
167
+ const c = parsePorcelain(statusOut);
168
+ return {
169
+ headDetached: c.headDetached,
170
+ ...(c.currentBranchName !== undefined ? { currentBranchName: c.currentBranchName } : {}),
171
+ stagedFileCount: c.staged,
172
+ unstagedFileCount: c.unstaged,
173
+ untrackedFileCount: c.untracked,
174
+ hasUpstream: c.hasUpstream,
175
+ aheadCount: c.ahead,
176
+ behindCount: c.behind,
177
+ existingLocalBranchNames: parseLines(branchOut),
178
+ remoteAliases: parseLines(remoteOut),
179
+ };
180
+ }
181
+ /**
182
+ * Reads the relative paths currently staged for commit (`git diff --cached --name-only`). Used by the
183
+ * server for commit-intent scope inference; the paths stay in-process and are never persisted.
184
+ */
185
+ export async function readStagedPaths(deps) {
186
+ const ctx = buildReadContext(deps);
187
+ const out = await runRead(ctx, ["diff", "--cached", "--name-only"]);
188
+ return parseLines(out);
189
+ }
package/dist/index.d.ts CHANGED
@@ -11,6 +11,15 @@ export { computeFileContent, type ApplyOutcome, type HunkConflict } from "./patc
11
11
  export { TOOL_DEFINITIONS } from "./schemas.js";
12
12
  export { WorkspaceToolHost } from "./registry.js";
13
13
  export * from "./terminal-policy.js";
14
+ export { GIT_MUTATION_FAILURE_CATEGORIES, GIT_MUTATION_LIFECYCLE_PHASES, GIT_MUTATION_PHASE_ORDER, GIT_MUTATION_STATUSES, gitMutationCategoryForExecutionError, gitMutationCategoryForExecutionResult, gitMutationFailureIsRecoverable, isGitMutationFailureCategory, isGitMutationLifecyclePhase, isGitMutationStatus, type GitMutationFailureCategory, type GitMutationLifecyclePhase, type GitMutationStatus, } from "./git-mutation-taxonomy.js";
15
+ export { evaluateGitPreflight, GIT_PREFLIGHT_FINDING_CODES, gitPreflightRemediationFor, isGitPreflightFindingCode, type GitPreflightFinding, type GitPreflightFindingCode, type GitPreflightRemediation, type GitPreflightReport, type GitPreflightSeverity, type GitWorktreeSnapshot, } from "./git-mutation-preflight.js";
16
+ export { buildAbortArgv, buildBranchCreateArgv, buildBranchSwitchArgv, buildCommitArgv, buildRecoveryArgv, buildStageArgv, buildUnstageArgv, GIT_MUTATION_ALLOWED_SUBCOMMANDS, GIT_MUTATION_COMMAND_RULES, gitMutationPlanIsGoverned, GitMutationArgvError, type GitAbortExecRequest, type GitBranchCreateExecRequest, type GitBranchSwitchExecRequest, type GitCommitExecRequest, type GitLocalMutationAdapter, type GitMutationArgvPlan, type GitRecoveryExecRequest, type GitStageExecRequest, type GitUnstageExecRequest, } from "./git-mutation-adapter.js";
17
+ export { createInMemoryGitMutationJournal, gitMutationOutcomeFailureCategory, runGitMutation, type GitAbortCommand, type GitBranchCreateCommand, type GitBranchSwitchCommand, type GitCommitCommand, type GitMutationCommand, type GitMutationJournal, type GitMutationLifecycleResult, type GitMutationOrchestratorDeps, type GitMutationOutcome, type GitMutationRequest, type GitRecoveryCommand, type GitStageCommand, type GitUnstageCommand, } from "./git-mutation-orchestrator.js";
18
+ export { buildGitDeliveryEvidenceRecord, type GitDeliveryEvidenceBuildDeps, type GitDeliveryEvidenceBuildInput, type GitDeliveryEvidenceSnapshot, } from "./git-mutation-evidence.js";
19
+ export { buildPushArgv, classifyGitPublishRejection, evaluateGitPublishEffectivePolicy, GIT_PUBLISH_ALLOWED_SUBCOMMANDS, GIT_PUBLISH_COMMAND_RULES, GIT_PUBLISH_REJECTION_REASONS, gitPublishArgvIsGoverned, gitPublishRejectionFor, gitPublishRejectionToErrorCode, GitPublishArgvError, isGitPublishRejectionReason, runGitPublish, type GitPublishEffectivePolicy, type GitPublishExecRequest, type GitPublishExecResult, type GitPublishLifecycleResult, type GitPublishOrchestratorDeps, type GitPublishRejection, type GitPublishRejectionReason, type GitPublishRequest, type GitPushCommand, type GitRemotePublishAdapter, } from "./git-publish-gateway.js";
20
+ export { buildPrConvertDraftGraphqlArgv, buildPrCreateArgv, buildPrMarkReadyGraphqlArgv, buildPrUpdateArgv, classifyGitPullRequestRejection, evaluateGitPullRequestEffectivePolicy, GIT_PULL_REQUEST_ALLOWED_SUBCOMMANDS, GIT_PULL_REQUEST_COMMAND_RULES, gitPrArgvIsGoverned, gitPrRejectionToErrorCode, gitPullRequestRejectionFor, GitPrArgvError, runGitPullRequest, type GitPrCreateCommand, type GitPrCreateExecRequest, type GitPrExecResult, type GitPrUpdateCommand, type GitPrUpdateExecRequest, type GitPullRequestAdapter, type GitPullRequestCommand, type GitPullRequestEffectivePolicy, type GitPullRequestLifecycleResult, type GitPullRequestOrchestratorDeps, type GitPullRequestRejection, type GitPullRequestRequest, } from "./git-pr-gateway.js";
21
+ export { buildDeleteMergedBranchArgv, buildHeadStatusArgv, buildMergeArgv, buildMergeReadinessArgv, buildRepoMergeConfigArgv, classifyGitMergeRejection, evaluateGitMergeEffectivePolicy, GIT_MERGE_ALLOWED_SUBCOMMANDS, GIT_MERGE_COMMAND_RULES, gitMergeArgvIsGoverned, gitMergeRejectionToErrorCode, GitMergeArgvError, mapRawMergeReadiness, runGitMerge, type GitMergeAdapter, type GitMergeCommand, type GitMergeEffectivePolicy, type GitMergeExecRequest, type GitMergeExecResult, type GitMergeLifecycleResult, type GitMergeOrchestratorDeps, type GitMergeProviderReadiness, type GitMergeReadinessRequest, type GitMergeRequest, type RawMergeReadiness, } from "./git-merge-gateway.js";
22
+ export { MAX_COMMIT_SUMMARY_AREAS, summarizeStagedChangeset } from "./git-commit-intent-node.js";
14
23
  export { BROWSER_ERROR_CODES, BrowserToolError, type BrowserErrorCode } from "./browser/errors.js";
15
24
  export { isLoopbackHost, isLoopbackUrl, normalizeCdpPort, normalizeNavigateUrl, } from "./browser/validators.js";
16
25
  export type { BrowserContentResult, BrowserNavigateResult, BrowserScreenshotPersisted, BrowserScreenshotPreview, BrowserScreenshotResult, BrowserSessionMeta, BrowserSessionStatus, BrowserViewportPx, CdpReachability, NormalizedNavigateUrl, } from "./browser/types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,YAAY,EACV,aAAa,EACb,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,eAAe,EACf,SAAS,EACT,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACpB,UAAU,EACV,iBAAiB,EACjB,SAAS,EACT,gBAAgB,EAChB,KAAK,QAAQ,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,eAAe,EACf,yBAAyB,EACzB,gBAAgB,EAChB,KAAK,eAAe,GACrB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,OAAO,EACL,UAAU,EACV,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,YAAY,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,KAAK,SAAS,EACd,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAKlD,cAAc,sBAAsB,CAAC;AAGrC,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EACL,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,oBAAoB,EACpB,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,SAAS,EACT,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,2BAA2B,EAC3B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}