dev-loops 0.2.4 → 0.2.5

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dev-loops",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "Agent-harness-agnostic dev-loop: agents, skills, and hooks for GitHub/Copilot-driven development loops.",
5
5
  "author": {
6
6
  "name": "Manuel Fittko",
@@ -53,7 +53,11 @@ Use this helper output as source of truth for the normal routing seam. Interpret
53
53
  ```sh
54
54
  node <resolved-skill-scripts>/loop/run-watch-cycle.mjs --repo <owner/name> --pr <number>
55
55
  ```
56
- Persistent async watch/fix loop, not handoff-only behavior: `watch → detect → if threads found, fix + reply + resolve → re-request → watch again → … → pre_approval_gate → merge`. **PERSISTENCE MODEL: Subagents do bounded implementation tasks and exit on external wait. The main session drives the loop and re-dispatches when continuation is feasible.** A single returned watch cycle is never completion by itself. If `cycleDisposition` is `pending` and `terminal` is `false`, the subagent exits on the wait boundary; the main session re-dispatches another watch boundary. Max watch timeout: **30 minutes** (from `policy-constants.mjs` COPILOT_REVIEW_WAIT_TIMEOUT_MS); expired budget + still `waiting_for_copilot_review` = hard stop. If the user explicitly asks for async handoff-only behavior, say that out loud and stop after the handoff boundary.
56
+ Persistent async watch/fix loop, not handoff-only behavior: `watch → detect → if threads found, fix + reply + resolve → re-request → watch again → … → pre_approval_gate → merge`. A single returned watch cycle is never completion by itself.
57
+
58
+ > Under the Claude Code harness, run this loop **inline in a single agent**: the helper-owned wait tools (`dev-loops loop watch-cycle`, `gh run watch`, `dev-loops gate probe-copilot`) block inline and return — when `cycleDisposition` is `pending` and `terminal` is `false`, run the next watch cycle yourself. Do not exit on the wait boundary to have a parent re-dispatch the loop; keep driving it in this agent until a terminal state or the watch budget expires. (Delegating a bounded fix to the `fixer` agent, per Step 6, is still fine — that is task delegation, not re-dispatching the watch loop.)
59
+
60
+ Max watch timeout: **30 minutes** (from `policy-constants.mjs` COPILOT_REVIEW_WAIT_TIMEOUT_MS); expired budget + still `waiting_for_copilot_review` = hard stop. If the user explicitly asks for async handoff-only behavior, say that out loud and stop after the handoff boundary.
57
61
 
58
62
  **4. Low-level helpers**
59
63
  ```sh
@@ -133,8 +137,8 @@ already has an outer-loop checkpoint, check whether the checkpoint implies an au
133
137
  (including `timestamp` and potentially incrementing `waitCycles`).
134
138
  Read the on-disk artifact without mutating it.
135
139
  2. If `outerAction` is `continue_wait`:
136
- - The loop was waiting. The subagent exits; the main session re-dispatches a fresh
137
- `dev-loop` async subagent that resumes from the checkpoint.
140
+ - The loop was waiting; resume it from the checkpoint.
141
+ Under the Claude Code harness, continue the wait inline (run the next watch cycle yourself).
138
142
  3. If `outerAction` is `reenter_copilot_loop`:
139
143
  - The copilot inner loop needs action. Run `copilot-pr-handoff.mjs` to determine the
140
144
  exact next step and proceed.
@@ -145,8 +149,8 @@ already has an outer-loop checkpoint, check whether the checkpoint implies an au
145
149
  6. If no checkpoint exists or `outerAction` is `done`:
146
150
  - Continue with normal step sequencing.
147
151
 
148
- Do not skip this guard when transitioning between async subagent runs on the same PR.
149
- The outer-loop checkpoint is the canonical re-attachment artifact for the subagent.
152
+ Do not skip this guard when resuming work on the same PR.
153
+ The outer-loop checkpoint is the canonical re-attachment artifact.
150
154
 
151
155
  ## Step 6: Async watch behavior
152
156
 
@@ -162,8 +166,7 @@ Preferred approach:
162
166
  - `timeout`/`idle` → re-run `copilot-pr-handoff.mjs --watch-status <status>` once to refresh state; if still `waiting_for_copilot_review` after 30-minute watch budget exhausted, hard stop with `watch timeout — PR #<number> needs manual attention`
163
167
  - zero-timeout `idle` probes are for explicit one-shot status/reattach checks only; they are not the normal async wait mechanism
164
168
  - after a successful fix / reply-resolve / re-request cycle, returning to `waiting_for_copilot_review` is a persistence boundary: resume the watcher instead of reporting completion
165
- - if a child async run exits and the refreshed state remains non-terminal (for example `waiting_for_copilot_review`) before merge and without a hard stop, treat that as early exit and the main session re-dispatches the same-PR follow-up path when feasible (the subagent exits on external wait)
166
- - dispatch fix findings to `fixer` subagent; do not run inline fix passes in-watcher
169
+ - dispatch fix findings to the `fixer` agent; do not run inline fix passes in-watcher
167
170
  - do not report completion while unresolved Copilot feedback remains
168
171
 
169
172
  ### Canonical async dispatch wording
@@ -177,8 +180,8 @@ Key rules:
177
180
  - agent-authored shell polling is forbidden: do not use `nohup`, detached shell jobs, `tmux`, `screen`, or ad hoc `for i in $(seq ...)`, `while true`, `until ...; do sleep ...; done`, or `sleep`-retry bash loops
178
181
  - do not wrap repeated `gh pr view`, `gh pr checks`, `gh api`, or `detect-copilot-loop-state.mjs` calls inside shell polling loops
179
182
  - do not bypass session-based async notifications with detached shell automation
180
- - if Pi async subagents or the designated async follow-up skill are not appropriate or available, stop and report rather than improvising a shell watcher
181
- - the async-start contract is enforced in code: `outer-loop.mjs` fails closed without a visible Pi-managed async run id when `workflow.asyncStartMode: required`
183
+ - if the designated async follow-up skill is not appropriate or available, stop and report rather than improvising a shell watcher
184
+ - the async-start contract is enforced in code: `outer-loop.mjs` fails closed without a visible async run id when `workflow.asyncStartMode: required` (relaxed automatically under the Claude Code harness — see #830)
182
185
 
183
186
  ### Async delegation guard rules (#524)
184
187
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.2.5
6
+
7
+ ### Changed
8
+
9
+ - **Claude Code: the Copilot PR follow-up loop runs inline** (#838, completing the umbrella
10
+ collapse from #837). The copilot-pr-followup skill's Pi "persistence model" — *subagents do
11
+ bounded work and exit on the wait boundary; the main session re-dispatches* — is now scoped to
12
+ Pi via `<!-- pi-only -->`. Under the Claude harness the single dev-loop agent runs the
13
+ `watch → fix/reply/resolve → re-request → watch` loop **inline**: the helper-owned wait tools
14
+ (`dev-loops loop watch-cycle`, `gh run watch`, `dev-loops gate probe-copilot`) block inline and return, so
15
+ the agent keeps looping until terminal or the watch budget expires — no exit-and-redispatch. The
16
+ outer-loop checkpoint, watch budget, the forbidden-shell-watcher rules, and the gate requirements
17
+ are unchanged and harness-agnostic. Pi behavior is unchanged.
18
+
5
19
  ## 0.2.4
6
20
 
7
21
  ### Changed
package/package.json CHANGED
@@ -68,7 +68,7 @@
68
68
  },
69
69
  "dependencies": {
70
70
  "mermaid": "11.15.0",
71
- "@dev-loops/core": "^0.2.4"
71
+ "@dev-loops/core": "^0.2.5"
72
72
  },
73
73
  "repository": {
74
74
  "type": "git",
@@ -78,7 +78,7 @@
78
78
  "url": "https://github.com/mfittko/dev-loops/issues"
79
79
  },
80
80
  "homepage": "https://github.com/mfittko/dev-loops#readme",
81
- "version": "0.2.4",
81
+ "version": "0.2.5",
82
82
  "files": [
83
83
  "cli/",
84
84
  "lib/",
@@ -57,7 +57,15 @@ Use this helper output as source of truth for the normal routing seam. Interpret
57
57
  ```sh
58
58
  node <resolved-skill-scripts>/loop/run-watch-cycle.mjs --repo <owner/name> --pr <number>
59
59
  ```
60
- Persistent async watch/fix loop, not handoff-only behavior: `watch → detect → if threads found, fix + reply + resolve → re-request → watch again → … → pre_approval_gate → merge`. **PERSISTENCE MODEL: Subagents do bounded implementation tasks and exit on external wait. The main session drives the loop and re-dispatches when continuation is feasible.** A single returned watch cycle is never completion by itself. If `cycleDisposition` is `pending` and `terminal` is `false`, the subagent exits on the wait boundary; the main session re-dispatches another watch boundary. Max watch timeout: **30 minutes** (from `policy-constants.mjs` COPILOT_REVIEW_WAIT_TIMEOUT_MS); expired budget + still `waiting_for_copilot_review` = hard stop. If the user explicitly asks for async handoff-only behavior, say that out loud and stop after the handoff boundary.
60
+ Persistent async watch/fix loop, not handoff-only behavior: `watch → detect → if threads found, fix + reply + resolve → re-request → watch again → … → pre_approval_gate → merge`. A single returned watch cycle is never completion by itself.
61
+
62
+ <!-- pi-only -->
63
+ **PERSISTENCE MODEL: Subagents do bounded implementation tasks and exit on external wait. The main session drives the loop and re-dispatches when continuation is feasible.** If `cycleDisposition` is `pending` and `terminal` is `false`, the subagent exits on the wait boundary; the main session re-dispatches another watch boundary.
64
+ <!-- /pi-only -->
65
+
66
+ > Under the Claude Code harness, run this loop **inline in a single agent**: the helper-owned wait tools (`dev-loops loop watch-cycle`, `gh run watch`, `dev-loops gate probe-copilot`) block inline and return — when `cycleDisposition` is `pending` and `terminal` is `false`, run the next watch cycle yourself. Do not exit on the wait boundary to have a parent re-dispatch the loop; keep driving it in this agent until a terminal state or the watch budget expires. (Delegating a bounded fix to the `fixer` agent, per Step 6, is still fine — that is task delegation, not re-dispatching the watch loop.)
67
+
68
+ Max watch timeout: **30 minutes** (from `policy-constants.mjs` COPILOT_REVIEW_WAIT_TIMEOUT_MS); expired budget + still `waiting_for_copilot_review` = hard stop. If the user explicitly asks for async handoff-only behavior, say that out loud and stop after the handoff boundary.
61
69
 
62
70
  **4. Low-level helpers**
63
71
  ```sh
@@ -137,8 +145,10 @@ already has an outer-loop checkpoint, check whether the checkpoint implies an au
137
145
  (including `timestamp` and potentially incrementing `waitCycles`).
138
146
  Read the on-disk artifact without mutating it.
139
147
  2. If `outerAction` is `continue_wait`:
140
- - The loop was waiting. The subagent exits; the main session re-dispatches a fresh
141
- `dev-loop` async subagent that resumes from the checkpoint.
148
+ - The loop was waiting; resume it from the checkpoint.
149
+ <!-- pi-only -->Under Pi the subagent exits and the main session re-dispatches a fresh
150
+ `dev-loop` async subagent that resumes from the checkpoint.<!-- /pi-only -->
151
+ Under the Claude Code harness, continue the wait inline (run the next watch cycle yourself).
142
152
  3. If `outerAction` is `reenter_copilot_loop`:
143
153
  - The copilot inner loop needs action. Run `copilot-pr-handoff.mjs` to determine the
144
154
  exact next step and proceed.
@@ -149,8 +159,8 @@ already has an outer-loop checkpoint, check whether the checkpoint implies an au
149
159
  6. If no checkpoint exists or `outerAction` is `done`:
150
160
  - Continue with normal step sequencing.
151
161
 
152
- Do not skip this guard when transitioning between async subagent runs on the same PR.
153
- The outer-loop checkpoint is the canonical re-attachment artifact for the subagent.
162
+ Do not skip this guard when resuming work on the same PR<!-- pi-only --> (under Pi, between async subagent runs)<!-- /pi-only -->.
163
+ The outer-loop checkpoint is the canonical re-attachment artifact.
154
164
 
155
165
  ## Step 6: Async watch behavior
156
166
 
@@ -166,8 +176,10 @@ Preferred approach:
166
176
  - `timeout`/`idle` → re-run `copilot-pr-handoff.mjs --watch-status <status>` once to refresh state; if still `waiting_for_copilot_review` after 30-minute watch budget exhausted, hard stop with `watch timeout — PR #<number> needs manual attention`
167
177
  - zero-timeout `idle` probes are for explicit one-shot status/reattach checks only; they are not the normal async wait mechanism
168
178
  - after a successful fix / reply-resolve / re-request cycle, returning to `waiting_for_copilot_review` is a persistence boundary: resume the watcher instead of reporting completion
179
+ <!-- pi-only -->
169
180
  - if a child async run exits and the refreshed state remains non-terminal (for example `waiting_for_copilot_review`) before merge and without a hard stop, treat that as early exit and the main session re-dispatches the same-PR follow-up path when feasible (the subagent exits on external wait)
170
- - dispatch fix findings to `fixer` subagent; do not run inline fix passes in-watcher
181
+ <!-- /pi-only -->
182
+ - dispatch fix findings to the `fixer` agent; do not run inline fix passes in-watcher
171
183
  - do not report completion while unresolved Copilot feedback remains
172
184
 
173
185
  ### Canonical async dispatch wording
@@ -181,8 +193,8 @@ Key rules:
181
193
  - agent-authored shell polling is forbidden: do not use `nohup`, detached shell jobs, `tmux`, `screen`, or ad hoc `for i in $(seq ...)`, `while true`, `until ...; do sleep ...; done`, or `sleep`-retry bash loops
182
194
  - do not wrap repeated `gh pr view`, `gh pr checks`, `gh api`, or `detect-copilot-loop-state.mjs` calls inside shell polling loops
183
195
  - do not bypass session-based async notifications with detached shell automation
184
- - if Pi async subagents or the designated async follow-up skill are not appropriate or available, stop and report rather than improvising a shell watcher
185
- - the async-start contract is enforced in code: `outer-loop.mjs` fails closed without a visible Pi-managed async run id when `workflow.asyncStartMode: required`
196
+ - if the designated async follow-up skill is not appropriate or available, stop and report rather than improvising a shell watcher
197
+ - the async-start contract is enforced in code: `outer-loop.mjs` fails closed without a visible async run id when `workflow.asyncStartMode: required` (relaxed automatically under the Claude Code harness — see #830)
186
198
 
187
199
  ### Async delegation guard rules (#524)
188
200