@maxiaochao/pi-toolkit 0.10.24 → 0.11.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/CHANGELOG.md +10 -0
- package/evaluations/agents-md/README.md +19 -0
- package/evaluations/agents-md/run.mjs +217 -0
- package/evaluations/agents-md/tests/run-tests.mjs +52 -0
- package/global/AGENTS.md +13 -8
- package/package.json +2 -1
- package/packages/herdr-subagents/ARCHITECTURE.md +407 -0
- package/packages/herdr-subagents/CHANGELOG.md +4 -0
- package/packages/herdr-subagents/README.md +2 -0
- package/packages/herdr-subagents/package.json +2 -1
- package/packages/worktree/CHANGELOG.md +5 -0
- package/packages/worktree/README.md +6 -7
- package/packages/worktree/TESTING.md +5 -5
- package/packages/worktree/bin/pi-worktree +31 -66
- package/packages/worktree/bin/pi-worktree-completion.bash +4 -4
- package/packages/worktree/docs/demo.gif +0 -0
- package/packages/worktree/docs/screenshot.png +0 -0
- package/packages/worktree/extensions/worktree.ts +30 -30
- package/packages/worktree/package.json +1 -1
- package/packages/worktree/skills/pi-worktree/SKILL.md +3 -6
- package/packages/worktree/tests/extension.test.mjs +2 -2
- package/packages/worktree/tests/run-tests.sh +28 -32
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# Herdr Subagents architecture and decision-pause design
|
|
2
|
+
|
|
3
|
+
This document describes the package's current architecture, the problems exposed by failure and blocking semantics, and the target decision-pause model. Sections marked **Current** describe implemented behavior. Sections marked **Target** are an implementation plan, not the current contract.
|
|
4
|
+
|
|
5
|
+
## 1. Product boundary
|
|
6
|
+
|
|
7
|
+
Herdr Subagents runs ordinary interactive Pi Agents in visible Herdr panes and keeps their complete sessions and results in project-local durable records. The parent receives compact status, questions, summaries, and document paths.
|
|
8
|
+
|
|
9
|
+
A batch is a resource-bounded collection of **independent tasks**:
|
|
10
|
+
|
|
11
|
+
- array order controls FIFO scheduling, pane numbering, and result order;
|
|
12
|
+
- `concurrency` controls how many tasks may be active at once;
|
|
13
|
+
- a batch containing a write-capable persona is forced to concurrency one;
|
|
14
|
+
- concurrency one does **not** express `A -> B` dependency semantics;
|
|
15
|
+
- tasks that consume another task's result must be orchestrated by the parent as separate runs.
|
|
16
|
+
|
|
17
|
+
The package does not currently need a DAG scheduler. If dependency workflows become a first-class product requirement, they should be introduced explicitly with dependency and skip-propagation semantics instead of inferred from array order.
|
|
18
|
+
|
|
19
|
+
## 2. Architecture overview
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Parent Pi tool call
|
|
23
|
+
|
|
|
24
|
+
v
|
|
25
|
+
Extension lifecycle and foreground handoff
|
|
26
|
+
| extensions/herdr-subagents.ts
|
|
27
|
+
v
|
|
28
|
+
Global run dispatcher ---- persisted background queue
|
|
29
|
+
| src/dispatcher.ts, src/queued-runs.ts
|
|
30
|
+
v
|
|
31
|
+
Batch runner and bounded workers
|
|
32
|
+
| src/batch-runner.ts
|
|
33
|
+
+---- pane allocation / Herdr Agent lifecycle
|
|
34
|
+
| src/run-pane-allocator.ts, src/live-agent.ts, src/herdr.ts
|
|
35
|
+
+---- attempt-scoped structured report
|
|
36
|
+
| src/attempts.ts, src/protocol.ts, src/records.ts
|
|
37
|
+
+---- durable run/task/session records
|
|
38
|
+
| .pi/herdr-subagents/runs/<run>/...
|
|
39
|
+
v
|
|
40
|
+
Aggregate status, monitor, control, recovery and cleanup
|
|
41
|
+
src/run-status.ts, src/status.ts, src/fleet*.ts,
|
|
42
|
+
src/blocking.ts, src/historical-resume.ts,
|
|
43
|
+
src/reconcile.ts, src/tab-cleanup.ts
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Responsibilities
|
|
47
|
+
|
|
48
|
+
| Layer | Responsibility |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Extension | Register tools, bind parent-session lifetime, return foreground results, send final background follow-ups. |
|
|
51
|
+
| Dispatcher | Give one run ownership of the global submission lane and queue later submissions FIFO. |
|
|
52
|
+
| Batch runner | Persist the run, start bounded workers, allocate one pane per task, and aggregate task results. |
|
|
53
|
+
| Live Agent adapter | Start or continue an interactive Pi Agent and distinguish runtime telemetry from business reports. |
|
|
54
|
+
| Records | Atomically persist run, task, turn, report, attempt, ownership, and resume state. |
|
|
55
|
+
| Control | Inspect, answer, retry/continue saved work, cancel, resume history, and clean archives. |
|
|
56
|
+
| Recovery | Reconcile stale owners and processes, settle abandoned work, and clean identifiable tabs. |
|
|
57
|
+
| Fleet | Project durable business state plus transient runtime telemetry into the parent UI. |
|
|
58
|
+
|
|
59
|
+
## 3. Authoritative state and invariants
|
|
60
|
+
|
|
61
|
+
1. A matching attempt-scoped `subagent_report` is authoritative for business `completed`, `blocked`, or `failed`.
|
|
62
|
+
2. Herdr `working`, `blocked`, `idle`, and `done` are transport/runtime telemetry. Herdr UI `blocked` projects to `waiting_interaction`; it does not make the business task blocked.
|
|
63
|
+
3. Each task owns one pane and one Pi session. A pane is never reused by another task.
|
|
64
|
+
4. A task session has at most one writer. Task resume locks enforce that invariant.
|
|
65
|
+
5. Shared `run.json` changes occur under the short-lived run-state lock. An Agent turn never holds that lock.
|
|
66
|
+
6. Every new prompt has a unique attempt ID. A late report from an older attempt cannot settle a newer attempt.
|
|
67
|
+
7. Task and report state is persisted before it is exposed as an actionable parent result.
|
|
68
|
+
8. Running work is not forcibly interrupted merely because a sibling needs a decision.
|
|
69
|
+
|
|
70
|
+
## 4. Current execution flow
|
|
71
|
+
|
|
72
|
+
### Submission
|
|
73
|
+
|
|
74
|
+
1. Tool parameters are validated.
|
|
75
|
+
2. Configuration and personas are loaded and resolved.
|
|
76
|
+
3. A stable run ID is allocated.
|
|
77
|
+
4. Background runs are durably queued before dispatch; foreground runs wait for the dispatcher lane.
|
|
78
|
+
5. The batch runner creates `run.json`, task directories, task records, prompts, and session paths.
|
|
79
|
+
6. Effective concurrency is bounded by settings and forced to one if any persona is write-capable.
|
|
80
|
+
|
|
81
|
+
### Task execution
|
|
82
|
+
|
|
83
|
+
Each worker repeatedly claims the next FIFO task, allocates a pane, starts an interactive Pi Agent, waits for the matching structured report, persists the result, and claims another task. A failed task does not currently stop that worker. A blocked task stops only its worker lane.
|
|
84
|
+
|
|
85
|
+
### Current foreground outcomes
|
|
86
|
+
|
|
87
|
+
| Event | Current foreground behavior | Queued siblings |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| All tasks complete | Return after the whole batch settles. | Completed normally. |
|
|
90
|
+
| Failure with concurrency one | Continue later tasks, then return terminal `failed` or `partial`. | Continue automatically. |
|
|
91
|
+
| Failure with concurrency greater than one and unfinished siblings | Persist the failure, return early, detach the batch, and let it finish in the background. | Continue automatically. |
|
|
92
|
+
| Business block | Wait for the other worker lanes to settle, then return the question and retain the dispatcher lane. | A blocked worker stops, but other workers keep claiming tasks. |
|
|
93
|
+
| Herdr UI block | Keep waiting for an authoritative report while showing `waiting_interaction`. | Unchanged. |
|
|
94
|
+
|
|
95
|
+
The failure and block rows are asymmetric: parallel failure gives control back promptly, while block may withhold its question until unrelated work finishes. Serial failure also assumes later tasks are independent. The target design removes both ambiguities.
|
|
96
|
+
|
|
97
|
+
## 5. Dispatcher ownership in plain language
|
|
98
|
+
|
|
99
|
+
The dispatcher is the global submission lane, not the task-concurrency limiter.
|
|
100
|
+
|
|
101
|
+
| Operation | Meaning |
|
|
102
|
+
| --- | --- |
|
|
103
|
+
| `detach` | The run continues in the background but gives up the submission lane, so another run may start. |
|
|
104
|
+
| `retain` | The run is waiting for a parent decision and keeps the lane; a new foreground run is rejected and a background run stays queued. |
|
|
105
|
+
| `release` | A retained run is resolved or cancelled and gives up the lane. |
|
|
106
|
+
|
|
107
|
+
Current parallel failure uses `detach`; current business block eventually uses `retain`.
|
|
108
|
+
|
|
109
|
+
## 6. Target decision-pause model
|
|
110
|
+
|
|
111
|
+
### Goal
|
|
112
|
+
|
|
113
|
+
Any actionable business problem returns control to the parent immediately and stops new task dispatch until the parent decides what to do. Already-running siblings are allowed to finish safely.
|
|
114
|
+
|
|
115
|
+
```text
|
|
116
|
+
A reports failed or blocked
|
|
117
|
+
|
|
|
118
|
+
+---- persist task/report/attempt state
|
|
119
|
+
+---- pause new queue claims
|
|
120
|
+
+---- return pause details to the parent immediately
|
|
121
|
+
+---- retain the dispatcher lane
|
|
122
|
+
|
|
|
123
|
+
B and C were already running ---- continue to a terminal report
|
|
124
|
+
D and E were queued ------------- remain queued
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
"Pause" means pausing **dispatch**, not freezing an Agent process at an arbitrary instruction. Forcibly suspending or cancelling running siblings could leave tools, file writes, or external operations in an unknown state.
|
|
128
|
+
|
|
129
|
+
### Run control state must be separate from task outcome
|
|
130
|
+
|
|
131
|
+
The current `RunStatus` reuses task statuses and aggregates them into `running`, `blocked`, `partial`, and terminal values. That combines two different questions:
|
|
132
|
+
|
|
133
|
+
1. May the scheduler dispatch more work?
|
|
134
|
+
2. What outcomes have tasks produced?
|
|
135
|
+
|
|
136
|
+
The target model separates them conceptually:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
type RunPhase = "queued" | "running" | "paused" | "cancelling" | "settled";
|
|
140
|
+
type RunOutcome = "completed" | "partial" | "failed" | "cancelled";
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The public status projection may continue exposing `status: "paused"` for convenience, but durable control logic should use the phase. While a run is paused, some task activities may still be `running` as already-started siblings settle.
|
|
144
|
+
|
|
145
|
+
### Durable pause reasons
|
|
146
|
+
|
|
147
|
+
A pause is tied to a specific task attempt so stale answers cannot resolve newer work:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
interface PauseReason {
|
|
151
|
+
taskId: string;
|
|
152
|
+
taskOrder: number;
|
|
153
|
+
attemptId: string;
|
|
154
|
+
kind: "blocked" | "failed";
|
|
155
|
+
resolution: "pending" | "responded" | "retried" | "continued" | "cancelled";
|
|
156
|
+
createdAt: string;
|
|
157
|
+
resolvedAt?: string;
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
The durable reason should reference authoritative task/report records instead of duplicating mutable summary, question, and error text. Status and tool responses project a detailed view:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"status": "paused",
|
|
166
|
+
"pauseReasons": [
|
|
167
|
+
{
|
|
168
|
+
"task": 1,
|
|
169
|
+
"kind": "failed",
|
|
170
|
+
"summary": "Authentication review failed.",
|
|
171
|
+
"error": "Provider request failed.",
|
|
172
|
+
"allowedActions": ["retry", "continue", "cancel"]
|
|
173
|
+
}
|
|
174
|
+
]
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Multiple already-running siblings may subsequently fail or block. Their reasons accumulate. No queued task starts while any pending reason remains.
|
|
179
|
+
|
|
180
|
+
### Decision actions
|
|
181
|
+
|
|
182
|
+
| Reason | Action | Effect |
|
|
183
|
+
| --- | --- | --- |
|
|
184
|
+
| `blocked` | `respond` | Continue the same live/saved session with the answer. |
|
|
185
|
+
| `failed` | `retry` | Retry or continue the selected task explicitly; never infer a task. |
|
|
186
|
+
| `failed` | `continue` | Accept that task's failure and allow the run to proceed without retrying it. |
|
|
187
|
+
| Any | `cancel` | Cancel running and queued work and settle the run as cancelled. |
|
|
188
|
+
|
|
189
|
+
`respond` should no longer be overloaded for failed tasks once `retry` exists. This makes control intent and audit history explicit.
|
|
190
|
+
|
|
191
|
+
The queue resumes only when every pending pause reason is resolved. A retry or response that blocks/fails again creates a reason for the new attempt.
|
|
192
|
+
|
|
193
|
+
### Failure classification
|
|
194
|
+
|
|
195
|
+
Both child-reported failures and generated terminal failures can pause a run:
|
|
196
|
+
|
|
197
|
+
- valid `subagent_report(status="failed")`;
|
|
198
|
+
- child process or prompt API terminal error without a valid report;
|
|
199
|
+
- Agent settled without publishing a report after the grace period;
|
|
200
|
+
- pane or Agent startup failure.
|
|
201
|
+
|
|
202
|
+
Ambiguous prompt delivery remains `delivery_unknown` while the child is alive and must not be converted into a retryable failure. Retry safety should be projected explicitly when the implementation can prove whether a prompt was submitted; the system must never automatically replay an attempt with uncertain side effects.
|
|
203
|
+
|
|
204
|
+
### Foreground handoff
|
|
205
|
+
|
|
206
|
+
Failure and block should share one foreground-handoff mechanism:
|
|
207
|
+
|
|
208
|
+
1. observe an actionable, durably persisted task attempt;
|
|
209
|
+
2. atomically pause dispatch and register its reason;
|
|
210
|
+
3. detach the parent tool-call abort signal without cancelling the run;
|
|
211
|
+
4. retain dispatcher ownership;
|
|
212
|
+
5. return the projected pause details immediately;
|
|
213
|
+
6. keep already-running siblings and final background lifecycle tracking alive;
|
|
214
|
+
7. send at most one terminal follow-up after the run eventually settles.
|
|
215
|
+
|
|
216
|
+
The event-specific policy only determines allowed decisions and response rendering. It should not duplicate lifecycle, persistence, or notification machinery.
|
|
217
|
+
|
|
218
|
+
## 7. Target flows
|
|
219
|
+
|
|
220
|
+
### Independent parallel tasks
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
Submit A, B, C, D with concurrency 3
|
|
224
|
+
A/B/C start; D queued
|
|
225
|
+
A fails
|
|
226
|
+
-> run phase paused
|
|
227
|
+
-> D remains queued
|
|
228
|
+
-> parent receives A failure immediately
|
|
229
|
+
B/C continue safely
|
|
230
|
+
Parent retries A, continues past A, or cancels
|
|
231
|
+
-> once all pending reasons are resolved, dispatch may resume
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Serial tasks
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
Submit A, B, C with concurrency 1
|
|
238
|
+
A starts; B/C queued
|
|
239
|
+
A fails or blocks
|
|
240
|
+
-> run phase paused
|
|
241
|
+
-> B/C do not start
|
|
242
|
+
-> parent decides
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
This makes serial execution safer, but still does not make B consume A's result. A real `A -> B` workflow remains parent-orchestrated as separate runs.
|
|
246
|
+
|
|
247
|
+
### Runtime-only Herdr block
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
Herdr reports blocked
|
|
251
|
+
-> task remains business running
|
|
252
|
+
-> Fleet shows waiting_interaction
|
|
253
|
+
-> no decision pause yet
|
|
254
|
+
Child publishes matching structured blocked report
|
|
255
|
+
-> create pause reason
|
|
256
|
+
-> return exact question
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## 8. Configuration: keep fewer concepts, not necessarily fewer files
|
|
260
|
+
|
|
261
|
+
### Current user-facing sources
|
|
262
|
+
|
|
263
|
+
| Scope | Runtime settings and persona overrides | Persona definitions and prompts |
|
|
264
|
+
| --- | --- | --- |
|
|
265
|
+
| Project | `.pi/herdr-subagents.json` | `.pi/herdr-subagents/agents/*.md` |
|
|
266
|
+
| Global | `~/.pi/agent/herdr-subagents.json` | `~/.pi/agent/herdr-subagents/agents/*.md` |
|
|
267
|
+
| Package | Built-in defaults | Built-in `agents/*.md` |
|
|
268
|
+
|
|
269
|
+
The two formats have distinct jobs:
|
|
270
|
+
|
|
271
|
+
- JSON is suitable for environment policy and small overrides.
|
|
272
|
+
- Markdown frontmatter plus body is suitable for a named persona and its system prompt.
|
|
273
|
+
|
|
274
|
+
Merging them into one physical file would either put long prompts into JSON or require runtime policy to be parsed from Markdown. It would also force users to copy an entire built-in persona merely to override its model. Therefore the two physical forms should remain.
|
|
275
|
+
|
|
276
|
+
### Sources of confusion to remove
|
|
277
|
+
|
|
278
|
+
1. Persona Markdown and JSON both expose `model`, `thinking`, and `skills`; this is intentional override layering but must be described as one resolution pipeline.
|
|
279
|
+
2. Call-level task model overrides are resolved later in `tool.ts`, after configuration loading.
|
|
280
|
+
3. TypeBox validates shape while `validation.ts` validates action-dependent requirements; these are complementary but currently look like duplicated validation.
|
|
281
|
+
4. Downstream modules receive partially resolved values instead of one canonical run plan.
|
|
282
|
+
|
|
283
|
+
### Canonical normalization boundary
|
|
284
|
+
|
|
285
|
+
All sources should be normalized once before persistence or dispatch:
|
|
286
|
+
|
|
287
|
+
```text
|
|
288
|
+
Built-in defaults
|
|
289
|
+
<- global JSON
|
|
290
|
+
<- project JSON
|
|
291
|
+
<- effective persona Markdown
|
|
292
|
+
<- global persona override
|
|
293
|
+
<- project persona override
|
|
294
|
+
<- call/task override
|
|
295
|
+
|
|
|
296
|
+
v
|
|
297
|
+
ResolvedRunPlan + diagnostics + source metadata
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
A target canonical plan can contain only execution-ready values:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
interface ResolvedRunPlan {
|
|
304
|
+
label: string;
|
|
305
|
+
requestedConcurrency: number;
|
|
306
|
+
effectiveConcurrency: number;
|
|
307
|
+
tasks: Array<{
|
|
308
|
+
name: string;
|
|
309
|
+
prompt: string;
|
|
310
|
+
persona: string;
|
|
311
|
+
access: "read" | "write";
|
|
312
|
+
model?: string;
|
|
313
|
+
thinking?: string;
|
|
314
|
+
tools?: string[];
|
|
315
|
+
skills: string[];
|
|
316
|
+
systemPrompt: string;
|
|
317
|
+
}>;
|
|
318
|
+
provenance: Record<string, string>;
|
|
319
|
+
diagnostics: string[];
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
After this boundary, the batch runner, persistence, recovery, and UI should not know about global/project/package precedence.
|
|
324
|
+
|
|
325
|
+
### Configuration reductions
|
|
326
|
+
|
|
327
|
+
Do:
|
|
328
|
+
|
|
329
|
+
- retain one JSON settings file per scope and one persona directory per scope;
|
|
330
|
+
- centralize precedence and call overrides in a single `resolveRunPlan` step;
|
|
331
|
+
- expose resolved values and provenance through `list/settings` diagnostics;
|
|
332
|
+
- state prominently that batch tasks are independent;
|
|
333
|
+
- make decision pause the safe fixed behavior rather than adding a new failure-policy option;
|
|
334
|
+
- keep runtime-only Herdr states out of business configuration.
|
|
335
|
+
|
|
336
|
+
Do not add now:
|
|
337
|
+
|
|
338
|
+
- DAG or `dependsOn` configuration;
|
|
339
|
+
- configurable `failurePolicy` variants;
|
|
340
|
+
- separate block/failure handoff settings;
|
|
341
|
+
- automatic retry counts;
|
|
342
|
+
- configuration for dispatcher `detach`/`retain` behavior.
|
|
343
|
+
|
|
344
|
+
These options would multiply state-machine branches before a demonstrated need. The safe decision gate should be the invariant.
|
|
345
|
+
|
|
346
|
+
### Validation ownership
|
|
347
|
+
|
|
348
|
+
- `parameters.ts`: public schema, field types, basic bounds, and model-visible descriptions.
|
|
349
|
+
- `validation.ts`: cross-field and action-specific requirements.
|
|
350
|
+
- `resolveRunPlan`: persona existence, precedence, capability constraints, effective concurrency, and canonical values.
|
|
351
|
+
- runtime state machine: whether an action is legal for the selected run/task/attempt.
|
|
352
|
+
|
|
353
|
+
This division avoids both duplicated validation and an oversized configuration loader.
|
|
354
|
+
|
|
355
|
+
## 9. Implementation seams for the target model
|
|
356
|
+
|
|
357
|
+
| Area | Required change |
|
|
358
|
+
| --- | --- |
|
|
359
|
+
| `records.ts` | Separate run phase/outcome, persist attempt-scoped pause reasons, and preserve backward-compatible reads. |
|
|
360
|
+
| `run-status.ts` | Aggregate task outcomes independently from scheduler phase. |
|
|
361
|
+
| `batch-runner.ts` | Add a shared dispatch gate; stop queue claims immediately when a reason is registered. |
|
|
362
|
+
| `extensions/herdr-subagents.ts` | Replace failure-only early return with shared actionable-event handoff. |
|
|
363
|
+
| `dispatcher.ts` | Retain paused runs and release only after resolution/cancellation; keep ownership transitions explicit. |
|
|
364
|
+
| `blocking.ts` / control | Split blocked `respond` from failed `retry`; add explicit `continue`. |
|
|
365
|
+
| `continue-run.ts` | Resume queued dispatch only when no pending reason remains. |
|
|
366
|
+
| `reconcile.ts` | Recover paused runs and cancel them when their owning parent session disappears. |
|
|
367
|
+
| `status.ts` / Fleet | Show pause reasons, allowed actions, and still-running sibling activity together. |
|
|
368
|
+
| `parameters.ts` / `validation.ts` | Add `retry` and `continue`, clarify independent-task semantics. |
|
|
369
|
+
| tests | Cover immediate handoff, dispatch pause, multiple reasons, resolution races, restart recovery, and exactly-once final notification. |
|
|
370
|
+
|
|
371
|
+
## 10. Required tests
|
|
372
|
+
|
|
373
|
+
1. Serial failure pauses before the next queued task starts.
|
|
374
|
+
2. Serial block pauses before the next queued task starts.
|
|
375
|
+
3. Parallel failure returns immediately while already-running siblings continue.
|
|
376
|
+
4. Parallel block returns immediately while already-running siblings continue.
|
|
377
|
+
5. Queued siblings never start while a reason is pending.
|
|
378
|
+
6. A second already-running sibling can add another pause reason without losing the first.
|
|
379
|
+
7. Resolving only one of multiple reasons does not resume dispatch.
|
|
380
|
+
8. `continue` preserves the failed task result and eventually produces `partial` when other tasks succeed.
|
|
381
|
+
9. Retry/response is scoped to task and attempt; stale resolution is rejected.
|
|
382
|
+
10. Herdr UI `blocked` alone never pauses business dispatch.
|
|
383
|
+
11. `delivery_unknown` never causes automatic replay.
|
|
384
|
+
12. A paused run retains the dispatcher lane; foreground submissions fail fast and background submissions remain queued.
|
|
385
|
+
13. Cancellation settles running/queued tasks and releases the retained lane.
|
|
386
|
+
14. Parent-session shutdown and startup reconciliation do not leave ownerless paused work.
|
|
387
|
+
15. Foreground handoff and final follow-up are each delivered at most once.
|
|
388
|
+
|
|
389
|
+
## 11. Non-goals
|
|
390
|
+
|
|
391
|
+
- Inferring dependencies from task order or prompt text.
|
|
392
|
+
- Freezing arbitrary live Agent processes.
|
|
393
|
+
- Automatically retrying failed or ambiguously delivered prompts.
|
|
394
|
+
- Treating Herdr UI state as business truth.
|
|
395
|
+
- Loading complete child results into parent context.
|
|
396
|
+
- Adding policy configuration for every state transition.
|
|
397
|
+
|
|
398
|
+
## 12. Summary
|
|
399
|
+
|
|
400
|
+
The architecture becomes clearer when it separates four concerns:
|
|
401
|
+
|
|
402
|
+
1. **Task outcome:** what each child authoritatively reported.
|
|
403
|
+
2. **Run phase:** whether new work may be dispatched or a parent decision is required.
|
|
404
|
+
3. **Runtime telemetry:** what Herdr currently observes without changing business truth.
|
|
405
|
+
4. **Dispatcher ownership:** whether another run may enter the global submission lane.
|
|
406
|
+
|
|
407
|
+
The immediate next design step is a shared decision-pause and foreground-handoff mechanism for business failure and block. Configuration should be simplified through one canonical resolution boundary and fewer policy choices, not by forcing settings and persona prompts into one file.
|
|
@@ -32,6 +32,8 @@ Inside a Herdr workspace, the package registers `herdr_subagents`, `herdr_subage
|
|
|
32
32
|
|
|
33
33
|
The design replaces hidden print-mode subprocesses with ordinary interactive Pi Agents managed through Herdr, so delegated work stays visible, inspectable, resumable, and durably recorded.
|
|
34
34
|
|
|
35
|
+
See [ARCHITECTURE.md](ARCHITECTURE.md) for the current execution architecture, the proposed decision-pause state machine, and configuration-normalization boundaries.
|
|
36
|
+
|
|
35
37
|
## Usage
|
|
36
38
|
|
|
37
39
|
Discover the effective personas first:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maxiaochao/pi-herdr-subagents",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Run inspectable interactive Pi subagent batches through Herdr.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"tests",
|
|
16
16
|
"docs",
|
|
17
17
|
"README.md",
|
|
18
|
+
"ARCHITECTURE.md",
|
|
18
19
|
"TESTING.md",
|
|
19
20
|
"CHANGELOG.md",
|
|
20
21
|
"package.json"
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-10-12 - v0.4.0
|
|
4
|
+
|
|
5
|
+
- Replace CLI start and prepare with the create-only command
|
|
6
|
+
- replace the CLI `start` and `prepare` commands with one idempotent `create` command that never launches Pi
|
|
7
|
+
|
|
3
8
|
## 2026-10-09 - v0.3.2
|
|
4
9
|
|
|
5
10
|
- continue Agent tasks automatically after switching into a worktree
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @maxiaochao/pi-worktree
|
|
2
2
|
|
|
3
|
-
`pi-worktree` CLI、Pi Extension 与配套 skill
|
|
3
|
+
`pi-worktree` CLI、Pi Extension 与配套 skill。CLI 负责管理 worktree;Extension 让用户或 Agent 在当前 Pi 界面中切换,并保留完整对话。
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|

|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
pi-worktree
|
|
17
|
-
pi-worktree
|
|
16
|
+
pi-worktree create feature
|
|
17
|
+
pi-worktree create --base main --json feature
|
|
18
18
|
pi-worktree info feature
|
|
19
19
|
pi-worktree out
|
|
20
20
|
pi-worktree remove feature
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
`
|
|
23
|
+
`create` 从当前分支(或显式 `--base`)创建或复用 `.worktrees/feature` 并记录 base,不启动 Pi。`--json` 提供相同操作的机器可读结果。
|
|
24
24
|
|
|
25
25
|
在交互式 Pi 中,用户可以保留当前界面和完整对话:
|
|
26
26
|
|
|
@@ -61,8 +61,7 @@ pi update npm:@maxiaochao/pi-worktree # 更新独立子包
|
|
|
61
61
|
## 命令
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
pi-worktree
|
|
65
|
-
pi-worktree prepare [--base <ref>] [--json] <name>
|
|
64
|
+
pi-worktree create [--base <ref>] [--json] <name>
|
|
66
65
|
pi-worktree list
|
|
67
66
|
pi-worktree info <name>
|
|
68
67
|
pi-worktree out
|
|
@@ -70,6 +69,6 @@ pi-worktree remove <name>
|
|
|
70
69
|
pi-worktree prune
|
|
71
70
|
```
|
|
72
71
|
|
|
73
|
-
`
|
|
72
|
+
`create` 是幂等接口;`create --json` 供 Extension 和其他宿主使用,返回 `created`、`attached`、`reused` 或 `already-active`,以及绝对路径、分支和 dirty 状态。已有 worktree 会复用;已存在但未挂载的同名分支会挂载;stale 注册、非法名称和路径冲突会显式失败。
|
|
74
73
|
|
|
75
74
|
Agent 用法见 `skills/pi-worktree/SKILL.md`。测试流程、夹具和结果见 [TESTING.md](TESTING.md)。
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
1. `npm --prefix packages/worktree test`:在临时 Git 仓库中运行 CLI,并验证 Extension 注册、延迟命令桥接和 session 切换生命周期。
|
|
6
6
|
2. `npm pack ./packages/worktree --dry-run`:确认 CLI、completion、skill 和安装脚本进入 tarball。
|
|
7
|
-
3. 手工验收发布包的 `pi-worktree
|
|
7
|
+
3. 手工验收发布包的 `pi-worktree create` 创建与复用流程。
|
|
8
8
|
4. 确认 README 示例、真实临时 Git 仓库输出 `docs/screenshot.png` 和 `docs/demo.gif` 进入 tarball。
|
|
9
9
|
|
|
10
10
|
## 用例数据
|
|
11
11
|
|
|
12
12
|
- `--help` 输出命令说明。
|
|
13
|
-
- `
|
|
14
|
-
- `
|
|
13
|
+
- `create` 从当前分支创建 `.worktrees/<name>` 并记录 base。
|
|
14
|
+
- `create --json` 覆盖 created、reused、already-active、dirty 和非法名称安全失败。
|
|
15
15
|
- `/worktree start` 把历史 fork 到 cwd 正确的新 session,再调用 `switchSession`。
|
|
16
|
-
- `enter_worktree`
|
|
16
|
+
- `enter_worktree` 串行创建或复用目标,在 `agent_settled` 后触发内部命令,并 fork 当前 session 后调用 `switchSession`。
|
|
17
17
|
- Agent 轮被中止时不触发切换;用户取消 session replacement 时删除派生 session。
|
|
18
18
|
- 自定义 session 目录在 fork 后保持不变。
|
|
19
|
-
-
|
|
19
|
+
- 已删除的 CLI `start` 和 `prepare` 会显式失败。
|
|
20
20
|
- `list` 标记主 checkout 和子 worktree。
|
|
21
21
|
- `info` 报告 clean、branch、base 和 ahead。
|
|
22
22
|
- postinstall 把可执行 CLI 与 completion 复制到隔离 HOME,并保持执行权限。
|