@vibe-commit/capture 0.7.0 → 0.9.0

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 (152) hide show
  1. package/README.md +238 -7
  2. package/dist/account_not_here.d.ts +15 -0
  3. package/dist/account_not_here.js +25 -0
  4. package/dist/account_not_here.js.map +1 -0
  5. package/dist/agents/claude_code.js +13 -0
  6. package/dist/agents/claude_code.js.map +1 -1
  7. package/dist/agents/codex_cli.js +11 -0
  8. package/dist/agents/codex_cli.js.map +1 -1
  9. package/dist/agents/cursor.js +7 -1
  10. package/dist/agents/cursor.js.map +1 -1
  11. package/dist/agents/registry.d.ts +7 -0
  12. package/dist/agents/registry.js +9 -0
  13. package/dist/agents/registry.js.map +1 -1
  14. package/dist/agents/types.d.ts +32 -0
  15. package/dist/agents/types.js.map +1 -1
  16. package/dist/bounded_id.d.ts +29 -0
  17. package/dist/bounded_id.js +42 -0
  18. package/dist/bounded_id.js.map +1 -0
  19. package/dist/codex_folders.d.ts +340 -0
  20. package/dist/codex_folders.js +1448 -0
  21. package/dist/codex_folders.js.map +1 -0
  22. package/dist/commands/auth.d.ts +7 -0
  23. package/dist/commands/auth.js +21 -0
  24. package/dist/commands/auth.js.map +1 -1
  25. package/dist/commands/backfill.d.ts +29 -7
  26. package/dist/commands/backfill.js +387 -109
  27. package/dist/commands/backfill.js.map +1 -1
  28. package/dist/commands/browser_credential.d.ts +4 -2
  29. package/dist/commands/browser_credential.js +5 -2
  30. package/dist/commands/browser_credential.js.map +1 -1
  31. package/dist/commands/connect.d.ts +10 -1
  32. package/dist/commands/connect.js +14 -9
  33. package/dist/commands/connect.js.map +1 -1
  34. package/dist/commands/connect_account.d.ts +135 -0
  35. package/dist/commands/connect_account.js +321 -0
  36. package/dist/commands/connect_account.js.map +1 -0
  37. package/dist/commands/connect_picker.js +204 -29
  38. package/dist/commands/connect_picker.js.map +1 -1
  39. package/dist/commands/device_credential.d.ts +3 -1
  40. package/dist/commands/device_credential.js +1 -0
  41. package/dist/commands/device_credential.js.map +1 -1
  42. package/dist/commands/finalize.d.ts +67 -0
  43. package/dist/commands/finalize.js +450 -114
  44. package/dist/commands/finalize.js.map +1 -1
  45. package/dist/commands/finish_mint.d.ts +28 -0
  46. package/dist/commands/finish_mint.js +16 -4
  47. package/dist/commands/finish_mint.js.map +1 -1
  48. package/dist/commands/scan.d.ts +28 -0
  49. package/dist/commands/scan.js +11 -0
  50. package/dist/commands/scan.js.map +1 -1
  51. package/dist/commands/status.d.ts +19 -1
  52. package/dist/commands/status.js +123 -14
  53. package/dist/commands/status.js.map +1 -1
  54. package/dist/commands/status_machine.d.ts +12 -3
  55. package/dist/commands/status_machine.js +111 -13
  56. package/dist/commands/status_machine.js.map +1 -1
  57. package/dist/commands/sync_reason.d.ts +17 -0
  58. package/dist/commands/sync_reason.js +25 -0
  59. package/dist/commands/sync_reason.js.map +1 -0
  60. package/dist/consent.d.ts +131 -3
  61. package/dist/consent.js +248 -14
  62. package/dist/consent.js.map +1 -1
  63. package/dist/copy/strings.d.ts +165 -4
  64. package/dist/copy/strings.js +190 -7
  65. package/dist/copy/strings.js.map +1 -1
  66. package/dist/folder_grants.d.ts +44 -0
  67. package/dist/folder_grants.js +101 -0
  68. package/dist/folder_grants.js.map +1 -0
  69. package/dist/git.d.ts +26 -4
  70. package/dist/git.js +82 -11
  71. package/dist/git.js.map +1 -1
  72. package/dist/grants_sync.d.ts +165 -0
  73. package/dist/grants_sync.js +289 -0
  74. package/dist/grants_sync.js.map +1 -0
  75. package/dist/grants_verb.d.ts +70 -0
  76. package/dist/grants_verb.js +121 -0
  77. package/dist/grants_verb.js.map +1 -0
  78. package/dist/hooks/entry.d.ts +30 -50
  79. package/dist/hooks/entry.js +601 -561
  80. package/dist/hooks/entry.js.map +1 -1
  81. package/dist/hooks/fire_lock.d.ts +31 -0
  82. package/dist/hooks/fire_lock.js +120 -12
  83. package/dist/hooks/fire_lock.js.map +1 -1
  84. package/dist/hooks/session_grants.d.ts +59 -0
  85. package/dist/hooks/session_grants.js +91 -0
  86. package/dist/hooks/session_grants.js.map +1 -0
  87. package/dist/hooks/session_start.d.ts +28 -7
  88. package/dist/hooks/session_start.js +55 -11
  89. package/dist/hooks/session_start.js.map +1 -1
  90. package/dist/index.js +22 -5
  91. package/dist/index.js.map +1 -1
  92. package/dist/machine_state.d.ts +44 -1
  93. package/dist/machine_state.js +75 -12
  94. package/dist/machine_state.js.map +1 -1
  95. package/dist/oauth/discovery.js +2 -1
  96. package/dist/oauth/discovery.js.map +1 -1
  97. package/dist/oauth/pkce.js +2 -1
  98. package/dist/oauth/pkce.js.map +1 -1
  99. package/dist/oauth/retire.d.ts +10 -0
  100. package/dist/oauth/retire.js +13 -0
  101. package/dist/oauth/retire.js.map +1 -1
  102. package/dist/paths.d.ts +54 -1
  103. package/dist/paths.js +88 -12
  104. package/dist/paths.js.map +1 -1
  105. package/dist/pending_revoke.d.ts +117 -0
  106. package/dist/pending_revoke.js +233 -0
  107. package/dist/pending_revoke.js.map +1 -0
  108. package/dist/pending_revoke_file.d.ts +55 -0
  109. package/dist/pending_revoke_file.js +74 -0
  110. package/dist/pending_revoke_file.js.map +1 -0
  111. package/dist/physical_path.d.ts +46 -0
  112. package/dist/physical_path.js +151 -0
  113. package/dist/physical_path.js.map +1 -0
  114. package/dist/picker.d.ts +82 -5
  115. package/dist/picker.js +183 -10
  116. package/dist/picker.js.map +1 -1
  117. package/dist/picker_checklist.d.ts +27 -3
  118. package/dist/picker_checklist.js +81 -6
  119. package/dist/picker_checklist.js.map +1 -1
  120. package/dist/policy.d.ts +24 -1
  121. package/dist/policy.js +30 -2
  122. package/dist/policy.js.map +1 -1
  123. package/dist/post.d.ts +55 -2
  124. package/dist/post.js +72 -22
  125. package/dist/post.js.map +1 -1
  126. package/dist/project.d.ts +89 -0
  127. package/dist/project.js +123 -0
  128. package/dist/project.js.map +1 -1
  129. package/dist/redact.d.ts +77 -2
  130. package/dist/redact.js +713 -47
  131. package/dist/redact.js.map +1 -1
  132. package/dist/session_targets.d.ts +713 -0
  133. package/dist/session_targets.js +2602 -0
  134. package/dist/session_targets.js.map +1 -0
  135. package/dist/spool.d.ts +12 -0
  136. package/dist/spool.js +29 -1
  137. package/dist/spool.js.map +1 -1
  138. package/dist/spool_union.d.ts +51 -0
  139. package/dist/spool_union.js +57 -0
  140. package/dist/spool_union.js.map +1 -0
  141. package/dist/state.d.ts +5 -0
  142. package/dist/state.js +19 -1
  143. package/dist/state.js.map +1 -1
  144. package/dist/system_message.d.ts +25 -2
  145. package/dist/system_message.js +29 -5
  146. package/dist/system_message.js.map +1 -1
  147. package/dist/text_tail.d.ts +8 -0
  148. package/dist/text_tail.js +19 -0
  149. package/dist/text_tail.js.map +1 -0
  150. package/dist/version.d.ts +1 -1
  151. package/dist/version.js +1 -1
  152. package/package.json +3 -3
