@pmelab/gtd 7.4.2 → 7.5.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 +10 -4
- package/bin/gtd +137 -18
- package/dist/gtd.bundle.mjs +4 -0
- package/docs/cli.md +66 -6
- package/docs/loop.md +37 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,6 +106,9 @@ handful of commands drive it:
|
|
|
106
106
|
pending changes, and which action leads where. The panel and diagram highlight
|
|
107
107
|
refresh live (~every 3s) while the page is open, so advancing the process
|
|
108
108
|
elsewhere shows up without a manual refresh.
|
|
109
|
+
- **`gtd edit [path]`** — open `<path>` (or, with no argument, the current
|
|
110
|
+
resting state's steering file, or the repo dir) in `${VISUAL:-$EDITOR}`,
|
|
111
|
+
blocking until it exits.
|
|
109
112
|
|
|
110
113
|
`gtd version` (or `gtd --version`/`-v`) prints the installed version and exits;
|
|
111
114
|
`gtd help` (or `gtd --help`/`-h`) prints the command list. Both short-circuit
|
|
@@ -172,10 +175,13 @@ the file.
|
|
|
172
175
|
|
|
173
176
|
Bare `gtd` (or `gtd loop`) is a ready-to-run driver for the whole protocol —
|
|
174
177
|
point it at a repo and it runs the loop until it's your turn. It is the only
|
|
175
|
-
command you run: at a gate
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
178
|
+
command you run: at a human gate it now opens `${VISUAL:-$EDITOR}` on the gate's
|
|
179
|
+
file for you automatically (answer a plan question, tick a review box, fix
|
|
180
|
+
code), waits for you to save and exit, then captures your edit itself and keeps
|
|
181
|
+
driving — or halts if you left nothing changed — so you never run
|
|
182
|
+
`gtd step human` by hand. Pass `--no-edit` (or set `GTD_NO_EDIT`) to fall back
|
|
183
|
+
to halting and printing the gate instead, if you'd rather edit and re-launch it
|
|
184
|
+
yourself. See [Driving the loop](docs/loop.md).
|
|
179
185
|
|
|
180
186
|
Before wiring gtd into a repo, note the
|
|
181
187
|
[repository requirements](docs/cli.md#repository-requirements) — most
|
package/bin/gtd
CHANGED
|
@@ -3,9 +3,17 @@ set -euo pipefail
|
|
|
3
3
|
|
|
4
4
|
# This file is the single published `bin` entry: `bin/gtd`. Before anything
|
|
5
5
|
# else, it dispatches on $1:
|
|
6
|
+
# - `--no-edit` (bare, or immediately after `loop`) -> stripped here and
|
|
7
|
+
# disables the loop's automatic editor launching for this run (see
|
|
8
|
+
# `edit_disabled`/`GTD_NO_EDIT` below); dispatch then continues on the
|
|
9
|
+
# remaining arguments as if it had never been given.
|
|
10
|
+
# - `edit [path]` -> handled entirely here in bash, never forwarded to the
|
|
11
|
+
# bundle: opens `${VISUAL:-$EDITOR}` on `path`, or (no `path` given) on the
|
|
12
|
+
# resolved rest's `.file` (or `.` when absent).
|
|
6
13
|
# - no arguments, or exactly `loop` with no further arguments -> fall through
|
|
7
14
|
# into the loop body below (the loop protocol comment further down).
|
|
8
|
-
# - `loop` with additional arguments
|
|
15
|
+
# - `loop` with additional arguments (other than a lone `--no-edit`) ->
|
|
16
|
+
# usage error, exit 2.
|
|
9
17
|
# - anything else -> hand off to the bundle via `run_gtd`, forwarding all
|
|
10
18
|
# arguments unchanged (e.g. `bin/gtd status`, `bin/gtd step human`).
|
|
11
19
|
# `run_gtd` is the ONE place that knows how to invoke "the bundle": by default
|
|
@@ -25,6 +33,55 @@ run_gtd() {
|
|
|
25
33
|
fi
|
|
26
34
|
}
|
|
27
35
|
|
|
36
|
+
# Shared editor-launch helper — used by both the `edit` subcommand below and
|
|
37
|
+
# the loop's human-gate flow further down. Resolves the editor git-style
|
|
38
|
+
# ($VISUAL, then $EDITOR — no fallback to `vi`), then launches it blocking in
|
|
39
|
+
# the foreground with the target path passed as a positional parameter
|
|
40
|
+
# (never string-spliced into the command), so a multi-word command
|
|
41
|
+
# (`code --wait`) and a path with special characters both work. A launch
|
|
42
|
+
# failure (bad/missing editor binary) is a plain non-zero return, propagating
|
|
43
|
+
# under `set -e`; the editor's own exit code is otherwise ignored entirely —
|
|
44
|
+
# the outcome is judged from tree state afterward, not from this function.
|
|
45
|
+
launch_editor() {
|
|
46
|
+
local target="$1" editor="${VISUAL:-${EDITOR:-}}"
|
|
47
|
+
if [[ -z "$editor" ]]; then
|
|
48
|
+
echo "gtd: no editor configured — set \$EDITOR (or \$VISUAL)" >&2
|
|
49
|
+
return 1
|
|
50
|
+
fi
|
|
51
|
+
bash -c "$editor \"\$1\"" gtd-edit "$target"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# --no-edit / GTD_NO_EDIT govern only the loop's automatic editor launching at
|
|
55
|
+
# human gates (see handle_human_gate further down) — `gtd edit` itself never
|
|
56
|
+
# reads either. `--no-edit` is recognised in exactly the two sanctioned
|
|
57
|
+
# positions (bare, or right after `loop`) and stripped before anything below
|
|
58
|
+
# looks at "$@", so the bundle's own unknown-option guard never sees it.
|
|
59
|
+
edit_disabled=0
|
|
60
|
+
[[ -n "${GTD_NO_EDIT:-}" ]] && edit_disabled=1
|
|
61
|
+
if [[ "${1:-}" == "--no-edit" && $# -eq 1 ]]; then
|
|
62
|
+
edit_disabled=1
|
|
63
|
+
shift
|
|
64
|
+
elif [[ "${1:-}" == "loop" && "${2:-}" == "--no-edit" && $# -eq 2 ]]; then
|
|
65
|
+
edit_disabled=1
|
|
66
|
+
set -- loop
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [[ "${1:-}" == "edit" ]]; then
|
|
70
|
+
shift
|
|
71
|
+
if [[ $# -gt 0 ]]; then
|
|
72
|
+
launch_editor "$1"
|
|
73
|
+
else
|
|
74
|
+
if ! peek_json="$(run_gtd next --json 2>&1)"; then
|
|
75
|
+
echo "gtd edit: could not determine the next step:" >&2
|
|
76
|
+
echo "$peek_json" >&2
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
file="$(jq -r '.file // empty' <<<"$peek_json")"
|
|
80
|
+
launch_editor "${file:-.}"
|
|
81
|
+
fi
|
|
82
|
+
exit 0
|
|
83
|
+
fi
|
|
84
|
+
|
|
28
85
|
if [[ $# -gt 0 && "$1" != "loop" ]]; then
|
|
29
86
|
run_gtd "$@"
|
|
30
87
|
exit $?
|
|
@@ -33,12 +90,16 @@ if [[ "${1:-}" == "loop" && $# -gt 1 ]]; then
|
|
|
33
90
|
echo "gtd: 'loop' takes no arguments" >&2
|
|
34
91
|
exit 2
|
|
35
92
|
fi
|
|
36
|
-
# otherwise ($# -eq 0, or exactly "loop" with no further args
|
|
37
|
-
# into the existing loop body below,
|
|
93
|
+
# otherwise ($# -eq 0, or exactly "loop" with no further args, --no-edit
|
|
94
|
+
# already stripped above): fall through into the existing loop body below,
|
|
95
|
+
# unchanged in behavior.
|
|
38
96
|
|
|
39
97
|
# Drives the v3 pattern-machine loop (see docs/loop.md): each iteration asks
|
|
40
98
|
# `gtd next --json` who's up and what they should do, dispatching on `kind`:
|
|
41
|
-
# - "message" (a human rest) ->
|
|
99
|
+
# - "message" (a human rest) -> see handle_human_gate above: with editing on
|
|
100
|
+
# (the default) open the editor at the gate and step human, driving on a
|
|
101
|
+
# captured commit; with editing off (--no-edit/GTD_NO_EDIT), halt and tell
|
|
102
|
+
# the user what gtd is waiting on, unchanged from before this feature.
|
|
42
103
|
# - "script" (a check rest) -> execute `content` (the emitted wrapper
|
|
43
104
|
# script) verbatim via bash — exit code deliberately ignored, the outcome
|
|
44
105
|
# lives in the tree — then `gtd step <actor>` to capture it; zero new
|
|
@@ -101,6 +162,57 @@ herdr_release() { # hand the pane back to Herdr's normal detection
|
|
|
101
162
|
herdr_run pane release-agent "$HERDR_PANE_ID" --source herdr:gtd --agent gtd
|
|
102
163
|
}
|
|
103
164
|
|
|
165
|
+
# Shared human-gate handler for a "message" (human) rest — used both by the
|
|
166
|
+
# opening move (when editing is on) and by every "message" rest the main loop
|
|
167
|
+
# encounters. $1 is the rest's `next --json` blob.
|
|
168
|
+
#
|
|
169
|
+
# Editing OFF ($edit_disabled): today's behavior, unchanged — print the gate
|
|
170
|
+
# and exit 0 without touching an editor.
|
|
171
|
+
#
|
|
172
|
+
# Editing ON (the default): open the editor on the rest's `.file` (or `.` when
|
|
173
|
+
# absent), wait for it to exit, then run `gtd step human`:
|
|
174
|
+
# - a NEW commit was authored -> return normally so the caller keeps driving.
|
|
175
|
+
# - ZERO commits were authored -> halt, exit 0 (closing the editor without a
|
|
176
|
+
# capturable change means "done for now" — and keeps a gate with no `C`
|
|
177
|
+
# pattern, e.g. idle, from being reopened forever).
|
|
178
|
+
# - the step REFUSES (non-zero exit: malformed steering file, unfinished
|
|
179
|
+
# review) -> surface it verbatim and halt, exit non-zero — the same
|
|
180
|
+
# wording an opening-move refusal already used before this function
|
|
181
|
+
# existed.
|
|
182
|
+
handle_human_gate() {
|
|
183
|
+
local json="$1" file label state step_out head_before head_after
|
|
184
|
+
label="$(jq -r '.label // .state' <<<"$json")"
|
|
185
|
+
state="$(jq -r .state <<<"$json")"
|
|
186
|
+
|
|
187
|
+
if [[ "$edit_disabled" == 1 ]]; then
|
|
188
|
+
herdr_report blocked "$label"
|
|
189
|
+
herdr_notify "gtd needs you — $(basename "$PWD")" "$label"
|
|
190
|
+
echo "--- Your turn ($state) ---"
|
|
191
|
+
run_gtd next
|
|
192
|
+
exit 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
file="$(jq -r '.file // empty' <<<"$json")"
|
|
196
|
+
herdr_report working "$label"
|
|
197
|
+
launch_editor "${file:-.}"
|
|
198
|
+
|
|
199
|
+
head_before="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
200
|
+
if ! step_out="$(run_gtd step human 2>&1)"; then
|
|
201
|
+
echo "gtd-loop: could not capture your changes at the human gate:" >&2
|
|
202
|
+
echo "$step_out" >&2
|
|
203
|
+
echo "Fix the reported issue and re-run gtd-loop." >&2
|
|
204
|
+
exit 1
|
|
205
|
+
fi
|
|
206
|
+
head_after="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
207
|
+
if [[ "$head_before" == "$head_after" ]]; then
|
|
208
|
+
herdr_report idle "$label"
|
|
209
|
+
herdr_release
|
|
210
|
+
echo "--- Done for now ($state: nothing captured) ---"
|
|
211
|
+
exit 0
|
|
212
|
+
fi
|
|
213
|
+
# else: a new commit was captured — return normally, caller keeps driving.
|
|
214
|
+
}
|
|
215
|
+
|
|
104
216
|
trap 'code=$?; if [ "$code" -ne 0 ]; then
|
|
105
217
|
herdr_report blocked "${GTD_LAST_LABEL:-stopped}: exited $code"
|
|
106
218
|
herdr_notify "gtd stopped — $(basename "$PWD")" "${GTD_LAST_LABEL:-loop} failed (exit $code)"
|
|
@@ -154,6 +266,12 @@ run_agent_turn() {
|
|
|
154
266
|
# a harmless no-op; a genuine refusal there (a malformed steering file, or an
|
|
155
267
|
# edit no `on` pattern accepts) is surfaced and stops the loop rather than being
|
|
156
268
|
# driven past.
|
|
269
|
+
#
|
|
270
|
+
# Editing ON: route through the exact same gate logic the main loop uses below
|
|
271
|
+
# (open the editor there first, THEN step) instead of blindly stepping human
|
|
272
|
+
# and moving on. Editing OFF: unchanged from before this function existed —
|
|
273
|
+
# step silently, refusal surfaced and halts, a clean/committed gate just falls
|
|
274
|
+
# into the loop below.
|
|
157
275
|
if ! peek_json="$(run_gtd next --json 2>&1)"; then
|
|
158
276
|
echo "gtd-loop: could not determine the next step:" >&2
|
|
159
277
|
echo "$peek_json" >&2
|
|
@@ -161,11 +279,15 @@ if ! peek_json="$(run_gtd next --json 2>&1)"; then
|
|
|
161
279
|
exit 1
|
|
162
280
|
fi
|
|
163
281
|
if [[ "$(jq -r .kind <<<"$peek_json")" == "message" ]]; then
|
|
164
|
-
if
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
282
|
+
if [[ "$edit_disabled" == 1 ]]; then
|
|
283
|
+
if ! step_out="$(run_gtd step human 2>&1)"; then
|
|
284
|
+
echo "gtd-loop: could not capture your changes at the human gate:" >&2
|
|
285
|
+
echo "$step_out" >&2
|
|
286
|
+
echo "Fix the reported issue and re-run gtd-loop." >&2
|
|
287
|
+
exit 1
|
|
288
|
+
fi
|
|
289
|
+
else
|
|
290
|
+
handle_human_gate "$peek_json"
|
|
169
291
|
fi
|
|
170
292
|
fi
|
|
171
293
|
|
|
@@ -186,18 +308,15 @@ while true; do
|
|
|
186
308
|
label="$(jq -r '.label // .state' <<<"$next_json")"
|
|
187
309
|
GTD_LAST_LABEL="$label"
|
|
188
310
|
|
|
189
|
-
if [[ "$kind" != "message" ]]; then
|
|
190
|
-
herdr_report working "$label"
|
|
191
|
-
fi
|
|
192
|
-
|
|
193
311
|
if [[ "$kind" == "message" ]]; then
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
exit 0
|
|
312
|
+
# handle_human_gate exits 0/non-zero itself on a halt/refusal; it only
|
|
313
|
+
# returns here when a new commit was captured, so we keep driving.
|
|
314
|
+
handle_human_gate "$next_json"
|
|
315
|
+
continue
|
|
199
316
|
fi
|
|
200
317
|
|
|
318
|
+
herdr_report working "$label"
|
|
319
|
+
|
|
201
320
|
if [[ "$kind" == "script" ]]; then
|
|
202
321
|
head_before="$(git rev-parse HEAD 2>/dev/null || echo none)"
|
|
203
322
|
# Execute the emitted wrapper verbatim; its exit code is deliberately
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -205428,6 +205428,10 @@ Commands:
|
|
|
205428
205428
|
an agent through gtd next/gtd step calls until the
|
|
205429
205429
|
workflow returns to its initial state again. A bare gtd
|
|
205430
205430
|
invocation and gtd loop both launch it identically
|
|
205431
|
+
edit [path] Open \${VISUAL:-$EDITOR} on <path>, or — with no path — on
|
|
205432
|
+
the resolved rest's declared file (or the repo directory
|
|
205433
|
+
if it declares none). Handled entirely by bin/gtd, not
|
|
205434
|
+
this bundle
|
|
205431
205435
|
init Scaffold a minimal .gtdrc.json for this repo, seeding the
|
|
205432
205436
|
default variables you are most likely to change (the test
|
|
205433
205437
|
command) and a Prettier formatting suggestion. gtd runs its
|
package/docs/cli.md
CHANGED
|
@@ -45,6 +45,10 @@ Commands:
|
|
|
45
45
|
commits that would be lost
|
|
46
46
|
next Print the resolved rest's rendered script/prompt/message
|
|
47
47
|
(no mutation)
|
|
48
|
+
edit [path] Open <path> (repo-relative) in $VISUAL/$EDITOR, blocking
|
|
49
|
+
until the editor exits. With no argument, opens the
|
|
50
|
+
resolved rest's declared file (or the repo root if it
|
|
51
|
+
declares none). Never reads --no-edit/GTD_NO_EDIT
|
|
48
52
|
status Print the resolved rest's state/actor and which declared
|
|
49
53
|
pattern (if any) each pending change matches (no mutation)
|
|
50
54
|
validate Format and validate the steering file the resolved rest
|
|
@@ -63,6 +67,8 @@ Options:
|
|
|
63
67
|
--no-open (gtd visualize only) do not open the browser
|
|
64
68
|
--cost=<n> (gtd step only) record the invocation's token cost
|
|
65
69
|
--model=<name> (gtd step only, with --cost) tag that cost's model
|
|
70
|
+
--no-edit (bare gtd or gtd loop only) disable the loop's automatic
|
|
71
|
+
editor launching at human gates
|
|
66
72
|
--version, -v Print version and exit
|
|
67
73
|
--help, -h Print this help and exit
|
|
68
74
|
```
|
|
@@ -79,12 +85,32 @@ history relative to cwd, so it refuses with a clear error if invoked from a
|
|
|
79
85
|
subdirectory.
|
|
80
86
|
|
|
81
87
|
`--json`, `--cost=<n>`, and `--model=<name>` (the latter two only for
|
|
82
|
-
`gtd step`) are the only long options
|
|
83
|
-
like `--jsn`) is rejected with a usage error
|
|
84
|
-
mistyped flag can never degrade a JSON caller
|
|
85
|
-
`--cost`/`--model` with no value, a non-numeric or
|
|
86
|
-
`--model`, `--model` without `--cost`, or either
|
|
87
|
-
`gtd step` are all usage errors.
|
|
88
|
+
`gtd step`) are the only long options the compiled bundle recognizes. Any other
|
|
89
|
+
`--` option (including a typo like `--jsn`) is rejected with a usage error
|
|
90
|
+
rather than silently ignored, so a mistyped flag can never degrade a JSON caller
|
|
91
|
+
to plain-text mode. A bare `--cost`/`--model` with no value, a non-numeric or
|
|
92
|
+
negative `--cost`, an empty `--model`, `--model` without `--cost`, or either
|
|
93
|
+
flag on any command other than `gtd step` are all usage errors.
|
|
94
|
+
|
|
95
|
+
`--no-edit` is a separate, bash-level flag handled entirely by `bin/gtd` itself,
|
|
96
|
+
stripped before anything reaches the bundle — see [`--no-edit`](#--no-edit)
|
|
97
|
+
below.
|
|
98
|
+
|
|
99
|
+
## `--no-edit`
|
|
100
|
+
|
|
101
|
+
A flag on the loop driver only — bare `gtd --no-edit` or `gtd loop --no-edit`
|
|
102
|
+
(the two are equivalent, since bare `gtd` and `gtd loop` are themselves
|
|
103
|
+
equivalent). Recognized in exactly those two positions; any other
|
|
104
|
+
placement/combination (e.g. `gtd step --no-edit`, or combined with any other
|
|
105
|
+
argument) is a usage error. The `GTD_NO_EDIT` environment variable (any
|
|
106
|
+
non-empty value) does the same thing.
|
|
107
|
+
|
|
108
|
+
Disables the loop's default behavior of launching an editor at human gates,
|
|
109
|
+
restoring the previous halt-and-print-and-exit behavior with no editor involved.
|
|
110
|
+
It governs only the loop's own automatic launching — `gtd edit` invoked directly
|
|
111
|
+
never reads it (see [`gtd edit`](#gtd-edit-path) above). See
|
|
112
|
+
[Driving the loop](loop.md) and `skills/loop/SKILL.md` for the full gate-flow
|
|
113
|
+
description.
|
|
88
114
|
|
|
89
115
|
## `gtd init`
|
|
90
116
|
|
|
@@ -408,6 +434,40 @@ which are JSON-only. `--json` emits
|
|
|
408
434
|
when the state has no `on` (a commit state); a per-edge `describe` is likewise
|
|
409
435
|
omitted when that edge declares none.
|
|
410
436
|
|
|
437
|
+
## `gtd edit [path]`
|
|
438
|
+
|
|
439
|
+
Handled entirely in `bin/gtd`'s own bash — unlike every other subcommand, it is
|
|
440
|
+
**never forwarded** to the compiled bundle (`dist/gtd.bundle.mjs`).
|
|
441
|
+
|
|
442
|
+
With `<path>` given (repo-relative), opens it in `${VISUAL:-$EDITOR}` (git's own
|
|
443
|
+
precedence — `$VISUAL` first, then `$EDITOR`; no fallback to `vi`), blocking in
|
|
444
|
+
the foreground until the editor exits. It creates nothing if `<path>` doesn't
|
|
445
|
+
exist — the path is handed straight to the editor command verbatim. The editor's
|
|
446
|
+
own exit code is ignored entirely; success is judged from tree state afterward,
|
|
447
|
+
not from this command.
|
|
448
|
+
|
|
449
|
+
With no argument, it peeks with `gtd next --json` to find the resolved rest's
|
|
450
|
+
declared `.file`, and opens that (repo-relative), or the repo directory (`.`)
|
|
451
|
+
when the resolved state declares no `file:`. If `gtd next --json` itself fails
|
|
452
|
+
(e.g. not in a repo), it prints an error and exits non-zero without attempting
|
|
453
|
+
to open an editor:
|
|
454
|
+
|
|
455
|
+
```
|
|
456
|
+
gtd edit: could not determine the next step:
|
|
457
|
+
<gtd next --json's own error output>
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
`gtd edit` **never** reads `--no-edit`/`GTD_NO_EDIT` — those two govern only the
|
|
461
|
+
loop's own automatic editor launching at human gates (see
|
|
462
|
+
[Driving the loop](loop.md) and `skills/loop/SKILL.md`), not this command.
|
|
463
|
+
Invoked directly, `gtd edit` always launches, unconditionally.
|
|
464
|
+
|
|
465
|
+
If neither `$VISUAL` nor `$EDITOR` is set, no editor is launched:
|
|
466
|
+
|
|
467
|
+
```
|
|
468
|
+
gtd: no editor configured — set $EDITOR (or $VISUAL)
|
|
469
|
+
```
|
|
470
|
+
|
|
411
471
|
## Running `script` rests (no `gtd` subcommand)
|
|
412
472
|
|
|
413
473
|
There is no `gtd` subcommand that executes a workflow script — gtd never runs a
|
package/docs/loop.md
CHANGED
|
@@ -41,16 +41,35 @@ loop picks their change up.
|
|
|
41
41
|
|
|
42
42
|
**A `"message"` rest is a real handoff, not a slow beat.** No driver signs off
|
|
43
43
|
for the human: in the bundled workflow the loop runs the whole cycle unattended
|
|
44
|
-
up to `await-review` and then
|
|
44
|
+
up to `await-review` and then rests there with the review checkout window open
|
|
45
45
|
(the reviewable diff surfaced as uncommitted changes — see
|
|
46
46
|
[STATES.md §11](../STATES.md#11-the-review-checkout-window)). Advancing takes a
|
|
47
47
|
human edit to `.gtd/REVIEW.md`: ticking every box with **no** comment signs off
|
|
48
48
|
into the squash finale, while any comment (a note, or a code edit of your own)
|
|
49
|
-
is feedback that routes into another build + re-review round.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
ended with [`gtd abandon`](cli.md#gtd-abandon---json), which drops the
|
|
53
|
-
commits and keeps their content as uncommitted changes.
|
|
49
|
+
is feedback that routes into another build + re-review round. That gate is the
|
|
50
|
+
contract, not a stall — nothing advances until the edit is captured, whether the
|
|
51
|
+
capture happens within the same run or a later one. A review nobody is going to
|
|
52
|
+
finish is ended with [`gtd abandon`](cli.md#gtd-abandon---json), which drops the
|
|
53
|
+
process's commits and keeps their content as uncommitted changes.
|
|
54
|
+
|
|
55
|
+
**Editing is on by default.** Reaching a `"message"` rest, `bin/gtd` opens
|
|
56
|
+
`${VISUAL:-$EDITOR}` on the rest's declared `.file` (or the repo root `.` when
|
|
57
|
+
the state declares none), blocking until the editor exits, then runs
|
|
58
|
+
`gtd step human` to capture whatever changed:
|
|
59
|
+
|
|
60
|
+
- a new commit was captured → the loop keeps driving on its own; re-launching is
|
|
61
|
+
never necessary;
|
|
62
|
+
- zero commits were captured (a clean tree once the editor closed) → the loop
|
|
63
|
+
halts, exit 0 — "done for now";
|
|
64
|
+
- the step refuses (a malformed steering file, or an edit matching no declared
|
|
65
|
+
pattern) → the refusal is surfaced verbatim and the loop halts non-zero,
|
|
66
|
+
exactly as a manual `gtd step human` refusal would.
|
|
67
|
+
|
|
68
|
+
Set `GTD_NO_EDIT` (any non-empty value), or pass `--no-edit` — see
|
|
69
|
+
[`cli.md`'s `--no-edit`](cli.md#--no-edit) for its exact syntax and positioning
|
|
70
|
+
— to disable this and restore the original halt-and-print behavior: the loop
|
|
71
|
+
prints the gate via `gtd next` and exits 0 without touching an editor, leaving
|
|
72
|
+
the human to edit and re-launch the loop themselves.
|
|
54
73
|
|
|
55
74
|
```bash
|
|
56
75
|
gtd next --json # ask who's up and what they should do
|
|
@@ -73,16 +92,18 @@ when the machine rests at a `"message"` gate — so `gtd` is the only command a
|
|
|
73
92
|
human runs. `bin/gtd` is the packaged entry point: invoked bare, or with `loop`
|
|
74
93
|
as its first argument, it runs this exact script; any other first argument (e.g.
|
|
75
94
|
`next`, `step`, `status`) hands off to `node dist/gtd.bundle.mjs` instead. The
|
|
76
|
-
loop body it runs adds
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
and
|
|
95
|
+
loop body it runs adds five things on top of the reference script above: it
|
|
96
|
+
opens an editor at every `"message"` gate instead of just printing it (see
|
|
97
|
+
"Editing is on by default" above; `--no-edit`/`GTD_NO_EDIT` fall back to the
|
|
98
|
+
reference script's plain print-and-exit); it stops with a diagnostic if the same
|
|
99
|
+
`"prompt"` state/content repeat with no progress (see `skills/loop/SKILL.md`'s
|
|
100
|
+
"Stall detection"); it lets `GTD_LOOP_AGENT_CMD` swap in any coding agent CLI in
|
|
101
|
+
place of the default `claude -p`, receiving the prompt via `$GTD_LOOP_PROMPT`;
|
|
102
|
+
it exports the resolved state's optional `model` hint as `$GTD_LOOP_MODEL`,
|
|
103
|
+
appending `--model "$GTD_LOOP_MODEL"` to the default `claude -p` invocation
|
|
104
|
+
whenever it's non-empty; and it acts on the optional `memory` scope hint (see
|
|
105
|
+
"Agent memory scope" below) — continuing one agent session across consecutive
|
|
106
|
+
same-scope turns and starting fresh when the scope changes.
|
|
86
107
|
|
|
87
108
|
`bin/gtd` resolves both its bundle hand-off and the loop's own internal `gtd`
|
|
88
109
|
calls against `dist/gtd.bundle.mjs` next to its own location. Set `GTD_BIN` — a
|