@selesai/code 0.5.20 → 0.5.21
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/dist/extensions/handoff-new.test.ts +8 -9
- package/dist/extensions/handoff-new.ts +6 -8
- package/dist/extensions/pi-subagents/CHANGELOG.md +1367 -0
- package/dist/extensions/pi-subagents/README.md +602 -220
- package/dist/extensions/pi-subagents/banner.png +0 -0
- package/dist/extensions/pi-subagents/index.ts +1 -0
- package/dist/extensions/pi-subagents/install.mjs +3 -3
- package/dist/extensions/pi-subagents/package-lock.json +3405 -0
- package/dist/extensions/pi-subagents/package.json +26 -14
- package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +3 -3
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +7 -7
- package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
- package/dist/extensions/pi-subagents/prompts/review-loop.md +13 -11
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +267 -176
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +89 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +218 -120
- package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +67 -13
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
- package/dist/extensions/pi-subagents/src/agents/skills.ts +25 -12
- package/dist/extensions/pi-subagents/src/api/background-work.ts +197 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +17 -0
- package/dist/extensions/pi-subagents/src/api/delegation.ts +285 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +399 -0
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +165 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +7 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +15 -0
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +113 -157
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +41 -4
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +45 -15
- package/dist/extensions/pi-subagents/src/extension/steering-notices.ts +35 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -15
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -3
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +225 -29
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +11 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -10
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +452 -62
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +60 -9
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +198 -52
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +119 -21
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +67 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +16 -8
- package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +6 -4
- package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +2 -11
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +260 -13
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +32 -6
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +171 -90
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +280 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +149 -88
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +14 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +33 -17
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +9 -1
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +38 -10
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +237 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +1297 -307
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +610 -0
- package/dist/extensions/pi-subagents/src/runs/background/top-level-async.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +26 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +230 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +22 -6
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +228 -140
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +452 -138
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +90 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1001 -416
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +443 -132
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +38 -0
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +178 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +121 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +41 -93
- package/dist/extensions/pi-subagents/src/runs/shared/context-mode.ts +44 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +11 -9
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +44 -7
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +154 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +174 -54
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +38 -31
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +90 -5
- package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +299 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +61 -6
- package/dist/extensions/pi-subagents/src/runs/shared/spawn-budget.ts +128 -0
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +112 -7
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +14 -6
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +149 -36
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +181 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +83 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +11 -5
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +50 -4
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +63 -14
- package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +25 -0
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +37 -7
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +18 -43
- package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +52 -0
- package/dist/extensions/pi-subagents/src/shared/env.ts +16 -0
- package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +47 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +28 -3
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +123 -0
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +8 -5
- package/dist/extensions/pi-subagents/src/shared/settings.ts +9 -1
- package/dist/extensions/pi-subagents/src/shared/status-format.ts +7 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +522 -51
- package/dist/extensions/pi-subagents/src/shared/utils.ts +59 -53
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +604 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-json.ts +108 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +249 -0
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +353 -345
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/selector.ts +147 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +265 -23
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +428 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +362 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +472 -0
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +664 -0
- package/dist/extensions/pi-subagents/src/tui/render.ts +115 -31
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +220 -0
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +205 -0
- package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +123 -0
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +532 -0
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +167 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +117 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +433 -0
- package/dist/extensions/pi-subagents/src/watchdog/render.ts +54 -0
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +298 -0
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +714 -0
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +528 -0
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +155 -0
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +161 -0
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +188 -0
- package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +73 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +130 -2
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +439 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1632 -61
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +54 -1
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +98 -1
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +179 -9
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +16 -9
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +6 -5
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +589 -9
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +528 -21
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +227 -3
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +235 -7
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +172 -2
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1502 -18
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +993 -4
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +7 -1
- package/dist/extensions/pi-subagents/test/support/helpers.ts +32 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +59 -2
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +32 -6
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +25 -24
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +59 -35
- package/dist/extensions/pi-subagents/test/support/session-lease-child.mjs +42 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +703 -69
- package/dist/extensions/pi-subagents/test/unit/accessible-dir.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +478 -19
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +228 -7
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +198 -78
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +15 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +102 -7
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +439 -6
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +285 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +46 -4
- package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +9 -17
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +175 -3
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +10 -5
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +126 -6
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +219 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +913 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +13 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +280 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +575 -0
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +65 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +94 -1
- package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +157 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +367 -5
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +11 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +25 -3
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +341 -10
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +16 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +168 -7
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +85 -7
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +243 -16
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +79 -36
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +174 -56
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +322 -0
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +204 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +20 -12
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +117 -4
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +40 -7
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +48 -1
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +21 -3
- package/dist/extensions/pi-subagents/test/unit/selector.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +101 -2
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +111 -1
- package/dist/extensions/pi-subagents/test/unit/spawn-budget.test.ts +124 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +6 -4
- package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +7 -0
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +397 -0
- package/dist/extensions/pi-subagents/test/unit/steering-notices.test.ts +58 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +173 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +25 -4
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +390 -25
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +837 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +47 -1
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +56 -10
- package/dist/extensions/pi-subagents/test/unit/watchdog-change-signature.test.ts +387 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +110 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-emission-guard.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-model-selection.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +76 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +327 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +863 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +290 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +91 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +130 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +32 -4
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +5 -1
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +30 -0
- package/dist/extensions/question/batch.ts +39 -0
- package/dist/extensions/question/dialog-adapter.ts +23 -1
- package/dist/extensions/question/index.ts +237 -7
- package/dist/extensions/question/schemas.ts +28 -15
- package/dist/extensions/question/tests/batch.test.ts +26 -0
- package/dist/extensions/question/tests/ui-protocol.test.ts +23 -3
- package/dist/extensions/question/tui-adapter.ts +2 -3
- package/dist/extensions/question/types.ts +37 -0
- package/dist/extensions/question/ui-protocol.ts +3 -3
- package/dist/skills/batch-grill-me/SKILL.md +3 -1
- package/package.json +1 -1
|
@@ -87,7 +87,7 @@ function parseSkill(value: string | undefined): string | string[] | false | unde
|
|
|
87
87
|
|
|
88
88
|
function parseAgent(frontmatter: Record<string, string>): string {
|
|
89
89
|
const subagent = stringField(frontmatter, "subagent");
|
|
90
|
-
if (!subagent || subagent === "true") return "
|
|
90
|
+
if (!subagent || subagent === "true") return "builder";
|
|
91
91
|
return subagent;
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -240,7 +240,7 @@ function workflowParams(workflow: PromptWorkflow, args: string[], runtime: Retur
|
|
|
240
240
|
function workflowChainStep(workflow: PromptWorkflow, args: string[], runtime: ReturnType<typeof parseRuntimeOptions>): ChainStep {
|
|
241
241
|
const params = workflowParams(workflow, args, runtime);
|
|
242
242
|
return {
|
|
243
|
-
agent: params.agent ?? "
|
|
243
|
+
agent: params.agent ?? "builder",
|
|
244
244
|
task: params.task,
|
|
245
245
|
...(params.model ? { model: params.model } : {}),
|
|
246
246
|
...(params.skill !== undefined ? { skill: params.skill } : {}),
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { DynamicBorder, keyHint, rawKeyHint, type Theme } from "@selesai/code";
|
|
2
|
+
import { Container, fuzzyFilter, Input, type KeybindingsManager, Spacer, Text, type TUI } from "@earendil-works/pi-tui";
|
|
3
|
+
|
|
4
|
+
/** A single selectable row. `value` is returned on confirm; `label` is the primary text. */
|
|
5
|
+
export interface SelectorItem {
|
|
6
|
+
value: string;
|
|
7
|
+
label: string;
|
|
8
|
+
/** Optional dimmed badge shown after the label (e.g. a provider name). */
|
|
9
|
+
badge?: string;
|
|
10
|
+
/** Marks the current selection (rendered with a ✓ checkmark). */
|
|
11
|
+
current?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface SelectorResult {
|
|
15
|
+
confirmed: boolean;
|
|
16
|
+
value?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface SelectorOptions {
|
|
20
|
+
title: string;
|
|
21
|
+
/** Optional dimmed hint line under the title (e.g. the current value). */
|
|
22
|
+
subtitle?: string;
|
|
23
|
+
items: SelectorItem[];
|
|
24
|
+
done: (result: SelectorResult) => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const MAX_VISIBLE = 10;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A single-select list with a search field and a bounded scroll window that keeps the
|
|
31
|
+
* highlighted row on screen with an `(n/total)` indicator, so the selection never scrolls
|
|
32
|
+
* out of view when the option list is long. Composed from pi's own TUI primitives so it
|
|
33
|
+
* matches the built-in `/model` picker.
|
|
34
|
+
*
|
|
35
|
+
* Colors come from the `theme` passed to the factory: the module-level `theme` singleton
|
|
36
|
+
* is undefined under the extension's jiti module cache.
|
|
37
|
+
*/
|
|
38
|
+
export class SelectorComponent extends Container {
|
|
39
|
+
private readonly tui: TUI;
|
|
40
|
+
private readonly theme: Theme;
|
|
41
|
+
private readonly keybindings: KeybindingsManager;
|
|
42
|
+
private readonly items: SelectorItem[];
|
|
43
|
+
private readonly done: (result: SelectorResult) => void;
|
|
44
|
+
|
|
45
|
+
private readonly searchInput: Input;
|
|
46
|
+
private readonly listContainer: Container;
|
|
47
|
+
private filtered: SelectorItem[];
|
|
48
|
+
private selectedIndex = 0;
|
|
49
|
+
|
|
50
|
+
constructor(tui: TUI, theme: Theme, keybindings: KeybindingsManager, options: SelectorOptions) {
|
|
51
|
+
super();
|
|
52
|
+
this.tui = tui;
|
|
53
|
+
this.theme = theme;
|
|
54
|
+
this.keybindings = keybindings;
|
|
55
|
+
this.items = options.items;
|
|
56
|
+
this.done = options.done;
|
|
57
|
+
this.filtered = [...this.items];
|
|
58
|
+
|
|
59
|
+
const border = () => new DynamicBorder((str) => theme.fg("border", str));
|
|
60
|
+
this.addChild(border());
|
|
61
|
+
this.addChild(new Spacer(1));
|
|
62
|
+
this.addChild(new Text(theme.fg("accent", theme.bold(options.title)), 0, 0));
|
|
63
|
+
if (options.subtitle) this.addChild(new Text(theme.fg("muted", options.subtitle), 0, 0));
|
|
64
|
+
this.addChild(new Spacer(1));
|
|
65
|
+
|
|
66
|
+
this.searchInput = new Input();
|
|
67
|
+
this.searchInput.focused = true;
|
|
68
|
+
this.searchInput.onSubmit = () => this.confirmSelection();
|
|
69
|
+
this.addChild(this.searchInput);
|
|
70
|
+
this.addChild(new Spacer(1));
|
|
71
|
+
|
|
72
|
+
this.listContainer = new Container();
|
|
73
|
+
this.addChild(this.listContainer);
|
|
74
|
+
this.addChild(new Spacer(1));
|
|
75
|
+
|
|
76
|
+
this.addChild(new Text(rawKeyHint("↑↓", "navigate") + " " + keyHint("tui.select.confirm", "select") + " " + keyHint("tui.select.cancel", "cancel"), 0, 0));
|
|
77
|
+
this.addChild(new Spacer(1));
|
|
78
|
+
this.addChild(border());
|
|
79
|
+
|
|
80
|
+
const currentIndex = this.filtered.findIndex((item) => item.current);
|
|
81
|
+
if (currentIndex >= 0) this.selectedIndex = currentIndex;
|
|
82
|
+
this.updateList();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private applyFilter(query: string): void {
|
|
86
|
+
const previous = this.filtered[this.selectedIndex]?.value;
|
|
87
|
+
this.filtered = query
|
|
88
|
+
? fuzzyFilter(this.items, query, (item) => `${item.label} ${item.value} ${item.badge ?? ""}`)
|
|
89
|
+
: [...this.items];
|
|
90
|
+
const keepIndex = this.filtered.findIndex((item) => item.value === previous);
|
|
91
|
+
this.selectedIndex = keepIndex >= 0 ? keepIndex : Math.min(this.selectedIndex, Math.max(0, this.filtered.length - 1));
|
|
92
|
+
this.updateList();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private updateList(): void {
|
|
96
|
+
const th = this.theme;
|
|
97
|
+
this.listContainer.clear();
|
|
98
|
+
const startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(MAX_VISIBLE / 2), this.filtered.length - MAX_VISIBLE));
|
|
99
|
+
const endIndex = Math.min(startIndex + MAX_VISIBLE, this.filtered.length);
|
|
100
|
+
|
|
101
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
102
|
+
const item = this.filtered[i]!;
|
|
103
|
+
const isSelected = i === this.selectedIndex;
|
|
104
|
+
const badge = item.badge ? ` ${th.fg("muted", `[${item.badge}]`)}` : "";
|
|
105
|
+
const checkmark = item.current ? th.fg("success", " ✓") : "";
|
|
106
|
+
const line = isSelected
|
|
107
|
+
? `${th.fg("accent", "→ ")}${th.fg("accent", item.label)}${badge}${checkmark}`
|
|
108
|
+
: ` ${item.label}${badge}${checkmark}`;
|
|
109
|
+
this.listContainer.addChild(new Text(line, 0, 0));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (startIndex > 0 || endIndex < this.filtered.length) {
|
|
113
|
+
this.listContainer.addChild(new Text(th.fg("muted", ` (${this.selectedIndex + 1}/${this.filtered.length})`), 0, 0));
|
|
114
|
+
}
|
|
115
|
+
if (this.filtered.length === 0) {
|
|
116
|
+
this.listContainer.addChild(new Text(th.fg("muted", " No matching entries"), 0, 0));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private confirmSelection(): void {
|
|
121
|
+
const selected = this.filtered[this.selectedIndex];
|
|
122
|
+
this.done(selected ? { confirmed: true, value: selected.value } : { confirmed: false });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
handleInput(keyData: string): void {
|
|
126
|
+
const kb = this.keybindings;
|
|
127
|
+
if (kb.matches(keyData, "tui.select.up")) {
|
|
128
|
+
if (this.filtered.length === 0) return;
|
|
129
|
+
this.selectedIndex = this.selectedIndex === 0 ? this.filtered.length - 1 : this.selectedIndex - 1;
|
|
130
|
+
this.updateList();
|
|
131
|
+
this.tui.requestRender();
|
|
132
|
+
} else if (kb.matches(keyData, "tui.select.down")) {
|
|
133
|
+
if (this.filtered.length === 0) return;
|
|
134
|
+
this.selectedIndex = this.selectedIndex === this.filtered.length - 1 ? 0 : this.selectedIndex + 1;
|
|
135
|
+
this.updateList();
|
|
136
|
+
this.tui.requestRender();
|
|
137
|
+
} else if (kb.matches(keyData, "tui.select.confirm")) {
|
|
138
|
+
this.confirmSelection();
|
|
139
|
+
} else if (kb.matches(keyData, "tui.select.cancel")) {
|
|
140
|
+
this.done({ confirmed: false });
|
|
141
|
+
} else {
|
|
142
|
+
this.searchInput.handleInput(keyData);
|
|
143
|
+
this.applyFilter(this.searchInput.getValue());
|
|
144
|
+
this.tui.requestRender();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { keyText, type ExtensionAPI, type ExtensionContext } from "@selesai/code";
|
|
5
|
-
import { Key, matchesKey } from "@earendil-works/pi-tui";
|
|
5
|
+
import { Key, matchesKey, type Component, type TUI } from "@earendil-works/pi-tui";
|
|
6
6
|
import { BUILTIN_AGENT_NAMES, discoverAgents, discoverAgentsAll, type ChainConfig } from "../agents/agents.ts";
|
|
7
7
|
import {
|
|
8
8
|
DEFAULT_PROVIDER_MODELS_MAX_AGE_DAYS,
|
|
@@ -16,11 +16,16 @@ import {
|
|
|
16
16
|
import type { SubagentParamsLike } from "../runs/foreground/subagent-executor.ts";
|
|
17
17
|
import { isDynamicParallelStep, isParallelStep, type ChainStep } from "../shared/settings.ts";
|
|
18
18
|
import { findModelInfo, toModelInfo } from "../shared/model-info.ts";
|
|
19
|
-
import { formatTokens } from "../shared/formatters.ts";
|
|
19
|
+
import { formatTokens, shortenPath } from "../shared/formatters.ts";
|
|
20
|
+
import { listAsyncRuns, formatAsyncRunProgressLabel, type AsyncRunSummary } from "../runs/background/async-status.ts";
|
|
21
|
+
import { scheduledRunStorePath } from "../runs/background/scheduled-runs.ts";
|
|
22
|
+
import { SUBAGENT_FANOUT_CHILD_ENV } from "../runs/shared/pi-args.ts";
|
|
20
23
|
import { assertJsonSchemaObject } from "../runs/shared/structured-output.ts";
|
|
21
24
|
import { validateAcceptanceInput } from "../runs/shared/acceptance.ts";
|
|
22
25
|
import type { SlashSubagentResponse, SlashSubagentUpdate } from "./slash-bridge.ts";
|
|
23
26
|
import { registerPromptWorkflowCommands } from "./prompt-workflows.ts";
|
|
27
|
+
import { openSubagentsAdmin } from "./subagents-admin.ts";
|
|
28
|
+
import { openSubagentFleet } from "../tui/fleet.ts";
|
|
24
29
|
import {
|
|
25
30
|
applySlashUpdate,
|
|
26
31
|
buildSlashInitialResult,
|
|
@@ -36,6 +41,7 @@ import {
|
|
|
36
41
|
SLASH_SUBAGENT_RESPONSE_EVENT,
|
|
37
42
|
SLASH_SUBAGENT_STARTED_EVENT,
|
|
38
43
|
SLASH_SUBAGENT_UPDATE_EVENT,
|
|
44
|
+
ASYNC_DIR,
|
|
39
45
|
type Details,
|
|
40
46
|
type JsonSchemaObject,
|
|
41
47
|
type SingleResult,
|
|
@@ -221,6 +227,160 @@ async function withSlashStatus<T>(
|
|
|
221
227
|
}
|
|
222
228
|
}
|
|
223
229
|
|
|
230
|
+
type Theme = ExtensionContext["ui"]["theme"];
|
|
231
|
+
|
|
232
|
+
type StopSelectorTarget = {
|
|
233
|
+
kind: "async" | "scheduled";
|
|
234
|
+
id: string;
|
|
235
|
+
label: string;
|
|
236
|
+
detail: string;
|
|
237
|
+
actionLabel: string;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
type StopSelectorResult = { confirmed: boolean; target?: StopSelectorTarget };
|
|
241
|
+
|
|
242
|
+
function commandForTarget(target: StopSelectorTarget): string {
|
|
243
|
+
return target.kind === "scheduled"
|
|
244
|
+
? `subagent({ action: "schedule-cancel", id: ${JSON.stringify(target.id)} })`
|
|
245
|
+
: `subagent({ action: "stop", id: ${JSON.stringify(target.id)} })`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function formatAsyncStopTarget(run: AsyncRunSummary): StopSelectorTarget {
|
|
249
|
+
const progress = formatAsyncRunProgressLabel(run);
|
|
250
|
+
const cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);
|
|
251
|
+
return {
|
|
252
|
+
kind: "async",
|
|
253
|
+
id: run.id,
|
|
254
|
+
label: `${run.id} · ${run.mode} · ${progress}`,
|
|
255
|
+
detail: `${run.state} · ${cwd}`,
|
|
256
|
+
actionLabel: "stop async run",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function scheduledStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {
|
|
261
|
+
const sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId();
|
|
262
|
+
if (!sessionId) return [];
|
|
263
|
+
const storePath = scheduledRunStorePath(ctx.cwd, sessionId);
|
|
264
|
+
if (!fs.existsSync(storePath)) return [];
|
|
265
|
+
let parsed: unknown;
|
|
266
|
+
try {
|
|
267
|
+
parsed = JSON.parse(fs.readFileSync(storePath, "utf-8"));
|
|
268
|
+
} catch {
|
|
269
|
+
return [];
|
|
270
|
+
}
|
|
271
|
+
const jobs = parsed && typeof parsed === "object" && Array.isArray((parsed as { jobs?: unknown }).jobs)
|
|
272
|
+
? (parsed as { jobs: Array<Record<string, unknown>> }).jobs
|
|
273
|
+
: [];
|
|
274
|
+
return jobs
|
|
275
|
+
.filter((job) => job.state === "scheduled" && typeof job.id === "string" && typeof job.name === "string" && typeof job.runAt === "number")
|
|
276
|
+
.sort((left, right) => Number(left.runAt) - Number(right.runAt))
|
|
277
|
+
.map((job) => ({
|
|
278
|
+
kind: "scheduled" as const,
|
|
279
|
+
id: String(job.id),
|
|
280
|
+
label: `${String(job.id)} · ${String(job.name)}`,
|
|
281
|
+
detail: `scheduled · ${new Date(Number(job.runAt)).toISOString()}`,
|
|
282
|
+
actionLabel: "cancel scheduled run",
|
|
283
|
+
}));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function discoverStopTargets(ctx: ExtensionContext, state: SubagentState): StopSelectorTarget[] {
|
|
287
|
+
const sessionId = state.currentSessionId ?? ctx.sessionManager.getSessionId() ?? undefined;
|
|
288
|
+
const asyncTargets = listAsyncRuns(ASYNC_DIR, {
|
|
289
|
+
states: ["queued", "running"],
|
|
290
|
+
...(sessionId ? { sessionId } : {}),
|
|
291
|
+
}).map(formatAsyncStopTarget);
|
|
292
|
+
return [...asyncTargets, ...scheduledStopTargets(ctx, state)];
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function stopFallbackText(targets: StopSelectorTarget[]): string {
|
|
296
|
+
if (targets.length === 0) return "No active current-session async runs or scheduled subagent runs to stop.";
|
|
297
|
+
const lines = ["Subagent stop targets:", ""];
|
|
298
|
+
for (const target of targets) {
|
|
299
|
+
lines.push(`- ${target.label}`);
|
|
300
|
+
lines.push(` ${target.detail}`);
|
|
301
|
+
lines.push(` ${target.actionLabel}: ${commandForTarget(target)}`);
|
|
302
|
+
if (target.kind === "async") lines.push(` slash: /subagents-stop ${target.id}`);
|
|
303
|
+
}
|
|
304
|
+
return lines.join("\n");
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
class SubagentsStopSelector implements Component {
|
|
308
|
+
readonly width = 84;
|
|
309
|
+
private selected = 0;
|
|
310
|
+
private confirming = false;
|
|
311
|
+
private readonly tui: TUI;
|
|
312
|
+
private readonly theme: Theme;
|
|
313
|
+
private readonly targets: StopSelectorTarget[];
|
|
314
|
+
private readonly done: (result: StopSelectorResult) => void;
|
|
315
|
+
|
|
316
|
+
constructor(tui: TUI, theme: Theme, targets: StopSelectorTarget[], done: (result: StopSelectorResult) => void) {
|
|
317
|
+
this.tui = tui;
|
|
318
|
+
this.theme = theme;
|
|
319
|
+
this.targets = targets;
|
|
320
|
+
this.done = done;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
handleInput(data: string): void {
|
|
324
|
+
if (matchesKey(data, "escape") || matchesKey(data, "ctrl+c")) {
|
|
325
|
+
this.done({ confirmed: false });
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (this.confirming) {
|
|
329
|
+
if (matchesKey(data, "return") || data.toLowerCase() === "y") {
|
|
330
|
+
this.done({ confirmed: true, target: this.targets[this.selected] });
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (data.toLowerCase() === "n" || matchesKey(data, "backspace")) {
|
|
334
|
+
this.confirming = false;
|
|
335
|
+
this.tui.requestRender();
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
if (matchesKey(data, "up")) {
|
|
340
|
+
this.selected = Math.max(0, this.selected - 1);
|
|
341
|
+
this.tui.requestRender();
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (matchesKey(data, "down")) {
|
|
345
|
+
this.selected = Math.min(this.targets.length - 1, this.selected + 1);
|
|
346
|
+
this.tui.requestRender();
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (matchesKey(data, "return")) {
|
|
350
|
+
this.confirming = true;
|
|
351
|
+
this.tui.requestRender();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
render(width: number): string[] {
|
|
356
|
+
const contentWidth = Math.max(40, Math.min(this.width, width || this.width));
|
|
357
|
+
const lines = [this.theme.bold("Stop subagent run"), this.theme.fg("dim", "Select a current-session async run to stop, or a scheduled run to cancel."), ""];
|
|
358
|
+
const maxRows = 10;
|
|
359
|
+
const start = Math.max(0, Math.min(this.selected - maxRows + 1, Math.max(0, this.targets.length - maxRows)));
|
|
360
|
+
for (let index = start; index < Math.min(this.targets.length, start + maxRows); index++) {
|
|
361
|
+
const target = this.targets[index]!;
|
|
362
|
+
const selected = index === this.selected;
|
|
363
|
+
const marker = selected ? "›" : " ";
|
|
364
|
+
const actionLabel = target.actionLabel;
|
|
365
|
+
const action = target.kind === "scheduled" ? this.theme.fg("warning", actionLabel) : this.theme.fg("accent", actionLabel);
|
|
366
|
+
const labelWidth = Math.max(0, contentWidth - marker.length - actionLabel.length - 2);
|
|
367
|
+
lines.push(`${marker} ${action} ${target.label.slice(0, labelWidth)}`);
|
|
368
|
+
if (selected) lines.push(this.theme.fg("dim", ` ${target.detail}`.slice(0, contentWidth)));
|
|
369
|
+
}
|
|
370
|
+
if (this.targets.length > maxRows) lines.push(this.theme.fg("dim", `Showing ${start + 1}-${Math.min(this.targets.length, start + maxRows)} of ${this.targets.length}`));
|
|
371
|
+
lines.push("");
|
|
372
|
+
if (this.confirming) {
|
|
373
|
+
const target = this.targets[this.selected]!;
|
|
374
|
+
lines.push(this.theme.fg("warning", `Confirm: ${target.actionLabel} ${target.id}?`));
|
|
375
|
+
if (target.kind === "async") lines.push(this.theme.fg("dim", "Stop ends this run; use interrupt for a resumable pause."));
|
|
376
|
+
lines.push(this.theme.fg("dim", "Enter/Y confirms · N returns · Esc cancels"));
|
|
377
|
+
} else {
|
|
378
|
+
lines.push(this.theme.fg("dim", "↑/↓ select · Enter confirm · Esc cancel"));
|
|
379
|
+
}
|
|
380
|
+
return lines;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
224
384
|
function emptyUsage(): Usage {
|
|
225
385
|
return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
|
|
226
386
|
}
|
|
@@ -334,8 +494,8 @@ function parseSingleRequiredArg(args: string, usage: string): { ok: true; value:
|
|
|
334
494
|
return { ok: true, value: parts[0]! };
|
|
335
495
|
}
|
|
336
496
|
|
|
337
|
-
function
|
|
338
|
-
const model = profile.subagents?.agentOverrides?.
|
|
497
|
+
function getProfileBuilderModel(profile: { subagents?: { agentOverrides?: Record<string, { model?: string }> } }): string | undefined {
|
|
498
|
+
const model = profile.subagents?.agentOverrides?.builder?.model;
|
|
339
499
|
return typeof model === "string" && model.trim() ? model.trim() : undefined;
|
|
340
500
|
}
|
|
341
501
|
|
|
@@ -577,6 +737,13 @@ async function runSlashSubagent(
|
|
|
577
737
|
}
|
|
578
738
|
}
|
|
579
739
|
|
|
740
|
+
function launchSlashSubagent(
|
|
741
|
+
pi: ExtensionAPI,
|
|
742
|
+
ctx: ExtensionContext,
|
|
743
|
+
params: SubagentParamsLike,
|
|
744
|
+
): void {
|
|
745
|
+
void runSlashSubagent(pi, ctx, params);
|
|
746
|
+
}
|
|
580
747
|
|
|
581
748
|
export interface GroupConfig { concurrency?: number; failFast?: boolean; worktree?: boolean }
|
|
582
749
|
export interface ParsedStep { kind: "step"; name: string; config: InlineConfig; task?: string }
|
|
@@ -841,7 +1008,7 @@ function validateInlineAcceptanceInput(value: string, agent: string): void {
|
|
|
841
1008
|
const errors = validateAcceptanceInput(value, `acceptance for step '${agent}'`);
|
|
842
1009
|
if (errors.length > 0) throw new SlashParseError(errors[0]!);
|
|
843
1010
|
if (!INLINE_ACCEPTANCE_LEVELS.has(value)) {
|
|
844
|
-
throw new SlashParseError(`Inline acceptance for step '${agent}' supports auto, attested, or checked. Use the subagent tool API or a saved .chain.json file for none, verified, or reviewed
|
|
1011
|
+
throw new SlashParseError(`Inline acceptance for step '${agent}' supports auto, attested, or checked. Use the subagent tool API or a saved .chain.json file for none, verified, or review requirements; reviewed is an achieved status, not an input level.`);
|
|
845
1012
|
}
|
|
846
1013
|
}
|
|
847
1014
|
|
|
@@ -977,6 +1144,32 @@ export function registerSlashCommands(
|
|
|
977
1144
|
pi: ExtensionAPI,
|
|
978
1145
|
state: SubagentState,
|
|
979
1146
|
): void {
|
|
1147
|
+
let fleetOpen = false;
|
|
1148
|
+
const showFleet = async (ctx: ExtensionContext) => {
|
|
1149
|
+
state.lastUiContext = ctx;
|
|
1150
|
+
if (!ctx.hasUI) {
|
|
1151
|
+
await runSlashSubagent(pi, ctx, { action: "status", view: "fleet" });
|
|
1152
|
+
return;
|
|
1153
|
+
}
|
|
1154
|
+
if (fleetOpen) {
|
|
1155
|
+
ctx.ui.notify("Subagent fleet inspector is already open.", "info");
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
fleetOpen = true;
|
|
1159
|
+
try {
|
|
1160
|
+
await openSubagentFleet(ctx, state);
|
|
1161
|
+
} finally {
|
|
1162
|
+
fleetOpen = false;
|
|
1163
|
+
}
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
pi.registerCommand("subagents", {
|
|
1167
|
+
description: "Administer subagents: inspect metadata and update models, thinking, or prompts",
|
|
1168
|
+
handler: async (args, ctx) => {
|
|
1169
|
+
await openSubagentsAdmin(pi, ctx, args);
|
|
1170
|
+
},
|
|
1171
|
+
});
|
|
1172
|
+
|
|
980
1173
|
pi.registerCommand("run", {
|
|
981
1174
|
description: "Run a subagent directly: /run agent[output=file] [task] [--bg] [--fork]",
|
|
982
1175
|
getArgumentCompletions: makeAgentCompletions(state, false),
|
|
@@ -1003,12 +1196,12 @@ export function registerSlashCommands(
|
|
|
1003
1196
|
if (inline.model) params.model = inline.model;
|
|
1004
1197
|
if (bg) params.async = true;
|
|
1005
1198
|
if (fork) params.context = "fork";
|
|
1006
|
-
|
|
1199
|
+
launchSlashSubagent(pi, ctx, params);
|
|
1007
1200
|
},
|
|
1008
1201
|
});
|
|
1009
1202
|
|
|
1010
1203
|
pi.registerCommand("chain", {
|
|
1011
|
-
description: "Run agents in sequence: /chain
|
|
1204
|
+
description: "Run agents in sequence: /chain explorer \"task\" -> architect [--bg] [--fork]",
|
|
1012
1205
|
getArgumentCompletions: makeAgentCompletions(state, true),
|
|
1013
1206
|
handler: async (args, ctx) => {
|
|
1014
1207
|
const { args: cleanedArgs, bg, fork } = extractExecutionFlags(args);
|
|
@@ -1017,7 +1210,7 @@ export function registerSlashCommands(
|
|
|
1017
1210
|
const params: SubagentParamsLike = { chain: built.chain, task: built.task, clarify: false, agentScope: "both" };
|
|
1018
1211
|
if (bg) params.async = true;
|
|
1019
1212
|
if (fork) params.context = "fork";
|
|
1020
|
-
|
|
1213
|
+
launchSlashSubagent(pi, ctx, params);
|
|
1021
1214
|
},
|
|
1022
1215
|
});
|
|
1023
1216
|
|
|
@@ -1047,12 +1240,12 @@ export function registerSlashCommands(
|
|
|
1047
1240
|
const params: SubagentParamsLike = { chain: mapSavedChainSteps(chain), task, clarify: false, agentScope: "both" };
|
|
1048
1241
|
if (bg) params.async = true;
|
|
1049
1242
|
if (fork) params.context = "fork";
|
|
1050
|
-
|
|
1243
|
+
launchSlashSubagent(pi, ctx, params);
|
|
1051
1244
|
},
|
|
1052
1245
|
});
|
|
1053
1246
|
|
|
1054
1247
|
pi.registerCommand("parallel", {
|
|
1055
|
-
description: "Run agents in parallel: /parallel
|
|
1248
|
+
description: "Run agents in parallel: /parallel explorer \"task1\" -> commentator \"task2\" [--bg] [--fork]",
|
|
1056
1249
|
getArgumentCompletions: makeAgentCompletions(state, true),
|
|
1057
1250
|
handler: async (args, ctx) => {
|
|
1058
1251
|
const { args: cleanedArgs, bg, fork } = extractExecutionFlags(args);
|
|
@@ -1071,7 +1264,7 @@ export function registerSlashCommands(
|
|
|
1071
1264
|
const params: SubagentParamsLike = { tasks, clarify: false, agentScope: "both" };
|
|
1072
1265
|
if (bg) params.async = true;
|
|
1073
1266
|
if (fork) params.context = "fork";
|
|
1074
|
-
|
|
1267
|
+
launchSlashSubagent(pi, ctx, params);
|
|
1075
1268
|
},
|
|
1076
1269
|
});
|
|
1077
1270
|
|
|
@@ -1090,15 +1283,64 @@ export function registerSlashCommands(
|
|
|
1090
1283
|
});
|
|
1091
1284
|
|
|
1092
1285
|
pi.registerCommand("subagents-fleet", {
|
|
1093
|
-
description: "
|
|
1094
|
-
handler: async (_args, ctx) =>
|
|
1095
|
-
|
|
1286
|
+
description: "Open the live, inspection-only subagent fleet",
|
|
1287
|
+
handler: async (_args, ctx) => showFleet(ctx),
|
|
1288
|
+
});
|
|
1289
|
+
|
|
1290
|
+
pi.registerShortcut(Key.ctrlAlt("f"), {
|
|
1291
|
+
description: "Open subagent fleet inspector",
|
|
1292
|
+
handler: async (ctx) => showFleet(ctx),
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
pi.registerCommand("subagents-stop", {
|
|
1296
|
+
description: "Stop a current-session async subagent run",
|
|
1297
|
+
handler: async (args, ctx) => {
|
|
1298
|
+
const id = args.trim();
|
|
1299
|
+
if (id) {
|
|
1300
|
+
await runSlashSubagent(pi, ctx, { action: "stop", id });
|
|
1301
|
+
return;
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
if (process.env[SUBAGENT_FANOUT_CHILD_ENV] === "1") {
|
|
1305
|
+
sendSlashText(pi, "Selector unavailable in child-safe fanout mode. Pass an explicit current-session top-level async run id, for example `/subagents-stop <run-id>` or `subagent({ action: \"stop\", id: \"<run-id>\" })`.");
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
let targets: StopSelectorTarget[];
|
|
1310
|
+
try {
|
|
1311
|
+
targets = discoverStopTargets(ctx, state);
|
|
1312
|
+
} catch (error) {
|
|
1313
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1314
|
+
ctx.ui.notify(message, "error");
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
if (!ctx.hasUI) {
|
|
1318
|
+
sendSlashText(pi, stopFallbackText(targets));
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
if (targets.length === 0) {
|
|
1322
|
+
ctx.ui.notify("No active current-session async runs or scheduled subagent runs to stop.", "info");
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
const result = await ctx.ui.custom<StopSelectorResult>(
|
|
1327
|
+
(tui, theme, _kb, done) => new SubagentsStopSelector(tui, theme, targets, done),
|
|
1328
|
+
{ overlay: true, overlayOptions: { anchor: "center", width: 88, maxHeight: "80%" } },
|
|
1329
|
+
);
|
|
1330
|
+
if (!result?.confirmed || !result.target) return;
|
|
1331
|
+
if (result.target.kind === "scheduled") {
|
|
1332
|
+
await runSlashSubagent(pi, ctx, { action: "schedule-cancel", id: result.target.id });
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1335
|
+
await runSlashSubagent(pi, ctx, { action: "stop", id: result.target.id });
|
|
1096
1336
|
},
|
|
1097
1337
|
});
|
|
1098
1338
|
|
|
1099
1339
|
registerPromptWorkflowCommands({
|
|
1100
1340
|
pi,
|
|
1101
|
-
run: (params, ctx) =>
|
|
1341
|
+
run: async (params, ctx) => {
|
|
1342
|
+
launchSlashSubagent(pi, ctx, params);
|
|
1343
|
+
},
|
|
1102
1344
|
});
|
|
1103
1345
|
|
|
1104
1346
|
pi.registerCommand("subagents-models", {
|
|
@@ -1153,7 +1395,7 @@ export function registerSlashCommands(
|
|
|
1153
1395
|
try {
|
|
1154
1396
|
await withSlashStatus(ctx, `Loading profile ${parsed.value}…`, async () => {
|
|
1155
1397
|
const { profile } = readSubagentProfile(parsed.value);
|
|
1156
|
-
const
|
|
1398
|
+
const builderModel = getProfileBuilderModel(profile);
|
|
1157
1399
|
const result = applySubagentProfile(parsed.value);
|
|
1158
1400
|
const lines = [
|
|
1159
1401
|
`Loaded subagent profile: ${parsed.value}`,
|
|
@@ -1161,24 +1403,24 @@ export function registerSlashCommands(
|
|
|
1161
1403
|
`Updated: ${result.settingsPath}`,
|
|
1162
1404
|
];
|
|
1163
1405
|
|
|
1164
|
-
if (
|
|
1406
|
+
if (builderModel && typeof pi.setModel === "function" && typeof ctx.modelRegistry?.find === "function" && typeof ctx.modelRegistry?.getAvailable === "function") {
|
|
1165
1407
|
const shouldSwitch = await ctx.ui.confirm(
|
|
1166
1408
|
"",
|
|
1167
|
-
`Profile loaded. Also switch this session to the profile
|
|
1409
|
+
`Profile loaded. Also switch this session to the profile builder model?\n\n${builderModel}`,
|
|
1168
1410
|
);
|
|
1169
1411
|
if (shouldSwitch) {
|
|
1170
|
-
const modelInfo = findModelInfo(
|
|
1412
|
+
const modelInfo = findModelInfo(builderModel, ctx.modelRegistry.getAvailable().map(toModelInfo));
|
|
1171
1413
|
const model = modelInfo ? ctx.modelRegistry.find(modelInfo.provider, modelInfo.id) : undefined;
|
|
1172
1414
|
if (!modelInfo || !model) {
|
|
1173
|
-
lines.push(`Could not switch current session model: '${
|
|
1415
|
+
lines.push(`Could not switch current session model: '${builderModel}' is not available in the current model registry.`);
|
|
1174
1416
|
} else {
|
|
1175
1417
|
const success = await pi.setModel(model);
|
|
1176
1418
|
if (success) lines.push(`Current session model switched to: ${modelInfo.fullId}`);
|
|
1177
|
-
else lines.push(`Could not switch current session model to '${
|
|
1419
|
+
else lines.push(`Could not switch current session model to '${builderModel}': no API key or provider access is available.`);
|
|
1178
1420
|
}
|
|
1179
1421
|
}
|
|
1180
|
-
} else if (
|
|
1181
|
-
lines.push(`Profile
|
|
1422
|
+
} else if (builderModel) {
|
|
1423
|
+
lines.push(`Profile builder model: ${builderModel}`);
|
|
1182
1424
|
}
|
|
1183
1425
|
|
|
1184
1426
|
sendSlashText(pi, lines.join("\n"));
|
|
@@ -193,8 +193,8 @@ function cloneResultsWithProgress(
|
|
|
193
193
|
progress: NonNullable<Details["progress"]> | undefined,
|
|
194
194
|
): SingleResult[] {
|
|
195
195
|
return results.map((result, index) => {
|
|
196
|
-
const nextProgress = progress?.find((entry) => entry.index === index
|
|
197
|
-
|
|
196
|
+
const nextProgress = progress?.find((entry) => entry.index === index
|
|
197
|
+
|| (entry.index === undefined && entry.agent === result.agent))
|
|
198
198
|
?? result.progress;
|
|
199
199
|
return nextProgress ? { ...result, progress: nextProgress } : result;
|
|
200
200
|
});
|