@@ -0,0 +1,121 @@
1
+ /**
2
+ * What a CLI verb does with the account's grants (slice 2, S4): `status` and `off` sync at the start or the end, and read what
3
+ * the last sync recorded. `connect` (the picker's "on your account" group, the joining-machine prompt, `g`) comes in a later PR.
4
+ *
5
+ * ```
6
+ * syncForVerb(ctx, …) one bounded sync, silent on failure (a verb's, never a hook's)
7
+ * accountView(…) the account rows' data, read from the files (no network)
8
+ * ```
9
+ *
10
+ * ## The first sync says what it saves, or it waits
11
+ *
12
+ * The first sync uploads what this machine already named — its owners and repos, and the slug of every per-clone consent
13
+ * made under 0.6.x/0.7.0 — to the user's account (R3-21). That is a disclosure the user must be able to read, so it runs
14
+ * only on a verb that can print it: a terminal, and not `--json`. Anywhere else it WAITS (nothing is sent, `pending` is
15
+ * untouched), and the next verb that can say so does it. The line names slugs, never paths.
16
+ *
17
+ * ## Nothing here is a hook
18
+ *
19
+ * Hooks never sync (`grants_sync.ts`). A verb reads the response with the 1 MiB cap a verb may use (`GRANTS_VERB_BODY_BYTES`).
20
+ */
21
+ import { accountNotHere, ownerName } from "./account_not_here.js";
22
+ import { normalizeSlug, readAccountState, readGrants, EMPTY_GRANTS } from "./consent.js";
23
+ import { loadCredential } from "./credential.js";
24
+ import { GRANTS_VERB_BODY_BYTES, planSync, syncGrants } from "./grants_sync.js";
25
+ import { readPerClone } from "./machine_state.js";
26
+ import { countPendingRevokes } from "./pending_revoke_file.js";
27
+ import { ingestUrl } from "./post.js";
28
+ import { STATUS } from "./copy/index.js";
29
+ import { wrap } from "./term.js";
30
+ import { writeLines } from "./commands/context.js";
31
+ /** The slugs of every per-clone consent, normalized — what `planSync` calls `consentedSlugs`. */
32
+ function consentedSlugs(home) {
33
+ const out = [];
34
+ for (const clone of readPerClone(home)) {
35
+ if (clone.slug === null)
36
+ continue;
37
+ const slug = normalizeSlug(clone.slug);
38
+ if (slug !== "" && !out.includes(slug))
39
+ out.push(slug);
40
+ }
41
+ return out;
42
+ }
43
+ /** `owner/` for an owner, the slug for a repo — the way every account row and the first-sync line name them (`account_not_here.ts`). */
44
+ export { ownerName };
45
+ /**
46
+ * One sync for a verb. `json` is true for `--json`, which can print no line and so never does a FIRST sync.
47
+ *
48
+ * Prints, to stdout, only the first-sync line (and its full list past three names) and a blank line after it. Never throws.
49
+ */
50
+ export async function syncForVerb(ctx, json, deps,
51
+ /** A verb that syncs more than once (`connect`: at its start and after its writes) says what the first sync saves only once. */
52
+ options = {}) {
53
+ try {
54
+ const load = loadCredential({ env: ctx.env, home: ctx.home });
55
+ if (load.kind !== "ok")
56
+ return { kind: "skipped" };
57
+ const url = ingestUrl(ctx.env);
58
+ if (url === null)
59
+ return { kind: "skipped" };
60
+ const read = readGrants(ctx.home);
61
+ if (read.kind === "unreadable")
62
+ return { kind: "skipped" };
63
+ const grants = read.kind === "ok" ? read.grants : EMPTY_GRANTS;
64
+ const consented = consentedSlugs(ctx.home);
65
+ const first = grants.synced_at === null;
66
+ let disclosed = false;
67
+ if (first) {
68
+ // ⛔ A first sync that cannot say what it is saving waits.
69
+ if (!ctx.stdinIsTty || json)
70
+ return { kind: "skipped" };
71
+ const plan = planSync(grants, consented, true);
72
+ const names = [
73
+ ...plan.named.owners.map(ownerName),
74
+ ...plan.named.repos,
75
+ ];
76
+ if (names.length > 0 && options.quietFirst !== true) {
77
+ const lines = [...wrap(STATUS.accountSaving(names.join("\n")), 2)];
78
+ if (names.length > 3)
79
+ lines.push(...names.map((name) => ` ${name}`));
80
+ writeLines(ctx.stdout, [...lines, ""]);
81
+ disclosed = true;
82
+ }
83
+ }
84
+ const result = await syncGrants(url, load.credential, consented, {
85
+ fetch: deps.fetch,
86
+ home: ctx.home,
87
+ now: ctx.now,
88
+ timeoutMs: deps.timeoutMs,
89
+ maxBodyBytes: GRANTS_VERB_BODY_BYTES,
90
+ });
91
+ // One line per verb run, never one per op (VQ's ruling (ii)); the `pending` row is what the user sees.
92
+ if (result.kind === "rejected" && ctx.env.VIBECOMMIT_DEBUG !== undefined && ctx.env.VIBECOMMIT_DEBUG !== "") {
93
+ ctx.stderr.write(`grants sync rejected (400): ${result.pendingRejected} queued change(s) not accepted\n`);
94
+ }
95
+ return { kind: "ran", result, disclosed };
96
+ }
97
+ catch {
98
+ return { kind: "skipped" };
99
+ }
100
+ }
101
+ /**
102
+ * ⛔ "Not on this machine" is what THIS machine has not named: not in its owners, its repos, or a per-clone consent, and not
103
+ * turned off here or on the account. A repo under an owner the account grants is covered by that owner's row, not listed
104
+ * again. An owner or repo the user turned off is a choice, not a gap.
105
+ */
106
+ export function accountView(grants, account, perCloneSlugs, sync, pendingRevokes = 0) {
107
+ const pendingRejected = sync.kind === "ran" && sync.result.kind === "rejected" ? sync.result.pendingRejected : 0;
108
+ // A revoke of a credential `g` dropped is a change not yet sent to the account like any queued op (R3-11).
109
+ const queued = grants.pending.length + pendingRevokes;
110
+ if (account === null)
111
+ return { account, notHere: [], pending: queued, pendingRejected };
112
+ return { account, notHere: accountNotHere(grants, account, perCloneSlugs), pending: queued, pendingRejected };
113
+ }
114
+ /** The account state and grants for a view, read fresh from disk. `null` when `grants.json` is unreadable. */
115
+ export function readAccountView(home, perCloneSlugs, sync) {
116
+ const read = readGrants(home);
117
+ if (read.kind === "unreadable")
118
+ return null;
119
+ return accountView(read.kind === "ok" ? read.grants : EMPTY_GRANTS, readAccountState(home).account, perCloneSlugs, sync, countPendingRevokes(home));
120
+ }
121
+ //# sourceMappingURL=grants_verb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grants_verb.js","sourceRoot":"","sources":["../src/grants_verb.ts"],"names":[],"mappings":"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"}
@@ -36,9 +36,10 @@
36
36
  import { type IngestCredential } from "../credential.js";
