pi-subagents 0.76.1 → 0.77.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.
- package/CHANGELOG.md +67 -0
- package/README.md +1 -1
- package/agents/oracle.md +8 -19
- package/agents/researcher.md +0 -3
- package/agents/reviewer.md +17 -61
- package/agents/scout.md +1 -4
- package/agents/worker.md +8 -25
- package/docs/agents.md +70 -3
- package/docs/configuration.md +55 -6
- package/docs/extension-api.md +33 -8
- package/docs/missions.md +24 -17
- package/docs/models.md +1 -1
- package/docs/observability.md +10 -5
- package/docs/tool-reference.md +101 -83
- package/docs/watchdog.md +8 -6
- package/docs/workflows.md +15 -6
- package/package.json +1 -1
- package/prompts/council.md +1 -1
- package/skills/pi-subagents/SKILL.md +1 -1
- package/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/skills/pi-subagents/references/execution-controls.md +16 -16
- package/skills/pi-subagents/references/management-authoring-rpc.md +16 -12
- package/skills/pi-subagents/references/prompting-and-roles.md +3 -3
- package/src/agents/advertised-agent-prompt.d.ts +5 -1
- package/src/agents/advertised-agent-prompt.d.ts.map +1 -1
- package/src/agents/advertised-agent-prompt.js +8 -2
- package/src/agents/advertised-agent-prompt.js.map +1 -1
- package/src/agents/agent-management.d.ts.map +1 -1
- package/src/agents/agent-management.js +5 -0
- package/src/agents/agent-management.js.map +1 -1
- package/src/agents/agent-scope.d.ts +1 -0
- package/src/agents/agent-scope.d.ts.map +1 -1
- package/src/agents/agent-scope.js +3 -0
- package/src/agents/agent-scope.js.map +1 -1
- package/src/agents/agent-serializer.d.ts.map +1 -1
- package/src/agents/agent-serializer.js +3 -0
- package/src/agents/agent-serializer.js.map +1 -1
- package/src/agents/agents.d.ts +14 -2
- package/src/agents/agents.d.ts.map +1 -1
- package/src/agents/agents.js +94 -36
- package/src/agents/agents.js.map +1 -1
- package/src/api/preflight.d.ts +2 -0
- package/src/api/preflight.d.ts.map +1 -1
- package/src/api/preflight.js +6 -2
- package/src/api/preflight.js.map +1 -1
- package/src/extension/config.d.ts.map +1 -1
- package/src/extension/config.js +23 -2
- package/src/extension/config.js.map +1 -1
- package/src/extension/control-notices.d.ts +0 -2
- package/src/extension/control-notices.d.ts.map +1 -1
- package/src/extension/control-notices.js +1 -7
- package/src/extension/control-notices.js.map +1 -1
- package/src/extension/declaration-pinning.d.ts +14 -0
- package/src/extension/declaration-pinning.d.ts.map +1 -0
- package/src/extension/declaration-pinning.js +147 -0
- package/src/extension/declaration-pinning.js.map +1 -0
- package/src/extension/fanout-child.d.ts.map +1 -1
- package/src/extension/fanout-child.js +6 -8
- package/src/extension/fanout-child.js.map +1 -1
- package/src/extension/index.d.ts +1 -1
- package/src/extension/index.d.ts.map +1 -1
- package/src/extension/index.js +50 -109
- package/src/extension/index.js.map +1 -1
- package/src/extension/rpc.d.ts.map +1 -1
- package/src/extension/rpc.js +12 -6
- package/src/extension/rpc.js.map +1 -1
- package/src/extension/schemas.d.ts +137 -1
- package/src/extension/schemas.d.ts.map +1 -1
- package/src/extension/schemas.js +22 -22
- package/src/extension/schemas.js.map +1 -1
- package/src/extension/subagent-guide.d.ts +1 -0
- package/src/extension/subagent-guide.d.ts.map +1 -1
- package/src/extension/subagent-guide.js +80 -6
- package/src/extension/subagent-guide.js.map +1 -1
- package/src/extension/subagent-options.d.ts +8 -0
- package/src/extension/subagent-options.d.ts.map +1 -0
- package/src/extension/subagent-options.js +52 -0
- package/src/extension/subagent-options.js.map +1 -0
- package/src/extension/tool-activation.d.ts.map +1 -1
- package/src/extension/tool-activation.js +3 -2
- package/src/extension/tool-activation.js.map +1 -1
- package/src/extension/tool-description.d.ts +4 -7
- package/src/extension/tool-description.d.ts.map +1 -1
- package/src/extension/tool-description.js +45 -59
- package/src/extension/tool-description.js.map +1 -1
- package/src/inspectors/actions.d.ts +2 -0
- package/src/inspectors/actions.d.ts.map +1 -1
- package/src/inspectors/actions.js +41 -13
- package/src/inspectors/actions.js.map +1 -1
- package/src/inspectors/plugins.d.ts.map +1 -1
- package/src/inspectors/plugins.js +3 -2
- package/src/inspectors/plugins.js.map +1 -1
- package/src/inspectors/tmux/actions.d.ts +26 -0
- package/src/inspectors/tmux/actions.d.ts.map +1 -0
- package/src/inspectors/tmux/actions.js +182 -0
- package/src/inspectors/tmux/actions.js.map +1 -0
- package/src/inspectors/tmux/client.d.ts +28 -0
- package/src/inspectors/tmux/client.d.ts.map +1 -0
- package/src/inspectors/tmux/client.js +65 -0
- package/src/inspectors/tmux/client.js.map +1 -0
- package/src/inspectors/tmux/plugin.d.ts +8 -0
- package/src/inspectors/tmux/plugin.d.ts.map +1 -0
- package/src/inspectors/tmux/plugin.js +15 -0
- package/src/inspectors/tmux/plugin.js.map +1 -0
- package/src/integrations/program-status.d.ts +31 -0
- package/src/integrations/program-status.d.ts.map +1 -0
- package/src/integrations/program-status.js +189 -0
- package/src/integrations/program-status.js.map +1 -0
- package/src/intercom/native-supervisor-channel.d.ts.map +1 -1
- package/src/intercom/native-supervisor-channel.js +76 -2
- package/src/intercom/native-supervisor-channel.js.map +1 -1
- package/src/intercom/result-intercom.js +1 -1
- package/src/intercom/result-intercom.js.map +1 -1
- package/src/intercom/supervisor-ui.d.ts +2 -12
- package/src/intercom/supervisor-ui.d.ts.map +1 -1
- package/src/intercom/supervisor-ui.js +2 -154
- package/src/intercom/supervisor-ui.js.map +1 -1
- package/src/missions/store.d.ts.map +1 -1
- package/src/missions/store.js +27 -5
- package/src/missions/store.js.map +1 -1
- package/src/runs/background/async-execution.d.ts +9 -1
- package/src/runs/background/async-execution.d.ts.map +1 -1
- package/src/runs/background/async-execution.js +250 -141
- package/src/runs/background/async-execution.js.map +1 -1
- package/src/runs/background/async-job-tracker.d.ts +4 -1
- package/src/runs/background/async-job-tracker.d.ts.map +1 -1
- package/src/runs/background/async-job-tracker.js +3 -2
- package/src/runs/background/async-job-tracker.js.map +1 -1
- package/src/runs/background/async-resume.d.ts.map +1 -1
- package/src/runs/background/async-resume.js +6 -2
- package/src/runs/background/async-resume.js.map +1 -1
- package/src/runs/background/await-async-run.d.ts +8 -4
- package/src/runs/background/await-async-run.d.ts.map +1 -1
- package/src/runs/background/await-async-run.js +14 -8
- package/src/runs/background/await-async-run.js.map +1 -1
- package/src/runs/background/binary-bootstrap.d.ts.map +1 -1
- package/src/runs/background/binary-bootstrap.js +2 -1
- package/src/runs/background/binary-bootstrap.js.map +1 -1
- package/src/runs/background/chain-root-attachment.d.ts +2 -0
- package/src/runs/background/chain-root-attachment.d.ts.map +1 -1
- package/src/runs/background/chain-root-attachment.js +5 -2
- package/src/runs/background/chain-root-attachment.js.map +1 -1
- package/src/runs/background/fleet-view.js +5 -5
- package/src/runs/background/fleet-view.js.map +1 -1
- package/src/runs/background/notify.d.ts +6 -1
- package/src/runs/background/notify.d.ts.map +1 -1
- package/src/runs/background/notify.js +125 -13
- package/src/runs/background/notify.js.map +1 -1
- package/src/runs/background/result-files.d.ts +27 -0
- package/src/runs/background/result-files.d.ts.map +1 -1
- package/src/runs/background/result-files.js +100 -6
- package/src/runs/background/result-files.js.map +1 -1
- package/src/runs/background/result-watcher.d.ts.map +1 -1
- package/src/runs/background/result-watcher.js +60 -64
- package/src/runs/background/result-watcher.js.map +1 -1
- package/src/runs/background/resume-guidance.js +2 -2
- package/src/runs/background/resume-guidance.js.map +1 -1
- package/src/runs/background/run-child-session.d.ts.map +1 -1
- package/src/runs/background/run-child-session.js +2 -1
- package/src/runs/background/run-child-session.js.map +1 -1
- package/src/runs/background/run-id-resolver.d.ts.map +1 -1
- package/src/runs/background/run-id-resolver.js +9 -6
- package/src/runs/background/run-id-resolver.js.map +1 -1
- package/src/runs/background/run-status.d.ts.map +1 -1
- package/src/runs/background/run-status.js +19 -15
- package/src/runs/background/run-status.js.map +1 -1
- package/src/runs/background/runner-child-launch.d.ts.map +1 -1
- package/src/runs/background/runner-child-launch.js +1 -0
- package/src/runs/background/runner-child-launch.js.map +1 -1
- package/src/runs/background/runner-http-dispatcher.d.ts +3 -0
- package/src/runs/background/runner-http-dispatcher.d.ts.map +1 -1
- package/src/runs/background/runner-http-dispatcher.js +2 -0
- package/src/runs/background/runner-http-dispatcher.js.map +1 -1
- package/src/runs/background/scheduled-runs.d.ts +9 -0
- package/src/runs/background/scheduled-runs.d.ts.map +1 -1
- package/src/runs/background/scheduled-runs.js +124 -36
- package/src/runs/background/scheduled-runs.js.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.d.ts.map +1 -1
- package/src/runs/background/subagent-runner-bootstrap.js +5 -1
- package/src/runs/background/subagent-runner-bootstrap.js.map +1 -1
- package/src/runs/background/subagent-runner.d.ts +3 -1
- package/src/runs/background/subagent-runner.d.ts.map +1 -1
- package/src/runs/background/subagent-runner.js +15 -6
- package/src/runs/background/subagent-runner.js.map +1 -1
- package/src/runs/background/subagent-wait.d.ts +2 -0
- package/src/runs/background/subagent-wait.d.ts.map +1 -1
- package/src/runs/background/subagent-wait.js +34 -20
- package/src/runs/background/subagent-wait.js.map +1 -1
- package/src/runs/background/terminal-run-index.d.ts +1 -0
- package/src/runs/background/terminal-run-index.d.ts.map +1 -1
- package/src/runs/background/terminal-run-index.js +47 -1
- package/src/runs/background/terminal-run-index.js.map +1 -1
- package/src/runs/background/wait-tool.d.ts.map +1 -1
- package/src/runs/background/wait-tool.js +36 -23
- package/src/runs/background/wait-tool.js.map +1 -1
- package/src/runs/foreground/async-stop-action.d.ts +7 -1
- package/src/runs/foreground/async-stop-action.d.ts.map +1 -1
- package/src/runs/foreground/async-stop-action.js +21 -16
- package/src/runs/foreground/async-stop-action.js.map +1 -1
- package/src/runs/foreground/execution.d.ts.map +1 -1
- package/src/runs/foreground/execution.js +40 -14
- package/src/runs/foreground/execution.js.map +1 -1
- package/src/runs/foreground/subagent-executor.d.ts +4 -1
- package/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/src/runs/foreground/subagent-executor.js +164 -60
- package/src/runs/foreground/subagent-executor.js.map +1 -1
- package/src/runs/shared/child-hooks.js +6 -5
- package/src/runs/shared/child-hooks.js.map +1 -1
- package/src/runs/shared/child-launch.d.ts +2 -0
- package/src/runs/shared/child-launch.d.ts.map +1 -1
- package/src/runs/shared/child-launch.js +1 -0
- package/src/runs/shared/child-launch.js.map +1 -1
- package/src/runs/shared/child-session.d.ts +4 -0
- package/src/runs/shared/child-session.d.ts.map +1 -1
- package/src/runs/shared/child-session.js +28 -23
- package/src/runs/shared/child-session.js.map +1 -1
- package/src/runs/shared/child-tool-plan.d.ts.map +1 -1
- package/src/runs/shared/child-tool-plan.js +11 -10
- package/src/runs/shared/child-tool-plan.js.map +1 -1
- package/src/runs/shared/dynamic-fanout.js +1 -1
- package/src/runs/shared/dynamic-fanout.js.map +1 -1
- package/src/runs/shared/herdr-placed-run.d.ts +1 -0
- package/src/runs/shared/herdr-placed-run.d.ts.map +1 -1
- package/src/runs/shared/herdr-placed-run.js +10 -6
- package/src/runs/shared/herdr-placed-run.js.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.d.ts +10 -0
- package/src/runs/shared/model-resolution-diagnostic.d.ts.map +1 -1
- package/src/runs/shared/model-resolution-diagnostic.js +24 -0
- package/src/runs/shared/model-resolution-diagnostic.js.map +1 -1
- package/src/runs/shared/model-resolution.d.ts.map +1 -1
- package/src/runs/shared/model-resolution.js +29 -1
- package/src/runs/shared/model-resolution.js.map +1 -1
- package/src/runs/shared/nested-events.d.ts +2 -0
- package/src/runs/shared/nested-events.d.ts.map +1 -1
- package/src/runs/shared/nested-events.js +4 -0
- package/src/runs/shared/nested-events.js.map +1 -1
- package/src/runs/shared/parallel-handoff.js +2 -2
- package/src/runs/shared/parallel-handoff.js.map +1 -1
- package/src/runs/shared/parallel-utils.d.ts +2 -0
- package/src/runs/shared/parallel-utils.d.ts.map +1 -1
- package/src/runs/shared/parallel-utils.js.map +1 -1
- package/src/runs/shared/runner-launcher.d.ts +12 -0
- package/src/runs/shared/runner-launcher.d.ts.map +1 -0
- package/src/runs/shared/runner-launcher.js +25 -0
- package/src/runs/shared/runner-launcher.js.map +1 -0
- package/src/runs/shared/single-output.d.ts +20 -0
- package/src/runs/shared/single-output.d.ts.map +1 -1
- package/src/runs/shared/single-output.js +57 -0
- package/src/runs/shared/single-output.js.map +1 -1
- package/src/runs/shared/structured-output.d.ts.map +1 -1
- package/src/runs/shared/structured-output.js +17 -8
- package/src/runs/shared/structured-output.js.map +1 -1
- package/src/runs/shared/subagent-control.js +3 -3
- package/src/runs/shared/subagent-control.js.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.d.ts +8 -2
- package/src/runs/shared/subagent-prompt-runtime.d.ts.map +1 -1
- package/src/runs/shared/subagent-prompt-runtime.js +40 -18
- package/src/runs/shared/subagent-prompt-runtime.js.map +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js +1 -1
- package/src/runs/shared/workflow-async-child-guidance.js.map +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js +1 -1
- package/src/runs/shared/worktree-cleanup-plan.js.map +1 -1
- package/src/shared/atomic-json.d.ts +4 -3
- package/src/shared/atomic-json.d.ts.map +1 -1
- package/src/shared/atomic-json.js +3 -1
- package/src/shared/atomic-json.js.map +1 -1
- package/src/shared/edit-distance.d.ts +5 -0
- package/src/shared/edit-distance.d.ts.map +1 -0
- package/src/shared/edit-distance.js +33 -0
- package/src/shared/edit-distance.js.map +1 -0
- package/src/shared/formatters.d.ts.map +1 -1
- package/src/shared/formatters.js +1 -6
- package/src/shared/formatters.js.map +1 -1
- package/src/shared/model-info.d.ts +8 -0
- package/src/shared/model-info.d.ts.map +1 -1
- package/src/shared/model-info.js +22 -0
- package/src/shared/model-info.js.map +1 -1
- package/src/shared/parent-wake.d.ts +1 -1
- package/src/shared/parent-wake.d.ts.map +1 -1
- package/src/shared/parent-wake.js +25 -12
- package/src/shared/parent-wake.js.map +1 -1
- package/src/shared/pruned-fork.d.ts +1 -1
- package/src/shared/pruned-fork.d.ts.map +1 -1
- package/src/shared/pruned-fork.js +6 -0
- package/src/shared/pruned-fork.js.map +1 -1
- package/src/shared/runtime-module-path.d.ts +11 -0
- package/src/shared/runtime-module-path.d.ts.map +1 -0
- package/src/shared/runtime-module-path.js +17 -0
- package/src/shared/runtime-module-path.js.map +1 -0
- package/src/shared/types.d.ts +26 -2
- package/src/shared/types.d.ts.map +1 -1
- package/src/shared/types.js +3 -0
- package/src/shared/types.js.map +1 -1
- package/src/shared/utils.d.ts.map +1 -1
- package/src/shared/utils.js +8 -7
- package/src/shared/utils.js.map +1 -1
- package/src/slash/slash-commands.js +3 -3
- package/src/slash/slash-commands.js.map +1 -1
- package/src/slash/subagents-admin.d.ts.map +1 -1
- package/src/slash/subagents-admin.js +2 -1
- package/src/slash/subagents-admin.js.map +1 -1
- package/src/tui/fleet-transcript.d.ts +2 -0
- package/src/tui/fleet-transcript.d.ts.map +1 -1
- package/src/tui/fleet-transcript.js +7 -2
- package/src/tui/fleet-transcript.js.map +1 -1
- package/src/tui/fleet.d.ts.map +1 -1
- package/src/tui/fleet.js +9 -4
- package/src/tui/fleet.js.map +1 -1
- package/src/tui/render.d.ts +2 -2
- package/src/tui/render.d.ts.map +1 -1
- package/src/tui/render.js +19 -17
- package/src/tui/render.js.map +1 -1
- package/src/tui/subagent-messages.d.ts +23 -0
- package/src/tui/subagent-messages.d.ts.map +1 -0
- package/src/tui/subagent-messages.js +270 -0
- package/src/tui/subagent-messages.js.map +1 -0
- package/src/watchdog/register-main.d.ts.map +1 -1
- package/src/watchdog/register-main.js +1 -19
- package/src/watchdog/register-main.js.map +1 -1
- package/src/watchdog/render.d.ts +2 -10
- package/src/watchdog/render.d.ts.map +1 -1
- package/src/watchdog/render.js +1 -19
- package/src/watchdog/render.js.map +1 -1
- package/src/watchdog/tool-actions.js +2 -2
- package/src/watchdog/tool-actions.js.map +1 -1
- package/src/workflows/scripted-workflow.d.ts.map +1 -1
- package/src/workflows/scripted-workflow.js +20 -6
- package/src/workflows/scripted-workflow.js.map +1 -1
- package/src/workflows/workflow-resources.d.ts.map +1 -1
- package/src/workflows/workflow-resources.js +12 -0
- package/src/workflows/workflow-resources.js.map +1 -1
package/docs/configuration.md
CHANGED
|
@@ -106,9 +106,9 @@ The choice is made at session start or tree navigation, and only for a session w
|
|
|
106
106
|
{ "toolDescriptionMode": "compact" }
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
Controls the parent-facing `subagent` tool description registered at startup. The default registers the
|
|
109
|
+
Controls the parent-facing `subagent` tool description registered at startup. The default registers the short execution/safety description, which states the delegation authorization rule, plus a one-line `promptSnippet`. Explicit `"compact"` uses the same description without the snippet; `"full"` adds workflow and management detail, also without the snippet. All modes retain the same flat parameter schema. Extended examples and recipes are available on demand through `action:"guide"` and the bundled pi-subagents skill; full mode is not an exhaustive manual. Count the default snippet as well as the tool definition when comparing prompt footprints.
|
|
110
110
|
|
|
111
|
-
`custom` reads `subagent-tool-description.md` from the project config directory, then from `~/.pi/agent/subagent-tool-description.md`. Missing, empty, unreadable, or oversized custom files fall back to the full description. Custom templates may use `{{fullDescription}}`, `{{compactDescription}}`, `{{safetyGuidance}}`, `{{agentDir}}`, and `{{projectConfigDir}}`; the safety guidance is always present so custom prose cannot remove the runtime guardrails. Restart Pi after changing the mode or custom file.
|
|
111
|
+
`custom` reads `subagent-tool-description.md` from the project config directory, then from `~/.pi/agent/subagent-tool-description.md`. Missing, empty, unreadable, or oversized custom files fall back to the full description. Custom templates may use `{{fullDescription}}`, `{{compactDescription}}`, `{{safetyGuidance}}`, `{{agentDir}}`, and `{{projectConfigDir}}`; the safety guidance is always present so custom prose cannot remove the runtime guardrails. Restart Pi after changing the mode or custom file. The change applies to new sessions; a resumed session keeps the tool definition and prompt text it already declared, so its prompt cache stays valid.
|
|
112
112
|
|
|
113
113
|
## `disabledFeatures`
|
|
114
114
|
|
|
@@ -116,7 +116,7 @@ Controls the parent-facing `subagent` tool description registered at startup. Th
|
|
|
116
116
|
{ "disabledFeatures": ["watchdog", "panes", "preflight", "lane-metadata", "gates"] }
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
Removes feature groups you do not use from the `subagent` tool. Each listed feature loses its parameters from the model-facing schema, and any request that still uses one of its parameters or actions fails with an error naming this setting. The check covers the parent tool, fanout-child tools, RPC, slash commands, prompt templates, scheduled launches, delegated launches, and workflow `runs.run`/`runs.all`/`runs.lanes` children, which are rejected before they launch. The built-in tool descriptions, the unknown-action list, the fanout-child tool description, and RPC `ping` no longer mention disabled features, and `{ action: "guide", topic: "tool-reference" }` starts with a notice listing what is disabled. Custom tool descriptions are not changed. Nothing is disabled by default, and the default schema and description are unchanged. An unknown or duplicate feature name fails config loading rather than silently re-enabling every feature.
|
|
119
|
+
Removes feature groups you do not use from the `subagent` tool. Each listed feature loses its top-level parameters from the model-facing schema and its `options` keys are rejected, and any request that still uses one of its parameters or actions fails with an error naming this setting. The check covers the parent tool, fanout-child tools, RPC, slash commands, prompt templates, scheduled launches, delegated launches, and workflow `runs.run`/`runs.all`/`runs.lanes` children, which are rejected before they launch. The built-in tool descriptions, the unknown-action list, the fanout-child tool description, and RPC `ping` no longer mention disabled features, and `{ action: "guide", options: { topic: "tool-reference" } }` starts with a notice listing what is disabled. Custom tool descriptions are not changed. Nothing is disabled by default, and the default schema and description are unchanged. An unknown or duplicate feature name fails config loading rather than silently re-enabling every feature.
|
|
120
120
|
|
|
121
121
|
| Feature | Parameters removed | Actions rejected |
|
|
122
122
|
|---|---|---|
|
|
@@ -136,7 +136,7 @@ Removes feature groups you do not use from the `subagent` tool. Each listed feat
|
|
|
136
136
|
| `external-machines` | `machine` | |
|
|
137
137
|
| `workflow-scripts` | `workflow`, `args`, `preflight`, `globalConcurrencyLimit`, `maxSubagentSpawnsPerRun` | `validate` |
|
|
138
138
|
|
|
139
|
-
Disabling a per-call option removes only the per-call override. Configured defaults such as `toolBudget`, `usageBudget`, and `control` in this file still apply, the watchdog still follows its own settings, missions still attach automatically when [`missions`](#missions) enables them, and agents with a `machine` in their definition still run there. Operator screens that do not go through the `subagent` executor, such as `/subagents-admin`, are unchanged. With every feature and [`scheduledRuns.enabled`](#scheduledruns) disabled, the default `subagent` tool declaration (name, description, and parameter schema as JSON) shrinks from 18,239 to 10,263 characters (80 to 41 parameters). Restart Pi after changing this setting.
|
|
139
|
+
Disabling a per-call option removes only the per-call override. Configured defaults such as `toolBudget`, `usageBudget`, and `control` in this file still apply, the watchdog still follows its own settings, missions still attach automatically when [`missions`](#missions) enables them, and agents with a `machine` in their definition still run there. Operator screens that do not go through the `subagent` executor, such as `/subagents-admin`, are unchanged. With every feature and [`scheduledRuns.enabled`](#scheduledruns) disabled, the default `subagent` tool declaration (name, description, and parameter schema as JSON) shrinks from 18,239 to 10,263 characters (80 to 41 parameters). Restart Pi after changing this setting. The smaller declaration applies to new sessions; a resumed session keeps the tool declaration it already sent, so its prompt cache stays valid. Disabled options and actions are still rejected in every session.
|
|
140
140
|
|
|
141
141
|
### Chain and tasks without workflow scripts
|
|
142
142
|
|
|
@@ -226,6 +226,25 @@ Set `enabled` to `false` (or remove the block) as a kill switch. In that state,
|
|
|
226
226
|
|
|
227
227
|
Workflow script calls use background execution when the request omits `async`. Set `asyncByDefault` to `false` to restore foreground-by-default behavior for tool launches that still use the internal single-run primitive. Callers can still force foreground with `async: false` unless `forceTopLevelAsync` is enabled.
|
|
228
228
|
|
|
229
|
+
## `runnerLaunchers`
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"runnerLaunchers": {
|
|
234
|
+
"net": ["nono", "run", "--profile", "net", "--"]
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Named command prefixes that wrap a background runner, for example to run some agents in a different sandbox from the parent. An agent selects one by name with `launcher: net` in its frontmatter; the runner then starts as `<launcher argv> <resolved runner command>`. Agents without `launcher` are unaffected.
|
|
240
|
+
|
|
241
|
+
- This key is read only from this user config file. Project settings, agent files, and tool calls cannot define a launcher command; an agent file can only name one defined here.
|
|
242
|
+
- Names must match `^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$`.
|
|
243
|
+
- Each value is a non-empty array of non-blank strings without NUL characters. It is passed to the operating system as an argument list, never through a shell, so quoting and whitespace inside an entry are kept as written.
|
|
244
|
+
- An invalid entry makes config loading fail with an error instead of falling back to defaults. If the file is not valid JSON at all, no launchers are defined, so every agent that names a launcher fails to launch.
|
|
245
|
+
|
|
246
|
+
See [Sandboxing background children with a launcher](agents.md#sandboxing-background-children-with-a-launcher) for the agent field, the requirements a wrapper must meet, and its limits.
|
|
247
|
+
|
|
229
248
|
## `defaultSubagentContext`
|
|
230
249
|
|
|
231
250
|
```json
|
|
@@ -304,6 +323,36 @@ Controls the under-editor widget for active background runs. It defaults to `tru
|
|
|
304
323
|
|
|
305
324
|
Starts each newly mounted under-editor async widget in its one-line folded state. It defaults to `false`. A header click still toggles the widget, and the folded state still resets when the widget is removed or Pi reloads.
|
|
306
325
|
|
|
326
|
+
## `asyncWidgetLayout`
|
|
327
|
+
|
|
328
|
+
```json
|
|
329
|
+
{ "asyncWidgetLayout": "rows" }
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Sets the layout of the unfolded under-editor async widget. Defaults to `"adaptive"`; valid values are `"adaptive"` and `"rows"`.
|
|
333
|
+
|
|
334
|
+
`"adaptive"` gives each run its own detail rows while the terminal has room, and switches to one line per run on a short terminal. `"rows"` shows a header line and one line per run even when the terminal has room for detail rows. It uses no more rows than the adaptive layout may: runs that do not fit are counted on a `+N more` line, and a workflow's lanes fill any rows left over. In both layouts, a header click and `asyncWidgetCollapsed` fold the widget to its count line, and Pi's expand key shows the detailed layout.
|
|
335
|
+
|
|
336
|
+
## `programStatus`
|
|
337
|
+
|
|
338
|
+
```json
|
|
339
|
+
{ "programStatus": false }
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Reports each background run's state to the terminal with [OSC 7501, the Program Status Protocol](https://www.superlogical.com/rex/docs/build/program-status), so a terminal that supports it (Ghostty and Rex, for example) can show which runs are working, waiting on you, finished, or failed. It defaults to `true`; set it to `false` to send nothing. Terminals that don't support OSC 7501 ignore it, so turn it off only if your terminal prints unknown escape sequences.
|
|
343
|
+
|
|
344
|
+
Reports are sent only from an interactive TUI session whose standard output is a terminal and whose `TERM` is not `dumb`, and only when a record changes. `PI_PROGRAM_STATUS=0`, Pi's own switch for its OSC 7501 reports, turns these off too. Each run gets its own record under `subagents/`: `subagents/<run>` for a run, where `<run>` is the first 12 characters of its run id, and `subagents/<workflow-run>.<key>` for a background workflow child. A key made only of letters, digits, `_`, `+` and `-`, and at most 19 characters long, is used as is; any other key becomes its first 12 characters (other characters replaced by `-`) plus a short hash of the full key, so different keys never share an id. Workflow children are siblings of their workflow's record, not nested under it, so clearing a finished workflow never removes a running child. The root record belongs to Pi itself, so this extension never writes it.
|
|
345
|
+
|
|
346
|
+
| Run | Reported state |
|
|
347
|
+
|---|---|
|
|
348
|
+
| queued or running | `working` |
|
|
349
|
+
| running, with a `contact_supervisor` question the parent left unanswered when it finished its turn | `blocked` (`kind=question`) |
|
|
350
|
+
| complete | `done` |
|
|
351
|
+
| failed, partial, or rejected | `error` |
|
|
352
|
+
| stopped or paused | `idle` |
|
|
353
|
+
|
|
354
|
+
Each record's `title` is the agent names or workflow key, and its `msg` is the current tool while working, or the outcome. Neither includes the task text. Finished runs keep their `done`, `error`, or `idle` record after they leave the async widget, for as long as they are in Fleet's recent history (the last 20 finished runs). Records of runs this session no longer tracks, for example after switching sessions, are cleared. At most 64 records are shown: running and waiting runs first, then finished ones, most recently updated first; older finished records are cleared to make room. When the extension is reloaded or the session is replaced, it clears every record it sent and the new session reports the runs it still tracks. Pi 1.1 and later reports its own state on the root record and clears every record, these included, when it quits, suspends with Ctrl+Z, or opens an external editor. After a suspend, this extension sends its records again; after an external editor, each record comes back the next time it changes. Foreground runs are not reported, and tmux drops these sequences unless you configure passthrough.
|
|
355
|
+
|
|
307
356
|
## `waitTool`
|
|
308
357
|
|
|
309
358
|
```json
|
|
@@ -312,7 +361,7 @@ Starts each newly mounted under-editor async widget in its one-line folded state
|
|
|
312
361
|
|
|
313
362
|
`defaultTimeoutMs` sets the blocking window used when a `bg_wait` call omits `timeoutMs`; explicit call values win, followed by this setting, then the 30-minute fallback. `bg_wait` is the only registered wait tool. When the window elapses, the tool returns a non-error `window_elapsed` result with the still-active work identities, and that work keeps running. Set `enabled` to `false` to make direct calls return immediately instead of blocking. The default is enabled. You can also set `"waitTool": false`; set `PI_SUBAGENT_WAIT_TOOL_ENABLED=false` (or `0`, `off`, `disabled`) to override config for one process. The effective enabled and default-timeout values are passed explicitly to child runtimes. Headless `agent_end` auto-drain retains its own strict deadline and fails if required work remains unresolved. Invalid config or environment values fail instead of being coerced.
|
|
314
363
|
|
|
315
|
-
Blocking `bg_wait({ id: "..." })` keeps the current tool call open until that run changes. By default it returns when a run needs attention. Use `bg_wait({ stopOnAttention: false })` only for run-to-completion flows that should wait through idle or long-thinking attention; supervisor/contact requests still stop the wait. In a long-lived interactive parent session, `bg_wait({ id: "...", nonBlocking: true })` instead resolves the prefix once, persists the exact run identity, returns a subscription token immediately, and wakes that session on completion, failure, attention, reconciliation failure, or timeout. Use it for provider, detached, or other background work without a native completion notification; ordinary async subagent runs notify the parent natively and do not need a wait subscription. Armed subscriptions appear in ordinary `subagent({ action: "status" })` output and are not counted as active child work. Native completion notifications wake the session through the Pi process that launched the run, while that process is still running; a session reopened in a new process does not get that wake and should read the result with `subagent({ action: "status" })`. `nonBlocking` subscriptions need a host with a UI context, such as interactive or RPC mode; plain SDK embedding without a UI context rejects them.
|
|
364
|
+
Blocking `bg_wait({ id: "..." })` keeps the current tool call open until that run changes. By default it returns when a run needs attention. Use `bg_wait({ stopOnAttention: false })` only for run-to-completion flows that should wait through idle or long-thinking attention; supervisor/contact requests still stop the wait. A steer or follow-up the operator sends while a blocking wait is open also ends it, with a non-error `user_input` result listing the still-active work, so the message reaches the model without waiting out the window. In a long-lived interactive parent session, `bg_wait({ id: "...", nonBlocking: true })` instead resolves the prefix once, persists the exact run identity, returns a subscription token immediately, and wakes that session on completion, failure, attention, reconciliation failure, or timeout. Use it for provider, detached, or other background work without a native completion notification; ordinary async subagent runs notify the parent natively and do not need a wait subscription. Armed subscriptions appear in ordinary `subagent({ action: "status" })` output and are not counted as active child work. Native completion notifications wake the session through the Pi process that launched the run, while that process is still running; a session reopened in a new process does not get that wake and should read the result with `subagent({ action: "status" })`. `nonBlocking` subscriptions need a host with a UI context, such as interactive or RPC mode; plain SDK embedding without a UI context rejects them.
|
|
316
365
|
|
|
317
366
|
This is different from `waitTool.enabled=false`, which returns immediately without registering any future wake. Provider items remain available only to blocking fleet-wide waits; non-blocking subscriptions require one async or remembered detached foreground run id.
|
|
318
367
|
|
|
@@ -388,7 +437,7 @@ Inline or file-backed top-level workflow calls may set a positive safe-integer `
|
|
|
388
437
|
|
|
389
438
|
Optionally caps the total number of child subagent launches during one parent session, including completed and failed children, parallel task counts, static chain steps, and bounded dynamic fanout children. Sessions are unlimited by default. Set this value to `0` to disable a configured cap. `PI_SUBAGENT_MAX_SPAWNS_PER_SESSION` overrides the config for a process and follows the same positive-cap/zero-unlimited semantics.
|
|
390
439
|
|
|
391
|
-
`subagent({ action: "status" })`, fleet status, and `subagent({ action: "doctor" })` expose used, effective limit, remaining capacity, grants, and the remaining grant allowance for this budget. A user may explicitly call `subagent({ action: "grant-spawn-budget", additional: 10 })` from the root interactive parent after all children settle and confirm the native prompt. Grants are additive: they never erase cumulative usage, are rejected for unlimited sessions and child/headless callers, and total granted capacity cannot exceed the original configured cap. Compaction remains part of the same logical parent session and does not reset usage or grants; starting a new parent session does.
|
|
440
|
+
`subagent({ action: "status" })`, fleet status, and `subagent({ action: "doctor" })` expose used, effective limit, remaining capacity, grants, and the remaining grant allowance for this budget. A user may explicitly call `subagent({ action: "grant-spawn-budget", options: { additional: 10 } })` from the root interactive parent after all children settle and confirm the native prompt. Grants are additive: they never erase cumulative usage, are rejected for unlimited sessions and child/headless callers, and total granted capacity cannot exceed the original configured cap. Compaction remains part of the same logical parent session and does not reset usage or grants; starting a new parent session does.
|
|
392
441
|
|
|
393
442
|
## `maxSubagentSpawnsPerRun`
|
|
394
443
|
|
package/docs/extension-api.md
CHANGED
|
@@ -19,7 +19,7 @@ registerWorkflowResource({
|
|
|
19
19
|
}): { dispose(): void }
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Names are case-sensitive, at most 128 characters, and match `[A-Za-z0-9][A-Za-z0-9._-]*`; use an extension prefix. Versions are positive safe integers. Registration throws for invalid input, protected builtins (`review`, `run-ci`, and `chain` and `tasks`, which back the tool's structured inputs), or duplicate names within the same session. Different sessions may register the same name. Dispose before replacement; there is no silent overwrite.
|
|
22
|
+
Names are case-sensitive, at most 128 characters, and match `[A-Za-z0-9][A-Za-z0-9._-]*`; use an extension prefix. Versions are positive safe integers. Registration throws for invalid input, protected builtins (`review`, `run-ci`, `parallel`, and `chain` and `tasks`, which back the tool's structured inputs), or duplicate names within the same session. Different sessions may register the same name. Dispose before replacement; there is no silent overwrite.
|
|
23
23
|
|
|
24
24
|
Register in `session_start` using **`ctx.sessionManager.getSessionId()`**, not the session file path or a tool argument. Dispose in `session_shutdown`. New/resumed/forked sessions and reloads need registration from the replacement runtime's `session_start`; do not retain old `pi`/`ctx` references. The extension owns cleanup, not an automatic registration lifecycle manager. Disposal is idempotent and cannot remove a newer replacement. Missing cleanup can cause a duplicate-registration failure on reload.
|
|
25
25
|
|
|
@@ -123,7 +123,7 @@ Method notes:
|
|
|
123
123
|
- `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.
|
|
124
124
|
- `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.
|
|
125
125
|
- `cost` returns the same parent-plus-child accounting `/subagent-cost` renders, as data: `{ version: 1, parent, children, childTotal, total, unresolvedAsyncChildren }`, where each usage is `{ input, output, cacheRead, cacheWrite, cost, turns }` and each child carries `label`, `agent`, `runId`, `usage`, and `sessionFile` when known. It is read-only and walks the current session branch plus existing run artifacts, so request it on your own turn boundaries (for example after `agent_settled` or an async completion wake), not on a timer. `unresolvedAsyncChildren` counts async children whose metadata could not be read; treat `childTotal` as a lower bound when it is non-zero, exactly as documented for `/subagent-cost` in [observability.md](observability.md). `ping.capabilities.cost` advertises `{ version: 1 }`.
|
|
126
|
-
- `stop`
|
|
126
|
+
- `stop` accepts current-session running or queued async runs and whole paused runs. Paused runs are sealed only with exact observed native runner-terminal proof; missing or unknown proof returns an error even if a stop request was persisted. A successful reply's `state: "stopping"` acknowledges the stop operation for the exact run, not its current lifecycle or retirement. Read status and process-terminal evidence to establish termination. Child-scoped stop remains limited to pending or running children of eligible runs; already-terminal targets are rejected.
|
|
127
127
|
- `status` keeps targeted and rich requests on the executor-backed path. A request with no `id`, `runId`, `dir`, `index`, `view`, or `lines` may use the restored in-memory projections and a short summary; when the live state is missing, stale, session-mismatched, or not restored, it falls back to normal executor status. Status `view`, `lines`, and `index` are forwarded for targeted transcript/fleet requests. Successful replies retain `text`, `details`, `fleet`, and `asyncSnapshot`; the short summary intentionally omits canonical filesystem details, wait subscriptions, and budget annotations.
|
|
128
128
|
|
|
129
129
|
Capability advertisements on `ping`:
|
|
@@ -141,6 +141,20 @@ Capability advertisements on `ping`:
|
|
|
141
141
|
|
|
142
142
|
Structured delegation progress updates carry `runId` as soon as foreground execution allocates it, so a caller can retain the package-owned revival target even if its own tool turn is interrupted before the terminal response. Foreground `details.results[]` rows also include a numeric `index` that is unique within the run and stable across partial progress snapshots and the final result; use `(runId, index)` instead of row position to correlate single, counted parallel, and chain children.
|
|
143
143
|
|
|
144
|
+
### Direct async launch correlation
|
|
145
|
+
|
|
146
|
+
Direct async runs retain their originating `toolCallId` in status and result
|
|
147
|
+
artifacts. After a lost RPC spawn reply, request `status` with
|
|
148
|
+
`id: "rpc-spawn-<original-requestId>"`. The raw request UUID is not a run ID.
|
|
149
|
+
Default targeted replies expose the resolved `runId` and retained `toolCallId`
|
|
150
|
+
in `data.details`; older artifacts can omit the latter.
|
|
151
|
+
|
|
152
|
+
Lookup uses the existing run indexes and retained artifacts. Terminal indexing
|
|
153
|
+
keeps the alias after result delivery while the run's status is retained.
|
|
154
|
+
Correlation is not idempotent spawn: multiple runs with one alias are ambiguous, and missing or
|
|
155
|
+
expired evidence never proves that execution did not start. Do not redispatch
|
|
156
|
+
on that basis.
|
|
157
|
+
|
|
144
158
|
### Fleet status DTO
|
|
145
159
|
|
|
146
160
|
When `ping.capabilities.fleetStatus` is `{ version: 1 }`, successful `status` replies include `data.fleet`: `{ version: 1, entries, totalActive, omitted }`.
|
|
@@ -264,6 +278,7 @@ Preflight covers ordinary single-agent launch resolution:
|
|
|
264
278
|
- A parsed-definition digest, including system prompt and launch-affecting model, tool, skill, extension, output, and memory fields. Runtime overlays such as the Intercom bridge never change it.
|
|
265
279
|
- Fresh/fork context, effective model and thinking, skill and tool resolution, direct MCP selections, runtime/configured extensions. Pass your extension's `pi` as `runtimeSnapshotHost` so `mcp:` selections resolve against Pi's built-in MCP the way a launch does. Without it, preflight cannot see built-in MCP and resolves `mcp:` selections through pi-mcp-adapter's configuration, as before.
|
|
266
280
|
- Model scope allow lists accept the reserved tokens `inherit` and `scoped`; `scoped` expands to the caller-supplied `scopedModelIds` snapshot, degrading to `inherit` when it is omitted. Callers whose `modelScope.allow` uses `scoped` must pass `scopedModelIds` (the session's `/scoped-models` snapshot) alongside `parentModel`, otherwise preflight resolves it as `inherit` and may reject models the actual launch allows.
|
|
281
|
+
- Pass `projectTrusted: ctx.isProjectTrusted()` to match a session that declined project trust. With `false`, project agents and project subagent settings are ignored and an explicit `agentScope: "project"` returns `restricted_agent`. It defaults to `true`.
|
|
267
282
|
- The resolved Intercom bridge state (`intercomBridge.mode` and `intercomBridge.active`). An active bridge appends the bridge instruction to the child prompt and adds `contact_supervisor` to a declared tool list, exactly as execution does.
|
|
268
283
|
- Artifact/session paths, async lifecycle/status/result/event/process-terminal paths, package/lifecycle versions, capability-ceiling audit data, and stable digests.
|
|
269
284
|
|
|
@@ -445,10 +460,10 @@ The async runner process does not import provider internals. It writes operation
|
|
|
445
460
|
Inspect is the portable command and action surface for an existing async run. The public actions are:
|
|
446
461
|
|
|
447
462
|
```ts
|
|
448
|
-
subagent({ action: "inspector.command", id: "<run-id>", index: 0 })
|
|
449
|
-
subagent({ action: "inspector.open", id: "<run-id>", index: 0, focus: true })
|
|
450
|
-
subagent({ action: "inspector.status", id: "<run-id>", index: 0 })
|
|
451
|
-
subagent({ action: "inspector.close", id: "<run-id>", index: 0 })
|
|
463
|
+
subagent({ action: "inspector.command", id: "<run-id>", options: { index: 0 } })
|
|
464
|
+
subagent({ action: "inspector.open", id: "<run-id>", options: { index: 0, focus: true } })
|
|
465
|
+
subagent({ action: "inspector.status", id: "<run-id>", options: { index: 0 } })
|
|
466
|
+
subagent({ action: "inspector.close", id: "<run-id>", options: { index: 0 } })
|
|
452
467
|
```
|
|
453
468
|
|
|
454
469
|
`inspector.command` returns a standalone runner command without contacting a host or writing a binding. `inspector.open` selects an available built-in or externally registered inspector plugin. `status` and `close` select the plugin that owns the run binding and report clearly when that plugin does not support the requested lifecycle action. Without an available plugin, `open` fails closed with an actionable message; ordinary launches remain headless. Closing an inspector never stops the run.
|
|
@@ -495,9 +510,9 @@ An `InspectorPlugin` supplies:
|
|
|
495
510
|
- `owns(context)`: synchronously check whether the provider owns an inspector binding for this target.
|
|
496
511
|
- Optional `status(context)` and `close(context)`: inspect or close that binding, returning the same result type. Closing an inspector must not stop the subagent.
|
|
497
512
|
|
|
498
|
-
The existing dispatcher tries Herdr, then Ghostty, then external providers in
|
|
513
|
+
The existing dispatcher tries Herdr, then Ghostty, then tmux, then external providers in
|
|
499
514
|
registration order. Names are case-sensitive; duplicate names and the built-in
|
|
500
|
-
names `herdr` and `
|
|
515
|
+
names `herdr`, `ghostty`, and `tmux` are rejected. A selected provider's failure is not
|
|
501
516
|
retried through another provider. Status/close use the first provider whose
|
|
502
517
|
`owns` returns true; unavailable lifecycle methods remain explicit errors.
|
|
503
518
|
Providers own their pane bindings and must verify ownership before closing one.
|
|
@@ -583,6 +598,16 @@ A host that embeds this extension owns whether completion wakes can be delivered
|
|
|
583
598
|
|
|
584
599
|
Ordinary async and foreground completion wakes use `registerSubagentNotify` and `sendCompletion`. They listen for completion events and deliver through `pi.sendMessage(..., { triggerTurn })`. When the parent is idle, every pi-subagents notice that should start a turn (completions, supervisor asks, control and steering notices, wait subscriptions) is instead appended without a turn, followed by one short user message, `Subagent updates above.`, sent with `pi.sendUserMessage`. Pi runs `before_agent_start` only for prompts, so this keeps extension-set system prompt sections in the woken run. A busy parent still gets the notice as a steering message. Session shutdown stops the result watcher and disposes this completion notifier. `createWaitSubscriptionManager` is separate: it is the explicit non-blocking `bg_wait` subscription path for work without native notification, not the ordinary completion wake path.
|
|
585
600
|
|
|
601
|
+
Each completion notice is a custom message with `customType: "subagent-notify"`. Its `content` is the text the model reads. Pi does not send `details` to the model, so hosts can use it to match a notice to its runs by id without parsing the text. `details.runs` has one entry per finished run, in the order of the notice. A grouped notice has several entries. Each entry has `agent` and `status` (`completed`, `failed`, `paused` or `stopped`). When known, an entry also has these fields:
|
|
602
|
+
|
|
603
|
+
- `runId`: the finished run's id. For a workflow it equals `workflowRunId`.
|
|
604
|
+
- `workflowRunId`: set only for workflows.
|
|
605
|
+
- `childRuns`: `{ runId, workflowKey?, agent?, status }` for each workflow, chain or parallel child.
|
|
606
|
+
- `childOutputs`: the per-child saved output paths of a workflow.
|
|
607
|
+
- `source`, `durationMs`, `asyncDir`, `workflowReceiptPath`, `handoffPath`, and `sessionLabel` with `sessionValue` (a session file, share URL or share error).
|
|
608
|
+
|
|
609
|
+
Entries can also carry other values the notice text is built from, such as `scheduleOrigin` and `watchdogBlockers`. The output previews are only in `content`.
|
|
610
|
+
|
|
586
611
|
Detached children do not stop when the session does. They are the host process's children, not the session's, so the run keeps going, completes, and notifies nobody. What is lost is the notification, not the work.
|
|
587
612
|
|
|
588
613
|
This matters because "is the parent busy?" is the wrong idle signal. A parent that launches a detached run and hands control back — which is what the async launch output tells it to do — is not prompting, streaming, compacting, or running a shell command. A host that reaps sessions on those signals alone will dispose exactly the session that was waiting to be woken.
|
package/docs/missions.md
CHANGED
|
@@ -28,13 +28,15 @@ An explicit `mission` object must have exactly one non-empty `title` or `summary
|
|
|
28
28
|
```ts
|
|
29
29
|
const created = subagent({
|
|
30
30
|
action: "mission.create",
|
|
31
|
-
|
|
31
|
+
options: {
|
|
32
|
+
mission: { title: "Ship auth refresh", objective: "Implement and validate token refresh" }
|
|
33
|
+
}
|
|
32
34
|
})
|
|
33
35
|
// After a ```js workflow block that runs the approved auth refresh plan:
|
|
34
|
-
subagent({ workflow: true, missionId: "<mission-id>" })
|
|
36
|
+
subagent({ workflow: true, options: { missionId: "<mission-id>" } })
|
|
35
37
|
|
|
36
38
|
// Or create and attach in one launch
|
|
37
|
-
subagent({ workflow: true, mission: { title: "Ship auth refresh" } })
|
|
39
|
+
subagent({ workflow: true, options: { mission: { title: "Ship auth refresh" } } })
|
|
38
40
|
```
|
|
39
41
|
|
|
40
42
|
### Goal missions
|
|
@@ -44,11 +46,13 @@ Set `goal: true` with a token budget to make an open mission an active continuat
|
|
|
44
46
|
```ts
|
|
45
47
|
subagent({
|
|
46
48
|
action: "mission.create",
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
options: {
|
|
50
|
+
mission: {
|
|
51
|
+
title: "Ship auth refresh",
|
|
52
|
+
objective: "Implement and validate token refresh",
|
|
53
|
+
goal: true,
|
|
54
|
+
budget: { tokens: 400000 }
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
})
|
|
54
58
|
```
|
|
@@ -92,10 +96,12 @@ return runs.run("main", { agent: "reviewer", task: "Review the current diff." })
|
|
|
92
96
|
subagent({
|
|
93
97
|
action: "schedule.create",
|
|
94
98
|
id: "evening-review",
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
workflow: true,
|
|
100
|
+
options: {
|
|
101
|
+
name: "Evening review",
|
|
102
|
+
at: "+30m",
|
|
103
|
+
baseRef: "refs/heads/release"
|
|
104
|
+
}
|
|
99
105
|
})
|
|
100
106
|
```
|
|
101
107
|
|
|
@@ -103,14 +109,14 @@ Create a fixed recurring workflow from a script file:
|
|
|
103
109
|
|
|
104
110
|
```ts
|
|
105
111
|
// .pi/workflows/backlog.js: return runs.run('main', { agent: 'worker', task: args.task })
|
|
106
|
-
subagent({ action: "schedule.create", id: "backlog",
|
|
112
|
+
subagent({ action: "schedule.create", id: "backlog", workflow: "./.pi/workflows/backlog.js", args: { task: "Maintain core" }, options: { every: "6h", catchUp: "latest" } })
|
|
107
113
|
```
|
|
108
114
|
|
|
109
115
|
Create a daily or weekly local-time schedule:
|
|
110
116
|
|
|
111
117
|
```ts
|
|
112
|
-
subagent({ action: "schedule.create", every: "day", at: "09:00", timezone: "Asia/Taipei"
|
|
113
|
-
subagent({ action: "schedule.create", every: "week", on: ["mon", "tue", "wed", "thu", "fri"], at: "09:00", timezone: "America/New_York"
|
|
118
|
+
subagent({ action: "schedule.create", workflow: "./.pi/workflows/review.js", options: { every: "day", at: "09:00", timezone: "Asia/Taipei" } })
|
|
119
|
+
subagent({ action: "schedule.create", workflow: "./.pi/workflows/review.js", options: { every: "week", on: ["mon", "tue", "wed", "thu", "fri"], at: "09:00", timezone: "America/New_York" } })
|
|
114
120
|
```
|
|
115
121
|
|
|
116
122
|
Calendar schedules require `HH:mm` and an explicit IANA `timezone` or `UTC`. Weekly `on` is a non-empty weekday array; duplicates are removed and weekdays sorted. Daily schedules do not accept `on`. Missing local times and skipped dates are skipped; a repeated time fires at its first instant only. The pending local date is persisted with a UTC cache that is refreshed on restoration using the host's current timezone data. Use a calendar-capable version in every session sharing these definitions; older schedulers reject the unknown trigger kind.
|
|
@@ -120,7 +126,7 @@ Fixed intervals support `m`, `h`, `d`, and `w` units and advance from the planne
|
|
|
120
126
|
Create a quiet recurring workflow whose successful completions stay visible but do not wake the parent session:
|
|
121
127
|
|
|
122
128
|
```ts
|
|
123
|
-
subagent({ action: "schedule.create", id: "nightly-sweep", every: "24h", quiet: true
|
|
129
|
+
subagent({ action: "schedule.create", id: "nightly-sweep", workflow: true, options: { every: "24h", quiet: true } })
|
|
124
130
|
```
|
|
125
131
|
|
|
126
132
|
Manage schedules with `schedule.list`, `schedule.show`, `schedule.history`, `schedule.pause`, `schedule.resume`, `schedule.run`, `schedule.run-due`, and `schedule.delete`.
|
|
@@ -128,7 +134,7 @@ Manage schedules with `schedule.list`, `schedule.show`, `schedule.history`, `sch
|
|
|
128
134
|
Attach an existing mission to give each scheduled workflow access to the same durable `state.get/set`:
|
|
129
135
|
|
|
130
136
|
```ts
|
|
131
|
-
subagent({ action: "schedule.create", id: "backlog",
|
|
137
|
+
subagent({ action: "schedule.create", id: "backlog", workflow: "./.pi/workflows/backlog.js", options: { every: "6h", missionId: "<mission-id>" } })
|
|
132
138
|
```
|
|
133
139
|
|
|
134
140
|
The mission must be readable in the store resolved from the schedule's target `cwd` and current mission configuration. Creation checks it without changing its status. Every fire uses the normal explicit mission launch path, including after session restoration; missing or invalid records fail before workflow execution. Schedules accept only an existing `missionId`, not mission creation or updates. The script's fixed `args` and its mutable mission state remain separate.
|
|
@@ -142,6 +148,7 @@ Mission-bound definitions use schedule schema version 2 so older versions reject
|
|
|
142
148
|
Behavior:
|
|
143
149
|
|
|
144
150
|
- Runs always launch async with fresh context. Without `missionId`, they disable mission creation and have no `state` global.
|
|
151
|
+
- Project-wide schedules (the default) fire in whichever Pi session in that project claims the fire first, and that session receives the run's notifications. Pass `sessionOnly: true` to bind restoration and every fire to the creating session; other sessions in the project never arm it.
|
|
145
152
|
- An optional top-level `baseRef` selects the safe Git ref used by managed worktrees (default `HEAD`); it is persisted with the schedule and forwarded on every fire. The source checkout must still be clean.
|
|
146
153
|
- Definitions, bounded history, append-only events, and per-run receipts are stored with mode `0600`.
|
|
147
154
|
- `overlap` is currently fixed to `skip`; `catchUp` supports `latest` (default) and `none`.
|
package/docs/models.md
CHANGED
|
@@ -220,7 +220,7 @@ Model scope is policy only. It rejects or warns; it does not select a cheaper mo
|
|
|
220
220
|
|
|
221
221
|
`inherit` and `scoped` expand in the parent process at each launch. They are never sent to the child as model ids. A nested child therefore inherits its immediate parent's current model, not the original top-level model. `scoped` uses the scoped-model set at launch, so a mid-session `/scoped-models` change applies to the next child; background runs keep the set captured when the run started. Pi reports an empty set when the session is unscoped, either because nothing is configured or because no configured pattern matches an available model, and then lets the parent use every model. In that case `scoped` behaves exactly as `inherit`, which is narrower. If no parent model is available, an enforced `inherit` or `scoped` entry does not match and fails closed.
|
|
222
222
|
|
|
223
|
-
Project `modelScope` settings replace the complete user `modelScope`, as with the existing project-over-user settings precedence.
|
|
223
|
+
Project `modelScope` settings replace the complete user `modelScope`, as with the existing project-over-user settings precedence. This applies only when the session trusts the project: when project trust is declined, project subagent settings are ignored and the user `modelScope` applies.
|
|
224
224
|
|
|
225
225
|
## Profiles and provider model catalogs
|
|
226
226
|
|
package/docs/observability.md
CHANGED
|
@@ -29,6 +29,8 @@ subagent({ action: "status", id: "..." }) // one run
|
|
|
29
29
|
|
|
30
30
|
Or ask naturally: "Show me the current async runs."
|
|
31
31
|
|
|
32
|
+
In a terminal that supports [OSC 7501](https://www.superlogical.com/rex/docs/build/program-status), each background run is also reported to the terminal as working, waiting on you, finished, or failed. See [`programStatus`](configuration.md#programstatus).
|
|
33
|
+
|
|
32
34
|
### Usage and cost accounting
|
|
33
35
|
|
|
34
36
|
Run `/subagent-cost` for the parent session's combined parent and child token usage and cost. It includes completed async workflow children when their persisted receipts and metadata remain available. Missing child metadata is reported as unavailable when the receipt identifies that child. If the workflow receipt itself is missing, unreadable, invalid, or non-terminal, affected children can be omitted from the total without an unavailable count, so treat the result as a lower bound when run artifacts are unavailable.
|
|
@@ -46,7 +48,7 @@ async subagent worker · background
|
|
|
46
48
|
Press configured-expand-key for live detail
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
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.
|
|
51
|
+
To inspect one background child in text, use `subagent({ action: "status", id: "...", options: { view: "transcript" } })`; add `index` for a specific child in a parallel or chain run.
|
|
50
52
|
|
|
51
53
|
In Pi fullscreen mode with mouse dispatch, left-click
|
|
52
54
|
anywhere on the async widget's header row to fold it into a live one-line status
|
|
@@ -79,6 +81,7 @@ For compact chat results with FleetView as the only live editor surface, merge t
|
|
|
79
81
|
- `fleetView: true` retains live progress. Open `/subagents-fleet` for details instead of repeatedly requesting status just to watch progress. Pi's expand key does not expand summary results; keep `"rich"` if you want expandable inline output.
|
|
80
82
|
- `asyncWidget: false` hides only the additional under-editor async widget, leaving FleetView available. This configuration reduces visible surfaces; it does not guarantee ordering relative to other extensions.
|
|
81
83
|
- `asyncWidgetCollapsed: true` starts each newly mounted async widget as a one-line live status summary; click its header to expand it.
|
|
84
|
+
- `asyncWidgetLayout: "rows"` shows each run in the async widget as one line under a header instead of a block of detail rows; Pi's expand key still shows the details.
|
|
82
85
|
|
|
83
86
|
Thanks to [DraconDev](https://github.com/DraconDev) for reporting the display noise and suggesting summary mode in [#1931](https://github.com/nicobailon/pi-subagents/issues/1931).
|
|
84
87
|
|
|
@@ -123,11 +126,11 @@ Default keys:
|
|
|
123
126
|
|
|
124
127
|
Set `fleetKeybindings` in the extension config to replace inspector-level keys when a terminal intercepts keys such as `PgUp`, `PgDn`, `Home`, or `End`. Prompt modes keep fixed keys such as `Esc`, `Enter`, `Tab`, and stop-confirmation `Y`/`N`.
|
|
125
128
|
|
|
126
|
-
Enter and `H` use the available Inspect plugin. On macOS with Ghostty 1.3+ (TERM_PROGRAM=ghostty), this includes the other bundled open-only plugin using Ghostty's preview AppleScript API; status and close are unavailable because no binding is written. In a child-specific inspector, type ordinary guidance and press Enter to send it through the acknowledged steer channel; `steer <message>`, `status`, and `stop` remain available as explicit controls. The bundled Herdr plugin uses Herdr 0.7.5+.
|
|
129
|
+
Enter and `H` use the available Inspect plugin. Inside tmux, this includes the bundled tmux plugin: it splits the focused window, runs the inspector pane there, and records a binding, so `status` and `close` are available and ordinary tmux keys such as the prefix keep working in the pane. On macOS with Ghostty 1.3+ (TERM_PROGRAM=ghostty), this includes the other bundled open-only plugin using Ghostty's preview AppleScript API; status and close are unavailable because no binding is written. In a child-specific inspector, type ordinary guidance and press Enter to send it through the acknowledged steer channel; `steer <message>`, `status`, and `stop` remain available as explicit controls. The bundled Herdr plugin uses Herdr 0.7.5+.
|
|
127
130
|
|
|
128
|
-
Without a TUI, `/subagents-fleet` retains the textual `subagent({ action: "status", view: "fleet" })` fallback, and mutations use explicit commands: run `/subagents-stop` and pick from the selector, or use `/subagents-stop <run-id>` / `subagent({ action: "stop", id: "..." })` when you already know the id.
|
|
131
|
+
Without a TUI, `/subagents-fleet` retains the textual `subagent({ action: "status", options: { view: "fleet" } })` fallback, and mutations use explicit commands: run `/subagents-stop` and pick from the selector, or use `/subagents-stop <run-id>` / `subagent({ action: "stop", id: "..." })` when you already know the id.
|
|
129
132
|
|
|
130
|
-
Use `/subagents-detach [run-id]` only for an active foreground single-subagent run you want to leave running without terminating; the eventual result remains available through status/wait.
|
|
133
|
+
Use `/subagents-detach [run-id]` only for an active foreground single-subagent run you want to leave running without terminating; the eventual result remains available through status/wait. A detached foreground child runs inside the current pi-subagents runtime. When `/reload`, a session resume, or a session switch replaces that runtime, the child is stopped, and `status` then shows it as stopped with the reason. `resume` continues it from its session.
|
|
131
134
|
|
|
132
135
|
Set `foregroundDetachShortcut` in `~/.pi/agent/extensions/subagent/config.json` to bind the same action to a shortcut. The running foreground card shows the configured shortcut beside its live-detail hint:
|
|
133
136
|
|
|
@@ -295,7 +298,7 @@ Debug artifacts live under `{sessionDir}/subagent-artifacts/`, `.pi/subagents/ar
|
|
|
295
298
|
- `{runId}_{agent}.jsonl`
|
|
296
299
|
- `{runId}_{agent}_meta.json`
|
|
297
300
|
|
|
298
|
-
Metadata records timing, usage, exit code, the resolved model, and the resolved acceptance ledger with its parsed child report. A strictly guarded retained-session recovery after a verified compaction abort may continue once on that same model; it never selects another model.
|
|
301
|
+
Metadata records the parent session id, timing, usage, exit code, the resolved model, and the resolved acceptance ledger with its parsed child report. A strictly guarded retained-session recovery after a verified compaction abort may continue once on that same model; it never selects another model.
|
|
299
302
|
|
|
300
303
|
For npm package projects, project-scoped artifacts need a `.npmignore` rule (or `.gitignore` when no `.npmignore` exists) or a `files` allowlist that does not include `.pi/subagents/`. pi-subagents warns at launch when these package settings can include the artifacts. Use `artifactDir: "session"` or `"temp"` to keep them outside the package worktree.
|
|
301
304
|
|
|
@@ -303,6 +306,8 @@ For npm package projects, project-scoped artifacts need a `.npmignore` rule (or
|
|
|
303
306
|
|
|
304
307
|
Session files are stored under a per-run session directory. With `context: "fork"`, each child starts from a branched session file produced from the parent's current leaf (foreground children open it in-process; background children receive it as `--session`). That is a real session fork, not an injected summary. An omitted launch `context` that resolves through `defaultContext: fork` uses the same branch when the parent session file and current leaf exist, and otherwise starts fresh.
|
|
305
308
|
|
|
309
|
+
A child session's header records the launching session's file as `parentSession`, the field Pi uses for its own forks, so a reader can find the parent session without parsing the directory layout. A nested child points at the session of the child that launched it. Run metadata (`{runId}_{agent}_meta.json`) also records `parentSessionId`, the launching session's id.
|
|
310
|
+
|
|
306
311
|
## Completion notifications
|
|
307
312
|
|
|
308
313
|
Async completions belong only to the originating session. The result watcher emits `subagent:async-complete` for detached runs. Awaited workflow children emit it when they settle, with `awaitedByWorkflow: true`, `parentWorkflowRunId`, and `triggerTurn: false`. They do not send a separate child notification or turn.
|