opencode-gbuild 0.9.0 → 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/README.md +31 -16
- package/agents/gbuild-implementer.md +4 -2
- package/agents/gbuild-reviewer.md +4 -2
- package/index.ts +9 -4
- package/package.json +2 -2
- package/reference/checklist.md +5 -1
- package/reference/graph-format.md +8 -2
- package/skills/design/SKILL.md +125 -0
- package/skills/plan/SKILL.md +15 -5
package/README.md
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
# gbuild — Claude Code + OpenCode plugin
|
|
2
2
|
|
|
3
|
-
Graph-native task planning and execution:
|
|
4
|
-
actual concurrent fan-out, a dedicated review pass on every node,
|
|
3
|
+
Graph-native task planning and execution: design a feature with the human, plan it as a real
|
|
4
|
+
dependency graph, then run it with actual concurrent fan-out, a dedicated review pass on every node,
|
|
5
|
+
and durable per-node checkpoints.
|
|
5
6
|
|
|
6
7
|
## The workflow
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
Design the feature first — `/gbuild:design` when the work needs shaping before it can be charted,
|
|
10
|
+
conversation (your agent's normal plan mode) when it doesn't — then hand it to gbuild:
|
|
9
11
|
|
|
10
|
-
1. `/gbuild:
|
|
11
|
-
2. `/gbuild:
|
|
12
|
-
3. `/gbuild:
|
|
13
|
-
4.
|
|
12
|
+
1. `/gbuild:design <the feature>` — shape it with the human into committed design artifacts (`docs/design/<slug>/`) on the feature branch in its own worktree; it ends only when you call the design good, and re-invoking with the slug resumes from the commits
|
|
13
|
+
2. `/gbuild:plan <the plan>` — chart it as a dependency graph
|
|
14
|
+
3. `/gbuild:run <slug>` — run it, once; it starts each node the moment its dependencies complete, until the graph completes (re-invoke only to resume an interrupted run)
|
|
15
|
+
4. `/gbuild:review <slug>` — audit the accumulated branch
|
|
16
|
+
5. Issues? `/gbuild:plan <slug> --add "<fix>"`, then `/gbuild:run` again. Clean? `/gbuild:pr <slug>`
|
|
14
17
|
|
|
15
|
-
The feature branch lives in its own git worktree (created by `plan`) — your checkout never changes
|
|
18
|
+
The feature branch lives in its own git worktree (created by `design` or `plan`) — your checkout never changes
|
|
16
19
|
branches, your uncommitted work is never in the way, and several features can be in flight in parallel
|
|
17
20
|
without racing each other's `HEAD`.
|
|
18
21
|
|
|
@@ -45,9 +48,9 @@ claude --plugin-dir ./plugins/gbuild
|
|
|
45
48
|
### OpenCode
|
|
46
49
|
|
|
47
50
|
The same directory is also an OpenCode (V2) plugin, published to npm as
|
|
48
|
-
[`opencode-gbuild`](https://www.npmjs.com/package/opencode-gbuild) — `index.ts` registers the
|
|
49
|
-
skills and
|
|
50
|
-
`/gbuild-pr`) from the same markdown the Claude plugin uses.
|
|
51
|
+
[`opencode-gbuild`](https://www.npmjs.com/package/opencode-gbuild) — `index.ts` registers the six
|
|
52
|
+
skills and six slash commands (`/gbuild-design`, `/gbuild-plan`, `/gbuild-run`, `/gbuild-status`,
|
|
53
|
+
`/gbuild-review`, `/gbuild-pr`) from the same markdown the Claude plugin uses.
|
|
51
54
|
|
|
52
55
|
```bash
|
|
53
56
|
opencode plugin add opencode-gbuild
|
|
@@ -73,8 +76,8 @@ The npm package is published from this directory:
|
|
|
73
76
|
One translation note: OpenCode plugins can't register agents, so where the Claude plugin spawns its
|
|
74
77
|
bundled `gbuild-implementer`/`gbuild-reviewer`/`gbuild-auditor` agents, the OpenCode skills dispatch the
|
|
75
78
|
built-in `general` subagent instead. For the implementer and reviewer the prompt is run's dispatch
|
|
76
|
-
prompt
|
|
77
|
-
|
|
79
|
+
prompt with its `Agent file: <path>.` field moved to the front as `Read <path> and follow it.`, so the
|
|
80
|
+
path appears once; the auditor gets `Read <plugin>/agents/gbuild-auditor.md and follow
|
|
78
81
|
it.` followed by exactly what the review skill passes it. The agent's text is never pasted into the
|
|
79
82
|
prompt. The review is still a fresh, isolated agent — never the implementer.
|
|
80
83
|
|
|
@@ -83,6 +86,7 @@ prompt. The review is still a fresh, isolated agent — never the implementer.
|
|
|
83
86
|
Claude Code:
|
|
84
87
|
|
|
85
88
|
```
|
|
89
|
+
/gbuild:design add OAuth login with GitHub
|
|
86
90
|
/gbuild:plan add OAuth login with GitHub
|
|
87
91
|
/gbuild:run add-oauth-login-with-github
|
|
88
92
|
/gbuild:status add-oauth-login-with-github
|
|
@@ -93,6 +97,7 @@ Claude Code:
|
|
|
93
97
|
OpenCode (same order, kebab-case names):
|
|
94
98
|
|
|
95
99
|
```
|
|
100
|
+
/gbuild-design add OAuth login with GitHub
|
|
96
101
|
/gbuild-plan add OAuth login with GitHub
|
|
97
102
|
/gbuild-run add-oauth-login-with-github
|
|
98
103
|
/gbuild-status add-oauth-login-with-github
|
|
@@ -100,7 +105,17 @@ OpenCode (same order, kebab-case names):
|
|
|
100
105
|
/gbuild-pr add-oauth-login-with-github
|
|
101
106
|
```
|
|
102
107
|
|
|
103
|
-
- **`
|
|
108
|
+
- **`design`** shapes a feature with the human before `plan` charts it — for when the destination
|
|
109
|
+
still has options, the moving parts aren't named, or the trade-offs are unmade. It analyses the
|
|
110
|
+
codebase, drives the discussion in batched question rounds (the destination first, one line), and
|
|
111
|
+
commits each settled piece to `docs/design/<slug>/` on the feature branch in its own worktree —
|
|
112
|
+
`design.md` carries the destination, scope, decisions with their ruled-out alternatives, and the
|
|
113
|
+
open questions. It ends only when the human calls the design good — never on its own judgement —
|
|
114
|
+
writes no implementation (unknowns that need code become open questions for `plan` to chart as
|
|
115
|
+
`research` nodes), and runs without `cypherlite` or a store; re-invoking with the slug resumes
|
|
116
|
+
from the committed artifacts.
|
|
117
|
+
- **`plan`** creates the feature branch in its own worktree (reusing the one `design` left, when
|
|
118
|
+
there is one) and charts the feature into a
|
|
104
119
|
machine-local CypherLite graph store (`<git-common-dir>/gbuild/<feature>/db`) — `Feature`,
|
|
105
120
|
`Acceptance`, and `GbuildNode` nodes, each node's contract as `INPUT`/`OUTPUT` `Field` nodes, and
|
|
106
121
|
`FROM` edges carrying data from one node's output to the next node's input. Every dependency edge
|
|
@@ -263,7 +278,7 @@ plugins/gbuild/
|
|
|
263
278
|
reference/ # graph-format.md (normative model), cypher.md (how to talk to the store), queries.md (ad-hoc recipes); shapes/failure-policies/cost-model/checklist inform plan
|
|
264
279
|
cypher/ # schema, validate, progress/attention/status/node/feature reads, run's dispatch/record/set-status, and brief/check-result/symbols for its agents
|
|
265
280
|
templates/example.cypher # a worked 4-node diamond, written the way plan writes a feature
|
|
266
|
-
skills/{plan,run,status,review,pr}/
|
|
281
|
+
skills/{design,plan,run,status,review,pr}/
|
|
267
282
|
index.ts # OpenCode plugin entry: registers the skills + /gbuild-* commands, translating paths/names
|
|
268
283
|
package.json # OpenCode plugin manifest (npm package "opencode-gbuild")
|
|
269
284
|
cypher.test.ts # node --test contract tests for the Cypher layer (repo-root `npm test`)
|
|
@@ -276,7 +291,7 @@ It holds the plan, every node's status and output values, the full review histor
|
|
|
276
291
|
reviewer's checklist), and the notes and symbols agents left; CypherLite checkpoints the store on exit,
|
|
277
292
|
so `db/graph.json` is just the engine's local snapshot. All of a feature's worktrees live under
|
|
278
293
|
`.git/gbuild/<feature>/` — never in `git status`: `tree/` is the feature worktree itself, created by
|
|
279
|
-
`plan` and kept until the feature is done, and during a run each file-touching node gets a `<node>/`
|
|
294
|
+
`design` or `plan` and kept until the feature is done, and during a run each file-touching node gets a `<node>/`
|
|
280
295
|
worktree that is removed the moment its node is accepted (merged into the feature branch, in `tree/`)
|
|
281
296
|
or terminally failed (discarded). Beside them, `inbox/` holds the run's hand-off files (`<slug>.json`,
|
|
282
297
|
`<slug>.review.json`), emptied when a run starts and cleared for each node once it is recorded.
|
|
@@ -9,7 +9,8 @@ You are implementing one gbuild node. Your prompt is a single line of paths:
|
|
|
9
9
|
gbuild node `<slug>`. Store: <DB>. Worktree: <worktree>. Feature branch: <BRANCH>. Agent file: <plugin>/agents/gbuild-implementer.md.
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
On OpenCode the
|
|
12
|
+
On OpenCode the `Agent file:` field moves to the front instead: the prompt starts with
|
|
13
|
+
`Read <agent file> and follow it.`, followed by that line without its `Agent file:` field.
|
|
13
14
|
|
|
14
15
|
Everything else — the node's title, type, acceptance, inputs, outputs, the failed criteria of a
|
|
15
16
|
previous attempt, and notes left by earlier agents — is in the store, and you read it yourself. The
|
|
@@ -19,7 +20,8 @@ bullet. Do the work for real, and make the result file honest.
|
|
|
19
20
|
|
|
20
21
|
## PATHS
|
|
21
22
|
|
|
22
|
-
- `<plugin>` — the agent-file path from your prompt
|
|
23
|
+
- `<plugin>` — the agent-file path from your prompt (the `Agent file:` field, or the path in the
|
|
24
|
+
`Read … and follow it.` sentence on OpenCode) minus `/agents/gbuild-implementer.md` (the
|
|
23
25
|
directory two levels above this file). Every script below is in `<plugin>/cypher/`. Always derive it
|
|
24
26
|
from the prompt; no plugin-root environment variable is set for you.
|
|
25
27
|
- `<feature>` — the path segment right before `/db` in `<DB>` (`…/gbuild/<feature>/db`).
|
|
@@ -20,9 +20,11 @@ Your prompt is one line of paths and nothing else:
|
|
|
20
20
|
gbuild node `<slug>`. Store: <DB>. Worktree: <worktree>. Feature branch: <BRANCH>. Agent file: <plugin>/agents/gbuild-reviewer.md.
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
On OpenCode the
|
|
23
|
+
On OpenCode the `Agent file:` field moves to the front instead: the prompt starts with
|
|
24
|
+
`Read <agent file> and follow it.`, followed by that line without its `Agent file:` field.
|
|
24
25
|
|
|
25
|
-
`<plugin>` is the directory two levels above the agent-file path
|
|
26
|
+
`<plugin>` is the directory two levels above the agent-file path — the `Agent file:` field, or the
|
|
27
|
+
path in the `Read … and follow it.` sentence on OpenCode (the path minus
|
|
26
28
|
`/agents/gbuild-reviewer.md`). Never rely on `${CLAUDE_PLUGIN_ROOT}` here; derive it from the path.
|
|
27
29
|
`<INBOX>` is the inbox directory beside `<DB>`: the `<DB>` path with its trailing `/db` replaced by
|
|
28
30
|
`/inbox`. You fetch everything else yourself, in this order:
|
package/index.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type { Plugin } from "@opencode/plugin"
|
|
|
19
19
|
|
|
20
20
|
const root = dirname(fileURLToPath(import.meta.url))
|
|
21
21
|
|
|
22
|
-
const SLUGS = ["plan", "run", "status", "review", "pr"] as const
|
|
22
|
+
const SLUGS = ["design", "plan", "run", "status", "review", "pr"] as const
|
|
23
23
|
type Slug = (typeof SLUGS)[number]
|
|
24
24
|
|
|
25
25
|
const OPENCODE_NOTES = `
|
|
@@ -38,8 +38,8 @@ instructions above:
|
|
|
38
38
|
registered agents here. When the instructions say to spawn one, dispatch the
|
|
39
39
|
built-in \`general\` subagent instead:
|
|
40
40
|
- \`gbuild-implementer\` / \`gbuild-reviewer\`: the prompt is run's dispatch
|
|
41
|
-
template
|
|
42
|
-
|
|
41
|
+
template with its closing \`Agent file: <path>.\` field moved to the front
|
|
42
|
+
as \`Read <path> and follow it.\` — the path appears once
|
|
43
43
|
(\`${join(root, "agents", "gbuild-implementer.md")}\` /
|
|
44
44
|
\`${join(root, "agents", "gbuild-reviewer.md")}\`).
|
|
45
45
|
- \`gbuild-auditor\`: send
|
|
@@ -61,10 +61,15 @@ const frontmatter = (raw: string): { description: string; body: string } => {
|
|
|
61
61
|
return { description, body: match[2] ?? "" }
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// `/gbuild:<slug>` → `/gbuild-<slug>`, derived from SLUGS so the alternation
|
|
65
|
+
// can never drift from the registered skills (a "/" needs no escaping in the
|
|
66
|
+
// string form a RegExp constructor takes).
|
|
67
|
+
const SLUG_REF_RE = new RegExp(`/gbuild:(${SLUGS.join("|")})\\b`, "g")
|
|
68
|
+
|
|
64
69
|
const translate = (text: string): string =>
|
|
65
70
|
text
|
|
66
71
|
.replaceAll("${CLAUDE_PLUGIN_ROOT}", root)
|
|
67
|
-
.replace(
|
|
72
|
+
.replace(SLUG_REF_RE, "/gbuild-$1")
|
|
68
73
|
|
|
69
74
|
interface LoadedSkill {
|
|
70
75
|
readonly slug: Slug
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "opencode-gbuild",
|
|
4
|
-
"version": "0.
|
|
5
|
-
"description": "OpenCode plugin for gbuild —
|
|
4
|
+
"version": "0.10.0",
|
|
5
|
+
"description": "OpenCode plugin for gbuild — design a feature with the human, plan it as a dependency graph, run it with concurrent fan-out, per-node review, and durable checkpoints.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": {
|
package/reference/checklist.md
CHANGED
|
@@ -30,7 +30,11 @@ fails means revise the graph (with Cypher), not add a caveat in prose.
|
|
|
30
30
|
`retry` everywhere without thinking about it.
|
|
31
31
|
12. **`model_tier` is `strong` only where judgement, not throughput, is the bottleneck** — see
|
|
32
32
|
`reference/cost-model.md`.
|
|
33
|
-
13. **
|
|
33
|
+
13. **No `research`, `decision` or `verify` node's acceptance requires a file change.** Those nodes edit
|
|
34
|
+
no files (`graph-format.md`); an ADR, doc or other file a decision implies belongs to a `code` node
|
|
35
|
+
reading the decision's outputs. `validate.cypher` can't see this — acceptance is free text — so check
|
|
36
|
+
each one.
|
|
37
|
+
14. **The graph, run end to end with every node passing review, actually reaches `destination`.** Read
|
|
34
38
|
the `Feature` node's `destination` property back against the node set: if every node completed, is
|
|
35
39
|
the feature actually done? A graph that's internally consistent but doesn't add up to the
|
|
36
40
|
destination is still wrong.
|
|
@@ -88,13 +88,19 @@ serves is `SATISFIES` edges, not a property.
|
|
|
88
88
|
|
|
89
89
|
| type | label | produces |
|
|
90
90
|
| ---------- | ---------- | -------------------------------------------------------------------- |
|
|
91
|
-
| `research` | `Research` | findings — an answer to a question, cited
|
|
92
|
-
| `decision` | `Decision` | a choice
|
|
91
|
+
| `research` | `Research` | findings — an answer to a question, cited, as output values |
|
|
92
|
+
| `decision` | `Decision` | a choice and the alternatives it ruled out, as output values |
|
|
93
93
|
| `code` | `Code` | a coherent, reviewable change, committed |
|
|
94
94
|
| `test` | `Test` | coverage for behavior a `code` node landed, when genuinely separable |
|
|
95
95
|
| `verify` | `Verify` | a check on another node's output — never the same agent, never self |
|
|
96
96
|
| `chore` | `Chore` | mechanical work with no behavior change |
|
|
97
97
|
|
|
98
|
+
**`research`, `decision` and `verify` nodes edit no files.** They get no worktree of their own — `run`
|
|
99
|
+
gives them the feature worktree read-only — and deliver only through their `OUTPUT` values. When a
|
|
100
|
+
choice or a finding must also land in the repo (an ADR, a doc), chart a `code` node that reads those
|
|
101
|
+
outputs through `FROM` and commits the file. A `chore` would fail `orphan-chore` unless something
|
|
102
|
+
depends on it.
|
|
103
|
+
|
|
98
104
|
**`acceptance` must be concrete** — checkable by a fresh context with no other information. Not
|
|
99
105
|
"looks correct" or "works well": name a file, a command's exit code, a specific behavior, or a literal
|
|
100
106
|
output value.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Designs a feature with the human — the design step before /gbuild:plan charts it: analyses the codebase, drives the discussion in batched question rounds, and commits the design artifacts (docs/design/<slug>/, entry doc design.md) to the feature branch in its own git worktree, never touching the main checkout. Ends only when the human calls the design good; re-invoking with the slug resumes from the committed artifacts. Runs without cypherlite and without a store — use when the work needs shaping before it can be charted.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Design the feature described by `$ARGUMENTS` — with the human, before `/gbuild:plan` charts it.
|
|
6
|
+
|
|
7
|
+
`plan` decomposes a feature that already makes sense: a one-line destination, a scope with edges,
|
|
8
|
+
constraints it can verify against. When the work isn't there yet — the destination still has
|
|
9
|
+
options, the moving parts aren't named, the trade-offs are unmade — this skill shapes it into
|
|
10
|
+
committed artifacts first. It writes the design onto the feature branch and stops: no graph, no
|
|
11
|
+
store, no implementation. The committed artifacts are the design's whole state, so re-invoking
|
|
12
|
+
`/gbuild:design <slug>` resumes exactly where the commits left off. After it, `/gbuild:plan <slug>`
|
|
13
|
+
has a design to decompose instead of a guess.
|
|
14
|
+
|
|
15
|
+
## Mode
|
|
16
|
+
|
|
17
|
+
| arguments | mode |
|
|
18
|
+
| --------------------------------------------------------- | --------------------------------------------------- |
|
|
19
|
+
| a description, link, or file path | **Design** — new feature |
|
|
20
|
+
| a slug with a feature worktree or branch, and no store | **Resume** — continue the committed artifacts |
|
|
21
|
+
| a slug whose store already exists | **Redirect** — `/gbuild:plan <slug> --add "<req>"` |
|
|
22
|
+
|
|
23
|
+
`$ARGUMENTS` is slug-shaped only if it is one kebab-case token. Then, in order: a store at
|
|
24
|
+
`<git-common-dir>/gbuild/<slug>/db` (its `graph.json` present) means `plan` already charted the
|
|
25
|
+
feature — don't design a charted feature; say so and point at `/gbuild:plan <slug> --add
|
|
26
|
+
"<requirement>"`, which is how a charted feature takes new work. A feature worktree or a branch
|
|
27
|
+
named `<slug>` or ending `/<slug>`, with no store, means a design started here and wasn't charted —
|
|
28
|
+
resume it. Anything else is a description — design it.
|
|
29
|
+
|
|
30
|
+
## Design
|
|
31
|
+
|
|
32
|
+
### 1. Slug, branch, and feature worktree
|
|
33
|
+
|
|
34
|
+
Derive the feature slug from `$ARGUMENTS`: kebab-case, ≤4 words, names the outcome not the mechanism
|
|
35
|
+
(`oauth-device-flow`, not `add-some-auth-stuff`). It names the artifact home below and the
|
|
36
|
+
`gbuild/<slug>/` directory `plan` later creates — immutable once the design is committed.
|
|
37
|
+
|
|
38
|
+
If the derived slug's store already exists (`<git-common-dir>/gbuild/<slug>/db`), stop: the feature
|
|
39
|
+
is charted, and new work goes to `/gbuild:plan <slug> --add`. Resolve `FT` (the feature worktree)
|
|
40
|
+
exactly as `/gbuild:plan`'s Chart step 1 describes (`${CLAUDE_PLUGIN_ROOT}/skills/plan/SKILL.md`) —
|
|
41
|
+
reuse the registered worktree, attach a branch checked out nowhere, or create branch and worktree
|
|
42
|
+
forked from the current HEAD. Report the branch and `FT`; everything below happens in `FT`. If
|
|
43
|
+
`docs/design/<slug>/` on that branch already has committed artifacts, this is a resume that arrived
|
|
44
|
+
as a description — read them (Resume below) instead of writing over them.
|
|
45
|
+
|
|
46
|
+
### 2. Analyse the codebase
|
|
47
|
+
|
|
48
|
+
Read the project manifest(s), directory structure, `README.md`, and the code the feature touches.
|
|
49
|
+
Resolve file paths or URLs in `$ARGUMENTS`; if a reference fails to load, say so and ask. For
|
|
50
|
+
related in-flight work — best-effort, never required: when `cypherlite` is on PATH, read the
|
|
51
|
+
`Feature` of every existing store (`feature.cypher` with `--read-only` against each
|
|
52
|
+
`<git-common-dir>/gbuild/*/db`, one at a time); when it isn't, skip — this skill needs neither
|
|
53
|
+
`cypherlite` nor a store, and never installs or creates either.
|
|
54
|
+
|
|
55
|
+
### 3. Fix the artifact home
|
|
56
|
+
|
|
57
|
+
The design artifacts live at `docs/design/<slug>/` on the feature branch; the entry doc is
|
|
58
|
+
`design.md`, and everything else hangs off it. Before writing anything, look at how the repo already
|
|
59
|
+
documents work — `docs/` layout, ADR or decision-record folders, README patterns — and follow an
|
|
60
|
+
existing convention when one is present: supporting docs take the repo's naming and format; only
|
|
61
|
+
the home and the entry doc are fixed here.
|
|
62
|
+
|
|
63
|
+
### 4. The design loop
|
|
64
|
+
|
|
65
|
+
The design is written by discussing it, one settled piece at a time. The loop runs until the human
|
|
66
|
+
calls the design good — never less, and never on your own judgement of when it's good enough.
|
|
67
|
+
|
|
68
|
+
1. **Open with what the analysis found.** A few lines: the pieces that exist, the gap, the
|
|
69
|
+
constraints — grounding, not a report. End with the first batch of questions.
|
|
70
|
+
2. **Ask in batches.** Put the round's open questions to the human in one message — cap at ~5. The
|
|
71
|
+
destination comes first, and it must end up one line, the thing that is true once this is done;
|
|
72
|
+
everything past it is scope to defend or cut. Then what the destination needs decided: scope
|
|
73
|
+
edges, naming, the trade-offs with real alternatives, the risks worth stating. Never one question
|
|
74
|
+
at a time, and never 20 questions — a round with more than ~5 open questions hasn't converged:
|
|
75
|
+
settle what the last answers gave you, and batch the rest into the next round.
|
|
76
|
+
3. **Settle as they solidify.** Fold each round's answers into the artifacts the moment they're
|
|
77
|
+
agreed, and commit — message `docs(design/<slug>): <what settled>` — so an interruption costs
|
|
78
|
+
nothing that had settled. `design.md` carries the state: the destination (one line), the scope
|
|
79
|
+
and out-of-scope, what the analysis found, each decision with its rationale and the alternatives
|
|
80
|
+
it ruled out, and the open questions still in play. Supporting docs — whatever this design
|
|
81
|
+
needs: diagrams, data shapes, interface sketches — follow the repo's convention (step 3).
|
|
82
|
+
4. **An unknown that needs code is an open question, not a prototype.** Design writes no
|
|
83
|
+
implementation — no scaffolding, no probes, no spike branches. A question the analysis can't
|
|
84
|
+
answer by reading goes into `design.md`'s open questions for `/gbuild:plan` to chart as a
|
|
85
|
+
`research` node.
|
|
86
|
+
|
|
87
|
+
### 5. Report and hand over
|
|
88
|
+
|
|
89
|
+
Only after the human has called the design good: ask nothing more, write and commit the last of it,
|
|
90
|
+
then report the artifacts (every file under `docs/design/<slug>/`), the branch, and `FT`. The feature
|
|
91
|
+
worktree stays — `plan` reuses it. Then both exits, the human's to pick:
|
|
92
|
+
|
|
93
|
+
- **Continue into gbuild** — `next: /gbuild:plan <slug>`.
|
|
94
|
+
- **A design review on a PR** — ask the agent to open it directly with `gh` from `FT` (push the
|
|
95
|
+
branch, `gh pr create`): `/gbuild:pr` can't, it needs a graph store, and a design isn't charted.
|
|
96
|
+
|
|
97
|
+
## Resume
|
|
98
|
+
|
|
99
|
+
Re-invoking `/gbuild:design <slug>` continues a design the feature worktree or branch already holds —
|
|
100
|
+
the mode table routed you here:
|
|
101
|
+
|
|
102
|
+
0. Resolve `FT` exactly as step 1 describes — reuse the registered worktree, attach the branch if
|
|
103
|
+
it's checked out nowhere. Never into the user's main checkout unless that's where the feature
|
|
104
|
+
branch already lives (a legacy feature).
|
|
105
|
+
1. Read the committed artifacts at `docs/design/<slug>/` in `FT`. `design.md` says what's decided
|
|
106
|
+
and what's open; the commit log says what settled when. Anything the loop left uncommitted never
|
|
107
|
+
settled — start that piece over.
|
|
108
|
+
2. Continue the loop (step 4) from the open questions. A settled decision reopens only on new
|
|
109
|
+
information, said out loud — not on a fresh context's second thoughts.
|
|
110
|
+
|
|
111
|
+
## Rules
|
|
112
|
+
|
|
113
|
+
- **Design, don't build.** Nothing lands on the branch but the artifacts under
|
|
114
|
+
`docs/design/<slug>/` — no implementation, no scaffolding, no probes. Unknowns that need code
|
|
115
|
+
become open questions for `plan` to chart as `research` nodes.
|
|
116
|
+
- **The human closes the design.** The loop ends on the human calling it good, never on your own
|
|
117
|
+
judgement; the closing report follows that word and nothing before it.
|
|
118
|
+
- **Commit as work solidifies.** Everything agreed is written and committed in the round it was
|
|
119
|
+
agreed in — the branch is the state, there is no store, and an interrupted design must resume
|
|
120
|
+
having lost nothing that had settled.
|
|
121
|
+
- **No cypherlite, no store.** This skill runs without either and never installs or creates
|
|
122
|
+
either: a store's existence only routes the mode, and sibling stores are read best-effort
|
|
123
|
+
(step 2), only when `cypherlite` is already on PATH.
|
|
124
|
+
- **The user's checkout never changes branch.** Every edit, commit, and check happens in `FT`; the
|
|
125
|
+
main tree is never touched.
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -6,10 +6,11 @@ Plan the work described in `$ARGUMENTS` as a graph.
|
|
|
6
6
|
|
|
7
7
|
## The loop
|
|
8
8
|
|
|
9
|
-
The intended workflow:
|
|
10
|
-
skill: `/gbuild:run <slug>` once — it starts each
|
|
11
|
-
completes. Then `/gbuild:review <slug>`; if it
|
|
12
|
-
`/gbuild:plan <slug> --add "<fix>"` and `/gbuild:run` again; if clean,
|
|
9
|
+
The intended workflow: `/gbuild:design <slug>` when the work needs shaping, ordinary conversation
|
|
10
|
+
when it doesn't, then chart it here. After this skill: `/gbuild:run <slug>` once — it starts each
|
|
11
|
+
node as its dependencies complete, until the graph completes. Then `/gbuild:review <slug>`; if it
|
|
12
|
+
finds issues, reopen with `/gbuild:plan <slug> --add "<fix>"` and `/gbuild:run` again; if clean,
|
|
13
|
+
`/gbuild:pr <slug>`.
|
|
13
14
|
|
|
14
15
|
Read `${CLAUDE_PLUGIN_ROOT}/reference/graph-format.md` (the normative graph model) and
|
|
15
16
|
`${CLAUDE_PLUGIN_ROOT}/reference/cypher.md` (how to talk to the store) before doing anything, and run
|
|
@@ -63,7 +64,13 @@ Report the branch and `FT`. Everything below happens in `FT`; `DB` below is `WT/
|
|
|
63
64
|
Read the project manifest(s), directory structure, `README.md`, and — for related in-flight work — the
|
|
64
65
|
`Feature` of every existing store (`feature.cypher` with `--read-only` against each `GC/gbuild/*/db`,
|
|
65
66
|
one at a time). Resolve
|
|
66
|
-
file paths or URLs in `$ARGUMENTS`; if a reference fails to load, say so and ask.
|
|
67
|
+
file paths or URLs in `$ARGUMENTS`; if a reference fails to load, say so and ask. When `FT` holds the
|
|
68
|
+
feature's design artifacts — committed by `/gbuild:design` at `docs/design/<slug>/`, entry doc
|
|
69
|
+
`design.md`, everything else hanging off it — read all of them first: they are the design context the
|
|
70
|
+
graph is charted from; its settled decisions are facts to decompose, not questions to reopen. When
|
|
71
|
+
no design is at `docs/design/<slug>/` in `FT`, check `docs/design/*` in `FT` before charting
|
|
72
|
+
fresh: a re-described feature — the same work, described again under a different slug — still
|
|
73
|
+
finds its committed design that way, and it is read exactly as above.
|
|
67
74
|
|
|
68
75
|
### 3. Validate and explore
|
|
69
76
|
|
|
@@ -117,6 +124,9 @@ For each GbuildNode decide (full model in `graph-format.md`):
|
|
|
117
124
|
|
|
118
125
|
- `slug` — kebab-case, immutable; what skills and the store key on. `title` — what the user reads.
|
|
119
126
|
- `type` — `research | decision | code | test | verify | chore`, plus the matching PascalCase label.
|
|
127
|
+
`research`, `decision` and `verify` nodes get no worktree and edit no files — they deliver through
|
|
128
|
+
their `OUTPUT` values only. Anything that must land in the repo (an ADR, a doc, a config file) belongs
|
|
129
|
+
to a `code` node that reads those outputs through `FROM`.
|
|
120
130
|
- **`OUTPUT` fields** — every node declares at least one, each with a precise `shape`
|
|
121
131
|
(`<integer>`, `<list of changed file paths>`, `<commit sha>`). Values will be scalars or lists of
|
|
122
132
|
scalars; for anything nested, the shape says it is a JSON-encoded string.
|