pi-subagents 0.56.0 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/agents/claude-code-writer.md +15 -0
  3. package/agents/claude-code.md +15 -0
  4. package/agents/codex-exec-writer.md +15 -0
  5. package/agents/codex-exec.md +15 -0
  6. package/agents/cursor-agent-writer.md +14 -0
  7. package/agents/cursor-agent.md +14 -0
  8. package/docs/agents.md +124 -21
  9. package/docs/configuration.md +37 -0
  10. package/docs/extension-api.md +41 -2
  11. package/docs/models.md +3 -3
  12. package/docs/observability.md +8 -7
  13. package/docs/tool-reference.md +14 -3
  14. package/docs/workflows.md +44 -0
  15. package/package.json +1 -1
  16. package/skills/pi-subagents/SKILL.md +2 -0
  17. package/skills/pi-subagents/references/execution-controls.md +2 -2
  18. package/skills/pi-subagents/references/management-authoring-rpc.md +1 -0
  19. package/skills/pi-subagents/references/prompting-and-roles.md +2 -2
  20. package/src/agents/agent-management.ts +36 -5
  21. package/src/agents/agent-refinements.ts +4 -4
  22. package/src/agents/agent-serializer.ts +5 -0
  23. package/src/agents/agents.ts +257 -51
  24. package/src/agents/builtin-names.ts +6 -0
  25. package/src/agents/runtime-agent-events.ts +70 -0
  26. package/src/agents/runtime-agent-registry.ts +18 -4
  27. package/src/api/agents.ts +10 -5
  28. package/src/api/preflight.ts +28 -3
  29. package/src/extension/config.ts +70 -0
  30. package/src/extension/doctor.ts +3 -3
  31. package/src/extension/index.ts +33 -8
  32. package/src/extension/public-execution.ts +29 -13
  33. package/src/extension/rpc.ts +55 -19
  34. package/src/extension/schemas.ts +6 -5
  35. package/src/extension/tool-description.ts +18 -12
  36. package/src/inspectors/herdr/actions.ts +2 -1
  37. package/src/inspectors/herdr/inspector-runner.ts +2 -10
  38. package/src/inspectors/herdr/session-roots-codec.ts +42 -0
  39. package/src/integrations/herdr-status.ts +51 -3
  40. package/src/runs/background/active-async-capacity.ts +77 -10
  41. package/src/runs/background/async-execution.ts +127 -19
  42. package/src/runs/background/async-job-tracker.ts +5 -0
  43. package/src/runs/background/async-resume.ts +6 -2
  44. package/src/runs/background/async-retention.ts +20 -3
  45. package/src/runs/background/async-status.ts +7 -0
  46. package/src/runs/background/chain-append.ts +2 -0
  47. package/src/runs/background/chain-root-attachment.ts +15 -1
  48. package/src/runs/background/fleet-view.ts +16 -10
  49. package/src/runs/background/inspect-rpc.ts +8 -8
  50. package/src/runs/background/notify.ts +26 -3
  51. package/src/runs/background/result-delivery-ownership.ts +45 -0
  52. package/src/runs/background/result-files.ts +27 -14
  53. package/src/runs/background/result-watcher.ts +36 -15
  54. package/src/runs/background/run-status.ts +33 -6
  55. package/src/runs/background/scheduled-runs.ts +7 -1
  56. package/src/runs/background/subagent-runner.ts +239 -56
  57. package/src/runs/background/wait-completions.ts +4 -0
  58. package/src/runs/foreground/execution.ts +92 -11
  59. package/src/runs/foreground/foreground-control.ts +6 -0
  60. package/src/runs/foreground/foreground-history.ts +22 -1
  61. package/src/runs/foreground/subagent-executor.ts +322 -102
  62. package/src/runs/foreground/workflow-detach-reconcile.ts +144 -18
  63. package/src/runs/shared/child-protocol.ts +21 -7
  64. package/src/runs/shared/claude-code-adapter.ts +129 -0
  65. package/src/runs/shared/codex-exec-adapter.ts +129 -0
  66. package/src/runs/shared/completion-guard.ts +4 -3
  67. package/src/runs/shared/cursor-agent-adapter.ts +114 -0
  68. package/src/runs/shared/dynamic-fanout.ts +3 -3
  69. package/src/runs/shared/external-cli-contract.ts +167 -0
  70. package/src/runs/shared/external-cli-preflight.ts +122 -0
  71. package/src/runs/shared/external-cli-runner.ts +348 -55
  72. package/src/runs/shared/fast-mode-extension.ts +5 -5
  73. package/src/runs/shared/launch-cwd.ts +16 -0
  74. package/src/runs/shared/long-running-guard.ts +2 -1
  75. package/src/runs/shared/mcp-config-sources.ts +386 -0
  76. package/src/runs/shared/mcp-direct-tool-allowlist.ts +155 -42
  77. package/src/runs/shared/model-exclusions.ts +69 -7
  78. package/src/runs/shared/model-fallback.ts +39 -5
  79. package/src/runs/shared/mutation-evidence.ts +7 -2
  80. package/src/runs/shared/nested-events.ts +3 -1
  81. package/src/runs/shared/nested-render.ts +2 -2
  82. package/src/runs/shared/parallel-utils.ts +8 -1
  83. package/src/runs/shared/pi-args.ts +61 -6
  84. package/src/runs/shared/process-signal.ts +13 -0
  85. package/src/runs/shared/run-history.ts +21 -1
  86. package/src/runs/shared/single-output.ts +17 -0
  87. package/src/runs/shared/subagent-prompt-runtime.ts +85 -9
  88. package/src/shared/fork-context.ts +21 -0
  89. package/src/shared/formatters.ts +13 -1
  90. package/src/shared/launch-contract.ts +4 -0
  91. package/src/shared/pruned-fork.ts +450 -0
  92. package/src/shared/session-file-trust.ts +19 -0
  93. package/src/shared/session-tokens.ts +14 -3
  94. package/src/shared/settings.ts +10 -2
  95. package/src/shared/shortcuts.ts +17 -0
  96. package/src/shared/types.ts +160 -10
  97. package/src/shared/utils.ts +6 -29
  98. package/src/shared/workflow-child-permit.ts +116 -0
  99. package/src/slash/delegation-adapters.ts +0 -1
  100. package/src/slash/slash-commands.ts +8 -6
  101. package/src/slash/subagents-admin.ts +3 -0
  102. package/src/tui/fleet-status.ts +27 -10
  103. package/src/tui/fleet-transcript.ts +11 -5
  104. package/src/tui/fleet.ts +28 -13
  105. package/src/tui/render.ts +55 -21
  106. package/src/workflows/scripted-workflow.ts +299 -31
  107. package/src/workflows/workflow-child-summary.ts +117 -0
  108. package/src/workflows/workflow-receipt.ts +155 -5
