@pmelab/gtd 6.3.0 → 6.4.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
@@ -113,7 +113,10 @@ globally in one place (a `vars:` edit or a `GTD_VAR_plannerModel` override)
113
113
  instead of per state.
114
114
 
115
115
  `gtd-loop`, installed alongside `gtd`, is a ready-to-run driver for the whole
116
- protocol — point it at a repo and it runs the loop until it's your turn. See
116
+ protocol — point it at a repo and it runs the loop until it's your turn. It is
117
+ the only command you run: at a gate you edit files (answer a plan question, tick
118
+ a review box, fix code) and re-launch it, and it captures your edit as its
119
+ opening move before driving on — so you never run `gtd step human` by hand. See
117
120
  [Driving the loop](docs/loop.md).
118
121
 
119
122
  Before wiring gtd into a repo, note the
package/bin/gtd-loop CHANGED
@@ -64,6 +64,35 @@ run_agent_turn() {
64
64
  GTD_LOOP_SESSION_ID="$session_id" GTD_LOOP_MEMORY_RESUME="$do_resume" bash -c "$cmd"
65
65
  }
66
66
 
67
+ # Opening move: capture the human's pending edit so gtd-loop is the ONLY command
68
+ # a human runs. A human acts at a gate by editing files (a plan answer, a review
69
+ # tick, a code fix) and re-launching the loop — they should never have to run
70
+ # `gtd step human` by hand first. So before driving, if the machine currently
71
+ # rests at a human gate, step the human once to commit whatever they left, then
72
+ # fall into the loop below from the resulting state.
73
+ #
74
+ # We peek with the pure, mutation-free `gtd next --json` and step ONLY when it
75
+ # reports a human rest (`kind == "message"`): at an agent/check rest
76
+ # `gtd step human` would refuse out-of-turn (non-zero, aborting under `set -e`),
77
+ # and a mid-cycle restart must simply resume driving, not fail. A clean gate is
78
+ # a harmless no-op; a genuine refusal there (a malformed steering file, or an
79
+ # edit no `on` pattern accepts) is surfaced and stops the loop rather than being
80
+ # driven past.
81
+ if ! peek_json="$(gtd next --json 2>&1)"; then
82
+ echo "gtd-loop: could not determine the next step:" >&2
83
+ echo "$peek_json" >&2
84
+ echo "Run \`gtd status\` to inspect the repo." >&2
85
+ exit 1
86
+ fi
87
+ if [[ "$(jq -r .kind <<<"$peek_json")" == "message" ]]; then
88
+ if ! step_out="$(gtd step human 2>&1)"; then
89
+ echo "gtd-loop: could not capture your changes at the human gate:" >&2
90
+ echo "$step_out" >&2
91
+ echo "Fix the reported issue and re-run gtd-loop." >&2
92
+ exit 1
93
+ fi
94
+ fi
95
+
67
96
  while true; do
68
97
  if ! next_json="$(gtd next --json 2>&1)"; then
69
98
  echo "gtd-loop: could not determine the next step:" >&2
package/docs/loop.md CHANGED
@@ -28,8 +28,11 @@ A loop is a simple cycle:
28
28
  2. Repeat until a `"message"` rest halts the loop, or a zero-commit script step
29
29
  at idle settles it (the green terminal signal).
30
30
 
31
- A human acts by editing files (e.g. writing/editing `.gtd/TODO.md`, fixing code)
32
- and then running `gtd step human` to capture the edit as their turn.
31
+ A human acts by editing files (e.g. writing/editing `.gtd/TODO.md`, fixing
32
+ code); `gtd step human` captures the edit as their turn. A driver can run that
33
+ capture for the human as its opening move (see below), so re-launching the loop
34
+ is the only thing the human ever does — at a gate they edit and re-run, and the
35
+ loop picks their change up.
33
36
 
34
37
  ```bash
35
38
  gtd next --json # ask who's up and what they should do
@@ -46,7 +49,9 @@ A minimal bash implementation of the pinned protocol, driving an agent CLI (e.g.
46
49
  `claude -p`) against `gtd next --json` output. This is the authoritative
47
50
  reference for what a loop driver must do; keep any other implementation
48
51
  (including `skills/loop/SKILL.md`) consistent with it rather than editing both
49
- independently. `bin/gtd-loop` is this exact script, packaged as the `gtd-loop`
52
+ independently. Both open with the same move — capture the human's pending edit
53
+ when the machine rests at a `"message"` gate — so `gtd-loop` is the only command
54
+ a human runs. `bin/gtd-loop` is this exact script, packaged as the `gtd-loop`
50
55
  binary, with four additions: it stops with a diagnostic if the same `"prompt"`
51
56
  state/content repeat with no progress (see `skills/loop/SKILL.md`'s "Stall
52
57
  detection"); it lets `GTD_LOOP_AGENT_CMD` swap in any coding agent CLI in place
@@ -61,6 +66,17 @@ same-scope turns and starting fresh when the scope changes.
61
66
  #!/usr/bin/env bash
62
67
  set -euo pipefail
63
68
 
69
+ # Opening move: if the machine rests at a human gate, capture the human's
70
+ # pending edit first, so re-launching the loop is the ONLY thing a human does
71
+ # (they never run `gtd step human` by hand). Peek with the pure `gtd next
72
+ # --json` and step only at a `"message"` rest — at an agent/check rest
73
+ # `gtd step human` would refuse out-of-turn, and a mid-cycle restart must just
74
+ # resume driving. A clean gate is a no-op; a genuine refusal (malformed steering
75
+ # file, unrecognized edit) stops the loop instead of being driven past.
76
+ if [[ "$(gtd next --json | jq -r .kind)" == "message" ]]; then
77
+ gtd step human >/dev/null
78
+ fi
79
+
64
80
  while true; do
65
81
  next_json="$(gtd next --json)"
66
82
  state="$(jq -r .state <<<"$next_json")"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmelab/gtd",
3
- "version": "6.3.0",
3
+ "version": "6.4.0",
4
4
  "private": false,
5
5
  "description": "Git-aware CLI that emits the next prompt for an autonomous coding agent based on the current repository state",
6
6
  "bin": {