@pmelab/gtd 7.3.0 → 7.4.1
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 +8 -8
- package/bin/{gtd-loop → gtd} +65 -12
- package/dist/gtd.bundle.mjs +5 -0
- package/docs/cli.md +23 -12
- package/docs/loop.md +41 -25
- package/docs/upgrading.md +41 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -167,11 +167,11 @@ through two `vars` tiers — `plannerModel` (heavier planning and review) and
|
|
|
167
167
|
place (a `vars:` edit or a `GTD_VAR_plannerModel` override) instead of per
|
|
168
168
|
state.
|
|
169
169
|
|
|
170
|
-
`gtd
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
170
|
+
Bare `gtd` (or `gtd loop`) is a ready-to-run driver for the whole protocol —
|
|
171
|
+
point it at a repo and it runs the loop until it's your turn. It is the only
|
|
172
|
+
command you run: at a gate you edit files (answer a plan question, tick a review
|
|
173
|
+
box, fix code) and re-launch it, and it captures your edit as its opening move
|
|
174
|
+
before driving on — so you never run `gtd step human` by hand. See
|
|
175
175
|
[Driving the loop](docs/loop.md).
|
|
176
176
|
|
|
177
177
|
Before wiring gtd into a repo, note the
|
|
@@ -196,7 +196,7 @@ Both halves are enforced by `gtd validate` and the `gtd step` gate.
|
|
|
196
196
|
|
|
197
197
|
Herdr integration: a workflow state can declare an optional `label:` — a
|
|
198
198
|
human-readable display name surfaced in `gtd next --json`/`gtd status`. The
|
|
199
|
-
reference `bin/gtd
|
|
199
|
+
reference `bin/gtd` driver uses it to report its lifecycle
|
|
200
200
|
(working/blocked/idle) to a [Herdr](https://herdr.dev) pane sidebar via the
|
|
201
201
|
`herdr` CLI when running under Herdr (`HERDR_ENV=1`, a pane ID, and `herdr` on
|
|
202
202
|
`$PATH`); outside Herdr this is a complete no-op. See
|
|
@@ -210,8 +210,8 @@ reporting contract.
|
|
|
210
210
|
sub-machines, and the bundled workflow template
|
|
211
211
|
- [CLI reference](docs/cli.md) — every command, exit codes, JSON schemas,
|
|
212
212
|
repository requirements
|
|
213
|
-
- [Driving the loop](docs/loop.md) — the reference loop driver,
|
|
214
|
-
custom agents
|
|
213
|
+
- [Driving the loop](docs/loop.md) — the reference loop driver,
|
|
214
|
+
`gtd`/`gtd loop`, custom agents
|
|
215
215
|
- [Configuration](docs/configuration.md) — `gtd init`, the `.gtdrc` `workflow:`
|
|
216
216
|
schema, lookup
|
|
217
217
|
- [Upgrading](docs/upgrading.md) — breaking changes and migration
|
package/bin/{gtd-loop → gtd}
RENAMED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
+
# This file is the single published `bin` entry: `bin/gtd`. Before anything
|
|
5
|
+
# else, it dispatches on $1:
|
|
6
|
+
# - no arguments, or exactly `loop` with no further arguments -> fall through
|
|
7
|
+
# into the loop body below (the loop protocol comment further down).
|
|
8
|
+
# - `loop` with additional arguments -> usage error, exit 2.
|
|
9
|
+
# - anything else -> hand off to the bundle via `run_gtd`, forwarding all
|
|
10
|
+
# arguments unchanged (e.g. `bin/gtd status`, `bin/gtd step human`).
|
|
11
|
+
# `run_gtd` is the ONE place that knows how to invoke "the bundle": by default
|
|
12
|
+
# it resolves `dist/gtd.bundle.mjs` relative to this script's own location
|
|
13
|
+
# (not cwd), but `GTD_BIN` (a dev/test override for the whole invocation
|
|
14
|
+
# command, e.g. `GTD_BIN="node $PWD/dev/run.mjs"`) takes precedence when set.
|
|
15
|
+
# Every call the loop body makes below goes through `run_gtd` too, so the loop
|
|
16
|
+
# always drives the exact same build/source it was launched from — no
|
|
17
|
+
# dependence on a `gtd` binary being on PATH.
|
|
18
|
+
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
|
19
|
+
|
|
20
|
+
run_gtd() {
|
|
21
|
+
if [[ -n "${GTD_BIN:-}" ]]; then
|
|
22
|
+
eval "$GTD_BIN" '"$@"'
|
|
23
|
+
else
|
|
24
|
+
node "$SCRIPT_DIR/../dist/gtd.bundle.mjs" "$@"
|
|
25
|
+
fi
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if [[ $# -gt 0 && "$1" != "loop" ]]; then
|
|
29
|
+
run_gtd "$@"
|
|
30
|
+
exit $?
|
|
31
|
+
fi
|
|
32
|
+
if [[ "${1:-}" == "loop" && $# -gt 1 ]]; then
|
|
33
|
+
echo "gtd: 'loop' takes no arguments" >&2
|
|
34
|
+
exit 2
|
|
35
|
+
fi
|
|
36
|
+
# otherwise ($# -eq 0, or exactly "loop" with no further args): fall through
|
|
37
|
+
# into the existing loop body below, unchanged in behavior.
|
|
38
|
+
|
|
4
39
|
# Drives the v3 pattern-machine loop (see docs/loop.md): each iteration asks
|
|
5
40
|
# `gtd next --json` who's up and what they should do, dispatching on `kind`:
|
|
6
41
|
# - "message" (a human rest) -> halt, tell the user what gtd is waiting on.
|
|
@@ -32,20 +67,38 @@ set -euo pipefail
|
|
|
32
67
|
# `--resume`/`--session-id`. An adapter that ignores them keeps working.
|
|
33
68
|
herdr_ok() { [ "${HERDR_ENV:-}" = 1 ] && [ -n "${HERDR_PANE_ID:-}" ] && command -v herdr >/dev/null 2>&1; }
|
|
34
69
|
|
|
70
|
+
# Run a `herdr` invocation best-effort. Normally output is discarded and a
|
|
71
|
+
# failure is swallowed (`|| true`) so a missing/incompatible herdr never blocks
|
|
72
|
+
# the loop. Set GTD_HERDR_DEBUG=1 to instead surface every call and its exit
|
|
73
|
+
# code on stderr — the escape hatch that makes a silent CLI-signature mismatch
|
|
74
|
+
# (e.g. an arg herdr rejects) visible again.
|
|
75
|
+
herdr_run() {
|
|
76
|
+
if [ "${GTD_HERDR_DEBUG:-}" = 1 ]; then
|
|
77
|
+
printf 'gtd/herdr: %s\n' "$*" >&2
|
|
78
|
+
herdr "$@" >&2
|
|
79
|
+
printf 'gtd/herdr: exit=%s\n' "$?" >&2
|
|
80
|
+
else
|
|
81
|
+
herdr "$@" >/dev/null 2>&1 || true
|
|
82
|
+
fi
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# NOTE: herdr requires the positional <PANE_ID> BEFORE the options for
|
|
86
|
+
# `pane` subcommands — passing it last makes herdr reject the first option as
|
|
87
|
+
# `unknown option` (exit 2). Keep the pane id first here.
|
|
35
88
|
herdr_report() { # $1=state (working|blocked|idle) $2=message
|
|
36
89
|
herdr_ok || return 0
|
|
37
|
-
|
|
38
|
-
--state "$1" --message "$2"
|
|
90
|
+
herdr_run pane report-agent "$HERDR_PANE_ID" \
|
|
91
|
+
--source herdr:gtd --agent gtd --state "$1" --message "$2"
|
|
39
92
|
}
|
|
40
93
|
|
|
41
94
|
herdr_notify() { # $1=title $2=body
|
|
42
95
|
herdr_ok || return 0
|
|
43
|
-
|
|
96
|
+
herdr_run notification show "$1" --body "$2" --sound request
|
|
44
97
|
}
|
|
45
98
|
|
|
46
99
|
herdr_release() { # hand the pane back to Herdr's normal detection
|
|
47
100
|
herdr_ok || return 0
|
|
48
|
-
|
|
101
|
+
herdr_run pane release-agent "$HERDR_PANE_ID" --source herdr:gtd --agent gtd
|
|
49
102
|
}
|
|
50
103
|
|
|
51
104
|
trap 'code=$?; if [ "$code" -ne 0 ]; then
|
|
@@ -101,14 +154,14 @@ run_agent_turn() {
|
|
|
101
154
|
# a harmless no-op; a genuine refusal there (a malformed steering file, or an
|
|
102
155
|
# edit no `on` pattern accepts) is surfaced and stops the loop rather than being
|
|
103
156
|
# driven past.
|
|
104
|
-
if ! peek_json="$(
|
|
157
|
+
if ! peek_json="$(run_gtd next --json 2>&1)"; then
|
|
105
158
|
echo "gtd-loop: could not determine the next step:" >&2
|
|
106
159
|
echo "$peek_json" >&2
|
|
107
160
|
echo "Run \`gtd status\` to inspect the repo." >&2
|
|
108
161
|
exit 1
|
|
109
162
|
fi
|
|
110
163
|
if [[ "$(jq -r .kind <<<"$peek_json")" == "message" ]]; then
|
|
111
|
-
if ! step_out="$(
|
|
164
|
+
if ! step_out="$(run_gtd step human 2>&1)"; then
|
|
112
165
|
echo "gtd-loop: could not capture your changes at the human gate:" >&2
|
|
113
166
|
echo "$step_out" >&2
|
|
114
167
|
echo "Fix the reported issue and re-run gtd-loop." >&2
|
|
@@ -117,7 +170,7 @@ if [[ "$(jq -r .kind <<<"$peek_json")" == "message" ]]; then
|
|
|
117
170
|
fi
|
|
118
171
|
|
|
119
172
|
while true; do
|
|
120
|
-
if ! next_json="$(
|
|
173
|
+
if ! next_json="$(run_gtd next --json 2>&1)"; then
|
|
121
174
|
echo "gtd-loop: could not determine the next step:" >&2
|
|
122
175
|
echo "$next_json" >&2
|
|
123
176
|
echo "Run \`gtd status\` to inspect the repo." >&2
|
|
@@ -141,7 +194,7 @@ while true; do
|
|
|
141
194
|
herdr_report blocked "$label"
|
|
142
195
|
herdr_notify "gtd needs you — $(basename "$PWD")" "$label"
|
|
143
196
|
echo "--- Your turn ($state) ---"
|
|
144
|
-
|
|
197
|
+
run_gtd next
|
|
145
198
|
exit 0
|
|
146
199
|
fi
|
|
147
200
|
|
|
@@ -152,7 +205,7 @@ while true; do
|
|
|
152
205
|
# the tree, and `gtd step` captures whatever it left there via the state's
|
|
153
206
|
# own `on` patterns.
|
|
154
207
|
bash -c "$content" || true
|
|
155
|
-
|
|
208
|
+
run_gtd step "$actor" >/dev/null
|
|
156
209
|
head_after="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
157
210
|
if [[ "$head_before" == "$head_after" ]]; then
|
|
158
211
|
herdr_report idle "$label"
|
|
@@ -170,7 +223,7 @@ while true; do
|
|
|
170
223
|
# progress; stop rather than spin on it.
|
|
171
224
|
if [[ "$state" == "$prev_state" && "$content" == "$prev_content" ]]; then
|
|
172
225
|
echo "gtd-loop: no progress at '$state' — the agent's last turn changed nothing. Stopping to avoid spinning." >&2
|
|
173
|
-
|
|
226
|
+
run_gtd next >&2
|
|
174
227
|
exit 1
|
|
175
228
|
fi
|
|
176
229
|
prev_state="$state"
|
|
@@ -213,7 +266,7 @@ while true; do
|
|
|
213
266
|
run_agent_turn "$content" "$resume"
|
|
214
267
|
|
|
215
268
|
fix_attempt=0
|
|
216
|
-
while ! validate_out="$(
|
|
269
|
+
while ! validate_out="$(run_gtd validate 2>&1)"; do
|
|
217
270
|
fix_attempt=$((fix_attempt + 1))
|
|
218
271
|
if ((fix_attempt > 3)); then
|
|
219
272
|
echo "gtd-loop: '$state' still fails \`gtd validate\` after 3 fix attempts:" >&2
|
|
@@ -228,5 +281,5 @@ while true; do
|
|
|
228
281
|
run_agent_turn "$content"$'\n\n'"Your last turn does not pass \`gtd validate\`. Fix these format violations, then finish:"$'\n'"$validate_out" "$fix_resume"
|
|
229
282
|
done
|
|
230
283
|
|
|
231
|
-
|
|
284
|
+
run_gtd step "$actor" >/dev/null
|
|
232
285
|
done
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -205351,6 +205351,11 @@ const GTD_VERSION = createRequire(import.meta.url)("../package.json").version;
|
|
|
205351
205351
|
const HELP_TEXT = `Usage: gtd [command] [options]
|
|
205352
205352
|
|
|
205353
205353
|
Commands:
|
|
205354
|
+
(no command), loop
|
|
205355
|
+
Launch the loop driver (bin/gtd), which repeatedly drives
|
|
205356
|
+
an agent through gtd next/gtd step calls until the
|
|
205357
|
+
workflow returns to its initial state again. A bare gtd
|
|
205358
|
+
invocation and gtd loop both launch it identically
|
|
205354
205359
|
init Scaffold a minimal .gtdrc.json for this repo, seeding the
|
|
205355
205360
|
default variables you are most likely to change (the test
|
|
205356
205361
|
command) and a Prettier formatting suggestion. gtd runs its
|
package/docs/cli.md
CHANGED
|
@@ -4,12 +4,19 @@
|
|
|
4
4
|
Usage: gtd [command] [options]
|
|
5
5
|
|
|
6
6
|
Commands:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
(no command), loop
|
|
8
|
+
Launch the loop driver (bin/gtd), which repeatedly drives
|
|
9
|
+
an agent through gtd next/gtd step calls until the
|
|
10
|
+
workflow returns to its initial state again. A bare gtd
|
|
11
|
+
invocation and gtd loop both launch it identically
|
|
12
|
+
init Scaffold a minimal .gtdrc.json for this repo, seeding the
|
|
13
|
+
default variables you are most likely to change (the test
|
|
14
|
+
command) and a Prettier formatting suggestion. gtd runs its
|
|
15
|
+
built-in workflow by default, so no workflow is written —
|
|
16
|
+
add a workflow: key only to customize the machine itself.
|
|
17
|
+
Takes no argument. Run once per repo; refuses if a gtd
|
|
18
|
+
config already exists. Leaves the file uncommitted for you
|
|
19
|
+
to review and commit
|
|
13
20
|
step <actor> Authenticate as <actor>, match the resolved rest's
|
|
14
21
|
declared patterns against the pending changes, and commit
|
|
15
22
|
(or squash) the one resulting transition. Pass
|
|
@@ -44,7 +51,9 @@ Commands:
|
|
|
44
51
|
declares, with its mode's commands (its file:/mode:);
|
|
45
52
|
exits non-zero with the findings when it is invalid
|
|
46
53
|
lsp Start the LSP server for .gtd/ steering files (stdio)
|
|
47
|
-
visualize Serve an interactive diagram of the active workflow
|
|
54
|
+
visualize Serve an interactive diagram of the active workflow on a
|
|
55
|
+
local web server (--port <n>, --no-open; --json prints the
|
|
56
|
+
model and exits)
|
|
48
57
|
version Print version and exit
|
|
49
58
|
help Print this help and exit
|
|
50
59
|
|
|
@@ -61,9 +70,11 @@ Options:
|
|
|
61
70
|
`--version` (`-v`) / `gtd version` and `--help` (`-h`) / `gtd help`
|
|
62
71
|
short-circuit before any git or repository-state work — they run outside a repo
|
|
63
72
|
and in any repo state (the bare subcommands are exact equivalents of their flag
|
|
64
|
-
forms). Bare `gtd` (no subcommand)
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
forms). Bare `gtd` (no subcommand) and `gtd loop` both launch the loop driver
|
|
74
|
+
(`bin/gtd`) immediately — neither is a usage error. Any other, truly unknown
|
|
75
|
+
subcommand remains a usage error: it prints the help text and exits 1 without
|
|
76
|
+
touching the repository. Every other (recognized) command must be run from the
|
|
77
|
+
**repository root** — gtd derives the workflow, pending changes, and process
|
|
67
78
|
history relative to cwd, so it refuses with a clear error if invoked from a
|
|
68
79
|
subdirectory.
|
|
69
80
|
|
|
@@ -401,7 +412,7 @@ which are JSON-only. `--json` emits
|
|
|
401
412
|
|
|
402
413
|
There is no `gtd` subcommand that executes a workflow script — gtd never runs a
|
|
403
414
|
workflow script itself. When `gtd next` resolves to a `script`-content rest, the
|
|
404
|
-
**driver** (`bin/gtd
|
|
415
|
+
**driver** (`bin/gtd`, or any loop harness) executes the emitted `content`
|
|
405
416
|
verbatim via `bash -c` — foreground, inherited stdio, exit code deliberately
|
|
406
417
|
ignored (a check script encodes its outcome in the tree, e.g. writing a findings
|
|
407
418
|
file, never in its exit status) — then runs `gtd step <actor>` for that state's
|
|
@@ -493,7 +504,7 @@ agent or human:
|
|
|
493
504
|
- **The producing agent self-validates.** Plain `gtd next` appends a "run
|
|
494
505
|
`gtd validate` and fix all violations" instruction to a `prompt` rest that
|
|
495
506
|
declares `file:`+`mode:`; `gtd next --json` withholds it and the driving loop
|
|
496
|
-
runs `gtd validate` after the turn instead (see `bin/gtd
|
|
507
|
+
runs `gtd validate` after the turn instead (see `bin/gtd` /
|
|
497
508
|
[STATES.md §12](../STATES.md#12-steering-file-validation-gtd-validate)).
|
|
498
509
|
- **`gtd step` enforces the same gate.** Capturing a turn out of a state that
|
|
499
510
|
declares `file:`+`mode:` formats that file in place and validates it first
|
package/docs/loop.md
CHANGED
|
@@ -57,9 +57,10 @@ gtd next --json # ask who's up and what they should do
|
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
See [`skills/loop/SKILL.md`](../skills/loop/SKILL.md) for the agent-facing
|
|
60
|
-
instructions that follow the same pinned contract. `gtd
|
|
61
|
-
|
|
62
|
-
that same script for anyone who doesn't want to drive the loop
|
|
60
|
+
instructions that follow the same pinned contract. `gtd` itself (bare, or with
|
|
61
|
+
`loop` as its first argument — see below) is the packaged, ready-to-run
|
|
62
|
+
implementation of that same script for anyone who doesn't want to drive the loop
|
|
63
|
+
by hand.
|
|
63
64
|
|
|
64
65
|
## The reference loop driver
|
|
65
66
|
|
|
@@ -68,17 +69,29 @@ A minimal bash implementation of the pinned protocol, driving an agent CLI (e.g.
|
|
|
68
69
|
reference for what a loop driver must do; keep any other implementation
|
|
69
70
|
(including `skills/loop/SKILL.md`) consistent with it rather than editing both
|
|
70
71
|
independently. Both open with the same move — capture the human's pending edit
|
|
71
|
-
when the machine rests at a `"message"` gate — so `gtd
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
72
|
+
when the machine rests at a `"message"` gate — so `gtd` is the only command a
|
|
73
|
+
human runs. `bin/gtd` is the packaged entry point: invoked bare, or with `loop`
|
|
74
|
+
as its first argument, it runs this exact script; any other first argument (e.g.
|
|
75
|
+
`next`, `step`, `status`) hands off to `node dist/gtd.bundle.mjs` instead. The
|
|
76
|
+
loop body it runs adds four things on top of the reference script above: it
|
|
77
|
+
stops with a diagnostic if the same `"prompt"` state/content repeat with no
|
|
78
|
+
progress (see `skills/loop/SKILL.md`'s "Stall detection"); it lets
|
|
79
|
+
`GTD_LOOP_AGENT_CMD` swap in any coding agent CLI in place of the default
|
|
80
|
+
`claude -p`, receiving the prompt via `$GTD_LOOP_PROMPT`; it exports the
|
|
81
|
+
resolved state's optional `model` hint as `$GTD_LOOP_MODEL`, appending
|
|
82
|
+
`--model "$GTD_LOOP_MODEL"` to the default `claude -p` invocation whenever it's
|
|
83
|
+
non-empty; and it acts on the optional `memory` scope hint (see "Agent memory
|
|
84
|
+
scope" below) — continuing one agent session across consecutive same-scope turns
|
|
85
|
+
and starting fresh when the scope changes.
|
|
86
|
+
|
|
87
|
+
`bin/gtd` resolves both its bundle hand-off and the loop's own internal `gtd`
|
|
88
|
+
calls against `dist/gtd.bundle.mjs` next to its own location. Set `GTD_BIN` — a
|
|
89
|
+
full command, not just a path — to point both at source instead, e.g. for
|
|
90
|
+
development or testing:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
GTD_BIN="node $PWD/dev/run.mjs" bin/gtd
|
|
94
|
+
```
|
|
82
95
|
|
|
83
96
|
```bash
|
|
84
97
|
#!/usr/bin/env bash
|
|
@@ -144,9 +157,9 @@ turn, or either side has no `memory` — start fresh.
|
|
|
144
157
|
This is what makes a loop retain memory while a phase boundary clears it: a loop
|
|
145
158
|
that keeps re-entering one state emits the same label every lap, so the agent
|
|
146
159
|
accumulates context across the loop; the move to the next phase's
|
|
147
|
-
differently-labelled state resets it. `bin/gtd
|
|
148
|
-
|
|
149
|
-
|
|
160
|
+
differently-labelled state resets it. `bin/gtd` implements this by mapping the
|
|
161
|
+
signal onto claude's session flags — `--session-id` to pin a fresh session when
|
|
162
|
+
the scope changes, `--resume` to continue it while the scope holds — and
|
|
150
163
|
persists the current scope + session id in the git dir (never the working tree,
|
|
151
164
|
so `gtd status` and the pending diff never see them) so retention survives even
|
|
152
165
|
across the restarts a human gate forces mid-loop. See `skills/loop/SKILL.md`'s
|
|
@@ -154,7 +167,7 @@ across the restarts a human gate forces mid-loop. See `skills/loop/SKILL.md`'s
|
|
|
154
167
|
|
|
155
168
|
## Using a different agent
|
|
156
169
|
|
|
157
|
-
`gtd
|
|
170
|
+
`gtd` (bare, or `gtd loop`) defaults to
|
|
158
171
|
`claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions`, but the agent
|
|
159
172
|
invocation is swappable: set `GTD_LOOP_AGENT_CMD` to any shell command, and it
|
|
160
173
|
runs with the prompt available as `$GTD_LOOP_PROMPT` in its environment, along
|
|
@@ -165,23 +178,26 @@ session). An adapter that ignores any of these keeps working unchanged. For
|
|
|
165
178
|
example, to drive a different agent CLI:
|
|
166
179
|
|
|
167
180
|
```bash
|
|
168
|
-
GTD_LOOP_AGENT_CMD='my-agent-cli --prompt "$GTD_LOOP_PROMPT"' gtd
|
|
181
|
+
GTD_LOOP_AGENT_CMD='my-agent-cli --prompt "$GTD_LOOP_PROMPT"' gtd
|
|
169
182
|
```
|
|
170
183
|
|
|
171
184
|
## Herdr integration (optional)
|
|
172
185
|
|
|
173
|
-
`bin/gtd
|
|
186
|
+
`bin/gtd` optionally reports its lifecycle to [Herdr](https://herdr.dev) (a
|
|
174
187
|
terminal multiplexer for coding agents) via a `herdr` CLI binary, entirely at
|
|
175
188
|
the driver's edge — gtd core never talks to Herdr. Every call is best-effort
|
|
176
189
|
(guarded, output discarded, `|| true`), so a missing/failing `herdr` binary
|
|
177
|
-
never blocks, slows, or fails the loop.
|
|
190
|
+
never blocks, slows, or fails the loop. Because that guard also hides a herdr
|
|
191
|
+
CLI-signature mismatch, set `GTD_HERDR_DEBUG=1` to surface every `herdr` call
|
|
192
|
+
and its exit code on stderr instead.
|
|
178
193
|
|
|
179
194
|
The reporting is a no-op unless all three guard conditions hold: `HERDR_ENV=1`,
|
|
180
|
-
a non-empty `$HERDR_PANE_ID`, and `herdr` on `$PATH`. When they do, `gtd
|
|
181
|
-
|
|
195
|
+
a non-empty `$HERDR_PANE_ID`, and `herdr` on `$PATH`. When they do, `gtd` makes
|
|
196
|
+
three kinds of calls (note the positional `<PANE_ID>` comes BEFORE the options —
|
|
197
|
+
herdr's `pane` subcommands reject a trailing pane id):
|
|
182
198
|
|
|
183
|
-
- `herdr pane report-agent --source herdr:gtd --agent gtd --state <state> --message <label
|
|
184
|
-
- `herdr pane release-agent --source herdr:gtd --agent gtd
|
|
199
|
+
- `herdr pane report-agent "$HERDR_PANE_ID" --source herdr:gtd --agent gtd --state <state> --message <label>`
|
|
200
|
+
- `herdr pane release-agent "$HERDR_PANE_ID" --source herdr:gtd --agent gtd`
|
|
185
201
|
- `herdr notification show <title> --body <label> --sound request`
|
|
186
202
|
|
|
187
203
|
mapped onto the loop's states like this:
|
package/docs/upgrading.md
CHANGED
|
@@ -159,6 +159,47 @@ loudly at load time rather than silently misinterpreting.
|
|
|
159
159
|
or agent harness, upgrading the `gtd` binary also means re-copying that skill
|
|
160
160
|
from this release.
|
|
161
161
|
|
|
162
|
+
## 7.4: `gtd-loop` is gone — bare `gtd` and `gtd loop` run it directly
|
|
163
|
+
|
|
164
|
+
`gtd-loop`, the standalone loop-driver binary installed alongside `gtd`, no
|
|
165
|
+
longer exists. Its body now lives in `bin/gtd` itself, which is a bash entry
|
|
166
|
+
script that dispatches on its first argument:
|
|
167
|
+
|
|
168
|
+
| behavior | before (≤ 7.3) | from 7.4 |
|
|
169
|
+
| ------------------------------------------------------ | ---------------------------------------------- | ----------------------------------------------- |
|
|
170
|
+
| `gtd-loop` | separate installed binary | removed |
|
|
171
|
+
| bare `gtd` (no subcommand) | usage error, prints help, exits 1 | runs the loop driver immediately |
|
|
172
|
+
| `gtd loop` | not a recognized subcommand | runs the loop driver immediately |
|
|
173
|
+
| any other subcommand (`step`, `status`, `validate`, …) | handled by `node dist/gtd.bundle.mjs` directly | same, now reached via `bin/gtd`'s hand-off/exec |
|
|
174
|
+
|
|
175
|
+
**Bare `gtd` is a behavior flip, not merely an addition** — the same kind of
|
|
176
|
+
change as the v1 → v2 label grammar below: previously it printed the help text
|
|
177
|
+
and exited 1 without touching the repository; from 7.4 it launches the loop
|
|
178
|
+
driver immediately, identically to `gtd loop`. A script that relied on bare
|
|
179
|
+
`gtd` failing fast (e.g. to detect a missing subcommand) now gets a running loop
|
|
180
|
+
instead of an error.
|
|
181
|
+
|
|
182
|
+
Because `bin/gtd` is a bash script for every invocation now, **running `gtd` at
|
|
183
|
+
all — including any subcommand — requires bash**. Before 7.4, only the loop
|
|
184
|
+
driver (`gtd-loop`) needed bash; a subcommand could be invoked directly via the
|
|
185
|
+
bundle (e.g. `node node_modules/.bin/gtd`) with no bash in between. This is
|
|
186
|
+
intentional and accepted, not an oversight: gtd's loop, its `script`-content
|
|
187
|
+
checks, and a steering-file mode's own `format:`/`validate:` commands already
|
|
188
|
+
run via `bash -c` (see
|
|
189
|
+
[Configuration](configuration.md#modes--pluggable-steering-file-modes)) — gtd
|
|
190
|
+
already assumes a unix/bash agent environment everywhere else, so the entry
|
|
191
|
+
point catching up removes an inconsistency rather than introducing a new
|
|
192
|
+
dependency.
|
|
193
|
+
|
|
194
|
+
**Migration:**
|
|
195
|
+
|
|
196
|
+
- Anyone invoking `gtd-loop` directly — in scripts, CI, or docs — should invoke
|
|
197
|
+
`gtd` or `gtd loop` instead.
|
|
198
|
+
- Anyone relying on `node node_modules/.bin/gtd` resolving straight to the
|
|
199
|
+
bundle should note `gtd` is now a bash script that execs the bundle for
|
|
200
|
+
subcommands, so behavior for actual subcommands (`gtd step`, `gtd status`,
|
|
201
|
+
etc.) is unchanged — only the underlying file changed.
|
|
202
|
+
|
|
162
203
|
## 7.2: the review checkout window is now per worktree
|
|
163
204
|
|
|
164
205
|
The review checkout window's two refs moved from the SHARED `refs/gtd/*`
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmelab/gtd",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.4.1",
|
|
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": {
|
|
7
|
-
"gtd": "
|
|
8
|
-
"gtd-loop": "bin/gtd-loop"
|
|
7
|
+
"gtd": "bin/gtd"
|
|
9
8
|
},
|
|
10
9
|
"files": [
|
|
11
10
|
"dist/",
|