@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
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import type { EntryRenderOptions, MessageRenderOptions, Theme } from "@selesai/code";
|
|
2
|
+
import { truncateToWidth, visibleWidth, wrapTextWithAnsi, type Component } from "@earendil-works/pi-tui";
|
|
3
|
+
import { safeTerminalText } from "../shared/display-text.ts";
|
|
4
|
+
|
|
5
|
+
export const SUPERVISOR_REQUEST_MESSAGE_TYPE = "subagent_supervisor_request";
|
|
6
|
+
export const SUPERVISOR_REPLY_ENTRY_TYPE = "subagent_supervisor_reply";
|
|
7
|
+
|
|
8
|
+
export type SupervisorReason = "need_decision" | "interview_request" | "progress_update";
|
|
9
|
+
|
|
10
|
+
export interface SupervisorRequestMessageDetails {
|
|
11
|
+
id?: string;
|
|
12
|
+
requestId?: string;
|
|
13
|
+
reason?: SupervisorReason;
|
|
14
|
+
expectsReply?: boolean;
|
|
15
|
+
runId?: string;
|
|
16
|
+
agent?: string;
|
|
17
|
+
childIndex?: number;
|
|
18
|
+
childTarget?: string;
|
|
19
|
+
interview?: unknown;
|
|
20
|
+
requestBody?: string;
|
|
21
|
+
replyHint?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface SupervisorReplyEntryData {
|
|
25
|
+
requestId: string;
|
|
26
|
+
reason?: SupervisorReason;
|
|
27
|
+
runId: string;
|
|
28
|
+
agent: string;
|
|
29
|
+
childIndex: number;
|
|
30
|
+
childTarget?: string;
|
|
31
|
+
message: string;
|
|
32
|
+
createdAt: number;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface SupervisorMessageLike {
|
|
36
|
+
content: unknown;
|
|
37
|
+
details?: unknown;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface SupervisorEntryLike {
|
|
41
|
+
data?: unknown;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const MAX_FIELD_CHARS = 512;
|
|
45
|
+
const MAX_BODY_CHARS = 8_000;
|
|
46
|
+
const MAX_INTERVIEW_CHARS = 4_000;
|
|
47
|
+
const MAX_RENDER_LINES = 36;
|
|
48
|
+
const TRUNCATION_MARKER = "[truncated]";
|
|
49
|
+
|
|
50
|
+
export function supervisorReplyHint(requestId: string): string {
|
|
51
|
+
return `subagent_supervisor({ action: "reply", replyTo: "${requestId}", message: "..." })`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function boundedText(value: string, maxChars: number): string {
|
|
55
|
+
const safe = safeTerminalText(value);
|
|
56
|
+
if (safe.length <= maxChars) return safe;
|
|
57
|
+
const prefixLength = Math.max(0, maxChars - TRUNCATION_MARKER.length - 1);
|
|
58
|
+
let prefix = "";
|
|
59
|
+
for (const character of safe) {
|
|
60
|
+
if (prefix.length + character.length > prefixLength) break;
|
|
61
|
+
prefix += character;
|
|
62
|
+
}
|
|
63
|
+
return `${prefix} ${TRUNCATION_MARKER}`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function displayText(value: string, maxChars: number, expanded: boolean): string {
|
|
67
|
+
return expanded ? safeTerminalText(value) : boundedText(value, maxChars);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function boundedField(value: unknown, fallback = "unknown"): string {
|
|
71
|
+
return boundedText(typeof value === "string" ? value : value === undefined ? fallback : String(value), MAX_FIELD_CHARS);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function contentText(content: unknown): string {
|
|
75
|
+
if (typeof content === "string") return content;
|
|
76
|
+
if (!Array.isArray(content)) return "";
|
|
77
|
+
return content
|
|
78
|
+
.map((part) => {
|
|
79
|
+
if (!part || typeof part !== "object") return "";
|
|
80
|
+
const text = (part as { text?: unknown }).text;
|
|
81
|
+
return typeof text === "string" ? text : "";
|
|
82
|
+
})
|
|
83
|
+
.filter(Boolean)
|
|
84
|
+
.join("\n");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function interviewText(interview: unknown, expanded: boolean): string {
|
|
88
|
+
let serialized: string;
|
|
89
|
+
try {
|
|
90
|
+
serialized = JSON.stringify(interview, null, 2) ?? String(interview);
|
|
91
|
+
} catch {
|
|
92
|
+
serialized = "[unavailable]";
|
|
93
|
+
}
|
|
94
|
+
return displayText(serialized, MAX_INTERVIEW_CHARS, expanded);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
98
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function isSupervisorReason(value: unknown): value is SupervisorReason {
|
|
102
|
+
return value === "need_decision" || value === "interview_request" || value === "progress_update";
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function optionalString(value: unknown): boolean {
|
|
106
|
+
return value === undefined || typeof value === "string";
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function requestDetails(value: unknown): SupervisorRequestMessageDetails | undefined {
|
|
110
|
+
if (!isRecord(value)) return undefined;
|
|
111
|
+
if (!optionalString(value.id) || !optionalString(value.requestId) || !optionalString(value.replyHint) || !optionalString(value.requestBody) || !optionalString(value.runId) || !optionalString(value.agent) || !optionalString(value.childTarget)) return undefined;
|
|
112
|
+
if (value.reason !== undefined && !isSupervisorReason(value.reason)) return undefined;
|
|
113
|
+
if (value.expectsReply !== undefined && typeof value.expectsReply !== "boolean") return undefined;
|
|
114
|
+
if (value.childIndex !== undefined && (typeof value.childIndex !== "number" || !Number.isFinite(value.childIndex))) return undefined;
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function replyData(value: unknown): SupervisorReplyEntryData | undefined {
|
|
119
|
+
if (!isRecord(value)) return undefined;
|
|
120
|
+
if (typeof value.requestId !== "string" || typeof value.runId !== "string" || typeof value.agent !== "string" || typeof value.message !== "string") return undefined;
|
|
121
|
+
if (value.reason !== undefined && !isSupervisorReason(value.reason)) return undefined;
|
|
122
|
+
if (value.childTarget !== undefined && typeof value.childTarget !== "string") return undefined;
|
|
123
|
+
if (typeof value.childIndex !== "number" || !Number.isFinite(value.childIndex) || typeof value.createdAt !== "number" || !Number.isFinite(value.createdAt)) return undefined;
|
|
124
|
+
return {
|
|
125
|
+
requestId: value.requestId,
|
|
126
|
+
...(value.reason === undefined ? {} : { reason: value.reason }),
|
|
127
|
+
runId: value.runId,
|
|
128
|
+
agent: value.agent,
|
|
129
|
+
childIndex: value.childIndex,
|
|
130
|
+
...(value.childTarget === undefined ? {} : { childTarget: value.childTarget }),
|
|
131
|
+
message: value.message,
|
|
132
|
+
createdAt: value.createdAt,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function withRequestId(details: SupervisorRequestMessageDetails): string {
|
|
137
|
+
return boundedField(details.requestId ?? details.id);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function requestHeading(reason: SupervisorReason | undefined): string {
|
|
141
|
+
if (reason === "interview_request") return "⚠ Supervisor interview request";
|
|
142
|
+
if (reason === "progress_update") return "ℹ Supervisor progress update";
|
|
143
|
+
return "⚠ Supervisor decision request";
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function requestLines(message: SupervisorMessageLike, details: SupervisorRequestMessageDetails, expanded: boolean): string[] {
|
|
147
|
+
const requestId = withRequestId(details);
|
|
148
|
+
const lines = [
|
|
149
|
+
`Reason: ${boundedField(details.reason)}`,
|
|
150
|
+
`Run: ${boundedField(details.runId)}`,
|
|
151
|
+
`Agent: ${boundedField(details.agent)}`,
|
|
152
|
+
`Child index: ${boundedField(details.childIndex)}`,
|
|
153
|
+
];
|
|
154
|
+
if (details.childTarget) lines.push(`Child target: ${boundedField(details.childTarget)}`);
|
|
155
|
+
lines.push(`Request ID: ${requestId}`);
|
|
156
|
+
if (details.expectsReply) lines.push(`Reply with: ${displayText(details.replyHint ?? supervisorReplyHint(requestId), MAX_BODY_CHARS, expanded)}`);
|
|
157
|
+
lines.push("", "Request:", displayText((details.requestBody ?? contentText(message.content)) || "(no request body)", MAX_BODY_CHARS, expanded));
|
|
158
|
+
if (details.interview !== undefined) lines.push("", "Interview shape:", interviewText(details.interview, expanded));
|
|
159
|
+
return lines;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function replyLines(data: SupervisorReplyEntryData, expanded: boolean): string[] {
|
|
163
|
+
const requestId = boundedField(data.requestId);
|
|
164
|
+
const lines = [
|
|
165
|
+
...(data.reason ? [`Reason: ${boundedField(data.reason)}`] : []),
|
|
166
|
+
`Run: ${boundedField(data.runId)}`,
|
|
167
|
+
`Agent: ${boundedField(data.agent)}`,
|
|
168
|
+
`Child index: ${boundedField(data.childIndex)}`,
|
|
169
|
+
];
|
|
170
|
+
if (data.childTarget) lines.push(`Child target: ${boundedField(data.childTarget)}`);
|
|
171
|
+
lines.push(`Reply to: ${requestId}`, "", "Reply:", displayText(data.message || "(empty reply)", MAX_BODY_CHARS, expanded));
|
|
172
|
+
return lines;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function renderCard(lines: string[], heading: string, theme: Theme, width: number, expanded: boolean): string[] {
|
|
176
|
+
const safeWidth = Math.max(0, Math.floor(width));
|
|
177
|
+
if (safeWidth < 3) return [truncateToWidth(heading, safeWidth, "")];
|
|
178
|
+
const bodyWidth = safeWidth - 2;
|
|
179
|
+
const headerText = truncateToWidth(` ${heading} `, bodyWidth, "");
|
|
180
|
+
const headerPadding = Math.max(0, bodyWidth - visibleWidth(headerText));
|
|
181
|
+
const border = (text: string) => theme.fg("accent", text);
|
|
182
|
+
const rendered = [border(`╭${headerText}${"─".repeat(headerPadding)}╮`)];
|
|
183
|
+
let hidden = false;
|
|
184
|
+
let interiorLines = 0;
|
|
185
|
+
for (const line of lines) {
|
|
186
|
+
const wrapped = wrapTextWithAnsi(line, Math.max(1, bodyWidth));
|
|
187
|
+
for (const wrappedLine of wrapped.length > 0 ? wrapped : [""]) {
|
|
188
|
+
if (!expanded && interiorLines >= MAX_RENDER_LINES) {
|
|
189
|
+
hidden = true;
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
const text = truncateToWidth(wrappedLine, bodyWidth, "");
|
|
193
|
+
rendered.push(border(`│${text}${" ".repeat(Math.max(0, bodyWidth - visibleWidth(text)))}│`));
|
|
194
|
+
interiorLines++;
|
|
195
|
+
}
|
|
196
|
+
if (hidden) break;
|
|
197
|
+
}
|
|
198
|
+
if (hidden) {
|
|
199
|
+
const text = truncateToWidth(TRUNCATION_MARKER, bodyWidth, "");
|
|
200
|
+
rendered.push(border(`│${text}${" ".repeat(Math.max(0, bodyWidth - visibleWidth(text)))}│`));
|
|
201
|
+
}
|
|
202
|
+
rendered.push(border(`╰${"─".repeat(bodyWidth)}╯`));
|
|
203
|
+
return rendered;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
class SupervisorCardComponent implements Component {
|
|
207
|
+
private readonly expanded: boolean;
|
|
208
|
+
private readonly heading: string;
|
|
209
|
+
private readonly lines: string[];
|
|
210
|
+
private readonly theme: Theme;
|
|
211
|
+
|
|
212
|
+
constructor(heading: string, lines: string[], theme: Theme, expanded: boolean) {
|
|
213
|
+
this.expanded = expanded;
|
|
214
|
+
this.heading = heading;
|
|
215
|
+
this.lines = lines;
|
|
216
|
+
this.theme = theme;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
invalidate(): void {}
|
|
220
|
+
|
|
221
|
+
render(width: number): string[] {
|
|
222
|
+
return renderCard(this.lines, this.heading, this.theme, width, this.expanded);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function renderSupervisorRequest(
|
|
227
|
+
message: SupervisorMessageLike,
|
|
228
|
+
options: MessageRenderOptions,
|
|
229
|
+
theme: Theme,
|
|
230
|
+
): Component | undefined {
|
|
231
|
+
const details = requestDetails(message.details);
|
|
232
|
+
if (!details) return undefined;
|
|
233
|
+
return new SupervisorCardComponent(requestHeading(details.reason), requestLines(message, details, options.expanded), theme, options.expanded);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export function renderSupervisorReply(
|
|
237
|
+
entry: SupervisorEntryLike,
|
|
238
|
+
options: EntryRenderOptions,
|
|
239
|
+
theme: Theme,
|
|
240
|
+
): Component | undefined {
|
|
241
|
+
const data = replyData(entry.data);
|
|
242
|
+
if (!data) return undefined;
|
|
243
|
+
return new SupervisorCardComponent("↩ Supervisor reply to child", replyLines(data, options.expanded), theme, options.expanded);
|
|
244
|
+
}
|
|
@@ -18,6 +18,12 @@ export interface MissionWorkflowState {
|
|
|
18
18
|
set(key: string, value: unknown): void;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export interface MissionWorkflowStateOptions {
|
|
22
|
+
isProcessAlive?: (pid: number) => boolean;
|
|
23
|
+
getProcessStartKey?: (pid: number) => string | undefined;
|
|
24
|
+
retryDelaysMs?: readonly number[];
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
export function missionStatePath(location: MissionStoreLocation, missionId: string): string {
|
|
22
28
|
return path.join(location.missionDir, validateMissionId(missionId), "state.json");
|
|
23
29
|
}
|
|
@@ -66,13 +72,22 @@ function windowsProcessStartKey(pid: number): string | undefined {
|
|
|
66
72
|
}
|
|
67
73
|
}
|
|
68
74
|
|
|
75
|
+
let currentProcessKey: string | undefined | null = null;
|
|
76
|
+
|
|
69
77
|
function processStartKey(pid: number): string | undefined {
|
|
78
|
+
// Foreign PIDs can be reused while this process lives, so resolve them afresh.
|
|
79
|
+
if (pid !== process.pid) return computeProcessStartKey(pid);
|
|
80
|
+
if (currentProcessKey === null) currentProcessKey = computeProcessStartKey(pid);
|
|
81
|
+
return currentProcessKey;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function computeProcessStartKey(pid: number): string | undefined {
|
|
70
85
|
if (process.platform === "linux") return linuxProcessStartKey(pid) ?? psProcessStartKey(pid);
|
|
71
86
|
if (process.platform === "win32") return windowsProcessStartKey(pid);
|
|
72
87
|
return undefined;
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
|
|
90
|
+
type StateLockOptions = Required<MissionWorkflowStateOptions>;
|
|
76
91
|
|
|
77
92
|
function readStateLockOwner(lockPath: string): StateLockOwner | undefined {
|
|
78
93
|
try {
|
|
@@ -91,13 +106,13 @@ function readStateLockOwner(lockPath: string): StateLockOwner | undefined {
|
|
|
91
106
|
return undefined;
|
|
92
107
|
}
|
|
93
108
|
|
|
94
|
-
function stateLockIsStale(lockPath: string, now = Date.now()): boolean {
|
|
109
|
+
function stateLockIsStale(lockPath: string, options: StateLockOptions, now = Date.now()): boolean {
|
|
95
110
|
const owner = readStateLockOwner(lockPath);
|
|
96
111
|
if (owner) {
|
|
97
|
-
if (!isProcessAlive(owner.pid)) return true;
|
|
112
|
+
if (!options.isProcessAlive(owner.pid)) return true;
|
|
98
113
|
if (owner.processKey) {
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
114
|
+
const observedProcessKey = options.getProcessStartKey(owner.pid);
|
|
115
|
+
if (observedProcessKey) return owner.processKey !== observedProcessKey;
|
|
101
116
|
if (owner.pid === process.pid) return true;
|
|
102
117
|
}
|
|
103
118
|
return false;
|
|
@@ -140,11 +155,11 @@ function waitForStateLock(delayMs: number | undefined, lockPath: string): void {
|
|
|
140
155
|
waitForFileSystemRetry(delayMs);
|
|
141
156
|
}
|
|
142
157
|
|
|
143
|
-
function reclaimStaleStateLock(lockPath: string, reclaimPath: string): boolean {
|
|
144
|
-
if (!stateLockIsStale(lockPath)) return false;
|
|
158
|
+
function reclaimStaleStateLock(lockPath: string, reclaimPath: string, options: StateLockOptions): boolean {
|
|
159
|
+
if (!stateLockIsStale(lockPath, options)) return false;
|
|
145
160
|
if (!tryMakeDirectory(reclaimPath, 0o700)) return false;
|
|
146
161
|
try {
|
|
147
|
-
if (!stateLockIsStale(lockPath)) return false;
|
|
162
|
+
if (!stateLockIsStale(lockPath, options)) return false;
|
|
148
163
|
fs.rmSync(lockPath, { recursive: true, force: true });
|
|
149
164
|
return true;
|
|
150
165
|
} finally {
|
|
@@ -152,7 +167,7 @@ function reclaimStaleStateLock(lockPath: string, reclaimPath: string): boolean {
|
|
|
152
167
|
}
|
|
153
168
|
}
|
|
154
169
|
|
|
155
|
-
function withStateFileLock<T>(filePath: string, operation: () => T): T {
|
|
170
|
+
function withStateFileLock<T>(filePath: string, operation: () => T, options: StateLockOptions): T {
|
|
156
171
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
157
172
|
const lockPath = `${filePath}.lock`;
|
|
158
173
|
const reclaimPath = `${lockPath}.reclaim`;
|
|
@@ -163,7 +178,7 @@ function withStateFileLock<T>(filePath: string, operation: () => T): T {
|
|
|
163
178
|
fs.rmSync(reclaimPath, { recursive: true, force: true });
|
|
164
179
|
continue;
|
|
165
180
|
}
|
|
166
|
-
waitForStateLock(
|
|
181
|
+
waitForStateLock(options.retryDelaysMs[attempt], lockPath);
|
|
167
182
|
continue;
|
|
168
183
|
}
|
|
169
184
|
let acquired = false;
|
|
@@ -171,17 +186,18 @@ function withStateFileLock<T>(filePath: string, operation: () => T): T {
|
|
|
171
186
|
acquired = tryMakeDirectory(lockPath, 0o700);
|
|
172
187
|
} catch (error) {
|
|
173
188
|
if (isRetryableFileSystemError(error)) {
|
|
174
|
-
waitForStateLock(
|
|
189
|
+
waitForStateLock(options.retryDelaysMs[attempt], lockPath);
|
|
175
190
|
continue;
|
|
176
191
|
}
|
|
177
192
|
throw new Error(`Failed to acquire mission state lock '${lockPath}': ${error instanceof Error ? error.message : String(error)}`);
|
|
178
193
|
}
|
|
179
194
|
if (!acquired) {
|
|
180
|
-
if (reclaimStaleStateLock(lockPath, reclaimPath)) continue;
|
|
181
|
-
waitForStateLock(
|
|
195
|
+
if (reclaimStaleStateLock(lockPath, reclaimPath, options)) continue;
|
|
196
|
+
waitForStateLock(options.retryDelaysMs[attempt], lockPath);
|
|
182
197
|
continue;
|
|
183
198
|
}
|
|
184
|
-
|
|
199
|
+
const key = options.getProcessStartKey(process.pid);
|
|
200
|
+
owner = { pid: process.pid, token: randomUUID(), createdAt: Date.now(), ...(key ? { processKey: key } : {}) };
|
|
185
201
|
try {
|
|
186
202
|
fs.writeFileSync(path.join(lockPath, "owner.json"), JSON.stringify(owner), { encoding: "utf-8", mode: 0o600 });
|
|
187
203
|
} catch (error) {
|
|
@@ -205,8 +221,13 @@ function validateStateKey(value: unknown): string {
|
|
|
205
221
|
return value;
|
|
206
222
|
}
|
|
207
223
|
|
|
208
|
-
export function createMissionWorkflowState(location: MissionStoreLocation, missionId: string): MissionWorkflowState {
|
|
224
|
+
export function createMissionWorkflowState(location: MissionStoreLocation, missionId: string, options: MissionWorkflowStateOptions = {}): MissionWorkflowState {
|
|
209
225
|
const filePath = missionStatePath(location, missionId);
|
|
226
|
+
const lockOptions: StateLockOptions = {
|
|
227
|
+
isProcessAlive: options.isProcessAlive ?? isProcessAlive,
|
|
228
|
+
getProcessStartKey: options.getProcessStartKey ?? processStartKey,
|
|
229
|
+
retryDelaysMs: options.retryDelaysMs ?? DEFAULT_FILE_SYSTEM_RETRY_DELAYS_MS,
|
|
230
|
+
};
|
|
210
231
|
let loaded = false;
|
|
211
232
|
let values: Record<string, unknown> = Object.create(null) as Record<string, unknown>;
|
|
212
233
|
|
|
@@ -254,7 +275,7 @@ export function createMissionWorkflowState(location: MissionStoreLocation, missi
|
|
|
254
275
|
writePrivateAtomicJson(filePath, next);
|
|
255
276
|
values = next;
|
|
256
277
|
loaded = true;
|
|
257
|
-
});
|
|
278
|
+
}, lockOptions);
|
|
258
279
|
},
|
|
259
280
|
};
|
|
260
281
|
}
|
|
@@ -12,7 +12,7 @@ export const DEFAULT_ABANDONED_SLOT_RELEASE_AFTER_MS = 20 * 60 * 1000;
|
|
|
12
12
|
export const MIN_ABANDONED_SLOT_RELEASE_AFTER_MS = 5 * 60 * 1000;
|
|
13
13
|
export const MAX_ABANDONED_SLOT_RELEASE_AFTER_MS = 24 * 60 * 60 * 1000;
|
|
14
14
|
|
|
15
|
-
export interface
|
|
15
|
+
export interface ActiveAsyncCapacityOwner {
|
|
16
16
|
version: 1;
|
|
17
17
|
reservationToken: string;
|
|
18
18
|
ownerSessionId: string;
|
|
@@ -29,7 +29,7 @@ export interface ActiveAsyncCapacityOwnerV1 {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export interface ActiveAsyncCapacityHandle {
|
|
32
|
-
readonly owner:
|
|
32
|
+
readonly owner: ActiveAsyncCapacityOwner;
|
|
33
33
|
markStarted(runnerProcessInstanceId: string): void;
|
|
34
34
|
markWorkflowStarted(): void;
|
|
35
35
|
rollback(): boolean;
|
|
@@ -44,7 +44,7 @@ interface CapacityOptions {
|
|
|
44
44
|
abandonedSlotReleaseAfterMs?: number | false;
|
|
45
45
|
pidLiveness?: (pid: number) => PidLiveness;
|
|
46
46
|
afterSlotRename?: (releasedDir: string) => void;
|
|
47
|
-
writeOwner?: (filePath: string, owner:
|
|
47
|
+
writeOwner?: (filePath: string, owner: ActiveAsyncCapacityOwner) => void;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
export interface ActiveAsyncCapacityReleaseEvidence {
|
|
@@ -61,7 +61,7 @@ export type ActiveAsyncCapacityReleaseVerdict =
|
|
|
61
61
|
| { state: "not-owned"; reason: string };
|
|
62
62
|
|
|
63
63
|
export interface ActiveAsyncCapacityInspection {
|
|
64
|
-
owner?:
|
|
64
|
+
owner?: ActiveAsyncCapacityOwner;
|
|
65
65
|
relation: "current" | "source" | "none";
|
|
66
66
|
slotDir?: string;
|
|
67
67
|
release: ActiveAsyncCapacityReleaseVerdict;
|
|
@@ -100,9 +100,9 @@ function slotDir(poolDir: string, slot: number): string {
|
|
|
100
100
|
return path.join(poolDir, `slot-${slot}`);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
function parseOwner(value: unknown):
|
|
103
|
+
function parseOwner(value: unknown): ActiveAsyncCapacityOwner | undefined {
|
|
104
104
|
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
105
|
-
const owner = value as Partial<
|
|
105
|
+
const owner = value as Partial<ActiveAsyncCapacityOwner>;
|
|
106
106
|
if (owner.version !== 1
|
|
107
107
|
|| typeof owner.reservationToken !== "string" || !owner.reservationToken
|
|
108
108
|
|| typeof owner.ownerSessionId !== "string" || !owner.ownerSessionId
|
|
@@ -116,10 +116,10 @@ function parseOwner(value: unknown): ActiveAsyncCapacityOwnerV1 | undefined {
|
|
|
116
116
|
if (owner.sourceRunId !== undefined && typeof owner.sourceRunId !== "string") return undefined;
|
|
117
117
|
if (owner.runnerProcessInstanceId !== undefined && (typeof owner.runnerProcessInstanceId !== "string" || !owner.runnerProcessInstanceId)) return undefined;
|
|
118
118
|
if (owner.runnerStartedAt !== undefined && (typeof owner.runnerStartedAt !== "number" || !Number.isFinite(owner.runnerStartedAt))) return undefined;
|
|
119
|
-
return owner as
|
|
119
|
+
return owner as ActiveAsyncCapacityOwner;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
function readOwner(dir: string):
|
|
122
|
+
function readOwner(dir: string): ActiveAsyncCapacityOwner | undefined {
|
|
123
123
|
try {
|
|
124
124
|
return parseOwner(JSON.parse(fs.readFileSync(path.join(dir, "owner.json"), "utf-8")));
|
|
125
125
|
} catch {
|
|
@@ -142,7 +142,7 @@ function snapshotFor(sessionId: string, limit: number | undefined, rootDir: stri
|
|
|
142
142
|
return { used: occupiedSlots(sessionDir(sessionId, rootDir)).length, limit: limit ?? 0 };
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
function matchingOwner(dir: string, expected:
|
|
145
|
+
function matchingOwner(dir: string, expected: ActiveAsyncCapacityOwner): ActiveAsyncCapacityOwner | undefined {
|
|
146
146
|
const owner = readOwner(dir);
|
|
147
147
|
return owner?.reservationToken === expected.reservationToken
|
|
148
148
|
&& owner.runId === expected.runId
|
|
@@ -176,7 +176,7 @@ function withSlotClaim<T>(dir: string, operation: () => T): { acquired: true; va
|
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
-
function removeOwnedSlot(dir: string, expected:
|
|
179
|
+
function removeOwnedSlot(dir: string, expected: ActiveAsyncCapacityOwner, options: CapacityOptions, requireUnstarted = false, release?: ActiveAsyncCapacityReleaseVerdict): boolean {
|
|
180
180
|
if (requireUnstarted && (expected.runnerProcessInstanceId || expected.runnerStartedAt)) return false;
|
|
181
181
|
const claimed = withSlotClaim(dir, () => {
|
|
182
182
|
const current = matchingOwner(dir, expected);
|
|
@@ -193,7 +193,7 @@ function removeOwnedSlot(dir: string, expected: ActiveAsyncCapacityOwnerV1, opti
|
|
|
193
193
|
return claimed.acquired && claimed.value;
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
function appendAbandonedReleaseEvent(asyncDir: string, owner:
|
|
196
|
+
function appendAbandonedReleaseEvent(asyncDir: string, owner: ActiveAsyncCapacityOwner, evidence: ActiveAsyncCapacityReleaseEvidence, now: number): void {
|
|
197
197
|
try {
|
|
198
198
|
const eventsPath = path.join(asyncDir, "events.jsonl");
|
|
199
199
|
fs.mkdirSync(path.dirname(eventsPath), { recursive: true });
|
|
@@ -213,7 +213,7 @@ function terminalState(state: AsyncStatus["state"]): boolean {
|
|
|
213
213
|
return state !== "queued" && state !== "running" && state !== "paused";
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
function runnerReleaseVerdict(owner:
|
|
216
|
+
function runnerReleaseVerdict(owner: ActiveAsyncCapacityOwner, status: AsyncStatus | null, options: CapacityOptions): ActiveAsyncCapacityReleaseVerdict {
|
|
217
217
|
if (!status) return { state: "retained", reason: "status file is missing or unreadable" };
|
|
218
218
|
if (!owner.runnerProcessInstanceId) return { state: "retained", reason: "runner process identity has not been recorded" };
|
|
219
219
|
if (status.sessionId !== owner.ownerSessionId) return { state: "retained", reason: `status session ${status.sessionId ?? "unknown"} does not match owner session ${owner.ownerSessionId}` };
|
|
@@ -262,7 +262,7 @@ function abandonedRunnerReleaseVerdict(status: AsyncStatus, proofState: string,
|
|
|
262
262
|
};
|
|
263
263
|
}
|
|
264
264
|
|
|
265
|
-
function workflowReleaseVerdict(owner:
|
|
265
|
+
function workflowReleaseVerdict(owner: ActiveAsyncCapacityOwner, status: AsyncStatus | null, liveWorkflowRunIds: ReadonlySet<string>): ActiveAsyncCapacityReleaseVerdict {
|
|
266
266
|
if (!status) return { state: "retained", reason: "status file is missing or unreadable" };
|
|
267
267
|
if (status.sessionId !== owner.ownerSessionId) return { state: "retained", reason: `status session ${status.sessionId ?? "unknown"} does not match owner session ${owner.ownerSessionId}` };
|
|
268
268
|
if (status.runId !== owner.runId) return { state: "retained", reason: `status run ${status.runId} does not match owner run ${owner.runId}` };
|
|
@@ -289,7 +289,7 @@ function workflowReleaseVerdict(owner: ActiveAsyncCapacityOwnerV1, status: Async
|
|
|
289
289
|
return { state: "releasable", reason: "workflow is terminal, controller is gone, and async children have observed proof" };
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
function ownerReleaseVerdict(owner:
|
|
292
|
+
function ownerReleaseVerdict(owner: ActiveAsyncCapacityOwner, liveWorkflowRunIds: ReadonlySet<string>, options: CapacityOptions): ActiveAsyncCapacityReleaseVerdict {
|
|
293
293
|
const status = readStatus(owner.asyncDir);
|
|
294
294
|
return owner.kind === "runner"
|
|
295
295
|
? runnerReleaseVerdict(owner, status, options)
|
|
@@ -364,7 +364,7 @@ export function getActiveAsyncCapacitySnapshot(
|
|
|
364
364
|
return reconcileActiveAsyncCapacity(sessionId, limit, options);
|
|
365
365
|
}
|
|
366
366
|
|
|
367
|
-
function createSlot(poolDir: string, owner:
|
|
367
|
+
function createSlot(poolDir: string, owner: ActiveAsyncCapacityOwner): boolean {
|
|
368
368
|
const destination = slotDir(poolDir, owner.slot);
|
|
369
369
|
fs.mkdirSync(poolDir, { recursive: true, mode: 0o700 });
|
|
370
370
|
try {
|
|
@@ -379,7 +379,7 @@ function createSlot(poolDir: string, owner: ActiveAsyncCapacityOwnerV1): boolean
|
|
|
379
379
|
return true;
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
function handleFor(owner:
|
|
382
|
+
function handleFor(owner: ActiveAsyncCapacityOwner, limit: number, options: CapacityOptions, rollbackOwner?: ActiveAsyncCapacityOwner): ActiveAsyncCapacityHandle {
|
|
383
383
|
const rootDir = options.rootDir ?? ACTIVE_ASYNC_CAPACITY_DIR;
|
|
384
384
|
const writeOwner = options.writeOwner ?? writePrivateAtomicJson;
|
|
385
385
|
const dir = slotDir(sessionDir(owner.ownerSessionId, rootDir), owner.slot);
|
|
@@ -462,7 +462,7 @@ export function acquireActiveAsyncCapacity(
|
|
|
462
462
|
const poolDir = sessionDir(input.sessionId, rootDir);
|
|
463
463
|
const token = options.token?.() ?? randomUUID();
|
|
464
464
|
for (let slot = 0; slot < input.limit; slot++) {
|
|
465
|
-
const owner:
|
|
465
|
+
const owner: ActiveAsyncCapacityOwner = {
|
|
466
466
|
version: 1,
|
|
467
467
|
reservationToken: token,
|
|
468
468
|
ownerSessionId: input.sessionId,
|
|
@@ -495,7 +495,7 @@ export function transferActiveAsyncCapacity(
|
|
|
495
495
|
if (!current || !status || status.runId !== input.sourceRunId || status.state === "queued" || status.state === "running") {
|
|
496
496
|
throw new Error(`Active async capacity source '${input.sourceRunId}' is not transferable.`);
|
|
497
497
|
}
|
|
498
|
-
const next:
|
|
498
|
+
const next: ActiveAsyncCapacityOwner = {
|
|
499
499
|
...current,
|
|
500
500
|
runId: input.runId,
|
|
501
501
|
sourceRunId: input.sourceRunId,
|