plumbbob 0.5.3 → 0.6.1
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 +9 -0
- package/dist/cli-core.js +4 -0
- package/dist/lib/agents.js +498 -0
- package/dist/lib/intent.js +98 -8
- package/dist/lib/settings.js +17 -0
- package/dist/lib/sidecar.js +39 -2
- package/dist/verbs/agent.js +312 -0
- package/dist/verbs/checkpoint.js +2 -1
- package/dist/verbs/doctor.js +96 -3
- package/dist/verbs/start.js +16 -3
- package/dist/verbs/status.js +64 -2
- package/node_modules/checkride/CHANGELOG.md +139 -0
- package/node_modules/checkride/LICENSE +21 -0
- package/node_modules/checkride/README.md +179 -0
- package/node_modules/checkride/dist/adapters.d.ts +56 -0
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -0
- package/node_modules/checkride/dist/adapters.js +219 -0
- package/node_modules/checkride/dist/adapters.js.map +1 -0
- package/node_modules/checkride/dist/cli.d.ts +29 -0
- package/node_modules/checkride/dist/cli.d.ts.map +1 -0
- package/node_modules/checkride/dist/cli.js +227 -0
- package/node_modules/checkride/dist/cli.js.map +1 -0
- package/node_modules/checkride/dist/config.d.ts +74 -0
- package/node_modules/checkride/dist/config.d.ts.map +1 -0
- package/node_modules/checkride/dist/config.js +126 -0
- package/node_modules/checkride/dist/config.js.map +1 -0
- package/node_modules/checkride/dist/doctor.d.ts +76 -0
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -0
- package/node_modules/checkride/dist/doctor.js +299 -0
- package/node_modules/checkride/dist/doctor.js.map +1 -0
- package/node_modules/checkride/dist/index.d.ts +18 -0
- package/node_modules/checkride/dist/index.d.ts.map +1 -0
- package/node_modules/checkride/dist/index.js +13 -0
- package/node_modules/checkride/dist/index.js.map +1 -0
- package/node_modules/checkride/dist/init.d.ts +64 -0
- package/node_modules/checkride/dist/init.d.ts.map +1 -0
- package/node_modules/checkride/dist/init.js +489 -0
- package/node_modules/checkride/dist/init.js.map +1 -0
- package/node_modules/checkride/dist/links.d.ts +23 -0
- package/node_modules/checkride/dist/links.d.ts.map +1 -0
- package/node_modules/checkride/dist/links.js +125 -0
- package/node_modules/checkride/dist/links.js.map +1 -0
- package/node_modules/checkride/dist/orchestrator.d.ts +96 -0
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -0
- package/node_modules/checkride/dist/orchestrator.js +234 -0
- package/node_modules/checkride/dist/orchestrator.js.map +1 -0
- package/node_modules/checkride/package.json +76 -0
- package/node_modules/checkride/templates/flat/fallow.toml +26 -0
- package/node_modules/checkride/templates/flat/pnpm-workspace.yaml +6 -0
- package/node_modules/checkride/templates/flat/tsconfig.json +9 -0
- package/node_modules/checkride/templates/hybrid/fallow.toml +42 -0
- package/node_modules/checkride/templates/hybrid/pnpm-workspace.yaml +6 -0
- package/node_modules/checkride/templates/hybrid/tsconfig.json +12 -0
- package/node_modules/checkride/templates/monorepo/fallow.toml +44 -0
- package/node_modules/checkride/templates/monorepo/pnpm-workspace.yaml +7 -0
- package/node_modules/checkride/templates/monorepo/tsconfig.json +7 -0
- package/node_modules/checkride/templates/shared/cspell.json +35 -0
- package/node_modules/checkride/templates/shared/gitignore +10 -0
- package/node_modules/checkride/templates/shared/markdownlint-cli2.jsonc +11 -0
- package/node_modules/checkride/templates/shared/npmrc +1 -0
- package/node_modules/checkride/templates/shared/oxlintrc.json +33 -0
- package/node_modules/checkride/templates/shared/rules/no-class.yml +8 -0
- package/node_modules/checkride/templates/shared/rules/no-deep-sibling-import.yml +15 -0
- package/node_modules/checkride/templates/shared/rules/no-default-export.yml +9 -0
- package/node_modules/checkride/templates/shared/rules/require-js-extension.yml +21 -0
- package/node_modules/checkride/templates/shared/sgconfig.yml +2 -0
- package/node_modules/checkride/templates/shared/tsconfig.base.json +28 -0
- package/node_modules/checkride/templates/shared/vitest.config.ts.template +27 -0
- package/package.json +4 -1
- package/skills/pb-build/SKILL.md +42 -7
- package/skills/pb-finish/SKILL.md +1 -1
- package/skills/pb-harvest/SKILL.md +1 -1
- package/skills/pb-park/SKILL.md +1 -1
- package/skills/pb-plan/SKILL.md +25 -4
- package/skills/pb-refine/SKILL.md +1 -1
- package/skills/pb-revert/SKILL.md +1 -1
- package/skills/pb-spike/SKILL.md +1 -1
- package/skills/pb-status/SKILL.md +1 -1
- package/skills/pb-step/SKILL.md +10 -2
- package/skills/pb-verify/SKILL.md +21 -6
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Fallow: dead code, circular deps, duplication, complexity, architecture boundaries.
|
|
2
|
+
# Docs: https://docs.fallow.tools
|
|
3
|
+
|
|
4
|
+
entry = [
|
|
5
|
+
"apps/*/src/index.ts",
|
|
6
|
+
"libs/*/src/index.ts",
|
|
7
|
+
"apps/*/src/**/*.test.ts",
|
|
8
|
+
"libs/*/src/**/*.test.ts",
|
|
9
|
+
"apps/*/test/**/*.test.ts",
|
|
10
|
+
"libs/*/test/**/*.test.ts",
|
|
11
|
+
"test/**/*.test.ts",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
# CLI/tooling deps used via command line or config files, not imported from source.
|
|
15
|
+
ignoreDependencies = ["@ast-grep/cli"]
|
|
16
|
+
|
|
17
|
+
[rules]
|
|
18
|
+
unused-exports = "error"
|
|
19
|
+
unused-files = "error"
|
|
20
|
+
unused-dependencies = "error"
|
|
21
|
+
circular-dependencies = "error"
|
|
22
|
+
boundary-violation = "error"
|
|
23
|
+
|
|
24
|
+
[duplicates]
|
|
25
|
+
mode = "mild"
|
|
26
|
+
minTokens = 50
|
|
27
|
+
|
|
28
|
+
[health]
|
|
29
|
+
maxCyclomatic = 15
|
|
30
|
+
maxCognitive = 15
|
|
31
|
+
|
|
32
|
+
# Architecture boundaries: libs are reusable internals; apps are deployable
|
|
33
|
+
# leaves. libs may not import from apps.
|
|
34
|
+
[[boundaries.zones]]
|
|
35
|
+
name = "apps"
|
|
36
|
+
patterns = ["apps/*/src/**"]
|
|
37
|
+
|
|
38
|
+
[[boundaries.zones]]
|
|
39
|
+
name = "libs"
|
|
40
|
+
patterns = ["libs/*/src/**"]
|
|
41
|
+
|
|
42
|
+
[[boundaries.rules]]
|
|
43
|
+
from = "libs"
|
|
44
|
+
allow = ["libs"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.2",
|
|
3
|
+
"language": "en",
|
|
4
|
+
"files": ["**/src/**/*.ts", "**/test/**/*.ts", "**/*.md"],
|
|
5
|
+
"ignorePaths": [
|
|
6
|
+
"**/node_modules/**",
|
|
7
|
+
"**/dist/**",
|
|
8
|
+
".check/**",
|
|
9
|
+
"pnpm-lock.yaml",
|
|
10
|
+
"package.json",
|
|
11
|
+
"CHANGELOG.md"
|
|
12
|
+
],
|
|
13
|
+
"words": [
|
|
14
|
+
"checkride",
|
|
15
|
+
"biome",
|
|
16
|
+
"cspell",
|
|
17
|
+
"devDeps",
|
|
18
|
+
"esbuild",
|
|
19
|
+
"eslint",
|
|
20
|
+
"fallow",
|
|
21
|
+
"knip",
|
|
22
|
+
"markdownlint",
|
|
23
|
+
"NodeNext",
|
|
24
|
+
"noemit",
|
|
25
|
+
"oxlint",
|
|
26
|
+
"oxlintrc",
|
|
27
|
+
"pnpm",
|
|
28
|
+
"sgconfig",
|
|
29
|
+
"stryker",
|
|
30
|
+
"tsbuildinfo",
|
|
31
|
+
"tsconfig",
|
|
32
|
+
"tsgolint",
|
|
33
|
+
"vitest"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
save-exact=true
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
|
3
|
+
"plugins": ["typescript", "unicorn", "import"],
|
|
4
|
+
"categories": {
|
|
5
|
+
"correctness": "error",
|
|
6
|
+
"suspicious": "error",
|
|
7
|
+
"perf": "warn",
|
|
8
|
+
"style": "off"
|
|
9
|
+
},
|
|
10
|
+
"options": {
|
|
11
|
+
"typeAware": true
|
|
12
|
+
},
|
|
13
|
+
"rules": {
|
|
14
|
+
"typescript/no-floating-promises": "error",
|
|
15
|
+
"typescript/no-misused-promises": "error",
|
|
16
|
+
"typescript/no-explicit-any": "error",
|
|
17
|
+
"typescript/await-thenable": "error",
|
|
18
|
+
"typescript/no-unnecessary-type-assertion": "error",
|
|
19
|
+
"typescript/prefer-nullish-coalescing": "error",
|
|
20
|
+
"typescript/prefer-optional-chain": "error",
|
|
21
|
+
"no-console": "warn",
|
|
22
|
+
"eqeqeq": "error"
|
|
23
|
+
},
|
|
24
|
+
"overrides": [
|
|
25
|
+
{
|
|
26
|
+
"files": ["**/*.test.ts"],
|
|
27
|
+
"rules": {
|
|
28
|
+
"typescript/no-unsafe-type-assertion": "off"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"ignorePatterns": ["dist/**", ".check/**", ".claude/**", "node_modules/**"]
|
|
33
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
id: no-deep-sibling-import
|
|
2
|
+
message: |
|
|
3
|
+
Deep-module boundary: don't reach past a sibling module's index.
|
|
4
|
+
Use `import { ... } from '../<sibling>/index.js'` instead of
|
|
5
|
+
`'../<sibling>/<internal>.js'`.
|
|
6
|
+
severity: error
|
|
7
|
+
language: typescript
|
|
8
|
+
files:
|
|
9
|
+
- '**/src/**/*.ts'
|
|
10
|
+
rule:
|
|
11
|
+
all:
|
|
12
|
+
- kind: import_statement
|
|
13
|
+
- regex: "from\\s+['\"]\\.\\./[^/]+/[^'\"]+['\"]"
|
|
14
|
+
- not:
|
|
15
|
+
regex: "from\\s+['\"]\\.\\./[^/]+/index\\.js['\"]"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
id: require-js-extension
|
|
2
|
+
message: |
|
|
3
|
+
NodeNext resolution requires an explicit `.js` (or `.mjs` / `.json`) extension
|
|
4
|
+
on relative imports. Use `'./foo.js'`, not `'./foo'` or `'./foo.ts'`.
|
|
5
|
+
severity: error
|
|
6
|
+
language: typescript
|
|
7
|
+
files:
|
|
8
|
+
- '**/src/**/*.ts'
|
|
9
|
+
- '**/test/**/*.ts'
|
|
10
|
+
rule:
|
|
11
|
+
any:
|
|
12
|
+
- all:
|
|
13
|
+
- kind: import_statement
|
|
14
|
+
- regex: "from\\s+['\"]\\.{1,2}/"
|
|
15
|
+
- not:
|
|
16
|
+
regex: "from\\s+['\"]\\.{1,2}/[^'\"]*\\.(js|mjs|json)['\"]"
|
|
17
|
+
- all:
|
|
18
|
+
- kind: export_statement
|
|
19
|
+
- regex: "from\\s+['\"]\\.{1,2}/"
|
|
20
|
+
- not:
|
|
21
|
+
regex: "from\\s+['\"]\\.{1,2}/[^'\"]*\\.(js|mjs|json)['\"]"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2024",
|
|
4
|
+
"lib": ["ES2024"],
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
|
|
8
|
+
"strict": true,
|
|
9
|
+
"noUncheckedIndexedAccess": true,
|
|
10
|
+
"exactOptionalPropertyTypes": true,
|
|
11
|
+
"noImplicitOverride": true,
|
|
12
|
+
"noPropertyAccessFromIndexSignature": true,
|
|
13
|
+
"noFallthroughCasesInSwitch": true,
|
|
14
|
+
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"verbatimModuleSyntax": true,
|
|
17
|
+
"esModuleInterop": true,
|
|
18
|
+
"forceConsistentCasingInFileNames": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"resolveJsonModule": true,
|
|
21
|
+
"types": ["node"],
|
|
22
|
+
|
|
23
|
+
"composite": true,
|
|
24
|
+
"declaration": true,
|
|
25
|
+
"declarationMap": true,
|
|
26
|
+
"sourceMap": true
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
include: ['**/src/**/*.{test,spec}.ts', '**/test/**/*.{test,spec}.ts'],
|
|
6
|
+
exclude: ['**/node_modules/**', '**/dist/**'],
|
|
7
|
+
reporters: ['default'],
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
include: ['**/src/**/*.ts'],
|
|
11
|
+
exclude: [
|
|
12
|
+
'**/src/**/*.{test,spec}.ts',
|
|
13
|
+
'**/src/**/*.d.ts',
|
|
14
|
+
'**/node_modules/**',
|
|
15
|
+
'**/dist/**',
|
|
16
|
+
],
|
|
17
|
+
reporter: ['text', 'json-summary', 'json'],
|
|
18
|
+
reportsDirectory: '.check/coverage',
|
|
19
|
+
thresholds: {
|
|
20
|
+
lines: 70,
|
|
21
|
+
functions: 70,
|
|
22
|
+
branches: 70,
|
|
23
|
+
statements: 70,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plumbbob",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Attention-first build process: 12 skills + a CLI that keep you the decider — guidance, not enforcement.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -56,6 +56,9 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"checkride": "0.1.6"
|
|
58
58
|
},
|
|
59
|
+
"bundleDependencies": [
|
|
60
|
+
"checkride"
|
|
61
|
+
],
|
|
59
62
|
"scripts": {
|
|
60
63
|
"clean": "rm -rf dist",
|
|
61
64
|
"build": "tsc -p tsconfig.build.json",
|
package/skills/pb-build/SKILL.md
CHANGED
|
@@ -4,12 +4,12 @@ description: The optional engine — read the next planned step from intent, imp
|
|
|
4
4
|
argument-hint: "[step-number] [--auto]"
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
model: opus
|
|
7
|
-
allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob build:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(git diff:*)
|
|
7
|
+
allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob build:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent:*), Bash(git diff:*)
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# PlumbBob — build a step (the optional engine)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
This is the **bundled executor** — one way to turn a planned step into code. It is
|
|
15
15
|
**optional** (D3): you can implement any step by hand, in a vibe session, or with
|
|
@@ -32,17 +32,43 @@ at the pause for your approval. **Re-firing `/pb-build` is itself the clock tick
|
|
|
32
32
|
3. **Read the plan.** Read the step's **done-when**, its **seam**, and the
|
|
33
33
|
**Decisions** and **Constraints** in `intent.md`. Build to *that* — the deciding
|
|
34
34
|
already happened, off the chat.
|
|
35
|
+
- **Run any bound `before`-agents** *(D43/D59)*. If the build's `harness.json` binds
|
|
36
|
+
agents to this step's `before` slot, run `plumbbob agent run --step <n> --mode
|
|
37
|
+
before` first: each returns a validated envelope on stdout that plumbbob also
|
|
38
|
+
appends to the step's `handoff.json`, and its `summary`/`body` become **context you
|
|
39
|
+
read into the build** (that is the whole point of the slot — load the context in
|
|
40
|
+
before you write). No binding, or no harness, is a clean no-op — just build.
|
|
35
41
|
4. **Implement** the step, and only that step, staying within the declared seam. A
|
|
36
42
|
new problem or "ooh what if" that surfaces mid-build is a `/pb-park`, **not** an
|
|
37
43
|
edit — capture it and stay on the step. If you genuinely cannot finish without
|
|
38
44
|
touching more than the seam, that is scope drift: surface it to the human rather
|
|
39
45
|
than sprawling.
|
|
46
|
+
- **If a `build`-slot agent is bound, delegate the diff to it** *(D43)*. Run
|
|
47
|
+
`plumbbob agent run --step <n> --mode build` and let that agent author the step's
|
|
48
|
+
code instead of writing it yourself; its envelope reports what it did. You still
|
|
49
|
+
own the verify tick below — the diff is reviewed the same way whoever wrote it (D3).
|
|
50
|
+
- **A manifest's `when` prose is your cue to fire an agent mid-build** *(D43/D55)*.
|
|
51
|
+
The three slots are the only *declarative* lifecycle points; there is no config for
|
|
52
|
+
"a salient moment in the middle." That is judgment, and you are the frontier model
|
|
53
|
+
in the room: when the work reaches the situation a bound agent's `when` (or a step
|
|
54
|
+
`note`) describes, fire `plumbbob agent run <name> --step <n>` yourself. Prose is
|
|
55
|
+
the orchestration language; you are the workflow engine.
|
|
56
|
+
- **Route a non-`done` envelope by its status** *(D52)*. An agent that returns
|
|
57
|
+
`blocked` couldn't finish (missing input, failed precondition): surface its `notes`,
|
|
58
|
+
let the human unblock, and re-run it — don't work around it. One that returns
|
|
59
|
+
`drift` finished but found the plan no longer matches reality: **stop and send the
|
|
60
|
+
human to `/pb-refine`** to repair the plan before continuing, rather than building
|
|
61
|
+
on a plan that's now wrong. A non-zero exit is a failed run: report it and stop.
|
|
40
62
|
5. **Verify, through to the pause.** Run the verify tick exactly as `/pb-verify`
|
|
41
63
|
does: `plumbbob check` (on red, read `.check/summary.json` and the failing slot's
|
|
42
64
|
raw output under `.check/` for the actual diagnostics; while iterating on a fix,
|
|
43
65
|
narrow the loop with `plumbbob check --bail --only <slots>` — the checkpoint gate
|
|
44
|
-
still runs everything) →
|
|
45
|
-
|
|
66
|
+
still runs everything) → run any bound `after`-agents (`plumbbob agent run --step
|
|
67
|
+
<n> --mode after`) and fold their envelopes into the self-review as **advisory
|
|
68
|
+
input** — they inform, they never gate (checkride gates, the human is the clock; an
|
|
69
|
+
`after`-agent that could fail a step is the lock in autonomy's costume, D45) →
|
|
70
|
+
self-review the diff against the done-when, the Decisions, and the Constraints (a
|
|
71
|
+
single structured read, D16) → validate → **PAUSE
|
|
46
72
|
for the human's approval** → only on approval, checkpoint with
|
|
47
73
|
`plumbbob checkpoint <n> --body <<'BODY' … BODY` — a commit body **proportional to the
|
|
48
74
|
step** (a line for a trivial change, a short paragraph for a meatier one; no TIL scan,
|
|
@@ -57,12 +83,17 @@ at the pause for your approval. **Re-firing `/pb-build` is itself the clock tick
|
|
|
57
83
|
progress instead of approving each step. It does the same work, but **the agent reviews
|
|
58
84
|
and approves in the human's place**, and it **chains**:
|
|
59
85
|
|
|
60
|
-
- Build the next step
|
|
86
|
+
- Build the next step, running its slots in the same order as the default path
|
|
87
|
+
(D56): bound `before`-agents → implement (or the bound `build`-agent) → bound
|
|
88
|
+
`after`-agents → `check` → self-review → **if the check is green AND the
|
|
61
89
|
self-review finds no done-when / Decision / Constraint mismatch, checkpoint** and move
|
|
62
|
-
straight on to the next planned step. Repeat.
|
|
90
|
+
straight on to the next planned step. Repeat. `--auto` adds no new machinery — the
|
|
91
|
+
`after`-agent output simply feeds the *existing* self-review halt condition.
|
|
63
92
|
- **Stop and hand back to the human** the moment any of these is true: the check is red,
|
|
64
93
|
the self-review finds a mismatch (surface exactly what, and do not checkpoint it), a
|
|
65
|
-
|
|
94
|
+
bound agent returns `blocked` or `drift` (unblock-and-re-run, or `/pb-refine` — an
|
|
95
|
+
agent cannot advance the loop, C6), a new decision is needed, or no planned steps
|
|
96
|
+
remain.
|
|
66
97
|
|
|
67
98
|
`--auto` is the only path that checkpoints without a human pause, and only because the
|
|
68
99
|
human asked for it by name. The default — no flag — always ends at the pause.
|
|
@@ -76,3 +107,7 @@ human asked for it by name. The default — no flag — always ends at the pause
|
|
|
76
107
|
- **Default ends at the pause.** Implement → verify → wait for approval; never
|
|
77
108
|
checkpoint without it. Only an explicit `--auto` lets the agent approve in your place,
|
|
78
109
|
and it still halts on a red check or any mismatch.
|
|
110
|
+
- **Agents feed the beat; they never advance it** (C6/D45). `before` loads context,
|
|
111
|
+
`build` writes the diff, `after` is advisory — none can checkpoint, flip a step, or
|
|
112
|
+
chain. `blocked` → unblock and re-run; `drift` → `/pb-refine`. You are still the one
|
|
113
|
+
who verifies and (bar `--auto`) the human is still the clock.
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Bash(plumbbob status:*), Bash(plumbbob finish:*)
|
|
|
8
8
|
|
|
9
9
|
# PlumbBob — finish the build (the close-out)
|
|
10
10
|
|
|
11
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
11
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
12
12
|
|
|
13
13
|
`/pb-finish` ends the build: it captures what happened, then makes the final commit
|
|
14
14
|
that closes the session. **Report by default** (D9) — no refuse-without-report gate,
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Edit, Bash(plumbbob status:*)
|
|
|
8
8
|
|
|
9
9
|
# PlumbBob — harvest the park list
|
|
10
10
|
|
|
11
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
11
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
12
12
|
|
|
13
13
|
`/pb-harvest` is the complement of `/pb-park` (D7): you parked ideas as seeds during a
|
|
14
14
|
build; now, at a boundary, you harvest them — decide what each one is.
|
package/skills/pb-park/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob park:*)
|
|
|
9
9
|
|
|
10
10
|
# PlumbBob — park an idea (capture, don't chase)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
`/pb-park` is the **capture** half of the loop; `/pb-harvest` is where parked items
|
|
15
15
|
get triaged later (D7). Capturing the instant an idea arrives — instead of acting on
|
package/skills/pb-plan/SKILL.md
CHANGED
|
@@ -4,12 +4,12 @@ description: "Frame a fresh goal and author the whole plan — Frame, Decisions,
|
|
|
4
4
|
argument-hint: "[spec-path | intent]"
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
model: opus
|
|
7
|
-
allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob start:*), Bash(plumbbob checkpoint:*)
|
|
7
|
+
allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob start:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent list:*)
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# PlumbBob — plan a goal (the whole-goal move)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
`/pb-plan` is the **whole-goal** move — it opens a session and gets the deciding out
|
|
15
15
|
of your head and onto `intent.md` *before* any code. By default it authors the
|
|
@@ -60,14 +60,35 @@ an agent can follow with `/pb-build`. The argument only seeds how you get there.
|
|
|
60
60
|
paths it touches). Later steps may be fuzzier than the first — that's fine; they get
|
|
61
61
|
sharpened just-in-time when you reach them with `/pb-step`. Keep each small enough to
|
|
62
62
|
verify in one review pass.
|
|
63
|
-
5. **
|
|
63
|
+
5. **Offer harness bindings** *(optional — D42/D43)*. If the build will lean on
|
|
64
|
+
user-authored agents, author `harness.json` in the build folder (beside `intent.md`)
|
|
65
|
+
and review it at the **same plan pause**, alongside the steps — bindings are
|
|
66
|
+
plan-adjacent configuration, so they converge with the plan. It binds agents to a
|
|
67
|
+
step's three lifecycle slots — `before` (context in), `build` (the diff), `after`
|
|
68
|
+
(advisory review) — with an optional prose `note`; a `defaults` block binds every
|
|
69
|
+
step. Run `plumbbob agent list` to see what's resolvable, per step:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"contract": 1,
|
|
74
|
+
"defaults": { "after": ["reviewer"] },
|
|
75
|
+
"steps": { "3": { "before": ["context-loader"], "note": "watch the auth seam" } }
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Keep it **bindings + prose only, never a conditional** (C3): the file says *which*
|
|
80
|
+
agent, not *when* — the host model reads each manifest's `when` prose and a step's
|
|
81
|
+
`note` and decides when to fire one mid-build. Skip the file entirely when no step
|
|
82
|
+
uses an agent — the loop runs identically without it (D54). The plan commit picks it
|
|
83
|
+
up automatically (it lives in the build folder).
|
|
84
|
+
6. **Commit the plan.** Once the human approves the frame and steps, run
|
|
64
85
|
`plumbbob checkpoint --plan` to commit the scaffold on its own — subject
|
|
65
86
|
`plumbbob: plan — <title>`, only `.plumbbob/builds/<slug>/`, a `plan <sha>` line in
|
|
66
87
|
`checkpoints` (D36). This keeps the first step's diff clean, so history reads
|
|
67
88
|
baseline → plan → steps. Pass a proportional `--body` (the single-quoted stdin
|
|
68
89
|
heredoc) when the rationale is worth carrying; skip it for a small plan. Do this
|
|
69
90
|
only on the human's approval — the plan is their convergence.
|
|
70
|
-
|
|
91
|
+
7. **Offer to stress-test it.** Suggest `/pb-refine` to attack the frame for holes (or
|
|
71
92
|
to repair the plan as it drifts). Optional, the human's call.
|
|
72
93
|
|
|
73
94
|
## The interview (mode 1)
|
|
@@ -9,7 +9,7 @@ allowed-tools: Read, Edit, Bash(plumbbob status:*)
|
|
|
9
9
|
|
|
10
10
|
# PlumbBob — refine the plan
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
`/pb-refine` keeps `intent.md` honest. Use it at **any point** — right after `/pb-plan`
|
|
15
15
|
to stress-test a fresh frame, or mid-build to repair a plan that drifted from what the
|
|
@@ -9,7 +9,7 @@ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob revert:*)
|
|
|
9
9
|
|
|
10
10
|
# PlumbBob — revert to a checkpoint (driver)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
This is a **driver skill** — a chat-side trigger for the mechanical `plumbbob revert` verb, so the whole workflow runs from the agent window instead of a terminal. It is `disable-model-invocation: true`: only the human fires it. It carries **no Edit and no Write tool** — its only action is to shell the verb and report the verb's output verbatim, including any refusal. The CLI is the source of truth: never retry a refused transition, and never edit a file to work around one.
|
|
15
15
|
|
package/skills/pb-spike/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ allowed-tools: Bash(plumbbob status:*), Bash(plumbbob spike:*)
|
|
|
9
9
|
|
|
10
10
|
# PlumbBob — spike an experiment (driver)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
This is a **driver skill** — a chat-side trigger for the mechanical `plumbbob spike` verb, so the whole workflow runs from the agent window instead of a terminal. It is `disable-model-invocation: true`: only the human fires it. It carries **no Edit and no Write tool** — its only action is to shell the verb and report the verb's output verbatim, including any refusal. The CLI is the source of truth: never retry a refused transition, and never edit a file to work around one.
|
|
15
15
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Bash(plumbbob status:*)
|
|
|
8
8
|
|
|
9
9
|
# PlumbBob — orient (the where-am-I move)
|
|
10
10
|
|
|
11
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
11
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
12
12
|
|
|
13
13
|
This is a **thin driver** for `plumbbob status`. The dashboard above is your
|
|
14
14
|
orientation — the intent, the step list, the parked/open-question counts, and the
|
package/skills/pb-step/SKILL.md
CHANGED
|
@@ -4,12 +4,12 @@ description: Revise the next increment just-in-time — sharpen the next undone
|
|
|
4
4
|
argument-hint: "[what-changed]"
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
model: opus
|
|
7
|
-
allowed-tools: Read, Edit, Bash(plumbbob status:*)
|
|
7
|
+
allowed-tools: Read, Edit, Write, Bash(plumbbob status:*), Bash(plumbbob agent list:*)
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# PlumbBob — revise the next step (the single-increment move)
|
|
11
11
|
|
|
12
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
12
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
13
13
|
|
|
14
14
|
`/pb-plan` authors the **whole** step list up front, so `/pb-step` is the
|
|
15
15
|
**just-in-time revision** move: it keeps the *next* undone step honest against what the
|
|
@@ -40,6 +40,14 @@ grew — but its everyday job is to sharpen, not to invent.
|
|
|
40
40
|
3. **Get the human's OK**, then write it into `## Steps` in the standard format —
|
|
41
41
|
`N. [ ] <title> — **done when:** <criterion>` with a `- seam:` sub-line. Revise the
|
|
42
42
|
existing step in place; only append when you are genuinely adding an increment.
|
|
43
|
+
4. **Revise the step's harness bindings if they drifted too** *(optional — D42)*. If the
|
|
44
|
+
build carries a `harness.json` (beside `intent.md`) and the reality that moved the
|
|
45
|
+
step also changed which agents it wants, sharpen that step's slot bindings
|
|
46
|
+
(`before`/`build`/`after`) and `note` at the same time — this is the just-in-time
|
|
47
|
+
counterpart to `/pb-plan`'s plan-time binding. `plumbbob agent list` shows what's
|
|
48
|
+
resolvable. Same rule as the plan move: bindings + prose only, never a conditional
|
|
49
|
+
(C3). Leave it untouched when the step's agents are still right, or when the build
|
|
50
|
+
uses none.
|
|
43
51
|
|
|
44
52
|
## The hard contracts
|
|
45
53
|
|
|
@@ -3,12 +3,12 @@ name: pb-verify
|
|
|
3
3
|
description: "The verify tick — run the check, self-review the diff against intent, validate the step's done-when, pause for your approval, then checkpoint. Executor-agnostic: it reads the diff, not who wrote it."
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
model: opus
|
|
6
|
-
allowed-tools: Read, Bash(plumbbob status:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(git diff:*), Bash(git status:*)
|
|
6
|
+
allowed-tools: Read, Bash(plumbbob status:*), Bash(plumbbob check:*), Bash(plumbbob checkpoint:*), Bash(plumbbob agent:*), Bash(git diff:*), Bash(git status:*)
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# PlumbBob — verify a step (the tick)
|
|
10
10
|
|
|
11
|
-
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not
|
|
11
|
+
Current session state (injected when this skill runs): !`plumbbob status 2>/dev/null || echo "plumbbob CLI not on PATH in this session. Marketplace install: confirm the plugin is enabled in /plugin, then /reload-plugins. Skills-dir/global install: npm i -g plumbbob && plumbbob init."`
|
|
12
12
|
|
|
13
13
|
This is the **tick** — the one beat where the human is the clock. Whatever produced
|
|
14
14
|
the current diff — `/pb-build`, your own hands, a vibe session, another harness —
|
|
@@ -24,17 +24,29 @@ this skill verifies it the same way: **it reads the diff, not the author** (D3).
|
|
|
24
24
|
scrollback. Report what failed and do **not** pause for approval — there is
|
|
25
25
|
nothing to approve yet. The human fixes it and re-invokes. (Exit 2 means the gate
|
|
26
26
|
itself broke — a harness problem to surface, not a code failure.)
|
|
27
|
-
2. **
|
|
27
|
+
2. **Run any bound `after`-agents** *(optional — D45)*. If the build's `harness.json`
|
|
28
|
+
binds agents to this step's `after` slot, run `plumbbob agent run --step <n> --mode
|
|
29
|
+
after`. Their envelopes are **advisory input to the self-review, never a gate** —
|
|
30
|
+
`plumbbob check` already gated in step 1, and an `after`-agent that could fail a step
|
|
31
|
+
is the lock returning in autonomy's costume (D45). Fold a `done` envelope's
|
|
32
|
+
`summary`/`body` into the review below; route a non-`done` one by its status (D52): a
|
|
33
|
+
`blocked` agent couldn't finish — surface its `notes`, let the human unblock, re-run;
|
|
34
|
+
a `drift` agent found the plan no longer matches reality — stop and send the human to
|
|
35
|
+
`/pb-refine` to repair the plan before checkpointing. No binding, or no harness, is a
|
|
36
|
+
clean no-op.
|
|
37
|
+
3. **Self-review** *(a single structured read, D16)*. Read `git diff` and
|
|
28
38
|
`.plumbbob/intent.md`, then in one pass check the diff against:
|
|
29
39
|
- the current step's **done-when** criterion — is it actually met?
|
|
30
40
|
- the **Decisions** — does anything contradict a settled call?
|
|
31
41
|
- the **Constraints** — are any violated?
|
|
42
|
+
- any **`after`-agent findings** from step 2 — advisory, weigh them, don't defer to them.
|
|
32
43
|
Surface every mismatch plainly. You are reviewing, not building — do not fix anything.
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
4. **Validate.** State, yes or no, whether the step's done-when is met, with the evidence.
|
|
45
|
+
5. **PAUSE.** Present the check result, the self-review (with any `after`-agent
|
|
46
|
+
findings), and the validation, then
|
|
35
47
|
**stop and wait for the human's explicit approval.** This is the convergence beat;
|
|
36
48
|
the human is the clock. Never checkpoint without it.
|
|
37
|
-
|
|
49
|
+
6. **Checkpoint** *(only after approval)*. Run `plumbbob checkpoint`: it makes the WIP
|
|
38
50
|
commit, records the SHA, flips the step to done, appends the step to the build-log's
|
|
39
51
|
`## Log`, and returns to DESIGN. The CLI owns the commit **subject**
|
|
40
52
|
(`plumbbob: step N — <title>`); you own the **body**. Compose a body *proportional to
|
|
@@ -62,3 +74,6 @@ this skill verifies it the same way: **it reads the diff, not the author** (D3).
|
|
|
62
74
|
it and end your turn.
|
|
63
75
|
- **You review; you do not build.** If the self-review finds a problem, surface it
|
|
64
76
|
and stop — fixing is a new build beat, not part of verify.
|
|
77
|
+
- **`after`-agents advise; they never gate** (D45). Their output feeds the
|
|
78
|
+
self-review — checkride gates, the human approves. `blocked` → unblock and re-run;
|
|
79
|
+
`drift` → `/pb-refine` before checkpointing. No code path makes them blocking.
|