@selesai/code 0.5.27 → 0.5.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +9 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config-selector.d.ts.map +1 -1
- package/dist/cli/config-selector.js +1 -1
- package/dist/cli/config-selector.js.map +1 -1
- package/dist/cli/credential-print.d.ts +23 -0
- package/dist/cli/credential-print.d.ts.map +1 -0
- package/dist/cli/credential-print.js +117 -0
- package/dist/cli/credential-print.js.map +1 -0
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -1
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +3 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session.d.ts +12 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +20 -14
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +11 -3
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +11 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +14 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +10 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/llama/provider.d.ts.map +1 -1
- package/dist/core/llama/provider.js +8 -3
- package/dist/core/llama/provider.js.map +1 -1
- package/dist/core/model-config.d.ts +30 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +6 -0
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +2 -2
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +20 -3
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +2 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +5 -4
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +13 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +24 -11
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +15 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +66 -9
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +1 -1
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tools/bash.d.ts +2 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +34 -5
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +3 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +249 -0
- package/dist/extensions/pi-intercom/README.md +102 -39
- package/dist/extensions/pi-intercom/broker/broker.ts +1233 -36
- package/dist/extensions/pi-intercom/broker/client.test.ts +83 -0
- package/dist/extensions/pi-intercom/broker/client.ts +315 -12
- package/dist/extensions/pi-intercom/broker/extension-state.ts +186 -0
- package/dist/extensions/pi-intercom/broker/extension.test.ts +387 -0
- package/dist/extensions/pi-intercom/broker/framing.test.ts +114 -0
- package/dist/extensions/pi-intercom/broker/framing.ts +82 -24
- package/dist/extensions/pi-intercom/broker/paths.test.ts +153 -0
- package/dist/extensions/pi-intercom/broker/paths.ts +117 -8
- package/dist/extensions/pi-intercom/broker/runtime-claim.test.ts +34 -0
- package/dist/extensions/pi-intercom/broker/runtime-claim.ts +21 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +160 -23
- package/dist/extensions/pi-intercom/broker/spawn.ts +113 -27
- package/dist/extensions/pi-intercom/config.test.ts +93 -0
- package/dist/extensions/pi-intercom/config.ts +55 -6
- package/dist/extensions/pi-intercom/cwd.test.ts +40 -0
- package/dist/extensions/pi-intercom/cwd.ts +31 -0
- package/dist/extensions/pi-intercom/extension-api.ts +44 -0
- package/dist/extensions/pi-intercom/format-context.test.ts +31 -0
- package/dist/extensions/pi-intercom/format-context.ts +32 -0
- package/dist/extensions/pi-intercom/index.ts +742 -145
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +2646 -0
- package/dist/extensions/pi-intercom/package.json +15 -5
- package/dist/extensions/pi-intercom/reply-tracker.test.ts +134 -0
- package/dist/extensions/pi-intercom/reply-tracker.ts +31 -13
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +13 -11
- package/dist/extensions/pi-intercom/test/inline-message.test.ts +184 -0
- package/dist/extensions/pi-intercom/test/overlay-width.test.ts +66 -0
- package/dist/extensions/pi-intercom/types.ts +94 -4
- package/dist/extensions/pi-intercom/ui/compose.ts +8 -4
- package/dist/extensions/pi-intercom/ui/inline-message.ts +61 -25
- package/dist/extensions/pi-intercom/ui/session-list.ts +7 -3
- package/dist/extensions/pi-subagents/CHANGELOG.md +85 -0
- package/dist/extensions/pi-subagents/LICENSE +21 -0
- package/dist/extensions/pi-subagents/README.md +146 -52
- package/dist/extensions/pi-subagents/agents/architect.md +1 -0
- package/dist/extensions/pi-subagents/agents/builder.md +1 -0
- package/dist/extensions/pi-subagents/package-lock.json +2 -2
- package/dist/extensions/pi-subagents/package.json +3 -3
- package/dist/extensions/pi-subagents/prompts/review-loop.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +21 -989
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +256 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +430 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +144 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +282 -0
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +71 -30
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +4 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +118 -9
- package/dist/extensions/pi-subagents/src/agents/skills.ts +14 -12
- package/dist/extensions/pi-subagents/src/api/delegation.ts +3 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +16 -12
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +17 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +17 -7
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +248 -6
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +31 -6
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +8 -7
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +9 -4
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +33 -4
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +63 -16
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +24 -13
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +7 -5
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -2
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +48 -5
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +68 -1
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +29 -4
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +29 -6
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +29 -3
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +372 -28
- package/dist/extensions/pi-subagents/src/runs/foreground/async-stop-action.ts +65 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +143 -43
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +527 -247
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +426 -123
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +15 -7
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +51 -19
- package/dist/extensions/pi-subagents/src/runs/shared/chain-outputs.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +44 -11
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +8 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +97 -20
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +43 -12
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +52 -4
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +19 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +45 -9
- package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +71 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +31 -1
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +101 -0
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/usage-budget.ts +65 -0
- package/dist/extensions/pi-subagents/src/runs/shared/workflow-graph.ts +26 -1
- package/dist/extensions/pi-subagents/src/shared/settings.ts +17 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +155 -10
- package/dist/extensions/pi-subagents/src/shared/utils.ts +73 -4
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +5 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +46 -4
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +5 -3
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +87 -24
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +182 -9
- package/dist/extensions/pi-subagents/src/tui/render.ts +27 -28
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +14 -7
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +5 -4
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +170 -17
- package/dist/extensions/pi-subagents/src/watchdog/scope.ts +62 -0
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +41 -1
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +10 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +348 -7
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +4 -2
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +51 -2
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +26 -1
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +48 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +213 -13
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +44 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +118 -12
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +850 -7
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +112 -23
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +17 -5
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/register-loader.mjs +3 -3
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +128 -0
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +47 -2
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +60 -0
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +8 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +102 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +6 -0
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +48 -48
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +4 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +176 -8
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +164 -5
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +11 -11
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +18 -2
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +20 -1
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +30 -2
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +10 -2
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +22 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +103 -0
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +18 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +46 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +13 -1
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +29 -4
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +223 -4
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +30 -0
- package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +34 -2
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +78 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +41 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +77 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +3 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/total-cost.test.ts +1 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +210 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-scope.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +32 -0
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +1 -1
- package/dist/extensions/question/index.ts +14 -1
- package/dist/extensions/question/tests/wizard.test.ts +11 -8
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +43 -0
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +3 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +10 -2
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/extension-editor.d.ts +1 -2
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-editor.js +16 -46
- package/dist/modes/interactive/components/extension-editor.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +4 -1
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/scoped-models-selector.js +22 -13
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts +12 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +37 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +72 -64
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +14 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/skills/batch-grill-me/SKILL.md +3 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +19 -8
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/docs/compaction.md +1 -1
- package/docs/custom-provider.md +14 -5
- package/docs/environment-variables.md +86 -0
- package/docs/extensions.md +15 -5
- package/docs/index.md +1 -0
- package/docs/models.md +9 -2
- package/docs/providers.md +21 -2
- package/docs/rpc.md +23 -6
- package/docs/session-format.md +2 -0
- package/docs/settings.md +1 -1
- package/docs/usage.md +0 -13
- package/examples/extensions/custom-compaction.ts +5 -2
- package/examples/extensions/custom-provider-anthropic/index.ts +9 -3
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/handoff.ts +11 -3
- package/examples/extensions/message-renderer.ts +3 -3
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/summarize.ts +5 -2
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/12-full-control.ts +3 -1
- package/package.json +15 -6
- package/dist/extensions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
|
@@ -109,6 +109,14 @@ describe("async resume lookup", () => {
|
|
|
109
109
|
});
|
|
110
110
|
assert.throws(() => resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir }), /capabilityCeiling sources/);
|
|
111
111
|
|
|
112
|
+
writeJson(path.join(asyncDir, "recovery-descriptor.json"), {
|
|
113
|
+
...descriptor,
|
|
114
|
+
launchContractDigest: "launch-contract-digest",
|
|
115
|
+
});
|
|
116
|
+
const valid = resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir });
|
|
117
|
+
assert.equal(valid.launchContractDigest, "launch-contract-digest");
|
|
118
|
+
assert.equal(valid.recoveryDescriptor?.launchContractDigest, "launch-contract-digest");
|
|
119
|
+
|
|
112
120
|
writeJson(path.join(asyncDir, "recovery-descriptor.json"), { ...descriptor, sourceRunId: "another-run" });
|
|
113
121
|
assert.throws(() => resolveAsyncResumeTarget({ id: "run-descriptor" }, { asyncDirRoot: asyncRoot, resultsDir }), /different source run/);
|
|
114
122
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { handleList } from "../../src/agents/agent-management.ts";
|
|
4
|
+
import type { AgentConfig } from "../../src/agents/agents.ts";
|
|
5
|
+
import { resolveSubagentLaunchContract } from "../../src/api/preflight.ts";
|
|
6
|
+
import {
|
|
7
|
+
decodeSubagentCapabilityCeiling,
|
|
8
|
+
encodeSubagentCapabilityCeiling,
|
|
9
|
+
intersectSubagentCapabilityCeilings,
|
|
10
|
+
parseSubagentCapabilityCeiling,
|
|
11
|
+
registerSubagentCapabilityCeiling,
|
|
12
|
+
} from "../../src/api/capability-ceiling.ts";
|
|
13
|
+
import { runSync } from "../../src/runs/foreground/execution.ts";
|
|
14
|
+
import { buildPiArgs } from "../../src/runs/shared/pi-args.ts";
|
|
15
|
+
|
|
16
|
+
function agent(name: string): AgentConfig {
|
|
17
|
+
return {
|
|
18
|
+
name,
|
|
19
|
+
description: `${name} agent`,
|
|
20
|
+
systemPrompt: `${name} prompt`,
|
|
21
|
+
systemPromptMode: "replace",
|
|
22
|
+
inheritProjectContext: false,
|
|
23
|
+
inheritSkills: false,
|
|
24
|
+
source: "project",
|
|
25
|
+
filePath: `/tmp/${name}.md`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe("capability ceiling agent allowlist", () => {
|
|
30
|
+
it("parses, round-trips, and intersects allowedAgents", () => {
|
|
31
|
+
const parsed = parseSubagentCapabilityCeiling({ version: 1, allowedAgents: ["worker", "reviewer", "worker"], denyExtensions: false, sources: ["plan"] });
|
|
32
|
+
assert.deepEqual(parsed.allowedAgents, ["reviewer", "worker"]);
|
|
33
|
+
assert.deepEqual(decodeSubagentCapabilityCeiling(encodeSubagentCapabilityCeiling(parsed)), parsed);
|
|
34
|
+
|
|
35
|
+
assert.deepEqual(intersectSubagentCapabilityCeilings(
|
|
36
|
+
{ version: 1, allowedAgents: ["worker", "reviewer"], denyExtensions: false, sources: ["outer"] },
|
|
37
|
+
{ version: 1, allowedAgents: ["reviewer", "scout"], denyExtensions: true, sources: ["inner"] },
|
|
38
|
+
), {
|
|
39
|
+
version: 1,
|
|
40
|
+
allowedAgents: ["reviewer"],
|
|
41
|
+
denyExtensions: true,
|
|
42
|
+
sources: ["inner", "outer"],
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
assert.deepEqual(intersectSubagentCapabilityCeilings(
|
|
46
|
+
{ version: 1, allowedTools: ["read"], denyExtensions: false, sources: ["tools-only"] },
|
|
47
|
+
{ version: 1, allowedAgents: [], denyExtensions: false, sources: ["none"] },
|
|
48
|
+
)?.allowedAgents, []);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("marks non-allowlisted agents as restricted in list output", () => {
|
|
52
|
+
const sessionId = `allowlist-list-${Date.now()}-${Math.random()}`;
|
|
53
|
+
const handle = registerSubagentCapabilityCeiling({ sessionId, source: "plan-mode", ceiling: { allowedAgents: ["commentator"] } });
|
|
54
|
+
try {
|
|
55
|
+
const result = handleList({}, { cwd: process.cwd(), currentSessionId: sessionId, modelRegistry: { getAvailable: () => [] } });
|
|
56
|
+
const text = result.content[0]?.text ?? "";
|
|
57
|
+
assert.match(text, /Executable agents:/);
|
|
58
|
+
assert.match(text, /- commentator /);
|
|
59
|
+
assert.match(text, /Restricted agents \(not executable in this session; capability ceiling: plan-mode\):/);
|
|
60
|
+
assert.match(text, /- builder /);
|
|
61
|
+
} finally {
|
|
62
|
+
handle.dispose();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("rejects a non-allowlisted agent in preflight launch resolution", async () => {
|
|
67
|
+
const result = await resolveSubagentLaunchContract({
|
|
68
|
+
agent: "builder",
|
|
69
|
+
cwd: process.cwd(),
|
|
70
|
+
capabilityCeiling: { version: 1, allowedAgents: ["commentator"], denyExtensions: false, sources: ["plan-mode"] },
|
|
71
|
+
});
|
|
72
|
+
assert.equal(result.ok, false);
|
|
73
|
+
assert.equal(result.code, "restricted_agent");
|
|
74
|
+
assert.match(result.message, /does not allow agent 'builder'/);
|
|
75
|
+
assert.match(result.message, /Allowed agents: commentator/);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("rejects a non-allowlisted foreground launch before spawning", async () => {
|
|
79
|
+
const result = await runSync(process.cwd(), [agent("builder"), agent("commentator")], "builder", "Do work", {
|
|
80
|
+
capabilityCeiling: { version: 1, allowedAgents: ["commentator"], denyExtensions: false, sources: ["plan-mode"] },
|
|
81
|
+
});
|
|
82
|
+
assert.equal(result.exitCode, 1);
|
|
83
|
+
assert.match(result.error ?? "", /does not allow agent 'builder'/);
|
|
84
|
+
assert.deepEqual(result.capabilityCeiling?.allowedAgents, ["commentator"]);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("includes allowedAgents in propagated launch env and audit metadata", () => {
|
|
88
|
+
const { env, capabilityAudit } = buildPiArgs({
|
|
89
|
+
baseArgs: [],
|
|
90
|
+
task: "Review",
|
|
91
|
+
sessionEnabled: false,
|
|
92
|
+
inheritProjectContext: false,
|
|
93
|
+
inheritSkills: false,
|
|
94
|
+
childAgentName: "commentator",
|
|
95
|
+
capabilityCeiling: { version: 1, allowedAgents: ["commentator"], allowedTools: ["read"], denyExtensions: true, sources: ["plan-mode"] },
|
|
96
|
+
});
|
|
97
|
+
assert.equal(capabilityAudit?.agentAllowed, true);
|
|
98
|
+
assert.deepEqual(capabilityAudit?.agentRestrictionSources, ["plan-mode"]);
|
|
99
|
+
assert.ok(env.SELESAI_SUBAGENT_CAPABILITY_CEILING_V1);
|
|
100
|
+
assert.deepEqual(decodeSubagentCapabilityCeiling(env.SELESAI_SUBAGENT_CAPABILITY_CEILING_V1)?.allowedAgents, ["commentator"]);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -33,7 +33,7 @@ describe("subagent capability ceiling", () => {
|
|
|
33
33
|
});
|
|
34
34
|
|
|
35
35
|
it("rejects malformed policy and disposed updates", () => {
|
|
36
|
-
assert.throws(() => registerSubagentCapabilityCeiling({ sessionId: "x", source: "x", ceiling: {} }), /allowedTools or denyExtensions/);
|
|
36
|
+
assert.throws(() => registerSubagentCapabilityCeiling({ sessionId: "x", source: "x", ceiling: {} }), /allowedTools, allowedAgents, or denyExtensions/);
|
|
37
37
|
const handle = registerSubagentCapabilityCeiling({ sessionId: "disposed", source: "test", ceiling: { denyExtensions: true } });
|
|
38
38
|
handle.dispose();
|
|
39
39
|
assert.throws(() => handle.update({ allowedTools: ["read"] }), /disposed/);
|
|
@@ -198,6 +198,12 @@ describe("chain append requests", () => {
|
|
|
198
198
|
"reviewer:pending",
|
|
199
199
|
"auditor:pending",
|
|
200
200
|
]);
|
|
201
|
+
// Appended steps must carry their own bounded task description for fleet display.
|
|
202
|
+
assert.deepEqual(status.steps?.slice(1).map((step) => step.description), [
|
|
203
|
+
"Use {previous}",
|
|
204
|
+
"Use {previous}",
|
|
205
|
+
"Use {previous}",
|
|
206
|
+
]);
|
|
201
207
|
assert.deepEqual(status.parallelGroups, [{ start: 2, count: 2, stepIndex: 2 }]);
|
|
202
208
|
assert.equal(status.workflowGraph?.nodes[1]?.id, "step-1");
|
|
203
209
|
assert.equal(status.workflowGraph?.nodes[2]?.kind, "parallel-group");
|
|
@@ -285,7 +285,7 @@ describe("registered subagent tool prepareArguments", { skip: !schemasAvailable
|
|
|
285
285
|
const output = execFileSync(
|
|
286
286
|
process.execPath,
|
|
287
287
|
[
|
|
288
|
-
"--experimental-
|
|
288
|
+
"--experimental-strip-types",
|
|
289
289
|
"--import",
|
|
290
290
|
"./test/support/register-loader.mjs",
|
|
291
291
|
"--input-type=module",
|
|
@@ -26,7 +26,7 @@ function assistantText(text: string): Message {
|
|
|
26
26
|
|
|
27
27
|
test("implementation task with no mutation triggers the completion guard", () => {
|
|
28
28
|
const result = evaluateCompletionMutationGuard({
|
|
29
|
-
agent: "
|
|
29
|
+
agent: "builder",
|
|
30
30
|
task: "Implement the approved fix",
|
|
31
31
|
messages: [assistantText("Plan: update the files...")],
|
|
32
32
|
});
|
|
@@ -67,9 +67,9 @@ test("read-only issue drafting tasks do not trigger on suggested fix wording", (
|
|
|
67
67
|
attemptedMutation: false,
|
|
68
68
|
triggered: false,
|
|
69
69
|
});
|
|
70
|
-
assert.equal(expectsImplementationMutation("
|
|
70
|
+
assert.equal(expectsImplementationMutation("builder", task), false);
|
|
71
71
|
assert.equal(
|
|
72
|
-
expectsImplementationMutation("
|
|
72
|
+
expectsImplementationMutation("builder", "Draft GitHub issue for a bug. Include suspected cause and suggested fix."),
|
|
73
73
|
false,
|
|
74
74
|
);
|
|
75
75
|
});
|
|
@@ -89,9 +89,9 @@ test("omitted, bash, unknown, write, and MCP tool capabilities stay conservative
|
|
|
89
89
|
assert.equal(evaluateCompletionMutationGuard({ ...base, tools: ["read", "grep"], mcpDirectTools: ["github/search"] }).triggered, true);
|
|
90
90
|
});
|
|
91
91
|
|
|
92
|
-
test("
|
|
92
|
+
test("builder with mutating-capable tools still triggers when no mutation is observed", () => {
|
|
93
93
|
const result = evaluateCompletionMutationGuard({
|
|
94
|
-
agent: "
|
|
94
|
+
agent: "builder",
|
|
95
95
|
task: "Fix the test implementation",
|
|
96
96
|
messages: [assistantText("I will edit it next")],
|
|
97
97
|
tools: ["read", "edit"],
|
|
@@ -104,10 +104,10 @@ test("worker with mutating-capable tools still triggers when no mutation is obse
|
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
test("
|
|
107
|
+
test("commentator review tasks with bash available do not require mutation", () => {
|
|
108
108
|
const task = "Review prep findings and determine what to implement with playbooks instead of before.";
|
|
109
109
|
const result = evaluateCompletionMutationGuard({
|
|
110
|
-
agent: "
|
|
110
|
+
agent: "commentator",
|
|
111
111
|
task,
|
|
112
112
|
messages: [assistantText("Review complete with file-backed findings.")],
|
|
113
113
|
tools: ["read", "grep", "find", "ls", "bash", "intercom"],
|
|
@@ -121,57 +121,57 @@ test("oracle review tasks with bash available do not require mutation", () => {
|
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
test("review-only, research, and framework output instructions do not expect mutation", () => {
|
|
124
|
-
assert.equal(expectsImplementationMutation("
|
|
125
|
-
assert.equal(expectsImplementationMutation("
|
|
126
|
-
assert.equal(expectsImplementationMutation("
|
|
127
|
-
assert.equal(expectsImplementationMutation("
|
|
128
|
-
assert.equal(expectsImplementationMutation("
|
|
124
|
+
assert.equal(expectsImplementationMutation("builder", "Review only: return findings, do not edit"), false);
|
|
125
|
+
assert.equal(expectsImplementationMutation("builder", "Do not edit files. Tell me how to fix the bug."), false);
|
|
126
|
+
assert.equal(expectsImplementationMutation("builder", "Review the diff and suggest fixes only. Do not edit files."), false);
|
|
127
|
+
assert.equal(expectsImplementationMutation("builder", "Implement this. Do not edit files outside this repo. Do not edit files."), false);
|
|
128
|
+
assert.equal(expectsImplementationMutation("builder", "Investigate why this failed"), false);
|
|
129
129
|
assert.equal(expectsImplementationMutation("researcher", "Research the API behavior"), false);
|
|
130
130
|
assert.equal(expectsImplementationMutation("researcher", "Research this and patch the bug"), false);
|
|
131
|
-
assert.equal(expectsImplementationMutation("
|
|
132
|
-
assert.equal(expectsImplementationMutation("
|
|
133
|
-
assert.equal(expectsImplementationMutation("
|
|
134
|
-
assert.equal(expectsImplementationMutation("
|
|
135
|
-
assert.equal(expectsImplementationMutation("
|
|
136
|
-
assert.equal(expectsImplementationMutation("
|
|
137
|
-
assert.equal(expectsImplementationMutation("
|
|
138
|
-
assert.equal(expectsImplementationMutation("
|
|
139
|
-
assert.equal(expectsImplementationMutation("
|
|
131
|
+
assert.equal(expectsImplementationMutation("commentator", "Review this and fix any real issues"), false);
|
|
132
|
+
assert.equal(expectsImplementationMutation("commentator", "Review this and fix any real issues; regardless of findings, apply changes directly"), true);
|
|
133
|
+
assert.equal(expectsImplementationMutation("builder", "[Write to: /tmp/result.md]\n\nSummarize findings"), false);
|
|
134
|
+
assert.equal(expectsImplementationMutation("builder", "Write report"), false);
|
|
135
|
+
assert.equal(expectsImplementationMutation("builder", "Create a report"), false);
|
|
136
|
+
assert.equal(expectsImplementationMutation("builder", "Create a summary"), false);
|
|
137
|
+
assert.equal(expectsImplementationMutation("builder", "Add a report"), false);
|
|
138
|
+
assert.equal(expectsImplementationMutation("builder", "Update a summary"), false);
|
|
139
|
+
assert.equal(expectsImplementationMutation("builder", "Write to {chain_dir}"), false);
|
|
140
140
|
assert.equal(
|
|
141
|
-
expectsImplementationMutation("
|
|
141
|
+
expectsImplementationMutation("builder", "Do async work\nUpdate progress at: /tmp/progress.md\n**Output:**\nWrite your findings to exactly this path: /tmp/out.md\nThis path is authoritative for this run.\nIgnore any other output filename or output path mentioned elsewhere."),
|
|
142
142
|
false,
|
|
143
143
|
);
|
|
144
144
|
});
|
|
145
145
|
|
|
146
|
-
test("
|
|
147
|
-
assert.equal(expectsImplementationMutation("
|
|
148
|
-
assert.equal(expectsImplementationMutation("
|
|
149
|
-
assert.equal(expectsImplementationMutation("
|
|
150
|
-
assert.equal(expectsImplementationMutation("
|
|
151
|
-
assert.equal(expectsImplementationMutation("
|
|
152
|
-
assert.equal(expectsImplementationMutation("
|
|
153
|
-
assert.equal(expectsImplementationMutation("
|
|
154
|
-
assert.equal(expectsImplementationMutation("
|
|
155
|
-
assert.equal(expectsImplementationMutation("
|
|
156
|
-
assert.equal(expectsImplementationMutation("
|
|
157
|
-
assert.equal(expectsImplementationMutation("
|
|
158
|
-
assert.equal(expectsImplementationMutation("
|
|
146
|
+
test("builder implementation verbs win over investigative wording and scoped prohibitions", () => {
|
|
147
|
+
assert.equal(expectsImplementationMutation("builder", "Investigate why the worker did not edit files and fix it"), true);
|
|
148
|
+
assert.equal(expectsImplementationMutation("builder", "Do not modify tests; implement the fix"), true);
|
|
149
|
+
assert.equal(expectsImplementationMutation("builder", "Do not modify tests — implement the fix"), true);
|
|
150
|
+
assert.equal(expectsImplementationMutation("builder", "Research the current code path and patch the bug"), true);
|
|
151
|
+
assert.equal(expectsImplementationMutation("builder", "Fix the bug where no edits were made"), true);
|
|
152
|
+
assert.equal(expectsImplementationMutation("builder", "Fix lint"), true);
|
|
153
|
+
assert.equal(expectsImplementationMutation("builder", "Fix the build"), true);
|
|
154
|
+
assert.equal(expectsImplementationMutation("builder", "Fix TypeScript errors"), true);
|
|
155
|
+
assert.equal(expectsImplementationMutation("builder", "Fix CI"), true);
|
|
156
|
+
assert.equal(expectsImplementationMutation("builder", "Fix the failing test"), true);
|
|
157
|
+
assert.equal(expectsImplementationMutation("builder", "Patch the cold start test"), true);
|
|
158
|
+
assert.equal(expectsImplementationMutation("builder", "Implement the fix and return findings."), true);
|
|
159
159
|
});
|
|
160
160
|
|
|
161
161
|
test("non-worker implementation tasks still expect mutation", () => {
|
|
162
162
|
assert.equal(expectsImplementationMutation("delegate", "Fix the bug where no edits were made"), true);
|
|
163
163
|
assert.equal(expectsImplementationMutation("delegate", "Apply the suggested fix to src/runs/shared/completion-guard.ts"), true);
|
|
164
|
-
assert.equal(expectsImplementationMutation("
|
|
164
|
+
assert.equal(expectsImplementationMutation("builder", "Draft a GitHub issue, then implement the fix"), true);
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
-
test("
|
|
168
|
-
assert.equal(expectsImplementationMutation("
|
|
169
|
-
assert.equal(expectsImplementationMutation("
|
|
170
|
-
assert.equal(expectsImplementationMutation("
|
|
171
|
-
assert.equal(expectsImplementationMutation("
|
|
172
|
-
assert.equal(expectsImplementationMutation("
|
|
173
|
-
assert.equal(expectsImplementationMutation("
|
|
174
|
-
assert.equal(expectsImplementationMutation("
|
|
167
|
+
test("builder edit intent covers common docs, config, and source tasks", () => {
|
|
168
|
+
assert.equal(expectsImplementationMutation("builder", "Update README to mention the native tool"), true);
|
|
169
|
+
assert.equal(expectsImplementationMutation("builder", "Remove share functionality and all Vercel references"), true);
|
|
170
|
+
assert.equal(expectsImplementationMutation("builder", "Replace the registered command with a render tool"), true);
|
|
171
|
+
assert.equal(expectsImplementationMutation("builder", "Create completion-guard.ts"), true);
|
|
172
|
+
assert.equal(expectsImplementationMutation("builder", "Add tests for the completion guard"), true);
|
|
173
|
+
assert.equal(expectsImplementationMutation("builder", "Implement the approved fixes. Do not edit files outside this repo."), true);
|
|
174
|
+
assert.equal(expectsImplementationMutation("builder", "Implement the fix. Do not edit unrelated files."), true);
|
|
175
175
|
});
|
|
176
176
|
|
|
177
177
|
test("edit and write tool calls count as mutation attempts", () => {
|
|
@@ -195,7 +195,7 @@ test("obvious mutating bash commands count as mutation attempts", () => {
|
|
|
195
195
|
|
|
196
196
|
test("implementation task with mutation attempts does not trigger", () => {
|
|
197
197
|
const result = evaluateCompletionMutationGuard({
|
|
198
|
-
agent: "
|
|
198
|
+
agent: "builder",
|
|
199
199
|
task: "Fix the failing test",
|
|
200
200
|
messages: [assistantToolCall("edit", { path: "test.ts" })],
|
|
201
201
|
});
|
|
@@ -279,7 +279,7 @@ test("provider checkpoint with a changed commit counts as mutation evidence", ()
|
|
|
279
279
|
assert.equal(hasMutationToolCall([message]), true);
|
|
280
280
|
assert.equal(
|
|
281
281
|
evaluateCompletionMutationGuard({
|
|
282
|
-
agent: "
|
|
282
|
+
agent: "builder",
|
|
283
283
|
task: "Edit the target source file",
|
|
284
284
|
messages: [message],
|
|
285
285
|
}).triggered,
|
|
@@ -297,7 +297,7 @@ test("unchanged provider checkpoint does not bypass the completion guard", () =>
|
|
|
297
297
|
assert.equal(hasMutationToolCall([message]), false);
|
|
298
298
|
assert.equal(
|
|
299
299
|
evaluateCompletionMutationGuard({
|
|
300
|
-
agent: "
|
|
300
|
+
agent: "builder",
|
|
301
301
|
task: "Edit the target source file",
|
|
302
302
|
messages: [message],
|
|
303
303
|
}).triggered,
|
|
@@ -308,7 +308,7 @@ test("unchanged provider checkpoint does not bypass the completion guard", () =>
|
|
|
308
308
|
|
|
309
309
|
test("implementation task with Cursor edit thinking does not trigger", () => {
|
|
310
310
|
const result = evaluateCompletionMutationGuard({
|
|
311
|
-
agent: "
|
|
311
|
+
agent: "builder",
|
|
312
312
|
task: "Edit docs/BACKEND_ARCHITECTURE.md",
|
|
313
313
|
messages: [
|
|
314
314
|
assistantThinking("Cursor edit: docs/BACKEND_ARCHITECTURE.md added 1 line\n"),
|
|
@@ -65,6 +65,29 @@ describe("config directory resolution", () => {
|
|
|
65
65
|
}
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
it("invalidates cached runtime resolution when the package root changes", () => {
|
|
69
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-config-cache-"));
|
|
70
|
+
try {
|
|
71
|
+
const firstRoot = path.join(tempDir, "first");
|
|
72
|
+
const secondRoot = path.join(tempDir, "second");
|
|
73
|
+
for (const [root, configDir] of [[firstRoot, ".first-pi"], [secondRoot, ".second-pi"]] as const) {
|
|
74
|
+
fs.mkdirSync(root, { recursive: true });
|
|
75
|
+
fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({
|
|
76
|
+
name: "@selesai/code",
|
|
77
|
+
piConfig: { configDir },
|
|
78
|
+
}), "utf-8");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = firstRoot;
|
|
82
|
+
assert.equal(getConfigDirName(), ".first-pi");
|
|
83
|
+
assert.equal(getConfigDirName(), ".first-pi");
|
|
84
|
+
process.env[SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV] = secondRoot;
|
|
85
|
+
assert.equal(getConfigDirName(), ".second-pi");
|
|
86
|
+
} finally {
|
|
87
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
68
91
|
it("canonicalizes watcher paths and preserves the original path when native realpath fails", () => {
|
|
69
92
|
assert.equal(resolveWatchPath("C:\\SHORT~1\\watch", () => "C:\\Long Path\\watch"), "C:\\Long Path\\watch");
|
|
70
93
|
assert.equal(resolveWatchPath("C:\\SHORT~1\\watch", () => { throw new Error("missing"); }), "C:\\SHORT~1\\watch");
|
|
@@ -148,6 +148,33 @@ describe("control channel: request file", () => {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
+
it("keeps steer requests for retry when the inbox cannot be scanned", () => {
|
|
152
|
+
const asyncDir = tmpAsyncDir("pi-control-steer-scan-retry-");
|
|
153
|
+
try {
|
|
154
|
+
requestAsyncSteer(asyncDir, { message: "retry me", id: "retry", ts: 1 });
|
|
155
|
+
let failScan = true;
|
|
156
|
+
const fsImpl = {
|
|
157
|
+
existsSync: fs.existsSync,
|
|
158
|
+
readdirSync: ((target: fs.PathLike) => {
|
|
159
|
+
if (failScan) {
|
|
160
|
+
failScan = false;
|
|
161
|
+
throw Object.assign(new Error("file table overflow"), { code: "ENFILE" });
|
|
162
|
+
}
|
|
163
|
+
return fs.readdirSync(target);
|
|
164
|
+
}) as typeof fs.readdirSync,
|
|
165
|
+
readFileSync: fs.readFileSync,
|
|
166
|
+
rmSync: fs.rmSync,
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
assert.deepEqual(consumeSteerRequests(asyncDir, fsImpl), []);
|
|
170
|
+
assert.deepEqual(consumeSteerRequests(asyncDir, fsImpl), [
|
|
171
|
+
{ type: "steer", id: "retry", ts: 1, message: "retry me" },
|
|
172
|
+
]);
|
|
173
|
+
} finally {
|
|
174
|
+
cleanup(asyncDir);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
151
178
|
it("does not deliver a steer request if another consumer removed it first", () => {
|
|
152
179
|
const asyncDir = tmpAsyncDir("pi-control-steer-concurrent-");
|
|
153
180
|
try {
|
|
@@ -213,7 +213,7 @@ describe("public subagent delegation contract", () => {
|
|
|
213
213
|
},
|
|
214
214
|
executeVersioned: async (_id, params, _signal, _ctx, onUpdate) => {
|
|
215
215
|
observedParams = params as unknown as Record<string, unknown>;
|
|
216
|
-
onUpdate({ details: { mode: "single", results: [{ agent: "reviewer", model: "openai/gpt-5", thinking: "high" }], progress: [{ currentTool: "read" }] } });
|
|
216
|
+
onUpdate({ details: { mode: "single", runId: "run-v2", results: [{ agent: "reviewer", model: "openai/gpt-5", thinking: "high" }], progress: [{ currentTool: "read" }] } });
|
|
217
217
|
return {
|
|
218
218
|
details: {
|
|
219
219
|
mode: "single",
|
|
@@ -223,6 +223,7 @@ describe("public subagent delegation contract", () => {
|
|
|
223
223
|
exitCode: 0,
|
|
224
224
|
model: "openai/gpt-5",
|
|
225
225
|
thinking: "high",
|
|
226
|
+
launchContractDigest: "launch-contract-digest",
|
|
226
227
|
finalOutput: '{"looks":"json"}',
|
|
227
228
|
usage: { input: 2, output: 3, cacheRead: 4, cacheWrite: 5, cost: 0.01, turns: 2 },
|
|
228
229
|
progressSummary: { toolCount: 6, tokens: 5, durationMs: 7 },
|
|
@@ -237,7 +238,7 @@ describe("public subagent delegation contract", () => {
|
|
|
237
238
|
const responsePromise = once(events, SUBAGENT_DELEGATION_RESPONSE_EVENT);
|
|
238
239
|
events.emit(SUBAGENT_DELEGATION_REQUEST_EVENT, textRequest);
|
|
239
240
|
assert.deepEqual(await startedPromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1" });
|
|
240
|
-
assert.deepEqual(await updatePromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1", currentTool: "read", model: "openai/gpt-5" });
|
|
241
|
+
assert.deepEqual(await updatePromise, { version: 2, requestId: "attempt-1", ownerRunId: "owner-1", nodeId: "node-1", runId: "run-v2", currentTool: "read", model: "openai/gpt-5" });
|
|
241
242
|
assert.deepEqual(await responsePromise, {
|
|
242
243
|
version: 2,
|
|
243
244
|
requestId: "attempt-1",
|
|
@@ -249,6 +250,7 @@ describe("public subagent delegation contract", () => {
|
|
|
249
250
|
model: "openai/gpt-5",
|
|
250
251
|
thinking: "high",
|
|
251
252
|
exitCode: 0,
|
|
253
|
+
launchContractDigest: "launch-contract-digest",
|
|
252
254
|
result: { kind: "text", text: '{"looks":"json"}' },
|
|
253
255
|
usage: { input: 2, output: 3, cacheRead: 4, cacheWrite: 5, cost: 0.01, turns: 2, toolCalls: 6, durationMs: 7 },
|
|
254
256
|
} satisfies SubagentDelegationV2Response);
|
|
@@ -200,6 +200,7 @@ describe("dynamic fanout helpers", () => {
|
|
|
200
200
|
const result = (agent: string, structuredOutput: unknown): SingleResult => ({
|
|
201
201
|
agent,
|
|
202
202
|
task: "t",
|
|
203
|
+
index: 0,
|
|
203
204
|
exitCode: 0,
|
|
204
205
|
messages: [],
|
|
205
206
|
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 },
|