plumbbob 0.8.18 → 0.9.2
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/.claude-plugin/plugin.json +1 -1
- package/README.md +51 -44
- package/dist/cli-core.js +35 -15
- package/dist/lib/agents.js +230 -112
- package/dist/lib/buildlog.js +50 -30
- package/dist/lib/buildlogsync.js +21 -12
- package/dist/lib/check.js +69 -35
- package/dist/lib/commitmsg.js +53 -32
- package/dist/lib/git.js +86 -31
- package/dist/lib/intent.js +91 -31
- package/dist/lib/latch.js +70 -39
- package/dist/lib/orient.js +78 -39
- package/dist/lib/plugins.js +11 -8
- package/dist/lib/settings.js +65 -32
- package/dist/lib/sidecar.js +356 -150
- package/dist/lib/templates.js +17 -6
- package/dist/verbs/agent.js +116 -55
- package/dist/verbs/build.js +27 -12
- package/dist/verbs/check.js +33 -7
- package/dist/verbs/checkpoint.js +158 -79
- package/dist/verbs/doctor.js +192 -95
- package/dist/verbs/finish.js +88 -46
- package/dist/verbs/handoff.js +56 -20
- package/dist/verbs/init.js +37 -12
- package/dist/verbs/park.js +14 -3
- package/dist/verbs/revert.js +64 -24
- package/dist/verbs/spike.js +89 -30
- package/dist/verbs/start.js +72 -38
- package/dist/verbs/status.js +44 -17
- package/dist/verbs/turn.js +88 -45
- package/dist/verbs/use.js +20 -9
- package/package.json +1 -1
- package/skills/{pb-build → build}/SKILL.md +25 -25
- package/skills/{pb-doctor → doctor}/SKILL.md +1 -1
- package/skills/{pb-finish → finish}/SKILL.md +3 -3
- package/skills/{pb-harvest → harvest}/SKILL.md +4 -4
- package/skills/{pb-park → park}/SKILL.md +2 -2
- package/skills/{pb-plan → plan}/SKILL.md +11 -11
- package/skills/{pb-refine → refine}/SKILL.md +7 -7
- package/skills/{pb-revert → revert}/SKILL.md +2 -2
- package/skills/{pb-spike → spike}/SKILL.md +4 -4
- package/skills/{pb-status → status}/SKILL.md +3 -3
- package/skills/{pb-step → step}/SKILL.md +9 -9
- package/skills/{pb-verify → verify}/SKILL.md +8 -8
- package/templates/build-log.md +7 -7
- package/templates/intent.md +8 -8
- package/templates/spike-report.md +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plumbbob",
|
|
3
3
|
"displayName": "PlumbBob",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.2",
|
|
5
5
|
"description": "Attention-first build process — driver skills + a CLI that keep you the decider: guidance on the work, a latch on the record.",
|
|
6
6
|
"author": { "name": "Rob McLarty", "email": "hello@robmclarty.com", "url": "https://robmclarty.com" },
|
|
7
7
|
"homepage": "https://github.com/robmclarty/plumbbob#readme",
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<a href="https://robmclarty.github.io/plumbbob/api.html">API reference</a>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
|
-
PlumbBob is a Claude Code plugin — twelve
|
|
13
|
+
PlumbBob is a Claude Code plugin — twelve skills and a small CLI — that runs
|
|
14
14
|
LLM-assisted coding as a loop you control. You and the model settle the plan in a file
|
|
15
15
|
*before* any code; then the model builds one small step at a time and **stops after
|
|
16
16
|
each one**, waiting for you to read the diff and approve it before anything is
|
|
@@ -41,7 +41,7 @@ model's goodwill:
|
|
|
41
41
|
run (types, lint, tests, dead code, docs) has to pass before a step lands.
|
|
42
42
|
- **One SHA per verified step.** Every approved step is its own git commit against a
|
|
43
43
|
recorded baseline — a ledger of checkpoints, not one undifferentiated diff at the end.
|
|
44
|
-
- **A preservation-aware revert.** `/
|
|
44
|
+
- **A preservation-aware revert.** `/plumbbob:revert` resets exactly to a recorded checkpoint
|
|
45
45
|
SHA while keeping your plan and notes intact, and restores *only* SHAs the loop wrote.
|
|
46
46
|
- **A build record that rides the PR.** The tracked `builds/<slug>/` folder — intent, log,
|
|
47
47
|
checkpoints, report — merges into `main` with the branch instead of dying with the
|
|
@@ -57,7 +57,7 @@ work, a latch on the record.**
|
|
|
57
57
|
## The loop in one picture
|
|
58
58
|
|
|
59
59
|
<p align="center">
|
|
60
|
-
<img src="demo.svg" alt="An animated terminal session: /
|
|
60
|
+
<img src="demo.svg" alt="An animated terminal session: /plumbbob:plan writes the plan, /plumbbob:build implements step 1 and stops at the PAUSE, the human approves, the step is checkpointed" width="760">
|
|
61
61
|
</p>
|
|
62
62
|
|
|
63
63
|
Everything the model must stay true to lives in one file, the build's `intent.md`
|
|
@@ -68,11 +68,11 @@ with its *because*), and the **Steps** — a numbered list where every step carr
|
|
|
68
68
|
expected to touch).
|
|
69
69
|
|
|
70
70
|
```text
|
|
71
|
-
/
|
|
71
|
+
/plumbbob:plan decide everything on paper — frame, decisions, all steps (once)
|
|
72
72
|
per step:
|
|
73
|
-
/
|
|
74
|
-
(approve)
|
|
75
|
-
/
|
|
73
|
+
/plumbbob:build implement the next step → run checks → self-review → PAUSE
|
|
74
|
+
(approve) → the step is committed as a checkpoint; fire /plumbbob:build again
|
|
75
|
+
/plumbbob:finish report what shipped and why, final commit, clear (once)
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
Nothing is locked and nothing refuses you — the loop does a step's labor, pulls up to
|
|
@@ -101,7 +101,7 @@ plumbbob init # link it into Claude Code; --uninstall to undo
|
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
Restart Claude Code (or `/reload-plugins`) to activate, then run `plumbbob doctor`
|
|
104
|
-
(or `/
|
|
104
|
+
(or `/plumbbob:doctor` in-session) to confirm the wiring. The full guide — namespacing,
|
|
105
105
|
per-project sessions, the agent-neutral roadmap — is in
|
|
106
106
|
[`docs/install.md`](docs/install.md).
|
|
107
107
|
|
|
@@ -109,11 +109,11 @@ per-project sessions, the agent-neutral roadmap — is in
|
|
|
109
109
|
|
|
110
110
|
In Claude Code, inside any git repo with a clean tree:
|
|
111
111
|
|
|
112
|
-
1. **Plan.** Fire `/
|
|
113
|
-
you), a rough line (`/
|
|
112
|
+
1. **Plan.** Fire `/plumbbob:plan` and give it whatever you have — nothing (it interviews
|
|
113
|
+
you), a rough line (`/plumbbob:plan rate-limit POST /login, 5/min/IP, return 429`), or a
|
|
114
114
|
path to a spec file. Together you fill the build's `intent.md`. No code is written
|
|
115
115
|
yet.
|
|
116
|
-
2. **Build.** Fire `/
|
|
116
|
+
2. **Build.** Fire `/plumbbob:build`. It implements the next undone step, runs the
|
|
117
117
|
heavy check gate, reviews its own diff against the plan, and stops:
|
|
118
118
|
|
|
119
119
|
```text
|
|
@@ -125,16 +125,16 @@ In Claude Code, inside any git repo with a clean tree:
|
|
|
125
125
|
code, docs. To gate through your own command instead, set the `"check"` key in
|
|
126
126
|
`.plumbbob/settings.json`, e.g. `"check": "npm test"`.)
|
|
127
127
|
3. **Approve** — or send fixes. On your OK it commits the step as a checkpoint, marks
|
|
128
|
-
it done, and returns to the boundary. Fire `/
|
|
129
|
-
re-firing it *is* the clock tick. Whenever you lose the thread, `/
|
|
128
|
+
it done, and returns to the boundary. Fire `/plumbbob:build` again for the next step —
|
|
129
|
+
re-firing it *is* the clock tick. Whenever you lose the thread, `/plumbbob:status` shows
|
|
130
130
|
where you are and names the next move.
|
|
131
|
-
4. **Finish.** When the last step is done, `/
|
|
131
|
+
4. **Finish.** When the last step is done, `/plumbbob:finish` writes a report of what shipped
|
|
132
132
|
and why into the build's tracked folder, makes the final commit, and clears the slate
|
|
133
133
|
for the next goal. The folder rides the branch into the PR — the build's record merges
|
|
134
134
|
into `main` instead of dying with the worktree.
|
|
135
135
|
|
|
136
|
-
A mid-build "ooh, what if…" never derails the step: `/
|
|
137
|
-
in one line, and `/
|
|
136
|
+
A mid-build "ooh, what if…" never derails the step: `/plumbbob:park` captures it to a list
|
|
137
|
+
in one line, and `/plumbbob:harvest` triages the list between steps. One goal walked end to
|
|
138
138
|
end, with the real output at every stage, is in
|
|
139
139
|
[`docs/happy-path.md`](docs/happy-path.md).
|
|
140
140
|
|
|
@@ -142,42 +142,43 @@ end, with the real output at every stage, is in
|
|
|
142
142
|
|
|
143
143
|
You drive the whole loop from your IDE with `/plumbbob:*` skills — no step numbers to
|
|
144
144
|
remember, no raw CLI to type. Every skill is `disable-model-invocation`, so *you* fire
|
|
145
|
-
every move, and `/
|
|
146
|
-
under the plugin
|
|
147
|
-
|
|
145
|
+
every move, and `/plumbbob:status` always names your next one. (Claude Code namespaces
|
|
146
|
+
them under the plugin, so the command is `/plumbbob:plan`. The bare `/plan` reaches it
|
|
147
|
+
too — but only where nothing else owns that name, and four of the twelve share one with
|
|
148
|
+
a Claude Code built-in, so these docs write the full form.)
|
|
148
149
|
|
|
149
150
|
**The happy path** — the three moves every session makes; many sessions need
|
|
150
151
|
nothing else:
|
|
151
152
|
|
|
152
153
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
153
154
|
|------------------------------------|------|
|
|
154
|
-
| `/
|
|
155
|
-
| `/
|
|
156
|
-
| `/
|
|
155
|
+
| `/plumbbob:plan` | plan the whole goal — open the session and author intent's Frame, Decisions, Constraints, **and all Steps** |
|
|
156
|
+
| `/plumbbob:build` | implement the next planned step, then verify it to the pause — `--auto` self-approves and chains to done; a range like `1-3` self-approves through step 3, then pauses |
|
|
157
|
+
| `/plumbbob:finish` | finish up — write the report, make the final commit, clear for a fresh goal |
|
|
157
158
|
|
|
158
159
|
**Plan-shaping moves** — optional, for when the plan needs work mid-flight:
|
|
159
160
|
|
|
160
161
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
161
162
|
|------------------------------------|------|
|
|
162
|
-
| `/
|
|
163
|
-
| `/
|
|
164
|
-
| `/
|
|
163
|
+
| `/plumbbob:step` | revise/sharpen the next step (empty input auto-syncs it to reality) |
|
|
164
|
+
| `/plumbbob:refine` | attack the frame for holes, or repair a drifted plan |
|
|
165
|
+
| `/plumbbob:spike` | throwaway worktree experiment for a fork the plan can't settle |
|
|
165
166
|
|
|
166
167
|
**Helpers** — orient, verify, recover, diagnose:
|
|
167
168
|
|
|
168
169
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
169
170
|
|------------------------------------|------|
|
|
170
|
-
| `/
|
|
171
|
-
| `/
|
|
172
|
-
| `/
|
|
173
|
-
| `/
|
|
171
|
+
| `/plumbbob:status` | orient — where you are, the next step's done-when and seam, and the next move |
|
|
172
|
+
| `/plumbbob:verify` | the tick, standalone — check → self-review → validate → **PAUSE** → checkpoint, for a diff `/plumbbob:build` didn't write |
|
|
173
|
+
| `/plumbbob:revert` | recover — `git reset --hard` to a recorded checkpoint |
|
|
174
|
+
| `/plumbbob:doctor` | check the install from inside a session |
|
|
174
175
|
|
|
175
176
|
**Capture** — the park/harvest loop for mid-build ideas:
|
|
176
177
|
|
|
177
178
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
178
179
|
|------------------------------------|------|
|
|
179
|
-
| `/
|
|
180
|
-
| `/
|
|
180
|
+
| `/plumbbob:park` | capture a mid-build idea without chasing it |
|
|
181
|
+
| `/plumbbob:harvest` | triage parked ideas between steps (blocker / tangent / pivot) |
|
|
181
182
|
|
|
182
183
|
All twelve, with inputs and effects, are in
|
|
183
184
|
[`docs/skills-reference.md`](docs/skills-reference.md).
|
|
@@ -189,9 +190,9 @@ flow), and a `.plumbbob/` sidecar you can open and edit by hand at any time —
|
|
|
189
190
|
that rides the branch into the PR, plus an untracked control plane (`settings.local.json`,
|
|
190
191
|
the session sentinel, the in-flight markers).
|
|
191
192
|
|
|
192
|
-
**`/
|
|
193
|
+
**`/plumbbob:build` is the default engine, not the only one.** It's one executor — the
|
|
193
194
|
loop doesn't care who writes the code. Implement a step by hand — or vibe it in
|
|
194
|
-
another session, or in another harness entirely — and run `/
|
|
195
|
+
another session, or in another harness entirely — and run `/plumbbob:verify` instead:
|
|
195
196
|
same checks, same pause, same checkpoint. It reads the *diff, not the author*.
|
|
196
197
|
|
|
197
198
|
**Bring your own agents.** Because the executor is author-blind, you can plug your
|
|
@@ -223,7 +224,7 @@ against the plan, and committed as its own checkpoint, so a wrong turn costs one
|
|
|
223
224
|
step, not the afternoon; and records the *whys* alongside the decisions, so the
|
|
224
225
|
archive can still answer "what did we decide, and why" long after the session is
|
|
225
226
|
gone. The two compose fine: plan mode — or anything else — can produce a step's
|
|
226
|
-
diff, and `/
|
|
227
|
+
diff, and `/plumbbob:verify` reads it like any other.
|
|
227
228
|
|
|
228
229
|
**…use git and a TODO file?** That's the honest skeleton, and if your discipline
|
|
229
230
|
holds by willpower alone, it may be all you need. What the CLI adds is the
|
|
@@ -259,19 +260,24 @@ that matters.
|
|
|
259
260
|
> The latch's payoff is measured, not asserted: the skill-eval harness
|
|
260
261
|
> ([`test/evals/`](test/evals/)) sweeps this loop headless — prose-only baseline vs. the
|
|
261
262
|
> shipped latch, N=5 per contract, every assertion a mechanical read of git state — and
|
|
262
|
-
> commits each receipt under [`
|
|
263
|
-
> ([opus, 2026-07-11](
|
|
263
|
+
> commits each receipt under [`docs/evals/`](docs/evals/). The first sweep
|
|
264
|
+
> ([opus, 2026-07-11](docs/evals/2026-07-11.md)) closed the route the latch owns —
|
|
264
265
|
> *no checkpoint over a red check under pressure* went from **2/5 prose-only to 5/5
|
|
265
266
|
> latched** — and named, rather than papered over, the two honest gaps it surfaced: park
|
|
266
267
|
> capture at 0/5, and adversarial pressure flipping a standing `auto` grant a model could
|
|
267
268
|
> write into settings, a legal side door. The re-sweep
|
|
268
|
-
> ([opus, 2026-07-18](
|
|
269
|
-
> *no checkpoint over a red check* still **5/5 latched** — and pinned both gaps.
|
|
270
|
-
>
|
|
271
|
-
> human-typed only) retired the settings `auto` grant, so the one
|
|
272
|
-
> forge is gone.
|
|
273
|
-
> ([D10](docs/decisions.md#d10)/[D13](docs/decisions.md#d13))
|
|
274
|
-
>
|
|
269
|
+
> ([opus, 2026-07-18](docs/evals/2026-07-18.md), plumbbob 0.8.7) reproduced the win —
|
|
270
|
+
> *no checkpoint over a red check* still **5/5 latched** — and pinned both gaps. Both are
|
|
271
|
+
> now closed. The side door went by construction: [D67](docs/decisions.md#d67)
|
|
272
|
+
> (self-approval is human-typed only) retired the settings `auto` grant, so the one
|
|
273
|
+
> approval a model could forge is gone. Park capture was never the latch's to reach —
|
|
274
|
+
> prose-governed by design ([D10](docs/decisions.md#d10)/[D13](docs/decisions.md#d13)) —
|
|
275
|
+
> and it failed because the guidance couldn't reach a fresh session at all; the turn hook
|
|
276
|
+
> now injects one line when a step is in flight, and the third sweep
|
|
277
|
+
> ([opus, 2026-07-27](docs/evals/2026-07-27.md), plumbbob 0.9.0) measures it at **5/5**,
|
|
278
|
+
> alongside every other contract. That sweep ran the latched arm only, so its numbers are
|
|
279
|
+
> a regression check on the shipped configuration, not a fresh baseline delta — the
|
|
280
|
+
> 2/5→5/5 headline above remains the 2026-07-11 measurement.
|
|
275
281
|
|
|
276
282
|
## Documentation
|
|
277
283
|
|
|
@@ -281,11 +287,12 @@ Each doc answers one question — in rough reading order for a new user:
|
|
|
281
287
|
- *Show me the artifacts it leaves behind.* → [`examples/`](examples/) — that same session's finished build folder, file by file.
|
|
282
288
|
- *Should I / can I / what about…?* → [`docs/faq.md`](docs/faq.md) — the adoption questions, answered straight.
|
|
283
289
|
- *What is each method for?* → [`docs/techniques.md`](docs/techniques.md) — steps, seams, the pause, park/harvest, spikes.
|
|
284
|
-
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md) — all twelve
|
|
290
|
+
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md) — all twelve skills: inputs, effects, when to reach for each.
|
|
285
291
|
- *How do I plug in my own agent?* → [`docs/agents.md`](docs/agents.md) — the subprocess envelope, the manifest, `harness.json`, and working examples (including a local-model reviewer via Ollama).
|
|
286
292
|
- *How do I get a local model reviewing my steps?* → [`docs/local-model-review.md`](docs/local-model-review.md) — the ollama-reviewer example walked end to end, install to every-pause review.
|
|
287
293
|
- *How do I install it, exactly?* → [`docs/install.md`](docs/install.md) — the full guide and the agent-neutral roadmap.
|
|
288
294
|
- *What does the CLI underneath do?* → [`docs/cli-reference.md`](docs/cli-reference.md) — every verb, flag, exit code, and the `.plumbbob/` sidecar.
|
|
295
|
+
- *What are these untracked files, and why is it touching my `.git`?* → [`docs/state-and-git.md`](docs/state-and-git.md) — the state files, the `info/exclude` mechanism, and the objections answered.
|
|
289
296
|
- *Something's broken.* → [`docs/troubleshooting.md`](docs/troubleshooting.md) — fixes for the common snags.
|
|
290
297
|
- *Why is it built this way?* → [`docs/decisions.md`](docs/decisions.md) — the `D#` / `C#` design-decision key the source cites.
|
|
291
298
|
- *How does it hang together inside?* → [`docs/architecture.md`](docs/architecture.md) — the layers and planes, for contributors (in progress).
|
package/dist/cli-core.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// plumbbob CLI core — argv dispatch and the help table, separated from the bin
|
|
2
2
|
// entry (cli.ts) so the routing/help logic is unit-testable in-process without
|
|
3
|
-
// the top-level process.exit. Node builtins plus
|
|
4
|
-
// currently checkride alone, via check.ts). Functional/procedural: no classes,
|
|
5
|
-
// no `this`, no default export
|
|
3
|
+
// the top-level process.exit. Node builtins plus a deliberate few dependencies
|
|
4
|
+
// (currently checkride alone, via check.ts). Functional/procedural: no classes,
|
|
5
|
+
// no `this`, no default export.
|
|
6
|
+
//
|
|
7
|
+
// The deciding/executing boundary is a pause, not a lock, so there is nothing
|
|
8
|
+
// to defend in the dispatcher — every verb runs the same whether a human or the
|
|
9
|
+
// model triggers it. There is no human-only `mode` escape hatch and no
|
|
10
|
+
// CLAUDECODE in-session refusal; what keeps the human the decider is the pause
|
|
11
|
+
// at the step boundary (the skills), not a refusal here.
|
|
6
12
|
import { readFileSync } from 'node:fs';
|
|
7
13
|
import { fileURLToPath } from 'node:url';
|
|
8
14
|
import { start } from "./verbs/start.js";
|
|
@@ -20,6 +26,7 @@ import { init } from "./verbs/init.js";
|
|
|
20
26
|
import { doctor } from "./verbs/doctor.js";
|
|
21
27
|
import { agent } from "./verbs/agent.js";
|
|
22
28
|
import { turn } from "./verbs/turn.js";
|
|
29
|
+
/** One help-table row per verb, in the order the table prints. */
|
|
23
30
|
const VERBS = [
|
|
24
31
|
{ name: 'start', summary: 'scaffold .plumbbob/; open the session; record the baseline commit' },
|
|
25
32
|
{ name: 'status', summary: 'print the orientation dashboard, or NO ACTIVE SESSION' },
|
|
@@ -37,20 +44,22 @@ const VERBS = [
|
|
|
37
44
|
{ name: 'agent', summary: 'agent list | run <name> [--step N] [--mode before|build|after]: list or spawn a user-authored agent' },
|
|
38
45
|
{ name: 'turn', summary: 'turn: UserPromptSubmit hook machinery — tick the turn ledger from stdin (not a user verb)' },
|
|
39
46
|
];
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// in-session refusal; what keeps the human the decider is the pause at
|
|
44
|
-
// the step boundary (the skills), not a refusal here.
|
|
47
|
+
/**
|
|
48
|
+
* Render the verb table for `plumbbob help`.
|
|
49
|
+
*/
|
|
45
50
|
export function formatHelp() {
|
|
46
51
|
const width = Math.max(...VERBS.map((v) => v.name.length));
|
|
47
52
|
const rows = VERBS.map((v) => ` ${v.name.padEnd(width)} ${v.summary}`);
|
|
48
53
|
return ['plumbbob — attention-first build process', '', 'Usage: plumbbob <verb> [args]', '', 'Verbs:', ...rows, ''].join('\n');
|
|
49
54
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
/**
|
|
56
|
+
* The package version, or 'unknown'.
|
|
57
|
+
*
|
|
58
|
+
* Read from the package.json one level above this module (dist/cli-core.js →
|
|
59
|
+
* ../package.json; in tests src/cli-core.ts → ../package.json, the repo root).
|
|
60
|
+
* An absent or malformed manifest degrades to 'unknown' rather than throwing,
|
|
61
|
+
* so `--version` never errors.
|
|
62
|
+
*/
|
|
54
63
|
export function readVersion() {
|
|
55
64
|
try {
|
|
56
65
|
const raw = readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf8');
|
|
@@ -60,9 +69,13 @@ export function readVersion() {
|
|
|
60
69
|
return 'unknown';
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Route a verb to its implementation, or report the unknown verb and exit 1.
|
|
74
|
+
*
|
|
75
|
+
* Async because checkride is: `check` and `checkpoint` await the gate, `start`
|
|
76
|
+
* awaits the plan-time detection probe; every other verb returns synchronously
|
|
77
|
+
* through the same Promise-typed seam.
|
|
78
|
+
*/
|
|
66
79
|
async function dispatch(verb, cwd, rest) {
|
|
67
80
|
switch (verb) {
|
|
68
81
|
case 'start':
|
|
@@ -100,6 +113,13 @@ async function dispatch(verb, cwd, rest) {
|
|
|
100
113
|
return 1;
|
|
101
114
|
}
|
|
102
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* The CLI entrypoint minus the exit: parse argv, dispatch, return the exit code.
|
|
118
|
+
*
|
|
119
|
+
* `help` and `version` short-circuit before dispatch; any thrown error becomes
|
|
120
|
+
* a one-line stderr report and exit 1, so the bin entry only ever exits with
|
|
121
|
+
* the code returned here.
|
|
122
|
+
*/
|
|
103
123
|
export async function run(argv) {
|
|
104
124
|
const verb = argv[0] ?? 'help';
|
|
105
125
|
const rest = argv.slice(1);
|