@pmelab/gtd 2.8.0 → 3.1.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 +61 -40
- package/bin/gtd-loop +43 -23
- package/dist/gtd.bundle.mjs +2511 -3481
- package/docs/cli.md +222 -281
- package/docs/configuration.md +350 -71
- package/docs/design/configurable-state-machine.md +1439 -0
- package/docs/design/delta-purity-plan.md +283 -0
- package/docs/design/pattern-machine-plan.md +164 -0
- package/docs/design/scripted-actor.md +289 -0
- package/docs/design/state-file-association.md +112 -0
- package/docs/design/state-machine-validation.md +437 -0
- package/docs/design/steering-file-loops.md +164 -0
- package/docs/design/work-packages.md +194 -0
- package/docs/development.md +55 -36
- package/docs/examples/advanced-workflow.md +428 -0
- package/docs/loop.md +60 -60
- package/docs/upgrading.md +125 -0
- package/package.json +2 -2
- package/schema.json +89 -65
- package/docs/upgrading-from-v1.md +0 -45
- package/docs/workflow.md +0 -428
package/README.md
CHANGED
|
@@ -21,18 +21,20 @@ No chat scrollback. No lost sessions. No infinite fix loops. Just git.
|
|
|
21
21
|
- **Shareable.** Push the branch, and the workflow travels with it — the state
|
|
22
22
|
lives in the commits, so another machine (or another person) picks up exactly
|
|
23
23
|
where you left off.
|
|
24
|
-
- **Files, not chat.** Plans live in `.gtd/TODO.md
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
- **Files, not chat.** Plans live in `.gtd/TODO.md`. Request changes by editing
|
|
25
|
+
it, approve by leaving the tree clean — all in your own editor. There is no
|
|
26
|
+
chat UI to lose.
|
|
27
27
|
- **Harness agnostic.** gtd emits prompts to stdout (or JSON). Claude Code, a
|
|
28
28
|
bash loop, a CI job, or you reading it out loud — the workflow doesn't care
|
|
29
29
|
who executes it.
|
|
30
|
-
- **Bounded, not runaway.** Fix attempts are
|
|
31
|
-
|
|
32
|
-
test for the 47th time.
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
- **Bounded, not runaway.** Fix attempts are capped (`retry` on a state). When
|
|
31
|
+
the cap is hit, gtd redirects to a human gate instead of burning tokens
|
|
32
|
+
rewriting the same test for the 47th time.
|
|
33
|
+
- **Your call on history.** Every intermediate `gtd(actor): state` commit is a
|
|
34
|
+
real, attributed commit — nothing hidden in chat. Squash them into one
|
|
35
|
+
conventional commit if you want that (an interactive rebase, an amend, a PR's
|
|
36
|
+
squash-merge, or a custom workflow with a `commit:` finale), or don't — gtd
|
|
37
|
+
makes no assumption.
|
|
36
38
|
|
|
37
39
|
## Install
|
|
38
40
|
|
|
@@ -51,30 +53,41 @@ schema stub on first run (see [Configuration](docs/configuration.md#auto-init)).
|
|
|
51
53
|
|
|
52
54
|
## How it works
|
|
53
55
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
gtd is a small **pattern machine**: named states, each awaiting one actor and
|
|
57
|
+
carrying one piece of content (a script, a prompt, a message, or a squash commit
|
|
58
|
+
template), with an ordered set of change-patterns routing to the next state.
|
|
59
|
+
Four commands drive it:
|
|
60
|
+
|
|
61
|
+
- **`gtd step <actor>`** — authenticate as `<actor>` and perform the one
|
|
62
|
+
transition the pending changes match.
|
|
63
|
+
- **`gtd next [--json]`** — print whichever actor is awaited and what they
|
|
64
|
+
should do, without mutating anything.
|
|
65
|
+
- **`gtd run`** — execute the awaited script (the only place gtd itself spawns a
|
|
66
|
+
subprocess), then step its actor.
|
|
67
|
+
- **`gtd status`** — a dry-run report of the resolved state and which pattern
|
|
68
|
+
each pending change matches.
|
|
69
|
+
|
|
70
|
+
The loop is one beat, repeated: run `gtd next --json` and dispatch on `kind` —
|
|
71
|
+
`"message"` means it's a human's move (stop and hand off); `"script"` means
|
|
72
|
+
`gtd run` it; `"prompt"` means feed `content` to your agent, then run
|
|
73
|
+
`gtd step <actor>` once it's done. See [STATES.md](STATES.md) for the model and
|
|
74
|
+
[Driving the loop](docs/loop.md) for the full protocol.
|
|
75
|
+
|
|
76
|
+
Along the way, the bundled default workflow develops your sketch into an
|
|
77
|
+
implementation plan — asking any open question it can't settle itself via a
|
|
78
|
+
deterministic `.gtd/TODO.md` format, validated before it ever reaches you —
|
|
79
|
+
builds it, runs your tests (looping on failures), and hands you a
|
|
80
|
+
`.gtd/REVIEW.md` checkbox review of the cycle's diff: tick a box to approve that
|
|
81
|
+
item, or edit/untick for feedback. Approving rests the cycle back at idle, with
|
|
82
|
+
every turn commit still sitting in history for you to squash however you like
|
|
83
|
+
(or not at all; gtd makes no assumption) — see
|
|
84
|
+
[STATES.md](STATES.md#10-the-bundled-default-workflow) for the full shape. A
|
|
85
|
+
heavier machine — two-phase Q&A planning, an architecture phase, task
|
|
86
|
+
decomposition, a per-task build loop, and a squash finale — is preserved as a
|
|
87
|
+
copy-paste `.gtdrc` example at
|
|
88
|
+
[docs/examples/advanced-workflow.md](docs/examples/advanced-workflow.md). The
|
|
89
|
+
workflow itself is just `.gtdrc` config — swap it for your own (see
|
|
90
|
+
[Configuration](docs/configuration.md)).
|
|
78
91
|
|
|
79
92
|
`gtd-loop`, installed alongside `gtd`, is a ready-to-run driver for the whole
|
|
80
93
|
protocol — point it at a repo and it runs the loop until it's your turn. See
|
|
@@ -82,21 +95,29 @@ protocol — point it at a repo and it runs the loop until it's your turn. See
|
|
|
82
95
|
|
|
83
96
|
Before wiring gtd into a repo, note the
|
|
84
97
|
[repository requirements](docs/cli.md#repository-requirements) — most
|
|
85
|
-
importantly: gitignore everything your
|
|
98
|
+
importantly: gitignore everything your scripts write.
|
|
99
|
+
|
|
100
|
+
Editor integration: `gtd lsp` starts an LSP server over stdio for `.gtd/`
|
|
101
|
+
steering files — symbols and check/uncheck actions over a `review`-mode file's
|
|
102
|
+
chunks, symbols over a `qa`-mode file's open questions, diagnostics for both
|
|
103
|
+
(live as you edit), and a `gtd.openSteeringFile` command that jumps to the
|
|
104
|
+
current state's steering file. Config-driven via each state's `file:`/`mode:`
|
|
105
|
+
(see [CLI reference](docs/cli.md#gtd-lsp)) — falls back to basename dispatch
|
|
106
|
+
(`TODO.md`/`REVIEW.md`) with no config in sight.
|
|
86
107
|
|
|
87
108
|
## Documentation
|
|
88
109
|
|
|
110
|
+
- [STATES.md](STATES.md) — the full pattern-machine specification: the model,
|
|
111
|
+
the pattern grammar, resolution, retry, the squash lifecycle, and the bundled
|
|
112
|
+
default workflow
|
|
89
113
|
- [CLI reference](docs/cli.md) — every command, exit codes, JSON schemas,
|
|
90
114
|
repository requirements
|
|
91
|
-
- [The workflow](docs/workflow.md) — states, grilling, budgets, the review gate,
|
|
92
|
-
learning, squash
|
|
93
115
|
- [Driving the loop](docs/loop.md) — the reference loop driver, `gtd-loop`,
|
|
94
116
|
custom agents
|
|
95
|
-
- [Configuration](docs/configuration.md) — `.gtdrc` schema, lookup,
|
|
96
|
-
-
|
|
97
|
-
|
|
117
|
+
- [Configuration](docs/configuration.md) — `.gtdrc` `workflow:` schema, lookup,
|
|
118
|
+
auto-init
|
|
119
|
+
- [Upgrading](docs/upgrading.md) — breaking changes and migration
|
|
98
120
|
- [Development](docs/development.md) — building, testing, releasing
|
|
99
|
-
- [STATES.md](STATES.md) — the full state-machine specification
|
|
100
121
|
|
|
101
122
|
## License
|
|
102
123
|
|
package/bin/gtd-loop
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
# Drives the
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
8
|
-
#
|
|
4
|
+
# Drives the v3 pattern-machine loop (see docs/loop.md): each iteration asks
|
|
5
|
+
# `gtd next --json` who's up and what they should do, dispatching on `kind`:
|
|
6
|
+
# - "message" (a human rest) -> halt, tell the user what gtd is waiting on.
|
|
7
|
+
# - "script" (a check rest) -> `gtd run` executes it and steps the check
|
|
8
|
+
# actor in one command; zero new commits = green with nothing owed (the
|
|
9
|
+
# terminal signal at idle).
|
|
10
|
+
# - "prompt" (an agent rest) -> feed `content` to the agent, then
|
|
11
|
+
# `gtd step <actor>` ourselves — the harness owns ending the turn, not
|
|
12
|
+
# the prompt text.
|
|
13
|
+
# `.model` (optional, opaque) is exported as $GTD_LOOP_MODEL for the agent
|
|
14
|
+
# adapter invoked at a "prompt" rest; the default adapter appends `--model
|
|
15
|
+
# "$GTD_LOOP_MODEL"` only when it's non-empty.
|
|
9
16
|
prev_state=""
|
|
10
|
-
|
|
17
|
+
prev_content=""
|
|
11
18
|
|
|
12
19
|
while true; do
|
|
13
|
-
gtd step --json >/dev/null 2>&1 || true
|
|
14
|
-
gtd step-agent --json >/dev/null 2>&1 || true
|
|
15
|
-
|
|
16
20
|
if ! next_json="$(gtd next --json 2>&1)"; then
|
|
17
21
|
echo "gtd-loop: could not determine the next step:" >&2
|
|
18
22
|
echo "$next_json" >&2
|
|
@@ -20,39 +24,55 @@ while true; do
|
|
|
20
24
|
exit 1
|
|
21
25
|
fi
|
|
22
26
|
|
|
23
|
-
actor="$(jq -r .actor <<<"$next_json")"
|
|
24
|
-
pending="$(jq -r .pending <<<"$next_json")"
|
|
25
27
|
state="$(jq -r .state <<<"$next_json")"
|
|
26
|
-
|
|
28
|
+
actor="$(jq -r .actor <<<"$next_json")"
|
|
29
|
+
kind="$(jq -r .kind <<<"$next_json")"
|
|
30
|
+
content="$(jq -r .content <<<"$next_json")"
|
|
31
|
+
model="$(jq -r '.model // empty' <<<"$next_json")"
|
|
27
32
|
|
|
28
|
-
if [[ "$
|
|
33
|
+
if [[ "$kind" == "message" ]]; then
|
|
29
34
|
echo "--- Your turn ($state) ---"
|
|
30
35
|
gtd next
|
|
31
36
|
exit 0
|
|
32
37
|
fi
|
|
33
38
|
|
|
34
|
-
if [[ "$
|
|
39
|
+
if [[ "$kind" == "script" ]]; then
|
|
40
|
+
head_before="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
41
|
+
gtd run
|
|
42
|
+
head_after="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
43
|
+
if [[ "$head_before" == "$head_after" ]]; then
|
|
44
|
+
echo "--- Settled ($state: check passed, nothing to do) ---"
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
35
47
|
prev_state=""
|
|
36
|
-
|
|
48
|
+
prev_content=""
|
|
37
49
|
continue
|
|
38
50
|
fi
|
|
39
51
|
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
# than spin on it.
|
|
43
|
-
if [[ "$state" == "$prev_state" && "$
|
|
52
|
+
# kind == "prompt": stall detection (skills/loop/SKILL.md) — the same
|
|
53
|
+
# agent-owned state and content repeating means the last dispatch made no
|
|
54
|
+
# progress; stop rather than spin on it.
|
|
55
|
+
if [[ "$state" == "$prev_state" && "$content" == "$prev_content" ]]; then
|
|
44
56
|
echo "gtd-loop: no progress at '$state' — the agent's last turn changed nothing. Stopping to avoid spinning." >&2
|
|
45
57
|
gtd next >&2
|
|
46
58
|
exit 1
|
|
47
59
|
fi
|
|
48
60
|
prev_state="$state"
|
|
49
|
-
|
|
61
|
+
prev_content="$content"
|
|
50
62
|
|
|
51
63
|
# Swappable agent adapter: GTD_LOOP_AGENT_CMD lets any coding agent CLI
|
|
52
|
-
# stand in for the default, receiving the prompt via $GTD_LOOP_PROMPT
|
|
64
|
+
# stand in for the default, receiving the prompt via $GTD_LOOP_PROMPT and
|
|
65
|
+
# the state's opaque model hint (if any) via $GTD_LOOP_MODEL. An adapter
|
|
66
|
+
# that ignores $GTD_LOOP_MODEL keeps working — it's exported alongside
|
|
67
|
+
# $GTD_LOOP_PROMPT, never required.
|
|
53
68
|
cmd="${GTD_LOOP_AGENT_CMD:-}"
|
|
54
69
|
if [[ -z "$cmd" ]]; then
|
|
55
|
-
|
|
70
|
+
if [[ -n "$model" ]]; then
|
|
71
|
+
cmd='claude -p "$GTD_LOOP_PROMPT" --model "$GTD_LOOP_MODEL" --dangerously-skip-permissions'
|
|
72
|
+
else
|
|
73
|
+
cmd='claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions'
|
|
74
|
+
fi
|
|
56
75
|
fi
|
|
57
|
-
GTD_LOOP_PROMPT="$
|
|
76
|
+
GTD_LOOP_PROMPT="$content" GTD_LOOP_MODEL="$model" bash -c "$cmd"
|
|
77
|
+
gtd step "$actor" >/dev/null
|
|
58
78
|
done
|