@pmelab/gtd 2.0.0 → 2.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.
Files changed (3) hide show
  1. package/README.md +23 -0
  2. package/bin/gtd-loop +58 -0
  3. package/package.json +4 -2
package/README.md CHANGED
@@ -67,6 +67,9 @@ gtd next --json # ask who's up and what they should do
67
67
  See [The reference loop driver](#the-reference-loop-driver) for a full script
68
68
  implementing this protocol, and [`skills/loop/SKILL.md`](skills/loop/SKILL.md)
69
69
  for the agent-facing instructions that follow the same pinned contract.
70
+ `gtd-loop`, installed alongside `gtd` (see below), is the packaged, ready-to-run
71
+ implementation of that same script for anyone who doesn't want to drive the loop
72
+ by hand.
70
73
 
71
74
  ## Installation
72
75
 
@@ -397,6 +400,26 @@ side can drive — agent rests and agent-driven checkpoints — reports
397
400
  cycles, a force-approved package close) chain without human involvement until an
398
401
  actual human gate is hit.
399
402
 
403
+ `bin/gtd-loop`, installed as the `gtd-loop` binary, is the packaged
404
+ implementation of this exact script — kept in sync with it the same way
405
+ `skills/loop/SKILL.md` is. It additionally attempts `gtd step` (not just
406
+ `gtd step-agent`) every iteration, so a plain rerun after you've edited a file
407
+ at a human gate (no commit needed) picks up your edit and keeps going, and it
408
+ halts with a diagnostic if the same state and prompt repeat with no progress
409
+ (see `skills/loop/SKILL.md`'s "Stall detection").
410
+
411
+ ### Using a different agent
412
+
413
+ `gtd-loop` defaults to
414
+ `claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions`, but the agent
415
+ invocation is swappable: set `GTD_LOOP_AGENT_CMD` to any shell command, and it
416
+ runs with the prompt available as `$GTD_LOOP_PROMPT` in its environment. For
417
+ example, to drive a different agent CLI:
418
+
419
+ ```bash
420
+ GTD_LOOP_AGENT_CMD='my-agent-cli --prompt "$GTD_LOOP_PROMPT"' gtd-loop
421
+ ```
422
+
400
423
  ## States & subjects overview
401
424
 
402
425
  `resolve()` lands on exactly one of **16 states**: `grilling`, `grilled`,
package/bin/gtd-loop ADDED
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ # Drives the two-beat protocol (README.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.
9
+ prev_state=""
10
+ prev_prompt=""
11
+
12
+ while true; do
13
+ gtd step --json >/dev/null 2>&1 || true
14
+ gtd step-agent --json >/dev/null 2>&1 || true
15
+
16
+ if ! next_json="$(gtd next --json 2>&1)"; then
17
+ echo "gtd-loop: could not determine the next step:" >&2
18
+ echo "$next_json" >&2
19
+ echo "Run \`gtd status\` to inspect the repo." >&2
20
+ exit 1
21
+ fi
22
+
23
+ actor="$(jq -r .actor <<<"$next_json")"
24
+ pending="$(jq -r .pending <<<"$next_json")"
25
+ state="$(jq -r .state <<<"$next_json")"
26
+ prompt="$(jq -r .prompt <<<"$next_json")"
27
+
28
+ if [[ "$actor" != "agent" ]]; then
29
+ echo "--- Your turn ($state) ---"
30
+ gtd next
31
+ exit 0
32
+ fi
33
+
34
+ if [[ "$pending" == "true" ]]; then
35
+ prev_state=""
36
+ prev_prompt=""
37
+ continue
38
+ fi
39
+
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
44
+ echo "gtd-loop: no progress at '$state' — the agent's last turn changed nothing. Stopping to avoid spinning." >&2
45
+ gtd next >&2
46
+ exit 1
47
+ fi
48
+ prev_state="$state"
49
+ prev_prompt="$prompt"
50
+
51
+ # 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.
53
+ cmd="${GTD_LOOP_AGENT_CMD:-}"
54
+ if [[ -z "$cmd" ]]; then
55
+ cmd='claude -p "$GTD_LOOP_PROMPT" --dangerously-skip-permissions'
56
+ fi
57
+ GTD_LOOP_PROMPT="$prompt" bash -c "$cmd"
58
+ done
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "@pmelab/gtd",
3
- "version": "2.0.0",
3
+ "version": "2.1.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": {
7
- "gtd": "dist/gtd.bundle.mjs"
7
+ "gtd": "dist/gtd.bundle.mjs",
8
+ "gtd-loop": "bin/gtd-loop"
8
9
  },
9
10
  "files": [
10
11
  "dist/",
12
+ "bin/",
11
13
  "README.md",
12
14
  "LICENSE",
13
15
  "schema.json"