pi-subagents 0.24.2 → 0.24.4
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 +26 -0
- package/README.md +13 -5
- package/package.json +4 -8
- package/prompts/review-loop.md +41 -0
- package/skills/pi-subagents/SKILL.md +51 -21
- package/src/agents/agent-management.ts +5 -0
- package/src/agents/agent-serializer.ts +2 -0
- package/src/agents/agents.ts +30 -6
- package/src/agents/skills.ts +25 -23
- package/src/extension/config.ts +16 -0
- package/src/extension/index.ts +8 -24
- package/src/extension/schemas.ts +1 -1
- package/src/intercom/intercom-bridge.ts +2 -1
- package/src/runs/background/async-execution.ts +16 -5
- package/src/runs/background/async-job-tracker.ts +16 -8
- package/src/runs/background/async-status.ts +5 -2
- package/src/runs/background/run-status.ts +4 -1
- package/src/runs/background/subagent-runner.ts +34 -7
- package/src/runs/foreground/execution.ts +17 -5
- package/src/runs/foreground/subagent-executor.ts +6 -7
- package/src/runs/shared/completion-guard.ts +23 -1
- package/src/runs/shared/mcp-direct-tool-allowlist.ts +365 -0
- package/src/runs/shared/parallel-utils.ts +2 -0
- package/src/runs/shared/pi-args.ts +5 -0
- package/src/runs/shared/run-history.ts +12 -7
- package/src/runs/shared/single-output.ts +12 -2
- package/src/shared/artifacts.ts +2 -2
- package/src/shared/formatters.ts +13 -0
- package/src/shared/model-info.ts +10 -0
- package/src/shared/types.ts +1 -0
- package/src/shared/utils.ts +11 -1
- package/src/tui/render.ts +160 -147
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
## [0.24.4] - 2026-05-20
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
- Treat provider-coerced single-run `output: "false"` the same as boolean `false`, preventing literal `false` output files in foreground and async runs.
|
|
13
|
+
- Include selected direct MCP tool names in explicit child `--tools` allowlists when metadata cache/config resolution is available.
|
|
14
|
+
- Honor `PI_CODING_AGENT_DIR` for runtime config, agent/chain/settings discovery, skills, run history, artifact cleanup, and intercom defaults.
|
|
15
|
+
- Hide nested child Pi process windows on Windows for both foreground and background subagent runs.
|
|
16
|
+
- Avoid completion-guard false positives for declared read-only agents, and add `completionGuard: false` for bash-enabled non-implementation agents that should not be required to edit files.
|
|
17
|
+
- Skip empty or whitespace-only assistant text parts when selecting subagent final output, so later meaningful text in the same or earlier assistant message is not masked.
|
|
18
|
+
- Declare `@earendil-works/pi-tui` as a runtime dependency so packaged installs can load the extension without relying on dev dependencies or optional peers.
|
|
19
|
+
- Treat recovered intermediate child tool/provider errors as successful when a later clean final assistant response is emitted, preventing false failed subagent results.
|
|
20
|
+
- Use progress-driven spinner frames in subagent result rows and async widgets, avoiding timer-driven off-screen redraw flicker in small terminals.
|
|
21
|
+
|
|
22
|
+
## [0.24.3] - 2026-05-14
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
- Show provider-free model and thinking labels in async subagent widgets and status views.
|
|
26
|
+
- Added a packaged `/review-loop` prompt for parent-controlled worker, fresh-reviewer, and fix-worker cycles that can run as an initial async chain or as follow-up subagent runs after async worker completions, stopping when reviewers find no fixes worth doing now or the review-round cap is reached.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Let `async: true` chain tool calls run in the background when `clarify` is omitted, and avoid showing the async badge for explicit foreground clarify runs.
|
|
30
|
+
|
|
5
31
|
## [0.24.2] - 2026-05-10
|
|
6
32
|
|
|
7
33
|
### Fixed
|
package/README.md
CHANGED
|
@@ -70,6 +70,10 @@ Run parallel reviewers on this diff. I want one focused on correctness, one on t
|
|
|
70
70
|
Have worker implement this approved plan. Afterward, run parallel reviewers, summarize their feedback, and apply the fixes that make sense.
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
```text
|
|
74
|
+
Run a review loop on this change until reviewers stop finding fixes worth doing, with a max of 3 rounds.
|
|
75
|
+
```
|
|
76
|
+
|
|
73
77
|
```text
|
|
74
78
|
Use scout to understand the auth flow, then have planner turn that into an implementation plan.
|
|
75
79
|
```
|
|
@@ -85,6 +89,7 @@ Those are ordinary Pi requests. Pi decides whether to call `subagent`, which age
|
|
|
85
89
|
| Review a diff | “Use reviewer to review this diff.” |
|
|
86
90
|
| Run parallel reviewers | “Run reviewers for correctness, tests, and cleanup.” |
|
|
87
91
|
| Implement then review | “Implement this, then review it.” |
|
|
92
|
+
| Review until clean | “Run a review loop on this change with a max of 3 rounds.” |
|
|
88
93
|
| Execute a plan carefully | “Have worker implement this approved plan, then run reviewers and apply the feedback.” |
|
|
89
94
|
| Scout before planning | “Use scout to inspect the auth flow before planning.” |
|
|
90
95
|
| Run in the background | “Run this in the background.” |
|
|
@@ -185,6 +190,7 @@ The package includes reusable prompt templates for common workflows. You do not
|
|
|
185
190
|
| Prompt | Use it for |
|
|
186
191
|
|--------|------------|
|
|
187
192
|
| `/parallel-review` | Launch fresh-context reviewers with distinct angles, then synthesize what to fix. |
|
|
193
|
+
| `/review-loop` | Run parent-controlled worker, reviewer, and fix-worker cycles until clean or capped. |
|
|
188
194
|
| `/parallel-research` | Combine `researcher` and `scout` for external evidence, local code context, and practical tradeoffs. |
|
|
189
195
|
| `/parallel-context-build` | Run `context-builder` agents in parallel to produce planning handoff context and meta-prompts. |
|
|
190
196
|
| `/parallel-handoff-plan` | Combine external research and `context-builder` passes into an implementation handoff plan and meta-prompt. |
|
|
@@ -427,6 +433,7 @@ skills: safe-bash, chrome-devtools
|
|
|
427
433
|
output: context.md
|
|
428
434
|
defaultReads: context.md
|
|
429
435
|
defaultProgress: true
|
|
436
|
+
completionGuard: false
|
|
430
437
|
interactive: true
|
|
431
438
|
maxSubagentDepth: 1
|
|
432
439
|
---
|
|
@@ -452,12 +459,13 @@ Important fields:
|
|
|
452
459
|
| `output` | Default single-agent output file. |
|
|
453
460
|
| `defaultReads` | Files to read before running in chain/parallel behavior. |
|
|
454
461
|
| `defaultProgress` | Maintain `progress.md`. |
|
|
462
|
+
| `completionGuard` | Set `false` only for non-implementation agents that may mention implementation words while using mutation-capable tools such as `bash`. |
|
|
455
463
|
| `interactive` | Parsed for compatibility but not enforced in v1. |
|
|
456
464
|
| `maxSubagentDepth` | Tightens nested delegation for this agent’s children. |
|
|
457
465
|
|
|
458
466
|
### Tool and extension selection
|
|
459
467
|
|
|
460
|
-
If `tools` is omitted, `pi-subagents` does not pass `--tools`, so the child gets Pi’s normal builtin tools. If `tools` is present, regular tool names become an explicit allowlist. `mcp:` entries are split out and forwarded as direct MCP selections. Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than builtin tool names.
|
|
468
|
+
If `tools` is omitted, `pi-subagents` does not pass `--tools`, so the child gets Pi’s normal builtin tools. If `tools` is present, regular tool names become an explicit allowlist. `mcp:` entries are split out and forwarded as direct MCP selections. Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than builtin tool names. Agents that declare only known read-only builtin tools skip the implementation completion guard, but `bash`, unknown tools, and MCP tools stay mutation-capable. Use `completionGuard: false` for bash-enabled validators or advisors that should never be judged as implementation agents.
|
|
461
469
|
|
|
462
470
|
Examples:
|
|
463
471
|
|
|
@@ -583,7 +591,7 @@ The package bundles a `pi-subagents` skill that is automatically available to th
|
|
|
583
591
|
|
|
584
592
|
What the bundled skill covers:
|
|
585
593
|
- **Delegation patterns**: when to launch which agent, whether to use single, parallel, chain, or async mode, and whether to use fresh or forked context
|
|
586
|
-
- **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command. This includes parallel review, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup
|
|
594
|
+
- **Prompt workflow recipes**: how to apply the packaged techniques directly with `subagent(...)` when the user describes the workflow in natural language instead of invoking a slash command. This includes parallel review, review-loop, parallel research, parallel context-build, parallel handoff-plan, gather-context-and-clarify, and parallel cleanup
|
|
587
595
|
- **Role-agent prompting guidance**: compact contract prompts instead of long scripts, what to include in role-specific meta prompts, and retrieval budgets for researchers
|
|
588
596
|
- **Safety boundaries**: child agents must not run subagents, must not invent intercom targets, and must escalate unapproved decisions
|
|
589
597
|
- **Intercom conventions**: when to ask vs send, and how parent-side result delivery works with `pi-intercom`
|
|
@@ -620,8 +628,8 @@ These are the parameters the LLM passes when it calls the `subagent` tool. Most
|
|
|
620
628
|
{ agent: "reviewer" }
|
|
621
629
|
]}
|
|
622
630
|
|
|
623
|
-
// Chain
|
|
624
|
-
{ chain: [...],
|
|
631
|
+
// Chain in the background, suitable for unblocking the main chat
|
|
632
|
+
{ chain: [...], async: true }
|
|
625
633
|
|
|
626
634
|
// Chain with fan-out/fan-in
|
|
627
635
|
{ chain: [
|
|
@@ -710,7 +718,7 @@ Agent definitions are not loaded into context by default. Management actions let
|
|
|
710
718
|
| `chainDir` | string | temp chain dir | Persistent directory for chain artifacts. |
|
|
711
719
|
| `clarify` | boolean | true for chains | Show TUI preview/edit flow. |
|
|
712
720
|
| `agentScope` | `user \| project \| both` | `both` | Agent discovery scope. Project wins on collisions. |
|
|
713
|
-
| `async` | boolean | false | Background execution.
|
|
721
|
+
| `async` | boolean | false | Background execution. For chains, `clarify: true` explicitly keeps the run foreground for the clarify UI. |
|
|
714
722
|
| `cwd` | string | runtime cwd | Override working directory. |
|
|
715
723
|
| `maxOutput` | object | 200KB, 5000 lines | Final output truncation limits. |
|
|
716
724
|
| `artifacts` | boolean | true | Write debug artifacts. |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-subagents",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.4",
|
|
4
4
|
"description": "Pi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification",
|
|
5
5
|
"author": "Nico Bailon",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,8 +54,7 @@
|
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@earendil-works/pi-agent-core": "*",
|
|
56
56
|
"@earendil-works/pi-ai": "*",
|
|
57
|
-
"@earendil-works/pi-coding-agent": "*"
|
|
58
|
-
"@earendil-works/pi-tui": "*"
|
|
57
|
+
"@earendil-works/pi-coding-agent": "*"
|
|
59
58
|
},
|
|
60
59
|
"peerDependenciesMeta": {
|
|
61
60
|
"@earendil-works/pi-agent-core": {
|
|
@@ -66,19 +65,16 @@
|
|
|
66
65
|
},
|
|
67
66
|
"@earendil-works/pi-coding-agent": {
|
|
68
67
|
"optional": true
|
|
69
|
-
},
|
|
70
|
-
"@earendil-works/pi-tui": {
|
|
71
|
-
"optional": true
|
|
72
68
|
}
|
|
73
69
|
},
|
|
74
70
|
"dependencies": {
|
|
71
|
+
"@earendil-works/pi-tui": "^0.74.0",
|
|
75
72
|
"jiti": "^2.7.0",
|
|
76
73
|
"typebox": "^1.1.24"
|
|
77
74
|
},
|
|
78
75
|
"devDependencies": {
|
|
79
76
|
"@earendil-works/pi-agent-core": "^0.74.0",
|
|
80
77
|
"@earendil-works/pi-ai": "^0.74.0",
|
|
81
|
-
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
82
|
-
"@earendil-works/pi-tui": "^0.74.0"
|
|
78
|
+
"@earendil-works/pi-coding-agent": "^0.74.0"
|
|
83
79
|
}
|
|
84
80
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Review/fix loop until clean
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Run a parent-orchestrated review loop for the requested work.
|
|
6
|
+
|
|
7
|
+
Use the `subagent` tool. Keep the parent session as the loop controller and final decision-maker. Child subagents must receive concrete role-specific tasks; they must not run subagents or manage the loop themselves.
|
|
8
|
+
|
|
9
|
+
Default to a maximum of 3 review rounds unless I specify a different cap. Count a review round each time fresh-context reviewers inspect the current diff after a worker pass. Stop early when reviewers find no blockers or fixes worth doing now.
|
|
10
|
+
|
|
11
|
+
If the invocation includes an implementation request, first launch one async `worker` to implement the approved scope. If the current diff is already the target, start with review. The sequence can be launched up front as an async/background chain when the workflow is already clear, or continued as follow-up subagent runs after each async completion. For an initial chain, pass `async: true` so the main chat is unblocked; do not set `clarify: true` unless I explicitly want the foreground clarify UI. Use only one writer against the active worktree at a time unless I explicitly ask for isolated worktrees.
|
|
12
|
+
|
|
13
|
+
For each review round, launch fresh-context `reviewer` agents in parallel. Reviewers must inspect the repository, relevant instructions, and current diff directly from files and commands. They must not rely on the main conversation history and must not edit files.
|
|
14
|
+
|
|
15
|
+
Choose review angles from the actual change. Common angles are correctness/regressions, tests/validation, and simplicity/maintainability. Add security, performance, docs/API contracts, or user-flow validation when the work calls for it. Prefer three strong reviewers over many vague reviewers.
|
|
16
|
+
|
|
17
|
+
After reviewers return, synthesize their feedback into:
|
|
18
|
+
- blockers or scope/product/architecture decisions that need user approval;
|
|
19
|
+
- fixes worth doing now;
|
|
20
|
+
- optional improvements;
|
|
21
|
+
- feedback to ignore or defer, with a short reason.
|
|
22
|
+
|
|
23
|
+
Do not blindly apply every reviewer suggestion. If reviewers surface an unapproved product, scope, or architecture decision, pause and ask me before launching a fix worker.
|
|
24
|
+
|
|
25
|
+
When an async implementation worker completes, treat its handoff as the transition into review, not as final completion, unless I explicitly asked for worker-only work, review-only output, or to stop after implementation.
|
|
26
|
+
|
|
27
|
+
When there are fixes worth doing now and the workflow is implementation-authorized, launch one async forked `worker` to apply only those synthesized fixes. Ask it to preserve the approved scope, run focused validation, and report changed files, commands run with exit codes, validation evidence, surprises, and anything left undone.
|
|
28
|
+
|
|
29
|
+
After a fix worker returns, run another review round only when it made material changes or addressed non-trivial findings. Do not keep looping for optional polish, speculative improvements, or findings already deferred by the parent.
|
|
30
|
+
|
|
31
|
+
Stop and summarize when one of these is true:
|
|
32
|
+
- reviewers find no blockers or fixes worth doing now;
|
|
33
|
+
- remaining feedback is optional, speculative, or intentionally deferred;
|
|
34
|
+
- reviewers surface an unapproved decision that needs me;
|
|
35
|
+
- the max review-round cap is reached.
|
|
36
|
+
|
|
37
|
+
On completion, inspect the final diff yourself, run or confirm focused validation where appropriate, and summarize the loop: rounds run, fixes applied, validation, remaining deferred items, and why the loop stopped.
|
|
38
|
+
|
|
39
|
+
Additional target, implementation request, max-iteration cap, or review focus from the slash command invocation:
|
|
40
|
+
|
|
41
|
+
$@
|
|
@@ -40,6 +40,7 @@ you are guiding a human through an interactive flow.
|
|
|
40
40
|
|
|
41
41
|
Packaged prompt shortcuts are also available for repeatable workflows. Treat them as reusable orchestration recipes, not just human slash commands. When the user asks for one of these shapes, or when the workflow clearly fits, apply the same pattern directly with `subagent(...)` and other tools:
|
|
42
42
|
- `/parallel-review` — fresh-context reviewers with distinct review angles, then synthesis
|
|
43
|
+
- `/review-loop` — parent-orchestrated worker, fresh-reviewer, and fix-worker cycles until clean or capped
|
|
43
44
|
- `/parallel-research` — combine `researcher` and `scout` for external evidence plus local code context
|
|
44
45
|
- `/parallel-context-build` — parallel `context-builder` passes that produce planning handoff context and meta-prompts
|
|
45
46
|
- `/parallel-handoff-plan` — external-reference research plus local `context-builder` passes, followed by a synthesis handoff plan and implementation-ready meta-prompt
|
|
@@ -54,6 +55,10 @@ The prompt templates in `prompts/` encode workflows the parent agent can run on
|
|
|
54
55
|
|
|
55
56
|
Use this when the user wants adversarial review of a diff, plan, issue, file, or implemented work. Launch fresh-context `reviewer` agents with distinct angles generated from the actual target. Common angles are correctness/regressions, tests/validation, and simplicity/maintainability; adapt for TypeScript, UI, security, docs, or large structural changes. Reviewers should inspect files and diffs directly, return concise evidence-backed findings with file/line references, and avoid edits unless the user explicitly asks for a writer pass. The parent synthesizes fixes worth doing now, optional improvements, and feedback to ignore/defer before applying anything.
|
|
56
57
|
|
|
58
|
+
### Review-loop technique
|
|
59
|
+
|
|
60
|
+
Use this when the user wants implementation or current diff review to continue until reviewers stop finding fixes worth doing now. Keep the loop in the parent session: one async `worker` implements or fixes, fresh-context `reviewer` agents inspect the actual repo and diff, the parent synthesizes accepted fixes, and one async forked `worker` applies them. The parent can express the sequence up front as an async/background chain when the workflow is known, or continue with explicit follow-up subagent runs after each async completion. For an initial chain, pass `async: true` so the main chat is unblocked; do not set `clarify: true` unless the user explicitly wants the foreground clarify UI. Treat an async implementation worker handoff as an intermediate state, not final completion, unless the user explicitly asked for worker-only work, review-only output, or to stop after implementation. Stop when reviewers find no blockers or fixes worth doing now, remaining feedback is optional or deferred, an unapproved product/scope/architecture decision appears, or the max review-round cap is reached. Default to 3 review rounds unless the user sets a different cap. Do not loop for optional polish, and do not let children launch subagents or decide the loop outcome.
|
|
61
|
+
|
|
57
62
|
### Parallel research technique
|
|
58
63
|
|
|
59
64
|
Use this when the question needs both external evidence and local implications. Combine `researcher` for official docs, specs, ecosystem behavior, recent changes, benchmarks, and primary sources with `scout` for repository files, patterns, constraints, tests, and likely integration points. Give each child a distinct angle: external evidence, local code context, and practical tradeoffs. Ask for source links or file ranges, confidence level, gaps, and decision implications. Do not ask these children to edit unless implementation was explicitly requested.
|
|
@@ -260,9 +265,11 @@ without forcing each step to rediscover everything.
|
|
|
260
265
|
|
|
261
266
|
### Async/background
|
|
262
267
|
|
|
263
|
-
|
|
268
|
+
Prefer async mode for every subagent launch. Set `async: true` no matter the task unless there is a specific reason to opt into a foreground/blocking run. This applies to scouts, researchers, workers, reviewers, validators, oracle checks, one-off delegates, chains, and parallel groups. Keep the write path single-threaded even when the run is async.
|
|
264
269
|
|
|
265
|
-
|
|
270
|
+
Async does not mean parallel writes. Do not edit the same active worktree while an async worker is changing it. Parent-side overlap should be reading, validation prep, synthesis, command planning, or review of unaffected context unless the writer is isolated in a separate worktree.
|
|
271
|
+
|
|
272
|
+
Do not end your turn immediately after launching an async child if you promised to keep working. Continue the local inspection, synthesis, or validation prep, then check the async run when its result is needed. If there is no independent work left and you would only be running `sleep` or status polling commands to wait, end your turn instead. Pi will deliver the async completion when it arrives.
|
|
266
273
|
|
|
267
274
|
```typescript
|
|
268
275
|
subagent({
|
|
@@ -360,7 +367,7 @@ subagent({
|
|
|
360
367
|
```
|
|
361
368
|
|
|
362
369
|
Chains default to clarify mode; set `clarify: false` to skip it. Clarify edits affect only the next run; use management actions, settings, or markdown files for persistent changes.
|
|
363
|
-
For programmatic background launches, use `clarify: false
|
|
370
|
+
For programmatic background launches, use `async: true`. Set `clarify: false` when you want to bypass chain clarification explicitly; `clarify: true` keeps the run foreground for the clarify UI.
|
|
364
371
|
|
|
365
372
|
|
|
366
373
|
## Worktree Isolation
|
|
@@ -410,6 +417,8 @@ subagent({
|
|
|
410
417
|
a forked advisory thread that inherits the parent session history and uses that
|
|
411
418
|
history as a baseline contract.
|
|
412
419
|
|
|
420
|
+
Use `oracle` as a smart-friend escalation when the parent needs help with trajectory rather than diff inspection: architectural boundaries, model capability routing, merge conflicts, reviewer disagreement, context drift after long work, a worker about to invent a pattern, or fixes that require product/scope tradeoffs. Ask broad questions when the right concern is unclear, and let `oracle` point out missing context or files the parent should inspect before asking again. Keep `oracle` advisory unless it has been explicitly assigned the single writer role.
|
|
421
|
+
|
|
413
422
|
## Subagent + Intercom Coordination
|
|
414
423
|
|
|
415
424
|
`pi-subagents` works without `pi-intercom`. When `pi-intercom` is installed and enabled, the intercom bridge can automatically give child agents a private coordination channel back to the parent session.
|
|
@@ -539,9 +548,10 @@ copying a full builtin file.
|
|
|
539
548
|
## Prompt Template Integration
|
|
540
549
|
|
|
541
550
|
The package includes prompt shortcuts for common workflows: `/parallel-review`,
|
|
542
|
-
`/
|
|
543
|
-
`/gather-context-and-clarify`, and
|
|
544
|
-
|
|
551
|
+
`/review-loop`, `/parallel-research`, `/parallel-context-build`,
|
|
552
|
+
`/parallel-handoff-plan`, `/gather-context-and-clarify`, and
|
|
553
|
+
`/parallel-cleanup`. Use them when the user wants repeatable review,
|
|
554
|
+
review/fix loops, research, context handoff, implementation handoff,
|
|
545
555
|
clarification, or cleanup-review patterns. `/parallel-review autofix` and
|
|
546
556
|
`/parallel-cleanup autofix` synthesize reviewer feedback and then apply only the
|
|
547
557
|
fixes worth doing now. Parent agents can also apply the same recipes directly
|
|
@@ -570,10 +580,13 @@ particular agent or with forked context.
|
|
|
570
580
|
|
|
571
581
|
## Best Practices
|
|
572
582
|
|
|
583
|
+
### Prefer async orchestration
|
|
584
|
+
|
|
585
|
+
Launch every subagent asynchronously by default. Use `async: true` for scouts, researchers, workers, reviewers, validators, oracle checks, one-off delegates, chains, and parallel groups unless you intentionally need a foreground/blocking run. The parent should keep moving: inspect code while scouts run, prepare validation while a worker implements, do a local diff pass while reviewers review, and synthesize or verify while a fix worker applies accepted feedback. Async is the default orchestration posture; foreground runs are the explicit opt-out.
|
|
586
|
+
|
|
573
587
|
### Keep writes single-threaded by default
|
|
574
588
|
|
|
575
|
-
A strong pattern is one main decision-maker plus advisory/research/review
|
|
576
|
-
subagents around it. Use `oracle` for advice and `worker` for the actual write path.
|
|
589
|
+
A strong pattern is one main decision-maker plus advisory/research/review/validation subagents around it. Use `oracle` for advice and `worker` for the actual write path. Parallelize reading, review, validation, and synthesis support, not normal writes, unless you deliberately isolate writers with worktrees. A child that writes should report what changed, what was left undone, commands run with exit codes, validation evidence, surprises, and any decisions that need parent approval.
|
|
577
590
|
|
|
578
591
|
### Use fork for branched advisory or execution threads
|
|
579
592
|
|
|
@@ -625,6 +638,7 @@ When the user approves launching a subagent to carry out a plan or workflow, tre
|
|
|
625
638
|
|
|
626
639
|
- `/gather-context-and-clarify` maps to: launch `scout` and, when needed, `researcher`; synthesize findings; then use `interview` to ask every clarification question needed for shared understanding.
|
|
627
640
|
- `/parallel-review` maps to: launch fresh-context `reviewer` agents with distinct review angles; synthesize the feedback before applying anything.
|
|
641
|
+
- `/review-loop` maps to: keep the parent in charge of worker → fresh reviewers → synthesized fix worker cycles until no fixes worth doing now remain, an unapproved decision appears, or the review-round cap is reached.
|
|
628
642
|
- `/parallel-research` maps to: combine local `scout` context with external `researcher` evidence when current docs, ecosystem behavior, or API details matter.
|
|
629
643
|
- `/parallel-context-build` maps to: run a chain-mode parallel group of `context-builder` agents with distinct temp output paths, then synthesize their context and meta-prompt sections.
|
|
630
644
|
- `/parallel-handoff-plan` maps to: run external `researcher` plus local/strategy `context-builder` passes, then a synthesis `context-builder` that writes an implementation handoff plan and implementation-ready meta-prompt.
|
|
@@ -633,26 +647,36 @@ When the user approves launching a subagent to carry out a plan or workflow, tre
|
|
|
633
647
|
For feature work, use this sequence as scaffolding for parent-agent behavior:
|
|
634
648
|
|
|
635
649
|
```text
|
|
636
|
-
clarify → planner → worker → parallel fresh-context reviewers → worker
|
|
650
|
+
clarify → validation contract → planner → async worker → parallel async fresh-context reviewers/validators → async fix worker → follow-up review when warranted → parent review
|
|
637
651
|
```
|
|
638
652
|
|
|
639
|
-
The
|
|
653
|
+
The validation contract defines what done means before code is written: expected behavior, acceptance checks, commands or user flows to exercise, and evidence the worker should return. Keep it lightweight for small tasks, but make it explicit enough that reviewers and validators are checking the intended outcome rather than the worker’s own assumptions.
|
|
654
|
+
|
|
655
|
+
The first `worker` implements the approved plan. The parent continues with independent inspection or validation prep while it runs, not parallel edits to the same worktree. When the async worker completes, treat its handoff as the transition into review, not as final completion, unless the user explicitly asked for worker-only work, review-only output, or to stop after implementation. Parallel reviewers inspect the resulting diff from fresh context. Validators check behavior with the best available evidence: commands, tests, browser/CLI interaction, screenshots, logs, or manual reproduction notes. The final `worker` applies synthesized review fixes in forked context, then the parent looks over the final diff before completing. The parent may launch these steps as an initial async chain when the workflow is already clear, or as follow-up subagent runs after each async completion. Initial chains should pass `async: true` so the main chat is unblocked; avoid `clarify: true` unless the user asked for foreground clarification. Do not stop after parallel review unless the user explicitly asked for review-only output or the review surfaced a decision that needs approval first.
|
|
656
|
+
|
|
657
|
+
For complex work, risky changes, broad refactors, or many changed lines, increase review and validation fanout rather than trusting one reviewer. Use distinct angles such as correctness/regressions, tests/validation, simplicity/maintainability, security/privacy, performance, docs/API contracts, and user-flow behavior. When reviewers find non-trivial issues or the fix worker touches many lines, run another focused review round before final validation.
|
|
658
|
+
|
|
659
|
+
For very large work, split into serial milestones instead of launching a swarm of writers. Each milestone gets one writer, a validation contract, fresh-context review/validation, a fix pass, and parent acceptance before the next milestone starts. Use parallel subagents inside a milestone for read-only context, research, review, and validation only.
|
|
640
660
|
|
|
641
661
|
Keep orchestration authority in the parent session. Child subagents should not launch more subagents, read this skill, or run their own orchestration loops. Spawned subagents do not receive the `pi-subagents` skill, parent-only status/control/slash messages, prior parent `subagent` tool-call/tool-result artifacts, or the `subagent` extension tool. Child context filtering also strips old hidden orchestration-instruction messages when they appear in inherited history. Every child also receives a boundary instruction that says the parent owns orchestration, the child must not propose or run subagents, and implementation children must call real edit/write tools instead of printing pseudo tool calls. Pass children concrete role-specific work instead.
|
|
642
662
|
|
|
643
663
|
1. Clarify first. This is mandatory. Gather code context with `scout` or `context-builder`, add `researcher` only when external evidence matters, then ask the user clarifying questions with `interview` until scope, acceptance criteria, constraints, and non-goals are clear.
|
|
644
|
-
2.
|
|
645
|
-
3.
|
|
646
|
-
4.
|
|
647
|
-
5.
|
|
648
|
-
6.
|
|
664
|
+
2. Define the validation contract. State what done means before implementation: expected behavior, checks to run, user flows to exercise, and evidence required in the worker handoff. For UI, CLI, integration, or workflow changes, include at least one validator angle that uses the product the way a user would rather than only reading code.
|
|
665
|
+
3. Plan when useful. For complex work, call `planner` or write a plan doc yourself and get approval before implementation. For simple work, confirm shared understanding and explicitly note why planning is skipped.
|
|
666
|
+
4. Implement with one writer. After approval, launch `worker` asynchronously with a proper meta prompt that includes clarified requirements, relevant context, plan path or summary, the validation contract, and output expectations. Packaged `worker` defaults to forked context; pass `context: "fresh"` only when you intentionally want a fresh child. While it runs, prepare validation or inspect adjacent code instead of editing the same worktree.
|
|
667
|
+
5. Require a useful worker handoff. Ask the worker to report changed files, what was implemented, what was left undone, commands run with exit codes, validation evidence, surprises or new risks, decisions made inside approved scope, and decisions needing parent approval.
|
|
668
|
+
6. Review after implementation. After the worker completes, launch parallel async fresh-context `reviewer` agents for correctness/regressions, tests/validation, and simplicity/maintainability. Add security, performance, docs/API, domain-specific, or user-flow validators for complex work, risky changes, broad refactors, or many changed lines. Use `output: false` unless review artifacts are explicitly needed.
|
|
669
|
+
7. Synthesize, then run the fix worker. Separate blockers, fixes worth doing now, optional improvements, and feedback to ignore/defer, then launch an async forked `worker` to apply fixes worth doing now when the workflow is implementation-authorized. If reviewers found scope/product/architecture choices that were not approved, ask the user first instead of applying them.
|
|
670
|
+
8. Review again when warranted. If the fix worker made substantial changes or addressed non-trivial findings, run another focused parallel review round before final validation.
|
|
671
|
+
9. Validate and complete. After the fix worker and any follow-up review return, inspect the final diff yourself, run or confirm focused validation, update docs/changelog when relevant, and summarize what changed and why.
|
|
649
672
|
|
|
650
673
|
Example implementation handoff after clarification and optional planning:
|
|
651
674
|
|
|
652
675
|
```typescript
|
|
653
676
|
subagent({
|
|
654
677
|
agent: "worker",
|
|
655
|
-
task: "Implement the approved feature.\n\nClarified requirements:\n- ...\n\nPlan: see ~/Documents/docs/...-plan.md\n\nValidation
|
|
678
|
+
task: "Implement the approved feature.\n\nClarified requirements:\n- ...\n\nPlan: see ~/Documents/docs/...-plan.md\n\nValidation contract:\n- ...\n\nReturn a handoff with changed files, what was implemented, what was left undone, commands run with exit codes, validation evidence, surprises/new risks, and decisions needing parent approval.",
|
|
679
|
+
async: true
|
|
656
680
|
})
|
|
657
681
|
```
|
|
658
682
|
|
|
@@ -661,12 +685,13 @@ Example review pass after implementation:
|
|
|
661
685
|
```typescript
|
|
662
686
|
subagent({
|
|
663
687
|
tasks: [
|
|
664
|
-
{ agent: "reviewer", task: "Review the current diff for correctness and regressions. Inspect changed files directly.", output: false },
|
|
665
|
-
{ agent: "reviewer", task: "Review the current diff for tests and validation quality. Inspect changed files directly.", output: false },
|
|
688
|
+
{ agent: "reviewer", task: "Review the current diff for correctness and regressions. Inspect changed files directly; do not rely on the worker's reasoning.", output: false },
|
|
689
|
+
{ agent: "reviewer", task: "Review the current diff for tests and validation quality against the validation contract. Inspect changed files directly.", output: false },
|
|
666
690
|
{ agent: "reviewer", task: "Review the current diff for simplicity and maintainability. Inspect changed files directly.", output: false }
|
|
667
691
|
],
|
|
668
692
|
concurrency: 3,
|
|
669
|
-
context: "fresh"
|
|
693
|
+
context: "fresh",
|
|
694
|
+
async: true
|
|
670
695
|
})
|
|
671
696
|
```
|
|
672
697
|
|
|
@@ -675,13 +700,18 @@ Example fix worker after parallel reviews:
|
|
|
675
700
|
```typescript
|
|
676
701
|
subagent({
|
|
677
702
|
agent: "worker",
|
|
678
|
-
task: "Apply the synthesized reviewer feedback below. Only apply fixes worth doing now; preserve user-approved scope; ask before unapproved product or architecture changes. Run focused validation and summarize what changed.\n\nReviewer synthesis:\n..."
|
|
703
|
+
task: "Apply the synthesized reviewer feedback below. Only apply fixes worth doing now; preserve user-approved scope; ask before unapproved product or architecture changes. Run focused validation and summarize what changed.\n\nReviewer synthesis:\n...",
|
|
704
|
+
async: true
|
|
679
705
|
})
|
|
680
706
|
```
|
|
681
707
|
|
|
682
708
|
### Review loop
|
|
683
709
|
|
|
684
|
-
Do not treat review as the final step for implementation work.
|
|
710
|
+
Do not treat review as the final step for implementation work. Run reviewers and validators, synthesize their findings against user scope and the validation contract, then launch one `worker` for accepted fixes when implementation is authorized.
|
|
711
|
+
|
|
712
|
+
When an async implementation worker completes, treat the worker handoff as an intermediate state. The next parent action is review fanout, then synthesis, then a fix worker if reviewers found fixes worth doing now. This can be planned as an initial async chain when the whole workflow is known, or continued as follow-up subagent runs when the parent only launched the first worker initially. Initial chains should pass `async: true` so the main chat is unblocked; `clarify: true` is the explicit foreground opt-in.
|
|
713
|
+
|
|
714
|
+
For explicit review-loop requests, repeat worker → fresh-reviewer → synthesized-fix-worker cycles until reviewers find no blockers or fixes worth doing now, remaining feedback is optional or intentionally deferred, an unapproved product/scope/architecture decision needs the user, or the max review-round cap is reached. Default to 3 review rounds unless the user sets a different cap. For complex work, many changed lines, or any fix pass that materially changes the diff, run another focused review round before the parent’s final look; otherwise stop instead of chasing optional polish.
|
|
685
715
|
|
|
686
716
|
### Parallel non-conflicting analysis
|
|
687
717
|
|
|
@@ -297,6 +297,10 @@ function applyAgentConfig(target: AgentConfig, cfg: Record<string, unknown>): st
|
|
|
297
297
|
target.maxSubagentDepth = cfg.maxSubagentDepth;
|
|
298
298
|
} else return "config.maxSubagentDepth must be an integer >= 0 or false when provided.";
|
|
299
299
|
}
|
|
300
|
+
if (hasKey(cfg, "completionGuard")) {
|
|
301
|
+
if (typeof cfg.completionGuard !== "boolean") return "config.completionGuard must be a boolean when provided.";
|
|
302
|
+
target.completionGuard = cfg.completionGuard;
|
|
303
|
+
}
|
|
300
304
|
return undefined;
|
|
301
305
|
}
|
|
302
306
|
|
|
@@ -366,6 +370,7 @@ function formatAgentDetail(agent: AgentConfig): string {
|
|
|
366
370
|
if (agent.defaultReads?.length) lines.push(`Reads: ${agent.defaultReads.join(", ")}`);
|
|
367
371
|
if (agent.defaultProgress) lines.push("Progress: true");
|
|
368
372
|
if (agent.maxSubagentDepth !== undefined) lines.push(`Max subagent depth: ${agent.maxSubagentDepth}`);
|
|
373
|
+
if (agent.completionGuard === false) lines.push("Completion guard: false");
|
|
369
374
|
if (agent.systemPrompt.trim()) lines.push("", "System Prompt:", agent.systemPrompt);
|
|
370
375
|
return lines.join("\n");
|
|
371
376
|
}
|
|
@@ -21,6 +21,7 @@ export const KNOWN_FIELDS = new Set([
|
|
|
21
21
|
"defaultProgress",
|
|
22
22
|
"interactive",
|
|
23
23
|
"maxSubagentDepth",
|
|
24
|
+
"completionGuard",
|
|
24
25
|
]);
|
|
25
26
|
|
|
26
27
|
function joinComma(values: string[] | undefined): string | undefined {
|
|
@@ -69,6 +70,7 @@ export function serializeAgent(config: AgentConfig): string {
|
|
|
69
70
|
if (Number.isInteger(config.maxSubagentDepth) && config.maxSubagentDepth >= 0) {
|
|
70
71
|
lines.push(`maxSubagentDepth: ${config.maxSubagentDepth}`);
|
|
71
72
|
}
|
|
73
|
+
if (config.completionGuard === false) lines.push("completionGuard: false");
|
|
72
74
|
|
|
73
75
|
if (config.extraFields) {
|
|
74
76
|
for (const [key, value] of Object.entries(config.extraFields)) {
|
package/src/agents/agents.ts
CHANGED
|
@@ -7,6 +7,7 @@ import * as os from "node:os";
|
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import type { OutputMode } from "../shared/types.ts";
|
|
10
|
+
import { getAgentDir } from "../shared/utils.ts";
|
|
10
11
|
import { KNOWN_FIELDS } from "./agent-serializer.ts";
|
|
11
12
|
import { parseChain } from "./chain-serializer.ts";
|
|
12
13
|
import { mergeAgentsForScope } from "./agent-selection.ts";
|
|
@@ -45,6 +46,7 @@ export interface BuiltinAgentOverrideBase {
|
|
|
45
46
|
skills?: string[];
|
|
46
47
|
tools?: string[];
|
|
47
48
|
mcpDirectTools?: string[];
|
|
49
|
+
completionGuard?: boolean;
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
interface BuiltinAgentOverrideConfig {
|
|
@@ -59,6 +61,7 @@ interface BuiltinAgentOverrideConfig {
|
|
|
59
61
|
systemPrompt?: string;
|
|
60
62
|
skills?: string[] | false;
|
|
61
63
|
tools?: string[] | false;
|
|
64
|
+
completionGuard?: boolean;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
interface BuiltinAgentOverrideInfo {
|
|
@@ -91,6 +94,7 @@ export interface AgentConfig {
|
|
|
91
94
|
defaultProgress?: boolean;
|
|
92
95
|
interactive?: boolean;
|
|
93
96
|
maxSubagentDepth?: number;
|
|
97
|
+
completionGuard?: boolean;
|
|
94
98
|
disabled?: boolean;
|
|
95
99
|
extraFields?: Record<string, string>;
|
|
96
100
|
override?: BuiltinAgentOverrideInfo;
|
|
@@ -131,7 +135,7 @@ interface AgentDiscoveryResult {
|
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
function getUserChainDir(): string {
|
|
134
|
-
return path.join(
|
|
138
|
+
return path.join(getAgentDir(), "chains");
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
function splitToolList(rawTools: string[] | undefined): { tools?: string[]; mcpDirectTools?: string[] } {
|
|
@@ -182,6 +186,7 @@ function cloneOverrideBase(agent: AgentConfig): BuiltinAgentOverrideBase {
|
|
|
182
186
|
skills: agent.skills ? [...agent.skills] : undefined,
|
|
183
187
|
tools: agent.tools ? [...agent.tools] : undefined,
|
|
184
188
|
mcpDirectTools: agent.mcpDirectTools ? [...agent.mcpDirectTools] : undefined,
|
|
189
|
+
completionGuard: agent.completionGuard,
|
|
185
190
|
};
|
|
186
191
|
}
|
|
187
192
|
|
|
@@ -200,6 +205,7 @@ function cloneOverrideValue(override: BuiltinAgentOverrideConfig): BuiltinAgentO
|
|
|
200
205
|
...(override.systemPrompt !== undefined ? { systemPrompt: override.systemPrompt } : {}),
|
|
201
206
|
...(override.skills !== undefined ? { skills: override.skills === false ? false : [...override.skills] } : {}),
|
|
202
207
|
...(override.tools !== undefined ? { tools: override.tools === false ? false : [...override.tools] } : {}),
|
|
208
|
+
...(override.completionGuard !== undefined ? { completionGuard: override.completionGuard } : {}),
|
|
203
209
|
};
|
|
204
210
|
}
|
|
205
211
|
|
|
@@ -217,7 +223,7 @@ function findNearestProjectRoot(cwd: string): string | null {
|
|
|
217
223
|
}
|
|
218
224
|
|
|
219
225
|
function getUserAgentSettingsPath(): string {
|
|
220
|
-
return path.join(
|
|
226
|
+
return path.join(getAgentDir(), "settings.json");
|
|
221
227
|
}
|
|
222
228
|
|
|
223
229
|
function getProjectAgentSettingsPath(cwd: string): string | null {
|
|
@@ -336,6 +342,14 @@ function parseBuiltinOverrideEntry(
|
|
|
336
342
|
}
|
|
337
343
|
}
|
|
338
344
|
|
|
345
|
+
if ("completionGuard" in input) {
|
|
346
|
+
if (typeof input.completionGuard === "boolean") {
|
|
347
|
+
override.completionGuard = input.completionGuard;
|
|
348
|
+
} else {
|
|
349
|
+
throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'completionGuard'; expected a boolean.`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
339
353
|
if ("systemPrompt" in input) {
|
|
340
354
|
if (typeof input.systemPrompt === "string") override.systemPrompt = input.systemPrompt;
|
|
341
355
|
else throw new Error(`Builtin override '${name}' in '${filePath}' has invalid 'systemPrompt'; expected a string.`);
|
|
@@ -408,6 +422,7 @@ function applyBuiltinOverride(
|
|
|
408
422
|
next.tools = tools;
|
|
409
423
|
next.mcpDirectTools = mcpDirectTools;
|
|
410
424
|
}
|
|
425
|
+
if (override.completionGuard !== undefined) next.completionGuard = override.completionGuard;
|
|
411
426
|
|
|
412
427
|
return next;
|
|
413
428
|
}
|
|
@@ -447,7 +462,7 @@ function applyBuiltinOverrides(
|
|
|
447
462
|
|
|
448
463
|
export function buildBuiltinOverrideConfig(
|
|
449
464
|
base: BuiltinAgentOverrideBase,
|
|
450
|
-
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools">,
|
|
465
|
+
draft: Pick<AgentConfig, "model" | "fallbackModels" | "thinking" | "systemPromptMode" | "inheritProjectContext" | "inheritSkills" | "defaultContext" | "disabled" | "systemPrompt" | "skills" | "tools" | "mcpDirectTools" | "completionGuard">,
|
|
451
466
|
): BuiltinAgentOverrideConfig | undefined {
|
|
452
467
|
const override: BuiltinAgentOverrideConfig = {};
|
|
453
468
|
|
|
@@ -465,6 +480,9 @@ export function buildBuiltinOverrideConfig(
|
|
|
465
480
|
const baseTools = joinToolList(base);
|
|
466
481
|
const draftTools = joinToolList(draft);
|
|
467
482
|
if (!arraysEqual(draftTools, baseTools)) override.tools = draftTools ? [...draftTools] : false;
|
|
483
|
+
if ((draft.completionGuard !== false) !== (base.completionGuard !== false)) {
|
|
484
|
+
override.completionGuard = draft.completionGuard !== false;
|
|
485
|
+
}
|
|
468
486
|
|
|
469
487
|
return Object.keys(override).length > 0 ? override : undefined;
|
|
470
488
|
}
|
|
@@ -630,6 +648,11 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
630
648
|
}
|
|
631
649
|
|
|
632
650
|
const parsedMaxSubagentDepth = Number(frontmatter.maxSubagentDepth);
|
|
651
|
+
const completionGuard = frontmatter.completionGuard === "false"
|
|
652
|
+
? false
|
|
653
|
+
: frontmatter.completionGuard === "true"
|
|
654
|
+
? true
|
|
655
|
+
: undefined;
|
|
633
656
|
|
|
634
657
|
agents.push({
|
|
635
658
|
name: runtimeName,
|
|
@@ -658,6 +681,7 @@ function loadAgentsFromDir(dir: string, source: AgentSource): AgentConfig[] {
|
|
|
658
681
|
Number.isInteger(parsedMaxSubagentDepth) && parsedMaxSubagentDepth >= 0
|
|
659
682
|
? parsedMaxSubagentDepth
|
|
660
683
|
: undefined,
|
|
684
|
+
completionGuard,
|
|
661
685
|
extraFields: Object.keys(extraFields).length > 0 ? extraFields : undefined,
|
|
662
686
|
});
|
|
663
687
|
}
|
|
@@ -723,7 +747,7 @@ function resolveNearestProjectChainDirs(cwd: string): { readDirs: string[]; pref
|
|
|
723
747
|
const BUILTIN_AGENTS_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..", "agents");
|
|
724
748
|
|
|
725
749
|
export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
|
|
726
|
-
const userDirOld = path.join(
|
|
750
|
+
const userDirOld = path.join(getAgentDir(), "agents");
|
|
727
751
|
const userDirNew = path.join(os.homedir(), ".agents");
|
|
728
752
|
const { readDirs: projectAgentDirs, preferredDir: projectAgentsDir } = resolveNearestProjectAgentDirs(cwd);
|
|
729
753
|
const userSettingsPath = getUserAgentSettingsPath();
|
|
@@ -762,7 +786,7 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
762
786
|
userSettingsPath: string;
|
|
763
787
|
projectSettingsPath: string | null;
|
|
764
788
|
} {
|
|
765
|
-
const userDirOld = path.join(
|
|
789
|
+
const userDirOld = path.join(getAgentDir(), "agents");
|
|
766
790
|
const userDirNew = path.join(os.homedir(), ".agents");
|
|
767
791
|
const userChainDir = getUserChainDir();
|
|
768
792
|
const { readDirs: projectDirs, preferredDir: projectDir } = resolveNearestProjectAgentDirs(cwd);
|
|
@@ -802,7 +826,7 @@ export function discoverAgentsAll(cwd: string): {
|
|
|
802
826
|
...Array.from(chainMap.values()),
|
|
803
827
|
];
|
|
804
828
|
|
|
805
|
-
const userDir = fs.existsSync(userDirNew) ? userDirNew : userDirOld;
|
|
829
|
+
const userDir = process.env.PI_CODING_AGENT_DIR ? userDirOld : fs.existsSync(userDirNew) ? userDirNew : userDirOld;
|
|
806
830
|
|
|
807
831
|
return { builtin, user, project, chains, userDir, projectDir, userChainDir, projectChainDir, userSettingsPath, projectSettingsPath };
|
|
808
832
|
}
|