package/CHANGELOG.md CHANGED
@@ -2,6 +2,98 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.58.0] - 2026-08-27
6
+
7
+ ### Highlights
8
+ - Launch MCP tools from more places, including runtime-registered servers, Pi package manifests, and Agent Plugin configs.
9
+ - Keep agent context smaller by default, with an explicit `inheritGlobalContext` opt-in when a child needs the operator's global context.
10
+ - Make detached and recovered workflow results more reliable, with clearer terminal handoffs and recovery actions.
11
+ - Show better launch and status diagnostics for workspace, authority, context-window, and missing-directory problems.
12
+ - Keep fast OpenAI-Codex launches compatible with priority service tier without losing provider request fields.
13
+
14
+ ### Added
15
+ - Support direct MCP tool launches from runtime-registered servers.
16
+ - Add `inheritGlobalContext` agent configuration so children can opt into the operator's global context file separately from repository context. Thanks to [@hknatm](https://github.com/hknatm) for #1560.
17
+ - Add process-local event registration so independent Pi extensions can register runtime agents through the installed owner. Thanks to [@fmoda3](https://github.com/fmoda3) for #1533.
18
+ - Add advisory launch preflight diagnostics for likely workspace scope and authority mismatches.
19
+ - Document per-run thinking suffixes in model-facing subagent guidance. Thanks to [@yanqianglu](https://github.com/yanqianglu) for #1565.
20
+ - Document unsupported native child options for external CLI agents in the subagent tool help, packaged guide, and packaged skill.
21
+
22
+ ### Changed
23
+ - Agents now omit the operator's global context file by default, including existing agents with `inheritProjectContext: true`; set `inheritGlobalContext: true` to preserve the previous behavior. Thanks to [@hknatm](https://github.com/hknatm) for #1560.
24
+
25
+ ### Fixed
26
+ - Fail explicitly requested models closed when a cached model exclusion is active, instead of silently selecting a fallback. Thanks to [@harpsychord](https://github.com/harpsychord) for #1556.
27
+ - Preserve fast-mode provider request root fields when adding OpenAI's priority service tier. Thanks to [@nothingrotf](https://github.com/nothingrotf) for #1570.
28
+ - Classify workflow budget and timeout stops as partial terminal outcomes while preserving settled child evidence. Thanks to [@yceachan](https://github.com/yceachan) for #1530.
29
+ - Publish a deterministic terminal handoff with settled child evidence and keyed recovery actions when detached workflow lanes settle. Thanks to [@yceachan](https://github.com/yceachan) for #1530.
30
+ - Resolve direct MCP tool selections from Pi package manifests and Agent Plugin configs. Thanks to [@fmoda3](https://github.com/fmoda3) for #1541.
31
+ - Fail closed with a launch diagnostic when configured runtime-style MCP direct-tool selectors cannot be resolved.
32
+ - Sync Herdr status after restoring active async jobs, so recovered work appears without waiting for another lifecycle event. Thanks to [@vicocamacho](https://github.com/vicocamacho) for #1553.
33
+ - Show task intent and context-window use in compact in-progress async status rows.
34
+ - Report deterministic settlement diagnostics when background children fail before required output handoff.
35
+ - Auto-resume workflow children once after setup-phase aborts that produce zero usage, preserving the retained transcript instead of rerunning the whole task.
36
+ - Finalize detached foreground worktree handoffs after terminal child completion, preserving captured changes before cleanup. Thanks to [@jpriverar](https://github.com/jpriverar) for #1562.
37
+ - Fail native child launches before spawn when the requested local working directory is missing or not a directory, with the requested and resolved paths in the error.
38
+ - Map report paths requested in workflow child tasks to the actual saved child output when workflow output routing overrides them.
39
+ - Stop same-session workflows recovered after extension reload through the durable control channel.
40
+ - Let agents declare extension mutation tools so real non-Git or untracked edits satisfy the implementation completion guard. Thanks to [@AlphaGodzilla](https://github.com/AlphaGodzilla) for #1532.
41
+ - Deliver async results from an explicitly replaced predecessor session without accepting unrelated session results. Thanks to [@DresvyanskiyDenis](https://github.com/DresvyanskiyDenis) for #1531.
42
+ - Avoid attributing assistant-issued workflow stops to the user.
43
+
44
+ ## [0.57.0] - 2026-08-26
45
+
46
+ ### Highlights
47
+ - Run Codex, Claude Code, and Cursor Agent subagents with packaged read-only and writing profiles.
48
+ - Validate workflow scripts before launch, and reuse workflow code from files with `workflowScriptPath`.
49
+ - Resume, inspect, and recover workflow children more reliably after errors, compaction, or session reloads.
50
+ - See clearer Fleet and status output, including task labels and live context-window usage.
51
+ - Recover from more async, scheduling, discovery, model fallback, and Windows edge cases without losing useful run history.
52
+
53
+ ### Added
54
+ - Add read-only and workspace-writing profiles for `codex-exec`, `claude-code`, and `cursor-agent`, with bounded result capture and opt-in smoke checks.
55
+ - Add external one-shot runner support for bounded parser hooks and logs, environment allowlists, cached launch preflight, parser progress, and process cleanup.
56
+ - Add compact external CLI capability and receipt metadata for adapter identity, artifacts, handoff mode, supervisor support, and resumability.
57
+ - Add configured pruned fork sessions with budgeted transcript-overflow summaries, stable recovery refs, and private recovery sidecars.
58
+ - Add offline `workflowScript` syntax and structural validation through the public subagent tool. Thanks to [@elecnix](https://github.com/elecnix) for #1462.
59
+ - Add `workflowScriptPath` so workflows can be loaded from files for execution, validation, and schedules. Thanks to [@elecnix](https://github.com/elecnix) for #1464.
60
+ - Add bounded workflow-child summaries to workflow results, status, receipts, and completion replay. Thanks to [@rochecompaan](https://github.com/rochecompaan) for #1453.
61
+ - Add live context-window usage to status and Fleet views, separate from cumulative token spend. Thanks to [@nazzeDe](https://github.com/nazzeDe) for #1444.
62
+ - Add active workflow task labels to compact status surfaces and Herdr pane metadata. Thanks to [@phoenixdam](https://github.com/phoenixdam) for #1459.
63
+ - Add `modelExclusions.defaultTtlMs` for controlling how long model exclusions stay active, with launch diagnostics for skipped candidates. Thanks to [@mithyer](https://github.com/mithyer) for #1439 and #1438.
64
+ - Add a package-internal one-use permit for one exact native child in a foreground `workflowScript`. Thanks to [@maroffo](https://github.com/maroffo) for #1494.
65
+
66
+ ### Fixed
67
+ - Preserve agent frontmatter output defaults for prompt-template delegated leaves. Thanks to [@ashlineldridge](https://github.com/ashlineldridge) for #1521.
68
+ - Preserve structured-output and related bounded child contract fields when foreground workflow children resume. Thanks to [@Livan-pro](https://github.com/Livan-pro) for #1460.
69
+ - Preserve typed errors, partial output, transcript metadata, and artifact metadata when foreground workflow children resume. See #1513.
70
+ - Keep inline workflow children resumable from their foreground runs without mistaking a missing async directory for lost state. Thanks to [@lancegui](https://github.com/lancegui) for #1442.
71
+ - Make workflow validation and return serialization failures easier to recover from with no-child-launch diagnostics, portable rewrite guidance, workflow ids, and completed-child output references (#1432, #1434).
72
+ - Clarify terminal keyed workflow-resume failures when `workflow-receipt.json` is unavailable, including direct child-run recovery from status and event logs (#1512).
73
+ - Preserve bounded async child failure context after compaction, including missing file-only output, instead of leaving failed run summaries empty. See #1495.
74
+ - Ignore stale child-settled events from retrying compaction attempts, so resumed children are not aborted before their replacement attempt can finish. See #1504.
75
+ - Make async runs visible to exact status lookup as soon as launch succeeds, and deliver one completion when a runner dies before its normal status write. Thanks to [@rafafortes](https://github.com/rafafortes) for #1471 and [@VincentHanxiaoDu](https://github.com/VincentHanxiaoDu) for #1480.
76
+ - Record explicit completed, failed, timed-out, stopped, and interrupted outcomes in run history. Thanks to [@rafafortes](https://github.com/rafafortes) for #1474.
77
+ - Repair bounded dead async run candidates before retention classifies them, so stale run directories can be reclaimed without deleting ambiguous worktrees or branches. Thanks to [@rafafortes](https://github.com/rafafortes) for #1477.
78
+ - Exclude completed one-shot schedules from the pending schedule limit without deleting their durable history. Thanks to [@rafafortes](https://github.com/rafafortes) for #1478.
79
+ - Reclaim failed async capacity slots after a configurable abandoned timeout when the runner PID is gone, while keeping clear diagnostics for unknown process state. Thanks to [@rafafortes](https://github.com/rafafortes) for #1472.
80
+ - Preserve parent model inheritance for workflow children when workflow setup reads session data before launch, and avoid carrying a stale live-session model into scheduled owners. Thanks to [@alexei-led](https://github.com/alexei-led) for #1489 and #1490.
81
+ - Retry fallback models for transient provider connection failures. Thanks to [@genkikadomatsu](https://github.com/genkikadomatsu) for #1508.
82
+ - Resolve the `advisor` builtin alias through the bundled `oracle` definition in model listings. Thanks to [@smileBeda](https://github.com/smileBeda) for #1502.
83
+ - Follow symlinked directories during agent discovery without revisiting recursive links. Thanks to [@robsdudeson](https://github.com/robsdudeson) for #1505 and #1510.
84
+ - Explain unknown-agent failures with the effective cwd and discovery inputs. Thanks to [@genkikadomatsu](https://github.com/genkikadomatsu) for #1511.
85
+ - Resolve package subagents from bare HTTP(S) Git URLs stored in Pi settings. Thanks to [@trancikk](https://github.com/trancikk) for #1452.
86
+ - Preview runtime-recorded workflow child sessions in Fleet and inspect without trusting sibling transcripts. Thanks to [@JHa13y](https://github.com/JHa13y) for #1441.
87
+ - Distinguish same-agent parallel children in Fleet with their explicit task labels. Thanks to [@ljie-PI](https://github.com/ljie-PI) for #1487.
88
+ - Preserve the local user identity and temporary-directory environment needed by authenticated Claude Code adapter runs.
89
+ - Report child processes that exit during tool execution as mid-tool failures instead of cold starts, even when earlier assistant text exists. Thanks to [@cyzlmh](https://github.com/cyzlmh) for #1437.
90
+ - Keep unaddressable legacy result aliases and overlong public result filenames from blocking canonical hashed or pending fallbacks. Thanks to [@LeonardBode](https://github.com/LeonardBode) for #1440.
91
+ - Bypass repository fsmonitor hooks when collecting mutation evidence. Thanks to [@jpriverar](https://github.com/jpriverar) for #1497.
92
+ - Avoid the fatal Node `ReadFileUtf8` retention path. Thanks to [@pgoodjohn](https://github.com/pgoodjohn) for #1501.
93
+ - Base64-encode Herdr inspector session roots so `inspector.open` handles Windows PowerShell argument parsing correctly. Thanks to [@stavg91](https://github.com/stavg91) for #1499.
94
+ - Keep async runner terminal event delivery from crashing the session when the captured extension context is stale after a session replacement or reload. Thanks to [@AdrianAcala](https://github.com/AdrianAcala) for #1485.
95
+ - Reject non-string workflow-child summary identifiers when reading receipt metadata.
96
+
5
97
  ## [0.56.0] - 2026-08-23
6
98
 
7
99
  ### Highlights
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: claude-code-writer
3
+ description: Explicit file-writing Claude Code CLI mode; requires local authentication and trusted user settings/hooks
4
+ runner:
5
+ type: external-cli
6
+ adapter: claude-code-writer
7
+ command: claude
8
+ promptDelivery: stdin
9
+ async: true
10
+ systemPromptMode: replace
11
+ inheritProjectContext: true
12
+ inheritSkills: false
13
+ ---
14
+
15
+ Prerequisites: the local Claude Code CLI is authenticated, and the operator trusts its user-level settings and hooks. Use only the code-owned Read, Write, Edit, Glob, and Grep tools. Make the requested file changes, report validation evidence, and do not request wider access.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: claude-code
3
+ description: Read-only Claude Code CLI analysis; requires local authentication and trusted user settings/hooks
4
+ runner:
5
+ type: external-cli
6
+ adapter: claude-code
7
+ command: claude
8
+ promptDelivery: stdin
9
+ async: true
10
+ systemPromptMode: replace
11
+ inheritProjectContext: true
12
+ inheritSkills: false
13
+ ---
14
+
15
+ Prerequisites: the local Claude Code CLI is authenticated, and the operator trusts its user-level settings and hooks. Analyze only the supplied handoff in no-tools mode. Return a concise final answer with evidence. Do not edit files or request wider access.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: codex-exec-writer
3
+ description: Explicit workspace-writing one-shot execution through the installed Codex CLI
4
+ runner:
5
+ type: external-cli
6
+ adapter: codex-exec-writer
7
+ command: codex
8
+ promptDelivery: stdin
9
+ async: true
10
+ systemPromptMode: replace
11
+ inheritProjectContext: true
12
+ inheritSkills: false
13
+ ---
14
+
15
+ Use the code-owned workspace-write sandbox to make the requested changes. Return a concise final answer with validation evidence. Do not request wider access or additional writable roots.
@@ -0,0 +1,15 @@
1
+ ---
2
+ name: codex-exec
3
+ description: Read-only one-shot analysis through the installed Codex CLI
4
+ runner:
5
+ type: external-cli
6
+ adapter: codex-exec
7
+ command: codex
8
+ promptDelivery: stdin
9
+ async: true
10
+ systemPromptMode: replace
11
+ inheritProjectContext: true
12
+ inheritSkills: false
13
+ ---
14
+
15
+ Analyze the task in read-only mode. Return a concise final answer with evidence. Do not edit files or request wider access.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: cursor-agent-writer
3
+ description: Explicit workspace-writing one-shot execution through the installed Cursor CLI
4
+ runner:
5
+ type: external-cli
6
+ adapter: cursor-agent-writer
7
+ command: cursor-agent
8
+ async: true
9
+ systemPromptMode: replace
10
+ inheritProjectContext: true
11
+ inheritSkills: false
12
+ ---
13
+
14
+ Use the code-owned sandbox to make the requested workspace changes. Return a concise final answer with validation evidence. Do not request wider access or additional workspace roots.
@@ -0,0 +1,14 @@
1
+ ---
2
+ name: cursor-agent
3
+ description: Read-only one-shot analysis through the installed Cursor CLI
4
+ runner:
5
+ type: external-cli
6
+ adapter: cursor-agent
7
+ command: cursor-agent
8
+ async: true
9
+ systemPromptMode: replace
10
+ inheritProjectContext: true
11
+ inheritSkills: false
12
+ ---
13
+
14
+ Analyze the task in read-only ask mode. Return a concise final answer with evidence. Do not edit files or request wider access.
package/docs/agents.md CHANGED
@@ -55,26 +55,124 @@ If you disabled the old bundled `gpt-pro` workaround with `agentOverrides.gpt-pr
55
55
 
56
56
  The Pi async run remains the source of truth for status, artifacts, wake/wait, mission attachment, retention, and diagnostics.
57
57
 
58
- Claude Code can be configured as a read-only advisor with `runner.type: external-cli` when the Claude Code CLI is installed and you have verified the flags for your local version. pi-subagents does not ship or enforce Claude Code flags. Use a project or user agent like this only after checking your CLI help:
58
+ ### Advisory runner data boundary
59
59
 
60
- ```yaml
61
- ---
62
- name: claude-advisor
63
- description: Read-only Claude Code advisor through the local CLI
64
- runner:
65
- type: external-cli
66
- command: claude
67
- args: ["<verified-read-only-flags>"]
68
- promptDelivery: stdin
69
- async: true
70
- ---
60
+ External CLI agents use their own runner contract. Do not pass native Pi child options such as model override, structured output, acceptance/agent contract, tool budgets, fast mode, fork context, skills, or native Pi tools unless the adapter explicitly implements them.
61
+
62
+ The built-in `codex-exec` and `codex-exec-writer` profiles are the supported Codex one-shot modes. Both require an installed and authenticated Codex CLI. The adapters own `codex exec --json` argv with ignored user config and rules, ephemeral sessions, approval policy `never`, and a final-message artifact.
71
63
 
72
- Review the task and return advice only. Do not edit files.
64
+ | Profile | Access | Sandbox |
65
+ |---|---|---|
66
+ | `codex-exec` | Read-only analysis | `read-only` |
67
+ | `codex-exec-writer` | Explicit workspace edits | `workspace-write` |
68
+
69
+ Neither adapter uses full access, approval or sandbox bypasses, automatic approval review, or additional writable roots. User profiles cannot add argv. The `codex-exec` selection identity is reserved for the read-only adapter.
70
+
71
+ Run it asynchronously:
72
+
73
+ ```text
74
+ Use codex-exec to analyze this change without editing files.
75
+
76
+ Use codex-exec-writer to make the requested workspace changes.
73
77
  ```
74
78
 
75
- ### Advisory runner data boundary
79
+ The adapter validates `codex --version` and `codex exec --help` only when a run launches. Discovery, list, status, and native Pi launches do not probe Codex. JSONL, stderr, and stdout are untrusted. A run succeeds only after bounded valid JSONL contains one `turn.completed` event and the bounded final-message artifact is present.
80
+
81
+ Maintainers can collect real smoke evidence without making it part of the normal test suite:
82
+
83
+ ```bash
84
+ PI_SUBAGENTS_CODEX_EXEC_SMOKE=1 \
85
+ PI_SUBAGENTS_CODEX_EXEC_SMOKE_REPORT=/tmp/pi-subagents-codex-exec-smoke.json \
86
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
87
+ --test test/integration/codex-exec-smoke.test.ts
88
+
89
+ PI_SUBAGENTS_CODEX_EXEC_WRITER_SMOKE=1 \
90
+ PI_SUBAGENTS_CODEX_EXEC_WRITER_SMOKE_REPORT=/tmp/pi-subagents-codex-exec-writer-smoke.json \
91
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
92
+ --test test/integration/codex-exec-writer-smoke.test.ts
93
+ ```
94
+
95
+ The read-only smoke must report `writeCanaryExists: false`. The writer smoke must report `writeCanaryMatches: true`. Both reports include startup duration and terminal proof without raw protocol output, prompts, or credentials.
96
+
97
+ The built-in `claude-code` and `claude-code-writer` profiles are the supported Claude Code one-shot modes. Both require an installed Claude Code CLI that is already authenticated through its normal local login. Claude Code 2.1.150 needs the user setting source for normal OAuth/keychain authentication, so both adapters load user settings but exclude project and local settings. User-level Claude Code settings and hooks are therefore an operator-trusted prerequisite. Review or disable unsafe user hooks before using either profile.
98
+
99
+ | Profile | Access | Permission mode | Built-in tools |
100
+ |---|---|---|---|
101
+ | `claude-code` | Handoff-only read-only advice | `plan` | none |
102
+ | `claude-code-writer` | Explicit workspace file edits | `acceptEdits` | `Read,Write,Edit,Glob,Grep` |
103
+
104
+ Both adapters own `claude -p` argv with stream JSON, strict empty MCP configuration, user-only setting sources, no session persistence, disabled slash commands, and disabled Chrome integration. The writer mode does not include Bash or any permission bypass. Neither mode uses `--bare`, which does not read normal OAuth/keychain authentication. Neither mode requires `--safe-mode`, which is absent from the installed 2.1.150 help. User profiles cannot add argv. Selecting the code-owned `claude-code-writer` adapter identity is the only way to opt into its write tools; the read-only adapter cannot be widened with user argv.
105
+
106
+ Run it asynchronously:
107
+
108
+ ```text
109
+ Use claude-code to analyze this handoff without editing files.
110
+
111
+ Use claude-code-writer to make the requested file changes.
112
+ ```
113
+
114
+ The adapter validates `claude --version` and `claude --help` only when a run launches. Discovery, list, status, and native Pi launches do not probe Claude Code or authentication. JSONL, stderr, and stdout are untrusted. A run succeeds only after bounded valid JSONL contains exactly one successful terminal `result` with non-empty final text. Missing or revoked local authentication, limit stops, malformed JSON, duplicate terminal results, and EOF before a terminal result fail closed.
115
+
116
+ Maintainers can opt in to separate read-only and writer canaries:
117
+
118
+ ```bash
119
+ PI_SUBAGENTS_CLAUDE_CODE_SMOKE=1 \
120
+ PI_SUBAGENTS_CLAUDE_CODE_SMOKE_REPORT=/tmp/pi-subagents-claude-code-smoke.json \
121
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
122
+ --test test/integration/claude-code-smoke.test.ts
123
+
124
+ PI_SUBAGENTS_CLAUDE_CODE_WRITER_SMOKE=1 \
125
+ PI_SUBAGENTS_CLAUDE_CODE_WRITER_SMOKE_REPORT=/tmp/pi-subagents-claude-code-writer-smoke.json \
126
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
127
+ --test test/integration/claude-code-writer-smoke.test.ts
128
+ ```
129
+
130
+ Both smoke reports record `authentication: "existing-cli-required"`, `settingSources: "user"`, and `userSettingsTrust: "required"` without recording credential details. For read-only, confirm `terminalState` is `completed` and `writeCanaryExists` is `false`. For writer, confirm `terminalState` is `completed` and `writeCanaryMatches` is `true`. `durationMs` records cold process time. If authentication is missing or revoked, repair the normal local Claude Code login and rerun the smoke. Reports do not contain raw protocol output or credentials.
131
+
132
+ The built-in `cursor-agent` and `cursor-agent-writer` profiles are the supported Cursor CLI one-shot modes. Both require an installed Cursor CLI and either `CURSOR_API_KEY` or an existing local login.
133
+
134
+ | Profile | Access | Cursor mode |
135
+ |---|---|---|
136
+ | `cursor-agent` | Read-only analysis | `ask` |
137
+ | `cursor-agent-writer` | Explicit workspace edits | non-interactive print |
138
+
139
+ Both adapters use stream JSON, the enabled sandbox, and the primary workspace. They write the full handoff to a private `0600` file in a private temporary directory. Process argv contains only a short instruction with that path. The temporary directory is added as a workspace root only when it is outside the primary workspace. The prompt file and directory are removed after completion, failure, or stop.
140
+
141
+ The adapters do not pass force, yolo, auto-review, MCP approval, plugin, session resume, continue, worktree, or workspace trust flags. User profiles cannot add argv or workspace roots. The `cursor-agent` selection identity is reserved for the read-only adapter.
142
+
143
+ Launch preflight validates `cursor-agent --version` and `cursor-agent --help` only when a run starts. Discovery, list, status, and native Pi launches do not execute Cursor or probe authentication. A run succeeds only when bounded valid JSONL ends with one successful `result` event that has non-empty final text. Error events, failed results, malformed JSON, output after the terminal event, and EOF before a result fail closed.
144
+
145
+ These headless smokes rely on saved workspace trust. Cursor documents no passive command that checks workspace trust, so the smoke cannot verify it before launch. The operator must use Cursor's interactive trust flow for the exact disposable workspace and the exact derived prompt directory, `<state-root>/external-0.cursor-prompt`. Keep that prompt directory after the trust step. It must be empty, owned by the operator who runs the smoke, and must not be a symlink. The harness preserves this directory but creates its private handoff with exclusive `0600` access and removes the handoff after every run. Repeat the trust setup if either exact path changes.
146
+
147
+ The smoke requires two existing, separate operator-managed directories and an explicit disposable-workspace attestation:
148
+
149
+ ```bash
150
+ export PI_SUBAGENTS_CURSOR_SMOKE_WORKSPACE=/tmp/pi-subagents-cursor-smoke-workspace
151
+ export PI_SUBAGENTS_CURSOR_SMOKE_STATE_ROOT=/tmp/pi-subagents-cursor-smoke-state
152
+ export PI_SUBAGENTS_CURSOR_SMOKE_DISPOSABLE=1
153
+ mkdir -p "$PI_SUBAGENTS_CURSOR_SMOKE_WORKSPACE" "$PI_SUBAGENTS_CURSOR_SMOKE_STATE_ROOT"
154
+ mkdir -p "$PI_SUBAGENTS_CURSOR_SMOKE_STATE_ROOT/external-0.cursor-prompt"
155
+ ```
156
+
157
+ Do not place a file at `pi-subagents-cursor-write-canary.txt` in the workspace or any file, including `handoff.txt`, in the prompt directory. The harness refuses the pre-existing canary and any non-empty prompt directory. It does not delete the workspace, state root, or operator-owned prompt directory. It removes only its canary and private handoff file.
158
+
159
+ Maintainers can then run separate read-only and writer canaries:
160
+
161
+ ```bash
162
+ PI_SUBAGENTS_CURSOR_AGENT_SMOKE=1 \
163
+ PI_SUBAGENTS_CURSOR_AGENT_SMOKE_REPORT=/tmp/pi-subagents-cursor-agent-smoke.json \
164
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
165
+ --test test/integration/cursor-agent-smoke.test.ts
166
+
167
+ PI_SUBAGENTS_CURSOR_AGENT_WRITER_SMOKE=1 \
168
+ PI_SUBAGENTS_CURSOR_AGENT_WRITER_SMOKE_REPORT=/tmp/pi-subagents-cursor-agent-writer-smoke.json \
169
+ node --experimental-strip-types --import ./test/support/register-loader.mjs \
170
+ --test test/integration/cursor-agent-writer-smoke.test.ts
171
+ ```
172
+
173
+ The read-only smoke must report `writeCanaryExists: false`. The writer smoke must report `writeCanaryMatches: true`. Both reports record `workspaceTrust: "operator-managed-saved"`, confirm that the external prompt root was added, and include startup duration and terminal proof without raw protocol output, prompts, or credentials. A trust-required error remains terminal; the harness does not retry with a trust, force, or yolo flag.
76
174
 
77
- Native `oracle` runs inside Pi and can use its configured read tools. `claude-advisor` sends the assembled prompt to the configured local external CLI through stdin. An external-job agent sends the assembled prompt to its registered provider. Provider options and a prompt digest are persisted in Pi run state. The prompt text is delivered through the local host bridge to the provider and is not stored in the public result payload. Do not place secrets in advisory prompts unless the target provider is approved to receive them.
175
+ Native `oracle` runs inside Pi and can use its configured read tools. The Claude profiles send the assembled prompt to the local Claude Code CLI through stdin. An external-job agent sends the assembled prompt to its registered provider. Provider options and a prompt digest are persisted in Pi run state. The prompt text is delivered through the local host bridge to the provider and is not stored in the public result payload. Do not place secrets in advisory prompts unless the target provider is approved to receive them.
78
176
 
79
177
  ### External-job state table
80
178
 
@@ -111,7 +209,7 @@ You can override selected builtin fields without copying the whole agent. Overri
111
209
  }
112
210
  ```
113
211
 
114
- Supported override fields: `description`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
212
+ Supported override fields: `description`, `output`, `outputMode`, `defaultReads`, `model`, `defaultProvider`, `fallbackModels`, `thinking`, `systemPromptMode`, `inheritProjectContext`, `inheritGlobalContext`, `inheritSkills`, `defaultContext`, `acceptanceRole`, `disabled`, `skills`, `tools`, and `systemPrompt`.
115
213
 
116
214
  - `description` replaces the discovered description for builtin and custom agents, which lets list output show deployment-specific routing or model metadata.
117
215
  - Use `output: false`, `defaultReads: false`, `defaultContext: false`, or `acceptanceRole: false` to clear an inherited value.
@@ -138,11 +236,12 @@ Use these fields when an agent should see more:
138
236
  | Field | Effect |
139
237
  |-------|--------|
140
238
  | `systemPromptMode: append` | Append the agent prompt to Pi's normal base prompt. |
141
- | `inheritProjectContext: true` | Keep inherited project instructions from files like `AGENTS.md` and `CLAUDE.md`. |
239
+ | `inheritProjectContext: true` | Keep inherited repository instructions from files like `AGENTS.md` and `CLAUDE.md`. |
240
+ | `inheritGlobalContext: true` | Also keep the operator's global context file from the Pi config agent directory (such as `~/.pi/agent/AGENTS.md`). Defaults to `false`. |
142
241
  | `inheritSkills: true` | Let the child see Pi's discovered skills catalog. |
143
242
  | `defaultContext: fork` | Prefer forked session context when a launch omits `context`; if the parent has no persisted session file or current leaf yet, the implicit default falls back to `fresh` without a failed first attempt. Explicit `context: "fork"` remains strict, and explicit `context: "fresh"` still wins. |
144
243
 
145
- Builtin agents opt into project instruction inheritance by default so they follow repo-specific rules out of the box. `delegate` also uses append mode because its job is orchestration inside the parent workflow.
244
+ Builtin agents opt into repository instruction inheritance by default so they follow repo-specific rules out of the box, but global context remains excluded unless `inheritGlobalContext: true` is set. This changes the behavior of existing agents that previously received global context as part of `inheritProjectContext: true`. `delegate` also uses append mode because its job is orchestration inside the parent workflow.
146
245
 
147
246
  ## Frontmatter reference
148
247
 
@@ -159,10 +258,11 @@ tools: read, grep, find, ls, bash, mcp:chrome-devtools
159
258
  extensions:
160
259
  subagentOnlyExtensions: ./tools/child-only-search.ts
161
260
  model: claude-haiku-4-5
162
- fallbackModels: openai/gpt-5-mini, anthropic/claude-sonnet-4
261
+ fallbackModels: openai-codex/gpt-5.6-luna:low, anthropic/claude-sonnet-4
163
262
  thinking: high
164
263
  systemPromptMode: replace
165
264
  inheritProjectContext: false
265
+ inheritGlobalContext: false
166
266
  inheritSkills: false
167
267
  skills: safe-bash, review-checklist
168
268
  skillPath: ./skills, ../shared-skills
@@ -190,7 +290,7 @@ tools:
190
290
  - read
191
291
  - mcp:github/search_repositories
192
292
  fallbackModels:
193
- - openai/gpt-5-mini
293
+ - openai-codex/gpt-5.6-luna:low
194
294
  - anthropic/claude-sonnet-4
195
295
  ```
196
296
 
@@ -207,7 +307,8 @@ Field notes:
207
307
  | `fallbackModels` | Ordered backup models for provider/model failures such as quota, auth, timeout, or unavailable model. Ordinary task failures do not trigger fallback. |
208
308
  | `thinking` | Appended as a `:level` suffix at runtime unless a suffix is already present. |
209
309
  | `systemPromptMode` | `replace` by default; `append` keeps Pi's base prompt. |
210
- | `inheritProjectContext` | Keeps or strips inherited project instruction blocks. |
310
+ | `inheritProjectContext` | Keeps or strips inherited repository instruction blocks. |
311
+ | `inheritGlobalContext` | Keeps or strips the operator's global context file from the Pi config agent directory (e.g. `~/.pi/agent/AGENTS.md`). It has an effect only when `inheritProjectContext` is `true`; otherwise all context files are already disabled. Defaults to `false`. |
211
312
  | `inheritSkills` | Keeps or strips Pi's discovered skills catalog. |
212
313
  | `defaultContext` | Optional `fresh` or `fork` launch-context preference. An implicit `fork` falls back to `fresh` when the parent has no persisted session file or current leaf; an explicit launch `context: "fork"` remains strict. |
213
314
  | `skills` | Selects specific skills for the child, regardless of `inheritSkills`. |
@@ -221,6 +322,7 @@ Field notes:
221
322
  | `turnBudget` | JSON object default such as `{"maxTurns":20,"graceTurns":2}` for single-agent launches. An explicit call value wins, followed by this agent default, then global `turnBudget` config. |
222
323
  | `acceptance` | Acceptance default for single-agent launches. Use a scalar level such as `checked` or an inline/block YAML map such as `{ level: "none", reason: "lightweight lookup" }`. Explicit call values win; chain and parallel acceptance remains task/step configuration. |
223
324
  | `acceptanceRole` | Optional `read-only` or `writer` role for automatic acceptance inference. Explicit task mutation or no-edit intent wins; otherwise the declared role replaces agent-name guessing. This does not grant or revoke tools. |
325
+ | `mutationTools` | Comma-separated extension tool names whose calls count as mutation attempts for the completion guard. This declares evidence only; list and load each tool through `tools` and its extension provider as usual. |
224
326
  | `completionGuard` | Set `false` only for non-implementation agents that may mention implementation words while using mutation-capable tools such as `bash`. |
225
327
  | `interactive` | Parsed for compatibility but not currently enforced. |
226
328
  | `maxSubagentDepth` | Tightens nested delegation for this agent's children. |
@@ -289,6 +391,7 @@ More rules:
289
391
  - `mcp:` entries are split out and forwarded as direct MCP selections without granting normal builtins unless those builtins are also listed.
290
392
  - Path-like `tools` entries, such as extension paths or `.ts`/`.js` files, are treated as tool-extension paths rather than tool names.
291
393
  - Internal runtime tools such as `structured_output` are added to an explicit allowlist only when their contract is active.
394
+ - Unknown extension tool calls count as mutation attempts only when their names are listed in `mutationTools`; undeclared unknown tools keep the no-edit guard active.
292
395
  - Agents that declare only known read-only builtin tools skip the implementation completion guard. `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.
293
396
 
294
397
  Examples:
@@ -18,6 +18,18 @@ By default, project settings resolve from the nearest parent directory that cont
18
18
 
19
19
  `"git-root"` keeps package discovery, project agents, chains, and `agentOverrides` anchored to the git worktree root when that root also has Pi project config. A nested project can still opt back into nearest-root behavior by setting `"projectRootResolution": "nearest"` in its own `.pi/settings.json`.
20
20
 
21
+ ## `modelExclusions`
22
+
23
+ ```json
24
+ {
25
+ "modelExclusions": {
26
+ "defaultTtlMs": 300000
27
+ }
28
+ }
29
+ ```
30
+
31
+ Controls the duration, in milliseconds, for model exclusions. The default is `86400000` (24 hours), and the maximum is `8000000000000000` so generated expiry timestamps remain valid JavaScript dates. The extension applies this value when it starts or reloads. A lower configured value shortens active cached exclusions from their original `recordedAt`; it never extends an existing expiry. Launches also warn when a candidate is skipped, including the cached reason and expiry. `PI_MODEL_EXCLUSIONS_PATH` changes the exclusion-store path but does not change this TTL.
32
+
21
33
  ## `toolDescriptionMode`
22
34
 
23
35
  ```json
@@ -109,6 +121,23 @@ Sets `fresh` or `fork` for every subagent launch that omits `context`. This glob
109
121
 
110
122
  With `"fork"`, the setting uses the existing implicit-fork behavior. A launch starts fresh when the parent session file or current leaf is not available. `"fresh"` starts fresh even when the selected agent defaults to fork. Scheduled runs continue to set fresh context explicitly. A runner or provider that does not support fork context keeps its existing rejection behavior.
111
123
 
124
+ ## `forkContext`
125
+
126
+ ```json
127
+ {
128
+ "forkContext": {
129
+ "mode": "pruned",
130
+ "model": "openai-codex/gpt-5.6-luna:max"
131
+ }
132
+ }
133
+ ```
134
+
135
+ Controls how resolved fork launches prepare the inherited session. The default `"full"` mode keeps the complete fork. `"pruned"` mode keeps inherited context exact while it fits the code-owned 64 KiB session budget. On overflow, the required `model` returns short JSON summaries keyed by stable item ids. Tool results spill first, then older assistant and tool context, and user text only when required. It applies to explicit `context: "fork"`, global and agent fork defaults, and `context: "profile"` when the selected profile resolves to fork.
136
+
137
+ Child-visible spilled items contain only the model summary and a stable `{ batchId, itemId }` recovery ref. Raw bodies and their digests, source entry ids, labels, sizes, and tool metadata go to a private `0600` sidecar next to the child session. This release does not add a recovery command or expose that payload to the child model.
138
+
139
+ Pruned forks keep the normal `parentSession` link, child cwd alignment, and fork thinking-block sanitization. Missing model or auth, invalid or incomplete summary JSON, budget overflow, recovery validation failure, and raw overflow leakage all stop the launch before child spawn. The extension never falls back to a full fork or refs-only context after a prune failure.
140
+
112
141
  ## `fleetView`
113
142
 
114
143
  ```json
@@ -244,6 +273,14 @@ Optionally caps concurrently active top-level async runs owned by one parent ses
244
273
 
245
274
  Queued, running, paused, and needs-attention runs retain capacity. Runner-backed slots release only after terminal logical state and matching observed process-terminal proof from #1030. Missing, malformed, or unknown cleanup proof retains the slot. A terminal async workflow releases after its controller is gone and every launched child is accounted for: awaited foreground children are covered by workflow settlement, while actual background children still require observed process-terminal proof. Resume transfers the source slot without a second charge. Dismissal and history cleanup do not release capacity.
246
275
 
276
+ When the runner is gone but process cleanup proof remains unknown, configure a bounded policy reclaim under `capacity.abandonedSlotReleaseAfterMs`:
277
+
278
+ ```json
279
+ { "maxActiveAsyncRunsPerSession": 4, "capacity": { "abandonedSlotReleaseAfterMs": 1200000 } }
280
+ ```
281
+
282
+ The default is `1200000` milliseconds (20 minutes). The policy releases only a failed terminal run whose runner PID is dead and whose last activity is older than the threshold. A live or unknown PID, a non-failed terminal state, a recent run, or missing activity timestamp retains the slot. Set the value to `false` to keep strict retention. Valid configured durations range from 5 minutes through 24 hours. Policy release is reported as `abandoned-timeout` with `processProof: unknown`; it is not observed process-terminal proof and may reclaim capacity while an orphan child still exists.
283
+
247
284
  This limit bounds current top-level async load. It is separate from cumulative `maxSubagentSpawnsPerSession`, `maxSubagentSpawnsPerRun`, and `globalConcurrencyLimit`.
248
285
 
249
286
  `subagent({ action: "status" })`, fleet status, and `subagent({ action: "doctor" })` expose used, effective limit, and remaining active capacity. Static chains and parallel calls fail before creating run artifacts or starting partial work when their declared capacity cannot fit. Later retries or unbounded dynamic work are not guaranteed by that preflight.
@@ -28,7 +28,7 @@ The RPC methods are `ping`, `status`, `manage`, `spawn`, `steer`, `interrupt`, `
28
28
  Method notes:
29
29
 
30
30
  - `manage` exposes a narrow schedule-only allowlist: `schedule.list`, `schedule.show`, `schedule.history`, `schedule.pause`, `schedule.resume`, `schedule.run`, and `schedule.delete`. All actions except `schedule.list` require `id`. Mission, agent, config, worktree, and arbitrary management actions are rejected before executor dispatch. `ping.capabilities.managementActions` advertises the exact allowlist.
31
- - `spawn` accepts structured single-child execution (`agent`, `task?`) or `workflowScript` and is async-only: omit `async` or set `async: true`, omit `clarify`, and do not pass management `action` values. It goes through the same executor as the `subagent` tool, so agent discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status all behave the same.
31
+ - `spawn` accepts structured single-child execution (`agent`, `task?`), inline `workflowScript`, or `workflowScriptPath` and is async-only: omit `async` or set `async: true`, omit `clarify`, and do not pass management `action` values. Relative script paths resolve against the request `cwd`. It goes through the same executor as the `subagent` tool, so agent discovery, validation, session attribution, configured spawn caps, child-safety depth, artifacts, and async status all behave the same.
32
32
  - `steer` requires an async run `id` (plus optional child `index`) and a non-empty `message`; its reply preserves the normal acknowledged-delivery result. Optional `mode` values are `steer` (default), `follow_up`, and `auto`, and receipts include `deliveryStatus: "delivered" | "queued"`. RPC steering disables the direct tool's pause-and-revive recovery in every mode so an extension keeps authority over the exact child it spawned; `ping.capabilities.nonRecoveringSteer` advertises this guarantee.
33
33
  - `resume` requires a run target and non-empty `message`. It delegates to the existing revival path, which validates current-session ownership, persisted session/recovery metadata, stopped/live state, capability ceilings, and the exclusive session lease before returning the new async run details. Callers may request a `file-only` output path for the revived result without overriding its model, tools, or budgets. `ping.capabilities.resume` advertises this seam.
34
34
  - `stop` targets current-session top-level async runs through the stop control channel and records a `stopped` lifecycle instead of reporting a timeout.
@@ -58,6 +58,45 @@ The DTO intentionally never exposes run, async, or tool IDs. Clients must ignore
58
58
 
59
59
  `pi.events` is in-process only. It does not reach separate Pi processes or child subagents; use the file lifecycle artifacts or `pi-intercom` for cross-process coordination.
60
60
 
61
+ ## Runtime agent registration from independent extensions
62
+
63
+ An independently installed Pi extension can register an agent with the installed `pi-subagents` owner through the process-local `pi-subagents:runtime-agent-register:v1` event. Emit after extension setup, such as during `session_start`. Event delivery is synchronous, so the owner writes the result onto the request before `emit()` returns.
64
+
65
+ ```typescript
66
+ const request: {
67
+ version: 1;
68
+ name: string;
69
+ definition: {
70
+ description: string;
71
+ systemPrompt: string;
72
+ tools?: readonly string[];
73
+ };
74
+ result?:
75
+ | { ok: true; registration: { dispose(): void } }
76
+ | { ok: false; error: Error };
77
+ } = {
78
+ version: 1,
79
+ name: "runtime-probe-agent",
80
+ definition: {
81
+ description: "Agent registered by an independent extension",
82
+ systemPrompt: "Return the words runtime probe.",
83
+ tools: [],
84
+ },
85
+ };
86
+
87
+ pi.events.emit("pi-subagents:runtime-agent-register:v1", request);
88
+ if (!request.result) throw new Error("pi-subagents is not installed or not ready");
89
+ if (!request.result.ok) throw request.result.error;
90
+ const registration = request.result.registration;
91
+ // Call registration.dispose() during your extension cleanup.
92
+ ```
93
+
94
+ If `pi-subagents` is a resolvable dependency of the consumer package, `pi-subagents/agents` exports `RUNTIME_AGENT_REGISTER_EVENT`, the request/result types, and `registerAgentViaEvents()` for the same contract. A separately installed Pi package is not automatically a Node dependency of another package. In that case, use the event contract directly instead of a runtime import. A type-only development dependency is optional.
95
+
96
+ The installed owner applies the existing runtime-agent validation, collision checks, limits, runtime source metadata, and cleanup. If more than one owner listens, the first handler that writes `request.result` wins. Unsupported versions, malformed requests, and registration failures return `{ ok: false, error }`. No result means no compatible owner handled the event.
97
+
98
+ This contract is process-local. It does not register agents in child processes or other Pi processes, and it does not change package discovery or package resolution.
99
+
61
100
  ## External jobs in FleetView
62
101
 
63
102
  Use `pi-subagents/external-runs` to publish display-only current-session jobs owned by another extension:
@@ -295,7 +334,7 @@ When Pi runs inside [Herdr](https://herdr.dev), pi-subagents automatically repor
295
334
  - The bridge is enabled only when Herdr supplies `HERDR_ENV=1` and `HERDR_PANE_ID`; outside Herdr it registers no listeners or timers.
296
335
  - It restores current-session active runs after `/reload` or `/resume`, refreshes metadata while work is active, and clears it on completion or shutdown.
297
336
  - The bridge uses Herdr's existing `herdr:blocked` sibling event when an async child needs attention, and emits `herdr:busy` while async work remains. Herdr versions that support the sibling event keep the pane's semantic state `working`; older versions ignore it safely and still display the metadata label while the Pi integration remains the lifecycle authority.
298
- - The owning Pi session is the only publisher for its own pane metadata. While active subagents exist, it reports a compact `title-suffix` token: one active run uses that agent name, two or more use the active-run count, and attention adds `⚠`. The suffix is cleared when active work reaches zero.
337
+ - The owning Pi session is the only publisher for its own pane metadata. When an active workflow has an explicit bounded `label`, the newest active label appears in the summary and compact `title-suffix`; overlapping completion restores the previous active label. Raw task and goal prompts never enter Herdr metadata. Without a label, one active run uses its agent name and two or more use the active-run count. Attention adds `⚠`, and the suffix is cleared when active work reaches zero.
299
338
 
300
339
  To show the reported label in the expanded Agent sidebar, include `state_text` or `$summary` in its row layout:
301
340
 
package/docs/models.md CHANGED
@@ -51,7 +51,7 @@ For a persistent role override with a backup model for provider failures:
51
51
  "reviewer": {
52
52
  "model": "anthropic/claude-sonnet-4",
53
53
  "thinking": "high",
54
- "fallbackModels": ["openai/gpt-5-mini"]
54
+ "fallbackModels": ["openai-codex/gpt-5.6-luna:low"]
55
55
  }
56
56
  }
57
57
  }
@@ -182,9 +182,9 @@ To keep subagents inside a budget or compliance profile, enforce a model scope.
182
182
  "modelScope": {
183
183
  "enforce": true,
184
184
  "strict": true,
185
- "allow": ["inherit", "openai/gpt-5-*"],
185
+ "allow": ["inherit", "openai/gpt-5-*", "openai-codex/gpt-5.6-*"],
186
186
  "agents": {
187
- "worker": { "allow": ["openai/gpt-5-mini"] },
187
+ "worker": { "allow": ["openai-codex/gpt-5.6-luna"] },
188
188
  "reviewer": { "allow": ["inherit"] }
189
189
  }
190
190
  }
@@ -6,9 +6,9 @@ Where running subagents show up, how to inspect them, and the files and events t
6
6
 
7
7
  Foreground runs stream progress in the conversation while they run. They default to a generous 30-minute wall-clock timeout when neither the call nor the selected agent provides a timeout; a global [`timeoutMs`](configuration.md#timeoutms) config replaces that default, and explicit `timeoutMs`/`maxRuntimeMs` and agent defaults win.
8
8
 
9
- Live progress shows compact detail for single, chain, and parallel modes: current tool, recent output, token counts, aggregate cost, duration, activity freshness, current-tool duration, and chain graph metadata when available.
9
+ Live progress shows compact detail for single, chain, and parallel modes: a bounded one-line task, current tool, recent output, token counts, aggregate cost, duration, activity freshness, current-tool duration, and chain graph metadata when available. Workflow `label` metadata wins over raw task text in compact multi-child cards.
10
10
 
11
- Press Pi's configured expand key (`Ctrl+O` by default) to expand the full streaming view with complete output per step.
11
+ Press Pi's configured expand key (`Ctrl+O` by default) to expand the full streaming view with complete output per step. Running-card hints also advertise `Ctrl+Alt+F` for the Fleet inspector.
12
12
 
13
13
  Sequential chains show a flow line like `done scout → running worker`. Chains with parallel steps show per-step cards instead. Chain status uses `label` and `phase` metadata when present, while falling back to agent names for older chains.
14
14
 
@@ -29,8 +29,9 @@ The under-editor async widget gives a short view while work runs. Its expand key
29
29
  async subagent worker · background
30
30
  ● worker
31
31
  ● Step 1/1: worker · running
32
+ task: Review authentication boundaries
32
33
  ⎿ read: src/auth.ts | 2.0s
33
- Press configured-expand-key for live detail
34
+ Press configured-expand-key for live detail · Ctrl+Alt+F Fleet
34
35
  ```
35
36
 
36
37
  To inspect one background child in text, use `subagent({ action: "status", id: "...", view: "transcript" })`; add `index` for a specific child in a parallel or chain run.
@@ -40,7 +41,7 @@ To inspect one background child in text, use `subagent({ action: "status", id: "
40
41
  In the TUI, a persistent FleetView below the editor keeps active work visible as a compact summary. Set `fleetViewPlacement` to `"aboveEditor"` to move it above the editor.
41
42
 
42
43
  ```text
43
- 2 active agents · 1 pane · ↓ 4.2k tokens · ↓/← to inspect
44
+ 2 active agents · 1 pane · ↓ 3.1k window · 4.2k spent · ↓/← to inspect
44
45
  ```
45
46
 
46
47
  After you expand it:
@@ -49,11 +50,11 @@ After you expand it:
49
50
  ↑↓/jk select · enter inspect · esc back
50
51
 
51
52
  > main
52
- scout · running 1m 12s · ↓ 2.8k tokens
53
- reviewer · running 38s · ↓ 1.4k tokens
53
+ scout · running 1m 12s · ↓ 2.0k window · 2.8k spent
54
+ reviewer · running 38s · ↓ 1.1k window · 1.4k spent
54
55
  ```
55
56
 
56
- When the focused editor is empty, press `↓` or `←` to expand the summary into `main` plus active children with agent name, state, elapsed time, and token totals. The compact line counts active current-session work and Herdr project panes. Then use `↑`/`↓` or `j`/`k` to select a child and `Enter` to inspect it. Printable navigation keys are never intercepted before activation.
57
+ When the focused editor is empty, press `↓` or `←` to expand the summary into `main` plus active children with agent name, state, elapsed time, and token usage. When providers report usage, `window` is the latest assistant turn's input plus cache-read tokens, while `spent` keeps the cumulative input-plus-output total. Old run artifacts without window data keep the existing token-total label. The compact line counts active current-session work and Herdr project panes. Then use `↑`/`↓` or `j`/`k` to select a child and `Enter` to inspect it. Printable navigation keys are never intercepted before activation.
57
58
 
58
59
  FleetView replaces the legacy above-editor async widget by default. Successful background completions stay quiet so inactive Pi tabs are not marked unread, while failed or paused completions still notify the originating session. Parallel runs show every active child independently. Chains with parallel groups keep their grouped shape in progress and results, so failed or paused agents stay visible next to completed ones. When a child is explicitly allowed to fan out with `tools: subagent`, its nested runs appear under that parent child in the main status tree instead of being hidden inside the child process.
59
60