@selesai/code 0.9.11 → 0.9.13
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 +17 -0
- package/dist/config.d.ts +4 -6
- package/dist/config.js +10 -14
- package/dist/core/agent-session.d.ts +0 -1
- package/dist/core/agent-session.js +3 -49
- package/dist/core/extensions/types.d.ts +0 -2
- package/dist/core/settings-manager.d.ts +0 -2
- package/dist/core/settings-manager.js +0 -3
- package/dist/core/tools/index.d.ts +0 -1
- package/dist/core/tools/index.js +0 -1
- package/dist/defaults/settings.json +2 -3
- package/dist/extensions/model-prompt-injector/index.test.ts +0 -10
- package/dist/extensions/model-prompt-injector/index.ts +0 -3
- package/dist/extensions/pi-intercom/CHANGELOG.md +53 -16
- package/dist/extensions/pi-intercom/README.md +41 -8
- package/dist/extensions/pi-intercom/banner.png +0 -0
- package/dist/extensions/pi-intercom/broker/broker.ts +498 -215
- package/dist/extensions/pi-intercom/broker/client.ts +39 -12
- package/dist/extensions/pi-intercom/broker/extension.test.ts +102 -3
- package/dist/extensions/pi-intercom/broker/paths.test.ts +2 -2
- package/dist/extensions/pi-intercom/broker/protocol.ts +26 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +5 -20
- package/dist/extensions/pi-intercom/config.test.ts +41 -0
- package/dist/extensions/pi-intercom/config.ts +21 -0
- package/dist/extensions/pi-intercom/extension-api.ts +40 -0
- package/dist/extensions/pi-intercom/index.ts +362 -26
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +819 -13
- package/dist/extensions/pi-intercom/package.json +1 -1
- package/dist/extensions/pi-intercom/project-agent.ts +2 -2
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +8 -110
- package/dist/extensions/pi-intercom/types.ts +32 -5
- package/dist/extensions/pi-intercom/ui/inline-message.ts +6 -0
- package/dist/extensions/pi-subagents/.github/assets/subagent-fleet-inspector.png +0 -0
- package/dist/extensions/pi-subagents/.github/workflows/release.yml +28 -0
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +51 -0
- package/dist/extensions/pi-subagents/.greptile/config.json +33 -0
- package/dist/extensions/pi-subagents/.greptile/files.json +8 -0
- package/dist/extensions/pi-subagents/.greptile/rules.md +16 -0
- package/dist/extensions/pi-subagents/CHANGELOG.md +309 -87
- package/dist/extensions/pi-subagents/README.md +15 -17
- package/dist/extensions/pi-subagents/agents/oracle.md +3 -1
- package/dist/extensions/pi-subagents/agents/researcher.md +32 -13
- package/dist/extensions/pi-subagents/agents/reviewer.md +13 -2
- package/dist/extensions/pi-subagents/agents/scout.md +2 -2
- package/dist/extensions/pi-subagents/agents/worker.md +2 -1
- package/dist/extensions/pi-subagents/async-retention-discovery-worker.mjs +180 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +106 -27
- package/dist/extensions/pi-subagents/docs/extension-api.md +85 -21
- package/dist/extensions/pi-subagents/docs/missions.md +41 -4
- package/dist/extensions/pi-subagents/docs/models.md +52 -9
- package/dist/extensions/pi-subagents/docs/observability.md +103 -16
- package/dist/extensions/pi-subagents/docs/tool-reference.md +60 -45
- package/dist/extensions/pi-subagents/docs/watchdog.md +60 -3
- package/dist/extensions/pi-subagents/docs/workflows.md +181 -7
- package/dist/extensions/pi-subagents/index.ts +10 -1
- package/dist/extensions/pi-subagents/install.mjs +4 -4
- package/dist/extensions/pi-subagents/package-lock.json +1483 -1470
- package/dist/extensions/pi-subagents/package.json +6 -3
- package/dist/extensions/pi-subagents/prompts/council.md +60 -0
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +5 -1
- package/dist/extensions/pi-subagents/prompts/review-loop.md +9 -5
- package/dist/extensions/pi-subagents/skills/council-mode/SKILL.md +254 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +18 -17
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +107 -140
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +44 -92
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +261 -368
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +6 -2
- package/dist/extensions/pi-subagents/src/agents/agents.ts +388 -85
- package/dist/extensions/pi-subagents/src/agents/builtin-names.ts +14 -0
- package/dist/extensions/pi-subagents/src/agents/runtime-agent-registry.ts +418 -0
- package/dist/extensions/pi-subagents/src/agents/skills.ts +1 -1
- package/dist/extensions/pi-subagents/src/api/agents.ts +7 -0
- package/dist/extensions/pi-subagents/src/api/external-job-provider.ts +195 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +88 -27
- package/dist/extensions/pi-subagents/src/api/project-panes.ts +2 -0
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +20 -11
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +14 -6
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +5 -4
- package/dist/extensions/pi-subagents/src/extension/index.ts +270 -187
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +65 -28
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +120 -11
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +46 -64
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +51 -37
- package/dist/extensions/pi-subagents/src/extension/tool-result.ts +19 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +2 -2
- package/dist/extensions/pi-subagents/src/inspectors/herdr/client.ts +3 -3
- package/dist/extensions/pi-subagents/src/inspectors/herdr/focus.ts +55 -0
- package/dist/extensions/pi-subagents/src/inspectors/herdr/inspector-runner.ts +2 -1
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +230 -46
- package/dist/extensions/pi-subagents/src/integrations/herdr-status.ts +26 -4
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +32 -10
- package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +6 -1
- package/dist/extensions/pi-subagents/src/missions/store.ts +4 -9
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +2 -2
- package/dist/extensions/pi-subagents/src/policy/authority.ts +2 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +31 -8
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +210 -52
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +63 -33
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +71 -17
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +886 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +14 -5
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +49 -56
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +1 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +3 -33
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +5 -0
- package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +5 -1
- package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +22 -12
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +105 -71
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +68 -19
- package/dist/extensions/pi-subagents/src/runs/background/index-segment.ts +59 -0
- package/dist/extensions/pi-subagents/src/runs/background/inspect-rpc.ts +443 -0
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +94 -10
- package/dist/extensions/pi-subagents/src/runs/background/result-files.ts +158 -90
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +141 -53
- package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +8 -5
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +14 -4
- package/dist/extensions/pi-subagents/src/runs/background/run-id-query.ts +7 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +13 -14
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +46 -25
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +823 -0
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +9 -3
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +11 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +594 -216
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -13
- package/dist/extensions/pi-subagents/src/runs/background/terminal-run-index.ts +138 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +23 -4
- package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +82 -4
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +5 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +21 -14
- package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +23 -2
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +153 -58
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +7 -9
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1283 -1657
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +274 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +6 -5
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +59 -10
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +1 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +52 -2
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/extension-bindings.ts +78 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-runner.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-job-bridge.ts +460 -0
- package/dist/extensions/pi-subagents/src/runs/shared/external-job-runner.ts +389 -0
- package/dist/extensions/pi-subagents/src/runs/shared/fast-mode-extension.ts +10 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +14 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +243 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +201 -85
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +106 -39
- package/dist/extensions/pi-subagents/src/runs/shared/mutation-evidence.ts +145 -0
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +150 -27
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +46 -4
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +19 -15
- package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +5 -1
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +86 -2
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +9 -9
- package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +0 -6
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +18 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +51 -7
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +62 -21
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +1 -3
- package/dist/extensions/pi-subagents/src/runs/shared/tool-timeout.ts +1 -3
- package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +1 -23
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +14 -2
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +2 -2
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +22 -2
- package/dist/extensions/pi-subagents/src/shared/capacity-resilient-json.ts +102 -0
- package/dist/extensions/pi-subagents/src/shared/completion-owner.ts +14 -0
- package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +49 -1
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +59 -1
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +12 -5
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +20 -0
- package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +0 -40
- package/dist/extensions/pi-subagents/src/shared/settings.ts +11 -30
- package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +52 -0
- package/dist/extensions/pi-subagents/src/shared/types.ts +228 -49
- package/dist/extensions/pi-subagents/src/shared/utils.ts +11 -3
- package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +10 -0
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +0 -162
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +2 -5
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +105 -13
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +6 -36
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +829 -0
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +1415 -0
- package/dist/extensions/pi-subagents/src/tui/render.ts +78 -7
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +1 -1
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +1 -0
- package/dist/extensions/pi-subagents/src/watchdog/permission-arbiter.ts +59 -51
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +8 -2
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +2 -1
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +4 -4
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +471 -86
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +140 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +1 -1
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +0 -54
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1053 -414
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +194 -4
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +59 -4
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +0 -77
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +107 -6
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +211 -897
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +265 -375
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +77 -7
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +10 -10
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +547 -30
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +2112 -310
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +274 -34
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +20 -3
- package/dist/extensions/pi-subagents/test/support/isolated-temp-root.mjs +9 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +30 -5
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +4 -2
- package/dist/extensions/pi-subagents/test/support/register-loader.mjs +1 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +197 -0
- package/dist/extensions/pi-subagents/test/unit/agent-contract.test.ts +14 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +204 -27
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +444 -145
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +256 -4
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +9 -7
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +152 -22
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +29 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +205 -23
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +579 -0
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/authority-policy.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/capacity-resilient-json.test.ts +155 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +7 -0
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +123 -0
- package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +81 -3
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +109 -7
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +5 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -2
- package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/external-cli-runner.test.ts +22 -0
- package/dist/extensions/pi-subagents/test/unit/external-job-runner.test.ts +961 -0
- package/dist/extensions/pi-subagents/test/unit/file-system-retry.test.ts +64 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +1110 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +1664 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +81 -1
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +138 -11
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +41 -2
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +210 -79
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +95 -0
- package/dist/extensions/pi-subagents/test/unit/inspect-rpc.test.ts +596 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +3 -5
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +167 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +319 -18
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +19 -5
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/unit/mutation-evidence.test.ts +129 -0
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +231 -2
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +28 -1
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +106 -2
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +204 -7
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +59 -4
- package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +2 -6
- package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +34 -2
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +116 -6
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +12 -3
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +56 -61
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +416 -1
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +9 -2
- package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +21 -30
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +86 -11
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +233 -5
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +28 -5
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +323 -20
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +66 -10
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +68 -5
- package/dist/extensions/pi-subagents/test/unit/runtime-agent-registration.test.ts +174 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +679 -0
- package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +55 -44
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +399 -84
- package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +13 -0
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +15 -10
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +11 -7
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +40 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +10 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +38 -3
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +110 -12
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +204 -19
- package/dist/extensions/pi-subagents/test/unit/temp-paths.test.ts +25 -0
- package/dist/extensions/pi-subagents/test/unit/thinking-ceiling.test.ts +73 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +90 -50
- package/dist/extensions/pi-subagents/test/unit/tool-timeout.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +234 -7
- package/dist/extensions/pi-subagents/test/unit/watch-strategy.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-permission-arbiter.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +37 -9
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +302 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +167 -7
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +113 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +6 -6
- package/dist/extensions/ponytail/index.js +31 -25
- package/dist/extensions/ponytail/ponytail-config.cjs +34 -7
- package/dist/extensions/ponytail/ponytail-instructions.cjs +7 -9
- package/dist/extensions/ponytail/test/extension.test.js +7 -8
- package/dist/extensions/ponytail/test/helpers.test.js +1 -1
- package/dist/skills/brandkit/SKILL.md +799 -0
- package/dist/skills/design-taste-frontend/SKILL.md +1207 -0
- package/dist/skills/design-taste-frontend-v1/SKILL.md +227 -0
- package/dist/skills/full-output-enforcement/SKILL.md +50 -0
- package/dist/skills/gpt-taste/SKILL.md +75 -0
- package/dist/skills/high-end-visual-design/SKILL.md +99 -0
- package/dist/skills/image-to-code/SKILL.md +1229 -0
- package/dist/skills/imagegen-frontend-mobile/SKILL.md +1466 -0
- package/dist/skills/imagegen-frontend-web/SKILL.md +988 -0
- package/dist/skills/industrial-brutalist-ui/SKILL.md +93 -0
- package/dist/skills/minimalist-ui/SKILL.md +86 -0
- package/dist/skills/pi-subagents/SKILL.md +18 -17
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +31 -9
- package/dist/skills/pi-subagents/references/execution-controls.md +95 -143
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +9 -12
- package/dist/skills/pi-subagents/references/multi-lane-orchestration.md +39 -0
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +45 -94
- package/dist/skills/ponytail/SKILL.md +12 -8
- package/dist/skills/ponytail-audit/SKILL.md +0 -1
- package/dist/skills/ponytail-debt/SKILL.md +0 -1
- package/dist/skills/ponytail-gain/SKILL.md +0 -1
- package/dist/skills/ponytail-help/SKILL.md +4 -3
- package/dist/skills/ponytail-review/SKILL.md +0 -1
- package/dist/skills/redesign-existing-projects/SKILL.md +179 -0
- package/dist/skills/stitch-design-taste/SKILL.md +185 -0
- package/dist/skills/unlazy/CHANGELOG.md +100 -0
- package/dist/skills/unlazy/CONTRIBUTING.md +66 -0
- package/dist/skills/unlazy/LICENSE +21 -0
- package/dist/skills/unlazy/README.md +242 -0
- package/dist/skills/unlazy/SECURITY.md +70 -0
- package/dist/skills/unlazy/SKILL.md +100 -0
- package/dist/skills/unlazy/package.json +13 -0
- package/dist/skills/unlazy/references/dispatch.md +82 -0
- package/dist/skills/unlazy/references/gates.md +132 -0
- package/dist/skills/unlazy/references/method.md +49 -0
- package/dist/skills/unlazy/references/orchestration.md +99 -0
- package/dist/skills/unlazy/references/parallel.md +123 -0
- package/dist/skills/unlazy/references/token-economy.md +39 -0
- package/dist/skills/unlazy/research/validation-protocol.md +81 -0
- package/dist/skills/unlazy/scripts/dispatch-check.mjs +108 -0
- package/dist/skills/unlazy/scripts/gate-check.mjs +894 -0
- package/dist/skills/unlazy/scripts/gate-lint.mjs +178 -0
- package/dist/skills/unlazy/scripts/install-hooks.mjs +206 -0
- package/dist/skills/unlazy/scripts/lib/check-supervisor.mjs +46 -0
- package/dist/skills/unlazy/scripts/lib/dispatch.mjs +283 -0
- package/dist/skills/unlazy/scripts/lib/gates.mjs +629 -0
- package/dist/skills/unlazy/scripts/lib/process-tree.mjs +161 -0
- package/dist/skills/unlazy/scripts/lib/regex-worker.mjs +9 -0
- package/dist/skills/unlazy/scripts/stop-hook.mjs +174 -0
- package/dist/skills/unlazy/templates/PLAN.md +65 -0
- package/dist/skills/unlazy/templates/gates-leaf.md +51 -0
- package/dist/skills/unlazy/templates/gates-node.md +50 -0
- package/dist/skills/unlazy/tests/contract-tests.mjs +127 -0
- package/dist/skills/unlazy/tests/dispatch-tests.mjs +481 -0
- package/dist/skills/unlazy/tests/hardening-tests.mjs +903 -0
- package/dist/skills/unlazy/tests/lint-tests.mjs +242 -0
- package/dist/skills/unlazy/tests/run-tests.mjs +554 -0
- package/dist/skills/unlazy/tests/self-check.mjs +165 -0
- package/dist/skills/unlazy/tests/stress-tests.mjs +356 -0
- package/dist/skills/web-design-guidelines/SKILL.md +40 -0
- package/docs/settings.md +0 -5
- package/package.json +1 -1
- package/dist/core/tools/schema-prune.d.ts +0 -16
- package/dist/core/tools/schema-prune.js +0 -39
- package/dist/core/tools/schema-prune.test.d.ts +0 -1
- package/dist/core/tools/schema-prune.test.js +0 -111
- package/dist/extensions/pi-subagents/UPSTREAM-V0.50-MAPPING.md +0 -172
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +0 -55
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +0 -61
- package/dist/extensions/pi-subagents/src/agents/task-aware-routing.ts +0 -132
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +0 -181
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +0 -1354
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +0 -1581
- package/dist/extensions/pi-subagents/src/shared/env.ts +0 -16
- package/dist/extensions/pi-subagents/src/shared/session-lineage.ts +0 -71
- package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +0 -136
- package/dist/extensions/pi-subagents/src/workflows/workflow-auto-relaunch.ts +0 -41
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +0 -466
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +0 -1859
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +0 -733
- package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +0 -63
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +0 -326
- package/dist/extensions/pi-subagents/test/unit/handoff-adoption.test.ts +0 -103
- package/dist/extensions/pi-subagents/test/unit/inline-subagents.test.ts +0 -127
- package/dist/extensions/pi-subagents/test/unit/session-lineage.test.ts +0 -73
- package/dist/extensions/pi-subagents/test/unit/task-aware-routing.test.ts +0 -213
- package/dist/extensions/pi-subagents/test/unit/workflow-auto-relaunch.test.ts +0 -65
|
@@ -86,6 +86,8 @@ export interface SubagentWaitParams {
|
|
|
86
86
|
all?: boolean;
|
|
87
87
|
/** Give up after this many milliseconds. Defaults to 30 minutes. */
|
|
88
88
|
timeoutMs?: number;
|
|
89
|
+
/** False keeps a blocking wait open through idle attention; supervisor/contact requests still stop the wait. */
|
|
90
|
+
stopOnAttention?: boolean;
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/** Minimal event-bus surface wait subscribes to (matches pi.events). */
|
|
@@ -110,6 +112,8 @@ export interface SubagentWaitDeps {
|
|
|
110
112
|
stopOnAttention?: boolean;
|
|
111
113
|
/** Internal auto-drain mode surfaces failed terminal subagent runs as errors. */
|
|
112
114
|
failOnFailedRuns?: boolean;
|
|
115
|
+
/** Internal auto-drain mode surfaces actionable attention as an error. */
|
|
116
|
+
failOnAttention?: boolean;
|
|
113
117
|
/** Arm a durable exact-target wait subscription in a long-lived interactive runtime. */
|
|
114
118
|
subscribe?: (input: { targetKind: "async" | "foreground"; runId: string; requestedId: string; timeoutMs: number }) => { token: string; expiresAt: number };
|
|
115
119
|
/** Injectable provider protocol surfaces for deterministic tests. */
|
|
@@ -226,7 +230,7 @@ function summarizeForegroundChildren(run: ForegroundResumeRun, indices: Set<numb
|
|
|
226
230
|
}
|
|
227
231
|
|
|
228
232
|
function foregroundChildrenNeedingAttention(run: ForegroundResumeRun, indices: Set<number>) {
|
|
229
|
-
return run.children.filter((child) => indices.has(child.index) && child.status === "detached" && child.activityState === "needs_attention");
|
|
233
|
+
return run.children.filter((child) => indices.has(child.index) && child.status === "detached" && child.activityState === "needs_attention" && child.currentTool === "contact_supervisor");
|
|
230
234
|
}
|
|
231
235
|
|
|
232
236
|
function formatForegroundAttention(run: ForegroundResumeRun, children: ReturnType<typeof foregroundChildrenNeedingAttention>, elapsedMs: number): AgentToolResult<Details> {
|
|
@@ -278,19 +282,19 @@ function attentionRunsForSession(params: SubagentWaitParams, deps: SubagentWaitD
|
|
|
278
282
|
return activeRunsForSession(params, deps).filter((run) => needsAttention(run) && initialIds.has(run.id));
|
|
279
283
|
}
|
|
280
284
|
|
|
281
|
-
/**
|
|
282
|
-
function
|
|
285
|
+
/** Exact initial runs in any state, for the final summary. */
|
|
286
|
+
function runsForIds(runIds: Iterable<string>, deps: SubagentWaitDeps): AsyncRunSummary[] {
|
|
283
287
|
const asyncDirRoot = deps.asyncDirRoot ?? DIRS.async;
|
|
284
288
|
const resultsDir = deps.resultsDir ?? DIRS.results;
|
|
285
|
-
|
|
289
|
+
return [...runIds].flatMap((runId) => listAsyncRuns(asyncDirRoot, {
|
|
286
290
|
sessionId: deps.state.currentSessionId ?? undefined,
|
|
287
291
|
resultsDir,
|
|
288
292
|
kill: deps.kill,
|
|
289
293
|
now: deps.now,
|
|
290
294
|
includeNested: false,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
295
|
+
runId,
|
|
296
|
+
exactRunId: true,
|
|
297
|
+
}));
|
|
294
298
|
}
|
|
295
299
|
|
|
296
300
|
function summarizeTerminalRuns(runs: AsyncRunSummary[], providerFinishedCount = 0): string {
|
|
@@ -453,7 +457,7 @@ async function waitForDetachedForegroundRun(
|
|
|
453
457
|
return result(`Remembered foreground run "${run.runId}" disappeared before a terminal child result was recorded. Completion cannot be confirmed; do not launch a replacement without checking the originating child session.`, true);
|
|
454
458
|
}
|
|
455
459
|
const pending = current.children.filter((child) => initialDetachedIndices.has(child.index) && child.status === "detached");
|
|
456
|
-
const attention =
|
|
460
|
+
const attention = foregroundChildrenNeedingAttention(current, initialDetachedIndices);
|
|
457
461
|
if (attention.length > 0) return formatForegroundAttention(current, attention, now() - startedAt);
|
|
458
462
|
if (pending.length === 0) {
|
|
459
463
|
const outcome = summarizeForegroundChildren(current, initialDetachedIndices);
|
|
@@ -555,11 +559,11 @@ export async function waitForSubagents(
|
|
|
555
559
|
const initialProviderIds = new Set(providerActive.map(backgroundWorkIdentity));
|
|
556
560
|
const initialProviderNames = new Set(providerActive.map((item) => item.provider));
|
|
557
561
|
const initialCount = initialAsyncIds.size + initialProviderIds.size;
|
|
558
|
-
const stopOnAttention = deps.stopOnAttention !== false;
|
|
562
|
+
const stopOnAttention = params.stopOnAttention ?? deps.stopOnAttention !== false;
|
|
559
563
|
let attention = active.filter((run) => needsAttention(run));
|
|
560
564
|
|
|
561
565
|
const isDone = (): boolean => {
|
|
562
|
-
if (
|
|
566
|
+
if (attention.some((run) => initialAsyncIds.has(run.id) && (stopOnAttention || hasSupervisorTool(run)))) return true;
|
|
563
567
|
const activeAsyncIds = new Set(active.map((run) => run.id));
|
|
564
568
|
const activeProviderIds = new Set(providerActive.map(backgroundWorkIdentity));
|
|
565
569
|
if (waitForAll) {
|
|
@@ -611,7 +615,7 @@ export async function waitForSubagents(
|
|
|
611
615
|
const activeProviderIds = new Set(providerActive.map(backgroundWorkIdentity));
|
|
612
616
|
const providerFinishedCount = [...initialProviderIds].filter((id) => !activeProviderIds.has(id)).length;
|
|
613
617
|
try {
|
|
614
|
-
const allNow =
|
|
618
|
+
const allNow = runsForIds(initialAsyncIds, deps);
|
|
615
619
|
const terminal = allNow.filter((run) => !ACTIVE_STATES.includes(run.state) && initialAsyncIds.has(run.id));
|
|
616
620
|
finishedAsyncCount = terminal.length;
|
|
617
621
|
failedAsyncCount = terminal.filter((run) => run.state === "failed").length;
|
|
@@ -643,7 +647,7 @@ export async function waitForSubagents(
|
|
|
643
647
|
const status = relevantAttention.length > 0 ? "attention required" : "done";
|
|
644
648
|
return result(
|
|
645
649
|
`Waited ${elapsed} for ${scope}; ${status}.${outcome}${resumeGuidance}${attentionNote} Completion/control events have been observed; inspect status if a notification is not visible yet.`,
|
|
646
|
-
deps.failOnFailedRuns === true && failedAsyncCount > 0,
|
|
650
|
+
(deps.failOnFailedRuns === true && failedAsyncCount > 0) || (deps.failOnAttention === true && relevantAttention.length > 0),
|
|
647
651
|
completions,
|
|
648
652
|
);
|
|
649
653
|
}
|
|
@@ -660,7 +664,7 @@ export async function waitForSubagents(
|
|
|
660
664
|
: `${finishedCount} of ${initialCount} ${subject} finished`;
|
|
661
665
|
return result(
|
|
662
666
|
`Waited ${elapsed}; ${progress}.${outcome}${resumeGuidance}${attentionNote}${remainder} Relevant completion/control events have been observed; inspect status if a notification is not visible yet.`,
|
|
663
|
-
deps.failOnFailedRuns === true && failedAsyncCount > 0,
|
|
667
|
+
(deps.failOnFailedRuns === true && failedAsyncCount > 0) || (deps.failOnAttention === true && relevantAttention.length > 0),
|
|
664
668
|
completions,
|
|
665
669
|
);
|
|
666
670
|
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import type { AsyncStatus } from "../../shared/types.ts";
|
|
4
|
+
import { readStatus } from "../../shared/utils.ts";
|
|
5
|
+
import { writeAtomicJson } from "../../shared/atomic-json.ts";
|
|
6
|
+
import { encodeIndexSegment } from "./index-segment.ts";
|
|
7
|
+
|
|
8
|
+
export const TERMINAL_RUN_INDEX_DIR = ".terminal-runs";
|
|
9
|
+
|
|
10
|
+
const TERMINAL_RUN_INDEX_VERSION = 1;
|
|
11
|
+
const TIMESTAMP_WIDTH = 16;
|
|
12
|
+
|
|
13
|
+
interface TerminalRunIndexEntry {
|
|
14
|
+
version: 1;
|
|
15
|
+
runId: string;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
endedAt: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isTerminalState(state: AsyncStatus["state"]): boolean {
|
|
21
|
+
return state === "complete" || state === "failed" || state === "paused" || state === "stopped" || state === "rejected";
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function indexRoot(asyncDirRoot: string): string {
|
|
25
|
+
return path.join(asyncDirRoot, TERMINAL_RUN_INDEX_DIR);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function sessionIndexDir(asyncDirRoot: string, sessionId: string): string {
|
|
29
|
+
return path.join(indexRoot(asyncDirRoot), encodeIndexSegment(sessionId));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function markerName(endedAt: number, runId: string): string {
|
|
33
|
+
return `${Math.max(0, Math.floor(endedAt)).toString().padStart(TIMESTAMP_WIDTH, "0")}-${encodeIndexSegment(runId)}.json`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function markerPath(asyncDir: string, sessionId: string, endedAt: number): string {
|
|
37
|
+
return path.join(sessionIndexDir(path.dirname(asyncDir), sessionId), markerName(endedAt, path.basename(asyncDir)));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseEntry(value: unknown): TerminalRunIndexEntry | undefined {
|
|
41
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
42
|
+
const entry = value as Partial<TerminalRunIndexEntry>;
|
|
43
|
+
if (entry.version !== TERMINAL_RUN_INDEX_VERSION
|
|
44
|
+
|| typeof entry.runId !== "string" || !entry.runId
|
|
45
|
+
|| typeof entry.sessionId !== "string" || !entry.sessionId
|
|
46
|
+
|| typeof entry.endedAt !== "number" || !Number.isFinite(entry.endedAt)) return undefined;
|
|
47
|
+
return { version: TERMINAL_RUN_INDEX_VERSION, runId: entry.runId, sessionId: entry.sessionId, endedAt: entry.endedAt };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function updateTerminalRunIndex(asyncDir: string, status: AsyncStatus): void {
|
|
51
|
+
if (!isTerminalState(status.state) || typeof status.sessionId !== "string" || !status.sessionId) return;
|
|
52
|
+
const endedAt = status.endedAt ?? status.lastUpdate ?? status.startedAt;
|
|
53
|
+
const marker = markerPath(asyncDir, status.sessionId, endedAt);
|
|
54
|
+
const entry: TerminalRunIndexEntry = {
|
|
55
|
+
version: TERMINAL_RUN_INDEX_VERSION,
|
|
56
|
+
runId: status.runId || path.basename(asyncDir),
|
|
57
|
+
sessionId: status.sessionId,
|
|
58
|
+
endedAt,
|
|
59
|
+
};
|
|
60
|
+
writeAtomicJson(marker, entry);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function removeInvalidMarker(marker: string): void {
|
|
64
|
+
try {
|
|
65
|
+
fs.rmSync(marker, { force: true });
|
|
66
|
+
} catch {
|
|
67
|
+
// An advisory marker can remain for a later read when cleanup is contended.
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
interface MarkerFile {
|
|
72
|
+
dir: string;
|
|
73
|
+
name: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function markerFiles(dir: string): MarkerFile[] {
|
|
77
|
+
try {
|
|
78
|
+
return fs.readdirSync(dir, { withFileTypes: true })
|
|
79
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(".json"))
|
|
80
|
+
.map((entry) => ({ dir, name: entry.name }));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
83
|
+
if (code === "ENOENT" || code === "ENOTDIR") return [];
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function sessionDirs(asyncDirRoot: string, sessionId: string | undefined): string[] {
|
|
89
|
+
if (sessionId) return [sessionIndexDir(asyncDirRoot, sessionId)];
|
|
90
|
+
try {
|
|
91
|
+
return fs.readdirSync(indexRoot(asyncDirRoot), { withFileTypes: true })
|
|
92
|
+
.filter((entry) => entry.isDirectory())
|
|
93
|
+
.map((entry) => path.join(indexRoot(asyncDirRoot), entry.name));
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
96
|
+
if (code === "ENOENT" || code === "ENOTDIR") return [];
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function recentMarkerFiles(dirs: string[], limit: number): string[] {
|
|
102
|
+
return dirs.flatMap(markerFiles)
|
|
103
|
+
.sort((left, right) => right.name.localeCompare(left.name))
|
|
104
|
+
.slice(0, limit)
|
|
105
|
+
.map((marker) => path.join(marker.dir, marker.name));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function readRecentTerminalRunIndex(asyncDirRoot: string, options: { sessionId?: string; limit?: number } = {}): string[] {
|
|
109
|
+
const limit = options.limit === undefined ? Number.POSITIVE_INFINITY : Math.max(0, Math.floor(options.limit));
|
|
110
|
+
const candidates = recentMarkerFiles(sessionDirs(asyncDirRoot, options.sessionId), limit);
|
|
111
|
+
const runIds: string[] = [];
|
|
112
|
+
const seen = new Set<string>();
|
|
113
|
+
for (const marker of candidates) {
|
|
114
|
+
let entry: TerminalRunIndexEntry | undefined;
|
|
115
|
+
try {
|
|
116
|
+
entry = parseEntry(JSON.parse(fs.readFileSync(marker, "utf-8")));
|
|
117
|
+
} catch (error) {
|
|
118
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") continue;
|
|
119
|
+
}
|
|
120
|
+
if (!entry || (options.sessionId !== undefined && entry.sessionId !== options.sessionId)) {
|
|
121
|
+
removeInvalidMarker(marker);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const asyncDir = path.join(asyncDirRoot, entry.runId);
|
|
125
|
+
const status = readStatus(asyncDir);
|
|
126
|
+
if (!status || !isTerminalState(status.state) || status.sessionId !== entry.sessionId || (status.runId && status.runId !== entry.runId)) {
|
|
127
|
+
removeInvalidMarker(marker);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (seen.has(entry.runId)) {
|
|
131
|
+
removeInvalidMarker(marker);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
seen.add(entry.runId);
|
|
135
|
+
runIds.push(entry.runId);
|
|
136
|
+
}
|
|
137
|
+
return runIds;
|
|
138
|
+
}
|
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import type { ArtifactPaths, SubagentState, WaitCompletion, WaitCompletionChild } from "../../shared/types.ts";
|
|
3
3
|
import type { AsyncRunSummary } from "./async-status.ts";
|
|
4
4
|
import { readCompletionReplay, writeCompletionReplay } from "./completion-replay.ts";
|
|
5
|
-
import { resultFilePath, resultPayloadPathForSessionRun } from "./result-files.ts";
|
|
5
|
+
import { fallbackResultPayloadPathForSessionRun, resultFilePath, resultPayloadPathForSessionRun } from "./result-files.ts";
|
|
6
6
|
|
|
7
7
|
function asNonEmptyString(value: unknown): string | undefined {
|
|
8
8
|
return typeof value === "string" && value ? value : undefined;
|
|
@@ -14,6 +14,11 @@ function errorCode(error: unknown): string | undefined {
|
|
|
14
14
|
: undefined;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
function isAccessDenied(error: unknown): boolean {
|
|
18
|
+
const code = errorCode(error);
|
|
19
|
+
return code === "EPERM" || code === "EACCES";
|
|
20
|
+
}
|
|
21
|
+
|
|
17
22
|
function errorMessage(error: unknown): string {
|
|
18
23
|
return error instanceof Error ? error.message : String(error);
|
|
19
24
|
}
|
|
@@ -39,6 +44,7 @@ export function toWaitCompletion(data: Record<string, unknown>, runId: string):
|
|
|
39
44
|
const childRunId = asNonEmptyString(child.runId);
|
|
40
45
|
const error = asNonEmptyString(child.error);
|
|
41
46
|
const model = asNonEmptyString(child.model);
|
|
47
|
+
const contextOverflow = child.contextOverflow === true;
|
|
42
48
|
return [{
|
|
43
49
|
...(agent ? { agent } : {}),
|
|
44
50
|
...(childRunId ? { runId: childRunId } : {}),
|
|
@@ -46,6 +52,7 @@ export function toWaitCompletion(data: Record<string, unknown>, runId: string):
|
|
|
46
52
|
...(outputState ? { outputState } : {}),
|
|
47
53
|
...(error ? { error } : {}),
|
|
48
54
|
...(model ? { model } : {}),
|
|
55
|
+
...(contextOverflow ? { contextOverflow: true } : {}),
|
|
49
56
|
...(artifactPaths ? { artifactPaths } : {}),
|
|
50
57
|
}];
|
|
51
58
|
})
|
|
@@ -115,9 +122,21 @@ export function collectWaitCompletions(terminal: AsyncRunSummary[], state: Subag
|
|
|
115
122
|
continue;
|
|
116
123
|
}
|
|
117
124
|
const publicResultPath = resultFilePath(resultsDir, run.id);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
let resultPath = publicResultPath;
|
|
126
|
+
try {
|
|
127
|
+
resultPath = run.sessionId
|
|
128
|
+
? resultPayloadPathForSessionRun(resultsDir, run.sessionId, run.id) ?? publicResultPath
|
|
129
|
+
: publicResultPath;
|
|
130
|
+
} catch (error) {
|
|
131
|
+
if (!isAccessDenied(error) || !run.sessionId) throw error;
|
|
132
|
+
try {
|
|
133
|
+
resultPath = fallbackResultPayloadPathForSessionRun(resultsDir, run.sessionId, run.id) ?? publicResultPath;
|
|
134
|
+
} catch (fallbackError) {
|
|
135
|
+
throw new Error(`Failed to read subagent result '${publicResultPath}': ${errorMessage(fallbackError)}`, {
|
|
136
|
+
cause: fallbackError instanceof Error ? fallbackError : undefined,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
121
140
|
try {
|
|
122
141
|
const raw = JSON.parse(fs.readFileSync(resultPath, "utf-8")) as Record<string, unknown>;
|
|
123
142
|
completions.push(toWaitCompletion(raw, run.id));
|
|
@@ -21,6 +21,20 @@ import {
|
|
|
21
21
|
|
|
22
22
|
const SUBSCRIPTION_VERSION = 1;
|
|
23
23
|
const RECONCILE_INTERVAL_MS = 1_000;
|
|
24
|
+
/**
|
|
25
|
+
* How often the subscriptions directory is re-scanned for expired records left
|
|
26
|
+
* by other sessions. Rare compared to RECONCILE_INTERVAL_MS because it costs a
|
|
27
|
+
* directory read, and nothing depends on the sweep being prompt.
|
|
28
|
+
*/
|
|
29
|
+
const FOREIGN_SWEEP_INTERVAL_MS = 60_000;
|
|
30
|
+
/**
|
|
31
|
+
* How far past expiry a record armed by another session is kept before it is
|
|
32
|
+
* swept. The owning session settles its own expired records with a "timed out"
|
|
33
|
+
* notice on the next restore(), so removing one the moment it expires would take
|
|
34
|
+
* that notice away from a session that simply had not resumed yet. A day is long
|
|
35
|
+
* enough for an ordinary return and short enough to bound the directory.
|
|
36
|
+
*/
|
|
37
|
+
const FOREIGN_SWEEP_GRACE_MS = 24 * 60 * 60 * 1000;
|
|
24
38
|
|
|
25
39
|
export interface ArmWaitSubscriptionInput {
|
|
26
40
|
targetKind: "async" | "foreground";
|
|
@@ -95,6 +109,63 @@ export function createWaitSubscriptionManager(
|
|
|
95
109
|
state.waitSubscriptions = subscriptions;
|
|
96
110
|
const unresolvedRestoredForegroundTokens = new Set<string>();
|
|
97
111
|
let disposed = false;
|
|
112
|
+
let lastForeignSweepAt = 0;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Remove expired records armed by another session.
|
|
116
|
+
*
|
|
117
|
+
* Only the owning session can be woken, so restore() never loads a foreign
|
|
118
|
+
* record into `subscriptions` and reconcileRecord() returns before its
|
|
119
|
+
* timeout branch. Nothing reconciles such a record and nothing expires it, so
|
|
120
|
+
* a session that arms a wait and never comes back (forked, renamed, deleted)
|
|
121
|
+
* leaves one file here per wait, forever.
|
|
122
|
+
*
|
|
123
|
+
* Kept for FOREIGN_SWEEP_GRACE_MS past expiry so an owner that resumes late
|
|
124
|
+
* still finds its record and gets the timeout notice.
|
|
125
|
+
*
|
|
126
|
+
* Runs on the reconcile timer as well as at restore(), because a record that
|
|
127
|
+
* is still live when another session starts would otherwise never be looked
|
|
128
|
+
* at again: restore() only fires on session_start, and reconcile() walks the
|
|
129
|
+
* in-memory map, which holds current-session records only. A host that keeps
|
|
130
|
+
* one session open for hours is exactly where that gap bites.
|
|
131
|
+
*
|
|
132
|
+
* Never throws: it runs from the reconcile timer.
|
|
133
|
+
*/
|
|
134
|
+
const sweepExpiredForeignSubscriptions = (force = false) => {
|
|
135
|
+
const sweptAt = now();
|
|
136
|
+
if (!force && sweptAt - lastForeignSweepAt < FOREIGN_SWEEP_INTERVAL_MS) return;
|
|
137
|
+
lastForeignSweepAt = sweptAt;
|
|
138
|
+
let files: string[];
|
|
139
|
+
try {
|
|
140
|
+
files = fs.readdirSync(subscriptionsDir).filter((file) => file.endsWith(".json"));
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (!isNotFound(error)) console.error(`Failed to scan wait subscriptions in '${subscriptionsDir}':`, error);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
for (const file of files) {
|
|
146
|
+
const filePath = path.join(subscriptionsDir, file);
|
|
147
|
+
let record: WaitSubscriptionRecord | undefined;
|
|
148
|
+
try {
|
|
149
|
+
record = parseRecord(JSON.parse(fs.readFileSync(filePath, "utf-8")));
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error(`Ignoring invalid wait subscription '${filePath}':`, error);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (!record || file !== `${record.token}.json`) continue;
|
|
155
|
+
// The owning session keeps its own expired records so reconcileRecord()
|
|
156
|
+
// can still settle them with the "timed out" notice callers expect.
|
|
157
|
+
if (record.sessionId === state.currentSessionId) continue;
|
|
158
|
+
if (sweptAt < record.expiresAt + FOREIGN_SWEEP_GRACE_MS) continue;
|
|
159
|
+
try {
|
|
160
|
+
fs.unlinkSync(filePath);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
// Losing this race is harmless: another session may have swept the
|
|
163
|
+
// same expired record. Anything else is reported and retried on the
|
|
164
|
+
// next sweep rather than interrupting the caller.
|
|
165
|
+
if (!isNotFound(error)) console.error(`Failed to remove expired wait subscription '${filePath}':`, error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
98
169
|
|
|
99
170
|
const remove = (record: WaitSubscriptionRecord) => {
|
|
100
171
|
try {
|
|
@@ -146,7 +217,7 @@ export function createWaitSubscriptionManager(
|
|
|
146
217
|
return;
|
|
147
218
|
}
|
|
148
219
|
const detached = run.children.filter((child) => child.status === "detached");
|
|
149
|
-
if (detached.some((child) => child.activityState === "needs_attention")) {
|
|
220
|
+
if (detached.some((child) => child.activityState === "needs_attention" && child.currentTool === "contact_supervisor")) {
|
|
150
221
|
settle(record, "needs attention", "Reply to the pending supervisor request or inspect the run status.");
|
|
151
222
|
return;
|
|
152
223
|
}
|
|
@@ -160,6 +231,7 @@ export function createWaitSubscriptionManager(
|
|
|
160
231
|
const runs = listAsyncRuns(asyncDirRoot, {
|
|
161
232
|
sessionId: record.sessionId,
|
|
162
233
|
runId: record.runId,
|
|
234
|
+
exactRunId: true,
|
|
163
235
|
resultsDir,
|
|
164
236
|
kill: options.kill,
|
|
165
237
|
now,
|
|
@@ -187,7 +259,11 @@ export function createWaitSubscriptionManager(
|
|
|
187
259
|
};
|
|
188
260
|
|
|
189
261
|
const reconcile = () => {
|
|
190
|
-
if (disposed
|
|
262
|
+
if (disposed) return;
|
|
263
|
+
// Before the session check: with no current session every record is
|
|
264
|
+
// foreign, and expired ones should still be cleaned up.
|
|
265
|
+
sweepExpiredForeignSubscriptions();
|
|
266
|
+
if (!state.currentSessionId) return;
|
|
191
267
|
for (const record of [...subscriptions.values()]) {
|
|
192
268
|
try {
|
|
193
269
|
reconcileRecord(record);
|
|
@@ -233,6 +309,9 @@ export function createWaitSubscriptionManager(
|
|
|
233
309
|
restore() {
|
|
234
310
|
subscriptions.clear();
|
|
235
311
|
unresolvedRestoredForegroundTokens.clear();
|
|
312
|
+
// Unconditional: a process that starts without a session identity should
|
|
313
|
+
// still clear records nobody can act on.
|
|
314
|
+
sweepExpiredForeignSubscriptions(true);
|
|
236
315
|
if (!state.currentSessionId) return;
|
|
237
316
|
let files: string[];
|
|
238
317
|
try {
|
|
@@ -245,8 +324,7 @@ export function createWaitSubscriptionManager(
|
|
|
245
324
|
try {
|
|
246
325
|
const record = parseRecord(JSON.parse(fs.readFileSync(path.join(subscriptionsDir, file), "utf-8")));
|
|
247
326
|
if (!record || file !== `${record.token}.json`) continue;
|
|
248
|
-
|
|
249
|
-
if (acceptedSessions.has(record.sessionId)) {
|
|
327
|
+
if (record.sessionId === state.currentSessionId) {
|
|
250
328
|
subscriptions.set(record.token, record);
|
|
251
329
|
if (record.targetKind === "foreground" && !state.foregroundRuns?.has(record.runId)) unresolvedRestoredForegroundTokens.add(record.token);
|
|
252
330
|
}
|
|
@@ -3,6 +3,7 @@ import { SubagentWaitParams } from "../../extension/schemas.ts";
|
|
|
3
3
|
import type { Details, SubagentState } from "../../shared/types.ts";
|
|
4
4
|
import { resolveWaitToolConfig, waitForSubagents } from "./subagent-wait.ts";
|
|
5
5
|
import type { WaitSubscriptionManager } from "./wait-subscriptions.ts";
|
|
6
|
+
import { finalizeToolResult } from "../../extension/tool-result.ts";
|
|
6
7
|
|
|
7
8
|
export function registerWaitTool(pi: ExtensionAPI, state: SubagentState, enabled = resolveWaitToolConfig().enabled, subscriptions?: Pick<WaitSubscriptionManager, "arm">): void {
|
|
8
9
|
const tool: ToolDefinition<typeof SubagentWaitParams, Details> = {
|
|
@@ -16,18 +17,19 @@ In an interactive chat, do not call this merely to wait: return control to the u
|
|
|
16
17
|
• { all: true } — wait for every async run and provider item that was active when the call began.
|
|
17
18
|
• { id: "..." } — wait for one async or remembered detached foreground subagent run (id or prefix).
|
|
18
19
|
• { id: "...", nonBlocking: true } — resolve the prefix once, persist an exact-run wake subscription, and return immediately. The originating interactive session wakes on completion, failure, attention, reconciliation failure, or timeout.
|
|
20
|
+
• { stopOnAttention: false } — for blocking waits only, keep waiting through idle or long-thinking attention; supervisor/contact requests still stop the wait.
|
|
19
21
|
• { timeoutMs: 600000 } — stop waiting after N ms; active work keeps running.
|
|
20
22
|
|
|
21
23
|
Non-blocking subscriptions are visible in subagent status and differ from disabling waitTool: waitTool.enabled=false returns immediately without registering any future wake. Provider jobs are session-scoped and identified exactly, so replacing one job with another cannot hide a completion. Provider extensions must be explicitly loaded in this process. In a child agent, keep \`subagent_wait\` in the child tool allowlist and load each provider through the agent's extensions or subagentOnlyExtensions; this tool never loads providers or grants tools itself.${enabled ? "" : "\n\nConfigured behavior: subagent_wait is disabled by config.waitTool or SELESAI_SUBAGENT_WAIT_TOOL_ENABLED and returns immediately without blocking."}`,
|
|
22
24
|
parameters: SubagentWaitParams,
|
|
23
|
-
execute(_id, params, signal, onUpdate, ctx) {
|
|
24
|
-
return waitForSubagents(params, signal, {
|
|
25
|
+
async execute(_id, params, signal, onUpdate, ctx) {
|
|
26
|
+
return finalizeToolResult(await waitForSubagents(params, signal, {
|
|
25
27
|
state,
|
|
26
28
|
events: pi.events,
|
|
27
29
|
enabled,
|
|
28
30
|
onUpdate,
|
|
29
31
|
...(subscriptions && ctx?.hasUI ? { subscribe: (input) => subscriptions.arm(input) } : {}),
|
|
30
|
-
});
|
|
32
|
+
}));
|
|
31
33
|
},
|
|
32
34
|
};
|
|
33
35
|
pi.registerTool(tool);
|
|
@@ -8,7 +8,17 @@ import { readStatus } from "../../shared/utils.ts";
|
|
|
8
8
|
import { consumeSteerAcks, deliverInterruptRequest, queueRevivalBrief, requestAsyncSteer, type SteerDeliveryMode, type SteerRequest } from "../background/control-channel.ts";
|
|
9
9
|
import { resolveAsyncResumeTarget } from "../background/async-resume.ts";
|
|
10
10
|
import { reconcileAsyncRun } from "../background/stale-run-reconciler.ts";
|
|
11
|
-
import { actionResultFromSteeringStatus, claimSteeringRecovery, createSteeringStatus, recordSteeringRequest, remainingSteeringRecoveryLimits, updateSteeringTarget, waitForSteeringAction } from "../background/steering.ts";
|
|
11
|
+
import { actionResultFromSteeringStatus, claimSteeringRecovery, createSteeringStatus, recordSteeringRequest, remainingSteeringRecoveryLimits, steeringReceipt, updateSteeringTarget, waitForSteeringAction } from "../background/steering.ts";
|
|
12
|
+
|
|
13
|
+
export function canQueueRetainedAsyncFollowUp(status: AsyncStatus, index?: number): boolean {
|
|
14
|
+
const steps = status.steps ?? [];
|
|
15
|
+
return status.state === "complete"
|
|
16
|
+
&& Boolean(status.parentWorkflowRunId)
|
|
17
|
+
&& steps.length === 1
|
|
18
|
+
&& (steps[0]?.status === "complete" || steps[0]?.status === "completed")
|
|
19
|
+
&& Boolean(steps[0]?.sessionFile ?? status.sessionFile)
|
|
20
|
+
&& (index === undefined || index === 0);
|
|
21
|
+
}
|
|
12
22
|
|
|
13
23
|
export async function steerAsyncRun(input: {
|
|
14
24
|
state: SubagentState;
|
|
@@ -51,7 +61,7 @@ export async function steerAsyncRun(input: {
|
|
|
51
61
|
}
|
|
52
62
|
const steps = status.steps ?? [];
|
|
53
63
|
if (status.state !== "running" && status.state !== "queued") {
|
|
54
|
-
const retained = input.mode === "follow_up" &&
|
|
64
|
+
const retained = input.mode === "follow_up" && canQueueRetainedAsyncFollowUp(status, input.index);
|
|
55
65
|
if (!retained) {
|
|
56
66
|
return {
|
|
57
67
|
content: [{ type: "text", text: `Async run '${input.runId}' is not running or queued and cannot be steered.` }],
|
|
@@ -59,9 +69,6 @@ export async function steerAsyncRun(input: {
|
|
|
59
69
|
details: { mode: "management", results: [] },
|
|
60
70
|
};
|
|
61
71
|
}
|
|
62
|
-
if (input.index !== undefined && input.index !== 0) {
|
|
63
|
-
return { content: [{ type: "text", text: `Retained async run '${status.runId}' has one child. Index ${input.index} is out of range.` }], isError: true, details: { mode: "management", results: [] } };
|
|
64
|
-
}
|
|
65
72
|
const request: SteerRequest = { type: "steer", id: randomUUID(), ts: Date.now(), message: input.message.trim(), mode: "follow_up", targetIndex: 0, source: "steer-action" };
|
|
66
73
|
try {
|
|
67
74
|
queueRevivalBrief(asyncDir, request);
|
|
@@ -72,7 +79,7 @@ export async function steerAsyncRun(input: {
|
|
|
72
79
|
recordSteeringRequest(status.steering, { id: request.id, requestedAt: request.ts, source: request.source, message: request.message, targets: [{ index: 0, state: "scheduled" }] });
|
|
73
80
|
writeAtomicJson(path.join(asyncDir, "status.json"), status);
|
|
74
81
|
const queued = { requestId: request.id, state: "scheduled" as const, deliveryStatus: "queued" as const, sourceRunId: status.runId, targets: [{ index: 0, state: "scheduled" as const }] };
|
|
75
|
-
return { content: [{ type: "text", text: `Follow-up queued for the next resume of retained async run ${status.runId} (request ${request.id}).` }], details: { mode: "management", results: [], steering: queued } };
|
|
82
|
+
return { content: [{ type: "text", text: steeringReceipt(request.message, `Follow-up queued for the next resume of retained async run ${status.runId} (request ${request.id}).`) }], details: { mode: "management", results: [], steering: queued } };
|
|
76
83
|
}
|
|
77
84
|
if (input.index !== undefined) {
|
|
78
85
|
if (input.index < 0 || input.index >= steps.length) {
|
|
@@ -135,17 +142,17 @@ export async function steerAsyncRun(input: {
|
|
|
135
142
|
const targets = targetIndexes.map((index) => ({ index, state: status.steps?.[index]?.status === "pending" ? "scheduled" as const : "pending" as const }));
|
|
136
143
|
if (targets.every((target) => target.state === "scheduled")) {
|
|
137
144
|
const scheduled = { requestId, state: "scheduled" as const, deliveryStatus: "queued" as const, sourceRunId: status.runId, targets };
|
|
138
|
-
return { content: [{ type: "text", text: `Steering scheduled for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: scheduled } };
|
|
145
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering scheduled for async run ${status.runId} (request ${requestId}).`) }], details: { mode: "management", results: [], steering: scheduled } };
|
|
139
146
|
}
|
|
140
147
|
const waited = await waitForSteeringAction({ asyncDir, sourceRunId: status.runId, requestId, timeoutMs: input.ackTimeoutMs ?? 3_000, signal: input.signal });
|
|
141
148
|
const result = waited ?? { requestId, state: "pending" as const, deliveryStatus: "queued" as const, sourceRunId: status.runId, targets };
|
|
142
149
|
if (input.signal?.aborted) {
|
|
143
|
-
return { content: [{ type: "text", text: `Steering pending for async run ${status.runId} (request ${requestId}); caller aborted before recovery.` }], details: { mode: "management", results: [], steering: result } };
|
|
150
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering pending for async run ${status.runId} (request ${requestId}); caller aborted before recovery.`) }], details: { mode: "management", results: [], steering: result } };
|
|
144
151
|
}
|
|
145
152
|
const finalStatus = readStatus(asyncDir);
|
|
146
153
|
const finalResult = finalStatus?.steering ? actionResultFromSteeringStatus(finalStatus.steering, status.runId, requestId) : undefined;
|
|
147
154
|
if (finalResult?.state === "delivered") {
|
|
148
|
-
return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: finalResult } };
|
|
155
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering delivered for async run ${status.runId} (request ${requestId}).`) }], details: { mode: "management", results: [], steering: finalResult } };
|
|
149
156
|
}
|
|
150
157
|
const running = (finalStatus?.steps ?? status.steps ?? []).filter((step) => step.status === "running");
|
|
151
158
|
const recoveryAllowed = (input.mode ?? "steer") === "steer" && status.mode === "single" && status.isNested !== true && running.length === 1 && Boolean(finalStatus?.steering) && (input.index === undefined || input.index === 0);
|
|
@@ -160,7 +167,7 @@ export async function steerAsyncRun(input: {
|
|
|
160
167
|
try {
|
|
161
168
|
const latest = readStatus(asyncDir);
|
|
162
169
|
const latestResult = latest?.steering ? actionResultFromSteeringStatus(latest.steering, status.runId, requestId) : undefined;
|
|
163
|
-
if (latestResult?.state === "delivered") return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: latestResult } };
|
|
170
|
+
if (latestResult?.state === "delivered") return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering delivered for async run ${status.runId} (request ${requestId}).`) }], details: { mode: "management", results: [], steering: latestResult } };
|
|
164
171
|
const committedAt = Date.now();
|
|
165
172
|
input.onBeforeRecoveryClaim?.(requestId, committedAt);
|
|
166
173
|
const { claimPath, markerPath } = claimSteeringRecovery(asyncDir, { requestId, sourceRunId: status.runId, committedAt });
|
|
@@ -170,7 +177,7 @@ export async function steerAsyncRun(input: {
|
|
|
170
177
|
if (preCommitResult?.state === "delivered" && preCommitResult.targets.every((target) => target.deliveredAt !== undefined && target.deliveredAt <= committedAt)) {
|
|
171
178
|
fs.rmSync(markerPath, { force: true });
|
|
172
179
|
fs.rmSync(claimPath, { force: true });
|
|
173
|
-
return { content: [{ type: "text", text: `Steering delivered for async run ${status.runId} (request ${requestId}).` }], details: { mode: "management", results: [], steering: preCommitResult } };
|
|
180
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering delivered for async run ${status.runId} (request ${requestId}).`) }], details: { mode: "management", results: [], steering: preCommitResult } };
|
|
174
181
|
}
|
|
175
182
|
try {
|
|
176
183
|
deliverInterruptRequest({ asyncDir, source: "steering-recovery" });
|
|
@@ -228,7 +235,7 @@ export async function steerAsyncRun(input: {
|
|
|
228
235
|
}
|
|
229
236
|
const recovered = paused.steering ? actionResultFromSteeringStatus(paused.steering, status.runId, requestId, revived.details.asyncId) : undefined;
|
|
230
237
|
appendSteeringNotice("recovered", `Steering recovered for run ${status.runId}; replacement ${revived.details.asyncId} launched.`);
|
|
231
|
-
return { content: [{ type: "text", text: `Steering recovered for async run ${status.runId}; replacement ${revived.details.asyncId} launched after the source paused.` }], details: { mode: "management", results: [], steering: recovered ?? { requestId, state: "recovered", sourceRunId: status.runId, replacementRunId: revived.details.asyncId, deliveryStatus: "delivered", targets: [{ index: input.index ?? 0, state: "recovered" }] } } };
|
|
238
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering recovered for async run ${status.runId}; replacement ${revived.details.asyncId} launched after the source paused.`) }], details: { mode: "management", results: [], steering: recovered ?? { requestId, state: "recovered", sourceRunId: status.runId, replacementRunId: revived.details.asyncId, deliveryStatus: "delivered", targets: [{ index: input.index ?? 0, state: "recovered" }] } } };
|
|
232
239
|
} catch (error) {
|
|
233
240
|
const reason = error instanceof Error ? error.message : String(error);
|
|
234
241
|
const failedStatus = readStatus(asyncDir);
|
|
@@ -242,13 +249,13 @@ export async function steerAsyncRun(input: {
|
|
|
242
249
|
}
|
|
243
250
|
const failed = failedStatus?.steering ? actionResultFromSteeringStatus(failedStatus.steering, status.runId, requestId) : undefined;
|
|
244
251
|
appendSteeringNotice("failed", `Steering failed for run ${status.runId}: ${reason}`);
|
|
245
|
-
return { content: [{ type: "text", text: `Steering failed for async run ${status.runId} (request ${requestId}): ${reason}` }], isError: true, details: { mode: "management", results: [], steering: failed ?? { requestId, state: "failed", sourceRunId: status.runId, deliveryStatus: "queued", targets: [{ index: input.index ?? 0, state: "failed", reason }] } } };
|
|
252
|
+
return { content: [{ type: "text", text: steeringReceipt(input.message, `Steering failed for async run ${status.runId} (request ${requestId}): ${reason}`) }], isError: true, details: { mode: "management", results: [], steering: failed ?? { requestId, state: "failed", sourceRunId: status.runId, deliveryStatus: "queued", targets: [{ index: input.index ?? 0, state: "failed", reason }] } } };
|
|
246
253
|
}
|
|
247
254
|
}
|
|
248
255
|
const stateText = result.state === "failed" ? "failed" : result.state === "partial" ? "partial" : result.deliveryStatus === "queued" ? "queued" : result.state === "delivered" ? "delivered" : result.state === "scheduled" ? "scheduled" : result.state === "recovered" ? "recovered" : "pending";
|
|
249
256
|
const isError = result.state === "failed" || result.state === "partial";
|
|
250
257
|
return {
|
|
251
|
-
content: [{ type: "text", text: `Steering ${stateText} for async run ${status.runId} (request ${requestId}).` }],
|
|
258
|
+
content: [{ type: "text", text: steeringReceipt(input.message, `Steering ${stateText} for async run ${status.runId} (request ${requestId}).`) }],
|
|
252
259
|
...(isError ? { isError: true } : {}),
|
|
253
260
|
details: { mode: "management", results: [], steering: result },
|
|
254
261
|
};
|
|
@@ -3,6 +3,7 @@ import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
|
3
3
|
import type { Details, SubagentState } from "../../shared/types.ts";
|
|
4
4
|
import { deliverStopRequest } from "../background/control-channel.ts";
|
|
5
5
|
import { reconcileAsyncRun } from "../background/stale-run-reconciler.ts";
|
|
6
|
+
import { isStoppableAsyncStatusStep, resolveAsyncStatusChild, type ResolvedAsyncStatusChild } from "../shared/child-identity.ts";
|
|
6
7
|
|
|
7
8
|
function getAsyncStopTarget(
|
|
8
9
|
state: SubagentState,
|
|
@@ -25,6 +26,7 @@ export function stopAsyncRun(
|
|
|
25
26
|
runId: string | undefined,
|
|
26
27
|
kill?: (pid: number, signal?: NodeJS.Signals | 0) => boolean,
|
|
27
28
|
location?: { asyncDir: string | null; resolvedId?: string },
|
|
29
|
+
childId?: string,
|
|
28
30
|
): AgentToolResult<Details> | null {
|
|
29
31
|
const target = getAsyncStopTarget(state, runId, location);
|
|
30
32
|
if (!target) return null;
|
|
@@ -43,15 +45,34 @@ export function stopAsyncRun(
|
|
|
43
45
|
details: { mode: "management", results: [] },
|
|
44
46
|
};
|
|
45
47
|
}
|
|
48
|
+
let child: ResolvedAsyncStatusChild | undefined;
|
|
49
|
+
if (childId !== undefined) {
|
|
50
|
+
const resolution = resolveAsyncStatusChild(status, childId);
|
|
51
|
+
if (!resolution.ok) {
|
|
52
|
+
return {
|
|
53
|
+
content: [{ type: "text", text: resolution.message }],
|
|
54
|
+
isError: true,
|
|
55
|
+
details: { mode: "management", results: [] },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
child = resolution.child;
|
|
59
|
+
if (!isStoppableAsyncStatusStep(child.step)) {
|
|
60
|
+
return {
|
|
61
|
+
content: [{ type: "text", text: `Child '${childId}' in async run '${status.runId}' is ${child.step.status}; stop only supports pending or running children.` }],
|
|
62
|
+
isError: true,
|
|
63
|
+
details: { mode: "management", results: [] },
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
46
67
|
try {
|
|
47
|
-
deliverStopRequest({ asyncDir: target.asyncDir, pid: typeof status.pid === "number" ? status.pid : undefined, kill, source: "stop-action" });
|
|
68
|
+
deliverStopRequest({ asyncDir: target.asyncDir, pid: typeof status.pid === "number" ? status.pid : undefined, kill, source: "stop-action", targetIndex: child?.index, childId: child?.id ?? childId });
|
|
48
69
|
const tracked = state.asyncJobs.get(target.asyncId);
|
|
49
70
|
if (tracked) {
|
|
50
71
|
tracked.activityState = undefined;
|
|
51
72
|
tracked.updatedAt = Date.now();
|
|
52
73
|
}
|
|
53
74
|
return {
|
|
54
|
-
content: [{ type: "text", text: `Stop requested for async run ${target.asyncId}.` }],
|
|
75
|
+
content: [{ type: "text", text: child ? `Stop requested for child ${child.id} in async run ${target.asyncId}.` : `Stop requested for async run ${target.asyncId}.` }],
|
|
55
76
|
details: { mode: "management", results: [] },
|
|
56
77
|
};
|
|
57
78
|
} catch (error) {
|