@selesai/code 0.13.15 → 0.13.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +2 -14
- package/dist/bun/cli.d.ts +3 -1
- package/dist/bun/cli.js +3 -9
- package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
- package/dist/bun/sandbox-env-setup.d.ts +1 -0
- package/dist/bun/sandbox-env-setup.js +3 -0
- package/dist/cli/auth-command.d.ts +23 -0
- package/dist/cli/auth-command.js +102 -0
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/setup.d.ts +1 -0
- package/dist/cli/setup.js +11 -0
- package/dist/cli.js +2 -14
- package/dist/config.d.ts +3 -2
- package/dist/config.js +9 -4
- package/dist/core/agent-session-runtime.js +15 -7
- package/dist/core/agent-session.d.ts +2 -6
- package/dist/core/agent-session.js +15 -4
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -1
- package/dist/core/extensions/loader.js +3 -0
- package/dist/core/extensions/types.d.ts +16 -2
- package/dist/core/http-dispatcher.js +2 -0
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.js +4 -0
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/model-config.d.ts +15 -0
- package/dist/core/model-config.js +3 -0
- package/dist/core/model-runtime.d.ts +1 -0
- package/dist/core/model-runtime.js +5 -2
- package/dist/core/provider-composer.js +8 -2
- package/dist/core/session-export.d.ts +3 -0
- package/dist/core/session-export.js +31 -0
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.js +40 -13
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.js +4 -2
- package/dist/core/system-prompt.js +10 -10
- package/dist/core/tools/bash.js +3 -117
- package/dist/core/tools/edit.d.ts +1 -12
- package/dist/core/tools/edit.js +5 -163
- package/dist/core/tools/find.js +4 -55
- package/dist/core/tools/grep.js +4 -60
- package/dist/core/tools/ls.js +4 -49
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.js +10 -122
- package/dist/core/tools/renderers/bash.d.ts +11 -0
- package/dist/core/tools/renderers/bash.js +129 -0
- package/dist/core/tools/renderers/edit.d.ts +22 -0
- package/dist/core/tools/renderers/edit.js +166 -0
- package/dist/core/tools/renderers/find.d.ts +9 -0
- package/dist/core/tools/renderers/find.js +63 -0
- package/dist/core/tools/renderers/grep.d.ts +9 -0
- package/dist/core/tools/renderers/grep.js +68 -0
- package/dist/core/tools/renderers/index.d.ts +27 -0
- package/dist/core/tools/renderers/index.js +46 -0
- package/dist/core/tools/renderers/ls.d.ts +9 -0
- package/dist/core/tools/renderers/ls.js +57 -0
- package/dist/core/tools/renderers/read.d.ts +10 -0
- package/dist/core/tools/renderers/read.js +128 -0
- package/dist/core/tools/renderers/write.d.ts +9 -0
- package/dist/core/tools/renderers/write.js +152 -0
- package/dist/core/tools/write.js +5 -146
- package/dist/extensions/capability-gateway/index.ts +12 -1
- package/dist/extensions/capability-gateway/integration.test.ts +23 -0
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
- package/dist/extensions/pi-hermes-memory/README.md +16 -12
- package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
- package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
- package/dist/extensions/pi-hermes-memory/package.json +4 -4
- package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
- package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
- package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
- package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
- package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
- package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
- package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
- package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
- package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
- package/dist/extensions/pi-intercom/README.md +16 -2
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
- package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
- package/dist/extensions/pi-intercom/index.ts +1 -1
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
- package/dist/extensions/pi-intercom/package.json +1 -1
- package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
- package/dist/extensions/pi-intercom/project-agent.ts +1 -6
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
- package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
- package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
- package/dist/extensions/pi-subagents/README.md +3 -3
- package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
- package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
- package/dist/extensions/pi-subagents/agents/scout.md +1 -1
- package/dist/extensions/pi-subagents/docs/agents.md +32 -16
- package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
- package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
- package/dist/extensions/pi-subagents/docs/missions.md +2 -0
- package/dist/extensions/pi-subagents/docs/models.md +58 -1
- package/dist/extensions/pi-subagents/docs/observability.md +50 -12
- package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
- package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
- package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
- package/dist/extensions/pi-subagents/package-lock.json +747 -177
- package/dist/extensions/pi-subagents/package.json +6 -4
- package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
- package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
- package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
- package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
- package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
- package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
- package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
- package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
- package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
- package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
- package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
- package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
- package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
- package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
- package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
- package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
- package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
- package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
- package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
- package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
- package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
- package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
- package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
- package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
- package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
- package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
- package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
- package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
- package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
- package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
- package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
- package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
- package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
- package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
- package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
- package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
- package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
- package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
- package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
- package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
- package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
- package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
- package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
- package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
- package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
- package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
- package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
- package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
- package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
- package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
- package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
- package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
- package/dist/extensions/pi-web-agent/src/backends/config.ts +1 -0
- package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +5 -3
- package/dist/extensions/pi-web-agent/src/search/tokenin.ts +7 -3
- package/dist/extensions/pi-web-agent/src/types.ts +1 -1
- package/dist/extensions/pi-zentui/README.md +17 -0
- package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
- package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
- package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
- package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
- package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
- package/dist/extensions/pi-zentui/package-lock.json +277 -517
- package/dist/extensions/pi-zentui/package.json +7 -4
- package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
- package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
- package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
- package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
- package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
- package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
- package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
- package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
- package/dist/index.d.ts +1 -1
- package/dist/main.js +4 -1
- package/dist/modes/interactive/chat-viewport.d.ts +19 -0
- package/dist/modes/interactive/chat-viewport.js +27 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
- package/dist/modes/interactive/components/assistant-message.js +30 -13
- package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
- package/dist/modes/interactive/components/custom-editor.js +39 -1
- package/dist/modes/interactive/components/first-time-setup.js +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
- package/dist/modes/interactive/components/markdown-transform.js +18 -0
- package/dist/modes/interactive/components/model-selector.js +19 -17
- package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
- package/dist/modes/interactive/components/settings-selector.js +128 -20
- package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
- package/dist/modes/interactive/components/settings-submenu.js +164 -0
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
- package/dist/modes/interactive/components/status-indicator.js +10 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.js +75 -18
- package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
- package/dist/modes/interactive/components/tool-execution.js +35 -33
- package/dist/modes/interactive/components/trust-selector.js +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts +13 -15
- package/dist/modes/interactive/interactive-mode.js +144 -80
- package/dist/modes/interactive/session-share.d.ts +15 -0
- package/dist/modes/interactive/session-share.js +183 -0
- package/dist/modes/interactive/theme/dark.json +2 -1
- package/dist/modes/interactive/theme/light.json +2 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +5 -0
- package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
- package/dist/modes/interactive/theme/theme-json.js +129 -0
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +14 -5
- package/dist/modes/interactive/theme/theme.js +18 -119
- package/dist/modes/interactive/tui-renderer.d.ts +20 -0
- package/dist/modes/interactive/tui-renderer.js +65 -0
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/management-http.d.ts +24 -0
- package/dist/utils/management-http.js +53 -0
- package/dist/utils/text.d.ts +7 -0
- package/dist/utils/text.js +8 -0
- package/dist/utils/tools-manager.d.ts +1 -0
- package/dist/utils/tools-manager.js +43 -21
- package/docs/docs.json +0 -4
- package/package.json +4 -4
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
- package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
- package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
- package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
- package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
- package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
- package/dist/skills/implanger/SKILL.md +0 -70
- package/dist/skills/output/SKILL.md +0 -49
- package/dist/skills/planger/SKILL.md +0 -167
- package/dist/skills/workflow/SKILL.md +0 -95
- package/docs/workflows.md +0 -18
- /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
|
@@ -115,6 +115,40 @@ describe("async chain root attachment", () => {
|
|
|
115
115
|
assert.equal(result.exitCode, 0);
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
+
for (const proofState of [undefined, "pending"]) it(`waits past the terminal grace for workflow-owned single publication with ${proofState ?? "absent"} root proof`, async (t) => {
|
|
119
|
+
t.mock.timers.enable({ apis: ["setTimeout", "Date"], now: 0 });
|
|
120
|
+
const importedRoot = { ...root(), resultPath: path.join(tempDir, "root-run", "workflow-result.json") };
|
|
121
|
+
writeJson(path.join(importedRoot.asyncDir, "status.json"), {
|
|
122
|
+
runId: importedRoot.runId,
|
|
123
|
+
mode: "single",
|
|
124
|
+
parentWorkflowRunId: "workflow-parent",
|
|
125
|
+
state: "running",
|
|
126
|
+
pid: process.pid,
|
|
127
|
+
startedAt: 1,
|
|
128
|
+
...(proofState ? { processTerminal: { version: 1, runId: importedRoot.runId, runnerProcessInstanceId: "runner-instance", state: proofState } } : {}),
|
|
129
|
+
steps: [{ agent: "worker", status: "complete" }],
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// The live publisher is this process; advance only the waiter's clock,
|
|
133
|
+
// leaving the real completed-step evidence intact until publication.
|
|
134
|
+
const waiting = waitForImportedAsyncRoot(importedRoot);
|
|
135
|
+
for (let poll = 0; poll < 3; poll++) {
|
|
136
|
+
t.mock.timers.tick(500);
|
|
137
|
+
await Promise.resolve();
|
|
138
|
+
}
|
|
139
|
+
assert.equal(Date.now(), 1_500);
|
|
140
|
+
assert.equal(fs.existsSync(importedRoot.resultPath), false);
|
|
141
|
+
writeJson(importedRoot.resultPath, {
|
|
142
|
+
state: "complete",
|
|
143
|
+
success: true,
|
|
144
|
+
results: [{ agent: "worker", output: "published after step completion", success: true }],
|
|
145
|
+
});
|
|
146
|
+
t.mock.timers.tick(500);
|
|
147
|
+
const result = await waiting;
|
|
148
|
+
assert.equal(result.success, true, result.error);
|
|
149
|
+
assert.equal(result.output, "published after step completion");
|
|
150
|
+
});
|
|
151
|
+
|
|
118
152
|
it("imports a failed root as a failed first chain step", async () => {
|
|
119
153
|
const importedRoot = root();
|
|
120
154
|
writeJson(path.join(importedRoot.asyncDir, "status.json"), {
|
|
@@ -188,14 +222,21 @@ describe("async chain root attachment", () => {
|
|
|
188
222
|
assert.deepEqual(result.effects?.fileMutation?.evidence?.changedFiles, ["input.md"]);
|
|
189
223
|
});
|
|
190
224
|
|
|
191
|
-
|
|
192
|
-
|
|
225
|
+
for (const fixture of [
|
|
226
|
+
{ name: "terminal root", status: { mode: "single", state: "complete" } },
|
|
227
|
+
{ name: "terminal workflow-owned single", status: { mode: "single", state: "complete", parentWorkflowRunId: "workflow-parent" } },
|
|
228
|
+
{ name: "running workflow-owned single with unavailable root proof", status: {
|
|
229
|
+
mode: "single", state: "running", parentWorkflowRunId: "workflow-parent",
|
|
230
|
+
processTerminal: { version: 1, runId: "root-run", runnerProcessInstanceId: "runner-instance", state: "unknown", reason: "runner-candidate-missing" },
|
|
231
|
+
} },
|
|
232
|
+
{ name: "selected child of running workflow-owned parallel root", index: 1, status: { mode: "parallel", state: "running", parentWorkflowRunId: "workflow-parent" } },
|
|
233
|
+
]) it(`fails closed without a result for ${fixture.name}`, async () => {
|
|
234
|
+
const importedRoot = root("root-run", fixture.index ?? 0);
|
|
193
235
|
writeJson(path.join(importedRoot.asyncDir, "status.json"), {
|
|
194
236
|
runId: importedRoot.runId,
|
|
195
|
-
|
|
196
|
-
state: "complete",
|
|
237
|
+
...fixture.status,
|
|
197
238
|
startedAt: 1,
|
|
198
|
-
steps: [{ agent: "worker", status: "complete" }],
|
|
239
|
+
steps: [...(fixture.index ? [{ agent: "first", status: "running" }] : []), { agent: "worker", status: "complete" }],
|
|
199
240
|
});
|
|
200
241
|
|
|
201
242
|
const result = await waitForImportedAsyncRoot(importedRoot, {
|
|
@@ -203,6 +244,7 @@ describe("async chain root attachment", () => {
|
|
|
203
244
|
terminalResultGraceMs: 0,
|
|
204
245
|
});
|
|
205
246
|
|
|
247
|
+
assert.equal(result.agent, "worker");
|
|
206
248
|
assert.equal(result.exitCode, 1);
|
|
207
249
|
assert.match(result.error ?? "", /ended without a result file/);
|
|
208
250
|
});
|
|
@@ -233,4 +275,4 @@ describe("async chain root attachment", () => {
|
|
|
233
275
|
assert.equal(result.error, "parent timed out");
|
|
234
276
|
assert.equal(result.output, "parent timed out");
|
|
235
277
|
});
|
|
236
|
-
});
|
|
278
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { createChildHooks } from "../../src/runs/shared/child-hooks.ts";
|
|
4
|
+
import { childSupervisorMetadata, evaluateChildToolDiagnostic, type ChildRuntimeConfig } from "../../src/runs/shared/child-runtime-config.ts";
|
|
5
|
+
|
|
6
|
+
function baseConfig(overrides: Partial<ChildRuntimeConfig> = {}): ChildRuntimeConfig {
|
|
7
|
+
return { fanoutChild: false, depth: 1, waitTool: { enabled: true }, fast: false, ...overrides };
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface FakePi {
|
|
11
|
+
handlers: Map<string, Array<(event?: unknown, ctx?: unknown) => unknown>>;
|
|
12
|
+
tools: Array<{ name: string }>;
|
|
13
|
+
api: unknown;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function fakePi(available: string[]): FakePi {
|
|
17
|
+
const handlers = new Map<string, Array<(event?: unknown, ctx?: unknown) => unknown>>();
|
|
18
|
+
const tools: Array<{ name: string }> = [];
|
|
19
|
+
const api = {
|
|
20
|
+
on(event: string, handler: (event?: unknown, ctx?: unknown) => unknown) {
|
|
21
|
+
handlers.set(event, [...(handlers.get(event) ?? []), handler]);
|
|
22
|
+
},
|
|
23
|
+
registerTool(tool: { name: string }) { tools.push(tool); },
|
|
24
|
+
getAllTools: () => [...available, ...tools.map((tool) => tool.name)].map((name) => ({ name })),
|
|
25
|
+
events: { on() {}, emit() {} },
|
|
26
|
+
sendMessage() {},
|
|
27
|
+
getThinkingLevel: () => "off",
|
|
28
|
+
};
|
|
29
|
+
return { handlers, tools, api };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe("child runtime config", () => {
|
|
33
|
+
it("creates the prompt runtime hook always and the fast and fanout hooks on demand", () => {
|
|
34
|
+
assert.deepEqual(createChildHooks(baseConfig()).map((hook) => hook.name), ["pi-subagents:prompt-runtime"]);
|
|
35
|
+
assert.deepEqual(createChildHooks(baseConfig({ fast: true })).map((hook) => hook.name), ["pi-subagents:prompt-runtime", "pi-subagents:fast-mode"]);
|
|
36
|
+
assert.deepEqual(createChildHooks(baseConfig({ fanoutChild: true })).map((hook) => hook.name), ["pi-subagents:prompt-runtime", "pi-subagents:fanout-child"]);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("hooks read the config object", async () => {
|
|
40
|
+
const diagnostics: unknown[] = [];
|
|
41
|
+
const captured: unknown[] = [];
|
|
42
|
+
const config = baseConfig({
|
|
43
|
+
agent: "config-agent",
|
|
44
|
+
requiredTools: ["read", "fixture_search"],
|
|
45
|
+
toolDiagnostic: (diagnostic) => diagnostics.push(diagnostic),
|
|
46
|
+
structuredOutput: { schema: { type: "object" }, capture: (value) => captured.push(value) },
|
|
47
|
+
inheritProjectContext: true,
|
|
48
|
+
inheritGlobalContext: true,
|
|
49
|
+
inheritSkills: true,
|
|
50
|
+
});
|
|
51
|
+
const pi = fakePi(["read"]);
|
|
52
|
+
for (const hook of createChildHooks(config)) hook.factory(pi.api as never);
|
|
53
|
+
|
|
54
|
+
assert.throws(() => pi.handlers.get("agent_start")?.[0]?.({}), /Agent 'config-agent' requested unavailable child tools: fixture_search/);
|
|
55
|
+
assert.deepEqual(diagnostics, [{ agent: "config-agent", required: ["read", "fixture_search"], available: ["read", "bg_wait", "subagent_wait", "structured_output"], missing: ["fixture_search"] }]);
|
|
56
|
+
|
|
57
|
+
const structured = pi.tools.find((tool) => tool.name === "structured_output") as { execute: (id: string, params: { value: unknown }) => Promise<unknown> } | undefined;
|
|
58
|
+
assert.ok(structured, "structured_output tool registered from config");
|
|
59
|
+
await structured.execute("call-1", { value: { done: true } });
|
|
60
|
+
assert.deepEqual(captured, [{ done: true }]);
|
|
61
|
+
|
|
62
|
+
const rewritten = await pi.handlers.get("before_agent_start")?.[0]?.({ systemPrompt: "base prompt" }) as { systemPrompt: string } | undefined;
|
|
63
|
+
assert.match(rewritten?.systemPrompt ?? "", /strict structured output contract/);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("evaluates the tool diagnostic against the available tools", () => {
|
|
67
|
+
assert.equal(evaluateChildToolDiagnostic(baseConfig(), ["read"]), undefined);
|
|
68
|
+
assert.equal(evaluateChildToolDiagnostic(baseConfig({ requiredTools: ["read"] }), ["read", "write"]), undefined);
|
|
69
|
+
assert.deepEqual(
|
|
70
|
+
evaluateChildToolDiagnostic(baseConfig({ agent: "worker", requiredTools: ["read", "mcp_search"], mcpDirectTools: ["mcp_search"] }), ["read"]),
|
|
71
|
+
{ agent: "worker", required: ["read", "mcp_search"], available: ["read"], missing: ["mcp_search"], missingMcpDirectTools: ["mcp_search"] },
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("derives supervisor metadata only when the channel, run, agent, index, and orchestrator session are all set", () => {
|
|
76
|
+
assert.equal(childSupervisorMetadata(baseConfig({ supervisorChannelDir: "/tmp/channel", runId: "run-1", agent: "worker" })), undefined);
|
|
77
|
+
assert.deepEqual(
|
|
78
|
+
childSupervisorMetadata(baseConfig({
|
|
79
|
+
supervisorChannelDir: "/tmp/channel",
|
|
80
|
+
runId: "run-1",
|
|
81
|
+
agent: "worker",
|
|
82
|
+
childIndex: 2,
|
|
83
|
+
orchestratorSessionId: "session-1",
|
|
84
|
+
orchestratorTarget: "orchestrator",
|
|
85
|
+
intercomSessionName: "child-target",
|
|
86
|
+
})),
|
|
87
|
+
{ channelDir: "/tmp/channel", runId: "run-1", agent: "worker", childIndex: 2, orchestratorTarget: "orchestrator", orchestratorSessionId: "session-1", childTarget: "child-target" },
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -9,11 +9,11 @@ import * as fs from "node:fs";
|
|
|
9
9
|
import * as os from "node:os";
|
|
10
10
|
import * as path from "node:path";
|
|
11
11
|
import { afterEach, describe, it } from "node:test";
|
|
12
|
+
import { buildInProcessChildLaunch, type BuildInProcessChildLaunchInput } from "../../src/runs/shared/child-launch.ts";
|
|
12
13
|
import {
|
|
13
|
-
buildPiArgs,
|
|
14
14
|
resolvePermissionSystemExtension,
|
|
15
15
|
resolvePiLaunchToolPlan,
|
|
16
|
-
} from "../../src/runs/shared/
|
|
16
|
+
} from "../../src/runs/shared/child-tool-plan.ts";
|
|
17
17
|
|
|
18
18
|
const originalEnv = {
|
|
19
19
|
HOME: process.env.HOME,
|
|
@@ -23,7 +23,7 @@ const originalEnv = {
|
|
|
23
23
|
const tempRoots: string[] = [];
|
|
24
24
|
|
|
25
25
|
function createFixture() {
|
|
26
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "
|
|
26
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), "child-tool-plan-perm-"));
|
|
27
27
|
tempRoots.push(root);
|
|
28
28
|
const home = path.join(root, "home");
|
|
29
29
|
const agentDir = path.join(home, ".selesai", "agent");
|
|
@@ -53,12 +53,25 @@ afterEach(() => {
|
|
|
53
53
|
tempRoots.length = 0;
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
function
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
function childLaunch(overrides: Partial<BuildInProcessChildLaunchInput> = {}): BuildInProcessChildLaunchInput {
|
|
57
|
+
return {
|
|
58
|
+
host: "parent",
|
|
59
|
+
cwd: process.cwd(),
|
|
60
|
+
sessionEnabled: false,
|
|
61
|
+
inheritProjectContext: false,
|
|
62
|
+
inheritGlobalContext: false,
|
|
63
|
+
inheritSkills: false,
|
|
64
|
+
childAgentName: "worker",
|
|
65
|
+
childIndex: 0,
|
|
66
|
+
...overrides,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** The system prompt the child session receives (append mode by default). */
|
|
71
|
+
function childSystemPrompt(result: ReturnType<typeof buildInProcessChildLaunch>): string {
|
|
72
|
+
const prompt = result.session.systemPrompt ?? result.session.appendSystemPrompt;
|
|
73
|
+
assert.ok(prompt !== undefined, "expected a child system prompt");
|
|
74
|
+
return prompt;
|
|
62
75
|
}
|
|
63
76
|
|
|
64
77
|
function escapeRegExp(value: string): string {
|
|
@@ -235,20 +248,11 @@ describe("resolvePiLaunchToolPlan with permission system", () => {
|
|
|
235
248
|
JSON.stringify({ name: "test", pi: { extensions: ["./src/index.ts"] } }),
|
|
236
249
|
);
|
|
237
250
|
|
|
238
|
-
const {
|
|
239
|
-
baseArgs: ["-p"],
|
|
240
|
-
task: "test task",
|
|
241
|
-
sessionEnabled: false,
|
|
242
|
-
inheritProjectContext: false,
|
|
243
|
-
inheritSkills: false,
|
|
244
|
-
});
|
|
245
|
-
const extensionArgs = args.filter(
|
|
246
|
-
(arg, index) => args[index - 1] === "--extension",
|
|
247
|
-
);
|
|
251
|
+
const { session } = buildInProcessChildLaunch(childLaunch());
|
|
248
252
|
assert.equal(
|
|
249
|
-
|
|
253
|
+
session.extensionPaths.includes(path.join(extDir, "src", "index.ts")),
|
|
250
254
|
false,
|
|
251
|
-
"permission system extension should not be
|
|
255
|
+
"permission system extension should not be loaded without native rules",
|
|
252
256
|
);
|
|
253
257
|
});
|
|
254
258
|
|
|
@@ -266,20 +270,10 @@ describe("resolvePiLaunchToolPlan with permission system", () => {
|
|
|
266
270
|
JSON.stringify({ name: "test", pi: { extensions: ["./src/index.ts"] } }),
|
|
267
271
|
);
|
|
268
272
|
|
|
269
|
-
const {
|
|
270
|
-
baseArgs: ["-p"],
|
|
271
|
-
task: "test task",
|
|
272
|
-
sessionEnabled: false,
|
|
273
|
-
inheritProjectContext: false,
|
|
274
|
-
inheritSkills: false,
|
|
275
|
-
permissionRules: { write: "ask" },
|
|
276
|
-
});
|
|
277
|
-
const extensionArgs = args.filter(
|
|
278
|
-
(arg, index) => args[index - 1] === "--extension",
|
|
279
|
-
);
|
|
273
|
+
const { session } = buildInProcessChildLaunch(childLaunch({ permissionRules: { write: "ask" } }));
|
|
280
274
|
assert.ok(
|
|
281
|
-
|
|
282
|
-
"permission system extension should be
|
|
275
|
+
session.extensionPaths.includes(path.join(extDir, "src", "index.ts")),
|
|
276
|
+
"permission system extension should be loaded when native rules are active",
|
|
283
277
|
);
|
|
284
278
|
});
|
|
285
279
|
|
|
@@ -329,23 +323,15 @@ describe("resolvePiLaunchToolPlan with permission system", () => {
|
|
|
329
323
|
});
|
|
330
324
|
});
|
|
331
325
|
|
|
332
|
-
describe("
|
|
326
|
+
describe("child launch <active_agent> tag injection", () => {
|
|
333
327
|
it("prepends <active_agent> tag when childAgentName is set", () => {
|
|
334
328
|
const { agentDir } = createFixture();
|
|
335
329
|
process.env.SELESAI_CODING_AGENT_DIR = agentDir;
|
|
336
330
|
|
|
337
|
-
const
|
|
338
|
-
baseArgs: ["-p"],
|
|
339
|
-
task: "test task",
|
|
340
|
-
sessionEnabled: false,
|
|
331
|
+
const promptContent = childSystemPrompt(buildInProcessChildLaunch(childLaunch({
|
|
341
332
|
systemPrompt: "You are a helpful assistant.",
|
|
342
|
-
inheritProjectContext: false,
|
|
343
|
-
inheritSkills: false,
|
|
344
333
|
childAgentName: "reviewer",
|
|
345
|
-
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
const promptContent = readPromptFile(result);
|
|
334
|
+
})));
|
|
349
335
|
assert.ok(
|
|
350
336
|
promptContent.startsWith('<active_agent name="reviewer"/>'),
|
|
351
337
|
`expected prompt to start with <active_agent> tag, got: ${promptContent.slice(0, 100)}`,
|
|
@@ -356,45 +342,29 @@ describe("buildPiArgs <active_agent> tag injection", () => {
|
|
|
356
342
|
);
|
|
357
343
|
});
|
|
358
344
|
|
|
359
|
-
it("
|
|
345
|
+
it("passes no system prompt when the agent has none", () => {
|
|
360
346
|
const { agentDir } = createFixture();
|
|
361
347
|
process.env.SELESAI_CODING_AGENT_DIR = agentDir;
|
|
362
348
|
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
sessionEnabled: false,
|
|
367
|
-
systemPrompt: "You are a helper.",
|
|
368
|
-
inheritProjectContext: false,
|
|
369
|
-
inheritSkills: false,
|
|
370
|
-
promptFileStem: "test",
|
|
371
|
-
});
|
|
372
|
-
|
|
373
|
-
const promptContent = readPromptFile(result);
|
|
374
|
-
assert.equal(
|
|
375
|
-
promptContent.includes("<active_agent"),
|
|
376
|
-
false,
|
|
377
|
-
"should not inject tag when no childAgentName",
|
|
378
|
-
);
|
|
379
|
-
assert.equal(promptContent, "You are a helper.");
|
|
349
|
+
const { session } = buildInProcessChildLaunch(childLaunch({ childAgentName: "helper" }));
|
|
350
|
+
assert.equal(session.systemPrompt, undefined);
|
|
351
|
+
assert.equal(session.appendSystemPrompt, undefined);
|
|
380
352
|
});
|
|
381
353
|
|
|
382
|
-
it("
|
|
354
|
+
it("replaces the system prompt in replace mode", () => {
|
|
383
355
|
const { agentDir } = createFixture();
|
|
384
356
|
process.env.SELESAI_CODING_AGENT_DIR = agentDir;
|
|
385
357
|
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
promptFileStem: "worker",
|
|
395
|
-
});
|
|
358
|
+
const { session } = buildInProcessChildLaunch(childLaunch({ systemPrompt: "You are a helper.", systemPromptMode: "replace", childAgentName: "helper" }));
|
|
359
|
+
assert.equal(session.systemPrompt, '<active_agent name="helper"/>\n\nYou are a helper.');
|
|
360
|
+
assert.equal(session.appendSystemPrompt, undefined);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("injects the tag even when systemPrompt is empty", () => {
|
|
364
|
+
const { agentDir } = createFixture();
|
|
365
|
+
process.env.SELESAI_CODING_AGENT_DIR = agentDir;
|
|
396
366
|
|
|
397
|
-
const promptContent =
|
|
367
|
+
const promptContent = childSystemPrompt(buildInProcessChildLaunch(childLaunch({ systemPrompt: "", childAgentName: "worker" })));
|
|
398
368
|
assert.ok(promptContent.startsWith('<active_agent name="worker"/>'));
|
|
399
369
|
});
|
|
400
370
|
|
|
@@ -402,18 +372,10 @@ describe("buildPiArgs <active_agent> tag injection", () => {
|
|
|
402
372
|
const { agentDir } = createFixture();
|
|
403
373
|
process.env.SELESAI_CODING_AGENT_DIR = agentDir;
|
|
404
374
|
|
|
405
|
-
const
|
|
406
|
-
baseArgs: ["-p"],
|
|
407
|
-
task: "test task",
|
|
408
|
-
sessionEnabled: false,
|
|
375
|
+
const promptContent = childSystemPrompt(buildInProcessChildLaunch(childLaunch({
|
|
409
376
|
systemPrompt: "System prompt here",
|
|
410
|
-
inheritProjectContext: false,
|
|
411
|
-
inheritSkills: false,
|
|
412
377
|
childAgentName: 'my "special" agent',
|
|
413
|
-
|
|
414
|
-
});
|
|
415
|
-
|
|
416
|
-
const promptContent = readPromptFile(result);
|
|
378
|
+
})));
|
|
417
379
|
assert.ok(
|
|
418
380
|
promptContent.startsWith('<active_agent name="my "special" agent"/>'),
|
|
419
381
|
`expected escaped tag, got: ${promptContent.slice(0, 120)}`,
|
|
@@ -434,4 +396,4 @@ describe("buildPiArgs <active_agent> tag injection", () => {
|
|
|
434
396
|
"prompt runtime extension should always be included",
|
|
435
397
|
);
|
|
436
398
|
});
|
|
437
|
-
});
|
|
399
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as path from "node:path";
|
|
5
|
+
import { describe, it } from "node:test";
|
|
6
|
+
import { resolvePiLaunchToolPlan } from "../../src/runs/shared/child-tool-plan.ts";
|
|
7
|
+
import { MCP_RUNTIME_SNAPSHOT_EVENT, MCP_RUNTIME_SNAPSHOT_VERSION, type McpRuntimeSnapshotHost } from "../../src/runs/shared/mcp-direct-tool-allowlist.ts";
|
|
8
|
+
|
|
9
|
+
/** A parent whose pi-mcp-adapter answers snapshot requests for one runtime-only server. */
|
|
10
|
+
function runtimeSnapshotHost(serverName: string): McpRuntimeSnapshotHost {
|
|
11
|
+
return {
|
|
12
|
+
events: {
|
|
13
|
+
emit(event, request) {
|
|
14
|
+
if (event !== MCP_RUNTIME_SNAPSHOT_EVENT || request.version !== MCP_RUNTIME_SNAPSHOT_VERSION || request.name !== serverName) return;
|
|
15
|
+
request.result = { ok: true, snapshot: { name: serverName, runtime: true, persisted: false, definition: { command: "node", args: ["server.js"] } } };
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("child tool plan", () => {
|
|
22
|
+
it("fails a launch that selects MCP tools from the adapter's runtime snapshot", () => {
|
|
23
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), "pi-subagents-runtime-mcp-"));
|
|
24
|
+
try {
|
|
25
|
+
assert.throws(
|
|
26
|
+
() => resolvePiLaunchToolPlan({ tools: ["read"], mcpDirectTools: ["runtime-only/search"], cwd, agentName: "browser", runtimeSnapshotHost: runtimeSnapshotHost("runtime-only") }),
|
|
27
|
+
/cannot be provided to in-process children; MCP tools must come from an ambient adapter extension in a background child/,
|
|
28
|
+
);
|
|
29
|
+
} finally {
|
|
30
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -19,49 +19,49 @@ describe("async compaction resume", () => {
|
|
|
19
19
|
let renders = 0;
|
|
20
20
|
const pi = new Proxy({
|
|
21
21
|
events,
|
|
22
|
-
on(name, handler) { handlers.set(name, handler); },
|
|
22
|
+
on(name, handler) { handlers.set(name, [...(handlers.get(name) ?? []), handler]); },
|
|
23
23
|
registerTool() {}, registerCommand() {}, registerShortcut() {}, registerMessageRenderer() {},
|
|
24
24
|
sendMessage(message, options) { sent.push({ message, options }); }, getSessionName() { return undefined; },
|
|
25
25
|
}, { get(target, prop) { return prop in target ? target[prop] : () => undefined; } });
|
|
26
26
|
const ctx = { cwd: process.cwd(), hasUI: true, ui: { setWidget(key, value) { widgets.push([key, value]); }, requestRender() { renders++; }, onTerminalInput() { return () => {}; }, getEditorText() { return ""; }, notify() {}, theme: { fg(_name, text) { return text; }, bg(_name, text) { return text; }, bold(text) { return text; } } }, sessionManager: { getSessionId() { return "compact-session"; }, getSessionFile() { return null; }, getEntries() { return []; } }, modelRegistry: { getAvailable() { return []; } } };
|
|
27
27
|
registerSubagentExtension(pi);
|
|
28
|
-
handlers.get("session_start")({}, ctx);
|
|
28
|
+
for (const handler of handlers.get("session_start")) await handler({}, ctx);
|
|
29
29
|
sent.length = 0;
|
|
30
30
|
events.emit("subagent:async-started", { id: "running", pid: 1, sessionId: "compact-session", mode: "single", agent: "worker", asyncDir: path.join(os.tmpdir(), "pi-compaction-test-running") });
|
|
31
31
|
widgets.length = 0;
|
|
32
32
|
renders = 0;
|
|
33
|
-
handlers.get("session_before_compact")({ reason: "threshold", signal: new AbortController().signal });
|
|
33
|
+
for (const handler of handlers.get("session_before_compact")) await handler({ reason: "threshold", signal: new AbortController().signal });
|
|
34
34
|
const cleared = widgets.filter(([key, value]) => value === undefined).map(([key]) => key).sort();
|
|
35
35
|
if (JSON.stringify(cleared) !== JSON.stringify(["subagent-async", "subagent-fleet-status"])) throw new Error(JSON.stringify(widgets));
|
|
36
36
|
widgets.length = 0;
|
|
37
37
|
events.emit("subagent:async-complete", { id: "running", sessionId: "compact-session", agent: "worker", success: true, summary: "done" });
|
|
38
38
|
events.emit("subagent:async-started", { id: "running-2", pid: 2, sessionId: "compact-session", mode: "single", agent: "worker", asyncDir: path.join(os.tmpdir(), "pi-compaction-test-running-2") });
|
|
39
39
|
if (widgets.length !== 0 || renders !== 0) throw new Error("widgets repainted during compaction");
|
|
40
|
-
handlers.get("session_compact")({ reason: "threshold" });
|
|
40
|
+
for (const handler of handlers.get("session_compact")) await handler({ reason: "threshold" });
|
|
41
41
|
if (widgets.length !== 0) throw new Error("widgets restored inside compaction hook");
|
|
42
|
-
handlers.get("agent_start")();
|
|
42
|
+
for (const handler of handlers.get("agent_start")) await handler();
|
|
43
43
|
const restored = widgets.filter(([_, value]) => value !== undefined).map(([key]) => key).sort();
|
|
44
44
|
if (JSON.stringify(restored) !== JSON.stringify(["subagent-async", "subagent-fleet-status"])) throw new Error(JSON.stringify(widgets));
|
|
45
45
|
if (sent.length !== 1 || sent[0].options?.triggerTurn !== true || sent[0].message?.customType !== "subagent-compaction-resume") throw new Error(JSON.stringify(sent));
|
|
46
46
|
|
|
47
47
|
sent.length = 0;
|
|
48
48
|
events.emit("subagent:async-complete", { id: "running-2", sessionId: "compact-session", agent: "worker", success: true, summary: "done" });
|
|
49
|
-
handlers.get("session_before_compact")({ reason: "threshold", signal: new AbortController().signal });
|
|
50
|
-
handlers.get("session_compact")({ reason: "threshold" });
|
|
51
|
-
handlers.get("agent_settled")();
|
|
49
|
+
for (const handler of handlers.get("session_before_compact")) await handler({ reason: "threshold", signal: new AbortController().signal });
|
|
50
|
+
for (const handler of handlers.get("session_compact")) await handler({ reason: "threshold" });
|
|
51
|
+
for (const handler of handlers.get("agent_settled")) await handler();
|
|
52
52
|
if (sent.some((entry) => entry.message?.customType === "subagent-compaction-resume")) throw new Error("resumed without active work");
|
|
53
53
|
|
|
54
54
|
events.emit("subagent:async-started", { id: "running-3", pid: 3, sessionId: "compact-session", mode: "single", agent: "worker", asyncDir: path.join(os.tmpdir(), "pi-compaction-test-running-3") });
|
|
55
55
|
widgets.length = 0;
|
|
56
|
-
handlers.get("session_before_compact")({ reason: "overflow", signal: new AbortController().signal });
|
|
56
|
+
for (const handler of handlers.get("session_before_compact")) await handler({ reason: "overflow", signal: new AbortController().signal });
|
|
57
57
|
widgets.length = 0;
|
|
58
|
-
handlers.get("agent_settled")();
|
|
58
|
+
for (const handler of handlers.get("agent_settled")) await handler();
|
|
59
59
|
if (!widgets.some(([_, value]) => value !== undefined)) throw new Error("widgets did not recover after compaction failure");
|
|
60
60
|
|
|
61
61
|
widgets.length = 0;
|
|
62
|
-
handlers.get("session_before_compact")({ reason: "manual", signal: new AbortController().signal });
|
|
62
|
+
for (const handler of handlers.get("session_before_compact")) await handler({ reason: "manual", signal: new AbortController().signal });
|
|
63
63
|
if (widgets.length !== 0) throw new Error("manual compaction changed widget state");
|
|
64
|
-
|
|
64
|
+
for (const handler of handlers.get("session_shutdown")) await handler();
|
|
65
65
|
`;
|
|
66
66
|
const env = { ...process.env };
|
|
67
67
|
delete env.SELESAI_SUBAGENT_CHILD;
|
|
@@ -76,23 +76,23 @@ describe("async compaction resume", () => {
|
|
|
76
76
|
const events = { listeners: new Map(), on(name, handler) { this.listeners.set(name, handler); return () => this.listeners.delete(name); }, emit(name, payload) { this.listeners.get(name)?.(payload); } };
|
|
77
77
|
const pi = new Proxy({
|
|
78
78
|
events,
|
|
79
|
-
on(name, handler) { handlers.set(name, handler); },
|
|
79
|
+
on(name, handler) { handlers.set(name, [...(handlers.get(name) ?? []), handler]); },
|
|
80
80
|
registerTool() {}, registerCommand() {}, registerShortcut() {}, registerMessageRenderer() {},
|
|
81
81
|
sendMessage() {}, getSessionName() { return undefined; },
|
|
82
82
|
}, { get(target, prop) { return prop in target ? target[prop] : () => undefined; } });
|
|
83
83
|
let stale = false;
|
|
84
84
|
const ctx = { cwd: process.cwd(), get hasUI() { if (stale) throw new Error("This extension ctx is stale after session replacement or reload."); return true; }, ui: { setWidget() {}, requestRender() {}, onTerminalInput() { return () => {}; }, getEditorText() { return ""; }, notify() {}, theme: { fg(_name, text) { return text; }, bg(_name, text) { return text; }, bold(text) { return text; } } }, sessionManager: { getSessionId() { return "stale-context-session"; }, getSessionFile() { return null; }, getEntries() { return []; } }, modelRegistry: { getAvailable() { return []; } } };
|
|
85
85
|
registerSubagentExtension(pi);
|
|
86
|
-
handlers.get("session_start")({}, ctx);
|
|
86
|
+
for (const handler of handlers.get("session_start")) await handler({}, ctx);
|
|
87
87
|
events.emit("subagent:async-started", { id: "running", sessionId: "stale-context-session", mode: "single", agent: "worker", asyncDir: "/tmp/pi-stale-context-running" });
|
|
88
88
|
stale = true;
|
|
89
|
-
handlers.get("session_compact")({ reason: "threshold" });
|
|
90
|
-
handlers.get("session_before_compact")({ reason: "threshold", signal: new AbortController().signal });
|
|
91
|
-
|
|
89
|
+
for (const handler of handlers.get("session_compact")) await handler({ reason: "threshold" });
|
|
90
|
+
for (const handler of handlers.get("session_before_compact")) await handler({ reason: "threshold", signal: new AbortController().signal });
|
|
91
|
+
for (const handler of handlers.get("session_shutdown")) await handler();
|
|
92
92
|
`;
|
|
93
93
|
const env = { ...process.env };
|
|
94
94
|
delete env.SELESAI_SUBAGENT_CHILD;
|
|
95
95
|
execFileSync(process.execPath, ["--experimental-strip-types", "--import", "./test/support/register-loader.mjs", "--input-type=module", "--eval", script], { cwd: projectRoot, env, stdio: "pipe" });
|
|
96
96
|
assert.ok(true);
|
|
97
97
|
});
|
|
98
|
-
});
|
|
98
|
+
});
|
|
@@ -23,7 +23,7 @@ describe("planCompletionEvidence", () => {
|
|
|
23
23
|
implementationMutationExpected: true,
|
|
24
24
|
mutationAttemptObserved: false,
|
|
25
25
|
mutationEvidence: evidence,
|
|
26
|
-
|
|
26
|
+
agentContractEnabled: false,
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
assert.equal(plan.guardTriggered, true);
|
|
@@ -37,14 +37,14 @@ describe("planCompletionEvidence", () => {
|
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
it("keeps agent contract
|
|
40
|
+
it("keeps agent contract rejection in evidence without forcing execution failure", () => {
|
|
41
41
|
const plan = planCompletionEvidence({
|
|
42
42
|
guard: { expectedMutation: true, attemptedMutation: false, triggered: true, blocked: false },
|
|
43
43
|
completionGuardEnabled: true,
|
|
44
44
|
mutationCapable: true,
|
|
45
45
|
implementationMutationExpected: true,
|
|
46
46
|
mutationAttemptObserved: false,
|
|
47
|
-
|
|
47
|
+
agentContractEnabled: true,
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
assert.equal(plan.guardTriggered, true);
|
|
@@ -59,7 +59,7 @@ describe("planCompletionEvidence", () => {
|
|
|
59
59
|
mutationCapable: false,
|
|
60
60
|
implementationMutationExpected: true,
|
|
61
61
|
mutationAttemptObserved: true,
|
|
62
|
-
|
|
62
|
+
agentContractEnabled: false,
|
|
63
63
|
});
|
|
64
64
|
assert.deepEqual(blocked.fileMutation, {
|
|
65
65
|
status: "blocked",
|
|
@@ -86,7 +86,7 @@ describe("planCompletionEvidence", () => {
|
|
|
86
86
|
implementationMutationExpected: true,
|
|
87
87
|
mutationAttemptObserved: false,
|
|
88
88
|
arbiterRescued: true,
|
|
89
|
-
|
|
89
|
+
agentContractEnabled: false,
|
|
90
90
|
});
|
|
91
91
|
assert.deepEqual(rescued.fileMutation, {
|
|
92
92
|
status: "not-applicable",
|
|
@@ -103,7 +103,7 @@ describe("planCompletionEvidence", () => {
|
|
|
103
103
|
mutationCapable: true,
|
|
104
104
|
implementationMutationExpected: true,
|
|
105
105
|
mutationAttemptObserved: false,
|
|
106
|
-
|
|
106
|
+
agentContractEnabled: false,
|
|
107
107
|
});
|
|
108
108
|
assert.equal(plan.mutationExpected, true);
|
|
109
109
|
assert.equal(plan.fileMutation, undefined);
|
|
@@ -117,7 +117,7 @@ describe("projectSettlementDiagnostic", () => {
|
|
|
117
117
|
mutationCapable: true,
|
|
118
118
|
implementationMutationExpected: true,
|
|
119
119
|
mutationAttemptObserved: false,
|
|
120
|
-
|
|
120
|
+
agentContractEnabled: false,
|
|
121
121
|
});
|
|
122
122
|
assert.deepEqual(projectSettlementDiagnostic(plan, {
|
|
123
123
|
terminalFailed: true,
|
|
@@ -139,7 +139,7 @@ describe("projectSettlementDiagnostic", () => {
|
|
|
139
139
|
mutationCapable: false,
|
|
140
140
|
implementationMutationExpected: false,
|
|
141
141
|
mutationAttemptObserved: false,
|
|
142
|
-
|
|
142
|
+
agentContractEnabled: false,
|
|
143
143
|
});
|
|
144
144
|
assert.equal(projectSettlementDiagnostic(plan, {
|
|
145
145
|
terminalFailed: false,
|
|
@@ -147,4 +147,4 @@ describe("projectSettlementDiagnostic", () => {
|
|
|
147
147
|
mutationObserved: false,
|
|
148
148
|
}), undefined);
|
|
149
149
|
});
|
|
150
|
-
});
|
|
150
|
+
});
|
|
@@ -53,7 +53,7 @@ function revivedTask(followUp: string): string {
|
|
|
53
53
|
"Original agent: worker",
|
|
54
54
|
"Original session file: /tmp/session.jsonl",
|
|
55
55
|
"",
|
|
56
|
-
"Use the stored session context as background. Answer the orchestrator's follow-up below. Do not assume the original child
|
|
56
|
+
"Use the stored session context as background. Answer the orchestrator's follow-up below. Do not assume the original child session is still running.",
|
|
57
57
|
"",
|
|
58
58
|
"Follow-up:",
|
|
59
59
|
followUp,
|
|
@@ -241,12 +241,13 @@ test("implementation challenge reports with negated or uncertain no-better-chang
|
|
|
241
241
|
|
|
242
242
|
});
|
|
243
243
|
|
|
244
|
-
test("
|
|
244
|
+
test("source_check read-only capability suppresses an implementation completion guard", () => {
|
|
245
|
+
assert.equal(expectsImplementationMutation("worker", "Implement the approved fix"), true);
|
|
245
246
|
const result = evaluateCompletionMutationGuard({
|
|
246
|
-
agent: "
|
|
247
|
-
task: "
|
|
248
|
-
messages: [assistantText("
|
|
249
|
-
tools: ["
|
|
247
|
+
agent: "worker",
|
|
248
|
+
task: "Implement the approved fix",
|
|
249
|
+
messages: [assistantText("Source evidence only")],
|
|
250
|
+
tools: ["source_check"],
|
|
250
251
|
});
|
|
251
252
|
|
|
252
253
|
assert.deepEqual(result, {
|
|
@@ -750,4 +751,4 @@ test("read-only agents and pure extension workers keep their launch contracts",
|
|
|
750
751
|
requestedTools: ["read"],
|
|
751
752
|
completionGuard: false,
|
|
752
753
|
}), undefined);
|
|
753
|
-
});
|
|
754
|
+
});
|