mixdog 1.4.1 → 1.4.3
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/package.json +4 -3
- package/scripts/build-shipped-history.mjs +125 -33
- package/scripts/gate-local.mjs +220 -63
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +139 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +71 -34
- package/scripts/lib/scoped-temp.mjs +1 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +9 -4
- package/scripts/lib/test-spawn-ledger.mjs +43 -3
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/pptx-kit-index.mjs +5 -6
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/scripts/suite-health.mjs +110 -28
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +38 -2
- package/src/defaults/skills/browser-use/SKILL.md +4 -1
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +12 -2
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +28 -9
- package/src/defaults/skills/setup/references/surfaces.md +5 -2
- package/src/defaults/skills/setup-guide/SKILL.md +11 -3
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +40 -50
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/rules/lead/LEAD.md +3 -3
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +4 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
- package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-port.mjs +19 -10
- package/src/runtime/channels/lib/whisper-server.mjs +22 -13
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
- package/src/runtime/connectors/gmail-app-password.mjs +4 -4
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +88 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +15 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +37 -10
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +14 -8
- package/src/runtime/shared/connector-catalog.mjs +70 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +21 -18
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/cost.mjs +6 -1
- package/src/runtime/shared/llm/http-agent.mjs +316 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +453 -0
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-surface.mjs +110 -36
- package/src/runtime/shared/tool-work-units.mjs +35 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +97 -7
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +962 -197
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +9 -5
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +4 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +4 -23
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/agent-task-sessions.mjs +410 -353
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +71 -25
- package/src/session-runtime/bot-status.mjs +103 -103
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/discovery.mjs +245 -47
- package/src/session-runtime/conversation-import/service.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/handoff-attachments.mjs +1 -1
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
- package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +14 -6
- package/src/session-runtime/services/provider-admin.mjs +281 -10
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +14 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +33 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +128 -1070
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +8 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon-session-control.mjs +151 -136
- package/src/standalone/daemon.mjs +61 -2
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +21 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +15 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/tui/App.jsx +162 -164
- package/src/tui/app/app-view/floating-panel.jsx +3 -0
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +22 -11
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
- package/src/tui/app/provider-setup-picker.mjs +20 -13
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
- package/src/tui/app/slash-commands.mjs +2 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +5 -4
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +48 -33
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +2205 -1371
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/quota-resume.mjs +1 -1
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -20,7 +20,7 @@ import { cwdWithinProjects } from '../../../shared/extension-scopes.mjs';
|
|
|
20
20
|
import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
|
|
21
21
|
import { mixyIdentityDir, userDefinitionDir } from '../../../shared/agent-store.mjs';
|
|
22
22
|
import { isSelfMcpToolName, parseMcpToolName } from '../../../shared/tool-primitives.mjs';
|
|
23
|
-
import { connectorToolDefault } from '../../../shared/connector-catalog.mjs';
|
|
23
|
+
import { connectorById, connectorToolDefault } from '../../../shared/connector-catalog.mjs';
|
|
24
24
|
import { MIXY_AGENT_ID } from '../session/agent-home.mjs';
|
|
25
25
|
import { AGENT_MODE, sessionModeOf } from '../session/agent-mode.mjs';
|
|
26
26
|
import { serverConnector } from './server-connectors.mjs';
|
|
@@ -214,12 +214,43 @@ export function connectorToolPermission(policy, toolOrName) {
|
|
|
214
214
|
const mcp = parseMcpToolName(toolOrName);
|
|
215
215
|
if (!mcp || isSelfMcpToolName(toolOrName)) return 'auto';
|
|
216
216
|
if (policy && !connectorEnabled(policy, mcp.server)) return 'disabled';
|
|
217
|
-
// An explicit per-tool entry decides; otherwise a
|
|
218
|
-
// high-risk tools ask (connectorToolDefault) and any
|
|
219
|
-
|
|
217
|
+
// An explicit per-tool entry of the tool's connector decides; otherwise a
|
|
218
|
+
// catalog connector's high-risk tools ask (connectorToolDefault) and any
|
|
219
|
+
// other tool is auto.
|
|
220
|
+
const [own] = connectorToolEntries(policy?.tools, connectorGroupId(mcp.server), mcp.tool);
|
|
221
|
+
return own || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
|
|
220
222
|
}
|
|
221
223
|
|
|
222
224
|
export const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
225
|
+
|
|
226
|
+
/** The connector a server (account) belongs to: `gmail-2` → `gmail` for a
|
|
227
|
+
* catalog connector; any other id is its own. A tool's permission is stored
|
|
228
|
+
* once, under this id, and governs every account. */
|
|
229
|
+
export function connectorGroupId(serverId) {
|
|
230
|
+
const base = String(serverId).replace(/-\d+$/, '');
|
|
231
|
+
return base !== serverId && connectorById(base) ? base : serverId;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const accountNumber = (id) => Number(/-(\d+)$/.exec(id)?.[1] ?? 0);
|
|
235
|
+
|
|
236
|
+
/** The entries for `tool` under the connector `group` or any of its accounts,
|
|
237
|
+
* topmost first: the connector's own, then the lowest-numbered account. An
|
|
238
|
+
* account only holds one in data saved before permissions were kept per
|
|
239
|
+
* connector; the first entry is the one that applies. */
|
|
240
|
+
export function connectorToolEntries(tools, group, tool) {
|
|
241
|
+
return Object.entries(tools || {})
|
|
242
|
+
.filter(([id, own]) => connectorGroupId(id) === group && CONNECTOR_PERMISSIONS.includes(own?.[tool]))
|
|
243
|
+
.sort(([a], [b]) => accountNumber(a) - accountNumber(b))
|
|
244
|
+
.map(([, own]) => own[tool]);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const UNLISTED_ACCOUNT = '\0unlisted account';
|
|
248
|
+
|
|
249
|
+
/** Rank of `tool` on one account of connector `group`: 0 when that account is
|
|
250
|
+
* off, else the topmost entry for the connector, else `unset` (no override:
|
|
251
|
+
* at least asks / at most runs freely). */
|
|
252
|
+
const accountRank = (tools, off, account, group, tool, unset) =>
|
|
253
|
+
off.has(account) ? 0 : (PERMISSION_RANK[connectorToolEntries(tools, group, tool)[0]] ?? unset);
|
|
223
254
|
export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do without asking; make it on the desktop.';
|
|
224
255
|
|
|
225
256
|
/** Whether replacing the stored policy `before` (a stored value, a parsed
|
|
@@ -243,21 +274,102 @@ function connectorPolicyWidens(before, after) {
|
|
|
243
274
|
for (const server of offBefore) if (!offAfter.has(server)) return true;
|
|
244
275
|
const toolsBefore = old.tools || {};
|
|
245
276
|
const toolsAfter = next.tools || {};
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
277
|
+
// Judged per connector and tool: the accounts of one connector share them.
|
|
278
|
+
const pairs = new Set(
|
|
279
|
+
[toolsBefore, toolsAfter].flatMap((tools) =>
|
|
280
|
+
Object.entries(tools).flatMap(([id, own]) =>
|
|
281
|
+
Object.keys(own || {}).map((tool) => `${connectorGroupId(id)}\0${tool}`)
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
);
|
|
285
|
+
for (const pair of pairs) {
|
|
286
|
+
const [group, tool] = pair.split('\0');
|
|
287
|
+
// Each account on its own: one that is off does not hold back its siblings.
|
|
288
|
+
// Plus one account the policy never names: it is on in both policies, so it
|
|
289
|
+
// stands for every installed account that is not listed.
|
|
290
|
+
const accounts = new Set([
|
|
291
|
+
UNLISTED_ACCOUNT,
|
|
292
|
+
...[group, ...offBefore, ...offAfter, ...Object.keys(toolsBefore), ...Object.keys(toolsAfter)].filter(
|
|
293
|
+
(id) => connectorGroupId(id) === group
|
|
294
|
+
),
|
|
295
|
+
]);
|
|
296
|
+
for (const account of accounts) {
|
|
297
|
+
const was = accountRank(toolsBefore, offBefore, account, group, tool, 1);
|
|
298
|
+
const now = accountRank(toolsAfter, offAfter, account, group, tool, 2);
|
|
252
299
|
if (now > was) return true;
|
|
253
300
|
}
|
|
254
301
|
}
|
|
255
302
|
return false;
|
|
256
303
|
}
|
|
257
304
|
|
|
258
|
-
/**
|
|
305
|
+
/** The `code` of the error a refused widening throws. */
|
|
306
|
+
export const CONNECTOR_POLICY_WIDENS = 'CONNECTOR_POLICY_WIDENS';
|
|
307
|
+
/** An approved tool change met a restriction newer than its request. */
|
|
308
|
+
export const CONNECTOR_TOOL_NARROWED = 'CONNECTOR_TOOL_NARROWED';
|
|
309
|
+
/** An approved tool change found the tool already at that level or more. */
|
|
310
|
+
export const CONNECTOR_TOOL_ALREADY = 'CONNECTOR_TOOL_ALREADY';
|
|
311
|
+
|
|
312
|
+
const codedError = (code, message) => Object.assign(new Error(message), { code });
|
|
313
|
+
|
|
314
|
+
// The one change a person approved on a card (setup-tool connector-widen-approval.mjs),
|
|
315
|
+
// set only for the synchronous stretch of its write.
|
|
316
|
+
let approvedToolChange = null;
|
|
317
|
+
|
|
318
|
+
/** Run `write` (a writer whose noWiden check runs synchronously, before it
|
|
319
|
+
* writes) with one approved change `{ server, tool, from, to }`: its check
|
|
320
|
+
* then lets exactly that tool go to `to`, judged on the stored policy it
|
|
321
|
+
* writes over, and nothing else widen. Returns what `write` returns. */
|
|
322
|
+
export function withApprovedConnectorToolChange(change, write) {
|
|
323
|
+
approvedToolChange = change;
|
|
324
|
+
try {
|
|
325
|
+
return write();
|
|
326
|
+
} finally {
|
|
327
|
+
approvedToolChange = null;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// The approved tool's entries (the connector's, and any account's) pinned to
|
|
332
|
+
// one value in both policies, so the comparison judges every other tool and switch.
|
|
333
|
+
const pinTool = (policy, group, tool) => {
|
|
334
|
+
const tools = Object.fromEntries(
|
|
335
|
+
Object.entries(policy?.tools || {}).map(([id, own]) => [
|
|
336
|
+
id,
|
|
337
|
+
connectorGroupId(id) === group ? { ...own, [tool]: 'disabled' } : own,
|
|
338
|
+
])
|
|
339
|
+
);
|
|
340
|
+
tools[group] = { ...tools[group], [tool]: 'disabled' };
|
|
341
|
+
return { off: policy?.off || [], tools };
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
function assertApprovedToolChange(before, after, { server, tool, from, to }) {
|
|
345
|
+
let old;
|
|
346
|
+
try {
|
|
347
|
+
old = before == null ? { off: [], tools: {} } : parseConnectorPolicy(before);
|
|
348
|
+
} catch {
|
|
349
|
+
throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
|
|
350
|
+
}
|
|
351
|
+
// The approved change is the connector's: its one entry goes to `to`.
|
|
352
|
+
const group = connectorGroupId(server);
|
|
353
|
+
if (old.allow || after?.tools?.[group]?.[tool] !== to) throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
|
|
354
|
+
if (connectorPolicyWidens(pinTool(old, group, tool), pinTool(after, group, tool))) {
|
|
355
|
+
throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
|
|
356
|
+
}
|
|
357
|
+
// No override: it asks at least (as connectorPolicyWidens reads it).
|
|
358
|
+
const was = accountRank(old.tools, new Set(old.off), server, group, tool, 1);
|
|
359
|
+
if (was < PERMISSION_RANK[from]) {
|
|
360
|
+
throw codedError(CONNECTOR_TOOL_NARROWED, 'A newer restriction on this tool landed meanwhile; it was kept.');
|
|
361
|
+
}
|
|
362
|
+
if (was >= PERMISSION_RANK[to]) {
|
|
363
|
+
throw codedError(CONNECTOR_TOOL_ALREADY, 'The tool already has this permission or more; nothing changed.');
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Throws NO_WIDEN_MESSAGE (code CONNECTOR_POLICY_WIDENS) when `after` could
|
|
368
|
+
* widen `before` (see connectorPolicyWidens); inside
|
|
369
|
+
* withApprovedConnectorToolChange, only its approved change may. */
|
|
259
370
|
export function assertConnectorPolicyNotWidened(before, after) {
|
|
260
|
-
if (
|
|
371
|
+
if (approvedToolChange) return assertApprovedToolChange(before, after, approvedToolChange);
|
|
372
|
+
if (connectorPolicyWidens(before, after)) throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
|
|
261
373
|
}
|
|
262
374
|
|
|
263
375
|
let toolPermissionWriter = null;
|
|
@@ -6,9 +6,12 @@
|
|
|
6
6
|
// grandchildren (uv.exe -> mcp-for-unity.exe -> python.exe) orphaned. This
|
|
7
7
|
// module implements the MCP spec shutdown order over the whole process tree:
|
|
8
8
|
// close stdin -> grace wait for voluntary exit -> force-kill the recorded
|
|
9
|
-
// tree (
|
|
10
|
-
// POSIX). No external dependencies.
|
|
11
|
-
|
|
9
|
+
// tree (the creation-checked tree kill below on Windows, SIGTERM->SIGKILL of
|
|
10
|
+
// every descendant on POSIX). No external dependencies.
|
|
11
|
+
//
|
|
12
|
+
// It also owns Mixdog's one Windows process-tree kill (treeKillCommand), which
|
|
13
|
+
// every other Windows tree kill runs, sync, async or detached.
|
|
14
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
12
15
|
import { runProcessOffThread } from '../../../shared/process-runner.mjs';
|
|
13
16
|
import { detachedSpawnOpts } from '../../../shared/spawn-flags.mjs';
|
|
14
17
|
|
|
@@ -49,13 +52,21 @@ export const ENUMERATION_DEADLINE_MS = 20_000;
|
|
|
49
52
|
// Output bound of one helper command: a process table is tens of KB.
|
|
50
53
|
const HELPER_MAX_BYTES = 64 * 1024 * 1024;
|
|
51
54
|
|
|
52
|
-
// Run a helper command
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
//
|
|
55
|
+
// Run a helper command (a process-table read or a tree kill) off the event
|
|
56
|
+
// loop (process-runner.mjs: under load one PowerShell start blocked the
|
|
57
|
+
// daemon's loop for seconds). Past `timeoutMs` the helper itself is killed
|
|
58
|
+
// directly: it starts nothing worth walking, and a tree kill of it would be
|
|
59
|
+
// one more pass on the same stuck table read, with a deadline of its own.
|
|
60
|
+
function runHelper(cmd, args, timeoutMs) {
|
|
61
|
+
return runProcessOffThread(cmd, args, { timeoutMs, maxBytes: HELPER_MAX_BYTES, killTree: false });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// A process-table helper's stdout. Past `timeoutMs` (default
|
|
65
|
+
// ENUMERATION_DEADLINE_MS) the helper is killed and the call settles. Strict:
|
|
66
|
+
// a failed, non-zero or timed-out run rejects; otherwise it resolves ''
|
|
67
|
+
// (non-zero exits keep their stdout).
|
|
57
68
|
function run(cmd, args, { strict = false, timeoutMs = ENUMERATION_DEADLINE_MS } = {}) {
|
|
58
|
-
return
|
|
69
|
+
return runHelper(cmd, args, timeoutMs).then(
|
|
59
70
|
({ code, stdout }) => {
|
|
60
71
|
if (strict && code !== 0) throw new Error(`Process enumeration failed (${code}).`);
|
|
61
72
|
return stdout;
|
|
@@ -69,8 +80,10 @@ function run(cmd, args, { strict = false, timeoutMs = ENUMERATION_DEADLINE_MS }
|
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
// Snapshot the whole process table once: parent map + a per-pid identity
|
|
72
|
-
// token (Windows CreationDate, POSIX lstart) so a later kill
|
|
73
|
-
// number was not recycled onto a different process before
|
|
83
|
+
// token (Windows CreationDate as a UTC FILETIME, POSIX lstart) so a later kill
|
|
84
|
+
// can prove a pid number was not recycled onto a different process before
|
|
85
|
+
// signalling it. The FILETIME form orders against the spawn server's root
|
|
86
|
+
// creation time and carries no local-time offset.
|
|
74
87
|
// POSIX rows also carry the process group id (Windows has none).
|
|
75
88
|
async function enumerate({ strict = false } = {}) {
|
|
76
89
|
const childrenOf = new Map();
|
|
@@ -84,7 +97,7 @@ async function enumerate({ strict = false } = {}) {
|
|
|
84
97
|
'-NoProfile',
|
|
85
98
|
'-NonInteractive',
|
|
86
99
|
'-Command',
|
|
87
|
-
`${strict ? "$ErrorActionPreference = 'Stop'; " : ''}Get-CimInstance Win32_Process | ForEach-Object { $created = if ($_.CreationDate) { $_.CreationDate.
|
|
100
|
+
`${strict ? "$ErrorActionPreference = 'Stop'; " : ''}Get-CimInstance Win32_Process | ForEach-Object { $created = if ($_.CreationDate) { $_.CreationDate.ToFileTimeUtc() } else { '' }; "$($_.ProcessId) $($_.ParentProcessId) $($_.Name) $created" }`,
|
|
88
101
|
],
|
|
89
102
|
{ strict, timeoutMs: ENUMERATION_DEADLINE_MS }
|
|
90
103
|
)
|
|
@@ -145,27 +158,41 @@ export function readProcessTable() {
|
|
|
145
158
|
return nextTable;
|
|
146
159
|
}
|
|
147
160
|
|
|
161
|
+
// Windows keeps a dead parent's pid in its children and hands that pid to new
|
|
162
|
+
// processes, so an older process can look like a newer one's child: wininit.exe
|
|
163
|
+
// still names its boot-time parent's pid, and a tree walked from whatever holds
|
|
164
|
+
// that pid now reaches services.exe and every service host under it. A child is
|
|
165
|
+
// never created before its parent, so on Windows a link is followed only from a
|
|
166
|
+
// process whose creation time is known, to one created no earlier. POSIX
|
|
167
|
+
// reparents orphans, so its links never dangle.
|
|
168
|
+
const createdTicks = (token) => (typeof token === 'string' && /^\d+$/.test(token) ? BigInt(token) : null);
|
|
169
|
+
|
|
148
170
|
// Walk every descendant pid of rootPid (excludes rootPid).
|
|
149
|
-
function descendantsOf(childrenOf, rootPid) {
|
|
171
|
+
function descendantsOf(childrenOf, rootPid, tokenOf) {
|
|
150
172
|
const result = [];
|
|
151
173
|
const seen = new Set([rootPid]);
|
|
152
174
|
const stack = [rootPid];
|
|
153
175
|
while (stack.length) {
|
|
154
176
|
const cur = stack.pop();
|
|
177
|
+
const parentCreated = isWin ? createdTicks(tokenOf.get(cur)) : null;
|
|
178
|
+
if (isWin && parentCreated == null) continue;
|
|
155
179
|
for (const child of childrenOf.get(cur) ?? []) {
|
|
156
|
-
if (
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
180
|
+
if (seen.has(child)) continue;
|
|
181
|
+
if (isWin) {
|
|
182
|
+
const childCreated = createdTicks(tokenOf.get(child));
|
|
183
|
+
if (childCreated == null || childCreated < parentCreated) continue;
|
|
160
184
|
}
|
|
185
|
+
seen.add(child);
|
|
186
|
+
result.push(child);
|
|
187
|
+
stack.push(child);
|
|
161
188
|
}
|
|
162
189
|
}
|
|
163
190
|
return result;
|
|
164
191
|
}
|
|
165
192
|
|
|
166
193
|
async function collectDescendants(rootPid) {
|
|
167
|
-
const { childrenOf } = await enumerate();
|
|
168
|
-
return descendantsOf(childrenOf, rootPid);
|
|
194
|
+
const { childrenOf, tokenOf } = await enumerate();
|
|
195
|
+
return descendantsOf(childrenOf, rootPid, tokenOf);
|
|
169
196
|
}
|
|
170
197
|
|
|
171
198
|
/** Descendant pids WITH their image names and identity tokens (creation
|
|
@@ -175,24 +202,163 @@ export async function collectDescendantProcesses(rootPid, { strict = false } = {
|
|
|
175
202
|
const { childrenOf, nameOf, tokenOf } = strict
|
|
176
203
|
? await snapshot
|
|
177
204
|
: await snapshot.catch(() => ({ childrenOf: new Map(), nameOf: new Map(), tokenOf: new Map() }));
|
|
178
|
-
return descendantsOf(childrenOf, rootPid).map((pid) => ({
|
|
205
|
+
return descendantsOf(childrenOf, rootPid, tokenOf).map((pid) => ({
|
|
179
206
|
pid,
|
|
180
207
|
name: nameOf.get(pid) || '',
|
|
181
208
|
token: tokenOf.get(pid) ?? null,
|
|
182
209
|
}));
|
|
183
210
|
}
|
|
184
211
|
|
|
185
|
-
|
|
186
|
-
|
|
212
|
+
const positivePids = (pids) => [...new Set((pids || []).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0))];
|
|
213
|
+
|
|
214
|
+
// The Windows tree kill, one PowerShell pass. taskkill /T is never used: it
|
|
215
|
+
// walks parent ids with no creation times, so it follows the dangling links
|
|
216
|
+
// descendantsOf refuses (on 2026-10-30 one such kill ended every user-owned
|
|
217
|
+
// service host and sihost.exe). A root counts only if it was created no later
|
|
218
|
+
// than -AliveAt (a pid taken over after the caller saw its process is not
|
|
219
|
+
// that process); a descendant only if created no earlier than its parent.
|
|
220
|
+
// Each process is ended through a handle whose start time matches the table.
|
|
221
|
+
// Exit: 0 ended, 128 no root matched (gone or a different process), 1 a root
|
|
222
|
+
// survived; a failed or timed-out table read fails the pass. The table read
|
|
223
|
+
// times out on its own (a pass detached from an exiting caller still ends);
|
|
224
|
+
// every spawn from Node is also held to TREE_KILL_DEADLINE_MS. -Table/-List: tests only, a
|
|
225
|
+
// stand-in table whose member pids are printed instead of ended.
|
|
226
|
+
export const TREE_KILL_SCRIPT = `param([int[]]$Pids, [long]$AliveAt, [object[]]$Table, [switch]$List)
|
|
227
|
+
$ErrorActionPreference = 'Stop'
|
|
228
|
+
$limit = [DateTime]::FromFileTimeUtc($AliveAt)
|
|
229
|
+
if ($Table) {
|
|
230
|
+
$rows = @(foreach ($t in $Table) { [pscustomobject]@{ Id = [int]$t.Id; Parent = [int]$t.Parent; Created = [DateTime]::FromFileTimeUtc([long]$t.Created) } })
|
|
231
|
+
} else {
|
|
232
|
+
$rows = @(Get-CimInstance Win32_Process -OperationTimeoutSec 10 | Where-Object CreationDate | ForEach-Object { [pscustomobject]@{ Id = [int]$_.ProcessId; Parent = [int]$_.ParentProcessId; Created = $_.CreationDate.ToUniversalTime() } })
|
|
233
|
+
}
|
|
234
|
+
$byId = @{}
|
|
235
|
+
$byParent = @{}
|
|
236
|
+
foreach ($r in $rows) {
|
|
237
|
+
$byId[$r.Id] = $r
|
|
238
|
+
if (-not $byParent.ContainsKey($r.Parent)) { $byParent[$r.Parent] = [Collections.Generic.List[object]]::new() }
|
|
239
|
+
$byParent[$r.Parent].Add($r)
|
|
240
|
+
}
|
|
241
|
+
$members = [Collections.Generic.List[object]]::new()
|
|
242
|
+
foreach ($id in $Pids) {
|
|
243
|
+
$r = $byId[$id]
|
|
244
|
+
if ($r -and $r.Created -le $limit -and -not $members.Contains($r)) { $members.Add($r) }
|
|
245
|
+
}
|
|
246
|
+
$roots = $members.Count
|
|
247
|
+
if ($roots -eq 0) { exit 128 }
|
|
248
|
+
for ($i = 0; $i -lt $members.Count; $i++) {
|
|
249
|
+
$parent = $members[$i]
|
|
250
|
+
if (-not $byParent.ContainsKey($parent.Id)) { continue }
|
|
251
|
+
foreach ($child in $byParent[$parent.Id]) {
|
|
252
|
+
if ($child.Created -ge $parent.Created -and -not $members.Contains($child)) { $members.Add($child) }
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if ($List) { foreach ($m in $members) { $m.Id }; exit 0 }
|
|
256
|
+
$survived = $false
|
|
257
|
+
for ($i = 0; $i -lt $members.Count; $i++) {
|
|
258
|
+
$m = $members[$i]
|
|
259
|
+
try { $p = [Diagnostics.Process]::GetProcessById($m.Id) } catch { continue }
|
|
260
|
+
try { $same = [math]::Abs(($p.StartTime.ToUniversalTime() - $m.Created).TotalMilliseconds) -lt 1 } catch { $same = $null }
|
|
261
|
+
if ($same -eq $false) { continue }
|
|
262
|
+
# A start time that cannot be read proves nothing: the process is left alone,
|
|
263
|
+
# and a root left alone counts as surviving.
|
|
264
|
+
if ($null -eq $same) { if ($i -lt $roots) { $survived = $true }; continue }
|
|
265
|
+
try { $p.Kill() } catch {}
|
|
266
|
+
if ($i -lt $roots) { try { if (-not $p.WaitForExit(2000)) { $survived = $true } } catch { $survived = $true } }
|
|
267
|
+
}
|
|
268
|
+
if ($survived) { exit 1 }
|
|
269
|
+
exit 0`;
|
|
270
|
+
|
|
271
|
+
const fileTime = (ms) => BigInt(Math.floor(Number(ms))) * 10_000n + 116_444_736_000_000_000n;
|
|
272
|
+
|
|
273
|
+
/** The command of one Windows tree kill of `pids` (see TREE_KILL_SCRIPT), for
|
|
274
|
+
* callers that spawn it themselves: awaited, synchronous, or detached and
|
|
275
|
+
* unref'd so it outlives an exiting caller. `aliveAt` (epoch ms): when the
|
|
276
|
+
* caller last knew each pid was its process (a live child handle: now; a
|
|
277
|
+
* pid file: when it was written). `table`: tests only, rows { pid, ppid,
|
|
278
|
+
* created (epoch ms) } standing in for the live table; the command then
|
|
279
|
+
* prints the member pids instead of ending them. */
|
|
280
|
+
export function treeKillCommand(pids, { aliveAt = Date.now(), table = null } = {}) {
|
|
281
|
+
const rows = table
|
|
282
|
+
? ` -List -Table @(${table.map((row) => `@{Id=${row.pid};Parent=${row.ppid};Created=${fileTime(row.created)}}`).join(',')})`
|
|
283
|
+
: '';
|
|
284
|
+
const source = `& {\n${TREE_KILL_SCRIPT}\n} -Pids @(${positivePids(pids).join(',')}) -AliveAt ${fileTime(aliveAt)}${rows}`;
|
|
285
|
+
const systemRoot = process.env.SystemRoot || process.env.WINDIR || 'C:\\Windows';
|
|
286
|
+
return {
|
|
287
|
+
command: `${systemRoot}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`,
|
|
288
|
+
args: ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(source, 'utf16le').toString('base64')],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** The hard lifetime of one tree-kill pass, enforced from Node whatever the
|
|
293
|
+
* table read does (its own timeout is 10 s). */
|
|
294
|
+
export const TREE_KILL_DEADLINE_MS = 15_000;
|
|
295
|
+
|
|
296
|
+
/** The tree kill run synchronously (Windows only): its exit status (see
|
|
297
|
+
* TREE_KILL_SCRIPT), or null when it could not run or outlived `timeoutMs`. */
|
|
298
|
+
export function killProcessTreesSync(pids, { aliveAt = Date.now(), timeoutMs = TREE_KILL_DEADLINE_MS } = {}) {
|
|
299
|
+
const { command, args } = treeKillCommand(pids, { aliveAt });
|
|
300
|
+
return spawnSync(command, args, { stdio: 'ignore', windowsHide: true, timeout: timeoutMs }).status;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/** The tree kill spawned (Windows only) and held to TREE_KILL_DEADLINE_MS:
|
|
304
|
+
* past it the pass is killed. `root`: the caller's own ChildProcess, alive
|
|
305
|
+
* now; it is killed directly once the pass has ended, failed or run out of
|
|
306
|
+
* time, so a hung pass never keeps it alive. `detached`: the pass outlives
|
|
307
|
+
* an exiting caller and is bounded only by its own table-read timeout.
|
|
308
|
+
* Neither the pass nor its deadline keeps the caller's event loop alive.
|
|
309
|
+
* Returns the pass's ChildProcess, or null when it could not be spawned. */
|
|
310
|
+
export function spawnTreeKill(pids, { aliveAt = Date.now(), root = null, detached = false } = {}) {
|
|
311
|
+
const killRoot = () => {
|
|
312
|
+
try {
|
|
313
|
+
root?.kill();
|
|
314
|
+
} catch {
|
|
315
|
+
/* already gone */
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
let pass;
|
|
319
|
+
try {
|
|
320
|
+
const { command, args } = treeKillCommand(pids, { aliveAt });
|
|
321
|
+
pass = spawn(command, args, { stdio: 'ignore', ...detachedSpawnOpts });
|
|
322
|
+
} catch {
|
|
323
|
+
killRoot();
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
pass.unref?.();
|
|
327
|
+
if (detached) {
|
|
328
|
+
pass.once('error', killRoot);
|
|
329
|
+
return pass;
|
|
330
|
+
}
|
|
331
|
+
const deadline = setTimeout(() => {
|
|
332
|
+
try {
|
|
333
|
+
pass.kill();
|
|
334
|
+
} catch {
|
|
335
|
+
/* already gone */
|
|
336
|
+
}
|
|
337
|
+
killRoot();
|
|
338
|
+
}, TREE_KILL_DEADLINE_MS);
|
|
339
|
+
deadline.unref?.();
|
|
340
|
+
const settle = () => {
|
|
341
|
+
clearTimeout(deadline);
|
|
342
|
+
killRoot();
|
|
343
|
+
};
|
|
344
|
+
pass.once('error', settle);
|
|
345
|
+
pass.once('exit', settle);
|
|
346
|
+
return pass;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/** Force-kill whole process trees by pid. Windows runs the tree kill off the
|
|
350
|
+
* event loop and resolves to its exit status (null: it could not run or
|
|
351
|
+
* timed out); POSIX escalates SIGTERM → SIGKILL. Best-effort: the caller
|
|
187
352
|
* verifies liveness afterwards rather than trusting the signal. */
|
|
188
|
-
export async function killProcessTrees(pids) {
|
|
189
|
-
const targets =
|
|
190
|
-
if (targets.length === 0) return;
|
|
353
|
+
export async function killProcessTrees(pids, { aliveAt = Date.now() } = {}) {
|
|
354
|
+
const targets = positivePids(pids);
|
|
355
|
+
if (targets.length === 0) return isWin ? 128 : undefined;
|
|
191
356
|
if (isWin) {
|
|
192
|
-
const args =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
357
|
+
const { command, args } = treeKillCommand(targets, { aliveAt });
|
|
358
|
+
return runHelper(command, args, TREE_KILL_DEADLINE_MS).then(
|
|
359
|
+
({ code }) => code,
|
|
360
|
+
() => null
|
|
361
|
+
);
|
|
196
362
|
}
|
|
197
363
|
for (const pid of targets) signalQuietly(pid, 'SIGTERM');
|
|
198
364
|
await delay(300);
|
|
@@ -204,10 +370,10 @@ export async function killProcessTrees(pids) {
|
|
|
204
370
|
/**
|
|
205
371
|
* Immediate, non-blocking tree kill for a transport whose MCP handshake never
|
|
206
372
|
* completed (shutdown-during-connect). Unlike shutdownStdioChild there is no
|
|
207
|
-
* grace wait and no
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* hold the caller's event loop open (the caller is a process about to exit).
|
|
373
|
+
* grace wait and no enumeration here — the ChildProcess handle is live, so the
|
|
374
|
+
* pid is current, and a detached tree kill reaps the still-parented tree after
|
|
375
|
+
* the caller is gone. Everything is unref'd/fire-and-forget so the kill can
|
|
376
|
+
* never hold the caller's event loop open (the caller is a process about to exit).
|
|
211
377
|
*/
|
|
212
378
|
export function killStdioChildTreeFast(transport) {
|
|
213
379
|
const proc = transport?._process;
|
|
@@ -232,15 +398,7 @@ export function killStdioChildTreeFast(transport) {
|
|
|
232
398
|
}
|
|
233
399
|
}
|
|
234
400
|
if (isWin) {
|
|
235
|
-
|
|
236
|
-
const cp = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], {
|
|
237
|
-
stdio: 'ignore',
|
|
238
|
-
...detachedSpawnOpts,
|
|
239
|
-
});
|
|
240
|
-
cp.unref();
|
|
241
|
-
} catch {
|
|
242
|
-
/* ignore */
|
|
243
|
-
}
|
|
401
|
+
spawnTreeKill([pid], { root: proc, detached: true });
|
|
244
402
|
return true;
|
|
245
403
|
}
|
|
246
404
|
// POSIX: cheap ps enumerate, then SIGKILL descendants + root. Best-effort
|
|
@@ -306,11 +464,8 @@ async function killVerified(pids, snapshotToken, currentTokens) {
|
|
|
306
464
|
const verified = pids.filter((pid) => stillSame(pid, snapshotToken, currentTokens));
|
|
307
465
|
if (verified.length === 0) return;
|
|
308
466
|
if (isWin) {
|
|
309
|
-
//
|
|
310
|
-
|
|
311
|
-
const args = ['/F', '/T'];
|
|
312
|
-
for (const p of verified) args.push('/PID', String(p));
|
|
313
|
-
await run('taskkill', args);
|
|
467
|
+
// Every listed pid was identity-checked just above.
|
|
468
|
+
await killProcessTrees(verified);
|
|
314
469
|
return;
|
|
315
470
|
}
|
|
316
471
|
// POSIX: terminate, brief wait, then hard-kill survivors. Re-verify with a
|
|
@@ -337,7 +492,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
|
|
|
337
492
|
// Snapshot #1: tree + identity tokens while it is still fully intact.
|
|
338
493
|
// Covers children that later get re-parented/orphaned during shutdown.
|
|
339
494
|
const before = await enumerate().catch(() => empty);
|
|
340
|
-
const initial = descendantsOf(before.childrenOf, pid);
|
|
495
|
+
const initial = descendantsOf(before.childrenOf, pid, before.tokenOf);
|
|
341
496
|
snapshotToken.set(pid, before.tokenOf.get(pid) ?? null);
|
|
342
497
|
for (const d of initial) snapshotToken.set(d, before.tokenOf.get(d) ?? null);
|
|
343
498
|
// 1. Close stdin to request a voluntary shutdown.
|
|
@@ -351,7 +506,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
|
|
|
351
506
|
// 3. Snapshot #2 after the grace: catches children spawned late during
|
|
352
507
|
// shutdown that were absent from the first snapshot.
|
|
353
508
|
const after = await enumerate().catch(() => empty);
|
|
354
|
-
const fresh = descendantsOf(after.childrenOf, pid);
|
|
509
|
+
const fresh = descendantsOf(after.childrenOf, pid, after.tokenOf);
|
|
355
510
|
for (const d of fresh) {
|
|
356
511
|
if (!snapshotToken.has(d)) snapshotToken.set(d, after.tokenOf.get(d) ?? null);
|
|
357
512
|
}
|
|
@@ -8,11 +8,9 @@ import { rememberMcpToolIdentity } from '../../../shared/tool-primitives.mjs';
|
|
|
8
8
|
|
|
9
9
|
/** Known auto-detect targets: the discovery-advert service name and the MCP
|
|
10
10
|
* endpoint path on its port.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* in-process through agent's toolExecutor (see orchestrator/internal-tools),
|
|
15
|
-
* so this registry is for genuinely external port-based MCP targets only. */
|
|
11
|
+
* The plugin's own tools are injected in-process through agent's
|
|
12
|
+
* toolExecutor (see orchestrator/internal-tools), so this registry is for
|
|
13
|
+
* genuinely external port-based MCP targets only. */
|
|
16
14
|
export const AUTO_DETECT_PORTS = {
|
|
17
15
|
'mixdog-memory': { discovery: 'memory', endpoint: '/mcp' },
|
|
18
16
|
};
|
|
@@ -307,14 +305,25 @@ export function resolveMcpTransportKind(cfg) {
|
|
|
307
305
|
throw new Error(`Invalid config: need autoDetect, type (stdio/http/sse/ws), url (http), or command (stdio)`);
|
|
308
306
|
}
|
|
309
307
|
|
|
310
|
-
/** The exact URL
|
|
311
|
-
*
|
|
308
|
+
/** The exact URL an HTTP/SSE server config signs in at with OAuth; null for
|
|
309
|
+
* other transports. */
|
|
312
310
|
export function resolveMcpOAuthUrl(cfg) {
|
|
313
311
|
const kind = resolveMcpTransportKind(cfg);
|
|
314
312
|
if (kind !== 'http' && kind !== 'sse') return null;
|
|
315
313
|
return normalizeMcpTransportUrl(expandEnvVars(String(cfg.url ?? '')), kind);
|
|
316
314
|
}
|
|
317
315
|
|
|
316
|
+
/** What the OAuth credentials of an HTTP/SSE server config are stored under:
|
|
317
|
+
* its exact URL, or a connector account's own `oauthKey` (another account
|
|
318
|
+
* of the connector signs in at the same URL), whatever the URL. Null for
|
|
319
|
+
* other transports. */
|
|
320
|
+
export function resolveMcpOAuthCredentialKey(cfg) {
|
|
321
|
+
const url = resolveMcpOAuthUrl(cfg);
|
|
322
|
+
if (!url) return null;
|
|
323
|
+
const own = typeof cfg.oauthKey === 'string' ? cfg.oauthKey.trim() : '';
|
|
324
|
+
return own ? `mcp-account:${own}` : url;
|
|
325
|
+
}
|
|
326
|
+
|
|
318
327
|
// MCP per-tool-call timeout. Default 2min: a hung/unresponsive MCP server
|
|
319
328
|
// (e.g. a busy editor) must not stall a tool call indefinitely. Genuinely
|
|
320
329
|
// long-running tools can raise/disable it via MIXDOG_MCP_CALL_TIMEOUT_MS or a
|