@selesai/code 0.8.3 → 0.8.4
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 +5 -0
- package/dist/extensions/handoff-new.ts +1 -1
- package/dist/extensions/inline-skills.test.ts +1 -0
- package/dist/extensions/inline-skills.ts +1 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +25 -3
- package/dist/extensions/pi-intercom/README.md +34 -15
- package/dist/extensions/pi-intercom/broker/broker.ts +38 -141
- package/dist/extensions/pi-intercom/broker/client-liveness.test.ts +173 -0
- package/dist/extensions/pi-intercom/broker/client.ts +78 -150
- package/dist/extensions/pi-intercom/broker/extension-state.ts +18 -7
- package/dist/extensions/pi-intercom/broker/framing.ts +1 -1
- package/dist/extensions/pi-intercom/broker/protocol.ts +182 -0
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +106 -7
- package/dist/extensions/pi-intercom/broker/spawn.ts +37 -11
- package/dist/extensions/pi-intercom/config.test.ts +8 -10
- package/dist/extensions/pi-intercom/config.ts +3 -3
- package/dist/extensions/pi-intercom/index.ts +218 -147
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +891 -103
- package/dist/extensions/pi-intercom/package.json +3 -2
- package/dist/extensions/pi-intercom/project-agent.test.ts +145 -0
- package/dist/extensions/pi-intercom/project-agent.ts +324 -0
- package/dist/extensions/pi-intercom/reply-tracker.test.ts +86 -1
- package/dist/extensions/pi-intercom/reply-tracker.ts +41 -9
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +49 -9
- package/dist/extensions/pi-intercom/test/inline-message.test.ts +9 -9
- package/dist/extensions/pi-intercom/types.ts +3 -1
- package/dist/extensions/pi-intercom/ui/inline-message.ts +7 -7
- package/dist/extensions/pi-powerline-footer/.github/workflows/test.yml +2 -2
- package/dist/extensions/pi-powerline-footer/CHANGELOG.md +14 -1
- package/dist/extensions/pi-powerline-footer/README.md +20 -37
- package/dist/extensions/pi-powerline-footer/bash-mode/completion.ts +40 -25
- package/dist/extensions/pi-powerline-footer/bash-mode/editor.ts +149 -18
- package/dist/extensions/pi-powerline-footer/bash-mode/types.ts +1 -0
- package/dist/extensions/pi-powerline-footer/editor-performance.ts +99 -0
- package/dist/extensions/pi-powerline-footer/git-status.ts +15 -0
- package/dist/extensions/pi-powerline-footer/index.ts +394 -317
- package/dist/extensions/pi-powerline-footer/package.json +1 -1
- package/dist/extensions/pi-powerline-footer/powerline-config.ts +0 -12
- package/dist/extensions/pi-powerline-footer/queue/store.ts +8 -56
- package/dist/extensions/pi-powerline-footer/queue/types.ts +1 -2
- package/dist/extensions/pi-powerline-footer/segments.ts +0 -3
- package/dist/extensions/pi-powerline-footer/tests/bash-mode.test.ts +231 -1
- package/dist/extensions/pi-powerline-footer/tests/custom-items.test.ts +5 -19
- package/dist/extensions/pi-powerline-footer/tests/editor-performance.test.ts +43 -0
- package/dist/extensions/pi-powerline-footer/tests/git-optional-locks.test.ts +64 -0
- package/dist/extensions/pi-powerline-footer/tests/jump-shortcuts.test.ts +116 -0
- package/dist/extensions/pi-powerline-footer/tests/queue-store.test.ts +19 -149
- package/dist/extensions/pi-powerline-footer/tests/remaining-regressions.test.ts +6 -0
- package/dist/extensions/pi-powerline-footer/tests/usage-display.test.ts +5 -5
- package/dist/extensions/pi-powerline-footer/types.ts +1 -2
- package/dist/extensions/pi-subagents/CHANGELOG.md +202 -14
- package/dist/extensions/pi-subagents/README.md +65 -1614
- package/dist/extensions/pi-subagents/agents/builder.md +0 -1
- package/dist/extensions/pi-subagents/agents/delegate.md +14 -0
- package/dist/extensions/pi-subagents/agents/oracle.md +74 -0
- package/dist/extensions/pi-subagents/agents/reviewer.md +78 -0
- package/dist/extensions/pi-subagents/agents/scout.md +50 -0
- package/dist/extensions/pi-subagents/agents/worker.md +58 -0
- package/dist/extensions/pi-subagents/docs/configuration.md +328 -0
- package/dist/extensions/pi-subagents/docs/extension-api.md +308 -0
- package/dist/extensions/pi-subagents/docs/missions.md +119 -0
- package/dist/extensions/pi-subagents/docs/models.md +192 -0
- package/dist/extensions/pi-subagents/docs/observability.md +174 -0
- package/dist/extensions/pi-subagents/docs/tool-reference.md +343 -0
- package/dist/extensions/pi-subagents/docs/watchdog.md +176 -0
- package/dist/extensions/pi-subagents/docs/workflows.md +163 -0
- package/dist/extensions/pi-subagents/inspector-runner.mjs +11 -0
- package/dist/extensions/pi-subagents/package-lock.json +152 -194
- package/dist/extensions/pi-subagents/package.json +9 -10
- package/dist/extensions/pi-subagents/prompts/gather-context-and-clarify.md +1 -1
- package/dist/extensions/pi-subagents/prompts/parallel-cleanup.md +9 -9
- package/dist/extensions/pi-subagents/prompts/parallel-research.md +6 -6
- package/dist/extensions/pi-subagents/prompts/parallel-review.md +8 -8
- package/dist/extensions/pi-subagents/prompts/review-loop.md +12 -12
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +22 -17
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +77 -72
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +177 -69
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +28 -8
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/prompting-and-roles.md +88 -66
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +3 -3
- package/dist/extensions/pi-subagents/src/agents/agent-refinements.ts +624 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +29 -16
- package/dist/extensions/pi-subagents/src/agents/frontmatter.ts +7 -3
- package/dist/extensions/pi-subagents/src/agents/proactive-skills.ts +2 -2
- package/dist/extensions/pi-subagents/src/agents/skills.ts +2 -9
- package/dist/extensions/pi-subagents/src/api/delegation.ts +1 -2
- package/dist/extensions/pi-subagents/src/api/project-panes.ts +30 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +56 -8
- package/dist/extensions/pi-subagents/src/extension/control-notices.ts +2 -2
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +51 -26
- package/dist/extensions/pi-subagents/src/extension/index.ts +119 -50
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +72 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +15 -15
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +58 -21
- package/dist/extensions/pi-subagents/src/extension/subagent-guide.ts +39 -0
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +47 -25
- package/dist/extensions/pi-subagents/src/inspectors/herdr/actions.ts +3 -3
- package/dist/extensions/pi-subagents/src/inspectors/herdr/project-panes.ts +460 -64
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +102 -4
- package/dist/extensions/pi-subagents/src/missions/actions.ts +77 -16
- package/dist/extensions/pi-subagents/src/missions/goal-driver.ts +162 -0
- package/dist/extensions/pi-subagents/src/missions/lifecycle.ts +65 -14
- package/dist/extensions/pi-subagents/src/missions/store.ts +147 -5
- package/dist/extensions/pi-subagents/src/missions/types.ts +58 -3
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +256 -0
- package/dist/extensions/pi-subagents/src/profiles/profiles.ts +8 -8
- package/dist/extensions/pi-subagents/src/runs/background/active-run-index.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +41 -7
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +294 -134
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +19 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +39 -6
- package/dist/extensions/pi-subagents/src/runs/background/completion-replay.ts +267 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +145 -60
- package/dist/extensions/pi-subagents/src/runs/background/result-watcher.ts +114 -6
- package/dist/extensions/pi-subagents/src/runs/background/resume-guidance.ts +33 -0
- package/dist/extensions/pi-subagents/src/runs/background/retained-children.ts +68 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-id-resolver.ts +71 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +21 -2
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +42 -14
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +12 -24
- package/dist/extensions/pi-subagents/src/runs/background/steering.ts +7 -5
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +152 -68
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +17 -4
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +146 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-subscriptions.ts +21 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/async-dismiss-action.ts +85 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +43 -18
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-clarify.ts +20 -19
- package/dist/extensions/pi-subagents/src/runs/foreground/chain-execution.ts +3 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +55 -26
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +137 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +798 -112
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +187 -0
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +165 -22
- package/dist/extensions/pi-subagents/src/runs/shared/dynamic-fanout.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/shared/model-scope.ts +12 -2
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +1 -0
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +465 -116
- package/dist/extensions/pi-subagents/src/runs/shared/pi-spawn.ts +10 -10
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +189 -32
- package/dist/extensions/pi-subagents/src/runs/shared/task-intent.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +3 -3
- package/dist/extensions/pi-subagents/src/shared/artifacts.ts +128 -3
- package/dist/extensions/pi-subagents/src/shared/display-text.ts +100 -0
- package/dist/extensions/pi-subagents/src/shared/file-coalescer.ts +9 -0
- package/dist/extensions/pi-subagents/src/shared/fork-context.ts +13 -0
- package/dist/extensions/pi-subagents/src/shared/formatters.ts +4 -6
- package/dist/extensions/pi-subagents/src/shared/prompt-resources.ts +51 -0
- package/dist/extensions/pi-subagents/src/shared/settings.ts +41 -11
- package/dist/extensions/pi-subagents/src/shared/types.ts +100 -3
- package/dist/extensions/pi-subagents/src/shared/utf8.ts +11 -0
- package/dist/extensions/pi-subagents/src/shared/utils.ts +43 -33
- package/dist/extensions/pi-subagents/src/slash/delegation-adapters.ts +1 -14
- package/dist/extensions/pi-subagents/src/slash/inline-subagents.ts +1 -1
- package/dist/extensions/pi-subagents/src/slash/prompt-template-bridge.ts +14 -12
- package/dist/extensions/pi-subagents/src/slash/prompt-workflows.ts +176 -21
- package/dist/extensions/pi-subagents/src/slash/slash-bridge.ts +12 -6
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +52 -18
- package/dist/extensions/pi-subagents/src/slash/slash-live-state.ts +36 -5
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +30 -16
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +151 -31
- package/dist/extensions/pi-subagents/src/tui/render.ts +201 -68
- package/dist/extensions/pi-subagents/src/types/pi-runtime-compat.d.ts +0 -6
- package/dist/extensions/pi-subagents/src/watchdog/change-signature.ts +5 -4
- package/dist/extensions/pi-subagents/src/watchdog/lsp-diagnostics.ts +0 -1
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +313 -25
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/cli.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/register-bedrock.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/bun/restore-sandbox-env.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/args.d.ts +57 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/config-selector.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/file-processor.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/initial-message.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/list-models.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/project-trust.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/session-picker.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli/startup-ui.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/cli.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/config.d.ts +96 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-runtime.d.ts +119 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session-services.d.ts +85 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/agent-session.d.ts +620 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-guidance.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/auth-storage.d.ts +56 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/bash-executor.d.ts +32 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/cache-stats.d.ts +49 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/branch-summarization.d.ts +93 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/compaction.d.ts +128 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/index.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/compaction/utils.d.ts +38 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/defaults.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/diagnostics.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/event-bus.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/exec.d.ts +29 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/experimental.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/index.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/export-html/tool-renderer.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/index.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/loader.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/runner.d.ts +171 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/types.d.ts +1261 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/extensions/wrapper.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/footer-data-provider.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/http-dispatcher.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/index.d.ts +13 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/keybindings.d.ts +358 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/messages.d.ts +77 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-config.d.ts +512 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-registry.d.ts +43 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-resolver.d.ts +121 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/model-runtime.d.ts +82 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/models-store.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/output-guard.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/package-manager.d.ts +210 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/project-trust.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/prompt-templates.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-attribution.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/provider-composer.d.ts +55 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/radius.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/remote-catalog-provider.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resolve-config-value.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/resource-loader.d.ts +206 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/runtime-credentials.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/sdk.d.ts +106 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-cwd.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/session-manager.d.ts +356 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/settings-manager.d.ts +297 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/skills.d.ts +60 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/slash-commands.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/source-info.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/system-prompt.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/telemetry.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/timings.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/bash.d.ts +68 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit-diff.d.ts +106 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/edit.d.ts +51 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/find.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/grep.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/index.d.ts +40 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/ls.d.ts +37 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/output-accumulator.d.ts +52 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/path-utils.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/read.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/render-utils.d.ts +24 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/truncate.d.ts +70 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/tools/write.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/trust-manager.d.ts +36 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/core/usage-totals.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/index.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/client.d.ts +61 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/huggingface.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/index.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/provider.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/extensions/llama/ui.d.ts +42 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/index.d.ts +35 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/main.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/migrations.d.ts +33 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/index.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/armin.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/assistant-message.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bash-execution.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/config-selector.d.ts +102 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-editor.d.ts +21 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-entry.d.ts +19 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/daxnuts.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-editor.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/extension-selector.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/first-time-setup.d.ts +25 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/footer.d.ts +32 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/index.d.ts +34 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/login-dialog.d.ts +52 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/model-selector.d.ts +54 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/oauth-selector.d.ts +33 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/settings-selector.d.ts +77 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/status-indicator.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tool-execution.d.ts +63 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/tree-selector.d.ts +94 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/trust-selector.d.ts +23 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/user-message.d.ts +14 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/interactive-mode.d.ts +394 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/model-search.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme-controller.d.ts +29 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/interactive/theme/theme.d.ts +120 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/print-mode.d.ts +28 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/jsonl.d.ts +17 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-client.d.ts +246 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/modes/rpc/rpc-types.d.ts +457 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/package-manager-cli.d.ts +8 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/rpc-entry.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/ansi.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/changelog.d.ts +22 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/child-process.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard-native.d.ts +11 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/clipboard.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/deprecation.d.ts +4 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/exif-orientation.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/frontmatter.d.ts +8 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/fs-watch.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/git.d.ts +26 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/html.d.ts +7 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-convert.d.ts +10 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-process.d.ts +18 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-core.d.ts +30 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize-worker.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/image-resize.d.ts +16 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/json.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/mime.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/open-browser.d.ts +9 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/paths.d.ts +31 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/photon.d.ts +21 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/pi-user-agent.d.ts +2 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/shell.d.ts +31 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/sleep.d.ts +5 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/syntax-highlight.d.ts +12 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/tools-manager.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/version-check.d.ts +15 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/dist/utils/windows-self-update.d.ts +3 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/index.mjs +84 -0
- package/dist/extensions/pi-subagents/test/fixtures/pi-coding-agent-shim/package.json +14 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +411 -300
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +309 -123
- package/dist/extensions/pi-subagents/test/integration/async-status.test.ts +99 -56
- package/dist/extensions/pi-subagents/test/integration/chain-clarify.test.ts +62 -16
- package/dist/extensions/pi-subagents/test/integration/chain-execution.test.ts +159 -108
- package/dist/extensions/pi-subagents/test/integration/detect-error.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/integration/external-cli-runner.test.ts +4 -2
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +56 -56
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +114 -45
- package/dist/extensions/pi-subagents/test/integration/parallel-execution.test.ts +57 -19
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +106 -106
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +416 -106
- package/dist/extensions/pi-subagents/test/integration/result-watcher.test.ts +287 -17
- package/dist/extensions/pi-subagents/test/integration/single-execution.test.ts +809 -87
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +107 -20
- package/dist/extensions/pi-subagents/test/integration/slash-live-state.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/integration/template-resolution.test.ts +26 -6
- package/dist/extensions/pi-subagents/test/integration/top-level-async.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/support/helpers.ts +2 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +1 -1
- package/dist/extensions/pi-subagents/test/support/ts-loader.mjs +0 -8
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +163 -58
- package/dist/extensions/pi-subagents/test/unit/agent-disabled.test.ts +15 -15
- package/dist/extensions/pi-subagents/test/unit/agent-eject-disable.test.ts +66 -66
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +334 -248
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +52 -52
- package/dist/extensions/pi-subagents/test/unit/agent-memory.test.ts +26 -26
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +99 -99
- package/dist/extensions/pi-subagents/test/unit/agent-refinements.test.ts +160 -0
- package/dist/extensions/pi-subagents/test/unit/agent-selection.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/artifacts.test.ts +43 -1
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +36 -10
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +387 -30
- package/dist/extensions/pi-subagents/test/unit/async-permission-session.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/async-resume.test.ts +94 -40
- package/dist/extensions/pi-subagents/test/unit/background-work.test.ts +5 -3
- package/dist/extensions/pi-subagents/test/unit/builtin-agent-documentation.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +19 -19
- package/dist/extensions/pi-subagents/test/unit/chain-append.test.ts +19 -19
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/chain-serializer.test.ts +20 -20
- package/dist/extensions/pi-subagents/test/unit/child-transcript.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +35 -5
- package/dist/extensions/pi-subagents/test/unit/completion-dedupe.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +52 -52
- package/dist/extensions/pi-subagents/test/unit/completion-replay.test.ts +187 -0
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +125 -71
- package/dist/extensions/pi-subagents/test/unit/control-notices.test.ts +18 -3
- package/dist/extensions/pi-subagents/test/unit/default-extensions.test.ts +12 -12
- package/dist/extensions/pi-subagents/test/unit/delegation-api.test.ts +17 -23
- package/dist/extensions/pi-subagents/test/unit/doctor.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/dynamic-fanout.test.ts +25 -25
- package/dist/extensions/pi-subagents/test/unit/extra-agent-dirs.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/file-coalescer.test.ts +15 -0
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +62 -44
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +329 -37
- package/dist/extensions/pi-subagents/test/unit/foreground-control.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/foreground-tool-call-compaction.test.ts +37 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector-bootstrap.test.ts +69 -0
- package/dist/extensions/pi-subagents/test/unit/herdr-inspector.test.ts +79 -2
- package/dist/extensions/pi-subagents/test/unit/herdr-status-bridge.test.ts +102 -49
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +98 -32
- package/dist/extensions/pi-subagents/test/unit/intercom-bridge.test.ts +5 -5
- package/dist/extensions/pi-subagents/test/unit/mission-goal-driver.test.ts +116 -0
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +55 -7
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +289 -13
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +28 -1
- package/dist/extensions/pi-subagents/test/unit/model-scope-settings.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/model-scope.test.ts +11 -2
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +84 -10
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +122 -8
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +8 -8
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +24 -24
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +16 -2
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/parallel-utils.test.ts +10 -10
- package/dist/extensions/pi-subagents/test/unit/path-handling.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/path-resolution.test.ts +26 -17
- package/dist/extensions/pi-subagents/test/unit/pi-args-permission-system.test.ts +405 -0
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +357 -92
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +22 -6
- package/dist/extensions/pi-subagents/test/unit/pi-spawn.test.ts +6 -6
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +43 -43
- package/dist/extensions/pi-subagents/test/unit/proactive-skills.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/process-terminal.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/profiles.test.ts +19 -19
- package/dist/extensions/pi-subagents/test/unit/project-panes-public-api.test.ts +243 -0
- package/dist/extensions/pi-subagents/test/unit/prompt-template-bridge.test.ts +68 -168
- package/dist/extensions/pi-subagents/test/unit/prompt-workflows.test.ts +58 -15
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +40 -0
- package/dist/extensions/pi-subagents/test/unit/reads-resolution.test.ts +66 -0
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +47 -28
- package/dist/extensions/pi-subagents/test/unit/result-intercom.test.ts +12 -12
- package/dist/extensions/pi-subagents/test/unit/retained-children.test.ts +57 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +107 -27
- package/dist/extensions/pi-subagents/test/unit/run-id-resolver.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +56 -50
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +69 -28
- package/dist/extensions/pi-subagents/test/unit/scheduled-store-root.test.ts +67 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +59 -44
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +424 -49
- package/dist/extensions/pi-subagents/test/unit/skills-fallback.test.ts +23 -1
- package/dist/extensions/pi-subagents/test/unit/slash-bridge.test.ts +32 -5
- package/dist/extensions/pi-subagents/test/unit/stale-run-reconciler.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +120 -91
- package/dist/extensions/pi-subagents/test/unit/steering.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-action-recovery.test.ts +85 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-control.test.ts +35 -35
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +24 -0
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +312 -22
- package/dist/extensions/pi-subagents/test/unit/subagent-wait.test.ts +150 -15
- package/dist/extensions/pi-subagents/test/unit/task-intent.test.ts +26 -26
- package/dist/extensions/pi-subagents/test/unit/timeout-defaults.test.ts +73 -0
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +76 -25
- package/dist/extensions/pi-subagents/test/unit/turn-budget.test.ts +5 -5
- package/dist/extensions/pi-subagents/test/unit/wait-subscriptions.test.ts +55 -6
- package/dist/extensions/pi-subagents/test/unit/watchdog-child-status.test.ts +13 -13
- package/dist/extensions/pi-subagents/test/unit/watchdog-lsp-diagnostics.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-runtime.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-settings.test.ts +8 -8
- package/dist/extensions/pi-subagents/test/unit/widget-nested-render.test.ts +6 -6
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +138 -11
- package/dist/extensions/pi-subagents/test/unit/workflow-graph.test.ts +8 -8
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +113 -0
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +7 -7
- package/dist/extensions/pi-subagents/test/unit/writer-budget-guidance.test.ts +6 -6
- package/dist/extensions/workflow/extension.ts +21 -19
- package/dist/extensions/workflow/modes.ts +65 -0
- package/dist/skills/pi-subagents/SKILL.md +20 -15
- package/dist/skills/pi-subagents/references/constraints-and-recipes.md +77 -83
- package/dist/skills/pi-subagents/references/execution-controls.md +215 -106
- package/dist/skills/pi-subagents/references/management-authoring-rpc.md +29 -9
- package/dist/skills/pi-subagents/references/prompting-and-roles.md +58 -43
- package/docs/plans/workflow-autoloop-reference.md +192 -0
- package/docs/plans/workflow-subagent-consolidation-planb.md +374 -0
- package/docs/plans/workflow-subagent-scripted-merge.md +406 -0
- package/package.json +1 -1
- package/dist/extensions/workflow/adapter.ts +0 -949
- package/dist/extensions/workflow/modes/loop.ts +0 -74
- package/dist/extensions/workflow/modes/prototype.ts +0 -170
- package/dist/extensions/workflow/modes/quicktype.ts +0 -150
- package/dist/extensions/workflow/modes/task.ts +0 -105
- package/dist/extensions/workflow/run-state.ts +0 -124
- package/dist/extensions/workflow/state-machine.ts +0 -484
- package/dist/extensions/workflow/validators.ts +0 -42
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
* This module adds a portable, file-based control inbox inside the run directory.
|
|
10
10
|
* The parent drops an interrupt request file; the runner watches the inbox and
|
|
11
11
|
* routes the request into its existing graceful `interruptRunner()` (pause +
|
|
12
|
-
* resumable), identically on every platform. The
|
|
13
|
-
*
|
|
14
|
-
* authoritative.
|
|
12
|
+
* resumable), identically on every platform. The file inbox is authoritative and
|
|
13
|
+
* avoids signaling a PID that the extension cannot prove belongs to the runner.
|
|
15
14
|
*/
|
|
16
15
|
|
|
17
16
|
import { randomUUID } from "node:crypto";
|
|
@@ -21,15 +20,19 @@ import { writeAtomicJson } from "../../shared/atomic-json.ts";
|
|
|
21
20
|
import { POLL_INTERVAL_MS } from "../../shared/types.ts";
|
|
22
21
|
import { resolveWatchPath } from "../../shared/utils.ts";
|
|
23
22
|
|
|
24
|
-
/**
|
|
25
|
-
* Opportunistic fast-path interrupt signal. On Unix `SIGUSR2` is trapped by the
|
|
26
|
-
* runner; on Windows `process.kill(pid, "SIGBREAK")` is not deliverable
|
|
27
|
-
* cross-process and throws `ENOSYS`, so the file inbox below is the real channel.
|
|
28
|
-
*/
|
|
29
|
-
export const INTERRUPT_SIGNAL: NodeJS.Signals = process.platform === "win32" ? "SIGBREAK" : "SIGUSR2";
|
|
30
|
-
|
|
31
23
|
export type ControlChannelFs = Pick<typeof fs, "mkdirSync" | "existsSync" | "rmSync" | "watch" | "readdirSync" | "readFileSync" | "realpathSync">;
|
|
24
|
+
|
|
25
|
+
function writeJsonToExistingDir(filePath: string, payload: object): void {
|
|
26
|
+
const tempPath = path.join(path.dirname(filePath), `.${path.basename(filePath)}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`);
|
|
27
|
+
try {
|
|
28
|
+
fs.writeFileSync(tempPath, JSON.stringify(payload, null, 2), { encoding: "utf-8", flag: "wx" });
|
|
29
|
+
fs.renameSync(tempPath, filePath);
|
|
30
|
+
} finally {
|
|
31
|
+
fs.rmSync(tempPath, { force: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
32
34
|
export type ControlChannelTimers = { setInterval: typeof setInterval; clearInterval: typeof clearInterval };
|
|
35
|
+
const CONTROL_SAFETY_POLL_INTERVAL_MS = 5000;
|
|
33
36
|
type KillFn = (pid: number, signal?: NodeJS.Signals | 0) => unknown;
|
|
34
37
|
|
|
35
38
|
export interface InterruptRequest {
|
|
@@ -60,11 +63,15 @@ export interface CheckpointDecisionRequest {
|
|
|
60
63
|
reason?: string;
|
|
61
64
|
}
|
|
62
65
|
|
|
66
|
+
export type SteerDeliveryMode = "steer" | "follow_up" | "auto";
|
|
67
|
+
export type SteerDeliveryStatus = "delivered" | "queued";
|
|
68
|
+
|
|
63
69
|
export interface SteerRequest {
|
|
64
70
|
type: "steer";
|
|
65
71
|
id: string;
|
|
66
72
|
ts: number;
|
|
67
73
|
message: string;
|
|
74
|
+
mode?: SteerDeliveryMode;
|
|
68
75
|
targetIndex?: number;
|
|
69
76
|
targetIndexes?: number[];
|
|
70
77
|
source?: string;
|
|
@@ -85,11 +92,14 @@ export interface SteerAck {
|
|
|
85
92
|
requestId: string;
|
|
86
93
|
index: number;
|
|
87
94
|
ts: number;
|
|
88
|
-
state: "delivered" | "failed";
|
|
95
|
+
state: "delivered" | "queued" | "failed";
|
|
96
|
+
deliveryStatus?: SteerDeliveryStatus;
|
|
89
97
|
message: string;
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
const STEER_REQUESTS_DIR = "steer-requests";
|
|
101
|
+
const REVIVAL_BRIEFS_DIR = "revival-briefs";
|
|
102
|
+
export const MAX_STEER_QUEUE_SIZE = 20;
|
|
93
103
|
const STEER_TARGETS_DIR = "steer-targets";
|
|
94
104
|
const STEER_CAPABILITIES_DIR = "steer-capabilities";
|
|
95
105
|
const STEER_ACKS_DIR = "steer-acks";
|
|
@@ -186,6 +196,7 @@ function validSteerRequest(request: Partial<SteerRequest>): request is SteerRequ
|
|
|
186
196
|
&& typeof request.message === "string"
|
|
187
197
|
&& Boolean(request.message.trim())
|
|
188
198
|
&& Buffer.byteLength(request.message, "utf8") <= MAX_STEER_MESSAGE_BYTES
|
|
199
|
+
&& (request.mode === undefined || request.mode === "steer" || request.mode === "follow_up" || request.mode === "auto")
|
|
189
200
|
&& (request.targetIndex === undefined || (Number.isInteger(request.targetIndex) && request.targetIndex >= 0 && request.targetIndex <= 1_000_000))
|
|
190
201
|
&& (request.targetIndexes === undefined || (
|
|
191
202
|
request.targetIndex === undefined
|
|
@@ -205,6 +216,13 @@ export function writeSteerRequestToDir(dir: string, request: SteerRequest): stri
|
|
|
205
216
|
return requestPath;
|
|
206
217
|
}
|
|
207
218
|
|
|
219
|
+
export function writeSteerRequestToExistingDir(dir: string, request: SteerRequest): string {
|
|
220
|
+
if (!validSteerRequest(request)) throw new Error("steer request is malformed or exceeds transport limits.");
|
|
221
|
+
const requestPath = path.join(dir, steerRequestFileName(request));
|
|
222
|
+
writeJsonToExistingDir(requestPath, request);
|
|
223
|
+
return requestPath;
|
|
224
|
+
}
|
|
225
|
+
|
|
208
226
|
export function writeSteerCapabilityAt(filePath: string, capability: Omit<SteerCapability, "type" | "protocolVersion">): string {
|
|
209
227
|
assertChildIndex(capability.index);
|
|
210
228
|
if (!Number.isInteger(capability.pid) || capability.pid <= 0) throw new Error("steer capability pid must be a positive integer.");
|
|
@@ -218,14 +236,26 @@ export function writeSteerCapability(asyncDir: string, capability: Omit<SteerCap
|
|
|
218
236
|
return writeSteerCapabilityAt(steerCapabilityPath(asyncDir, capability.index), capability);
|
|
219
237
|
}
|
|
220
238
|
|
|
239
|
+
function steerAckWritePath(filePath: string, ack: Omit<SteerAck, "type" | "protocolVersion">): string {
|
|
240
|
+
const parsed = path.parse(filePath);
|
|
241
|
+
const stateOrder = ack.state === "queued" ? "0" : ack.state === "delivered" ? "1" : "2";
|
|
242
|
+
const timestamp = String(Math.trunc(ack.ts)).padStart(13, "0");
|
|
243
|
+
for (let suffix = 0; suffix < 1_000; suffix += 1) {
|
|
244
|
+
const candidate = path.join(parsed.dir, `${parsed.name}-${timestamp}-${stateOrder}-${ack.state}${suffix === 0 ? "" : `-${suffix}`}${parsed.ext}`);
|
|
245
|
+
if (!fs.existsSync(candidate)) return candidate;
|
|
246
|
+
}
|
|
247
|
+
throw new Error("steer acknowledgment queue is full.");
|
|
248
|
+
}
|
|
249
|
+
|
|
221
250
|
export function writeSteerAckAt(filePath: string, ack: Omit<SteerAck, "type" | "protocolVersion">): string {
|
|
222
251
|
assertChildIndex(ack.index);
|
|
223
252
|
if (!/^[^\s]+$/.test(ack.requestId) || ack.requestId.length > 256) throw new Error("steer acknowledgment requestId is invalid.");
|
|
224
253
|
if (!Number.isFinite(ack.ts) || ack.ts <= 0) throw new Error("steer acknowledgment ts must be a finite timestamp.");
|
|
225
254
|
if (!ack.message.trim() || ack.message.length > 1000) throw new Error("steer acknowledgment message is invalid.");
|
|
226
255
|
const record: SteerAck = { type: "steer-ack", protocolVersion: 1, ...ack, message: ack.message.trim() };
|
|
227
|
-
|
|
228
|
-
|
|
256
|
+
const ackPath = steerAckWritePath(filePath, ack);
|
|
257
|
+
writeAtomicJson(ackPath, record);
|
|
258
|
+
return ackPath;
|
|
229
259
|
}
|
|
230
260
|
|
|
231
261
|
export function writeSteerAck(asyncDir: string, ack: Omit<SteerAck, "type" | "protocolVersion">): string {
|
|
@@ -283,7 +313,7 @@ export function requestAsyncCheckpointDecision(
|
|
|
283
313
|
|
|
284
314
|
export function requestAsyncSteer(
|
|
285
315
|
asyncDir: string,
|
|
286
|
-
payload: { message: string; targetIndex?: number; targetIndexes?: number[]; source?: string; id?: string; ts?: number },
|
|
316
|
+
payload: { message: string; mode?: SteerDeliveryMode; targetIndex?: number; targetIndexes?: number[]; source?: string; id?: string; ts?: number },
|
|
287
317
|
deps: { now?: () => number; randomId?: () => string } = {},
|
|
288
318
|
): string {
|
|
289
319
|
const message = payload.message.trim();
|
|
@@ -309,6 +339,7 @@ export function requestAsyncSteer(
|
|
|
309
339
|
id: payload.id ?? deps.randomId?.() ?? randomUUID(),
|
|
310
340
|
ts: payload.ts ?? deps.now?.() ?? Date.now(),
|
|
311
341
|
message,
|
|
342
|
+
...(payload.mode && payload.mode !== "steer" ? { mode: payload.mode } : {}),
|
|
312
343
|
...(payload.targetIndex !== undefined ? { targetIndex: payload.targetIndex } : {}),
|
|
313
344
|
...(payload.targetIndexes !== undefined ? { targetIndexes: [...payload.targetIndexes] } : {}),
|
|
314
345
|
...(payload.source ? { source: payload.source } : {}),
|
|
@@ -343,9 +374,10 @@ function parseSteerAck(raw: unknown): SteerAck | undefined {
|
|
|
343
374
|
if (input.type !== "steer-ack" || input.protocolVersion !== 1 || typeof input.requestId !== "string" || !/^[^\s]+$/.test(input.requestId) || input.requestId.length > 256) return undefined;
|
|
344
375
|
const { index, ts, state, message } = input;
|
|
345
376
|
if (typeof index !== "number" || typeof ts !== "number" || !Number.isInteger(index) || index < 0 || index > 1_000_000 || !Number.isFinite(ts) || ts <= 0) return undefined;
|
|
346
|
-
if (state !== "delivered" && state !== "failed") return undefined;
|
|
377
|
+
if (state !== "delivered" && state !== "queued" && state !== "failed") return undefined;
|
|
378
|
+
if (input.deliveryStatus !== undefined && input.deliveryStatus !== "delivered" && input.deliveryStatus !== "queued") return undefined;
|
|
347
379
|
if (typeof message !== "string" || !message.trim() || message.length > 1000) return undefined;
|
|
348
|
-
return { type: "steer-ack", protocolVersion: 1, requestId: input.requestId, index, ts, state, message: message.trim() };
|
|
380
|
+
return { type: "steer-ack", protocolVersion: 1, requestId: input.requestId, index, ts, state, ...(input.deliveryStatus ? { deliveryStatus: input.deliveryStatus } : {}), message: message.trim() };
|
|
349
381
|
}
|
|
350
382
|
|
|
351
383
|
export function readSteerCapability(asyncDir: string, index: number): SteerCapability | undefined {
|
|
@@ -371,6 +403,25 @@ export function consumeSteerCapabilities(asyncDir: string, fsImpl: Pick<typeof f
|
|
|
371
403
|
return capabilities;
|
|
372
404
|
}
|
|
373
405
|
|
|
406
|
+
export function consumeSteerAckFromDir(
|
|
407
|
+
dir: string,
|
|
408
|
+
requestId: string,
|
|
409
|
+
fsImpl: Pick<typeof fs, "existsSync" | "readdirSync" | "readFileSync" | "rmSync"> = fs,
|
|
410
|
+
): SteerAck | undefined {
|
|
411
|
+
if (!fsImpl.existsSync(dir)) return undefined;
|
|
412
|
+
let entries: string[];
|
|
413
|
+
try { entries = fsImpl.readdirSync(dir).filter((name) => name.endsWith(".json")).sort(); } catch { return undefined; }
|
|
414
|
+
for (const entry of entries) {
|
|
415
|
+
const target = path.join(dir, entry);
|
|
416
|
+
let ack: SteerAck | undefined;
|
|
417
|
+
try { ack = parseSteerAck(JSON.parse(fsImpl.readFileSync(target, "utf-8"))); } catch { ack = undefined; }
|
|
418
|
+
if (ack?.requestId !== requestId) continue;
|
|
419
|
+
try { fsImpl.rmSync(target, { force: true }); } catch { return undefined; }
|
|
420
|
+
return ack;
|
|
421
|
+
}
|
|
422
|
+
return undefined;
|
|
423
|
+
}
|
|
424
|
+
|
|
374
425
|
export function consumeSteerAcks(asyncDir: string, fsImpl: Pick<typeof fs, "existsSync" | "readdirSync" | "readFileSync" | "rmSync"> = fs): SteerAck[] {
|
|
375
426
|
const root = path.join(controlInboxDir(asyncDir), STEER_ACKS_DIR);
|
|
376
427
|
if (!fsImpl.existsSync(root)) return [];
|
|
@@ -401,6 +452,7 @@ function parseSteerRequest(raw: unknown): SteerRequest | undefined {
|
|
|
401
452
|
id: input.id.trim(),
|
|
402
453
|
ts: input.ts,
|
|
403
454
|
message: input.message.trim(),
|
|
455
|
+
...(input.mode ? { mode: input.mode } : {}),
|
|
404
456
|
...(input.targetIndex !== undefined ? { targetIndex: input.targetIndex } : {}),
|
|
405
457
|
...(input.targetIndexes !== undefined ? { targetIndexes: [...input.targetIndexes] } : {}),
|
|
406
458
|
...(typeof input.source === "string" && input.source.trim() ? { source: input.source } : {}),
|
|
@@ -440,6 +492,27 @@ export function consumeSteerRequests(asyncDir: string, fsImpl: Pick<typeof fs, "
|
|
|
440
492
|
return consumeSteerRequestsFromDir(steerRequestsDir(asyncDir), fsImpl);
|
|
441
493
|
}
|
|
442
494
|
|
|
495
|
+
export function queueRevivalBrief(asyncDir: string, request: SteerRequest): string {
|
|
496
|
+
const dir = path.join(controlInboxDir(asyncDir), REVIVAL_BRIEFS_DIR);
|
|
497
|
+
const queued = fs.existsSync(dir) ? fs.readdirSync(dir).filter((entry) => entry.endsWith(".json")).length : 0;
|
|
498
|
+
if (queued >= MAX_STEER_QUEUE_SIZE) throw new Error(`Follow-up queue is full (${MAX_STEER_QUEUE_SIZE} messages).`);
|
|
499
|
+
return writeSteerRequestToDir(dir, { ...request, mode: "follow_up" });
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export function readRevivalBriefs(asyncDir: string): Array<{ request: SteerRequest; path: string }> {
|
|
503
|
+
const dir = path.join(controlInboxDir(asyncDir), REVIVAL_BRIEFS_DIR);
|
|
504
|
+
if (!fs.existsSync(dir)) return [];
|
|
505
|
+
return fs.readdirSync(dir).filter((entry) => entry.endsWith(".json")).sort().flatMap((entry) => {
|
|
506
|
+
const filePath = path.join(dir, entry);
|
|
507
|
+
try {
|
|
508
|
+
const request = parseSteerRequest(JSON.parse(fs.readFileSync(filePath, "utf-8")));
|
|
509
|
+
return request ? [{ request, path: filePath }] : [];
|
|
510
|
+
} catch {
|
|
511
|
+
return [];
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
|
|
443
516
|
/**
|
|
444
517
|
* Runner side: consume a pending interrupt request. Idempotent — removes the file
|
|
445
518
|
* so each distinct request fires exactly once. Returns whether one was pending.
|
|
@@ -501,38 +574,13 @@ export function consumeCheckpointDecisionRequest(
|
|
|
501
574
|
return undefined;
|
|
502
575
|
}
|
|
503
576
|
|
|
504
|
-
/**
|
|
505
|
-
* Parent side: portable interrupt = authoritative file request + best-effort OS
|
|
506
|
-
* signal. The signal is only a latency optimization on Unix; ENOSYS on Windows
|
|
507
|
-
* is swallowed because the file inbox is authoritative there. Other signal
|
|
508
|
-
* failures are surfaced because they usually mean the runner is not alive to
|
|
509
|
-
* consume the request.
|
|
510
|
-
*/
|
|
577
|
+
/** Parent side: write the authoritative portable interrupt request. */
|
|
511
578
|
export function deliverInterruptRequest(input: {
|
|
512
579
|
asyncDir: string;
|
|
513
|
-
pid?: number;
|
|
514
|
-
kill?: KillFn;
|
|
515
|
-
signal?: NodeJS.Signals;
|
|
516
580
|
now?: () => number;
|
|
517
581
|
source?: string;
|
|
518
582
|
}): void {
|
|
519
|
-
|
|
520
|
-
if (typeof input.pid === "number" && input.pid > 0) {
|
|
521
|
-
try {
|
|
522
|
-
(input.kill ?? process.kill)(input.pid, input.signal ?? INTERRUPT_SIGNAL);
|
|
523
|
-
} catch (error) {
|
|
524
|
-
if ((error as NodeJS.ErrnoException | undefined)?.code === "ENOSYS") {
|
|
525
|
-
// File inbox is authoritative when custom cross-process signals are unavailable.
|
|
526
|
-
return;
|
|
527
|
-
}
|
|
528
|
-
try {
|
|
529
|
-
fs.rmSync(requestPath, { force: true });
|
|
530
|
-
} catch {
|
|
531
|
-
// Best effort cleanup; the caller still gets the signal failure.
|
|
532
|
-
}
|
|
533
|
-
throw error;
|
|
534
|
-
}
|
|
535
|
-
}
|
|
583
|
+
requestAsyncInterrupt(input.asyncDir, input.source ? { source: input.source } : {}, { now: input.now });
|
|
536
584
|
}
|
|
537
585
|
|
|
538
586
|
export function deliverTimeoutRequest(input: {
|
|
@@ -574,9 +622,9 @@ export function deliverCheckpointDecisionRequest(input: {
|
|
|
574
622
|
|
|
575
623
|
/**
|
|
576
624
|
* Runner side: watch the control inbox and route interrupt requests into
|
|
577
|
-
* `onInterrupt`. Uses `fs.watch` when available
|
|
578
|
-
*
|
|
579
|
-
*
|
|
625
|
+
* `onInterrupt`. Uses `fs.watch` when available and starts interval polling
|
|
626
|
+
* only when native watching is unavailable or fails. Fires once per distinct
|
|
627
|
+
* request. Returns a disposer.
|
|
580
628
|
*/
|
|
581
629
|
export function watchAsyncControlInbox(
|
|
582
630
|
asyncDir: string,
|
|
@@ -589,6 +637,7 @@ export function watchAsyncControlInbox(
|
|
|
589
637
|
onSteerCapability?: (capability: SteerCapability) => void;
|
|
590
638
|
onSteerAck?: (ack: SteerAck) => void;
|
|
591
639
|
pollIntervalMs?: number;
|
|
640
|
+
safetyPollIntervalMs?: number;
|
|
592
641
|
fs?: ControlChannelFs;
|
|
593
642
|
timers?: ControlChannelTimers;
|
|
594
643
|
},
|
|
@@ -622,27 +671,63 @@ export function watchAsyncControlInbox(
|
|
|
622
671
|
// Handle a request that may have arrived before the watcher started.
|
|
623
672
|
check();
|
|
624
673
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
674
|
+
const watchers: fs.FSWatcher[] = [];
|
|
675
|
+
const watchedDirs = new Set<string>();
|
|
676
|
+
let interval: ReturnType<typeof setInterval> | undefined;
|
|
677
|
+
let safetyInterval: ReturnType<typeof setInterval> | undefined;
|
|
678
|
+
const startPolling = (): void => {
|
|
679
|
+
if (interval || disposed) return;
|
|
680
|
+
interval = timers.setInterval(check, opts.pollIntervalMs ?? POLL_INTERVAL_MS);
|
|
681
|
+
interval.unref?.();
|
|
682
|
+
};
|
|
683
|
+
const startSafetyPolling = (): void => {
|
|
684
|
+
if (safetyInterval || disposed) return;
|
|
685
|
+
safetyInterval = timers.setInterval(check, opts.safetyPollIntervalMs ?? CONTROL_SAFETY_POLL_INTERVAL_MS);
|
|
686
|
+
safetyInterval.unref?.();
|
|
687
|
+
};
|
|
688
|
+
const watchDir = (target: string, create = false): void => {
|
|
689
|
+
if (disposed || watchedDirs.has(target)) return;
|
|
690
|
+
if (create) fsImpl.mkdirSync(target, { recursive: true });
|
|
691
|
+
const watcher = fsImpl.watch(resolveWatchPath(target, fsImpl.realpathSync.native), () => {
|
|
692
|
+
watchExistingSteerAckDirs();
|
|
693
|
+
check();
|
|
630
694
|
});
|
|
695
|
+
watcher.on?.("error", startPolling);
|
|
696
|
+
watchers.push(watcher);
|
|
697
|
+
watchedDirs.add(target);
|
|
698
|
+
};
|
|
699
|
+
const watchExistingSteerAckDirs = (): void => {
|
|
700
|
+
const ackRoot = path.join(dir, STEER_ACKS_DIR);
|
|
701
|
+
let entries: string[];
|
|
702
|
+
try {
|
|
703
|
+
entries = fsImpl.readdirSync(ackRoot).filter((name) => /^\d+$/.test(name));
|
|
704
|
+
} catch {
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
for (const entry of entries) watchDir(path.join(ackRoot, entry));
|
|
708
|
+
};
|
|
709
|
+
try {
|
|
710
|
+
watchDir(dir);
|
|
711
|
+
watchDir(steerRequestsDir(asyncDir), true);
|
|
712
|
+
watchDir(steerCapabilitiesDir(asyncDir), true);
|
|
713
|
+
watchDir(path.join(dir, STEER_ACKS_DIR), true);
|
|
714
|
+
watchExistingSteerAckDirs();
|
|
715
|
+
startSafetyPolling();
|
|
631
716
|
} catch {
|
|
632
|
-
|
|
717
|
+
startPolling();
|
|
633
718
|
}
|
|
634
719
|
|
|
635
|
-
const interval = timers.setInterval(check, opts.pollIntervalMs ?? POLL_INTERVAL_MS);
|
|
636
|
-
interval.unref?.();
|
|
637
|
-
|
|
638
720
|
return () => {
|
|
639
721
|
if (disposed) return;
|
|
640
722
|
disposed = true;
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
723
|
+
for (const watcher of watchers) {
|
|
724
|
+
try {
|
|
725
|
+
watcher.close();
|
|
726
|
+
} catch {
|
|
727
|
+
// ignore
|
|
728
|
+
}
|
|
645
729
|
}
|
|
646
|
-
timers.clearInterval(interval);
|
|
730
|
+
if (interval) timers.clearInterval(interval);
|
|
731
|
+
if (safetyInterval) timers.clearInterval(safetyInterval);
|
|
647
732
|
};
|
|
648
733
|
}
|
|
@@ -20,13 +20,16 @@ import {
|
|
|
20
20
|
} from "../../intercom/result-intercom.ts";
|
|
21
21
|
import { projectNestedRegistryForRoot, sanitizeSummary } from "../shared/nested-events.ts";
|
|
22
22
|
import { resolveWatchPath } from "../../shared/utils.ts";
|
|
23
|
+
import { recordWaitCompletion } from "./wait-completions.ts";
|
|
24
|
+
import { MISSION_BINDING_FILE, syncMissionFromAsyncCompletion } from "../../missions/lifecycle.ts";
|
|
23
25
|
import type { CompletionNotifier, CompletionNotification } from "./notify.ts";
|
|
24
26
|
|
|
25
27
|
const WATCHER_RESTART_DELAY_MS = 3000;
|
|
26
28
|
const POLL_INTERVAL_MS = 3000;
|
|
29
|
+
const HEALTHY_SCAN_INTERVAL_MS = 60_000;
|
|
27
30
|
const RETRY_DELAY_MS = 100;
|
|
28
31
|
|
|
29
|
-
type ResultWatcherFs = Pick<typeof fs, "existsSync" | "readFileSync" | "unlinkSync" | "readdirSync" | "mkdirSync" | "realpathSync" | "watch">;
|
|
32
|
+
type ResultWatcherFs = Pick<typeof fs, "existsSync" | "readFileSync" | "unlinkSync" | "readdirSync" | "mkdirSync" | "realpathSync" | "statSync" | "watch">;
|
|
30
33
|
|
|
31
34
|
type ResultWatcherTimers = {
|
|
32
35
|
setTimeout: typeof setTimeout;
|
|
@@ -41,6 +44,10 @@ type ResultWatcherDeps = {
|
|
|
41
44
|
notifier?: Pick<CompletionNotifier, "deliver">;
|
|
42
45
|
/** Receives persisted completions before active-session delivery filtering. */
|
|
43
46
|
observeCompletion?: (result: CompletionNotification & { runId: string }) => void;
|
|
47
|
+
/** Returns cross-session run ids that the completion observer currently owns. */
|
|
48
|
+
observedCompletionRunIds?: () => Iterable<string>;
|
|
49
|
+
/** Parses a relevant result payload after its lightweight identity check. */
|
|
50
|
+
parseResult?: (raw: string) => ResultFileData;
|
|
44
51
|
/** External grouped-result transport. Disable when native completion notifications own delivery. */
|
|
45
52
|
deliverIntercomResults?: boolean;
|
|
46
53
|
};
|
|
@@ -74,6 +81,33 @@ type ResultFileData = CompletionNotification & {
|
|
|
74
81
|
parallelHandoff?: ParallelHandoffReference;
|
|
75
82
|
};
|
|
76
83
|
|
|
84
|
+
type ResultFileIdentity = {
|
|
85
|
+
sessionId?: string;
|
|
86
|
+
runId?: string;
|
|
87
|
+
asyncDir?: string;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
function jsonStringProperty(raw: string, property: string): string | undefined {
|
|
91
|
+
const matches = raw.matchAll(new RegExp(`"${property}"\\s*:\\s*("(?:\\\\.|[^"\\\\])*")`, "g"));
|
|
92
|
+
let encoded: string | undefined;
|
|
93
|
+
for (const match of matches) encoded = match[1];
|
|
94
|
+
if (!encoded) return undefined;
|
|
95
|
+
try {
|
|
96
|
+
const value = JSON.parse(encoded) as unknown;
|
|
97
|
+
return typeof value === "string" && value ? value : undefined;
|
|
98
|
+
} catch {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function resultFileIdentity(raw: string, file: string): ResultFileIdentity {
|
|
104
|
+
return {
|
|
105
|
+
sessionId: jsonStringProperty(raw, "sessionId"),
|
|
106
|
+
runId: file.replace(/\.json$/i, ""),
|
|
107
|
+
asyncDir: jsonStringProperty(raw, "asyncDir"),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
77
111
|
function sanitizeNestedResultChildren(value: unknown, resultPath: string, label: string): NestedRunSummary[] | undefined {
|
|
78
112
|
if (value === undefined) return undefined;
|
|
79
113
|
if (!Array.isArray(value)) {
|
|
@@ -119,11 +153,14 @@ export function createResultWatcher(
|
|
|
119
153
|
const fsApi = deps.fs ?? fs;
|
|
120
154
|
const timers = deps.timers ?? { setTimeout, clearTimeout, setInterval, clearInterval };
|
|
121
155
|
const notifier = deps.notifier ?? { deliver: async () => true };
|
|
156
|
+
const parseResult = deps.parseResult ?? ((raw: string) => JSON.parse(raw) as ResultFileData);
|
|
122
157
|
const deliverIntercomResults = deps.deliverIntercomResults !== false;
|
|
123
158
|
const pendingTriggerTurn = new Map<string, boolean>();
|
|
124
159
|
const processing = new Set<string>();
|
|
160
|
+
const identityCache = new Map<string, { signature: string; identity: ResultFileIdentity }>();
|
|
125
161
|
let deliveryActive = true;
|
|
126
162
|
let deliveryEpoch = 0;
|
|
163
|
+
let resultScanTimer: ReturnType<typeof setInterval> | null = null;
|
|
127
164
|
// The sole in-memory ownership lease. It is acquired for one active session
|
|
128
165
|
// and revoked before the watcher, queues, or callbacks are torn down.
|
|
129
166
|
let activeSessionId: string | null = null;
|
|
@@ -140,14 +177,58 @@ export function createResultWatcher(
|
|
|
140
177
|
state.resultFileCoalescer.schedule(file, delayMs);
|
|
141
178
|
};
|
|
142
179
|
|
|
180
|
+
const inspectResult = (file: string): ResultFileIdentity | undefined => {
|
|
181
|
+
const resultPath = path.join(resultsDir, file);
|
|
182
|
+
try {
|
|
183
|
+
const stat = fsApi.statSync(resultPath);
|
|
184
|
+
const signature = `${stat.size}:${stat.mtimeMs}`;
|
|
185
|
+
const cached = identityCache.get(file);
|
|
186
|
+
if (cached?.signature === signature) return cached.identity;
|
|
187
|
+
const identity = resultFileIdentity(fsApi.readFileSync(resultPath, "utf-8"), file);
|
|
188
|
+
identityCache.set(file, { signature, identity });
|
|
189
|
+
return identity;
|
|
190
|
+
} catch (error) {
|
|
191
|
+
identityCache.delete(file);
|
|
192
|
+
if (!isNotFound(error)) console.error(`Failed to inspect subagent result file '${resultPath}':`, error);
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const observedRunIds = (): ReadonlySet<string> => {
|
|
198
|
+
try {
|
|
199
|
+
return new Set(deps.observedCompletionRunIds?.() ?? []);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
console.error("Failed to inspect observed subagent completion ids:", error);
|
|
202
|
+
return new Set();
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const shouldProcessResult = (file: string, observed?: ReadonlySet<string>): boolean => {
|
|
207
|
+
const identity = inspectResult(file);
|
|
208
|
+
if (!identity) return false;
|
|
209
|
+
// Missing identity stays on the normal parser path so malformed or legacy
|
|
210
|
+
// files keep their existing diagnostics and compatibility behavior.
|
|
211
|
+
if (!identity.sessionId) return true;
|
|
212
|
+
if (identity.sessionId === state.currentSessionId) return true;
|
|
213
|
+
if (identity.asyncDir && fsApi.existsSync(path.join(identity.asyncDir, MISSION_BINDING_FILE))) return true;
|
|
214
|
+
if (identity.runId && (observed ?? observedRunIds()).has(identity.runId)) return true;
|
|
215
|
+
return Boolean(deps.observeCompletion && !deps.observedCompletionRunIds);
|
|
216
|
+
};
|
|
217
|
+
|
|
143
218
|
const handleResult = async (file: string, triggerTurn: boolean) => {
|
|
144
219
|
const resultPath = path.join(resultsDir, file);
|
|
145
220
|
if (processing.has(file) || !fsApi.existsSync(resultPath)) return;
|
|
221
|
+
if (!shouldProcessResult(file)) return;
|
|
146
222
|
processing.add(file);
|
|
147
223
|
try {
|
|
148
|
-
const data =
|
|
224
|
+
const data = parseResult(fsApi.readFileSync(resultPath, "utf-8"));
|
|
149
225
|
if (typeof data.sessionId !== "string" || !data.sessionId) return;
|
|
150
226
|
const runId = data.runId ?? data.id ?? file.replace(/\.json$/i, "");
|
|
227
|
+
try {
|
|
228
|
+
syncMissionFromAsyncCompletion({ ...data, runId });
|
|
229
|
+
} catch (error) {
|
|
230
|
+
console.error(`Mission completion sync failed for '${resultPath}':`, error);
|
|
231
|
+
}
|
|
151
232
|
try {
|
|
152
233
|
deps.observeCompletion?.({ ...data, runId });
|
|
153
234
|
} catch (error) {
|
|
@@ -155,6 +236,12 @@ export function createResultWatcher(
|
|
|
155
236
|
}
|
|
156
237
|
const epoch = deliveryEpoch;
|
|
157
238
|
if (!ownsSession(data.sessionId, epoch)) return;
|
|
239
|
+
// Recorded before dedupe and before the unlink below so subagent_wait can
|
|
240
|
+
// use the in-memory record or its bounded durable replay after cleanup.
|
|
241
|
+
recordWaitCompletion(state, runId, data, Date.now(), completionTtlMs, {
|
|
242
|
+
resultsDir,
|
|
243
|
+
sessionId: data.sessionId,
|
|
244
|
+
});
|
|
158
245
|
const hasExplicitNestedChildren = data.nestedChildren !== undefined;
|
|
159
246
|
let nestedChildren = compactNestedResultChildren(sanitizeNestedResultChildren(data.nestedChildren, resultPath, "nestedChildren"));
|
|
160
247
|
if (!nestedChildren?.length && !hasExplicitNestedChildren) {
|
|
@@ -175,6 +262,7 @@ export function createResultWatcher(
|
|
|
175
262
|
if (!ownsSession(data.sessionId, epoch) || !fsApi.existsSync(resultPath)) return;
|
|
176
263
|
try {
|
|
177
264
|
fsApi.unlinkSync(resultPath);
|
|
265
|
+
identityCache.delete(file);
|
|
178
266
|
} catch (error) {
|
|
179
267
|
if (!isNotFound(error)) {
|
|
180
268
|
console.error(`Failed to remove delivered subagent result '${resultPath}'; will retry:`, error);
|
|
@@ -300,6 +388,7 @@ export function createResultWatcher(
|
|
|
300
388
|
if (!ownsSession(data.sessionId, epoch) || !fsApi.existsSync(resultPath)) return;
|
|
301
389
|
try {
|
|
302
390
|
fsApi.unlinkSync(resultPath);
|
|
391
|
+
identityCache.delete(file);
|
|
303
392
|
} catch (error) {
|
|
304
393
|
if (!isNotFound(error)) {
|
|
305
394
|
console.error(`Failed to remove delivered subagent result '${resultPath}'; will retry:`, error);
|
|
@@ -324,15 +413,23 @@ export function createResultWatcher(
|
|
|
324
413
|
const triggerTurn = options.triggerTurn !== false;
|
|
325
414
|
fsApi.readdirSync(resultsDir)
|
|
326
415
|
.filter((f) => f.endsWith(".json"))
|
|
327
|
-
.forEach((file) =>
|
|
416
|
+
.forEach((file) => {
|
|
417
|
+
if (shouldProcessResult(file)) scheduleResult(file, triggerTurn);
|
|
418
|
+
});
|
|
328
419
|
} catch (error) {
|
|
329
420
|
if (!isNotFound(error)) console.error(`Failed to scan subagent result directory '${resultsDir}':`, error);
|
|
330
421
|
}
|
|
331
422
|
};
|
|
332
423
|
|
|
424
|
+
const clearResultScan = () => {
|
|
425
|
+
if (resultScanTimer) timers.clearInterval(resultScanTimer);
|
|
426
|
+
resultScanTimer = null;
|
|
427
|
+
};
|
|
428
|
+
|
|
333
429
|
const startPolling = (reason: unknown) => {
|
|
334
430
|
state.watcher?.close();
|
|
335
431
|
state.watcher = null;
|
|
432
|
+
clearResultScan();
|
|
336
433
|
if (state.watcherRestartTimer) return;
|
|
337
434
|
console.error(`Subagent result watcher for '${resultsDir}' fell back to polling because native fs.watch is unavailable (${errorCode(reason) ?? "unknown error"}).`);
|
|
338
435
|
primeExistingResults();
|
|
@@ -341,6 +438,7 @@ export function createResultWatcher(
|
|
|
341
438
|
};
|
|
342
439
|
|
|
343
440
|
const scheduleRestart = () => {
|
|
441
|
+
clearResultScan();
|
|
344
442
|
if (state.watcherRestartTimer) return;
|
|
345
443
|
state.watcherRestartTimer = timers.setTimeout(() => {
|
|
346
444
|
state.watcherRestartTimer = null;
|
|
@@ -368,10 +466,16 @@ export function createResultWatcher(
|
|
|
368
466
|
}
|
|
369
467
|
try {
|
|
370
468
|
const watchDir = resolveWatchPath(resultsDir, fsApi.realpathSync.native);
|
|
371
|
-
state.watcher = fsApi.watch(watchDir, (
|
|
372
|
-
if (
|
|
469
|
+
state.watcher = fsApi.watch(watchDir, (_event, file) => {
|
|
470
|
+
if (!file) {
|
|
471
|
+
primeExistingResults();
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
373
474
|
const fileName = file.toString();
|
|
374
|
-
if (fileName.endsWith(".json"))
|
|
475
|
+
if (fileName.endsWith(".json")) {
|
|
476
|
+
identityCache.delete(fileName);
|
|
477
|
+
scheduleResult(fileName, true);
|
|
478
|
+
}
|
|
375
479
|
});
|
|
376
480
|
state.watcher.on("error", (error) => {
|
|
377
481
|
if (shouldPoll(error)) return startPolling(error);
|
|
@@ -381,6 +485,8 @@ export function createResultWatcher(
|
|
|
381
485
|
scheduleRestart();
|
|
382
486
|
});
|
|
383
487
|
state.watcher.unref?.();
|
|
488
|
+
resultScanTimer = timers.setInterval(primeExistingResults, HEALTHY_SCAN_INTERVAL_MS);
|
|
489
|
+
resultScanTimer.unref?.();
|
|
384
490
|
} catch (error) {
|
|
385
491
|
if (shouldPoll(error)) return startPolling(error);
|
|
386
492
|
console.error(`Failed to start subagent result watcher for '${resultsDir}':`, error);
|
|
@@ -400,9 +506,11 @@ export function createResultWatcher(
|
|
|
400
506
|
timers.clearInterval(state.watcherRestartTimer);
|
|
401
507
|
}
|
|
402
508
|
state.watcherRestartTimer = null;
|
|
509
|
+
clearResultScan();
|
|
403
510
|
state.resultFileCoalescer.clear();
|
|
404
511
|
pendingTriggerTurn.clear();
|
|
405
512
|
processing.clear();
|
|
513
|
+
identityCache.clear();
|
|
406
514
|
};
|
|
407
515
|
|
|
408
516
|
return { startResultWatcher, primeExistingResults, stopResultWatcher };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import type { AsyncRunSummary } from "./async-status.ts";
|
|
3
|
+
|
|
4
|
+
export function formatAsyncReviveCommand(run: AsyncRunSummary): string | undefined {
|
|
5
|
+
const step = run.steps.find((candidate) => candidate.status === "failed" && candidate.sessionFile && fs.existsSync(candidate.sessionFile));
|
|
6
|
+
if (!step) {
|
|
7
|
+
if (run.steps.length === 1 && run.sessionFile && fs.existsSync(run.sessionFile)) {
|
|
8
|
+
return `subagent({ action: "resume", id: "${run.id}", message: "Continue from the persisted child session and report the result." })`;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const index = run.steps.length === 1 ? "" : `, index: ${step.index}`;
|
|
13
|
+
return `subagent({ action: "resume", id: "${run.id}"${index}, message: "Continue from the persisted child session and report the result." })`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function formatResumeFirstFailedRunDetail(run: AsyncRunSummary): string | undefined {
|
|
17
|
+
if (run.state !== "failed") return undefined;
|
|
18
|
+
const command = formatAsyncReviveCommand(run);
|
|
19
|
+
if (!command) return undefined;
|
|
20
|
+
return `Resume-first: failed run "${run.id}" has a persisted child session. Revive the original run with ${command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function formatResumeFirstFailedRunsNote(runs: AsyncRunSummary[]): string {
|
|
24
|
+
const resumable = runs
|
|
25
|
+
.filter((run) => run.state === "failed")
|
|
26
|
+
.map((run) => ({ run, command: formatAsyncReviveCommand(run) }))
|
|
27
|
+
.filter((entry): entry is { run: AsyncRunSummary; command: string } => Boolean(entry.command));
|
|
28
|
+
if (resumable.length === 0) return "";
|
|
29
|
+
const guidance = resumable.length === 1
|
|
30
|
+
? `failed run "${resumable[0]!.run.id}" has a persisted child session. Revive the original run with ${resumable[0]!.command}`
|
|
31
|
+
: `${resumable.length} failed runs have persisted child sessions. Inspect status and revive each original run before retrying`;
|
|
32
|
+
return ` Resume-first: ${guidance} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
|
|
33
|
+
}
|