37
37
  import { type Delivery, type FileKey } from "../post.js";
38
38
  import { type RecordCutter } from "../policy.js";
39
+ import { type Isolation } from "../session_targets.js";
39
40
  import type { HookEventName } from "../agents/types.js";
40
41
  import { type SessionKey } from "../paths.js";
41
- import { type ProjectKeys } from "../project.js";
42
+ export { confinementRoots } from "../project.js";
42
43
  import { turnStart, type TurnStart } from "../pending_bound.js";
43
44
  /**
44
45
  * Default wall-clock budget. `CR-028` sets the real per-event `timeout` in
@@ -268,6 +269,20 @@ export declare function deliverSubagents(opts: {
268
269
  sendBudget: number;
269
270
  /** ⛔ REQUIRED. A hook's deliveries stamp `liveAt`; `vibecommit finalize`'s must not (see `DeliveryContext.byHook`). */
270
271
  byHook: boolean;
272
+ /**
273
+ * A FOLDER target's per-stream ceiling: the offset the resolver SCANNED for each file key (A-T3, P1 (b)). A delegated stream
274
+ * delivers only up to it and a file key the scan never reached delivers nothing: bytes the resolver has not read for repo
275
+ * evidence are not sent under the folder's name. The returned `files` carry the CAPPED size, so `stampGaps` never writes off
276
+ * bytes this target was never allowed to send. Absent for a repo target: it sends to each file's end, as it always did.
277
+ */
278
+ sizeCap?: Readonly<Record<string, number>>;
279
+ /** A-T4: what the delegated streams may contain (R17 / R6). Default: a repo target's own `redactionRoots`. */
280
+ isolation?: Isolation;
281
+ /**
282
+ * C25: the caller's session-lock heartbeat (`finalize`, `backfill`). Called before each delegated file and before every request
283
+ * inside it; `false` means the lock is gone, and the loop stops with nothing more written. A hook passes none.
284
+ */
285
+ heartbeat?: () => boolean;
271
286
  }): Promise<DelegatedDeliveries>;
