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
package/dist/verbs/start.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// `plumbbob start "<title>"
|
|
1
|
+
// `plumbbob start "<title>"`: open a session: scaffold the sidecar (the
|
|
2
2
|
// `.plumbbob/` tree of build artifacts and control files), record the baseline
|
|
3
3
|
// commit, and point the session at a new build. Refuses on a dirty tree (a
|
|
4
4
|
// clean baseline is the contract; `--allow-dirty` overrides), an existing
|
|
@@ -7,7 +7,7 @@ import { existsSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { detectGate } from "../lib/check.js";
|
|
9
9
|
import { readTemplate, stampTemplate } from "../lib/templates.js";
|
|
10
|
-
import { findRepoRoot, hasCommit, headSha, isDirty } from "../lib/git.js";
|
|
10
|
+
import { findRepoRoot, hasCommit, headSha, isDirty, isIgnored } from "../lib/git.js";
|
|
11
11
|
import { sidecarDir, buildDir, listBuilds, slugify, checkpointsPath, intentPath, buildLogPath, beginSession, hasSession, excludeControl, excludeSidecar, setGrant, stampTick, } from "../lib/sidecar.js";
|
|
12
12
|
import { settingsPath } from "../lib/settings.js";
|
|
13
13
|
/**
|
|
@@ -15,7 +15,7 @@ import { settingsPath } from "../lib/settings.js";
|
|
|
15
15
|
* {{CHECK}} line.
|
|
16
16
|
*
|
|
17
17
|
* The gate is checkride unless a `check` setting overrides it, so settings.json
|
|
18
|
-
* seeds with no `check` key at all
|
|
18
|
+
* seeds with no `check` key at all; absence IS the default; this line says
|
|
19
19
|
* that in prose where the templates need it.
|
|
20
20
|
*/
|
|
21
21
|
const CHECK_ECHO = 'checkride (set a "check" key in .plumbbob/settings.json to override)';
|
|
@@ -71,13 +71,13 @@ export async function start(cwd, args) {
|
|
|
71
71
|
}
|
|
72
72
|
const sha = headSha(root);
|
|
73
73
|
mkdirSync(sidecarDir(root), { recursive: true });
|
|
74
|
-
// beginSession writes STATE
|
|
74
|
+
// beginSession writes STATE: one file that is both the session sentinel (its
|
|
75
75
|
// existence means a session is live) and the active-build cursor (its single
|
|
76
|
-
// line names the build every verb acts on). Point it at this build
|
|
76
|
+
// line names the build every verb acts on). Point it at this build: null
|
|
77
77
|
// under --local, which has no cursor. The cursor lives in STATE, not
|
|
78
78
|
// settings.local.json, so that personal overlay stays purely human-owned.
|
|
79
79
|
beginSession(root, local ? null : slug);
|
|
80
|
-
// Scaffold the tracked settings.json ONLY when absent, and seed it EMPTY
|
|
80
|
+
// Scaffold the tracked settings.json ONLY when absent, and seed it EMPTY: the
|
|
81
81
|
// human owns this file once it exists (their `check` gate lives here), so a
|
|
82
82
|
// re-start must never touch it. Inject no opinions even on first create:
|
|
83
83
|
// absence of `check` already means checkride and absence of `auto` already
|
|
@@ -87,11 +87,11 @@ export async function start(cwd, args) {
|
|
|
87
87
|
if (!existsSync(settingsPath(root))) {
|
|
88
88
|
writeFileSync(settingsPath(root), `${JSON.stringify({}, null, 2)}\n`);
|
|
89
89
|
}
|
|
90
|
-
// `--local` keeps a fully
|
|
91
|
-
// git-excluded); the default plants a tracked `builds/<slug>/` folder
|
|
92
|
-
// build's record
|
|
93
|
-
// PR
|
|
94
|
-
// date-prefixed when derived (see datedSlug) and validated unique above
|
|
90
|
+
// `--local` keeps a fully untracked flat layout (the whole `.plumbbob/`
|
|
91
|
+
// git-excluded); the default plants a tracked `builds/<slug>/` folder (the
|
|
92
|
+
// build's record [intent, build-log, checkpoints] rides its branch into the
|
|
93
|
+
// PR) and git-excludes only the per-worktree control files. The slug is
|
|
94
|
+
// date-prefixed when derived (see datedSlug) and validated unique above;
|
|
95
95
|
// the CLI refuses a collision, never auto-suffixes.
|
|
96
96
|
let intentLocation;
|
|
97
97
|
if (local) {
|
|
@@ -112,18 +112,32 @@ export async function start(cwd, args) {
|
|
|
112
112
|
}
|
|
113
113
|
// The plan's entry stamp for the checkpoint latch: set TICK to the current
|
|
114
114
|
// TURN, so `checkpoint --plan` only lands once the harness ledger records a
|
|
115
|
-
// human turn after this moment. Skipped when TURN is absent
|
|
115
|
+
// human turn after this moment. Skipped when TURN is absent: a hookless host
|
|
116
116
|
// grows no ledger and the latch stays dormant, which also covers a first
|
|
117
117
|
// session where the hook has never ticked; that one plan commit stays
|
|
118
118
|
// guidance-governed. Any GRANT file lying around predates this session (a
|
|
119
|
-
// legitimate one is minted by a `/build` prompt, which never runs `start`)
|
|
120
|
-
//
|
|
119
|
+
// legitimate one is minted by a `/build` prompt, which never runs `start`);
|
|
120
|
+
// clear it so a stale grant can't self-approve this session's plan; a
|
|
121
121
|
// grant's lifetime is one turn.
|
|
122
122
|
setGrant(root, null);
|
|
123
123
|
stampTick(root, local ? null : slug);
|
|
124
124
|
process.stdout.write(`plumbbob: started "${title}" — baseline ${sha.slice(0, 9)}. Frame and decide in ${intentLocation}; \`build\` a step once the decisions are made.\n`);
|
|
125
|
+
// The tracked layout plants `builds/<slug>/` to ride the branch into the PR,
|
|
126
|
+
// but a repo whose own `.gitignore` excludes `.plumbbob/` overrides that, and
|
|
127
|
+
// an explicit `git add` of an ignored folder is a hard error. Detect it here,
|
|
128
|
+
// once, so the record-only mode (plan/finish commits land empty; their bodies
|
|
129
|
+
// carry the record, the files stay untracked) is a known mode from the start
|
|
130
|
+
// rather than a surprise at the first `checkpoint --plan`. `--local` already
|
|
131
|
+
// excludes the whole sidecar by design and says so, so skip the probe there.
|
|
132
|
+
// Guidance only, and the session is already open: a probe hiccup stays silent
|
|
133
|
+
// rather than half-crashing a scaffolded session.
|
|
134
|
+
if (!local && sidecarIsIgnored(root, slug)) {
|
|
135
|
+
process.stderr.write('plumbbob: heads-up — this repo gitignores .plumbbob/, so the tracked build folder cannot ride the branch.\n' +
|
|
136
|
+
' Plan and finish commits will be record-only (empty commits; the plan and report ride the commit message).\n' +
|
|
137
|
+
' To keep the record in-tree, unignore .plumbbob/builds/ (or the whole sidecar) before the first checkpoint.\n');
|
|
138
|
+
}
|
|
125
139
|
// The plan-time gate probe: if checkride sees no code checks here, say so
|
|
126
|
-
// NOW
|
|
140
|
+
// NOW (while the human is still deciding) instead of at the first
|
|
127
141
|
// checkpoint, where the gate either refuses a vacuous run or, worse, greens
|
|
128
142
|
// on the always-on repo checks alone. Guidance only: it never changes the
|
|
129
143
|
// exit code, and a configured `check` or a probe hiccup stays silent.
|
|
@@ -139,8 +153,8 @@ export async function start(cwd, args) {
|
|
|
139
153
|
* Derive a `YYYY-MM-DD-<slug>` build slug from the title (local time).
|
|
140
154
|
*
|
|
141
155
|
* The date prefix makes `builds/` sort chronologically under `listBuilds`'
|
|
142
|
-
* plain lexical sort
|
|
143
|
-
* explicit `--slug` bypasses this and stays verbatim
|
|
156
|
+
* plain lexical sort: ordering by construction, not by titling convention. An
|
|
157
|
+
* explicit `--slug` bypasses this and stays verbatim: the CLI never rewrites
|
|
144
158
|
* what the caller chose. An untitleable title yields `''` so the empty-slug
|
|
145
159
|
* guard fires instead of minting a date-only slug.
|
|
146
160
|
*/
|
|
@@ -153,7 +167,23 @@ function datedSlug(title) {
|
|
|
153
167
|
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())}-${base}`;
|
|
154
168
|
}
|
|
155
169
|
/**
|
|
156
|
-
*
|
|
170
|
+
* Whether the tracked build folder is gitignored: the record-only heads-up's
|
|
171
|
+
* predicate, probing exactly the path `checkpoint --plan` will try to stage.
|
|
172
|
+
*
|
|
173
|
+
* Best-effort: a probe that throws (a fatal `git check-ignore`) reads as
|
|
174
|
+
* not-ignored so the heads-up stays silent rather than crashing a session that
|
|
175
|
+
* is already open.
|
|
176
|
+
*/
|
|
177
|
+
function sidecarIsIgnored(root, slug) {
|
|
178
|
+
try {
|
|
179
|
+
return isIgnored(root, buildDir(root, slug));
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Read the value that follows a `--flag` in argv (for example `--slug my-build`), or
|
|
157
187
|
* undefined when the flag is absent or trails with no value.
|
|
158
188
|
*/
|
|
159
189
|
function flagValue(args, flag) {
|
|
@@ -161,7 +191,7 @@ function flagValue(args, flag) {
|
|
|
161
191
|
return i >= 0 ? args[i + 1] : undefined;
|
|
162
192
|
}
|
|
163
193
|
/**
|
|
164
|
-
* Stamp a build template's `{{TITLE}}`/`{{CHECK}}
|
|
194
|
+
* Stamp a build template's `{{TITLE}}`/`{{CHECK}}`: the check is always the
|
|
165
195
|
* echo constant, since an absent `check` setting IS the checkride default.
|
|
166
196
|
*/
|
|
167
197
|
function stampBuild(template, title) {
|
package/dist/verbs/status.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// `plumbbob status
|
|
2
|
-
// parses the live session
|
|
3
|
-
// the in-flight STEP marker
|
|
1
|
+
// `plumbbob status`: the orientation dashboard, or NO ACTIVE SESSION. It
|
|
2
|
+
// parses the live session (intent.md, the build-log, the checkpoints ledger,
|
|
3
|
+
// the in-flight STEP marker) into a where-am-I view that suggests one primary
|
|
4
4
|
// next move while printing the full picture, so you can always override.
|
|
5
5
|
// Read-only, always exits 0. Skills pre-inject this output to gate their own
|
|
6
6
|
// behavior, so the `NO ACTIVE SESSION` sentinel is kept exact.
|
|
@@ -25,7 +25,7 @@ function readOr(path) {
|
|
|
25
25
|
* Print the orientation dashboard for the active build, plus its harness bindings.
|
|
26
26
|
*
|
|
27
27
|
* No session prints the exact `NO ACTIVE SESSION` sentinel; a session with
|
|
28
|
-
* builds but no active one lists them and points at `use`. Always exits 0
|
|
28
|
+
* builds but no active one lists them and points at `use`. Always exits 0:
|
|
29
29
|
* status is a report, never a gate.
|
|
30
30
|
*/
|
|
31
31
|
export function status(cwd, args = []) {
|
|
@@ -46,9 +46,9 @@ export function status(cwd, args = []) {
|
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
const inFlightRaw = readOr(stepPath(root, slug)).trim();
|
|
49
|
-
// Out-of-band commits
|
|
49
|
+
// Out-of-band commits (ones that landed outside the checkpoints ledger) are
|
|
50
50
|
// surfaced here, never blocked. Counting them needs git (orient is pure), so
|
|
51
|
-
// status measures it: commits on HEAD since the last ledger line's SHA
|
|
51
|
+
// status measures it: commits on HEAD since the last ledger line's SHA:
|
|
52
52
|
// baseline, plan, or step, so a commit landing before the first step
|
|
53
53
|
// checkpoint still surfaces. No ledger yet ⇒ nothing to reconcile against ⇒ 0.
|
|
54
54
|
const checkpoints = readOr(checkpointsPath(root, slug));
|
|
@@ -70,7 +70,7 @@ export function status(cwd, args = []) {
|
|
|
70
70
|
* `defaults` and per step.
|
|
71
71
|
*
|
|
72
72
|
* Bindings live in `builds/<slug>/harness.json` and status is the surface that
|
|
73
|
-
* reports them
|
|
73
|
+
* reports them: no separate `agent check` verb. Any bound agent that does not
|
|
74
74
|
* resolve gets a warning, not an error: a teammate can lack a personal agent
|
|
75
75
|
* and the loop still works. Returns [] when the build has no harness.json (a
|
|
76
76
|
* clean no-op) or the file binds nothing, so the dashboard stays uncluttered
|
|
@@ -100,7 +100,7 @@ function harnessSection(root, slug) {
|
|
|
100
100
|
/**
|
|
101
101
|
* Render a SlotBindings as `slot: name1, name2` fragments, in slot order.
|
|
102
102
|
*
|
|
103
|
-
* A slot bound to no agents (an explicit "override to none") is omitted
|
|
103
|
+
* A slot bound to no agents (an explicit "override to none") is omitted:
|
|
104
104
|
* there is nothing to run and nothing to name.
|
|
105
105
|
*/
|
|
106
106
|
function slotFragments(bindings) {
|
package/dist/verbs/turn.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
// `plumbbob turn
|
|
1
|
+
// `plumbbob turn`: the turn-ledger hook. Wired to the harness's
|
|
2
2
|
// UserPromptSubmit event, it runs once per human prompt and maintains two of the
|
|
3
3
|
// sidecar's git-excluded control files (flat files under `.plumbbob/`): it ticks
|
|
4
4
|
// `TURN`, the monotonic count of human turns the checkpoint latch compares
|
|
5
5
|
// against a step's entry stamp to know a human turn intervened since the step
|
|
6
|
-
// began, and it rewrites `GRANT` from the literal prompt
|
|
6
|
+
// began, and it rewrites `GRANT` from the literal prompt, minting a one-turn
|
|
7
7
|
// self-approval only when the human typed `/build --auto` or an `N-M` step
|
|
8
8
|
// range, clearing it otherwise (those strings can only come from a human
|
|
9
|
-
// keystroke, because `build` is disable-model-invocation
|
|
9
|
+
// keystroke, because `build` is disable-model-invocation: a grant the model
|
|
10
10
|
// could forge would be no grant). When a step is in flight it also emits ONE
|
|
11
11
|
// `UserPromptSubmit` additionalContext line so a fresh session (post-compaction,
|
|
12
12
|
// or a scripted `-p` turn where no skill prose is in context) still knows the
|
|
13
|
-
// beat
|
|
13
|
+
// beat: a tangent is parked, not chased. Guidance only: it blocks nothing. It
|
|
14
14
|
// ALWAYS exits 0 and any failure degrades to no output, so neither the tick nor
|
|
15
15
|
// the emit can ever wedge prompting.
|
|
16
16
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
@@ -18,7 +18,7 @@ import { findSessionRoot, setGrant, stepPath, turnPath } from "../lib/sidecar.js
|
|
|
18
18
|
/**
|
|
19
19
|
* The hook entry point: apply the tick, then emit the in-flight-step nudge.
|
|
20
20
|
*
|
|
21
|
-
* Always returns 0
|
|
21
|
+
* Always returns 0: a broken turn must never wedge a prompt, so any failure is
|
|
22
22
|
* swallowed and degrades to no output.
|
|
23
23
|
*/
|
|
24
24
|
export function turn(cwd, _args) {
|
|
@@ -29,7 +29,7 @@ export function turn(cwd, _args) {
|
|
|
29
29
|
process.stdout.write(context);
|
|
30
30
|
}
|
|
31
31
|
catch {
|
|
32
|
-
// A broken turn must never wedge a prompt
|
|
32
|
+
// A broken turn must never wedge a prompt: swallow and exit 0.
|
|
33
33
|
}
|
|
34
34
|
return 0;
|
|
35
35
|
}
|
|
@@ -59,7 +59,7 @@ export function stepInFlightContext(cwd) {
|
|
|
59
59
|
* The in-flight step number, or null when no STEP marker is present.
|
|
60
60
|
*
|
|
61
61
|
* Absent means no step entered, or it already checkpointed. A garbled marker
|
|
62
|
-
* reads as null
|
|
62
|
+
* reads as null (never an error), because the hook must not wedge a prompt.
|
|
63
63
|
*/
|
|
64
64
|
function inFlightStep(root) {
|
|
65
65
|
try {
|
|
@@ -73,14 +73,14 @@ function inFlightStep(root) {
|
|
|
73
73
|
/**
|
|
74
74
|
* The testable core: apply one tick given the raw hook stdin.
|
|
75
75
|
*
|
|
76
|
-
* Split from the fd-0 read so the unit tests can drive it directly
|
|
76
|
+
* Split from the fd-0 read so the unit tests can drive it directly: an
|
|
77
77
|
* in-process test cannot feed fd 0 (the same constraint checkpoint's `--body`
|
|
78
78
|
* lives under).
|
|
79
79
|
*/
|
|
80
80
|
export function applyTurn(cwd, raw) {
|
|
81
81
|
const root = findSessionRoot(cwd);
|
|
82
82
|
if (root === null)
|
|
83
|
-
return 0; // no active session above cwd
|
|
83
|
+
return 0; // no active session above cwd: silent no-op.
|
|
84
84
|
writeFileSync(turnPath(root), `${readTurn(root) + 1}\n`);
|
|
85
85
|
setGrant(root, grantFromPrompt(extractPrompt(raw)));
|
|
86
86
|
return 0;
|
|
@@ -90,7 +90,7 @@ export function applyTurn(cwd, raw) {
|
|
|
90
90
|
*
|
|
91
91
|
* A grant is minted only from a literal `build` invocation the human typed:
|
|
92
92
|
* `build` is disable-model-invocation, so this string can only come from a
|
|
93
|
-
* human keystroke, never model-authored pressure
|
|
93
|
+
* human keystroke, never model-authored pressure: a grant the model can forge
|
|
94
94
|
* is no grant. A bounded range beats `--auto` (bounded wins); a bare
|
|
95
95
|
* `/build`, or any non-invocation prompt, mints nothing. The namespaced
|
|
96
96
|
* `/plumbbob:build` form is honored alongside the bare one.
|
|
@@ -101,10 +101,10 @@ export function applyTurn(cwd, raw) {
|
|
|
101
101
|
*
|
|
102
102
|
* Only the invocation's own arguments can mint: the tokens that follow it on
|
|
103
103
|
* its line, up to the first token that isn't a sanctioned argument (`--auto`, a
|
|
104
|
-
* step number, or a range
|
|
104
|
+
* step number, or a range; the argument-hint sanctions nothing else). An
|
|
105
105
|
* unrecognized flag ends the scan, so `/build --wip 2020-2024` mints
|
|
106
|
-
* nothing
|
|
107
|
-
* the prompt
|
|
106
|
+
* nothing: the `2020-2024` is never reached. An incidental range elsewhere in
|
|
107
|
+
* the prompt (an issue number, a pasted `2020-2024`) is prose, not a grant.
|
|
108
108
|
* Trailing sentence punctuation on an argument (`/build 1-3.`) is still the
|
|
109
109
|
* argument the human typed.
|
|
110
110
|
*/
|
|
@@ -129,8 +129,8 @@ export function grantFromPrompt(prompt) {
|
|
|
129
129
|
continue;
|
|
130
130
|
}
|
|
131
131
|
if (/^\d+$/.test(word))
|
|
132
|
-
continue; // a bare step number
|
|
133
|
-
break; // an unrecognized flag or free text
|
|
132
|
+
continue; // a bare step number: keep scanning for a range/--auto
|
|
133
|
+
break; // an unrecognized flag or free text: the arguments have ended
|
|
134
134
|
}
|
|
135
135
|
if (ceiling !== undefined)
|
|
136
136
|
return `range ${ceiling}`;
|
|
@@ -170,7 +170,7 @@ function readTurn(root) {
|
|
|
170
170
|
* Read the hook JSON from fd 0, degrading to '' on any failure.
|
|
171
171
|
*
|
|
172
172
|
* An interactive TTY never sends EOF, so skip the read there rather than hang
|
|
173
|
-
* (mirrors checkpoint's `--body`); a read error degrades to ''
|
|
173
|
+
* (mirrors checkpoint's `--body`); a read error degrades to '': extractPrompt
|
|
174
174
|
* then clears the grant and the tick still lands.
|
|
175
175
|
*/
|
|
176
176
|
function readStdin() {
|
package/dist/verbs/use.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
// `plumbbob use <slug
|
|
1
|
+
// `plumbbob use <slug>`: re-point the active-build cursor at an existing build
|
|
2
2
|
// and resume it, `nvm use`-shaped: switching and resuming are the same one word.
|
|
3
3
|
// The cursor is the single-line content of `.plumbbob/STATE`, the untracked
|
|
4
4
|
// per-worktree file whose existence means a session is live and whose one line
|
|
5
|
-
// names the build that session is on
|
|
5
|
+
// names the build that session is on, so pointing it elsewhere IS the switch,
|
|
6
6
|
// and one-active-per-worktree holds by construction (one line cannot name two
|
|
7
|
-
// builds). It validates the target folder exists, and warns
|
|
7
|
+
// builds). It validates the target folder exists, and warns (but allows)
|
|
8
8
|
// leaving a build with a step in flight: the in-flight markers live per build,
|
|
9
9
|
// so that state survives the switch and resumes the next time you `use` the
|
|
10
10
|
// build.
|
|
@@ -15,7 +15,7 @@ import { activeBuild, hasSession, intentPath, listBuilds, setActiveBuild, stepPa
|
|
|
15
15
|
* Switch the active-build cursor to the named build.
|
|
16
16
|
*
|
|
17
17
|
* Refuses without a session, without a slug, or when the target folder has no
|
|
18
|
-
* intent.md; notes
|
|
18
|
+
* intent.md; notes (but allows) a step left in flight on the build being left.
|
|
19
19
|
*/
|
|
20
20
|
export function use(cwd, args) {
|
|
21
21
|
const root = findRepoRoot(cwd);
|
package/hooks/post-edit.sh
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
# post-edit.sh — light feedback (
|
|
2
|
+
# post-edit.sh — light feedback — D25 (light-then-heavy). PostToolUse, non-blocking, ALWAYS exits 0.
|
|
3
3
|
# Runs file-scoped oxlint + ast-grep on the changed file and injects any failures
|
|
4
|
-
# into the model's context via additionalContext (verified API
|
|
4
|
+
# into the model's context via additionalContext (verified API — D25 (light-then-heavy)). No-ops when
|
|
5
5
|
# the tools are absent or there is no session. tsc is deferred to the heavy tier
|
|
6
|
-
# (
|
|
6
|
+
# — D25 (light-then-heavy): it has no true single-file mode and would tax every keystroke.
|
|
7
7
|
|
|
8
8
|
# The repo root is the nearest ancestor whose .plumbbob/STATE is NON-EMPTY — the
|
|
9
|
-
# per-worktree signal that a tracked build is live here (
|
|
9
|
+
# per-worktree signal that a tracked build is live here — D28 (state-cursor). STATE's existence
|
|
10
10
|
# means "a session is active"; its content is the active-build cursor, so a non-empty
|
|
11
11
|
# STATE is exactly "a tracked build is live" (the `--local` layout leaves STATE empty,
|
|
12
12
|
# and this file-scoped check is a tracked-build affordance). `-s` tests both existence
|
package/hooks/pre-bash-commit.sh
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
# pre-bash-commit.sh — the git-commit ask-hook (
|
|
2
|
+
# pre-bash-commit.sh — the git-commit ask-hook — D66 (oob-commits-surfaced). PreToolUse on Bash: when a
|
|
3
3
|
# step is in flight and the model reaches for a raw `git commit`, turn that commit
|
|
4
4
|
# into a permission *question*, never a wall. checkpoint owns the landing (the latch
|
|
5
5
|
# lives there); this only nudges the human to route through it. ALWAYS exits 0 and
|
|
6
|
-
# never `deny`s — the human decides, C5 stays intact (
|
|
6
|
+
# never `deny`s — the human decides, C5 (additive-git) stays intact — D66 (oob-commits-surfaced). `plumbbob checkpoint`'s
|
|
7
7
|
# own internal `git commit` spawn never passes through hooks, so nothing self-trips.
|
|
8
8
|
|
|
9
9
|
# The repo root is the nearest ancestor with an active session — `.plumbbob/STATE`,
|
|
@@ -27,7 +27,7 @@ root=$(find_root) || exit 0 # no active session here: nothing to guard
|
|
|
27
27
|
|
|
28
28
|
# The in-flight signal is STEP (cleared when the step checkpoints): inside the
|
|
29
29
|
# active build's folder when STATE names one, else the flat sidecar STEP of the
|
|
30
|
-
# `--local` layout. STATE's content IS the cursor (
|
|
30
|
+
# `--local` layout. STATE's content IS the cursor — D28 (state-cursor) — read the first line, trim
|
|
31
31
|
# whitespace, and treat the legacy `active` sentinel (pre-STATE-cursor) as no cursor.
|
|
32
32
|
slug=$(head -n1 "$root/.plumbbob/STATE" 2>/dev/null | tr -d '[:space:]')
|
|
33
33
|
[ "$slug" = "active" ] && slug=""
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "checkride",
|
|
3
|
+
"displayName": "checkride",
|
|
4
|
+
"version": "0.12.2",
|
|
5
|
+
"description": "Bounded, contract-aware readers for what checkride already writes: triage a red gate and read quality signal without loading megabytes of raw artifacts.",
|
|
6
|
+
"author": { "name": "Rob McLarty", "email": "hello@robmclarty.com", "url": "https://robmclarty.com" },
|
|
7
|
+
"homepage": "https://robmclarty.github.io/checkride/",
|
|
8
|
+
"repository": "https://github.com/robmclarty/checkride",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"keywords": ["claude-code", "claude", "agent", "checkride", "ci", "triage"]
|
|
11
|
+
}
|