@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
|
@@ -2,12 +2,14 @@ import * as fs from "node:fs";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import type { AgentToolResult } from "@earendil-works/pi-agent-core";
|
|
4
4
|
import { safeTerminalText } from "../../shared/display-text.ts";
|
|
5
|
+
import { getArtifactPaths, getArtifactsDir } from "../../shared/artifacts.ts";
|
|
6
|
+
import { readFleetTranscript } from "../../tui/fleet-transcript.ts";
|
|
5
7
|
import { formatAsyncRunList, formatAsyncRunOutputPath, formatAsyncRunProgressLabel, formatWorkflowStageLine, listAsyncRuns } from "./async-status.ts";
|
|
6
8
|
import { formatAsyncResultTranscript, formatAsyncRunTranscript, formatNestedRunTranscript, inspectSubagentFleet } from "./fleet-view.ts";
|
|
7
9
|
import { formatNestedRunStatusLines } from "../shared/nested-render.ts";
|
|
8
10
|
import { formatModelThinking } from "../../shared/formatters.ts";
|
|
9
11
|
import { formatActivityLabel } from "../../shared/status-format.ts";
|
|
10
|
-
import { DIRS, type AsyncStatus, type Details, type ForegroundResumeRun, type NestedRunSummary, type SteeringStatus, type SubagentState } from "../../shared/types.ts";
|
|
12
|
+
import { DIRS, type AsyncStatus, type Details, type ForegroundRunControl, type ForegroundResumeRun, type NestedRunSummary, type SteeringStatus, type SubagentState } from "../../shared/types.ts";
|
|
11
13
|
import { inspectActiveAsyncCapacityOwner, type ActiveAsyncCapacityInspection } from "./active-async-capacity.ts";
|
|
12
14
|
import { readStatus } from "../../shared/utils.ts";
|
|
13
15
|
import { resolveSubagentIntercomTarget } from "../../intercom/intercom-bridge.ts";
|
|
@@ -88,6 +90,7 @@ function formatRunLifecycleDebug(input: { status: AsyncStatus; asyncDir: string;
|
|
|
88
90
|
`Run: ${status.runId}`,
|
|
89
91
|
`Dir: ${asyncDir}`,
|
|
90
92
|
`Status file: ${path.join(asyncDir, "status.json")}`,
|
|
93
|
+
status.workflowReceiptPath ? `Workflow receipt: ${status.workflowReceiptPath}` : undefined,
|
|
91
94
|
`Process terminal file: ${path.join(asyncDir, "process-terminal.json")}`,
|
|
92
95
|
`Session: ${status.sessionId ?? "unknown"}`,
|
|
93
96
|
`State: ${status.state}`,
|
|
@@ -241,6 +244,54 @@ function formatRememberedForegroundStatus(run: ForegroundResumeRun): string {
|
|
|
241
244
|
return lines.join("\n");
|
|
242
245
|
}
|
|
243
246
|
|
|
247
|
+
/** Request-only snapshot of the same artifact used by Fleet; no session or output fallback. */
|
|
248
|
+
function formatLiveForegroundTranscript(control: ForegroundRunControl, state: SubagentState, options: { index?: number; lines?: number }): string {
|
|
249
|
+
if (!state.currentSessionId || control.sessionId !== state.currentSessionId) {
|
|
250
|
+
throw new Error(`Foreground run '${control.runId}' is not owned by the current session.`);
|
|
251
|
+
}
|
|
252
|
+
if (options.index !== undefined && (!Number.isInteger(options.index) || options.index < 0)) {
|
|
253
|
+
throw new Error("Transcript index must be a non-negative integer.");
|
|
254
|
+
}
|
|
255
|
+
const children = control.activeChildren
|
|
256
|
+
? [...control.activeChildren.values()]
|
|
257
|
+
: control.currentAgent ? [{ index: control.currentIndex ?? 0, agent: control.currentAgent, sessionName: control.sessionName }] : [];
|
|
258
|
+
const header = [`Run: ${control.runId}`, "State: live foreground"];
|
|
259
|
+
if (children.length === 0) return `${header.map((line) => safeTerminalText(line)).join("\n")}\nTranscript unavailable: no active foreground child.`;
|
|
260
|
+
if (options.index === undefined && children.length > 1) {
|
|
261
|
+
throw new Error(`Transcript view requires index for foreground run '${control.runId}'. Active child indexes: ${children.map((child) => child.index).join(", ")}.`);
|
|
262
|
+
}
|
|
263
|
+
const child = options.index === undefined ? children[0]! : children.find((child) => child.index === options.index);
|
|
264
|
+
if (!child) throw new Error(`Transcript index ${options.index} is not an active foreground child of '${control.runId}'.`);
|
|
265
|
+
const root = getArtifactsDir(state.parentSessionFile ?? null, control.cwd ?? state.baseCwd, state.artifactDirPreference);
|
|
266
|
+
const transcriptPath = getArtifactPaths(root, control.runId, child.agent, child.index).transcriptPath;
|
|
267
|
+
const transcript = readFleetTranscript(transcriptPath, { trustedRoots: [root] });
|
|
268
|
+
const lineLimit = Number.isFinite(options.lines) ? Math.max(1, Math.min(500, Math.trunc(options.lines!))) : 80;
|
|
269
|
+
const allLines = transcript.events.flatMap((event) => {
|
|
270
|
+
const text = event.kind === "tool"
|
|
271
|
+
? [`Tool: ${event.name} (${event.status})`, event.argsPayload ?? event.args, event.output ?? event.error].filter(Boolean).join("\n")
|
|
272
|
+
: event.kind === "notice" ? event.text : `${event.kind === "assistant" ? "Assistant" : "Supervisor"}: ${event.text}`;
|
|
273
|
+
return text.split(/\r?\n/);
|
|
274
|
+
});
|
|
275
|
+
let body = allLines.slice(-lineLimit).join("\n");
|
|
276
|
+
let truncated = transcript.truncated || allLines.length > lineLimit
|
|
277
|
+
|| transcript.events.some((event) => event.kind === "tool" && event.outputTruncated)
|
|
278
|
+
|| body.includes("… message truncated");
|
|
279
|
+
const maxOutputBytes = 32 * 1024;
|
|
280
|
+
const bytes = Buffer.from(body);
|
|
281
|
+
if (bytes.length > maxOutputBytes) {
|
|
282
|
+
// Skip UTF-8 continuation bytes at the beginning of the bounded tail.
|
|
283
|
+
let start = bytes.length - maxOutputBytes;
|
|
284
|
+
while ((bytes[start]! & 0xc0) === 0x80) start++;
|
|
285
|
+
body = bytes.subarray(start).toString("utf-8");
|
|
286
|
+
truncated = true;
|
|
287
|
+
}
|
|
288
|
+
header.push(`Child: ${child.index} (${child.sessionName?.trim() || child.agent})`, `Transcript: ${transcriptPath}`);
|
|
289
|
+
if (transcript.warning) header.push(`Transcript warning: ${transcript.warning}`);
|
|
290
|
+
header.push(`Live transcript tail${truncated ? " (tail truncated)" : ""}:`);
|
|
291
|
+
if (!body) header.push("Transcript unavailable: no readable activity in the bounded artifact tail yet.");
|
|
292
|
+
return [...header.map((line) => safeTerminalText(line)), body].filter(Boolean).join("\n");
|
|
293
|
+
}
|
|
294
|
+
|
|
244
295
|
function formatRememberedForegroundTranscript(run: ForegroundResumeRun, options: { index?: number; lines?: number }): string {
|
|
245
296
|
let index = options.index;
|
|
246
297
|
if (index !== undefined && !Number.isInteger(index)) throw new Error("Transcript index must be an integer.");
|
|
@@ -313,6 +364,12 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
313
364
|
return inspectSubagentFleet(params, { asyncDirRoot, resultsDir, kill: deps.kill, now: deps.now, state: deps.state, childSafe: Boolean(deps.nested) });
|
|
314
365
|
}
|
|
315
366
|
if (!params.id && !params.runId && !params.dir) {
|
|
367
|
+
if (params.view === "transcript" && deps.state?.currentSessionId) {
|
|
368
|
+
const controls = [...deps.state.foregroundControls.values()].filter((control) => control.sessionId === currentSessionId);
|
|
369
|
+
const foreground = controls.find((control) => control.runId === deps.state?.lastForegroundControlId)
|
|
370
|
+
?? controls.sort((left, right) => right.updatedAt - left.updatedAt)[0];
|
|
371
|
+
if (foreground) return inspectSubagentStatus({ ...params, id: foreground.runId }, deps);
|
|
372
|
+
}
|
|
316
373
|
if (deps.nested) {
|
|
317
374
|
return {
|
|
318
375
|
content: [{ type: "text", text: "Child-safe subagent status requires an id when no foreground run is active." }],
|
|
@@ -353,6 +410,13 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
353
410
|
} else if (!params.dir && requestedId) {
|
|
354
411
|
const resolved = resolveSubagentRunId(requestedId, { asyncDirRoot, resultsDir, state: deps.state, nested: deps.nested });
|
|
355
412
|
if (resolved?.kind === "foreground") {
|
|
413
|
+
const control = deps.state?.foregroundControls.get(resolved.id);
|
|
414
|
+
if (control && deps.state && params.view === "transcript") {
|
|
415
|
+
return {
|
|
416
|
+
content: [{ type: "text", text: formatLiveForegroundTranscript(control, deps.state, params) }],
|
|
417
|
+
details: { mode: "management", results: [] },
|
|
418
|
+
};
|
|
419
|
+
}
|
|
356
420
|
const run = deps.state?.foregroundRuns?.get(resolved.id);
|
|
357
421
|
if (run) {
|
|
358
422
|
try {
|
|
@@ -423,7 +487,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
423
487
|
const capacity = inspectActiveAsyncCapacityOwner({ runId: diskStatus.runId, sessionId: diskStatus.sessionId, asyncDir }, { rootDir: deps.activeCapacityRoot, liveWorkflowRunIds: new Set(deps.state?.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: deps.abandonedSlotReleaseAfterMs });
|
|
424
488
|
return {
|
|
425
489
|
content: [{ type: "text", text: formatRunLifecycleDebug({ status: diskStatus, asyncDir, sidecarProcessTerminal: sidecar, overlayProcessTerminal: overlay, capacity }) }],
|
|
426
|
-
details: { mode: "single", results: [], ...((sidecar ?? overlay) ? { lifecycleStatus: { processTerminal: sidecar ?? overlay } } : {}) },
|
|
490
|
+
details: { mode: "single", results: [], ...(diskStatus.workflowReceiptPath ? { workflowReceiptPath: diskStatus.workflowReceiptPath } : {}), ...((sidecar ?? overlay) ? { lifecycleStatus: { processTerminal: sidecar ?? overlay } } : {}) },
|
|
427
491
|
};
|
|
428
492
|
}
|
|
429
493
|
if (params.view === "transcript") {
|
|
@@ -450,7 +514,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
450
514
|
const capacity = inspectActiveAsyncCapacityOwner({ runId: status.runId, sessionId: status.sessionId, asyncDir }, { rootDir: deps.activeCapacityRoot, liveWorkflowRunIds: new Set(deps.state?.workflowControllers?.keys() ?? []), abandonedSlotReleaseAfterMs: deps.abandonedSlotReleaseAfterMs });
|
|
451
515
|
return {
|
|
452
516
|
content: [{ type: "text", text: formatRunLifecycleDebug({ status, asyncDir, sidecarProcessTerminal: sidecar, overlayProcessTerminal: overlay, capacity }) }],
|
|
453
|
-
details: { mode: "single", results: [], ...((sidecar ?? overlay) ? { lifecycleStatus: { processTerminal: sidecar ?? overlay } } : {}) },
|
|
517
|
+
details: { mode: "single", results: [], ...(status.workflowReceiptPath ? { workflowReceiptPath: status.workflowReceiptPath } : {}), ...((sidecar ?? overlay) ? { lifecycleStatus: { processTerminal: sidecar ?? overlay } } : {}) },
|
|
454
518
|
};
|
|
455
519
|
}
|
|
456
520
|
if (params.view === "transcript") {
|
|
@@ -545,7 +609,6 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
545
609
|
const liveWorkflowControls = status.mode === "workflow" && deps.state?.currentSessionId === status.sessionId && deps.state?.workflowControllers?.has(status.runId)
|
|
546
610
|
? [...(deps.state?.foregroundControls.values() ?? [])].filter((control) => control.parentWorkflowRunId === status.runId
|
|
547
611
|
&& control.sessionId === status.sessionId
|
|
548
|
-
&& Boolean(control.workflowSteeringDir && fs.existsSync(control.workflowSteeringDir))
|
|
549
612
|
&& (control.activeChildren?.size ?? 0) > 0)
|
|
550
613
|
: [];
|
|
551
614
|
let hasExternalJobFollowUpHint = false;
|
|
@@ -627,6 +690,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
627
690
|
}
|
|
628
691
|
}
|
|
629
692
|
if (nestedWarning) lines.push(`Warning: ${nestedWarning}`);
|
|
693
|
+
if (status.workflowReceiptPath) lines.push(`Workflow receipt: ${status.workflowReceiptPath}`);
|
|
630
694
|
if (status.sessionFile) lines.push(`Session: ${status.sessionFile}`);
|
|
631
695
|
const allExternal = (status.steps?.length ?? 0) > 0 && status.steps!.every((step) => step.runner?.type === "external-cli" || step.runner?.type === "external-job");
|
|
632
696
|
if (status.state === "running" && !allExternal && status.mode !== "workflow") lines.push(`Steer running child: subagent({ action: "steer", id: "${status.runId}", message: "..." })`);
|
|
@@ -640,7 +704,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
640
704
|
|
|
641
705
|
const workflowChildren = parseWorkflowChildSummary(status.workflowChildren);
|
|
642
706
|
if (workflowChildren && workflowChildren.workflowRunId !== status.runId) throw new Error("workflowChildren.workflowRunId does not match async status runId.");
|
|
643
|
-
return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(status.preflight ? { preflight: status.preflight } : {}), ...(status.workflow?.preflightWarnings?.length ? { preflightWarnings: status.workflow.preflightWarnings } : {}), ...(workflowChildren ? { workflowChildren } : {}), ...(runFanoutBudget ? { runFanoutBudget } : {}), ...(processTerminal ? { lifecycleStatus: { processTerminal } } : {}) } };
|
|
707
|
+
return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(status.workflowReceiptPath ? { workflowReceiptPath: status.workflowReceiptPath } : {}), ...(status.preflight ? { preflight: status.preflight } : {}), ...(status.workflow?.preflightWarnings?.length ? { preflightWarnings: status.workflow.preflightWarnings } : {}), ...(workflowChildren ? { workflowChildren } : {}), ...(runFanoutBudget ? { runFanoutBudget } : {}), ...(processTerminal ? { lifecycleStatus: { processTerminal } } : {}) } };
|
|
644
708
|
}
|
|
645
709
|
}
|
|
646
710
|
|
|
@@ -681,6 +745,11 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
681
745
|
const runId = data.runId ?? data.id ?? resolvedId;
|
|
682
746
|
const lines = [`Run: ${runId}`, data.toolCallId ? `Tool call: ${data.toolCallId}` : undefined, `State: ${status}`, `Result: ${resultPath}`].filter((line): line is string => Boolean(line));
|
|
683
747
|
if (data.parallelHandoff?.path) lines.push(`Parallel handoff: ${data.parallelHandoff.path}`);
|
|
748
|
+
const receipt = (data as Record<string, unknown>).workflowReceipt;
|
|
749
|
+
const receiptPath = receipt && typeof receipt === "object" && !Array.isArray(receipt)
|
|
750
|
+
? (receipt as Record<string, unknown>).path : undefined;
|
|
751
|
+
const workflowReceiptPath = typeof receiptPath === "string" && receiptPath ? receiptPath : undefined;
|
|
752
|
+
if (workflowReceiptPath) lines.push(`Workflow receipt: ${workflowReceiptPath}`);
|
|
684
753
|
const children = Array.isArray(data.results) ? data.results : data.agent ? [{ agent: data.agent, sessionFile: data.sessionFile }] : [];
|
|
685
754
|
lines.push(...formatTimeoutRecoveryLines(data.timeoutRecovery, " "));
|
|
686
755
|
for (const [index, child] of children.entries()) {
|
|
@@ -695,7 +764,7 @@ export function inspectSubagentStatus(params: RunStatusParams, deps: RunStatusDe
|
|
|
695
764
|
if (data.summary) lines.push("", data.summary);
|
|
696
765
|
const workflowChildren = parseWorkflowChildSummary((data as unknown as Record<string, unknown>).workflowChildren);
|
|
697
766
|
if (workflowChildren && workflowChildren.workflowRunId !== runId) throw new Error("workflowChildren.workflowRunId does not match the result run id.");
|
|
698
|
-
return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(workflowChildren ? { workflowChildren } : {}) } };
|
|
767
|
+
return { content: [{ type: "text", text: lines.join("\n") }], details: { mode: "single", results: [], ...(workflowReceiptPath ? { workflowReceiptPath } : {}), ...(workflowChildren ? { workflowChildren } : {}) } };
|
|
699
768
|
} catch (error) {
|
|
700
769
|
const message = error instanceof Error ? error.message : String(error);
|
|
701
770
|
return {
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module aliases for the detached async runner.
|
|
3
|
+
*
|
|
4
|
+
* The runner is a plain Node process started through jiti. The child hooks it
|
|
5
|
+
* loads import pi's host packages (`@selesai/code`,
|
|
6
|
+
* `pi-agent-core`, `pi-ai`, `pi-tui`, `typebox`), which are peer packages of
|
|
7
|
+
* this extension and are not installed next to it. pi's own extension loader
|
|
8
|
+
* aliases those specifiers to the copies shipped inside the installed pi
|
|
9
|
+
* package; the parent computes the same map and hands it to the runner
|
|
10
|
+
* through `JITI_ALIAS`, so child sessions and hooks retain host API identity.
|
|
11
|
+
* Only Pi 0.85.0's missing server exports may come from this extension.
|
|
12
|
+
*/
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
16
|
+
|
|
17
|
+
export const JITI_ALIAS_ENV = "JITI_ALIAS";
|
|
18
|
+
|
|
19
|
+
/** Specifiers the runner's import graph may use, with the package and export subpath each resolves to. */
|
|
20
|
+
export const HOST_PEER_ALIASES: ReadonlyArray<{ specifier: string; pkg: string; subpath: string }> = [
|
|
21
|
+
{ specifier: "@selesai/code", pkg: "@selesai/code", subpath: "." },
|
|
22
|
+
{ specifier: "@earendil-works/pi-agent-core", pkg: "@earendil-works/pi-agent-core", subpath: "." },
|
|
23
|
+
{ specifier: "@earendil-works/pi-agent-core/node", pkg: "@earendil-works/pi-agent-core", subpath: "./node" },
|
|
24
|
+
{ specifier: "@earendil-works/chord", pkg: "@earendil-works/chord", subpath: "." },
|
|
25
|
+
{ specifier: "@earendil-works/chord/context", pkg: "@earendil-works/chord", subpath: "./context" },
|
|
26
|
+
{ specifier: "@earendil-works/pi-tui", pkg: "@earendil-works/pi-tui", subpath: "." },
|
|
27
|
+
{ specifier: "@earendil-works/pi-ai", pkg: "@earendil-works/pi-ai", subpath: "./compat" },
|
|
28
|
+
{ specifier: "@earendil-works/pi-ai/compat", pkg: "@earendil-works/pi-ai", subpath: "./compat" },
|
|
29
|
+
{ specifier: "@earendil-works/pi-ai/oauth", pkg: "@earendil-works/pi-ai", subpath: "./oauth" },
|
|
30
|
+
{ specifier: "@earendil-works/pi-ai/providers/all", pkg: "@earendil-works/pi-ai", subpath: "./providers/all" },
|
|
31
|
+
{ specifier: "typebox", pkg: "typebox", subpath: "." },
|
|
32
|
+
{ specifier: "typebox/compile", pkg: "typebox", subpath: "./compile" },
|
|
33
|
+
{ specifier: "typebox/value", pkg: "typebox", subpath: "./value" },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
/** Experimental dependencies accidentally published in exactly Pi 0.85.0. */
|
|
37
|
+
const PI0850_PEER_ALIASES = [
|
|
38
|
+
{ specifier: "@earendil-works/pi-server", pkg: "@earendil-works/pi-server", subpath: "." },
|
|
39
|
+
{ specifier: "@earendil-works/pi-server/unix", pkg: "@earendil-works/pi-server", subpath: "./unix" },
|
|
40
|
+
{ specifier: "@earendil-works/pi-client/unix", pkg: "@earendil-works/pi-client", subpath: "./unix" },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
interface PackageManifest {
|
|
44
|
+
name?: unknown;
|
|
45
|
+
version?: unknown;
|
|
46
|
+
main?: unknown;
|
|
47
|
+
exports?: unknown;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function readManifest(packageDir: string): PackageManifest | undefined {
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs.readFileSync(path.join(packageDir, "package.json"), "utf-8")) as PackageManifest;
|
|
53
|
+
} catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Pick the import target of one exports entry (string, conditions object, or array of those). */
|
|
59
|
+
function exportTarget(entry: unknown): string | undefined {
|
|
60
|
+
if (typeof entry === "string") return entry;
|
|
61
|
+
if (Array.isArray(entry)) {
|
|
62
|
+
for (const candidate of entry) {
|
|
63
|
+
const target = exportTarget(candidate);
|
|
64
|
+
if (target) return target;
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
if (entry && typeof entry === "object") {
|
|
69
|
+
const conditions = entry as Record<string, unknown>;
|
|
70
|
+
for (const condition of ["import", "node", "default"]) {
|
|
71
|
+
if (condition in conditions) {
|
|
72
|
+
const target = exportTarget(conditions[condition]);
|
|
73
|
+
if (target) return target;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Resolve `subpath` of the package at `packageDir` through its `exports` map (with `*` patterns) or `main`. */
|
|
81
|
+
export function resolvePackageSubpath(packageDir: string, subpath: string): string | undefined {
|
|
82
|
+
const manifest = readManifest(packageDir);
|
|
83
|
+
if (!manifest) return undefined;
|
|
84
|
+
const exportsField = manifest.exports;
|
|
85
|
+
if (exportsField !== undefined) {
|
|
86
|
+
const map: Record<string, unknown> = typeof exportsField === "string" || Array.isArray(exportsField) || (exportsField && typeof exportsField === "object" && !Object.keys(exportsField as object).some((key) => key.startsWith(".")))
|
|
87
|
+
? { ".": exportsField }
|
|
88
|
+
: exportsField as Record<string, unknown>;
|
|
89
|
+
const exact = exportTarget(map[subpath]);
|
|
90
|
+
if (exact) return path.resolve(packageDir, exact);
|
|
91
|
+
for (const [pattern, entry] of Object.entries(map)) {
|
|
92
|
+
const star = pattern.indexOf("*");
|
|
93
|
+
if (star === -1) continue;
|
|
94
|
+
const prefix = pattern.slice(0, star);
|
|
95
|
+
const suffix = pattern.slice(star + 1);
|
|
96
|
+
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix) || subpath.length < prefix.length + suffix.length) continue;
|
|
97
|
+
const target = exportTarget(entry);
|
|
98
|
+
if (!target) continue;
|
|
99
|
+
const wildcard = subpath.slice(prefix.length, subpath.length - suffix.length);
|
|
100
|
+
return path.resolve(packageDir, target.replace("*", wildcard));
|
|
101
|
+
}
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
if (subpath !== ".") return undefined;
|
|
105
|
+
return path.resolve(packageDir, typeof manifest.main === "string" && manifest.main.trim() ? manifest.main : "index.js");
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Find `pkg` as the pi package itself, one of its dependencies, or a sibling in a hoisted install. */
|
|
109
|
+
export function findHostPeerPackageDir(piPackageRoot: string, pkg: string): string | undefined {
|
|
110
|
+
return findPeerPackageDir(piPackageRoot, pkg, readManifest(piPackageRoot)?.name);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function findPeerPackageDir(piPackageRoot: string, pkg: string, hostName: unknown): string | undefined {
|
|
114
|
+
if (hostName === pkg) return piPackageRoot;
|
|
115
|
+
const candidates = [path.join(piPackageRoot, "node_modules", pkg)];
|
|
116
|
+
let dir = piPackageRoot;
|
|
117
|
+
for (;;) {
|
|
118
|
+
const parent = path.dirname(dir);
|
|
119
|
+
if (parent === dir) break;
|
|
120
|
+
if (path.basename(parent) === "node_modules" || path.basename(path.dirname(parent)) === "node_modules") {
|
|
121
|
+
const modulesRoot = path.basename(parent) === "node_modules" ? parent : path.dirname(parent);
|
|
122
|
+
candidates.push(path.join(modulesRoot, pkg));
|
|
123
|
+
}
|
|
124
|
+
candidates.push(path.join(parent, "node_modules", pkg));
|
|
125
|
+
dir = parent;
|
|
126
|
+
}
|
|
127
|
+
return candidates.find((candidate) => readManifest(candidate)?.name === pkg);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** The alias map the runner needs, or the specifiers that could not be resolved. */
|
|
131
|
+
export function resolveHostPeerAliases(
|
|
132
|
+
piPackageRoot: string,
|
|
133
|
+
extensionRoot = fileURLToPath(new URL("../../../", import.meta.url)),
|
|
134
|
+
): { aliases: Record<string, string>; missing: string[]; supplemental: string[] } {
|
|
135
|
+
const aliases: Record<string, string> = {};
|
|
136
|
+
const missing: string[] = [];
|
|
137
|
+
const supplemental: string[] = [];
|
|
138
|
+
const hostManifest = readManifest(piPackageRoot);
|
|
139
|
+
const isPi0850 = hostManifest?.version === "0.85.0";
|
|
140
|
+
const required = isPi0850 ? [...HOST_PEER_ALIASES, ...PI0850_PEER_ALIASES] : HOST_PEER_ALIASES;
|
|
141
|
+
for (const { specifier, pkg, subpath } of required) {
|
|
142
|
+
const packageDir = findPeerPackageDir(piPackageRoot, pkg, hostManifest?.name);
|
|
143
|
+
let target = packageDir ? resolvePackageSubpath(packageDir, subpath) : undefined;
|
|
144
|
+
// Pi 0.85.0 omitted this runtime dependency. Never replace working host
|
|
145
|
+
// exports or extend this exact version contract to other peers/hosts.
|
|
146
|
+
if ((!target || !fs.existsSync(target))
|
|
147
|
+
&& (specifier === "@earendil-works/pi-server" || specifier === "@earendil-works/pi-server/unix")
|
|
148
|
+
&& isPi0850
|
|
149
|
+
&& (!packageDir || readManifest(packageDir)?.version === "0.85.0")) {
|
|
150
|
+
const localDir = findHostPeerPackageDir(extensionRoot, pkg);
|
|
151
|
+
if (localDir && readManifest(localDir)?.version === "0.85.0") {
|
|
152
|
+
const localTarget = resolvePackageSubpath(localDir, subpath);
|
|
153
|
+
if (localTarget && fs.existsSync(localTarget)) {
|
|
154
|
+
target = localTarget;
|
|
155
|
+
supplemental.push(specifier);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (target && fs.existsSync(target)) aliases[specifier] = target;
|
|
160
|
+
else missing.push(specifier);
|
|
161
|
+
}
|
|
162
|
+
return { aliases, missing, supplemental };
|
|
163
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/** Native runner construction, separate from its executable entrypoint and attempt loop. */
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { buildInProcessChildLaunch, type BuildInProcessChildLaunchInput, type InheritedChildRuntime } from "../shared/child-launch.ts";
|
|
4
|
+
import { deriveForkPromptCacheKey } from "../shared/child-tool-plan.ts";
|
|
5
|
+
import { normalizeExtensionBindings } from "../shared/extension-bindings.ts";
|
|
6
|
+
import type { RunnerSubagentStep } from "../shared/parallel-utils.ts";
|
|
7
|
+
import { formatAcceptancePrompt } from "../shared/acceptance.ts";
|
|
8
|
+
import { isAgentContract } from "../shared/agent-contract.ts";
|
|
9
|
+
|
|
10
|
+
export interface RunnerChildLaunchContext {
|
|
11
|
+
cwd: string;
|
|
12
|
+
id: string;
|
|
13
|
+
flatIndex: number;
|
|
14
|
+
artifactsDir?: string;
|
|
15
|
+
childIntercomTarget?: string;
|
|
16
|
+
orchestratorIntercomTarget?: string;
|
|
17
|
+
nestedRoute?: BuildInProcessChildLaunchInput["nestedRoute"];
|
|
18
|
+
runFanoutBudget?: BuildInProcessChildLaunchInput["runFanoutBudget"];
|
|
19
|
+
capabilityCeiling?: BuildInProcessChildLaunchInput["capabilityCeiling"];
|
|
20
|
+
inheritedChildRuntime?: InheritedChildRuntime;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function buildRunnerChildLaunch(step: RunnerSubagentStep, ctx: RunnerChildLaunchContext, attempt: {
|
|
24
|
+
model?: string;
|
|
25
|
+
sessionEnabled: boolean;
|
|
26
|
+
sessionDir?: string;
|
|
27
|
+
sessionName?: string;
|
|
28
|
+
structuredOutput?: BuildInProcessChildLaunchInput["structuredOutput"];
|
|
29
|
+
childWatchdog?: BuildInProcessChildLaunchInput["childWatchdog"];
|
|
30
|
+
watchdogStatus: NonNullable<BuildInProcessChildLaunchInput["watchdogStatus"]>;
|
|
31
|
+
}) {
|
|
32
|
+
// Resource-backed system instructions survive SDK split-turn compaction verbatim.
|
|
33
|
+
const acceptancePrompt = step.effectiveAcceptance
|
|
34
|
+
? formatAcceptancePrompt(step.effectiveAcceptance, { reportOptional: isAgentContract(step.agentContract), structuredOutput: Boolean(step.structuredOutput?.acceptanceReportPath) })
|
|
35
|
+
: "";
|
|
36
|
+
return buildInProcessChildLaunch({
|
|
37
|
+
parentSessionId: step.parentSessionId,
|
|
38
|
+
forkCacheKey: step.context === "fork" ? deriveForkPromptCacheKey(step.parentSessionId) : undefined,
|
|
39
|
+
sessionEnabled: attempt.sessionEnabled,
|
|
40
|
+
sessionDir: attempt.sessionDir,
|
|
41
|
+
sessionFile: step.sessionFile,
|
|
42
|
+
model: attempt.model,
|
|
43
|
+
inheritProjectContext: step.inheritProjectContext,
|
|
44
|
+
inheritGlobalContext: step.inheritGlobalContext,
|
|
45
|
+
inheritSkills: step.inheritSkills,
|
|
46
|
+
requireReadTool: Boolean(step.skills?.length),
|
|
47
|
+
tools: step.tools,
|
|
48
|
+
excludeTools: step.excludeTools,
|
|
49
|
+
allowNestedSubagents: step.allowNestedSubagents,
|
|
50
|
+
extensions: step.extensions,
|
|
51
|
+
subagentOnlyExtensions: step.subagentOnlyExtensions,
|
|
52
|
+
fast: step.fast,
|
|
53
|
+
modelCandidates: step.modelCandidates,
|
|
54
|
+
systemPrompt: acceptancePrompt ? `${step.systemPrompt ?? ""}\n${acceptancePrompt}` : step.systemPrompt ?? "",
|
|
55
|
+
systemPromptMode: step.systemPromptMode,
|
|
56
|
+
mcpDirectTools: step.mcpDirectTools,
|
|
57
|
+
extensionBindings: normalizeExtensionBindings(step.extensionBindings)?.value,
|
|
58
|
+
capabilityCeiling: step.capabilityCeiling ?? ctx.capabilityCeiling,
|
|
59
|
+
cwd: step.cwd ?? ctx.cwd,
|
|
60
|
+
intercomSessionName: ctx.childIntercomTarget,
|
|
61
|
+
sessionName: attempt.sessionName,
|
|
62
|
+
orchestratorIntercomTarget: ctx.orchestratorIntercomTarget,
|
|
63
|
+
runId: ctx.id,
|
|
64
|
+
childAgentName: step.agent,
|
|
65
|
+
childIndex: ctx.flatIndex,
|
|
66
|
+
nestedRoute: ctx.nestedRoute,
|
|
67
|
+
runFanoutBudget: ctx.runFanoutBudget ? {
|
|
68
|
+
...ctx.runFanoutBudget,
|
|
69
|
+
...(step.runFanoutPath ? { parentPath: `${ctx.runFanoutBudget.parentPath ? `${ctx.runFanoutBudget.parentPath}/` : ""}${step.runFanoutPath}` } : {}),
|
|
70
|
+
} : undefined,
|
|
71
|
+
structuredOutput: attempt.structuredOutput,
|
|
72
|
+
toolBudget: step.toolBudget,
|
|
73
|
+
permissionRules: step.permissionRules,
|
|
74
|
+
permissionAuditPath: step.permissionRules && ctx.artifactsDir
|
|
75
|
+
? path.join(ctx.artifactsDir, "permission-audit", `${ctx.id}-${ctx.flatIndex}.jsonl`) : undefined,
|
|
76
|
+
childWatchdog: attempt.childWatchdog,
|
|
77
|
+
// registerChildWatchdog returns before reading the sink when unconfigured.
|
|
78
|
+
...(attempt.childWatchdog ? { watchdogStatus: attempt.watchdogStatus } : {}),
|
|
79
|
+
waitToolEnabled: step.waitToolEnabled,
|
|
80
|
+
waitToolDefaultTimeoutMs: step.waitToolDefaultTimeoutMs,
|
|
81
|
+
thinkingCeiling: step.thinkingCeiling,
|
|
82
|
+
maxSubagentDepth: step.maxSubagentDepth,
|
|
83
|
+
inherited: ctx.inheritedChildRuntime,
|
|
84
|
+
host: "runner",
|
|
85
|
+
});
|
|
86
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Child session factory for the detached async runner.
|
|
3
|
+
*
|
|
4
|
+
* The runner imports `@selesai/code` like the parent does;
|
|
5
|
+
* the parent aliases that specifier (and the other host peer packages) to the
|
|
6
|
+
* installed pi package through `JITI_ALIAS` when it spawns the runner, see
|
|
7
|
+
* `runner-aliases.ts`. Tests replace the factory with a scripted one by
|
|
8
|
+
* naming a module in the runner config.
|
|
9
|
+
*/
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { pathToFileURL } from "node:url";
|
|
12
|
+
import { createDefaultChildSessionFactory, type ChildSessionFactory } from "../shared/child-session.ts";
|
|
13
|
+
|
|
14
|
+
export interface RunnerChildSessionConfig {
|
|
15
|
+
/** Test seam: module whose default export is a `ChildSessionFactory`, or a function returning one. */
|
|
16
|
+
childSessionFactoryModule?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isChildSessionFactory(value: unknown): value is ChildSessionFactory {
|
|
20
|
+
return Boolean(value) && typeof value === "object" && typeof (value as ChildSessionFactory).create === "function" && typeof (value as ChildSessionFactory).dispose === "function";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export async function loadRunnerChildSessionFactory(config: RunnerChildSessionConfig): Promise<ChildSessionFactory> {
|
|
24
|
+
if (!config.childSessionFactoryModule) return createDefaultChildSessionFactory();
|
|
25
|
+
const loaded = await import(pathToFileURL(path.resolve(config.childSessionFactoryModule)).href) as { default?: unknown };
|
|
26
|
+
const candidate = typeof loaded.default === "function" ? (loaded.default as () => unknown)() : loaded.default;
|
|
27
|
+
if (!isChildSessionFactory(candidate)) {
|
|
28
|
+
throw new Error(`Child session factory module '${config.childSessionFactoryModule}' must default-export a ChildSessionFactory or a function returning one.`);
|
|
29
|
+
}
|
|
30
|
+
return candidate;
|
|
31
|
+
}
|
|
@@ -14,6 +14,7 @@ import type { ResolvedSubagentCapabilityCeiling } from "../shared/capability-cei
|
|
|
14
14
|
import { previewSimpleWorkflowRun } from "../../workflows/scripted-workflow.ts";
|
|
15
15
|
import { resolveGitRepositoryIdentity } from "../../workflows/chat-progress.ts";
|
|
16
16
|
import { getConfigDirName } from "../../shared/utils.ts";
|
|
17
|
+
import { normalizeWorktreeBaseRef } from "../shared/worktree.ts";
|
|
17
18
|
|
|
18
19
|
export const SCHEDULED_RUN_ACTIONS = [
|
|
19
20
|
"schedule.create",
|
|
@@ -39,7 +40,7 @@ export type ScheduleRunState = "running" | "skipped" | "missed" | "completed" |
|
|
|
39
40
|
export type ScheduleTrigger =
|
|
40
41
|
| { kind: "once"; at: string; nextRunAt?: string }
|
|
41
42
|
| { kind: "interval"; every: string; everyMs: number; anchorAt: string; nextRunAt: string };
|
|
42
|
-
export type ScheduleTarget = { workflowScript: string };
|
|
43
|
+
export type ScheduleTarget = { workflowScript: string; baseRef?: string };
|
|
43
44
|
|
|
44
45
|
export interface ScheduleRecord {
|
|
45
46
|
schemaVersion: 1;
|
|
@@ -281,8 +282,15 @@ function readJson(file: string, label: string): unknown {
|
|
|
281
282
|
|
|
282
283
|
function parseScheduleTarget(value: unknown, file: string): ScheduleTarget {
|
|
283
284
|
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(`Schedule record '${file}' has invalid trigger or target.`);
|
|
284
|
-
const target = value as { workflowScript?: unknown; agent?: unknown; task?: unknown };
|
|
285
|
-
if (typeof target.workflowScript === "string" && target.workflowScript.trim())
|
|
285
|
+
const target = value as { workflowScript?: unknown; baseRef?: unknown; agent?: unknown; task?: unknown };
|
|
286
|
+
if (typeof target.workflowScript === "string" && target.workflowScript.trim()) {
|
|
287
|
+
try {
|
|
288
|
+
const baseRef = normalizeWorktreeBaseRef(target.baseRef);
|
|
289
|
+
return { workflowScript: target.workflowScript.trim(), ...(baseRef === undefined ? {} : { baseRef }) };
|
|
290
|
+
} catch (error) {
|
|
291
|
+
throw new Error(`Schedule record '${file}' has an invalid baseRef: ${error instanceof Error ? error.message : String(error)}`);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
286
294
|
if (target.agent !== undefined || target.task !== undefined) throw new Error(`Schedule record '${file}' uses a removed legacy agent target; recreate it with target.workflowScript.`);
|
|
287
295
|
throw new Error(`Schedule record '${file}' requires a workflowScript target.`);
|
|
288
296
|
}
|
|
@@ -429,9 +437,15 @@ function sanitizeTarget(params: SubagentParamsLike): { target?: ScheduleTarget;
|
|
|
429
437
|
if (typeof params.workflowScript !== "string" || !params.workflowScript.trim()) return { error: "schedule.create requires a non-empty workflowScript." };
|
|
430
438
|
if (params.context === "fork") return { error: "Scheduled runs require fresh context." };
|
|
431
439
|
if (params.async === false) return { error: "Scheduled runs are always async." };
|
|
440
|
+
let baseRef: string | undefined;
|
|
441
|
+
try {
|
|
442
|
+
baseRef = normalizeWorktreeBaseRef(params.baseRef);
|
|
443
|
+
} catch (error) {
|
|
444
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
445
|
+
}
|
|
432
446
|
const acceptanceErrors = validateExecutionAcceptance(params as Parameters<typeof validateExecutionAcceptance>[0]);
|
|
433
447
|
if (acceptanceErrors.length) return { error: acceptanceErrors.join(" ") };
|
|
434
|
-
return { target: { workflowScript: params.workflowScript.trim() } };
|
|
448
|
+
return { target: { workflowScript: params.workflowScript.trim(), ...(baseRef === undefined ? {} : { baseRef }) } };
|
|
435
449
|
}
|
|
436
450
|
|
|
437
451
|
function executionParams(schedule: ScheduleRecord): SubagentParamsLike {
|
|
@@ -9,6 +9,7 @@ import { resolveEffectiveThinking } from "../../shared/model-info.ts";
|
|
|
9
9
|
import { normalizeParallelGroups } from "./parallel-groups.ts";
|
|
10
10
|
import { nestedSummaryFromAsyncStatus, projectNestedEvents, resolveNestedAsyncDir, writeNestedEvent, type NestedRoute } from "../shared/nested-events.ts";
|
|
11
11
|
import { assertWorkflowGraphHostSteps } from "../shared/host-step-status.ts";
|
|
12
|
+
import type { RawDrainStatusObserver } from "../shared/readonly-drain-observation.ts";
|
|
12
13
|
|
|
13
14
|
export type PidLiveness = "alive" | "dead" | "unknown";
|
|
14
15
|
|
|
@@ -352,9 +353,10 @@ export function checkPidLiveness(pid: number, kill: KillFn = process.kill): PidL
|
|
|
352
353
|
}
|
|
353
354
|
}
|
|
354
355
|
|
|
355
|
-
export function reconcileAsyncRun(asyncDir: string, options: ReconcileAsyncRunOptions = {}): ReconcileAsyncRunResult {
|
|
356
|
+
export function reconcileAsyncRun(asyncDir: string, options: ReconcileAsyncRunOptions = {}, observeStatus?: RawDrainStatusObserver): ReconcileAsyncRunResult {
|
|
356
357
|
const now = options.now?.() ?? Date.now();
|
|
357
358
|
const status = readStatus(asyncDir);
|
|
359
|
+
observeStatus?.(status);
|
|
358
360
|
const startedStatus = !status && options.startedRun ? buildStartedStatus(asyncDir, options.startedRun, now) : undefined;
|
|
359
361
|
const effectiveStatus = status ?? startedStatus;
|
|
360
362
|
if (!effectiveStatus) return { status: null, repaired: false };
|