272
287
  /**
273
288
  * What `deliverSubagents` found, and whether any of its sends was HELD.
@@ -289,53 +304,6 @@ export interface DelegatedDeliveries {
289
304
  }
290
305
  /** Size in bytes, or null if it cannot be read. */
291
306
  export declare function fileSize(path: string): number | null;
292
- /**
293
- * ⛔ **The redaction confinement ROOT SET — `D184 §3`.**
294
- *
295
- * ```
296
- * isInsideAny([worktree, mainToplevel], candidate)
297
- * ```
298
- *
299
- * ## Why it is a set, and why the common dir is not in it
300
- *
301
- * `D184` moved the consent key to the git common dir so that a session inside a
302
- * `git worktree` is admitted at all. ⛔ **The confinement root MUST NOT follow
303
- * it there.** `isInside` realpaths both sides and fail-closes anything it cannot
304
- * place to *outside* — which here means REDACT — so a root at `<main>/.git`
305
- * would judge every file of an external worktree to be outside the main clone
306
- * and replace its `content`, `oldString`, `newString` and `structuredPatch` with
307
- * markers. **The capture still succeeds. The turn counts still look right. The
308
- * content is gone**, and a test asserting *"worktree sessions capture now"*
309
- * passes on an empty payload.
310
- *
311
- * Two roots, because both are genuinely the user's own tree: the worktree the
312
- * session is running in, and the main clone it was cut from — a builder in a
313
- * worktree reads the main clone's files constantly.
314
- *
315
- * ## ⛔ The `paths.ts:487-489` prohibition, answered — `D184 §5`
316
- *
317
- * > *"`roots` comes from the REGISTRY. It must never be derived from input."*
318
- *
319
- * **That prohibition is about PROVENANCE, and both members have the right one.**
320
- * The named hazard is *anything on hook stdin* — attacker-supplied. Neither of
321
- * these is: `keys` can only be produced by `resolveProjectKeys`, which is git's
322
- * own answer about the directory the session runs in; `mainToplevel` is git's
323
- * answer about the repository **the consent gate already approved**, and it is
324
- * content-validated by `mainWorkTree` above. The worktree root has exactly the
325
- * same provenance and has been used this way since `CR-024d`.
326
- *
327
- * ⚠ **Provenance is the whole argument, so this code preserves it:** nothing
328
- * here is read from stdin, the derivation is validated by content, and a failure
329
- * yields no second root rather than a fallback. An empty set would refuse
330
- * everything (`paths.ts:491-492`), which is the correct direction — but this
331
- * function cannot return one, because `keys.worktree` is always a member.
332
- *
333
- * ⚠ The dedup is cosmetic. `isInsideAny` over a repeated root is a union with
334
- * itself; it is dropped so that a main-clone session reads as the single root it
335
- * has always had, and so a cell asserting "no second root" is asserting
336
- * something.
337
- */
338
- export declare function confinementRoots(keys: ProjectKeys): readonly string[];
339
307
  /**
340
308
  * Read `[from, to)` of the transcript, REDACT it, and compress it.
341
309
  *
@@ -377,12 +345,25 @@ export declare function confinementRoots(keys: ProjectKeys): readonly string[];
377
345
  * set is the ordinary main-clone case and behaves exactly as the old parameter
378
346
  * did.
379
347
  *
348
+ * ## ⛔ `isolation` — what a TARGET's stream may contain beyond the path rule (any-folder capture)
349
+ *
350
+ * R6 · R17. A session that worked in N granted repos uploads N copies, so the chokepoint also knows WHOSE copy it is cutting.
351
+ * For a REPO target, a record whose `cwd` resolves inside a work tree other than the target's is withheld (length-preserving, the
352
+ * same markers): another repo's commands and output must not reach this repo's readers. For a FOLDER target, anything inside a
353
+ * git work tree nested in the folder is withheld (exclusion roots). Records run from the launch folder are kept in every copy;
354
+ * that residual (prompts and prose from the parent folder) is stated in the README and the claims register. Absent: the
355
+ * structured-path rule alone, exactly as before.
356
+ *
380
357
  * EXPORTED for `connect`'s test capture (`CR-025`), which reads a transcript on
381
358
  * a path the hook never takes. It reuses this rather than opening one itself,
382
359
  * because a second reader would bypass both the confinement and the redaction —
383
360
  * exactly what the chokepoint note above warns about.
384
361
  */
385
- export declare function readSpan(path: string, from: number, to: number, projectRoots: readonly string[], home: string, env: NodeJS.ProcessEnv): Uint8Array | null;
362
+ export declare function readSpan(path: string, from: number, to: number, projectRoots: readonly string[], home: string, env: NodeJS.ProcessEnv,
363
+ /** A-T4: the target's isolation (R17 record isolation for a repo, R6 exclusion roots for a folder). Absent: structured-path redaction only. */
364
+ isolation?: Isolation,
365
+ /** The stream this file is. Default: derived from the path (Claude's `subagents/agent-<id>.jsonl`); a Codex delegated file is announced, not found by directory, so its caller says. */
366
+ streamKey?: string): Uint8Array | null;
386
367
  /**
387
368
  * PR 4a — where a transcript's records end, for `deliver()` to cut a delta on.
388
369
  *
@@ -400,4 +381,3 @@ export declare function recordCutter(path: string): RecordCutter;
400
381
  * when the session has no pending line — the usual case on every Stop — so the scan is skipped then. `scan` is a test seam.
401
382
  */
402
383
  export declare function promotionBound(home: string, key: SessionKey, transcriptPath: string, nowMs: number, scan?: typeof turnStart): TurnStart;
403
- export {};