@pmelab/gtd 5.0.0 → 6.0.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 +32 -19
- package/dist/gtd.bundle.mjs +281 -153
- package/docs/cli.md +85 -12
- package/docs/configuration.md +116 -51
- package/docs/development.md +7 -5
- package/docs/examples/advanced-workflow.md +33 -23
- package/docs/upgrading.md +49 -32
- package/package.json +1 -1
- package/schema.json +4 -0
package/docs/cli.md
CHANGED
|
@@ -4,16 +4,23 @@
|
|
|
4
4
|
Usage: gtd [command] [options]
|
|
5
5
|
|
|
6
6
|
Commands:
|
|
7
|
+
init <workflow> Scaffold a .gtdrc.json for this repo with the chosen
|
|
8
|
+
bundled workflow inline (one of: simple, advanced). Run
|
|
9
|
+
once per repo; refuses if a gtd config already exists.
|
|
10
|
+
Leaves the file uncommitted for you to review and commit
|
|
7
11
|
step <actor> Authenticate as <actor>, match the resolved rest's
|
|
8
12
|
declared patterns against the pending changes, and commit
|
|
9
13
|
(or squash) the one resulting transition. Pass
|
|
10
14
|
--cost=<n> (optionally --model=<name>) to record the
|
|
11
15
|
just-finished invocation's token cost and model on the
|
|
12
16
|
turn commit (summed into it.processCost/processCostByModel)
|
|
17
|
+
review <commitish>
|
|
18
|
+
Start a NEW review process at the workflow's declared
|
|
19
|
+
review-entry state (reviewEntry: true), reviewing
|
|
20
|
+
<commitish>..HEAD — e.g. a colleague's PR branch. Requires
|
|
21
|
+
a clean tree resting at the workflow's initial state
|
|
13
22
|
next Print the resolved rest's rendered script/prompt/message
|
|
14
23
|
(no mutation)
|
|
15
|
-
run Execute the resolved rest's emitted script, then step its
|
|
16
|
-
actor (the built-in script driver)
|
|
17
24
|
status Print the resolved rest's state/actor and which declared
|
|
18
25
|
pattern (if any) each pending change matches (no mutation)
|
|
19
26
|
validate Format and validate the steering file the resolved rest
|
|
@@ -47,6 +54,28 @@ mistyped flag can never degrade a JSON caller to plain-text mode. A bare
|
|
|
47
54
|
`--model`, `--model` without `--cost`, or either flag on any command other than
|
|
48
55
|
`gtd step` are all usage errors.
|
|
49
56
|
|
|
57
|
+
## `gtd init <workflow>`
|
|
58
|
+
|
|
59
|
+
Scaffolds a `.gtdrc.json` at the repository root with one of the bundled
|
|
60
|
+
workflow templates inline under a `workflow:` key, plus a `$schema` link.
|
|
61
|
+
`<workflow>` is required and must be `simple` or `advanced` (a missing or
|
|
62
|
+
unknown name is a usage error listing both). gtd ships **no** default workflow,
|
|
63
|
+
so this is the one-time setup step for a repo; a state command run before it
|
|
64
|
+
fails with `gtd: no workflow configured — run \`gtd init <simple|advanced>\` …`.
|
|
65
|
+
|
|
66
|
+
- `simple` — the 10-state machine (see
|
|
67
|
+
[STATES.md §10](../STATES.md#10-the-bundled-workflow-templates)).
|
|
68
|
+
- `advanced` — the fuller machine (see
|
|
69
|
+
[advanced-workflow.md](examples/advanced-workflow.md)).
|
|
70
|
+
|
|
71
|
+
The file is written **uncommitted**; review and commit it before your first
|
|
72
|
+
`gtd step` (an uncommitted `.gtdrc.json` is a pending change the initial state
|
|
73
|
+
would otherwise capture). `gtd init` refuses if any gtd config already exists,
|
|
74
|
+
requires the repository root, and — with `gtd lsp` — is one of the two commands
|
|
75
|
+
that run with no workflow configured. `--json` prints
|
|
76
|
+
`{"written":".gtdrc.json","workflow":"<name>"}`. See
|
|
77
|
+
[Configuration](configuration.md#gtd-init).
|
|
78
|
+
|
|
50
79
|
## `gtd step <actor> [--cost=<n>] [--model=<name>]`
|
|
51
80
|
|
|
52
81
|
Authenticates `<actor>` against the resolved rest and performs the ONE resulting
|
|
@@ -103,6 +132,49 @@ not passed):
|
|
|
103
132
|
}
|
|
104
133
|
```
|
|
105
134
|
|
|
135
|
+
## `gtd review <commitish> [--json]`
|
|
136
|
+
|
|
137
|
+
Starts a BRAND NEW review process at the active workflow's declared
|
|
138
|
+
`reviewEntry: true` state (see
|
|
139
|
+
[STATES.md §11](../STATES.md#11-the-review-checkout-window)), reviewing
|
|
140
|
+
`<commitish>..HEAD` — e.g. a colleague's PR branch pushed on top of a shared
|
|
141
|
+
base, with no gtd process of its own. Reuses the workflow's existing
|
|
142
|
+
review/feedback machinery unmodified; there is no separate review-entry command
|
|
143
|
+
surface to keep in sync.
|
|
144
|
+
|
|
145
|
+
Requires, in order (any failure is a plain refusal — exit non-zero, nothing
|
|
146
|
+
written):
|
|
147
|
+
|
|
148
|
+
- the machine currently resting at the workflow's **initial state** (a plain
|
|
149
|
+
non-gtd branch resolves there via the inert-subject rule — the normal case; a
|
|
150
|
+
process already underway refuses);
|
|
151
|
+
- a **clean working tree**;
|
|
152
|
+
- the active workflow declaring a **`reviewEntry: true`** state (otherwise:
|
|
153
|
+
`gtd review: the active workflow declares no review entry state`);
|
|
154
|
+
- `<commitish>` resolving to a commit, being an **ancestor of HEAD**, and
|
|
155
|
+
**differing from HEAD** (nothing to review otherwise).
|
|
156
|
+
|
|
157
|
+
On success, writes ONE empty commit, `gtd(human): <review-entry-state>`,
|
|
158
|
+
carrying the resolved commit's full hash as a `Gtd-Review-Base: <hash>` trailer
|
|
159
|
+
(mirroring how `gtd step --cost` writes its own `Gtd-Cost:` trailer). Everything
|
|
160
|
+
downstream that renders a diff — `it.processDiff`, and the review checkout
|
|
161
|
+
window opened by a downstream `reviewWindow: true` state — keys off the
|
|
162
|
+
process's diff base, and this trailer is exactly how that base gets re-pointed
|
|
163
|
+
at `<commitish>..HEAD` (see
|
|
164
|
+
[STATES.md §7](../STATES.md#7-retry)/[§11](../STATES.md#11-the-review-checkout-window)).
|
|
165
|
+
|
|
166
|
+
Plain-mode output is one line, same shape as `gtd step`:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
committed: gtd(human): reviewing
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`--json` emits `{state, subject}` — `state` is the entered review-entry state,
|
|
173
|
+
`subject` the bare commit subject (the trailer is not echoed).
|
|
174
|
+
|
|
175
|
+
Takes exactly one positional argument (`<commitish>`); missing or extra
|
|
176
|
+
arguments are usage errors.
|
|
177
|
+
|
|
106
178
|
## `gtd next [--json]`
|
|
107
179
|
|
|
108
180
|
Pure emitter of the resolved rest's rendered content — it **never mutates** the
|
|
@@ -247,9 +319,9 @@ Then:
|
|
|
247
319
|
approve), has nothing to validate and exits `0`
|
|
248
320
|
(`nothing to validate at "<state>"`). Nothing is formatted in that case.
|
|
249
321
|
|
|
250
|
-
This is how the
|
|
251
|
-
in-machine validation state — and the check runs whoever last touched the
|
|
252
|
-
agent or human:
|
|
322
|
+
This is how the `simple` template keeps its steering files well-formed without
|
|
323
|
+
an in-machine validation state — and the check runs whoever last touched the
|
|
324
|
+
file, agent or human:
|
|
253
325
|
|
|
254
326
|
- **The producing agent self-validates.** Plain `gtd next` appends a "run
|
|
255
327
|
`gtd validate` and fix all violations" instruction to a `prompt` rest that
|
|
@@ -330,8 +402,9 @@ with no `.gtdrc` in sight. Also registers an `executeCommand`,
|
|
|
330
402
|
naming the state instead — bind it to an editor keybinding for a "jump to the
|
|
331
403
|
active steering file" command.
|
|
332
404
|
|
|
333
|
-
Dispatched before the repository-root guard and
|
|
334
|
-
git/workflow state of its own
|
|
405
|
+
Dispatched before the repository-root guard and the config-reading path — the
|
|
406
|
+
server needs no git/workflow state of its own (like `gtd init`, it runs with no
|
|
407
|
+
workflow configured). Rejects `--json` (exit 1,
|
|
335
408
|
`gtd lsp does not accept --json`) and extra positional arguments — it's a
|
|
336
409
|
long-running server, not a state command. Runs until the client disconnects (the
|
|
337
410
|
LSP `exit` notification), then exits cleanly.
|
|
@@ -362,8 +435,8 @@ the plain-text one.
|
|
|
362
435
|
report, a log file — into the working tree, the tree never goes clean after a
|
|
363
436
|
green run, and the check's `"C"` pattern never fires. Gitignore every path
|
|
364
437
|
your scripts write before wiring gtd into a repo.
|
|
365
|
-
- **Repository root invocation.** Every state subcommand (`step`/`
|
|
366
|
-
`status`/`mermaid`) must run from the git repository root — the
|
|
367
|
-
pending changes, and process history are resolved against the
|
|
368
|
-
`--help`/`--version`, `format`, and `lsp` skip this guard
|
|
369
|
-
git/`.gtdrc` dependency along with it).
|
|
438
|
+
- **Repository root invocation.** Every state subcommand (`step`/`review`/
|
|
439
|
+
`next`/`status`/`mermaid`) must run from the git repository root — the
|
|
440
|
+
workflow, pending changes, and process history are resolved against the
|
|
441
|
+
process cwd. `--help`/`--version`, `format`, and `lsp` skip this guard
|
|
442
|
+
entirely (and any git/`.gtdrc` dependency along with it).
|
package/docs/configuration.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Configuration
|
|
2
2
|
|
|
3
|
-
gtd reads
|
|
4
|
-
[cosmiconfig](https://github.com/cosmiconfig/cosmiconfig).
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
gtd reads a required `.gtdrc` config file via
|
|
4
|
+
[cosmiconfig](https://github.com/cosmiconfig/cosmiconfig). gtd ships **no**
|
|
5
|
+
default workflow: scaffold one for the repo with [`gtd init`](#gtd-init) (once),
|
|
6
|
+
which writes a `.gtdrc.json` carrying a bundled workflow template inline. A
|
|
7
|
+
state command run with no `workflow:` configured fails, pointing you at
|
|
8
|
+
`gtd init`. Supported filenames (searched in this order):
|
|
8
9
|
|
|
9
10
|
- `.gtdrc`
|
|
10
11
|
- `.gtdrc.json`
|
|
@@ -17,16 +18,17 @@ bundled default workflow applies (see
|
|
|
17
18
|
|
|
18
19
|
v3's `.gtdrc` has exactly three blessed top-level keys:
|
|
19
20
|
|
|
20
|
-
- **`workflow`** (object,
|
|
21
|
-
plus its own `vars:` defaults and `modes:`), compiled by
|
|
22
|
-
`src/PatternConfig.ts`. Absent =
|
|
21
|
+
- **`workflow`** (object, **required**) — the whole machine definition (its
|
|
22
|
+
states, plus its own `vars:` defaults and `modes:`), compiled by
|
|
23
|
+
`src/PatternConfig.ts`. Absent = a hard error pointing at
|
|
24
|
+
[`gtd init`](#gtd-init); there is no bundled default. See
|
|
23
25
|
["The `workflow:` key" below](#the-workflow-key) for its schema.
|
|
24
26
|
- **`vars`** (object, optional) — a flat `name -> scalar` map, one layer of the
|
|
25
27
|
merged `it.vars` every template sees — see ["Variables"](#variables) below.
|
|
26
28
|
- **`modes`** (object, optional) — steering-file modes (`format:`/`validate:`
|
|
27
29
|
shell commands), layered over the active workflow's own `modes:` and gtd's
|
|
28
30
|
built-in validators, so a project can plug its formatter or linter into the
|
|
29
|
-
|
|
31
|
+
configured workflow without re-declaring that mode on the workflow itself. See
|
|
30
32
|
["`modes:`"](#modes--pluggable-steering-file-modes) below.
|
|
31
33
|
- **`$schema`** (string, optional) — stripped before validation, so it never
|
|
32
34
|
counts as an unknown key. Point it at the published schema for editor-backed
|
|
@@ -37,16 +39,18 @@ Any other top-level key is **rejected** (`onExcessProperty: "error"`) — v3 has
|
|
|
37
39
|
no `testCommand`, `fixAttemptCap`, `reviewThreshold`, `agenticReview`, `squash`,
|
|
38
40
|
`learning`, `decisionLog`, or `models` keys; all of that machinery is gone (see
|
|
39
41
|
[Upgrading](upgrading.md)). The engine blesses no VARIABLE NAMES either —
|
|
40
|
-
`testCommand` (the bundled
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
`testCommand` (the bundled templates' own var, see ["Variables"](#variables)) is
|
|
43
|
+
workflow-authored data like any other `it.vars` entry, not a special key gtd
|
|
44
|
+
interprets.
|
|
43
45
|
|
|
44
46
|
## The `workflow:` key
|
|
45
47
|
|
|
46
48
|
The `workflow:` key is the **only** definition source — there is no `extends`,
|
|
47
|
-
no merge-over-a-built-in
|
|
48
|
-
|
|
49
|
-
`
|
|
49
|
+
no merge-over-a-built-in. The bundled templates `gtd init` scaffolds are
|
|
50
|
+
themselves YAML assets (`src/workflows/simple.yaml`,
|
|
51
|
+
`src/workflows/advanced.yaml`) compiled through the exact same compiler
|
|
52
|
+
(`compileWorkflowConfig`); `gtd init` just writes one of them, inline, under
|
|
53
|
+
this key. Its shape:
|
|
50
54
|
|
|
51
55
|
```yaml
|
|
52
56
|
workflow:
|
|
@@ -219,9 +223,9 @@ Because `grilling` re-enters itself around the answer loop, every lap emits
|
|
|
219
223
|
`building` emits a different label (`build`), which is where the driver clears
|
|
220
224
|
memory for a fresh implementation turn. A loop of same-labelled turns retains; a
|
|
221
225
|
differently-labelled state at a phase boundary clears. This is exactly how the
|
|
222
|
-
|
|
223
|
-
see [STATES.md §10](../STATES.md#10-the-bundled-
|
|
224
|
-
loop driver reads it is spelled out in `skills/loop/SKILL.md`.
|
|
226
|
+
`simple` template scopes its four agent states (`plan`/`build`/`fix`/`review` —
|
|
227
|
+
see [STATES.md §10](../STATES.md#10-the-bundled-workflow-templates)), and how
|
|
228
|
+
the loop driver reads it is spelled out in `skills/loop/SKILL.md`.
|
|
225
229
|
|
|
226
230
|
Like `model`, `memory:` is rendered as an Eta template through the same context
|
|
227
231
|
as the state's content — a plain label (`plan`) passes through unchanged, while
|
|
@@ -239,7 +243,8 @@ A state may additionally declare `file:` — an Eta template naming THE steering
|
|
|
239
243
|
file this state is about: the file a human/editor should look at while the
|
|
240
244
|
machine rests here (rendered through the same `it.vars`-carrying context as
|
|
241
245
|
content/`model`; must render non-empty). Forbidden on a commit state (never at
|
|
242
|
-
rest). Multiple states may share one `file:` (and, in the
|
|
246
|
+
rest). Multiple states may share one `file:` (and, in the `simple` template,
|
|
247
|
+
do):
|
|
243
248
|
|
|
244
249
|
```yaml
|
|
245
250
|
workflow:
|
|
@@ -357,16 +362,20 @@ So for a state declaring `mode: qa`:
|
|
|
357
362
|
| both | its `format:` | its `validate:` |
|
|
358
363
|
|
|
359
364
|
That is what makes the built-in modes extensible rather than all-or-nothing —
|
|
360
|
-
and the top-level key means a project
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
365
|
+
and the top-level key means a project can plug its formatter into whichever
|
|
366
|
+
workflow it scaffolded (`gtd init simple`/`advanced`) without re-declaring a
|
|
367
|
+
`modes:` block on the workflow itself. Add it alongside the `workflow:` key in
|
|
368
|
+
your `.gtdrc.json`:
|
|
369
|
+
|
|
370
|
+
```jsonc
|
|
371
|
+
// .gtdrc.json — the workflow from `gtd init`, plus your own markdown formatter
|
|
372
|
+
{
|
|
373
|
+
"workflow": { "...": "..." },
|
|
374
|
+
"modes": {
|
|
375
|
+
"qa": { "format": "npx prettier --write <%= it.file %>" },
|
|
376
|
+
"review": { "format": "npx prettier --write <%= it.file %>" },
|
|
377
|
+
},
|
|
378
|
+
}
|
|
370
379
|
```
|
|
371
380
|
|
|
372
381
|
**Known limitation — no live editor support for a custom mode.** `gtd lsp`
|
|
@@ -411,13 +420,50 @@ workflow:
|
|
|
411
420
|
"* **": building
|
|
412
421
|
```
|
|
413
422
|
|
|
414
|
-
The
|
|
423
|
+
The `simple` template enables `reviewWindow: true` on `await-review` (no
|
|
415
424
|
`reviewBase` state, so the base is the whole cycle). The pure engine never
|
|
416
425
|
observes an open window — it is opened/closed entirely at the edge; the real
|
|
417
426
|
head is preserved under `refs/gtd/review-head` (the base under
|
|
418
427
|
`refs/gtd/review-base`) for the window's lifetime. See
|
|
419
428
|
[STATES.md §11](../STATES.md) for the full lifecycle.
|
|
420
429
|
|
|
430
|
+
### `reviewEntry:` — the review entry point (`gtd review <commitish>`)
|
|
431
|
+
|
|
432
|
+
A state may separately declare `reviewEntry: true` (at most one across the whole
|
|
433
|
+
workflow; forbidden on a commit state and on the initial state). It marks the
|
|
434
|
+
state [`gtd review <commitish>`](cli.md#gtd-review-commitish---json) enters to
|
|
435
|
+
start a BRAND NEW process reviewing `<commitish>..HEAD` — e.g. a colleague's PR
|
|
436
|
+
branch with no gtd process of its own — reusing whatever `on`/
|
|
437
|
+
`reviewWindow`/`reviewBase` machinery that state and its downstream states
|
|
438
|
+
already declare, with zero duplicated logic.
|
|
439
|
+
|
|
440
|
+
```yaml
|
|
441
|
+
workflow:
|
|
442
|
+
states:
|
|
443
|
+
# …
|
|
444
|
+
review:
|
|
445
|
+
actor: agent
|
|
446
|
+
reviewEntry: true # `gtd review <commitish>` starts a new process here
|
|
447
|
+
prompt: summarize <%~ it.processDiff %> for a human to check
|
|
448
|
+
on:
|
|
449
|
+
"* **": await-review
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
`gtd review <commitish>` requires resting at the workflow's initial state with a
|
|
453
|
+
clean tree, and requires the active workflow to declare a `reviewEntry` state.
|
|
454
|
+
It resolves `<commitish>` (which must name an ancestor of HEAD other than HEAD
|
|
455
|
+
itself) and writes one empty `gtd(human): <review-entry-state>` turn commit
|
|
456
|
+
carrying the resolved hash as a `Gtd-Review-Base:` trailer — read back by
|
|
457
|
+
`computeProcessRun` to override the new process's diff base (`it.startCommit`
|
|
458
|
+
and `it.processDiff` then cover `<commitish>..HEAD`, and a downstream
|
|
459
|
+
`reviewWindow: true` state's checkout window opens over that same range). The
|
|
460
|
+
process's `retry`/squash trace boundary is untouched: the entry commit's own
|
|
461
|
+
parent is a non-workflow commit, so the ordinary boundary rule already stops
|
|
462
|
+
there. See [STATES.md §11](../STATES.md#11-the-review-checkout-window) for the
|
|
463
|
+
full mechanism.
|
|
464
|
+
|
|
465
|
+
The bundled default enables `reviewEntry: true` on `reviewing` itself.
|
|
466
|
+
|
|
421
467
|
### Template variables
|
|
422
468
|
|
|
423
469
|
Every `script`/`prompt`/`message`/`commit`/`model`/`memory`/`file` template is
|
|
@@ -425,7 +471,7 @@ rendered as an Eta template (`it.<name>`) with:
|
|
|
425
471
|
|
|
426
472
|
| Variable | Meaning |
|
|
427
473
|
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
428
|
-
| `startCommit` | The
|
|
474
|
+
| `startCommit` | The current process's diff base — normally the process start, but re-pointed to `<commitish>`'s hash for a process `gtd review <commitish>` started (see ["`reviewEntry:`"](#reviewentry--the-review-entry-point-gtd-review-commitish)). |
|
|
429
475
|
| `currentCommit` | HEAD's hash at render time. |
|
|
430
476
|
| `previousCommit` | The hash before the last transition (HEAD's parent, in-process). |
|
|
431
477
|
| `state` | The state whose content is being rendered. |
|
|
@@ -491,10 +537,10 @@ Every template — `script`/`prompt`/`message`/`commit`, and `model`/`memory`/
|
|
|
491
537
|
layers, **later wins**:
|
|
492
538
|
|
|
493
539
|
1. **The workflow's own `vars:` key** (sibling to `states:`, shown above) — the
|
|
494
|
-
workflow author's declared defaults. The
|
|
540
|
+
workflow author's declared defaults. The `simple` template declares
|
|
495
541
|
`vars: { testCommand: "npm test" }`, read by `checking`'s script as
|
|
496
542
|
`<%~ it.vars.testCommand %>` (see
|
|
497
|
-
[STATES.md §10](../STATES.md#10-the-bundled-
|
|
543
|
+
[STATES.md §10](../STATES.md#10-the-bundled-workflow-templates)).
|
|
498
544
|
2. **A top-level `.gtdrc` `vars:` key** (a sibling of `workflow:`, NOT nested
|
|
499
545
|
inside it) — per-repo tuning without redefining the whole workflow. Subject
|
|
500
546
|
to the same cwd→home deep merge as everything else in `.gtdrc` (innermost
|
|
@@ -512,7 +558,7 @@ alongside every other config-shape finding (see
|
|
|
512
558
|
already strings.
|
|
513
559
|
|
|
514
560
|
```yaml
|
|
515
|
-
# .gtdrc — overriding the
|
|
561
|
+
# .gtdrc — overriding the `simple` template's testCommand
|
|
516
562
|
vars:
|
|
517
563
|
testCommand: npm run test:ci
|
|
518
564
|
```
|
|
@@ -598,19 +644,38 @@ finds along the way. All found levels are **deep-merged**, with the **innermost
|
|
|
598
644
|
directory cascades to every checkout beneath it, while any individual checkout
|
|
599
645
|
can still override with its own `.gtdrc`.
|
|
600
646
|
|
|
601
|
-
##
|
|
647
|
+
## `gtd init`
|
|
648
|
+
|
|
649
|
+
gtd ships **no** default workflow, so a repo must scaffold one before any state
|
|
650
|
+
command works:
|
|
651
|
+
|
|
652
|
+
```bash
|
|
653
|
+
gtd init simple # or: gtd init advanced
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
`gtd init <workflow>` writes a `.gtdrc.json` at the repository root with the
|
|
657
|
+
chosen bundled template's whole workflow inline under a `workflow:` key, plus a
|
|
658
|
+
`$schema` link (so editors pick up completion/validation). The two templates:
|
|
659
|
+
|
|
660
|
+
- **`simple`** — the 10-state machine walked through in
|
|
661
|
+
[STATES.md §10](../STATES.md#10-the-bundled-workflow-templates): idle →
|
|
662
|
+
grilling ⇄ grilling-answer → building → checking ⇄ fixing (→ escalate) →
|
|
663
|
+
reviewing → await-review, resting back at idle on approval (no squash).
|
|
664
|
+
- **`advanced`** — the fuller machine (two-phase Q&A planning, an architecture
|
|
665
|
+
phase, task decomposition, a per-task build queue, and a squash finale),
|
|
666
|
+
walked through at
|
|
667
|
+
[docs/examples/advanced-workflow.md](examples/advanced-workflow.md).
|
|
668
|
+
|
|
669
|
+
The file is written **uncommitted** — review it, then commit it before your
|
|
670
|
+
first `gtd step` (an uncommitted `.gtdrc.json` is a pending change the initial
|
|
671
|
+
state's `* **` edge would otherwise capture). `gtd init` refuses if any gtd
|
|
672
|
+
config already exists (remove it first to re-init), requires the repository
|
|
673
|
+
root, and is one of the two commands (with `gtd lsp`) that run with no workflow
|
|
674
|
+
configured. A state command run before `gtd init` fails with:
|
|
602
675
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
`$schema` link. Auto-init never runs for `--version`/`--help`, `format`,
|
|
607
|
-
bare/unknown commands, or an invocation refused by the repo-root guard — those
|
|
608
|
-
perform no repository mutation of any kind. On a repo with no commits yet, or
|
|
609
|
-
whose HEAD isn't a `gtd(actor): state` commit, the stub is committed as its own
|
|
610
|
-
`chore: add .gtdrc.json`. If HEAD is already a `gtd(actor): state` commit
|
|
611
|
-
(mid-process), the stub is instead **amended into HEAD** — stacking a fresh
|
|
612
|
-
boundary commit there would produce an unrecognized HEAD that resolves back to
|
|
613
|
-
the workflow's initial state.
|
|
676
|
+
```
|
|
677
|
+
gtd: no workflow configured — run `gtd init <simple|advanced>` to create .gtdrc.json
|
|
678
|
+
```
|
|
614
679
|
|
|
615
680
|
## A complete example
|
|
616
681
|
|
|
@@ -683,8 +748,8 @@ agent-encoded verdict") for the worked example.
|
|
|
683
748
|
|
|
684
749
|
## A fuller example: two-phase planning, task decomposition, agent-prepared review
|
|
685
750
|
|
|
686
|
-
The
|
|
687
|
-
planning loops, an architecture phase, task
|
|
688
|
-
per-task `picking` arbiter, and agent-prepared
|
|
689
|
-
|
|
690
|
-
|
|
751
|
+
The example above is deliberately small (it is close to the `simple` template).
|
|
752
|
+
For a heavier machine — Q&A planning loops, an architecture phase, task
|
|
753
|
+
decomposition, the deterministic per-task `picking` arbiter, and agent-prepared
|
|
754
|
+
`.gtd/REVIEW.md` review — run `gtd init advanced`, walked through at
|
|
755
|
+
[docs/examples/advanced-workflow.md](examples/advanced-workflow.md).
|
package/docs/development.md
CHANGED
|
@@ -31,16 +31,18 @@ registry to keep in sync: a workflow's content strings are either inline in its
|
|
|
31
31
|
YAML/`.gtdrc` or a `./`-relative file reference auto-inlined at config load
|
|
32
32
|
(`src/PatternConfig.ts`) — see
|
|
33
33
|
[Configuration](configuration.md#content-values-inline-or-a-file-reference). The
|
|
34
|
-
bundled
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(`src/workflows/
|
|
34
|
+
bundled workflow templates (`src/workflows/simple.yaml`,
|
|
35
|
+
`src/workflows/advanced.yaml`) `gtd init` scaffolds are imported as raw text via
|
|
36
|
+
tsdown's `.yaml`-as-text loader (`tsdown.config.ts`) and compiled through the
|
|
37
|
+
same path a `.gtdrc` `workflow:` key goes through (`src/workflows/templates.ts`)
|
|
38
|
+
— no privileged code path.
|
|
38
39
|
|
|
39
40
|
`npm run dev` runs `src/main.ts` directly via Node's native TypeScript
|
|
40
41
|
type-stripping (requires Node 22.6+). It registers `dev/hooks.mjs`, which
|
|
41
42
|
resolves `./Foo.js` specifiers to the on-disk `./Foo.ts` and imports `*.yaml`
|
|
42
43
|
files as raw text, mirroring tsdown's `.yaml`-as-text loader — this is what lets
|
|
43
|
-
`src/workflows/
|
|
44
|
+
`src/workflows/simple.yaml` and `src/workflows/advanced.yaml` resolve when
|
|
45
|
+
running from source.
|
|
44
46
|
|
|
45
47
|
The decision core is pure and IO-free: the pattern machine's shape (states,
|
|
46
48
|
patterns, retry) is a plain-data `WorkflowDefinition` (`src/PatternMachine.ts`),
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# The `advanced` template: the full grilling → architecting → decompose → picking → review machine
|
|
2
2
|
|
|
3
|
-
This
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
This walks through the **`advanced`** bundled workflow template — the fuller
|
|
4
|
+
machine `gtd init advanced` scaffolds (`src/workflows/advanced.yaml`). The other
|
|
5
|
+
bundled template, **`simple`** (`gtd init simple`), is the smaller 10-state
|
|
6
|
+
machine walked through in
|
|
7
|
+
[STATES.md §10](../../STATES.md#10-the-bundled-workflow-templates) — including
|
|
8
|
+
the two steering-file validation loops it carries over `.gtd/TODO.md` and
|
|
9
|
+
`.gtd/REVIEW.md`, which this machine's own `grilling`/`reviewing` phases predate
|
|
10
|
+
and don't validate. `gtd init advanced` writes the block below directly, so you
|
|
11
|
+
normally don't paste it by hand; it's reproduced here as the annotated
|
|
12
|
+
reference.
|
|
11
13
|
|
|
12
|
-
Compared to the
|
|
14
|
+
Compared to the `simple` template, this machine adds:
|
|
13
15
|
|
|
14
16
|
- **Two-phase human-in-the-loop planning with Q&A loops** — `grilling` ⇄
|
|
15
17
|
`grilling-answer` develops a product-level plan from `.gtd/TODO.md` one open
|
|
@@ -23,12 +25,15 @@ Compared to the simplified bundled default, this machine adds:
|
|
|
23
25
|
`checking`/`fixing` loop, until the queue empties.
|
|
24
26
|
- **Agent-prepared review** — `reviewing` has the agent write `.gtd/REVIEW.md`
|
|
25
27
|
summarizing the full cycle diff for a human to check before `await-review`
|
|
26
|
-
resolves an approval or feedback.
|
|
28
|
+
resolves an approval or feedback. `reviewing` also declares
|
|
29
|
+
`reviewEntry: true`, so `gtd review <commitish>` can start a review process
|
|
30
|
+
here directly over `<commitish>..HEAD` (e.g. a colleague's PR branch) — see
|
|
31
|
+
[STATES.md §11](../../STATES.md#11-the-review-checkout-window).
|
|
27
32
|
- **A squash finale** — approval at `await-review` moves to `squashing` (the
|
|
28
33
|
agent authors `.gtd/COMMIT_MSG.md`) and then `done`, a `commit:` state that
|
|
29
|
-
squashes the whole cycle into one commit. The
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
squashes the whole cycle into one commit. The `simple` template drops this: it
|
|
35
|
+
rests at `idle` on approval instead and leaves every turn commit in history
|
|
36
|
+
for the human to squash (or not) however they choose.
|
|
32
37
|
|
|
33
38
|
This example also carries `file:`/`mode:` annotations on every state that rests
|
|
34
39
|
on a steering file (see the state table below and
|
|
@@ -41,11 +46,12 @@ actions/diagnostics off those declarations rather than a hardcoded basename:
|
|
|
41
46
|
`review`-format (`vars.reviewFile`), and `fixing`/`escalate` declare `file:`
|
|
42
47
|
alone (`vars.feedbackFile` is plain text, no LSP format).
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
Running `gtd init advanced` writes this whole definition into `.gtdrc.json`
|
|
50
|
+
under a `workflow:` key for you. The block below is the same definition in YAML
|
|
51
|
+
form (the source is `src/workflows/advanced.yaml`), nested under `workflow:` —
|
|
52
|
+
paste it into your own `.gtdrc`/`.gtdrc.yaml` if you'd rather hand-author or
|
|
53
|
+
tweak it. See [Configuration](../configuration.md) for the `.gtdrc` schema this
|
|
54
|
+
slots into.
|
|
49
55
|
|
|
50
56
|
## State table
|
|
51
57
|
|
|
@@ -222,7 +228,7 @@ workflow:
|
|
|
222
228
|
actor: check
|
|
223
229
|
script: |
|
|
224
230
|
#!/usr/bin/env bash
|
|
225
|
-
# gtd check turn (the queue arbiter) — the driver
|
|
231
|
+
# gtd check turn (the queue arbiter) — the loop driver executes
|
|
226
232
|
# this verbatim, then steps the check actor. Mechanics only: take the
|
|
227
233
|
# first task file (by name) under .gtd/tasks/ into .gtd/NEXT.md, or
|
|
228
234
|
# remove .gtd/NEXT.md when the queue is empty. What NEXT.md's
|
|
@@ -265,7 +271,7 @@ workflow:
|
|
|
265
271
|
actor: check
|
|
266
272
|
script: |
|
|
267
273
|
#!/usr/bin/env bash
|
|
268
|
-
# gtd check turn — the driver
|
|
274
|
+
# gtd check turn — the loop driver executes this verbatim, then
|
|
269
275
|
# steps the check actor. Mechanics only: run the test suite and record a
|
|
270
276
|
# red run's output as .gtd/FEEDBACK.md. What that output MEANS (another
|
|
271
277
|
# fix round vs escalation) is decided by the workflow's own `on`/`retry`
|
|
@@ -333,6 +339,10 @@ workflow:
|
|
|
333
339
|
file: <%= it.vars.reviewFile %>
|
|
334
340
|
mode: review
|
|
335
341
|
model: smart
|
|
342
|
+
# A second way in: `gtd review <commitish>` (clean tree, resting at the
|
|
343
|
+
# initial state) enters here directly over <commitish>..HEAD — see
|
|
344
|
+
# STATES.md §11.
|
|
345
|
+
reviewEntry: true
|
|
336
346
|
prompt: |
|
|
337
347
|
You are an autonomous coding agent. `.gtd/` holds this workflow's own
|
|
338
348
|
state — never create, edit, or delete anything under `.gtd/` except
|
|
@@ -429,8 +439,8 @@ event) accepts the current phase's draft and moves on; any other pending change
|
|
|
429
439
|
loops back for another round. `picking` is a `script` state whose only job is to
|
|
430
440
|
inspect `.gtd/tasks/` (a tree property patterns can't see directly) and turn it
|
|
431
441
|
into a diff patterns CAN see — see the walkthrough in
|
|
432
|
-
[STATES.md §10](../../STATES.md#10-the-bundled-
|
|
433
|
-
that section frozen alongside this example) for the full state-by-state
|
|
442
|
+
[STATES.md §10](../../STATES.md#10-the-bundled-workflow-templates) (the version
|
|
443
|
+
of that section frozen alongside this example) for the full state-by-state
|
|
434
444
|
narrative, including the `on`-declaration-order subtlety at `picking` and the
|
|
435
445
|
`fixing` retry-cap pooling caveat.
|
|
436
446
|
|