@vibe-commit/capture 0.1.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.
- package/LICENSE +21 -0
- package/README.md +66 -0
- package/dist/agents/claude_code.d.ts +11 -0
- package/dist/agents/claude_code.js +162 -0
- package/dist/agents/claude_code.js.map +1 -0
- package/dist/agents/codex_cli.d.ts +15 -0
- package/dist/agents/codex_cli.js +67 -0
- package/dist/agents/codex_cli.js.map +1 -0
- package/dist/agents/cursor.d.ts +21 -0
- package/dist/agents/cursor.js +89 -0
- package/dist/agents/cursor.js.map +1 -0
- package/dist/agents/registry.d.ts +184 -0
- package/dist/agents/registry.js +212 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +279 -0
- package/dist/agents/types.js +67 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/commands/connect.d.ts +36 -0
- package/dist/commands/connect.js +499 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/context.d.ts +45 -0
- package/dist/commands/context.js +14 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/report.d.ts +105 -0
- package/dist/commands/report.js +430 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/status.d.ts +29 -0
- package/dist/commands/status.js +236 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/why.d.ts +349 -0
- package/dist/commands/why.js +937 -0
- package/dist/commands/why.js.map +1 -0
- package/dist/consent.d.ts +59 -0
- package/dist/consent.js +111 -0
- package/dist/consent.js.map +1 -0
- package/dist/copy/claims.d.ts +79 -0
- package/dist/copy/claims.js +343 -0
- package/dist/copy/claims.js.map +1 -0
- package/dist/copy/grades.d.ts +117 -0
- package/dist/copy/grades.js +96 -0
- package/dist/copy/grades.js.map +1 -0
- package/dist/copy/index.d.ts +12 -0
- package/dist/copy/index.js +13 -0
- package/dist/copy/index.js.map +1 -0
- package/dist/copy/strings.d.ts +1328 -0
- package/dist/copy/strings.js +1243 -0
- package/dist/copy/strings.js.map +1 -0
- package/dist/copy/time.d.ts +27 -0
- package/dist/copy/time.js +43 -0
- package/dist/copy/time.js.map +1 -0
- package/dist/credential.d.ts +211 -0
- package/dist/credential.js +298 -0
- package/dist/credential.js.map +1 -0
- package/dist/exit.d.ts +59 -0
- package/dist/exit.js +60 -0
- package/dist/exit.js.map +1 -0
- package/dist/git.d.ts +299 -0
- package/dist/git.js +653 -0
- package/dist/git.js.map +1 -0
- package/dist/hooks/entry.d.ts +277 -0
- package/dist/hooks/entry.js +1092 -0
- package/dist/hooks/entry.js.map +1 -0
- package/dist/hooks/post_commit.d.ts +59 -0
- package/dist/hooks/post_commit.js +160 -0
- package/dist/hooks/post_commit.js.map +1 -0
- package/dist/hooks/post_rewrite.d.ts +59 -0
- package/dist/hooks/post_rewrite.js +161 -0
- package/dist/hooks/post_rewrite.js.map +1 -0
- package/dist/hooks/session_end.d.ts +101 -0
- package/dist/hooks/session_end.js +120 -0
- package/dist/hooks/session_end.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +360 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +153 -0
- package/dist/install.js +284 -0
- package/dist/install.js.map +1 -0
- package/dist/json.d.ts +100 -0
- package/dist/json.js +94 -0
- package/dist/json.js.map +1 -0
- package/dist/oauth/discovery.d.ts +96 -0
- package/dist/oauth/discovery.js +163 -0
- package/dist/oauth/discovery.js.map +1 -0
- package/dist/oauth/lock.d.ts +100 -0
- package/dist/oauth/lock.js +287 -0
- package/dist/oauth/lock.js.map +1 -0
- package/dist/oauth/loopback.d.ts +85 -0
- package/dist/oauth/loopback.js +124 -0
- package/dist/oauth/loopback.js.map +1 -0
- package/dist/oauth/pkce.d.ts +58 -0
- package/dist/oauth/pkce.js +77 -0
- package/dist/oauth/pkce.js.map +1 -0
- package/dist/oauth/read.d.ts +120 -0
- package/dist/oauth/read.js +144 -0
- package/dist/oauth/read.js.map +1 -0
- package/dist/oauth/session.d.ts +80 -0
- package/dist/oauth/session.js +112 -0
- package/dist/oauth/session.js.map +1 -0
- package/dist/oauth/signin.d.ts +178 -0
- package/dist/oauth/signin.js +225 -0
- package/dist/oauth/signin.js.map +1 -0
- package/dist/oauth/token.d.ts +139 -0
- package/dist/oauth/token.js +183 -0
- package/dist/oauth/token.js.map +1 -0
- package/dist/paths.d.ts +366 -0
- package/dist/paths.js +460 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy.d.ts +195 -0
- package/dist/policy.js +244 -0
- package/dist/policy.js.map +1 -0
- package/dist/post.d.ts +302 -0
- package/dist/post.js +384 -0
- package/dist/post.js.map +1 -0
- package/dist/project.d.ts +99 -0
- package/dist/project.js +192 -0
- package/dist/project.js.map +1 -0
- package/dist/redact.d.ts +175 -0
- package/dist/redact.js +700 -0
- package/dist/redact.js.map +1 -0
- package/dist/runtime.d.ts +30 -0
- package/dist/runtime.js +37 -0
- package/dist/runtime.js.map +1 -0
- package/dist/spawn_budget.d.ts +101 -0
- package/dist/spawn_budget.js +124 -0
- package/dist/spawn_budget.js.map +1 -0
- package/dist/spool.d.ts +390 -0
- package/dist/spool.js +556 -0
- package/dist/spool.js.map +1 -0
- package/dist/state.d.ts +109 -0
- package/dist/state.js +217 -0
- package/dist/state.js.map +1 -0
- package/dist/system_message.d.ts +101 -0
- package/dist/system_message.js +141 -0
- package/dist/system_message.js.map +1 -0
- package/dist/term.d.ts +112 -0
- package/dist/term.js +134 -0
- package/dist/term.js.map +1 -0
- package/dist/version.d.ts +16 -0
- package/dist/version.js +17 -0
- package/dist/version.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SessionEnd` settles before it reads — `CR-020d`, D57 §DX7.
|
|
3
|
+
*
|
|
4
|
+
* The finding, verbatim: *"`SessionEnd` settles and re-reads inside its timeout.
|
|
5
|
+
* `transcript_path` is documented as written asynchronously and may lag;
|
|
6
|
+
* `SessionEnd` has no next event, so D56's advance-regardless loses the final
|
|
7
|
+
* turn **permanently**."*
|
|
8
|
+
*
|
|
9
|
+
* ## Why only this event
|
|
10
|
+
*
|
|
11
|
+
* The client's whole design tolerates a lagging write: read what is there, leave
|
|
12
|
+
* the offset where it lands, and let the NEXT invocation pick up whatever the
|
|
13
|
+
* write had not flushed yet. `Stop` and `PreCompact` both have a next
|
|
14
|
+
* invocation. `SessionEnd` does not — it is the last hook of the session, so
|
|
15
|
+
* bytes missed here are missed forever, and they are the bytes of the final
|
|
16
|
+
* turn, which is the one a user is most likely to go looking for.
|
|
17
|
+
*
|
|
18
|
+
* So the fix is narrow on purpose: one event pays the cost, and `Stop` behaves
|
|
19
|
+
* exactly as it did before this task. `test/contract.test.ts` asserts that
|
|
20
|
+
* negative half directly, because a change that quietly made every event settle
|
|
21
|
+
* would pass the positive test just as well.
|
|
22
|
+
*
|
|
23
|
+
* ## One wait, not a poll loop
|
|
24
|
+
*
|
|
25
|
+
* The task is "settle-and-reread", singular. D56 §D8 is a founder override that
|
|
26
|
+
* a hook must never block or slow a developer's turn, and "wait until the file
|
|
27
|
+
* stops growing" has no natural upper bound — under load it is unbounded exactly
|
|
28
|
+
* when blocking is least affordable. A single named wait is the simplest thing
|
|
29
|
+
* that closes the finding, and its cost is knowable by reading one constant.
|
|
30
|
+
*
|
|
31
|
+
* ## This module holds no I/O and no clock
|
|
32
|
+
*
|
|
33
|
+
* `settledSize` takes both, for the same reason `policy.ts` is pure: the whole
|
|
34
|
+
* settle rule is then testable without a real 250 ms of wall clock and without a
|
|
35
|
+
* filesystem, and the one place that does touch either is the caller.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* The event name Claude Code sends on stdin as `hook_event_name` for the last
|
|
39
|
+
* hook of a session. DESIGN.md §13.7 governs it alongside `Stop` and
|
|
40
|
+
* `PreCompact`; this task changes WHEN bytes are read, never the exit contract.
|
|
41
|
+
*/
|
|
42
|
+
export const SESSION_END_EVENT = "SessionEnd";
|
|
43
|
+
/**
|
|
44
|
+
* How long to let the transcript settle. **250 ms, and the number is reasoned.**
|
|
45
|
+
*
|
|
46
|
+
* The lag being covered is a local filesystem write-flush artifact — Claude
|
|
47
|
+
* Code's own process appending JSONL lines to a file this process is about to
|
|
48
|
+
* stat — not a network round trip. That puts the expected lag in the
|
|
49
|
+
* tens-of-milliseconds range, so 250 ms is roughly an order of magnitude of
|
|
50
|
+
* margin over the effect it is covering, while staying a twentieth of the
|
|
51
|
+
* default 5 s budget.
|
|
52
|
+
*
|
|
53
|
+
* It is deliberately NOT larger. Every millisecond here is taken from the send
|
|
54
|
+
* that follows (see `settleDelayMs`), and a settle generous enough to cover a
|
|
55
|
+
* pathologically slow write would starve the upload it exists to make complete.
|
|
56
|
+
* If evidence ever shows real lag above this, change the constant and say why —
|
|
57
|
+
* it is one number in one place precisely so that stays cheap.
|
|
58
|
+
*/
|
|
59
|
+
export const SESSION_END_SETTLE_DELAY_MS = 250;
|
|
60
|
+
/**
|
|
61
|
+
* The most of the hook's budget the settle may ever claim.
|
|
62
|
+
*
|
|
63
|
+
* The settle is carved OUT of the existing budget, never added on top of it, so
|
|
64
|
+
* it competes with the send. This cap is what keeps the constant above safe at
|
|
65
|
+
* any budget: on the 5 s default it never binds (0.3 × 5000 = 1500 ≫ 250), and
|
|
66
|
+
* on a budget small enough that a flat 250 ms would swallow the invocation it
|
|
67
|
+
* scales the settle down instead of eating the send.
|
|
68
|
+
*/
|
|
69
|
+
export const SETTLE_BUDGET_FRACTION = 0.3;
|
|
70
|
+
/**
|
|
71
|
+
* How long to actually settle, given this invocation's whole budget.
|
|
72
|
+
*
|
|
73
|
+
* The override exists for the same two reasons `resolveCaps` has one
|
|
74
|
+
* (`policy.ts`): an operator on a filesystem slower than this constant assumes
|
|
75
|
+
* can raise it without a release, and the end-to-end test has to widen the
|
|
76
|
+
* window to land an append inside it deterministically rather than racing a
|
|
77
|
+
* child's boot — which varies by an order of magnitude under load (`CR-126`).
|
|
78
|
+
*
|
|
79
|
+
* Unset or unparseable takes the default rather than disabling the settle: a
|
|
80
|
+
* window an empty string can switch off is not a window. The budget cap still
|
|
81
|
+
* applies to the override, so it can widen the settle but never let it swallow
|
|
82
|
+
* the send.
|
|
83
|
+
*/
|
|
84
|
+
export function settleDelayMs(env, budgetMs) {
|
|
85
|
+
const raw = env.VIBECOMMIT_SESSION_END_SETTLE_MS;
|
|
86
|
+
const parsed = raw === undefined ? NaN : Number(raw);
|
|
87
|
+
const configured = Number.isFinite(parsed) && parsed > 0 ? parsed : SESSION_END_SETTLE_DELAY_MS;
|
|
88
|
+
return Math.min(configured, Math.floor(budgetMs * SETTLE_BUDGET_FRACTION));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The transcript's size after letting a lagging write land.
|
|
92
|
+
*
|
|
93
|
+
* Read, wait, read again, and take the LARGER. Growth is the case this exists
|
|
94
|
+
* for: the first read raced a write in progress, and the second sees the final
|
|
95
|
+
* turn the first one missed.
|
|
96
|
+
*
|
|
97
|
+
* **A SHORTER second read keeps the first.** That is truncation or rotation — a
|
|
98
|
+
* different and much rarer failure mode, which this task deliberately does not
|
|
99
|
+
* try to solve; `nextSpan` already resyncs from 0 when the offset sits past EOF,
|
|
100
|
+
* and `readSpan` already sends only the bytes actually present. Named as a known
|
|
101
|
+
* gap rather than handled speculatively.
|
|
102
|
+
*
|
|
103
|
+
* A `null` second read (the file went away mid-settle) also keeps the first, for
|
|
104
|
+
* the same reason: what we saw is better evidence than what we can no longer see.
|
|
105
|
+
*/
|
|
106
|
+
export async function settledSize(sizeOf, wait, delayMs) {
|
|
107
|
+
const first = sizeOf();
|
|
108
|
+
// Nothing to settle toward — the caller treats null as "do not send", and a
|
|
109
|
+
// wait would spend budget to learn the same thing again.
|
|
110
|
+
if (first === null)
|
|
111
|
+
return null;
|
|
112
|
+
if (delayMs <= 0)
|
|
113
|
+
return first;
|
|
114
|
+
await wait(delayMs);
|
|
115
|
+
const second = sizeOf();
|
|
116
|
+
if (second === null)
|
|
117
|
+
return first;
|
|
118
|
+
return second > first ? second : first;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=session_end.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session_end.js","sourceRoot":"","sources":["../../src/hooks/session_end.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AAE/C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB,EAAE,QAAgB;IACpE,MAAM,GAAG,GAAG,GAAG,CAAC,gCAAgC,CAAC;IACjD,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,UAAU,GACd,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC;IAC/E,OAAO,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,sBAAsB,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAA2B,EAC3B,IAAmC,EACnC,OAAe;IAEf,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IACvB,4EAA4E;IAC5E,yDAAyD;IACzD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/B,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;IAEpB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClC,OAAO,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;AACzC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { type InvocationMode } from "./exit.js";
|
|
3
|
+
declare const VERBS: readonly ["connect", "status", "off", "why", "report"];
|
|
4
|
+
export type Verb = (typeof VERBS)[number];
|
|
5
|
+
export declare function isVerb(value: string): value is Verb;
|
|
6
|
+
/**
|
|
7
|
+
* Hook invocations are distinguished by ARGV FIRST, then by env.
|
|
8
|
+
*
|
|
9
|
+
* ⚠ `CLAUDE_HOOK_EVENT` is **not** a variable Claude Code sets. The documented
|
|
10
|
+
* contract puts `hook_event_name` on **stdin JSON**, and the environment carries
|
|
11
|
+
* `CLAUDE_PROJECT_DIR` / `CLAUDE_PLUGIN_ROOT` — neither of which identifies a
|
|
12
|
+
* hook event. Keying the mode off that variable alone would make every hook
|
|
13
|
+
* invocation run in INTERACTIVE mode, which is the shape of a contract test that
|
|
14
|
+
* passes while testing nothing.
|
|
15
|
+
*
|
|
16
|
+
* So the primary signal is the one we control: `CR-028`'s `hooks.json` invokes
|
|
17
|
+
* `vibecommit hook`. The env var is kept as a secondary because the scaffold
|
|
18
|
+
* established it and a wrapper may already set it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function invocationMode(env: NodeJS.ProcessEnv, argv: readonly string[]): InvocationMode;
|
|
21
|
+
/**
|
|
22
|
+
* `--help`, wrapped hard at 80 columns per DESIGN.md §13.4.
|
|
23
|
+
*
|
|
24
|
+
* Never reflows to `process.stdout.columns`: identical commands must emit
|
|
25
|
+
* identical bytes, or issue-paste, screenshots and every golden-file test of the
|
|
26
|
+
* copy break. `test/help-golden.test.ts` is that golden file.
|
|
27
|
+
*
|
|
28
|
+
* No SGR here at all. Colour would have to be resolved before help could be
|
|
29
|
+
* rendered, and help is the one surface where structure alone is enough —
|
|
30
|
+
* indentation and the label gutter carry it, which is §13.1's point about
|
|
31
|
+
* `NO_COLOR` being a lossless degradation rather than a downgrade.
|
|
32
|
+
*/
|
|
33
|
+
export declare function renderHelp(): string;
|
|
34
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* `vibecommit` — CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* Verb bodies that are NOT here, each an owned task in
|
|
6
|
+
* `coordination/CAPTURE_REFACTOR_TASKS.md`:
|
|
7
|
+
*
|
|
8
|
+
* why CR-086 report CR-108 connect's live-capture ending CR-025
|
|
9
|
+
* status/off output spec CR-021 failure policy CR-018
|
|
10
|
+
* repo binding key + X-Repo-Slug CR-017 / CR-019
|
|
11
|
+
*
|
|
12
|
+
* What IS established here, and must not be undone by those tasks:
|
|
13
|
+
* - no user-facing string literal in a command body (CR-090 → `src/copy/`)
|
|
14
|
+
* - the exit-code contract is split hook vs interactive (CR-022 → `src/exit.ts`)
|
|
15
|
+
* - one commit-header renderer taking the grade (CR-090 → `src/copy/grades.ts`)
|
|
16
|
+
* - every escape sequence comes from `src/term.ts` (DESIGN.md §13.2)
|
|
17
|
+
* - the hook contract is enforced by the entry, not by each verb
|
|
18
|
+
*/
|
|
19
|
+
import { writeSync } from "node:fs";
|
|
20
|
+
import { homedir } from "node:os";
|
|
21
|
+
import { createInterface } from "node:readline/promises";
|
|
22
|
+
import { resolveAgentId } from "./agents/registry.js";
|
|
23
|
+
import { connect } from "./commands/connect.js";
|
|
24
|
+
import { off, status } from "./commands/status.js";
|
|
25
|
+
import { report } from "./commands/report.js";
|
|
26
|
+
import { why } from "./commands/why.js";
|
|
27
|
+
import { HELP, INTERNAL, USAGE } from "./copy/index.js";
|
|
28
|
+
import { EXIT } from "./exit.js";
|
|
29
|
+
import { runHook } from "./hooks/entry.js";
|
|
30
|
+
import { runPostCommit } from "./hooks/post_commit.js";
|
|
31
|
+
import { runPostRewrite } from "./hooks/post_rewrite.js";
|
|
32
|
+
import { LABEL_GUTTER, renderErrorBlock, resolveColour, wrap } from "./term.js";
|
|
33
|
+
import { CLIENT_VERSION } from "./version.js";
|
|
34
|
+
const VERBS = ["connect", "status", "off", "why", "report"];
|
|
35
|
+
export function isVerb(value) {
|
|
36
|
+
return VERBS.includes(value);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Hook invocations are distinguished by ARGV FIRST, then by env.
|
|
40
|
+
*
|
|
41
|
+
* ⚠ `CLAUDE_HOOK_EVENT` is **not** a variable Claude Code sets. The documented
|
|
42
|
+
* contract puts `hook_event_name` on **stdin JSON**, and the environment carries
|
|
43
|
+
* `CLAUDE_PROJECT_DIR` / `CLAUDE_PLUGIN_ROOT` — neither of which identifies a
|
|
44
|
+
* hook event. Keying the mode off that variable alone would make every hook
|
|
45
|
+
* invocation run in INTERACTIVE mode, which is the shape of a contract test that
|
|
46
|
+
* passes while testing nothing.
|
|
47
|
+
*
|
|
48
|
+
* So the primary signal is the one we control: `CR-028`'s `hooks.json` invokes
|
|
49
|
+
* `vibecommit hook`. The env var is kept as a secondary because the scaffold
|
|
50
|
+
* established it and a wrapper may already set it.
|
|
51
|
+
*/
|
|
52
|
+
export function invocationMode(env, argv) {
|
|
53
|
+
if (argv[0] === "hook")
|
|
54
|
+
return "hook";
|
|
55
|
+
return env.CLAUDE_HOOK_EVENT ? "hook" : "interactive";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* `--help`, wrapped hard at 80 columns per DESIGN.md §13.4.
|
|
59
|
+
*
|
|
60
|
+
* Never reflows to `process.stdout.columns`: identical commands must emit
|
|
61
|
+
* identical bytes, or issue-paste, screenshots and every golden-file test of the
|
|
62
|
+
* copy break. `test/help-golden.test.ts` is that golden file.
|
|
63
|
+
*
|
|
64
|
+
* No SGR here at all. Colour would have to be resolved before help could be
|
|
65
|
+
* rendered, and help is the one surface where structure alone is enough —
|
|
66
|
+
* indentation and the label gutter carry it, which is §13.1's point about
|
|
67
|
+
* `NO_COLOR` being a lossless degradation rather than a downgrade.
|
|
68
|
+
*/
|
|
69
|
+
export function renderHelp() {
|
|
70
|
+
const lines = [
|
|
71
|
+
...wrap(HELP.tagline, 2),
|
|
72
|
+
"",
|
|
73
|
+
...wrap(`${USAGE.usageLabel} ${HELP.usage}`, 2),
|
|
74
|
+
"",
|
|
75
|
+
...wrap(USAGE.commandsLabel, 2),
|
|
76
|
+
];
|
|
77
|
+
for (const verb of VERBS) {
|
|
78
|
+
// The description is wrapped on its own and the verb column is written over
|
|
79
|
+
// the first line's indent. Wrapping `verb + padding + description` as one
|
|
80
|
+
// string would not work: `wrap` normalises whitespace, so the fixed gutter
|
|
81
|
+
// would collapse to a single space.
|
|
82
|
+
const head = ` ${verb.padEnd(LABEL_GUTTER)}`;
|
|
83
|
+
const body = wrap(HELP.commands[verb], head.length);
|
|
84
|
+
lines.push(head + body[0].slice(head.length), ...body.slice(1));
|
|
85
|
+
}
|
|
86
|
+
lines.push("", ...wrap(`${USAGE.docsLabel} ${HELP.docsUrl}`, 2));
|
|
87
|
+
return lines.join("\n");
|
|
88
|
+
}
|
|
89
|
+
function interactiveContext(argv) {
|
|
90
|
+
return {
|
|
91
|
+
env: process.env,
|
|
92
|
+
home: homedir(),
|
|
93
|
+
cwd: process.cwd(),
|
|
94
|
+
nodeVersion: process.versions.node,
|
|
95
|
+
// `CR-183`. Resolved from argv HERE, the same pure read the hook branch at
|
|
96
|
+
// the bottom of this file makes — `connect` needs it to know whether the
|
|
97
|
+
// agent it was told about has a way to find the running session at all.
|
|
98
|
+
agentId: resolveAgentId(argv),
|
|
99
|
+
colour: resolveColour({
|
|
100
|
+
env: process.env,
|
|
101
|
+
isTty: process.stdout.isTTY === true,
|
|
102
|
+
noColorFlag: argv.includes("--no-color"),
|
|
103
|
+
json: argv.includes("--json"),
|
|
104
|
+
}),
|
|
105
|
+
stdinIsTty: process.stdin.isTTY === true,
|
|
106
|
+
stdout: process.stdout,
|
|
107
|
+
stderr: process.stderr,
|
|
108
|
+
/**
|
|
109
|
+
* The readline interface is created HERE, on the first question, and not
|
|
110
|
+
* once per invocation — CR-117.
|
|
111
|
+
*
|
|
112
|
+
* `createInterface` RESUMES stdin, and a resumed stdin keeps the event loop
|
|
113
|
+
* alive until it ends. Built eagerly, a verb that returns without ever
|
|
114
|
+
* prompting sat there until the pipe closed: `connect` refusing a non-TTY,
|
|
115
|
+
* and `status` / `off`, which never ask anything. On a terminal that looked
|
|
116
|
+
* fine, because stdin ends at EOF; under `cmd | vibecommit connect` in CI it
|
|
117
|
+
* is the hang the source finding names first, burning the job's whole
|
|
118
|
+
* timeout with the refusal already on screen and no way to explain it.
|
|
119
|
+
*
|
|
120
|
+
* It also makes style guide §10.2 rule 2 literally true rather than nearly
|
|
121
|
+
* true: on the refusal path stdin is not read, resumed, or opened at all.
|
|
122
|
+
*/
|
|
123
|
+
ask: async (question) => {
|
|
124
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
125
|
+
try {
|
|
126
|
+
return await rl.question(question);
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
rl.close();
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
now: () => new Date(),
|
|
133
|
+
selfPath: process.argv[1] ?? "",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async function main(argv) {
|
|
137
|
+
const [verb] = argv;
|
|
138
|
+
if (verb === undefined || verb === "--help" || verb === "-h") {
|
|
139
|
+
process.stdout.write(`${renderHelp()}\n`);
|
|
140
|
+
return EXIT.ok;
|
|
141
|
+
}
|
|
142
|
+
if (verb === "--version" || verb === "-v") {
|
|
143
|
+
process.stdout.write(`${CLIENT_VERSION}\n`);
|
|
144
|
+
return EXIT.ok;
|
|
145
|
+
}
|
|
146
|
+
if (!isVerb(verb)) {
|
|
147
|
+
process.stderr.write(`${USAGE.unknownCommand(verb)}\n\n${renderHelp()}\n`);
|
|
148
|
+
return EXIT.usage;
|
|
149
|
+
}
|
|
150
|
+
const ctx = interactiveContext(argv);
|
|
151
|
+
switch (verb) {
|
|
152
|
+
case "connect":
|
|
153
|
+
// `--sign-in` (CR-084d) is a FLAG, not a verb: `VERBS` is what `renderHelp`
|
|
154
|
+
// iterates, so a sixth verb would move `test/help.golden.txt`, and the
|
|
155
|
+
// brief for this task is explicit that the golden file must not move.
|
|
156
|
+
return await connect(ctx, { signIn: argv.includes("--sign-in") });
|
|
157
|
+
case "status":
|
|
158
|
+
// `argv.slice(1)` for the same reason `why` and `report` take it: `status`
|
|
159
|
+
// reads its own `--json` flag rather than this package acquiring an
|
|
160
|
+
// argument parser it has deliberately never had (DESIGN.md §13.3).
|
|
161
|
+
return status(ctx, argv.slice(1));
|
|
162
|
+
case "off":
|
|
163
|
+
return off(ctx);
|
|
164
|
+
case "why":
|
|
165
|
+
// CR-086. `argv.slice(1)` is everything after the verb — there is no
|
|
166
|
+
// argument parser in this package and `why` does not add one; it reads
|
|
167
|
+
// `<file>:<line>` and refuses `--json`, which is the smallest shape that
|
|
168
|
+
// satisfies the verbatim-approved `--help` sentence.
|
|
169
|
+
return await why(ctx, argv.slice(1));
|
|
170
|
+
case "report":
|
|
171
|
+
// CR-108, W10. Same shape as `why`: `argv.slice(1)` is everything after
|
|
172
|
+
// the verb, and the verb reads its own two flags rather than adding an
|
|
173
|
+
// argument parser this package deliberately does not have.
|
|
174
|
+
return await report(ctx, argv.slice(1));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function readStdin() {
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
let buf = "";
|
|
180
|
+
process.stdin.setEncoding("utf8");
|
|
181
|
+
process.stdin.on("data", (chunk) => {
|
|
182
|
+
buf += chunk;
|
|
183
|
+
});
|
|
184
|
+
process.stdin.on("end", () => resolve(buf));
|
|
185
|
+
process.stdin.on("error", () => resolve(""));
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The INTERACTIVE half of the split exit contract — CR-022, D61 round 3 §D8.
|
|
190
|
+
*
|
|
191
|
+
* The hook half is enforced in `hooks/entry.ts`: swallow everything, exit 0, stay
|
|
192
|
+
* silent, because a non-zero hook feeds stderr back into the user's agent and
|
|
193
|
+
* derails the task they were actually doing. **An interactive verb must not
|
|
194
|
+
* inherit that blanket.** As originally written the exit-0/stdout-empty rule read
|
|
195
|
+
* as governing the whole binary, which would make `why` on a read-lane 5xx exit 0
|
|
196
|
+
* and print nothing — a read verb failing silently, which is the defect this
|
|
197
|
+
* split exists to prevent.
|
|
198
|
+
*
|
|
199
|
+
* So: same fault, same binary, two modes, two behaviours. Interactive gets exit 1
|
|
200
|
+
* and §13.6's shape.
|
|
201
|
+
*
|
|
202
|
+
* Two things this deliberately does NOT do:
|
|
203
|
+
* - **No signal handling.** `Ctrl-C` cancelling a `connect` prompt is normal
|
|
204
|
+
* CLI behaviour, and suppressing `SIGINT` globally would be a UX regression
|
|
205
|
+
* dressed up as a fix. The hook's signal override stays scoped to hook mode.
|
|
206
|
+
* - **No stack trace** unless `VIBECOMMIT_DEBUG` is set (§13.6, first
|
|
207
|
+
* prohibition). The detail then goes out RAW, after the block, rather than
|
|
208
|
+
* through `wrap()`, which would reflow a stack into nonsense.
|
|
209
|
+
*/
|
|
210
|
+
function reportUnexpected(error, argv) {
|
|
211
|
+
const colour = resolveColour({
|
|
212
|
+
env: process.env,
|
|
213
|
+
isTty: process.stderr.isTTY === true,
|
|
214
|
+
noColorFlag: argv.includes("--no-color"),
|
|
215
|
+
json: argv.includes("--json"),
|
|
216
|
+
});
|
|
217
|
+
const lines = renderErrorBlock({
|
|
218
|
+
kind: "bad",
|
|
219
|
+
what: INTERNAL.unexpectedWhat,
|
|
220
|
+
why: [INTERNAL.unexpectedWhy],
|
|
221
|
+
fixLabel: INTERNAL.unexpectedFix,
|
|
222
|
+
fixes: [INTERNAL.unexpectedDebugCommand],
|
|
223
|
+
}, colour);
|
|
224
|
+
if (process.env.VIBECOMMIT_DEBUG !== undefined)
|
|
225
|
+
lines.push("", detailOf(error));
|
|
226
|
+
// `writeSync(2, …)` rather than `process.stderr.write`: stderr to a pipe is
|
|
227
|
+
// asynchronous and `process.exit` does not flush it, so the caller below would
|
|
228
|
+
// race its own diagnostic away. Same reason `finish()` uses it on fd 1.
|
|
229
|
+
try {
|
|
230
|
+
writeSync(2, `${lines.join("\n")}\n`);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// An unwritable stderr is not worth a second exception on this path.
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The raw detail, for `VIBECOMMIT_DEBUG` only.
|
|
238
|
+
*
|
|
239
|
+
* Interpolating an error is safe by construction here: an `IngestCredential`
|
|
240
|
+
* renders `vcik_…redacted` through `toString`, `toJSON` and the inspect hook, so
|
|
241
|
+
* a stack that embedded one cannot print the plaintext.
|
|
242
|
+
*/
|
|
243
|
+
function detailOf(error) {
|
|
244
|
+
if (error instanceof Error && typeof error.stack === "string")
|
|
245
|
+
return error.stack;
|
|
246
|
+
return String(error);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Catch what escapes `main()` entirely — a stray timer's throw, a rejection from
|
|
250
|
+
* a promise nobody awaited. Without these, Node prints its own stack trace to
|
|
251
|
+
* stderr, which §13.6 forbids outright.
|
|
252
|
+
*
|
|
253
|
+
* These force an exit rather than setting `process.exitCode`, because by
|
|
254
|
+
* definition something unexpected is still in flight and may be holding the event
|
|
255
|
+
* loop open. The `main()` rejection path below does not: nothing is in flight
|
|
256
|
+
* there, and letting the loop drain preserves whatever the verb already wrote.
|
|
257
|
+
*/
|
|
258
|
+
function installInteractiveGuards(argv) {
|
|
259
|
+
const fail = (error) => {
|
|
260
|
+
reportUnexpected(error, argv);
|
|
261
|
+
process.exit(EXIT.failure);
|
|
262
|
+
};
|
|
263
|
+
process.on("uncaughtException", fail);
|
|
264
|
+
process.on("unhandledRejection", fail);
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Swallow EPIPE.
|
|
268
|
+
*
|
|
269
|
+
* `vibecommit --help | head` closes stdout mid-write, and Node's default for an
|
|
270
|
+
* unhandled stream error is to print a stack trace and exit non-zero. §13.6
|
|
271
|
+
* forbids the stack trace outright, and a non-zero exit for an ordinary
|
|
272
|
+
* `| head` would teach a wrapper script that the command failed.
|
|
273
|
+
*/
|
|
274
|
+
function installPipeGuards() {
|
|
275
|
+
for (const stream of [process.stdout, process.stderr]) {
|
|
276
|
+
stream.on("error", (err) => {
|
|
277
|
+
if (err.code === "EPIPE")
|
|
278
|
+
process.exit(EXIT.ok);
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Only run when executed as the binary, so tests can import the module freely.
|
|
283
|
+
if (process.argv[1] && import.meta.url === `file://${process.argv[1]}`) {
|
|
284
|
+
installPipeGuards();
|
|
285
|
+
const argv = process.argv.slice(2);
|
|
286
|
+
if (argv[0] === "post-commit") {
|
|
287
|
+
// ⛔ A HIDDEN VERB, dispatched here rather than through `main`, and NOT in
|
|
288
|
+
// `VERBS` — `renderHelp` iterates that list, so adding it would move
|
|
289
|
+
// `test/help.golden.txt` for a verb no human ever types. `hook` is dispatched
|
|
290
|
+
// the same way, for the same reason.
|
|
291
|
+
//
|
|
292
|
+
// It runs inside the user's `git commit`, so it exits 0 unconditionally and
|
|
293
|
+
// writes nothing to either stream (`hooks/post_commit.ts`).
|
|
294
|
+
//
|
|
295
|
+
// ⛔ `env` IS THE LADDER'S FIRST RUNG. Claude Code exports
|
|
296
|
+
// `CLAUDE_CODE_SESSION_ID` into the Bash tool's environment and git passes it
|
|
297
|
+
// through to us (`M1`), so the committing session identifies ITSELF instead of
|
|
298
|
+
// being guessed at by mtime. This is the one place the real environment is
|
|
299
|
+
// read on this path; everything below takes it as a parameter.
|
|
300
|
+
process.exit(runPostCommit({ home: homedir(), cwd: process.cwd(), env: process.env }));
|
|
301
|
+
}
|
|
302
|
+
if (argv[0] === "post-rewrite") {
|
|
303
|
+
// The other hidden verb, for the same reason — and it is `post-commit`'s
|
|
304
|
+
// other half: `--amend` and `rebase` fire `post-commit` for a sha they then
|
|
305
|
+
// DESTROY (`M5`), and this is the only hook git tells about the pairing.
|
|
306
|
+
//
|
|
307
|
+
// ⛔ THE PAIRS ARRIVE ON STDIN, and it is read HERE so `hooks/post_rewrite.ts`
|
|
308
|
+
// opens nothing — the same seam that keeps every other module in this package
|
|
309
|
+
// free of a real file descriptor. ⚠ `readStdin` REUSED rather than a second
|
|
310
|
+
// synchronous reader beside it: it already resolves an `error` to `""`, and
|
|
311
|
+
// two stdin readers in one file is how the two come to disagree about what an
|
|
312
|
+
// unreadable stream means. An empty read parses to zero pairs, which is an
|
|
313
|
+
// ordinary answer rather than a failure.
|
|
314
|
+
void readStdin().then((stdin) => process.exit(runPostRewrite({
|
|
315
|
+
home: homedir(),
|
|
316
|
+
cwd: process.cwd(),
|
|
317
|
+
env: process.env,
|
|
318
|
+
// git's own `argv[1]` — `amend` or `rebase`.
|
|
319
|
+
kind: argv[1] ?? "",
|
|
320
|
+
stdin,
|
|
321
|
+
})));
|
|
322
|
+
// ⛔ `else if` FROM HERE, AND THE BRANCH ABOVE IS WHY. Reading stdin is
|
|
323
|
+
// asynchronous, so unlike `post-commit` this block RETURNS rather than
|
|
324
|
+
// exiting — and a plain `if` below would then run `main(["post-rewrite"])`
|
|
325
|
+
// synchronously, print an unknown-verb error, and put it in the terminal of
|
|
326
|
+
// someone in the middle of a `git rebase`. The contract this hook is held to
|
|
327
|
+
// is silence.
|
|
328
|
+
}
|
|
329
|
+
else if (invocationMode(process.env, argv) === "hook") {
|
|
330
|
+
// `runHook` installs the contract guards before it does any work and always
|
|
331
|
+
// calls `process.exit(0)`. It never returns, so nothing follows it.
|
|
332
|
+
void runHook({
|
|
333
|
+
env: process.env,
|
|
334
|
+
home: homedir(),
|
|
335
|
+
nodeVersion: process.versions.node,
|
|
336
|
+
// ⛔ `CR-183` — THE ONE PLACE THE FLAG IS READ ON THIS PATH, and it is read
|
|
337
|
+
// HERE rather than inside the hook for a structural reason: `runHook` never
|
|
338
|
+
// receives argv at all, and `parseHookInput` must not select the adapter
|
|
339
|
+
// because stdin is the input the confinement boundary exists to constrain.
|
|
340
|
+
// This is the seam that already injects `home` and `nodeVersion`.
|
|
341
|
+
//
|
|
342
|
+
// ⚠ Note what the line ABOVE this block does and does not do: resolving an
|
|
343
|
+
// id is not entering hook mode. `invocationMode` keys on `argv[0]`, so the
|
|
344
|
+
// registered command MUST lead with the `hook` verb — put the flag first
|
|
345
|
+
// and this branch is never taken.
|
|
346
|
+
agentId: resolveAgentId(argv),
|
|
347
|
+
readStdin,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
installInteractiveGuards(argv);
|
|
352
|
+
void main(argv).then((code) => {
|
|
353
|
+
process.exitCode = code;
|
|
354
|
+
}, (error) => {
|
|
355
|
+
reportUnexpected(error, argv);
|
|
356
|
+
process.exitCode = EXIT.failure;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|