@selesai/code 0.5.20 → 0.5.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/extensions/handoff-new.test.ts +8 -9
- package/dist/extensions/handoff-new.ts +6 -8
- package/dist/extensions/pi-subagents/CHANGELOG.md +1367 -0
- package/dist/extensions/pi-subagents/README.md +602 -220
- package/dist/extensions/pi-subagents/banner.png +0 -0
- package/dist/extensions/pi-subagents/index.ts +1 -0
- package/dist/extensions/pi-subagents/install.mjs +3 -3
- package/dist/extensions/pi-subagents/package-lock.json +3405 -0
- package/dist/extensions/pi-subagents/package.json +26 -14
- package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
- package/dist/extensions/pi-subagents/prompts/parallel-context-build.md +3 -3
- package/dist/extensions/pi-subagents/prompts/parallel-handoff-plan.md +7 -7
- package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
- package/dist/extensions/pi-subagents/prompts/review-loop.md +13 -11
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +267 -176
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +89 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +19 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +218 -120
- package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +67 -13
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
- package/dist/extensions/pi-subagents/src/agents/skills.ts +25 -12
- package/dist/extensions/pi-subagents/src/api/background-work.ts +197 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +17 -0
- package/dist/extensions/pi-subagents/src/api/delegation.ts +285 -0
- package/dist/extensions/pi-subagents/src/api/preflight.ts +399 -0
- package/dist/extensions/pi-subagents/src/extension/chain-validation.ts +165 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +7 -1
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +15 -0
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +3 -1
- package/dist/extensions/pi-subagents/src/extension/index.ts +113 -157
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +41 -4
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +45 -15
- package/dist/extensions/pi-subagents/src/extension/steering-notices.ts +35 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +28 -15
- package/dist/extensions/pi-subagents/src/intercom/intercom-bridge.ts +4 -3
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +225 -29
- package/dist/extensions/pi-subagents/src/intercom/result-intercom.ts +11 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -10
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +452 -62
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +60 -9
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +198 -52
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +119 -21
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +67 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-append.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +16 -8
- package/dist/extensions/pi-subagents/src/runs/background/completion-batcher.ts +6 -4
- package/dist/extensions/pi-subagents/src/runs/background/completion-dedupe.ts +2 -11
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +260 -13
- package/dist/extensions/pi-subagents/src/runs/background/fleet-view.ts +32 -6
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +171 -90
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +280 -0
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +149 -88
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +14 -2
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +33 -17
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +9 -1
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +38 -10
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +237 -0
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +1297 -307
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +610 -0
- package/dist/extensions/pi-subagents/src/runs/background/top-level-async.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/background/wait-config.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-tool.ts +26 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +230 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +22 -6
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +228 -140
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +452 -138
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +90 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +1001 -416
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +443 -132
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +38 -0
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +178 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +121 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +41 -93
- package/dist/extensions/pi-subagents/src/runs/shared/context-mode.ts +44 -0
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +11 -9
- package/dist/extensions/pi-subagents/src/runs/shared/long-running-guard.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +12 -6
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +36 -0
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +44 -7
- package/dist/extensions/pi-subagents/src/runs/shared/nested-render.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +154 -0
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +18 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +174 -54
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +38 -31
- package/dist/extensions/pi-subagents/src/runs/shared/run-history.ts +90 -5
- package/dist/extensions/pi-subagents/src/runs/shared/session-lease.ts +299 -0
- package/dist/extensions/pi-subagents/src/runs/shared/single-output.ts +61 -6
- package/dist/extensions/pi-subagents/src/runs/shared/spawn-budget.ts +128 -0
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +112 -7
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +14 -6
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +149 -36
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +181 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +83 -0
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +11 -5
- package/dist/extensions/pi-subagents/src/runs/shared/turn-budget.ts +50 -4
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +63 -14
- package/dist/extensions/pi-subagents/src/shared/accessible-dir.ts +25 -0
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +37 -7
- package/dist/extensions/pi-subagents/src/shared/atomic-json.ts +18 -43
- package/dist/extensions/pi-subagents/src/shared/child-transcript.ts +52 -0
- package/dist/extensions/pi-subagents/src/shared/env.ts +16 -0
- package/dist/extensions/pi-subagents/src/shared/file-system-retry.ts +47 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +28 -3
- package/dist/extensions/pi-subagents/src/shared/launch-contract.ts +123 -0
- package/dist/extensions/pi-subagents/src/shared/model-info.ts +8 -5
- package/dist/extensions/pi-subagents/src/shared/settings.ts +9 -1
- package/dist/extensions/pi-subagents/src/shared/status-format.ts +7 -1
- package/dist/extensions/pi-subagents/src/shared/types.ts +522 -51
- package/dist/extensions/pi-subagents/src/shared/utils.ts +59 -53
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +604 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-json.ts +108 -0
- package/dist/extensions/pi-subagents/src/slash/delegation-request.ts +249 -0
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +353 -345
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/selector.ts +147 -0
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +265 -23
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +2 -2
- package/dist/extensions/pi-subagents/src/slash/subagents-admin.ts +428 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +362 -0
- package/dist/extensions/pi-subagents/src/tui/fleet-transcript.ts +472 -0
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +664 -0
- package/dist/extensions/pi-subagents/src/tui/render.ts +115 -31
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +220 -0
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +205 -0
- package/dist/extensions/pi-subagents/src/watchdog/emission-guard.ts +123 -0
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +532 -0
- package/dist/extensions/pi-subagents/src/watchdog/model-selection.ts +167 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +117 -0
- package/dist/extensions/pi-subagents/src/watchdog/register-main.ts +433 -0
- package/dist/extensions/pi-subagents/src/watchdog/render.ts +54 -0
- package/dist/extensions/pi-subagents/src/watchdog/review.ts +298 -0
- package/dist/extensions/pi-subagents/src/watchdog/runtime.ts +714 -0
- package/dist/extensions/pi-subagents/src/watchdog/settings.ts +528 -0
- package/dist/extensions/pi-subagents/src/watchdog/tool-actions.ts +155 -0
- package/dist/extensions/pi-subagents/src/watchdog/turn-delta.ts +161 -0
- package/dist/extensions/pi-subagents/src/watchdog/types.ts +188 -0
- package/dist/extensions/pi-subagents/src/watchdog/warning-format.ts +73 -0
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +130 -2
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +439 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +1632 -61
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +54 -1
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +112 -0
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +98 -1
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +179 -9
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +16 -9
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +6 -5
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +589 -9
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +528 -21
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +227 -3
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +235 -7
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +172 -2
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +1502 -18
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +993 -4
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +27 -0
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +7 -1
- package/dist/extensions/pi-subagents/test/support/helpers.ts +32 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +59 -2
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +32 -6
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +25 -24
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +59 -35
- package/dist/extensions/pi-subagents/test/support/session-lease-child.mjs +42 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +703 -69
- package/dist/extensions/pi-subagents/test/unit/accessible-dir.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +478 -19
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +228 -7
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +198 -78
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +15 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +102 -7
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +439 -6
- package/dist/extensions/pi-subagents/test/unit/atomic-json.test.ts +41 -1
- package/dist/extensions/pi-subagents/test/unit/auto-drain.test.ts +79 -0
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +285 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +68 -0
- package/dist/extensions/pi-subagents/test/unit/chain-validation.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +82 -0
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +46 -4
- package/dist/extensions/pi-subagents/test/unit/completion-batcher.test.ts +3 -1
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +9 -17
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +175 -3
- package/dist/extensions/pi-subagents/test/unit/config-dir-runtime.test.ts +10 -5
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +126 -6
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +219 -0
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +913 -0
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +13 -2
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +351 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-transcript.test.ts +280 -0
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +575 -0
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +65 -0
- package/dist/extensions/pi-subagents/test/unit/fork-context.test.ts +94 -1
- package/dist/extensions/pi-subagents/test/unit/get-final-output.test.ts +23 -0
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +157 -0
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +367 -5
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +11 -0
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +36 -0
- package/dist/extensions/pi-subagents/test/unit/model-info.test.ts +25 -3
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +341 -10
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +16 -0
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +52 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +168 -7
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +85 -7
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +243 -16
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +79 -36
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +174 -56
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +322 -0
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +204 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +20 -12
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +117 -4
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +40 -7
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +48 -1
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +21 -3
- package/dist/extensions/pi-subagents/test/unit/selector.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/unit/session-lease.test.ts +326 -0
- package/dist/extensions/pi-subagents/test/unit/single-output.test.ts +101 -2
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +111 -1
- package/dist/extensions/pi-subagents/test/unit/spawn-budget.test.ts +124 -0
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +6 -4
- package/dist/extensions/pi-subagents/test/unit/status-format.test.ts +7 -0
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +397 -0
- package/dist/extensions/pi-subagents/test/unit/steering-notices.test.ts +58 -0
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +173 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +25 -4
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +390 -25
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +837 -0
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +86 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +47 -1
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +56 -10
- package/dist/extensions/pi-subagents/test/unit/watchdog-change-signature.test.ts +387 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +110 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-emission-guard.test.ts +62 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +144 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-model-selection.test.ts +121 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-render.test.ts +76 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-review.test.ts +327 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +863 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +290 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +91 -0
- package/dist/extensions/pi-subagents/test/unit/watchdog-turn-delta.test.ts +130 -0
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +32 -4
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +5 -1
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +30 -0
- package/dist/extensions/question/batch.ts +39 -0
- package/dist/extensions/question/dialog-adapter.ts +23 -1
- package/dist/extensions/question/index.ts +237 -7
- package/dist/extensions/question/schemas.ts +28 -15
- package/dist/extensions/question/tests/batch.test.ts +26 -0
- package/dist/extensions/question/tests/ui-protocol.test.ts +23 -3
- package/dist/extensions/question/tui-adapter.ts +2 -3
- package/dist/extensions/question/types.ts +37 -0
- package/dist/extensions/question/ui-protocol.ts +3 -3
- package/dist/skills/batch-grill-me/SKILL.md +3 -1
- package/package.json +1 -1
|
@@ -68,20 +68,20 @@ describe("builtin agent overrides", () => {
|
|
|
68
68
|
subagents: {
|
|
69
69
|
defaultModel: "deepseek-v4-flash",
|
|
70
70
|
agentOverrides: {
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
commentator: { model: "deepseek-v4-pro" },
|
|
72
|
+
builder: { model: false },
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
const builtins = discoverAgentsAll(tempProject).builtin;
|
|
78
|
-
const
|
|
79
|
-
assert.equal(
|
|
80
|
-
assert.equal(
|
|
81
|
-
assert.equal(
|
|
82
|
-
assert.equal(builtins.find((agent) => agent.name === "
|
|
83
|
-
assert.equal(builtins.find((agent) => agent.name === "
|
|
84
|
-
assert.equal(builtins.find((agent) => agent.name === "
|
|
78
|
+
const architect = builtins.find((agent) => agent.name === "architect");
|
|
79
|
+
assert.equal(architect?.model, "deepseek-v4-flash");
|
|
80
|
+
assert.equal(architect?.modelSource?.type, "subagents.defaultModel");
|
|
81
|
+
assert.equal(architect?.modelSource?.scope, "user");
|
|
82
|
+
assert.equal(builtins.find((agent) => agent.name === "explorer")?.model, "deepseek-v4-flash");
|
|
83
|
+
assert.equal(builtins.find((agent) => agent.name === "commentator")?.model, "deepseek-v4-pro");
|
|
84
|
+
assert.equal(builtins.find((agent) => agent.name === "builder")?.model, undefined);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
it("prefers project subagents.defaultModel over user defaultModel", () => {
|
|
@@ -93,9 +93,70 @@ describe("builtin agent overrides", () => {
|
|
|
93
93
|
subagents: { defaultModel: "deepseek-v4-pro" },
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
const
|
|
97
|
-
assert.ok(
|
|
98
|
-
assert.equal(
|
|
96
|
+
const explorer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "explorer");
|
|
97
|
+
assert.ok(explorer);
|
|
98
|
+
assert.equal(explorer.model, "deepseek-v4-pro");
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("applies subagents.defaultThinking only when thinking is unset", () => {
|
|
102
|
+
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
103
|
+
subagents: {
|
|
104
|
+
defaultThinking: " low ",
|
|
105
|
+
agentOverrides: {
|
|
106
|
+
recapper: { thinking: "xhigh" },
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
writeUserAgent(tempHome, "user-default", `---\nname: user-default\ndescription: User agent\n---\n\nUse the default.\n`);
|
|
111
|
+
writeProjectAgent(tempProject, "project-default", `---\nname: project-default\ndescription: Project agent\n---\n\nUse the default.\n`);
|
|
112
|
+
writeProjectAgent(tempProject, "explicit-off", `---\nname: explicit-off\ndescription: Explicitly disabled\nthinking: false\n---\n\nStay off.\n`);
|
|
113
|
+
|
|
114
|
+
const discovered = discoverAgentsAll(tempProject);
|
|
115
|
+
assert.equal(discovered.builtin.find((agent) => agent.name === "recapper")?.thinking, "xhigh");
|
|
116
|
+
assert.equal(discovered.builtin.find((agent) => agent.name === "builder")?.thinking, "high");
|
|
117
|
+
assert.equal(discovered.user.find((agent) => agent.name === "user-default")?.thinking, "low");
|
|
118
|
+
assert.equal(discovered.project.find((agent) => agent.name === "project-default")?.thinking, "low");
|
|
119
|
+
assert.equal(discovered.project.find((agent) => agent.name === "explicit-off")?.thinking, false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("prefers project subagents.defaultThinking over user defaultThinking", () => {
|
|
123
|
+
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
124
|
+
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
125
|
+
subagents: { defaultThinking: "low" },
|
|
126
|
+
});
|
|
127
|
+
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
128
|
+
subagents: { defaultThinking: "high" },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const recapper = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "recapper");
|
|
132
|
+
assert.ok(recapper);
|
|
133
|
+
assert.equal(recapper.thinking, "high");
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("preserves custom-agent thinking when disableThinking clears builtin defaults", () => {
|
|
137
|
+
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
138
|
+
subagents: { defaultThinking: "low", disableThinking: true },
|
|
139
|
+
});
|
|
140
|
+
writeProjectAgent(tempProject, "custom-default", `---\nname: custom-default\ndescription: Custom default\n---\n\nUse the default.\n`);
|
|
141
|
+
writeProjectAgent(tempProject, "custom-explicit", `---\nname: custom-explicit\ndescription: Custom explicit\nthinking: high\n---\n\nUse the explicit level.\n`);
|
|
142
|
+
|
|
143
|
+
const discovered = discoverAgentsAll(tempProject);
|
|
144
|
+
assert.equal(discovered.builtin.find((agent) => agent.name === "builder")?.thinking, undefined);
|
|
145
|
+
assert.equal(discovered.project.find((agent) => agent.name === "custom-default")?.thinking, "low");
|
|
146
|
+
assert.equal(discovered.project.find((agent) => agent.name === "custom-explicit")?.thinking, "high");
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("surfaces malformed defaultThinking settings", () => {
|
|
150
|
+
const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
|
|
151
|
+
for (const defaultThinking of ["", 42]) {
|
|
152
|
+
writeJson(settingsPath, { subagents: { defaultThinking } });
|
|
153
|
+
assert.throws(
|
|
154
|
+
() => discoverAgents(tempProject, "both"),
|
|
155
|
+
(error: unknown) => error instanceof Error
|
|
156
|
+
&& error.message.includes(settingsPath)
|
|
157
|
+
&& error.message.includes("defaultThinking"),
|
|
158
|
+
);
|
|
159
|
+
}
|
|
99
160
|
});
|
|
100
161
|
|
|
101
162
|
it("applies subagents.defaultModel to custom agents without a frontmatter model", () => {
|
|
@@ -109,24 +170,25 @@ describe("builtin agent overrides", () => {
|
|
|
109
170
|
});
|
|
110
171
|
writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
|
|
111
172
|
writeProjectAgent(tempProject, "auditor", `---\nname: auditor\ndescription: Audit code\nmodel: google/gemini-3-pro\n---\n\nAudit the code.\n`);
|
|
112
|
-
writeProjectAgent(tempProject, "
|
|
173
|
+
writeProjectAgent(tempProject, "architect-copy", `---\nname: architect-copy\ndescription: Scout code\n---\n\nScout the code.\n`);
|
|
113
174
|
|
|
114
175
|
const agents = discoverAgents(tempProject, "both").agents;
|
|
115
176
|
assert.equal(agents.find((agent) => agent.name === "implementer")?.model, "deepseek-v4-pro");
|
|
116
177
|
assert.equal(agents.find((agent) => agent.name === "auditor")?.model, "google/gemini-3-pro");
|
|
117
|
-
assert.equal(agents.find((agent) => agent.name === "
|
|
178
|
+
assert.equal(agents.find((agent) => agent.name === "architect-copy")?.model, "deepseek-v4-flash");
|
|
118
179
|
});
|
|
119
180
|
|
|
120
181
|
it("applies user settings overrides to builtin agents", () => {
|
|
121
182
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
122
183
|
subagents: {
|
|
123
184
|
agentOverrides: {
|
|
124
|
-
|
|
185
|
+
builder: {
|
|
125
186
|
model: "openai/gpt-5.4",
|
|
126
187
|
thinking: "xhigh",
|
|
127
188
|
systemPromptMode: "replace",
|
|
128
189
|
inheritProjectContext: true,
|
|
129
190
|
inheritSkills: true,
|
|
191
|
+
acceptanceRole: "writer",
|
|
130
192
|
subagentOnlyExtensions: ["./tools/child-review.ts"],
|
|
131
193
|
completionGuard: false,
|
|
132
194
|
},
|
|
@@ -134,18 +196,19 @@ describe("builtin agent overrides", () => {
|
|
|
134
196
|
},
|
|
135
197
|
});
|
|
136
198
|
|
|
137
|
-
const
|
|
138
|
-
assert.ok(
|
|
139
|
-
assert.equal(
|
|
140
|
-
assert.equal(
|
|
141
|
-
assert.equal(
|
|
142
|
-
assert.equal(
|
|
143
|
-
assert.equal(
|
|
144
|
-
assert.equal(
|
|
145
|
-
assert.
|
|
146
|
-
assert.
|
|
147
|
-
assert.equal(
|
|
148
|
-
assert.equal(
|
|
199
|
+
const builder = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "builder");
|
|
200
|
+
assert.ok(builder);
|
|
201
|
+
assert.equal(builder.source, "builtin");
|
|
202
|
+
assert.equal(builder.model, "openai/gpt-5.4");
|
|
203
|
+
assert.equal(builder.thinking, "xhigh");
|
|
204
|
+
assert.equal(builder.systemPromptMode, "replace");
|
|
205
|
+
assert.equal(builder.inheritProjectContext, true);
|
|
206
|
+
assert.equal(builder.inheritSkills, true);
|
|
207
|
+
assert.equal(builder.acceptanceRole, "writer");
|
|
208
|
+
assert.deepEqual(builder.subagentOnlyExtensions, ["./tools/child-review.ts"]);
|
|
209
|
+
assert.equal(builder.completionGuard, false);
|
|
210
|
+
assert.equal(builder.override?.scope, "user");
|
|
211
|
+
assert.equal(builder.override?.path, path.join(tempHome, ".selesai", "agent", "settings.json"));
|
|
149
212
|
});
|
|
150
213
|
|
|
151
214
|
it("globally disables builtin thinking suffix defaults from user settings", () => {
|
|
@@ -156,7 +219,7 @@ describe("builtin agent overrides", () => {
|
|
|
156
219
|
});
|
|
157
220
|
|
|
158
221
|
const builtins = discoverAgentsAll(tempProject).builtin;
|
|
159
|
-
assert.ok(builtins.some((agent) => agent.name === "
|
|
222
|
+
assert.ok(builtins.some((agent) => agent.name === "builder"));
|
|
160
223
|
assert.deepEqual(
|
|
161
224
|
builtins
|
|
162
225
|
.filter((agent) => agent.thinking !== undefined)
|
|
@@ -164,7 +227,7 @@ describe("builtin agent overrides", () => {
|
|
|
164
227
|
[],
|
|
165
228
|
);
|
|
166
229
|
assert.equal(
|
|
167
|
-
builtins.find((agent) => agent.name === "
|
|
230
|
+
builtins.find((agent) => agent.name === "builder")?.override?.path,
|
|
168
231
|
path.join(tempHome, ".selesai", "agent", "settings.json"),
|
|
169
232
|
);
|
|
170
233
|
});
|
|
@@ -174,7 +237,7 @@ describe("builtin agent overrides", () => {
|
|
|
174
237
|
subagents: {
|
|
175
238
|
disableThinking: true,
|
|
176
239
|
agentOverrides: {
|
|
177
|
-
|
|
240
|
+
builder: {
|
|
178
241
|
thinking: "high",
|
|
179
242
|
},
|
|
180
243
|
},
|
|
@@ -182,12 +245,12 @@ describe("builtin agent overrides", () => {
|
|
|
182
245
|
});
|
|
183
246
|
|
|
184
247
|
const agents = discoverAgents(tempProject, "both").agents;
|
|
185
|
-
const
|
|
186
|
-
const
|
|
187
|
-
assert.ok(
|
|
188
|
-
assert.ok(
|
|
189
|
-
assert.equal(
|
|
190
|
-
assert.equal(
|
|
248
|
+
const builder = agents.find((agent) => agent.name === "builder");
|
|
249
|
+
const explorer = agents.find((agent) => agent.name === "explorer");
|
|
250
|
+
assert.ok(builder);
|
|
251
|
+
assert.ok(explorer);
|
|
252
|
+
assert.equal(builder.thinking, "high");
|
|
253
|
+
assert.equal(explorer.thinking, undefined);
|
|
191
254
|
});
|
|
192
255
|
|
|
193
256
|
it("lets project settings disable builtin thinking even when user overrides request it", () => {
|
|
@@ -195,7 +258,7 @@ describe("builtin agent overrides", () => {
|
|
|
195
258
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
196
259
|
subagents: {
|
|
197
260
|
agentOverrides: {
|
|
198
|
-
|
|
261
|
+
builder: {
|
|
199
262
|
thinking: "xhigh",
|
|
200
263
|
},
|
|
201
264
|
},
|
|
@@ -207,9 +270,9 @@ describe("builtin agent overrides", () => {
|
|
|
207
270
|
},
|
|
208
271
|
});
|
|
209
272
|
|
|
210
|
-
const
|
|
211
|
-
assert.ok(
|
|
212
|
-
assert.equal(
|
|
273
|
+
const builder = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "builder");
|
|
274
|
+
assert.ok(builder);
|
|
275
|
+
assert.equal(builder.thinking, undefined);
|
|
213
276
|
});
|
|
214
277
|
|
|
215
278
|
it("surfaces malformed subagent default model settings", () => {
|
|
@@ -247,45 +310,74 @@ describe("builtin agent overrides", () => {
|
|
|
247
310
|
it("prefers project settings overrides over user settings overrides", () => {
|
|
248
311
|
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
249
312
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
250
|
-
subagents: { agentOverrides: {
|
|
313
|
+
subagents: { agentOverrides: { builder: { model: "openai/gpt-5.4" } } },
|
|
314
|
+
});
|
|
315
|
+
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
316
|
+
subagents: { agentOverrides: { builder: { model: "openai-codex/gpt-5.4-mini", thinking: "high" } } },
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
const builder = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "builder");
|
|
320
|
+
assert.ok(builder);
|
|
321
|
+
assert.equal(builder.model, "openai-codex/gpt-5.4-mini");
|
|
322
|
+
assert.equal(builder.thinking, "high");
|
|
323
|
+
assert.equal(builder.override?.scope, "project");
|
|
324
|
+
assert.equal(builder.override?.path, path.join(tempProject, ".selesai", "settings.json"));
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
it("applies acceptance role precedence and false clearing to builtin and custom agents", () => {
|
|
328
|
+
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
329
|
+
subagents: {
|
|
330
|
+
agentOverrides: {
|
|
331
|
+
builder: { acceptanceRole: "read-only" },
|
|
332
|
+
architect: { acceptanceRole: "read-only" },
|
|
333
|
+
implementer: { acceptanceRole: "read-only" },
|
|
334
|
+
},
|
|
335
|
+
},
|
|
251
336
|
});
|
|
337
|
+
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
252
338
|
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
253
|
-
subagents: {
|
|
339
|
+
subagents: {
|
|
340
|
+
agentOverrides: {
|
|
341
|
+
builder: { acceptanceRole: "writer" },
|
|
342
|
+
architect: { acceptanceRole: false },
|
|
343
|
+
implementer: { acceptanceRole: false },
|
|
344
|
+
},
|
|
345
|
+
},
|
|
254
346
|
});
|
|
347
|
+
writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
|
|
255
348
|
|
|
256
|
-
const
|
|
257
|
-
assert.
|
|
258
|
-
assert.equal(
|
|
259
|
-
assert.equal(
|
|
260
|
-
assert.equal(
|
|
261
|
-
assert.equal(reviewer.override?.path, path.join(tempProject, ".selesai", "settings.json"));
|
|
349
|
+
const agents = discoverAgents(tempProject, "both").agents;
|
|
350
|
+
assert.equal(agents.find((agent) => agent.name === "builder")?.acceptanceRole, "writer");
|
|
351
|
+
assert.equal(agents.find((agent) => agent.name === "architect")?.acceptanceRole, undefined);
|
|
352
|
+
assert.equal(agents.find((agent) => agent.name === "implementer")?.acceptanceRole, undefined);
|
|
353
|
+
assert.equal(agents.find((agent) => agent.name === "implementer")?.override?.scope, "project");
|
|
262
354
|
});
|
|
263
355
|
|
|
264
356
|
it("does not apply project settings overrides when scope is user", () => {
|
|
265
357
|
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
266
358
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
267
|
-
subagents: { agentOverrides: {
|
|
359
|
+
subagents: { agentOverrides: { builder: { model: "openai/gpt-5.4" } } },
|
|
268
360
|
});
|
|
269
361
|
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
270
|
-
subagents: { agentOverrides: {
|
|
362
|
+
subagents: { agentOverrides: { builder: { model: "openai-codex/gpt-5.4-mini" } } },
|
|
271
363
|
});
|
|
272
364
|
|
|
273
|
-
const
|
|
274
|
-
assert.ok(
|
|
275
|
-
assert.equal(
|
|
276
|
-
assert.equal(
|
|
365
|
+
const builder = discoverAgents(tempProject, "user").agents.find((agent) => agent.name === "builder");
|
|
366
|
+
assert.ok(builder);
|
|
367
|
+
assert.equal(builder.model, "openai/gpt-5.4");
|
|
368
|
+
assert.equal(builder.override?.scope, "user");
|
|
277
369
|
});
|
|
278
370
|
|
|
279
371
|
it("does not apply user settings overrides when scope is project", () => {
|
|
280
372
|
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
281
373
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
282
|
-
subagents: { agentOverrides: {
|
|
374
|
+
subagents: { agentOverrides: { builder: { model: "openai/gpt-5.4" } } },
|
|
283
375
|
});
|
|
284
376
|
|
|
285
|
-
const
|
|
286
|
-
assert.ok(
|
|
287
|
-
assert.notEqual(
|
|
288
|
-
assert.equal(
|
|
377
|
+
const builder = discoverAgents(tempProject, "project").agents.find((agent) => agent.name === "builder");
|
|
378
|
+
assert.ok(builder);
|
|
379
|
+
assert.notEqual(builder.model, "openai/gpt-5.4");
|
|
380
|
+
assert.equal(builder.override, undefined);
|
|
289
381
|
});
|
|
290
382
|
|
|
291
383
|
it("does not read malformed out-of-scope settings files", () => {
|
|
@@ -293,27 +385,27 @@ describe("builtin agent overrides", () => {
|
|
|
293
385
|
fs.mkdirSync(path.join(tempHome, ".selesai", "agent"), { recursive: true });
|
|
294
386
|
fs.writeFileSync(path.join(tempHome, ".selesai", "agent", "settings.json"), '{"subagents":', "utf-8");
|
|
295
387
|
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
296
|
-
subagents: { agentOverrides: {
|
|
388
|
+
subagents: { agentOverrides: { builder: { model: "openai-codex/gpt-5.4-mini" } } },
|
|
297
389
|
});
|
|
298
390
|
|
|
299
|
-
const
|
|
300
|
-
assert.ok(
|
|
301
|
-
assert.equal(
|
|
302
|
-
assert.equal(
|
|
391
|
+
const builder = discoverAgents(tempProject, "project").agents.find((agent) => agent.name === "builder");
|
|
392
|
+
assert.ok(builder);
|
|
393
|
+
assert.equal(builder.model, "openai-codex/gpt-5.4-mini");
|
|
394
|
+
assert.equal(builder.override?.scope, "project");
|
|
303
395
|
});
|
|
304
396
|
|
|
305
397
|
it("frontmatter wins per-field over agentOverrides for a shadowing project agent", () => {
|
|
306
398
|
fs.mkdirSync(path.join(tempProject, ".selesai"), { recursive: true });
|
|
307
399
|
writeJson(path.join(tempProject, ".selesai", "settings.json"), {
|
|
308
|
-
subagents: { agentOverrides: {
|
|
400
|
+
subagents: { agentOverrides: { builder: { model: "openai/gpt-5.4" } } },
|
|
309
401
|
});
|
|
310
|
-
writeProjectAgent(tempProject, "
|
|
402
|
+
writeProjectAgent(tempProject, "builder", `---\nname: builder\ndescription: Project builder\nmodel: google/gemini-3-pro\n---\n\nUse the project builder.\n`);
|
|
311
403
|
|
|
312
|
-
const
|
|
313
|
-
assert.ok(
|
|
314
|
-
assert.equal(
|
|
315
|
-
assert.equal(
|
|
316
|
-
assert.equal(
|
|
404
|
+
const builder = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "builder");
|
|
405
|
+
assert.ok(builder);
|
|
406
|
+
assert.equal(builder.source, "project");
|
|
407
|
+
assert.equal(builder.model, "google/gemini-3-pro");
|
|
408
|
+
assert.equal(builder.override, undefined);
|
|
317
409
|
});
|
|
318
410
|
|
|
319
411
|
it("fills in unset fields on a custom project agent from project agentOverrides", () => {
|
|
@@ -329,6 +421,7 @@ describe("builtin agent overrides", () => {
|
|
|
329
421
|
inheritProjectContext: true,
|
|
330
422
|
inheritSkills: true,
|
|
331
423
|
defaultContext: "fork",
|
|
424
|
+
acceptanceRole: "writer",
|
|
332
425
|
tools: ["bash", "mcp:xcodebuild_list_sims"],
|
|
333
426
|
skills: ["tdd"],
|
|
334
427
|
subagentOnlyExtensions: ["./tools/child-review.ts"],
|
|
@@ -349,6 +442,7 @@ describe("builtin agent overrides", () => {
|
|
|
349
442
|
assert.equal(implementer.inheritProjectContext, true);
|
|
350
443
|
assert.equal(implementer.inheritSkills, true);
|
|
351
444
|
assert.equal(implementer.defaultContext, "fork");
|
|
445
|
+
assert.equal(implementer.acceptanceRole, "writer");
|
|
352
446
|
assert.deepEqual(implementer.tools, ["bash"]);
|
|
353
447
|
assert.deepEqual(implementer.mcpDirectTools, ["xcodebuild_list_sims"]);
|
|
354
448
|
assert.deepEqual(implementer.skills, ["tdd"]);
|
|
@@ -412,12 +506,13 @@ describe("builtin agent overrides", () => {
|
|
|
412
506
|
skills: ["override-skill"],
|
|
413
507
|
inheritProjectContext: true,
|
|
414
508
|
defaultContext: "fork",
|
|
509
|
+
acceptanceRole: "writer",
|
|
415
510
|
completionGuard: true,
|
|
416
511
|
},
|
|
417
512
|
},
|
|
418
513
|
},
|
|
419
514
|
});
|
|
420
|
-
writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\nmodel: google/gemini-3-pro\nthinking: medium\ntools: read, mcp:local_tool\nskills: agent-skill\ninheritProjectContext: false\ndefaultContext: fresh\ncompletionGuard: false\n---\n\nDrive the failing test first.\n`);
|
|
515
|
+
writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\nmodel: google/gemini-3-pro\nthinking: medium\ntools: read, mcp:local_tool\nskills: agent-skill\ninheritProjectContext: false\ndefaultContext: fresh\nacceptanceRole: read-only\ncompletionGuard: false\n---\n\nDrive the failing test first.\n`);
|
|
421
516
|
|
|
422
517
|
const implementer = discoverAgents(tempProject, "both").agents.find((agent) => agent.name === "implementer");
|
|
423
518
|
assert.ok(implementer);
|
|
@@ -428,13 +523,14 @@ describe("builtin agent overrides", () => {
|
|
|
428
523
|
assert.deepEqual(implementer.skills, ["agent-skill"]);
|
|
429
524
|
assert.equal(implementer.inheritProjectContext, false);
|
|
430
525
|
assert.equal(implementer.defaultContext, "fresh");
|
|
526
|
+
assert.equal(implementer.acceptanceRole, "read-only");
|
|
431
527
|
assert.equal(implementer.completionGuard, false);
|
|
432
528
|
assert.equal(implementer.override, undefined);
|
|
433
529
|
});
|
|
434
530
|
|
|
435
531
|
it("leaves a custom agent untouched when no agentOverrides entry matches its name", () => {
|
|
436
532
|
writeJson(path.join(tempHome, ".selesai", "agent", "settings.json"), {
|
|
437
|
-
subagents: { agentOverrides: {
|
|
533
|
+
subagents: { agentOverrides: { builder: { model: "openai/gpt-5.4" } } },
|
|
438
534
|
});
|
|
439
535
|
writeProjectAgent(tempProject, "implementer", `---\nname: implementer\ndescription: TDD implementer\n---\n\nDrive the failing test first.\n`);
|
|
440
536
|
|
|
@@ -458,7 +554,7 @@ describe("builtin agent overrides", () => {
|
|
|
458
554
|
it("does not create a settings file when removing a non-existent override", () => {
|
|
459
555
|
const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
|
|
460
556
|
assert.equal(fs.existsSync(settingsPath), false);
|
|
461
|
-
removeBuiltinAgentOverride(tempProject, "
|
|
557
|
+
removeBuiltinAgentOverride(tempProject, "builder", "user");
|
|
462
558
|
assert.equal(fs.existsSync(settingsPath), false);
|
|
463
559
|
});
|
|
464
560
|
|
|
@@ -492,7 +588,7 @@ describe("builtin agent overrides", () => {
|
|
|
492
588
|
writeJson(settingsPath, {
|
|
493
589
|
subagents: {
|
|
494
590
|
agentOverrides: {
|
|
495
|
-
|
|
591
|
+
builder: {
|
|
496
592
|
inheritProjectContext: "true",
|
|
497
593
|
},
|
|
498
594
|
},
|
|
@@ -503,17 +599,38 @@ describe("builtin agent overrides", () => {
|
|
|
503
599
|
() => discoverAgents(tempProject, "both"),
|
|
504
600
|
(error: unknown) => error instanceof Error
|
|
505
601
|
&& error.message.includes(settingsPath)
|
|
506
|
-
&& error.message.includes("
|
|
602
|
+
&& error.message.includes("builder")
|
|
507
603
|
&& error.message.includes("inheritProjectContext"),
|
|
508
604
|
);
|
|
509
605
|
});
|
|
510
606
|
|
|
607
|
+
it("surfaces malformed acceptance role override values", () => {
|
|
608
|
+
const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
|
|
609
|
+
writeJson(settingsPath, {
|
|
610
|
+
subagents: {
|
|
611
|
+
agentOverrides: {
|
|
612
|
+
builder: {
|
|
613
|
+
acceptanceRole: "observer",
|
|
614
|
+
},
|
|
615
|
+
},
|
|
616
|
+
},
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
assert.throws(
|
|
620
|
+
() => discoverAgents(tempProject, "both"),
|
|
621
|
+
(error: unknown) => error instanceof Error
|
|
622
|
+
&& error.message.includes(settingsPath)
|
|
623
|
+
&& error.message.includes("builder")
|
|
624
|
+
&& error.message.includes("acceptanceRole"),
|
|
625
|
+
);
|
|
626
|
+
});
|
|
627
|
+
|
|
511
628
|
it("surfaces malformed completion guard override values", () => {
|
|
512
629
|
const settingsPath = path.join(tempHome, ".selesai", "agent", "settings.json");
|
|
513
630
|
writeJson(settingsPath, {
|
|
514
631
|
subagents: {
|
|
515
632
|
agentOverrides: {
|
|
516
|
-
|
|
633
|
+
builder: {
|
|
517
634
|
completionGuard: "false",
|
|
518
635
|
},
|
|
519
636
|
},
|
|
@@ -524,7 +641,7 @@ describe("builtin agent overrides", () => {
|
|
|
524
641
|
() => discoverAgents(tempProject, "both"),
|
|
525
642
|
(error: unknown) => error instanceof Error
|
|
526
643
|
&& error.message.includes(settingsPath)
|
|
527
|
-
&& error.message.includes("
|
|
644
|
+
&& error.message.includes("builder")
|
|
528
645
|
&& error.message.includes("completionGuard"),
|
|
529
646
|
);
|
|
530
647
|
});
|
|
@@ -539,6 +656,7 @@ describe("builtin agent overrides", () => {
|
|
|
539
656
|
inheritProjectContext: true,
|
|
540
657
|
inheritSkills: false,
|
|
541
658
|
defaultContext: "fork",
|
|
659
|
+
acceptanceRole: "read-only",
|
|
542
660
|
systemPrompt: "Base prompt",
|
|
543
661
|
skills: ["safe-bash"],
|
|
544
662
|
tools: ["bash"],
|
|
@@ -554,6 +672,7 @@ describe("builtin agent overrides", () => {
|
|
|
554
672
|
inheritProjectContext: false,
|
|
555
673
|
inheritSkills: false,
|
|
556
674
|
defaultContext: undefined,
|
|
675
|
+
acceptanceRole: undefined,
|
|
557
676
|
systemPrompt: "Base prompt",
|
|
558
677
|
skills: undefined,
|
|
559
678
|
tools: undefined,
|
|
@@ -570,6 +689,7 @@ describe("builtin agent overrides", () => {
|
|
|
570
689
|
systemPromptMode: "replace",
|
|
571
690
|
inheritProjectContext: false,
|
|
572
691
|
defaultContext: false,
|
|
692
|
+
acceptanceRole: false,
|
|
573
693
|
skills: false,
|
|
574
694
|
tools: false,
|
|
575
695
|
subagentOnlyExtensions: false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { describe, it } from "node:test";
|
|
4
|
-
import { buildAsyncRunnerSteps, resolveAsyncRunnerLogPaths } from "../../src/runs/background/async-execution.ts";
|
|
4
|
+
import { buildAsyncRunnerSteps, formatAsyncStartedMessage, resolveAsyncRunnerLogPaths } from "../../src/runs/background/async-execution.ts";
|
|
5
5
|
import type { AgentConfig } from "../../src/agents/agents.ts";
|
|
6
6
|
|
|
7
7
|
const agent = (name: string, toolBudget?: AgentConfig["toolBudget"]): AgentConfig => ({
|
|
@@ -25,6 +25,18 @@ const ctx = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
describe("async runner execution", () => {
|
|
28
|
+
it("formats interactive yield and headless auto-drain guidance separately", () => {
|
|
29
|
+
const interactive = formatAsyncStartedMessage("Async: worker [interactive]", true);
|
|
30
|
+
assert.match(interactive, /interactive session[\s\S]*return control/i);
|
|
31
|
+
assert.match(interactive, /do not call subagent_wait\(\) merely to wait/i);
|
|
32
|
+
assert.doesNotMatch(interactive, /auto-drains current-session background work/i);
|
|
33
|
+
|
|
34
|
+
const headless = formatAsyncStartedMessage("Async: worker [headless]", false);
|
|
35
|
+
assert.match(headless, /non-interactive run.*auto-drains current-session background work at agent_end/i);
|
|
36
|
+
assert.match(headless, /call subagent_wait\(\).*results before it ends/i);
|
|
37
|
+
assert.doesNotMatch(headless, /By default, return control to the user/i);
|
|
38
|
+
});
|
|
39
|
+
|
|
28
40
|
it("places detached runner stdio logs in the async run directory", () => {
|
|
29
41
|
const asyncDir = path.join("tmp", "async-run");
|
|
30
42
|
assert.deepEqual(resolveAsyncRunnerLogPaths({ asyncDir }), {
|
|
@@ -47,12 +59,14 @@ describe("async runner execution", () => {
|
|
|
47
59
|
ctx,
|
|
48
60
|
asyncDir: path.join(process.cwd(), ".tmp-async-test"),
|
|
49
61
|
maxSubagentDepth: 2,
|
|
62
|
+
waitToolEnabled: false,
|
|
50
63
|
toolBudget: { hard: 3, block: ["find"] },
|
|
51
64
|
configToolBudget: { hard: 5, block: ["ls"] },
|
|
52
65
|
});
|
|
53
66
|
|
|
54
67
|
assert.ok("steps" in result, "expected successful step build");
|
|
55
68
|
assert.deepEqual(result.steps[0]?.toolBudget, { hard: 3, block: ["find"] });
|
|
69
|
+
assert.equal(result.steps[0]?.waitToolEnabled, false);
|
|
56
70
|
assert.deepEqual(result.steps[1]?.toolBudget, { hard: 2, block: ["grep"] });
|
|
57
71
|
});
|
|
58
72
|
|