@pmelab/gtd 2.8.0 → 3.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 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`, reviews in
25
- `.gtd/REVIEW.md`. Answer the agent's questions inline, approve by ticking
26
- checkboxes — all in your own editor. There is no chat UI to lose.
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 budgeted. When the cap is hit, gtd
31
- stops and escalates to a human instead of burning tokens rewriting the same
32
- test for the 47th time.
33
- - **Clean history.** When the feature ships, all the intermediate `gtd:` commits
34
- squash into one conventional commit — as if a very disciplined engineer did it
35
- in one sitting.
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
- Three commands drive everything:
55
-
56
- - **`gtd step`** — advance the workflow as the **human** actor.
57
- - **`gtd step-agent`** — advance the workflow as the **agent** actor.
58
- - **`gtd next`** — print the prompt for whichever actor is currently awaited,
59
- without mutating anything.
60
-
61
- The loop is two beats, repeated: run `gtd step-agent`, then `gtd next --json`.
62
- If the `actor` field says `"agent"`, feed the prompt to your agent and repeat;
63
- if it says `"human"`, stop — it's your move. You act by editing files (answering
64
- questions, reviewing the diff in your editor, fixing code) and running
65
- `gtd step`.
66
-
67
- Along the way, gtd grills your idea into a product plan, then a technical
68
- architecture, decomposes it into work packages, builds them one at a time, runs
69
- your tests after every package, has the agent review its own diff, walks you
70
- through a final review, and squashes the whole cycle into one clean commit.
71
-
72
- You don't have to start at the beginning: the steering file you hand the entry
73
- turn picks the phase — plain notes start product grilling,
74
- `.gtd/ARCHITECTURE.md` starts technical grilling, a final `.gtd/PLAN.md` goes
75
- straight to decomposition, and a hand-written `.gtd/HEALTH.md` goes straight
76
- into the error-fixing loop. See
77
- [Entry points](docs/workflow.md#entry-points-which-file-starts-the-cycle-where).
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 test command writes.
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, auto-init
96
- - [Upgrading from v1](docs/upgrading-from-v1.md) — breaking changes and
97
- migration
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 two-beat protocol (docs/loop.md "The reference loop driver") to a
5
- # human gate. Both mutators are attempted every iteration, refusal-tolerant:
6
- # whichever actor is actually awaited claims the turn (captures the human's
7
- # uncommitted edit after a halt, or the agent's own edit from the previous
8
- # iteration), the other refuses harmlessly.
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
- prev_prompt=""
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
- prompt="$(jq -r .prompt <<<"$next_json")"
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 [[ "$actor" != "agent" ]]; then
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 [[ "$pending" == "true" ]]; then
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
- prev_prompt=""
48
+ prev_content=""
37
49
  continue
38
50
  fi
39
51
 
40
- # Stall detection (skills/loop/SKILL.md): the same agent-owned state and
41
- # prompt repeating means the last dispatch made no progress — stop rather
42
- # than spin on it.
43
- if [[ "$state" == "$prev_state" && "$prompt" == "$prev_prompt" ]]; then
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
- prev_prompt="$prompt"
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
- cmd='claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions'
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="$prompt" bash -c "$cmd"
76
+ GTD_LOOP_PROMPT="$content" GTD_LOOP_MODEL="$model" bash -c "$cmd"
77
+ gtd step "$actor" >/dev/null
58
78
  done