plumbbob 0.9.3 → 0.10.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/.claude-plugin/plugin.json +1 -1
- package/README.md +92 -89
- package/dist/cli-core.js +25 -8
- package/dist/cli.js +1 -1
- package/dist/lib/agents.js +26 -26
- package/dist/lib/buildlog.js +11 -11
- package/dist/lib/buildlogsync.js +8 -8
- package/dist/lib/check.js +55 -22
- package/dist/lib/commitbody.js +72 -0
- package/dist/lib/commitmsg.js +7 -7
- package/dist/lib/git.js +44 -15
- package/dist/lib/intent.js +21 -20
- package/dist/lib/latch.js +19 -19
- package/dist/lib/orient.js +36 -17
- package/dist/lib/reentry.js +70 -0
- package/dist/lib/settings.js +16 -16
- package/dist/lib/sidecar.js +54 -54
- package/dist/lib/templates.js +1 -1
- package/dist/verbs/agent.js +27 -27
- package/dist/verbs/build.js +9 -9
- package/dist/verbs/check.js +6 -6
- package/dist/verbs/checkpoint.js +48 -47
- package/dist/verbs/doctor.js +31 -30
- package/dist/verbs/finish.js +28 -41
- package/dist/verbs/handoff.js +9 -8
- package/dist/verbs/init.js +9 -9
- package/dist/verbs/park.js +3 -3
- package/dist/verbs/recover.js +297 -0
- package/dist/verbs/revert.js +13 -13
- package/dist/verbs/spike.js +25 -19
- package/dist/verbs/start.js +49 -19
- package/dist/verbs/status.js +8 -8
- package/dist/verbs/turn.js +16 -16
- package/dist/verbs/use.js +4 -4
- package/hooks/post-edit.sh +4 -4
- package/hooks/pre-bash-commit.sh +3 -3
- package/node_modules/checkride/.claude-plugin/plugin.json +11 -0
- package/node_modules/checkride/CHANGELOG.md +1404 -0
- package/node_modules/checkride/LICENSE +201 -21
- package/node_modules/checkride/README.md +197 -38
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts +15 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts.map +1 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js +17 -0
- package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js.map +1 -0
- package/node_modules/checkride/dist/adapters.d.ts +30 -10
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +62 -23
- package/node_modules/checkride/dist/adapters.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/claude.d.ts +88 -0
- package/node_modules/checkride/dist/agent-setup/claude.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/claude.js +305 -0
- package/node_modules/checkride/dist/agent-setup/claude.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts +43 -0
- package/node_modules/checkride/dist/agent-setup/command.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/command.js +77 -0
- package/node_modules/checkride/dist/agent-setup/command.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts +69 -0
- package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js +247 -0
- package/node_modules/checkride/dist/agent-setup/cursor.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts +50 -0
- package/node_modules/checkride/dist/agent-setup/files.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/files.js +80 -0
- package/node_modules/checkride/dist/agent-setup/files.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts +101 -0
- package/node_modules/checkride/dist/agent-setup/harness.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/harness.js +93 -0
- package/node_modules/checkride/dist/agent-setup/harness.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/hook.d.ts +45 -52
- package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.js +64 -95
- package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.d.ts +10 -4
- package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.js +9 -4
- package/node_modules/checkride/dist/agent-setup/index.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts +81 -0
- package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js +604 -0
- package/node_modules/checkride/dist/agent-setup/scripts.js.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts +31 -0
- package/node_modules/checkride/dist/agent-setup/skills.d.ts.map +1 -0
- package/node_modules/checkride/dist/agent-setup/skills.js +56 -0
- package/node_modules/checkride/dist/agent-setup/skills.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts +30 -0
- package/node_modules/checkride/dist/artifacts/configured.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/configured.js +45 -0
- package/node_modules/checkride/dist/artifacts/configured.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts +33 -0
- package/node_modules/checkride/dist/artifacts/format.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/format.js +56 -0
- package/node_modules/checkride/dist/artifacts/format.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts +32 -0
- package/node_modules/checkride/dist/artifacts/freshness.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/freshness.js +37 -0
- package/node_modules/checkride/dist/artifacts/freshness.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts +22 -0
- package/node_modules/checkride/dist/artifacts/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/index.js +19 -0
- package/node_modules/checkride/dist/artifacts/index.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts +31 -0
- package/node_modules/checkride/dist/artifacts/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/json.js +47 -0
- package/node_modules/checkride/dist/artifacts/json.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts +60 -0
- package/node_modules/checkride/dist/artifacts/raw.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/raw.js +91 -0
- package/node_modules/checkride/dist/artifacts/raw.js.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts +69 -0
- package/node_modules/checkride/dist/artifacts/summary.d.ts.map +1 -0
- package/node_modules/checkride/dist/artifacts/summary.js +108 -0
- package/node_modules/checkride/dist/artifacts/summary.js.map +1 -0
- package/node_modules/checkride/dist/atomic.d.ts +16 -1
- package/node_modules/checkride/dist/atomic.d.ts.map +1 -1
- package/node_modules/checkride/dist/atomic.js +25 -3
- package/node_modules/checkride/dist/atomic.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.d.ts +9 -5
- package/node_modules/checkride/dist/baseline/fallow.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.js +163 -60
- package/node_modules/checkride/dist/baseline/fallow.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +20 -11
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.js +73 -23
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
- package/node_modules/checkride/dist/baseline/history.d.ts +98 -0
- package/node_modules/checkride/dist/baseline/history.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/history.js +232 -0
- package/node_modules/checkride/dist/baseline/history.js.map +1 -0
- package/node_modules/checkride/dist/baseline/index.d.ts +7 -5
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/index.js +5 -4
- package/node_modules/checkride/dist/baseline/index.js.map +1 -1
- package/node_modules/checkride/dist/baseline/store.d.ts +41 -10
- package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/store.js +65 -24
- package/node_modules/checkride/dist/baseline/store.js.map +1 -1
- package/node_modules/checkride/dist/baseline-command.d.ts +5 -5
- package/node_modules/checkride/dist/baseline-command.js +7 -7
- package/node_modules/checkride/dist/baseline-command.js.map +1 -1
- package/node_modules/checkride/dist/cli.d.ts +21 -4
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +350 -36
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +114 -9
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +142 -23
- package/node_modules/checkride/dist/config.js.map +1 -1
- package/node_modules/checkride/dist/digest/digest.d.ts +5 -5
- package/node_modules/checkride/dist/digest/digest.js +6 -6
- package/node_modules/checkride/dist/digest/index.d.ts +2 -2
- package/node_modules/checkride/dist/digest/index.js +2 -2
- package/node_modules/checkride/dist/doctor.d.ts +27 -6
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +231 -27
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/gate.d.ts +180 -0
- package/node_modules/checkride/dist/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/gate.js +617 -0
- package/node_modules/checkride/dist/gate.js.map +1 -0
- package/node_modules/checkride/dist/init.d.ts +79 -12
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +385 -81
- package/node_modules/checkride/dist/init.js.map +1 -1
- package/node_modules/checkride/dist/json.d.ts +21 -0
- package/node_modules/checkride/dist/json.d.ts.map +1 -0
- package/node_modules/checkride/dist/json.js +21 -0
- package/node_modules/checkride/dist/json.js.map +1 -0
- package/node_modules/checkride/dist/links.d.ts +31 -5
- package/node_modules/checkride/dist/links.d.ts.map +1 -1
- package/node_modules/checkride/dist/links.js +141 -32
- package/node_modules/checkride/dist/links.js.map +1 -1
- package/node_modules/checkride/dist/node-pin.d.ts +129 -0
- package/node_modules/checkride/dist/node-pin.d.ts.map +1 -0
- package/node_modules/checkride/dist/node-pin.js +211 -0
- package/node_modules/checkride/dist/node-pin.js.map +1 -0
- package/node_modules/checkride/dist/orchestrator.d.ts +53 -10
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +312 -113
- package/node_modules/checkride/dist/orchestrator.js.map +1 -1
- package/node_modules/checkride/dist/pack.d.ts +8 -9
- package/node_modules/checkride/dist/pack.d.ts.map +1 -1
- package/node_modules/checkride/dist/pack.js +53 -17
- package/node_modules/checkride/dist/pack.js.map +1 -1
- package/node_modules/checkride/dist/pm/detect.d.ts +6 -1
- package/node_modules/checkride/dist/pm/detect.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/detect.js +6 -1
- package/node_modules/checkride/dist/pm/detect.js.map +1 -1
- package/node_modules/checkride/dist/pm/index.d.ts +7 -2
- package/node_modules/checkride/dist/pm/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/index.js +6 -2
- package/node_modules/checkride/dist/pm/index.js.map +1 -1
- package/node_modules/checkride/dist/pm/launch.d.ts +72 -0
- package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/launch.js +108 -0
- package/node_modules/checkride/dist/pm/launch.js.map +1 -0
- package/node_modules/checkride/dist/pm/tools.d.ts +73 -0
- package/node_modules/checkride/dist/pm/tools.d.ts.map +1 -0
- package/node_modules/checkride/dist/pm/tools.js +124 -0
- package/node_modules/checkride/dist/pm/tools.js.map +1 -0
- package/node_modules/checkride/dist/pm/translate.d.ts +35 -9
- package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/translate.js +78 -18
- package/node_modules/checkride/dist/pm/translate.js.map +1 -1
- package/node_modules/checkride/dist/proc.d.ts +30 -0
- package/node_modules/checkride/dist/proc.d.ts.map +1 -0
- package/node_modules/checkride/dist/proc.js +42 -0
- package/node_modules/checkride/dist/proc.js.map +1 -0
- package/node_modules/checkride/dist/qa/cli.d.ts +20 -0
- package/node_modules/checkride/dist/qa/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/cli.js +24 -0
- package/node_modules/checkride/dist/qa/cli.js.map +1 -0
- package/node_modules/checkride/dist/qa/dead.d.ts +39 -0
- package/node_modules/checkride/dist/qa/dead.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dead.js +88 -0
- package/node_modules/checkride/dist/qa/dead.js.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts +45 -0
- package/node_modules/checkride/dist/qa/dupes.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/dupes.js +62 -0
- package/node_modules/checkride/dist/qa/dupes.js.map +1 -0
- package/node_modules/checkride/dist/qa/health.d.ts +85 -0
- package/node_modules/checkride/dist/qa/health.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/health.js +109 -0
- package/node_modules/checkride/dist/qa/health.js.map +1 -0
- package/node_modules/checkride/dist/qa/index.d.ts +23 -0
- package/node_modules/checkride/dist/qa/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/index.js +22 -0
- package/node_modules/checkride/dist/qa/index.js.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts +80 -0
- package/node_modules/checkride/dist/qa/mutation.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/mutation.js +195 -0
- package/node_modules/checkride/dist/qa/mutation.js.map +1 -0
- package/node_modules/checkride/dist/qa/qa.d.ts +71 -0
- package/node_modules/checkride/dist/qa/qa.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/qa.js +158 -0
- package/node_modules/checkride/dist/qa/qa.js.map +1 -0
- package/node_modules/checkride/dist/qa/read.d.ts +40 -0
- package/node_modules/checkride/dist/qa/read.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/read.js +47 -0
- package/node_modules/checkride/dist/qa/read.js.map +1 -0
- package/node_modules/checkride/dist/qa/render.d.ts +26 -0
- package/node_modules/checkride/dist/qa/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/qa/render.js +310 -0
- package/node_modules/checkride/dist/qa/render.js.map +1 -0
- package/node_modules/checkride/dist/recover.d.ts +48 -0
- package/node_modules/checkride/dist/recover.d.ts.map +1 -0
- package/node_modules/checkride/dist/recover.js +220 -0
- package/node_modules/checkride/dist/recover.js.map +1 -0
- package/node_modules/checkride/dist/security.d.ts +45 -0
- package/node_modules/checkride/dist/security.d.ts.map +1 -0
- package/node_modules/checkride/dist/security.js +86 -0
- package/node_modules/checkride/dist/security.js.map +1 -0
- package/node_modules/checkride/dist/smoke.d.ts +6 -6
- package/node_modules/checkride/dist/smoke.js +6 -6
- package/node_modules/checkride/dist/snippets.d.ts +27 -30
- package/node_modules/checkride/dist/snippets.d.ts.map +1 -1
- package/node_modules/checkride/dist/snippets.js +26 -30
- package/node_modules/checkride/dist/snippets.js.map +1 -1
- package/node_modules/checkride/dist/tool-json.d.ts +33 -0
- package/node_modules/checkride/dist/tool-json.d.ts.map +1 -0
- package/node_modules/checkride/dist/tool-json.js +58 -0
- package/node_modules/checkride/dist/tool-json.js.map +1 -0
- package/node_modules/checkride/dist/triage/cli.d.ts +21 -0
- package/node_modules/checkride/dist/triage/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/cli.js +26 -0
- package/node_modules/checkride/dist/triage/cli.js.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts +51 -0
- package/node_modules/checkride/dist/triage/doctor-fold.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js +88 -0
- package/node_modules/checkride/dist/triage/doctor-fold.js.map +1 -0
- package/node_modules/checkride/dist/triage/env.d.ts +54 -0
- package/node_modules/checkride/dist/triage/env.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/env.js +81 -0
- package/node_modules/checkride/dist/triage/env.js.map +1 -0
- package/node_modules/checkride/dist/triage/gate.d.ts +61 -0
- package/node_modules/checkride/dist/triage/gate.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/gate.js +121 -0
- package/node_modules/checkride/dist/triage/gate.js.map +1 -0
- package/node_modules/checkride/dist/triage/index.d.ts +22 -0
- package/node_modules/checkride/dist/triage/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/index.js +20 -0
- package/node_modules/checkride/dist/triage/index.js.map +1 -0
- package/node_modules/checkride/dist/triage/render.d.ts +19 -0
- package/node_modules/checkride/dist/triage/render.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/render.js +419 -0
- package/node_modules/checkride/dist/triage/render.js.map +1 -0
- package/node_modules/checkride/dist/triage/triage.d.ts +83 -0
- package/node_modules/checkride/dist/triage/triage.d.ts.map +1 -0
- package/node_modules/checkride/dist/triage/triage.js +131 -0
- package/node_modules/checkride/dist/triage/triage.js.map +1 -0
- package/node_modules/checkride/package.json +18 -15
- package/node_modules/checkride/schema/checkride.config.schema.json +70 -5
- package/node_modules/checkride/schema/checkride.summary.schema.json +1 -1
- package/node_modules/checkride/skills/check/SKILL.md +265 -0
- package/node_modules/checkride/skills/qa/SKILL.md +231 -0
- package/node_modules/checkride/templates/shared/cspell.json +1 -0
- package/node_modules/checkride/templates/shared/oxlintrc.json +1 -1
- package/node_modules/checkride/templates/shared/styles/Repo/Drift.yml +41 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Latin.yml +14 -0
- package/node_modules/checkride/templates/shared/styles/Repo/LyHyphen.yml +28 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Minted.yml +33 -0
- package/node_modules/checkride/templates/shared/styles/Repo/ThereIs.yml +16 -0
- package/node_modules/checkride/templates/shared/styles/Repo/Weasel.yml +26 -0
- package/node_modules/checkride/templates/shared/vale.ini +34 -0
- package/package.json +10 -9
- package/skills/build/SKILL.md +85 -76
- package/skills/doctor/SKILL.md +11 -11
- package/skills/finish/SKILL.md +21 -18
- package/skills/harvest/SKILL.md +13 -11
- package/skills/park/SKILL.md +10 -10
- package/skills/plan/SKILL.md +69 -59
- package/skills/recover/SKILL.md +28 -0
- package/skills/refine/SKILL.md +21 -18
- package/skills/revert/SKILL.md +6 -6
- package/skills/spike/SKILL.md +9 -9
- package/skills/status/SKILL.md +5 -5
- package/skills/step/SKILL.md +20 -15
- package/skills/verify/SKILL.md +56 -46
- package/templates/build-log.md +7 -7
- package/templates/intent.md +52 -41
- package/templates/spike-report.md +10 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plumbbob",
|
|
3
3
|
"displayName": "PlumbBob",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.10.0",
|
|
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,45 +10,46 @@
|
|
|
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
|
|
13
|
+
PlumbBob is a Claude Code plugin (thirteen 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
|
|
17
|
-
committed. It's built for the small-to-medium work that fills most days
|
|
18
|
-
bug, a refactor
|
|
17
|
+
committed. It's built for the small-to-medium work that fills most days (a feature, a
|
|
18
|
+
bug, a refactor) where a fully autonomous build is overkill but freestyle prompting
|
|
19
19
|
leaves you dragged behind the model, reacting instead of deciding.
|
|
20
20
|
|
|
21
21
|
> Establish *plumb* before you build. The LLM is a hand, not a head.
|
|
22
22
|
|
|
23
23
|
Its one law is **vibe to execute, never vibe to decide**: the human owns every
|
|
24
24
|
decision, the LLM owns the labor, and the boundary between them is a **pause you
|
|
25
|
-
advance**, not a wall that refuses you. The *why* behind that
|
|
26
|
-
resource
|
|
25
|
+
advance**, not a wall that refuses you. The *why* behind that (attention as the scarce
|
|
26
|
+
resource) is in [`docs/attention-first-development.md`](docs/attention-first-development.md).
|
|
27
27
|
PlumbBob is the layer below [Ridgeline](https://github.com/robmclarty/ridgeline): where
|
|
28
28
|
Ridgeline runs large, settled work autonomously without you, PlumbBob keeps you in the
|
|
29
29
|
driver's seat for the work your judgment has to steer. This repository was built using
|
|
30
|
-
PlumbBob,
|
|
30
|
+
PlumbBob itself, running its own loop.
|
|
31
31
|
|
|
32
32
|
## What a prompt can't replicate
|
|
33
33
|
|
|
34
34
|
A system prompt can *ask* a model to plan first and stop for review. What it can't do is
|
|
35
|
-
**hold the line when the model doesn't
|
|
35
|
+
**hold the line when the model doesn't**, and that mechanical half is what PlumbBob adds
|
|
36
36
|
under the skills. Five deterministic edges, enforced by the CLI and git rather than by the
|
|
37
37
|
model's goodwill:
|
|
38
38
|
|
|
39
39
|
- **A gate that refuses red.** `checkpoint` won't record a step while the check gate is
|
|
40
|
-
red, and `start` refuses a dirty tree
|
|
40
|
+
red, and `start` refuses a dirty tree: the [checkride](https://www.npmjs.com/package/checkride)
|
|
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
|
-
recorded baseline
|
|
43
|
+
recorded baseline: a ledger of checkpoints, not one undifferentiated diff at the end.
|
|
44
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
|
-
- **A build record that rides the PR.** The tracked `builds/<slug>/` folder
|
|
47
|
-
checkpoints, report
|
|
46
|
+
- **A build record that rides the PR.** The tracked `builds/<slug>/` folder (intent, log,
|
|
47
|
+
checkpoints, report) merges into `main` with the branch instead of dying with the
|
|
48
48
|
worktree; the archive never destroys.
|
|
49
49
|
- **The approval latch.** `checkpoint` refuses to land a step until the harness records a
|
|
50
|
-
human turn since that step began ([D64
|
|
51
|
-
|
|
50
|
+
human turn since that step began ([D64 (approval-latch)](docs/decisions.md#d64)–[D66
|
|
51
|
+
(oob-commits-surfaced)](docs/decisions.md#d66), the ledger-plane enforcement), so the
|
|
52
|
+
model can't self-commit past you: the refusal *is* the pause.
|
|
52
53
|
|
|
53
54
|
The planning surface is the on-ramp; these five are the floor under it. And the latch's
|
|
54
55
|
payoff is [measured, not asserted](#why-not-just), not just claimed. **Guidance on the
|
|
@@ -63,7 +64,7 @@ work, a latch on the record.**
|
|
|
63
64
|
Everything the model must stay true to lives in one file, the build's `intent.md`
|
|
64
65
|
(under `.plumbbob/builds/<slug>/`), written before any code: the **Frame** (the problem, what done looks like, what you're
|
|
65
66
|
explicitly *not* doing), the **Decisions** and **Constraints** (the settled calls, each
|
|
66
|
-
with its *because*), and the **Steps
|
|
67
|
+
with its *because*), and the **Steps**: a numbered list where every step carries a
|
|
67
68
|
**done-when** (a checkable finish line, ideally a test) and a **seam** (the files it's
|
|
68
69
|
expected to touch).
|
|
69
70
|
|
|
@@ -75,16 +76,16 @@ expected to touch).
|
|
|
75
76
|
/plumbbob:finish report what shipped and why, final commit, clear (once)
|
|
76
77
|
```
|
|
77
78
|
|
|
78
|
-
Nothing is locked and nothing refuses you
|
|
79
|
+
Nothing is locked and nothing refuses you: the loop does a step's labor, pulls up to
|
|
79
80
|
the line, and waits for you to advance it. **You are the clock.**
|
|
80
81
|
|
|
81
82
|
## Install
|
|
82
83
|
|
|
83
|
-
PlumbBob installs **once, globally**
|
|
84
|
+
PlumbBob installs **once, globally** (like `gh` or your dotfiles). Two ways work;
|
|
84
85
|
pick one (both register a Claude Code plugin named `plumbbob`, so running both
|
|
85
86
|
collides).
|
|
86
87
|
|
|
87
|
-
**Marketplace plugin
|
|
88
|
+
**Marketplace plugin**: Claude Code installs the published `plumbbob` package for you
|
|
88
89
|
(skills, hook, and the CLI on PATH), so you run no `npm i -g` and no `init`:
|
|
89
90
|
|
|
90
91
|
```text
|
|
@@ -92,7 +93,7 @@ collides).
|
|
|
92
93
|
/plugin install plumbbob@robmclarty
|
|
93
94
|
```
|
|
94
95
|
|
|
95
|
-
**npm global + `init
|
|
96
|
+
**npm global + `init`**: installs the CLI, then links the skills and hook into Claude
|
|
96
97
|
Code in place:
|
|
97
98
|
|
|
98
99
|
```sh
|
|
@@ -101,15 +102,15 @@ plumbbob init # link it into Claude Code; --uninstall to undo
|
|
|
101
102
|
```
|
|
102
103
|
|
|
103
104
|
Restart Claude Code (or `/reload-plugins`) to activate, then run `plumbbob doctor`
|
|
104
|
-
(or `/plumbbob:doctor` in-session) to confirm the wiring. The full guide
|
|
105
|
-
per-project sessions, the agent-neutral roadmap
|
|
105
|
+
(or `/plumbbob:doctor` in-session) to confirm the wiring. The full guide (namespacing,
|
|
106
|
+
per-project sessions, the agent-neutral roadmap) is in
|
|
106
107
|
[`docs/install.md`](docs/install.md).
|
|
107
108
|
|
|
108
109
|
## Your first session
|
|
109
110
|
|
|
110
111
|
In Claude Code, inside any git repo with a clean tree:
|
|
111
112
|
|
|
112
|
-
1. **Plan.** Fire `/plumbbob:plan` and give it whatever you have
|
|
113
|
+
1. **Plan.** Fire `/plumbbob:plan` and give it whatever you have: nothing (it interviews
|
|
113
114
|
you), a rough line (`/plumbbob:plan rate-limit POST /login, 5/min/IP, return 429`), or a
|
|
114
115
|
path to a spec file. Together you fill the build's `intent.md`. No code is written
|
|
115
116
|
yet.
|
|
@@ -120,17 +121,17 @@ In Claude Code, inside any git repo with a clean tree:
|
|
|
120
121
|
PAUSE — read the diff as an editor. Approve to checkpoint, or send fixes.
|
|
121
122
|
```
|
|
122
123
|
|
|
123
|
-
(The check gate is [checkride](https://www.npmjs.com/package/checkride)
|
|
124
|
+
(The check gate is [checkride](https://www.npmjs.com/package/checkride), one
|
|
124
125
|
run across the tools your repo already configures: types, lint, tests, dead
|
|
125
126
|
code, docs. To gate through your own command instead, set the `"check"` key in
|
|
126
|
-
`.plumbbob/settings.json`,
|
|
127
|
-
3. **Approve
|
|
128
|
-
it done, and returns to the boundary. Fire `/plumbbob:build` again for the next step
|
|
127
|
+
`.plumbbob/settings.json`, for example `"check": "npm test"`.)
|
|
128
|
+
3. **Approve**, or send fixes. On your OK it commits the step as a checkpoint, marks
|
|
129
|
+
it done, and returns to the boundary. Fire `/plumbbob:build` again for the next step:
|
|
129
130
|
re-firing it *is* the clock tick. Whenever you lose the thread, `/plumbbob:status` shows
|
|
130
131
|
where you are and names the next move.
|
|
131
132
|
4. **Finish.** When the last step is done, `/plumbbob:finish` writes a report of what shipped
|
|
132
133
|
and why into the build's tracked folder, makes the final commit, and clears the slate
|
|
133
|
-
for the next goal. The folder rides the branch into the PR
|
|
134
|
+
for the next goal. The folder rides the branch into the PR: the build's record merges
|
|
134
135
|
into `main` instead of dying with the worktree.
|
|
135
136
|
|
|
136
137
|
A mid-build "ooh, what if…" never derails the step: `/plumbbob:park` captures it to a list
|
|
@@ -140,23 +141,23 @@ end, with the real output at every stage, is in
|
|
|
140
141
|
|
|
141
142
|
## The skills
|
|
142
143
|
|
|
143
|
-
You drive the whole loop from your IDE with `/plumbbob:*` skills
|
|
144
|
+
You drive the whole loop from your IDE with `/plumbbob:*` skills: no step numbers to
|
|
144
145
|
remember, no raw CLI to type. Every skill is `disable-model-invocation`, so *you* fire
|
|
145
146
|
every move, and `/plumbbob:status` always names your next one. (Claude Code namespaces
|
|
146
147
|
them under the plugin, so the command is `/plumbbob:plan`. The bare `/plan` reaches it
|
|
147
|
-
too
|
|
148
|
+
too, but only where nothing else owns that name, and four of the thirteen share one with
|
|
148
149
|
a Claude Code built-in, so these docs write the full form.)
|
|
149
150
|
|
|
150
|
-
**The happy path
|
|
151
|
+
**The happy path**: the three moves every session makes; many sessions need
|
|
151
152
|
nothing else:
|
|
152
153
|
|
|
153
154
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
154
155
|
|------------------------------------|------|
|
|
155
|
-
| `/plumbbob:plan` | plan the whole goal
|
|
156
|
-
| `/plumbbob:build` | implement the next planned step, then verify it to the pause
|
|
157
|
-
| `/plumbbob:finish` | finish up
|
|
156
|
+
| `/plumbbob:plan` | plan the whole goal: open the session and author intent's Frame, Decisions, Constraints, **and all Steps** |
|
|
157
|
+
| `/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 |
|
|
158
|
+
| `/plumbbob:finish` | finish up: write the report, make the final commit, clear for a fresh goal |
|
|
158
159
|
|
|
159
|
-
**Plan-shaping moves
|
|
160
|
+
**Plan-shaping moves**: optional, for when the plan needs work mid-flight:
|
|
160
161
|
|
|
161
162
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
162
163
|
|------------------------------------|------|
|
|
@@ -164,48 +165,49 @@ nothing else:
|
|
|
164
165
|
| `/plumbbob:refine` | attack the frame for holes, or repair a drifted plan |
|
|
165
166
|
| `/plumbbob:spike` | throwaway worktree experiment for a fork the plan can't settle |
|
|
166
167
|
|
|
167
|
-
**Helpers
|
|
168
|
+
**Helpers**: orient, verify, recover, diagnose:
|
|
168
169
|
|
|
169
170
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
170
171
|
|------------------------------------|------|
|
|
171
|
-
| `/plumbbob:status` | orient
|
|
172
|
-
| `/plumbbob:verify` | the tick, standalone
|
|
173
|
-
| `/plumbbob:revert` |
|
|
172
|
+
| `/plumbbob:status` | orient: where you are, the next step's done-when and seam, and the next move |
|
|
173
|
+
| `/plumbbob:verify` | the tick, standalone: check → self-review → validate → **PAUSE** → checkpoint, for a diff `/plumbbob:build` didn't write |
|
|
174
|
+
| `/plumbbob:revert` | rewind: `git reset --hard` to a recorded checkpoint |
|
|
175
|
+
| `/plumbbob:recover` | reconcile the session's own state when the dashboard looks wrong |
|
|
174
176
|
| `/plumbbob:doctor` | check the install from inside a session |
|
|
175
177
|
|
|
176
|
-
**Capture
|
|
178
|
+
**Capture**: the park/harvest loop for mid-build ideas:
|
|
177
179
|
|
|
178
180
|
| Skill <img alt="" width="110" height="1"> | Does |
|
|
179
181
|
|------------------------------------|------|
|
|
180
182
|
| `/plumbbob:park` | capture a mid-build idea without chasing it |
|
|
181
183
|
| `/plumbbob:harvest` | triage parked ideas between steps (blocker / tangent / pivot) |
|
|
182
184
|
|
|
183
|
-
All
|
|
185
|
+
All thirteen, with inputs and effects, are in
|
|
184
186
|
[`docs/skills-reference.md`](docs/skills-reference.md).
|
|
185
187
|
|
|
186
188
|
Under the skills ships a lean `plumbbob` CLI (the mechanical verbs the
|
|
187
189
|
skills shell out to), one session-gated post-edit hook (non-blocking lint feedback in
|
|
188
|
-
flow), and a `.plumbbob/` sidecar you can open and edit by hand at any time
|
|
190
|
+
flow), and a `.plumbbob/` sidecar you can open and edit by hand at any time: a tracked
|
|
189
191
|
`builds/<slug>/` folder per build (`intent.md`, `build-log.md`, `checkpoints`, `report.md`)
|
|
190
192
|
that rides the branch into the PR, plus an untracked control plane (`settings.local.json`,
|
|
191
193
|
the session sentinel, the in-flight markers).
|
|
192
194
|
|
|
193
|
-
**`/plumbbob:build` is the default engine, not the only one.** It's one executor
|
|
194
|
-
loop doesn't care who writes the code. Implement a step by hand
|
|
195
|
-
another session, or in another harness entirely
|
|
195
|
+
**`/plumbbob:build` is the default engine, not the only one.** It's one executor: the
|
|
196
|
+
loop doesn't care who writes the code. Implement a step by hand (or vibe it in
|
|
197
|
+
another session, or in another harness entirely) and run `/plumbbob:verify` instead:
|
|
196
198
|
same checks, same pause, same checkpoint. It reads the *diff, not the author*.
|
|
197
199
|
|
|
198
200
|
**Bring your own agents.** Because the executor is author-blind, you can plug your
|
|
199
201
|
own in. A **user-authored agent** is any executable that speaks one small JSON
|
|
200
202
|
envelope; drop it under `.plumbbob/agents/`, bind it to a step's `before`, `build`,
|
|
201
203
|
or `after` slot in the build's `harness.json`, and PlumbBob runs it through the same
|
|
202
|
-
pause
|
|
204
|
+
pause, with **no way for it to advance the loop** (checkride still gates, you're
|
|
203
205
|
still the clock). The full contract for authors, with a copy-paste example, is in
|
|
204
206
|
[`docs/agents.md`](docs/agents.md).
|
|
205
207
|
|
|
206
208
|
## Why "PlumbBob"
|
|
207
209
|
|
|
208
|
-
The name is the method. A plumb bob is a weight on a string
|
|
210
|
+
The name is the method. A plumb bob is a weight on a string; gravity pulls it into a
|
|
209
211
|
perfectly straight vertical line, the builder's oldest reference for *true*: the fixed
|
|
210
212
|
mark you hold the work against so it never drifts out of square. PlumbBob hangs your
|
|
211
213
|
**intent** as that line and keeps every step aligned to it, so the build stays plumb
|
|
@@ -215,90 +217,91 @@ with what you decided instead of wandering off behind the model.
|
|
|
215
217
|
|
|
216
218
|
The questions a skeptic should ask, answered straight.
|
|
217
219
|
|
|
218
|
-
**…use plan mode?** Plan mode is the same instinct
|
|
220
|
+
**…use plan mode?** Plan mode is the same instinct (decide before executing),
|
|
219
221
|
scoped to one session. The plan lives in the chat, so it fades with the context
|
|
220
222
|
window, and the approval gates the *start* of the work, not each increment of it.
|
|
221
223
|
PlumbBob puts the plan in a file in your repo that survives compaction, restarts,
|
|
222
|
-
and next week; moves the approval to **every step**
|
|
223
|
-
against the plan, and committed as its own checkpoint, so a wrong turn costs one
|
|
224
|
+
and next week; moves the approval to **every step** (each checked, reviewed
|
|
225
|
+
against the plan, and committed as its own checkpoint), so a wrong turn costs one
|
|
224
226
|
step, not the afternoon; and records the *whys* alongside the decisions, so the
|
|
225
227
|
archive can still answer "what did we decide, and why" long after the session is
|
|
226
|
-
gone. The two compose fine: plan mode
|
|
228
|
+
gone. The two compose fine: plan mode (or anything else) can produce a step's
|
|
227
229
|
diff, and `/plumbbob:verify` reads it like any other.
|
|
228
230
|
|
|
229
231
|
**…use git and a TODO file?** That's the honest skeleton, and if your discipline
|
|
230
232
|
holds by willpower alone, it may be all you need. What the CLI adds is the
|
|
231
|
-
[mechanical half of the discipline](#what-a-prompt-cant-replicate)
|
|
232
|
-
top
|
|
233
|
+
[mechanical half of the discipline](#what-a-prompt-cant-replicate) (the five edges up
|
|
234
|
+
top), so willpower is spent only at the pause. The one not on that list: a status
|
|
233
235
|
dashboard re-injected into every skill, so the model re-orients on each move without you
|
|
234
236
|
re-explaining the state.
|
|
235
237
|
|
|
236
|
-
**…wait for a vendor to ship this natively?** They're converging on it
|
|
237
|
-
modes, spec kits, native checkpoints
|
|
238
|
+
**…wait for a vendor to ship this natively?** They're converging on it (plan
|
|
239
|
+
modes, spec kits, native checkpoints), and that convergence is evidence *for* the
|
|
238
240
|
premise. PlumbBob is deliberately thin against that future: the artifacts are
|
|
239
241
|
plain markdown and ordinary git commits in your own repo, the CLI is lean
|
|
240
242
|
(node builtins plus one deliberate dependency), and nothing locks you in. The
|
|
241
|
-
investment is small
|
|
242
|
-
skills over a plain-markdown sidecar, learnable in an afternoon
|
|
243
|
+
investment is small (thirteen
|
|
244
|
+
skills over a plain-markdown sidecar, learnable in an afternoon), and what you're
|
|
243
245
|
actually learning is the method: decisions before code, one verified step at a
|
|
244
246
|
time, capture instead of chase. That transfers to whatever tool wins. If
|
|
245
247
|
something better ships, you walk away with your archives and your habits intact.
|
|
246
248
|
|
|
247
|
-
**…admit the pause is unenforceable?** On the **work** plane, yes
|
|
248
|
-
([D10](docs/decisions.md#d10)/[D13](docs/decisions.md#d13) in
|
|
249
|
+
**…admit the pause is unenforceable?** On the **work** plane, yes, on purpose
|
|
250
|
+
([D10 (pause-not-lock)](docs/decisions.md#d10)/[D13 (no-edit-guards)](docs/decisions.md#d13) in
|
|
249
251
|
[`docs/decisions.md`](docs/decisions.md)): a hard lock on every edit buys ritual, not
|
|
250
252
|
control, because a determined model routes around it and a denial mid-thought leaves no
|
|
251
253
|
legal move. But the **record** is a different plane, and there the tick *is* latched
|
|
252
|
-
([D64–D66](docs/decisions.md#
|
|
253
|
-
records a human turn since that step began, so the agent cannot self-commit past you
|
|
254
|
+
([D64 (approval-latch)](docs/decisions.md#d64)–[D66 (oob-commits-surfaced)](docs/decisions.md#d66)): `checkpoint` refuses to land a step until the harness
|
|
255
|
+
records a human turn since that step began, so the agent cannot self-commit past you:
|
|
254
256
|
the refusal simply *is* the pause. It extends the [deterministic edges above](#what-a-prompt-cant-replicate)
|
|
255
257
|
to the one boundary the product is named after, while leaving human what must be human:
|
|
256
258
|
you, reading the diff. And when a raw commit does slip the ledger, `status` says so and the
|
|
257
|
-
checkpoint record makes recovery one command
|
|
259
|
+
checkpoint record makes recovery one command; cheap recovery, not a cage, is the control
|
|
258
260
|
that matters.
|
|
259
261
|
|
|
260
262
|
> The latch's payoff is measured, not asserted: the skill-eval harness
|
|
261
|
-
> ([`test/evals/`](test/evals/)) sweeps this loop headless
|
|
262
|
-
> shipped latch, N=5 per contract, every assertion a mechanical read of git state
|
|
263
|
+
> ([`test/evals/`](test/evals/)) sweeps this loop headless (prose-only baseline vs. the
|
|
264
|
+
> shipped latch, N=5 per contract, every assertion a mechanical read of git state) and
|
|
263
265
|
> 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
|
|
265
|
-
> *no checkpoint over a red check under pressure* went from **2/5 prose-only to 5/5
|
|
266
|
-
> latched**
|
|
266
|
+
> ([opus, 2026-07-11](docs/evals/2026-07-11.md)) closed the route the latch owns
|
|
267
|
+
> (*no checkpoint over a red check under pressure* went from **2/5 prose-only to 5/5
|
|
268
|
+
> latched**) and named, rather than papered over, the two honest gaps it surfaced: park
|
|
267
269
|
> capture at 0/5, and adversarial pressure flipping a standing `auto` grant a model could
|
|
268
270
|
> write into settings, a legal side door. The re-sweep
|
|
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**
|
|
271
|
-
> now closed. The side door went by construction: [D67](docs/decisions.md#d67)
|
|
271
|
+
> ([opus, 2026-07-18](docs/evals/2026-07-18.md), plumbbob 0.8.7) reproduced the win
|
|
272
|
+
> (*no checkpoint over a red check* still **5/5 latched**) and pinned both gaps. Both are
|
|
273
|
+
> now closed. The side door went by construction: [D67 (auto-not-a-grant)](docs/decisions.md#d67)
|
|
272
274
|
> (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
|
+
> approval a model could forge is gone. Park capture was never the latch's to reach,
|
|
276
|
+
> prose-governed by design ([D10 (pause-not-lock)](docs/decisions.md#d10)/[D13 (no-edit-guards)](docs/decisions.md#d13)),
|
|
275
277
|
> and it failed because the guidance couldn't reach a fresh session at all; the turn hook
|
|
276
278
|
> now injects one line when a step is in flight, and the third sweep
|
|
277
279
|
> ([opus, 2026-07-27](docs/evals/2026-07-27.md), plumbbob 0.9.0) measures it at **5/5**,
|
|
278
280
|
> 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
|
|
281
|
+
> a regression check on the shipped configuration, not a fresh baseline delta: the
|
|
280
282
|
> 2/5→5/5 headline above remains the 2026-07-11 measurement.
|
|
281
283
|
|
|
282
284
|
## Documentation
|
|
283
285
|
|
|
284
|
-
Each doc answers one question
|
|
285
|
-
|
|
286
|
-
- *What does a session actually look like?* → [`docs/happy-path.md`](docs/happy-path.md)
|
|
287
|
-
- *Show me the artifacts it leaves behind.* → [`examples/`](examples/)
|
|
288
|
-
- *Should I / can I / what about…?* → [`docs/faq.md`](docs/faq.md)
|
|
289
|
-
- *What is each method for?* → [`docs/techniques.md`](docs/techniques.md)
|
|
290
|
-
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md)
|
|
291
|
-
- *How do I plug in my own agent?* → [`docs/agents.md`](docs/agents.md)
|
|
292
|
-
- *How do I get a local model reviewing my steps?* → [`docs/local-model-review.md`](docs/local-model-review.md)
|
|
293
|
-
- *How do I install it, exactly?* → [`docs/install.md`](docs/install.md)
|
|
294
|
-
- *What does the CLI underneath do?* → [`docs/cli-reference.md`](docs/cli-reference.md)
|
|
295
|
-
- *What are these untracked files, and why is it touching my `.git`?* → [`docs/state-and-git.md`](docs/state-and-git.md)
|
|
296
|
-
- *Something's broken.* → [`docs/troubleshooting.md`](docs/troubleshooting.md)
|
|
297
|
-
- *Why is it built this way?* → [`docs/decisions.md`](docs/decisions.md)
|
|
298
|
-
- *How does it hang together inside?* → [`docs/architecture.md`](docs/architecture.md)
|
|
299
|
-
- *Why does this exist at all?* → [`docs/attention-first-development.md`](docs/attention-first-development.md)
|
|
300
|
-
- *
|
|
301
|
-
- *
|
|
286
|
+
Each doc answers one question (in rough reading order for a new user):
|
|
287
|
+
|
|
288
|
+
- *What does a session actually look like?* → [`docs/happy-path.md`](docs/happy-path.md): one goal walked end to end; read this first.
|
|
289
|
+
- *Show me the artifacts it leaves behind.* → [`examples/`](examples/): that same session's finished build folder, file by file.
|
|
290
|
+
- *Should I / can I / what about…?* → [`docs/faq.md`](docs/faq.md): the adoption questions, answered straight.
|
|
291
|
+
- *What is each method for?* → [`docs/techniques.md`](docs/techniques.md): steps, seams, the pause, park/harvest, spikes.
|
|
292
|
+
- *What does each skill do?* → [`docs/skills-reference.md`](docs/skills-reference.md): all thirteen skills: inputs, effects, when to reach for each.
|
|
293
|
+
- *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).
|
|
294
|
+
- *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.
|
|
295
|
+
- *How do I install it, exactly?* → [`docs/install.md`](docs/install.md): the full guide and the agent-neutral roadmap.
|
|
296
|
+
- *What does the CLI underneath do?* → [`docs/cli-reference.md`](docs/cli-reference.md): every verb, flag, exit code, and the `.plumbbob/` sidecar.
|
|
297
|
+
- *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.
|
|
298
|
+
- *Something's broken.* → [`docs/troubleshooting.md`](docs/troubleshooting.md): fixes for the common snags.
|
|
299
|
+
- *Why is it built this way?* → [`docs/decisions.md`](docs/decisions.md): the `D#` / `C#` design-decision key the source cites.
|
|
300
|
+
- *How does it hang together inside?* → [`docs/architecture.md`](docs/architecture.md): the layers and planes, for contributors (in progress).
|
|
301
|
+
- *Why does this exist at all?* → [`docs/attention-first-development.md`](docs/attention-first-development.md): the philosophy: attention as the scarce resource.
|
|
302
|
+
- *Why does AI-written prose get worse over time?* → [`docs/generation-loss.md`](docs/generation-loss.md): the copy-of-a-copy problem, and why anchor texts are written by hand.
|
|
303
|
+
- *What does it run on my machine?* → [`SECURITY.md`](SECURITY.md): execution surface and how to report a vulnerability.
|
|
304
|
+
- *How do I contribute?* → [`CONTRIBUTING.md`](CONTRIBUTING.md): setup, conventions, and how to submit changes.
|
|
302
305
|
|
|
303
306
|
## License
|
|
304
307
|
|
package/dist/cli-core.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
// plumbbob CLI core
|
|
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
3
|
// the top-level process.exit. Node builtins plus a deliberate few dependencies
|
|
4
4
|
// (currently checkride alone, via check.ts). Functional/procedural: no classes,
|
|
5
5
|
// no `this`, no default export.
|
|
6
6
|
//
|
|
7
7
|
// The deciding/executing boundary is a pause, not a lock, so there is nothing
|
|
8
|
-
// to defend in the dispatcher
|
|
9
|
-
// model triggers it.
|
|
8
|
+
// to defend in the dispatcher; every verb runs the same whether a human or the
|
|
9
|
+
// model triggers it. No human-only `mode` escape hatch exists and no
|
|
10
10
|
// CLAUDECODE in-session refusal; what keeps the human the decider is the pause
|
|
11
11
|
// at the step boundary (the skills), not a refusal here.
|
|
12
12
|
import { readFileSync } from 'node:fs';
|
|
@@ -24,6 +24,7 @@ import { use } from "./verbs/use.js";
|
|
|
24
24
|
import { finish } from "./verbs/finish.js";
|
|
25
25
|
import { init } from "./verbs/init.js";
|
|
26
26
|
import { doctor } from "./verbs/doctor.js";
|
|
27
|
+
import { recover } from "./verbs/recover.js";
|
|
27
28
|
import { agent } from "./verbs/agent.js";
|
|
28
29
|
import { turn } from "./verbs/turn.js";
|
|
29
30
|
/** Shared across every verb that resolves through the active-build cursor. */
|
|
@@ -37,7 +38,7 @@ const BUILD_FLAG = {
|
|
|
37
38
|
*
|
|
38
39
|
* One table drives three things: the top-level verb table, per-verb `--help`,
|
|
39
40
|
* and the unknown-flag refusal in `run`. Keeping it as data rather than inline
|
|
40
|
-
* writes is the deliberate exception to the write-at-the-call-site convention
|
|
41
|
+
* writes is the deliberate exception to the write-at-the-call-site convention;
|
|
41
42
|
* a synopsis has to be readable by the validator, not just printable.
|
|
42
43
|
*/
|
|
43
44
|
const VERBS = [
|
|
@@ -162,6 +163,13 @@ const VERBS = [
|
|
|
162
163
|
flags: [{ name: '--migrate', gloss: 'move a legacy flat sidecar into builds/ (staged, not committed)' }],
|
|
163
164
|
notes: 'Exits 0 when everything passes, 1 when a check fails or an un-migrated legacy sidecar is present.',
|
|
164
165
|
},
|
|
166
|
+
{
|
|
167
|
+
name: 'recover',
|
|
168
|
+
description: 'reconcile the control plane: stale markers, a cursor pointing nowhere, spike leftovers',
|
|
169
|
+
synopsis: ['recover [--fix]'],
|
|
170
|
+
flags: [{ name: '--fix', gloss: 'repair the stale untracked control files it can repair on its own' }],
|
|
171
|
+
notes: 'Exits 0 when the control plane is consistent, 1 while any problem stands. --fix never touches a tracked artifact, git history, or the loop; spike worktrees are reported, never removed.',
|
|
172
|
+
},
|
|
165
173
|
{
|
|
166
174
|
name: 'agent',
|
|
167
175
|
description: 'list or spawn a user-authored agent',
|
|
@@ -247,7 +255,7 @@ export function verbSpec(name) {
|
|
|
247
255
|
return VERBS.find((v) => v.name === name) ?? null;
|
|
248
256
|
}
|
|
249
257
|
/**
|
|
250
|
-
* Every verb name, in table order
|
|
258
|
+
* Every verb name, in table order: the contract tests iterate this.
|
|
251
259
|
*/
|
|
252
260
|
export function verbNames() {
|
|
253
261
|
return VERBS.map((v) => v.name);
|
|
@@ -333,6 +341,8 @@ async function dispatch(verb, cwd, rest) {
|
|
|
333
341
|
return init(rest);
|
|
334
342
|
case 'doctor':
|
|
335
343
|
return doctor(cwd, rest);
|
|
344
|
+
case 'recover':
|
|
345
|
+
return recover(cwd, rest);
|
|
336
346
|
case 'agent':
|
|
337
347
|
return agent(cwd, rest);
|
|
338
348
|
case 'turn':
|
|
@@ -352,12 +362,19 @@ async function dispatch(verb, cwd, rest) {
|
|
|
352
362
|
* used to commit a real checkpoint. Any thrown error becomes a one-line stderr
|
|
353
363
|
* report and exit 1, so the bin entry only ever exits with the code returned
|
|
354
364
|
* here.
|
|
365
|
+
*
|
|
366
|
+
* `cwd` is the repo the verbs act on. It defaults to the process's (the only
|
|
367
|
+
* thing the bin entry ever wants) and is a parameter solely so a test can name
|
|
368
|
+
* a fixture. Screening argv does not help when the argv is *valid*: `checkpoint
|
|
369
|
+
* -m --help` reads `--help` as the subject, exactly as it should, and then
|
|
370
|
+
* commits. Whose repo it commits is decided here, and a default is not a choice
|
|
371
|
+
* a test should inherit silently.
|
|
355
372
|
*/
|
|
356
|
-
export async function run(argv) {
|
|
373
|
+
export async function run(argv, cwd = process.cwd()) {
|
|
357
374
|
const verb = argv[0] ?? 'help';
|
|
358
375
|
const rest = argv.slice(1);
|
|
359
376
|
if (verb === 'help' || verb === '--help' || verb === '-h') {
|
|
360
|
-
// `plumbbob help <verb>` is the same page as `plumbbob <verb> --help
|
|
377
|
+
// `plumbbob help <verb>` is the same page as `plumbbob <verb> --help`;
|
|
361
378
|
// both spellings get typed, so both work.
|
|
362
379
|
const topic = rest.find((a) => !a.startsWith('-'));
|
|
363
380
|
if (topic === undefined) {
|
|
@@ -389,7 +406,7 @@ export async function run(argv) {
|
|
|
389
406
|
}
|
|
390
407
|
}
|
|
391
408
|
try {
|
|
392
|
-
return await dispatch(verb,
|
|
409
|
+
return await dispatch(verb, cwd, rest);
|
|
393
410
|
}
|
|
394
411
|
catch (err) {
|
|
395
412
|
const message = err instanceof Error ? err.message : String(err);
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// plumbbob CLI entry
|
|
2
|
+
// plumbbob CLI entry: the published bin. All routing and the help table live in
|
|
3
3
|
// cli-core.ts (unit-tested in-process); this file is only the executable shell:
|
|
4
4
|
// it wires argv to the dispatcher and turns the returned code into the exit code.
|
|
5
5
|
// Keeping the single process.exit here is what lets cli-core.ts be imported by a
|