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
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
* loop each read stretched to seconds. This worker runs exactly that pipeline
|
|
9
9
|
* (stat → read → stat, digest, readTopLevelLifecycleRecord →
|
|
10
10
|
* projectStoredTranscript with no turn checkpoint) and hands back the
|
|
11
|
-
* digest and the
|
|
12
|
-
*
|
|
11
|
+
* digest and one slice of the session's display history: the history itself
|
|
12
|
+
* is built once per content and kept here with its base, and only the window
|
|
13
|
+
* or page a request names (`slice`: `{ limit, skip }`) crosses back, with its
|
|
14
|
+
* serialized size measured here.
|
|
13
15
|
*
|
|
14
16
|
* Inside the worker, one projection base (recovery, prepared session and
|
|
15
17
|
* whole-transcript context gauge) per session content is shared by every
|
|
@@ -60,8 +62,14 @@ function clientFor(sessionId) {
|
|
|
60
62
|
* the full file stamp the bytes provably came from, or null. Rejects when the
|
|
61
63
|
* worker cannot answer; callers then run the pipeline on their own thread.
|
|
62
64
|
*/
|
|
63
|
-
export function projectStoredTranscriptOffThread({
|
|
64
|
-
|
|
65
|
+
export function projectStoredTranscriptOffThread({
|
|
66
|
+
sessionId,
|
|
67
|
+
recordPath,
|
|
68
|
+
known = null,
|
|
69
|
+
fingerprint = '',
|
|
70
|
+
slice = null,
|
|
71
|
+
}) {
|
|
72
|
+
return clientFor(sessionId)({ sessionId, recordPath, known, fingerprint, slice });
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
/** Whether the projection worker of `sessionId` is attached (a request now
|
|
@@ -321,15 +329,108 @@ async function buildBase(sessionId, text, previousMessages, timing) {
|
|
|
321
329
|
|
|
322
330
|
const baseBuilds = createBaseBuilds({ build: buildBase });
|
|
323
331
|
|
|
324
|
-
|
|
332
|
+
// Serialized bytes of the display histories this worker keeps for slicing:
|
|
333
|
+
// one larger than the per-session bound is rebuilt per request instead, and
|
|
334
|
+
// the oldest go once all of them exceed the worker's bound. The worker's idle
|
|
335
|
+
// exit releases every one.
|
|
336
|
+
// Measured: a history is about as large as its record (74 MB record: 75 MB
|
|
337
|
+
// history) and a page of a retained one costs ~0.2 s, a rebuilt one ~1 s. 96
|
|
338
|
+
// MB keeps the largest sessions seen (~78 MB records) smooth; 128 MB holds
|
|
339
|
+
// one of those beside a few ordinary ones.
|
|
340
|
+
const WORKER_HISTORY_SESSION_MAX_BYTES = 96 * 1024 * 1024;
|
|
341
|
+
const WORKER_HISTORY_MAX_BYTES = 128 * 1024 * 1024;
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* The display histories one worker retains (`{ value, rowBytes, bytes }`,
|
|
345
|
+
* keyed by session, Map order LRU) within `sessionMaxBytes` each and
|
|
346
|
+
* `maxBytes` together. A history of other content (`owner`, the record
|
|
347
|
+
* content it was built from, and its sidecar fingerprint) is never served.
|
|
348
|
+
*/
|
|
349
|
+
export function createHistoryRetention({
|
|
350
|
+
sessionMaxBytes = WORKER_HISTORY_SESSION_MAX_BYTES,
|
|
351
|
+
maxBytes = WORKER_HISTORY_MAX_BYTES,
|
|
352
|
+
} = {}) {
|
|
353
|
+
const histories = new Map();
|
|
354
|
+
let retainedBytes = 0;
|
|
355
|
+
const drop = (sessionId) => {
|
|
356
|
+
const entry = histories.get(sessionId);
|
|
357
|
+
if (!entry) return;
|
|
358
|
+
histories.delete(sessionId);
|
|
359
|
+
retainedBytes -= entry.history.bytes;
|
|
360
|
+
};
|
|
361
|
+
return {
|
|
362
|
+
get(sessionId, owner, fingerprint) {
|
|
363
|
+
const entry = histories.get(sessionId);
|
|
364
|
+
if (!entry || entry.owner !== owner || entry.fingerprint !== fingerprint) return null;
|
|
365
|
+
histories.delete(sessionId);
|
|
366
|
+
histories.set(sessionId, entry);
|
|
367
|
+
return entry.history;
|
|
368
|
+
},
|
|
369
|
+
/** Keeps `history` when it fits; whether it was kept. */
|
|
370
|
+
retain(sessionId, owner, fingerprint, history) {
|
|
371
|
+
drop(sessionId);
|
|
372
|
+
if (history.bytes > sessionMaxBytes) return false;
|
|
373
|
+
histories.set(sessionId, { owner, fingerprint, history });
|
|
374
|
+
retainedBytes += history.bytes;
|
|
375
|
+
while (retainedBytes > maxBytes && histories.size > 1) drop(histories.keys().next().value);
|
|
376
|
+
return true;
|
|
377
|
+
},
|
|
378
|
+
forget: drop,
|
|
379
|
+
stats: () => ({ histories: histories.size, retainedBytes }),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const historyRetention = createHistoryRetention();
|
|
384
|
+
/** sessionId -> { owner, fingerprint, promise }: histories being built. */
|
|
385
|
+
const historyBuilds = new Map();
|
|
386
|
+
|
|
387
|
+
/** The display history of `built` (one base) under sidecar `fingerprint`,
|
|
388
|
+
* with each row's serialized bytes: retained, joined while another request
|
|
389
|
+
* builds it, or built now. */
|
|
390
|
+
async function displayHistory(sessionId, built, content, fingerprint, projection) {
|
|
391
|
+
const retained = historyRetention.get(sessionId, content, fingerprint);
|
|
392
|
+
if (retained) return { history: retained, historyBuilt: false };
|
|
393
|
+
const pending = historyBuilds.get(sessionId);
|
|
394
|
+
if (pending && pending.owner === content && pending.fingerprint === fingerprint) {
|
|
395
|
+
return { history: await pending.promise, historyBuilt: false };
|
|
396
|
+
}
|
|
397
|
+
const promise = (async () => {
|
|
398
|
+
const value = await projection.windowStoredTranscript(sessionId, built.base, {
|
|
399
|
+
history: true,
|
|
400
|
+
includeMessages: false,
|
|
401
|
+
});
|
|
402
|
+
const rowBytes = new Float64Array(value.items.length);
|
|
403
|
+
let bytes = 0;
|
|
404
|
+
for (let index = 0; index < value.items.length; index += 1) {
|
|
405
|
+
rowBytes[index] = Buffer.byteLength(JSON.stringify(value.items[index] ?? null));
|
|
406
|
+
bytes += rowBytes[index];
|
|
407
|
+
}
|
|
408
|
+
return { value, rowBytes, bytes };
|
|
409
|
+
})();
|
|
410
|
+
const record = { owner: content, fingerprint, promise };
|
|
411
|
+
historyBuilds.set(sessionId, record);
|
|
412
|
+
try {
|
|
413
|
+
const history = await promise;
|
|
414
|
+
if (historyBuilds.get(sessionId) === record) historyRetention.retain(sessionId, content, fingerprint, history);
|
|
415
|
+
return { history, historyBuilt: true };
|
|
416
|
+
} finally {
|
|
417
|
+
if (historyBuilds.get(sessionId) === record) historyBuilds.delete(sessionId);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async function project({ sessionId, recordPath, known, fingerprint = '', slice = null }) {
|
|
325
422
|
const importStartedAt = performance.now();
|
|
326
|
-
const [
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
423
|
+
const [
|
|
424
|
+
{ statSessionStamp, sameSessionStamp },
|
|
425
|
+
{ readTextFile, PROBE_PRESENT },
|
|
426
|
+
{ transcriptTextHash, historyStampOf },
|
|
427
|
+
projection,
|
|
428
|
+
] = await Promise.all([
|
|
429
|
+
import('./store/canonical-reader.mjs'),
|
|
430
|
+
import('./store/fs-probe.mjs'),
|
|
431
|
+
import('./store-transcript-cache.mjs'),
|
|
432
|
+
import('./store-transcript-projection.mjs'),
|
|
433
|
+
]);
|
|
333
434
|
const timing = { importMs: performance.now() - importStartedAt };
|
|
334
435
|
const observe = () => {
|
|
335
436
|
try {
|
|
@@ -374,12 +475,32 @@ async function project({ sessionId, recordPath, itemLimit, known }) {
|
|
|
374
475
|
const built = await pending;
|
|
375
476
|
if (built === RESTART_READ) continue;
|
|
376
477
|
if (built.unreadable) return { ...digest, unreadable: true };
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
478
|
+
// The whole display history stays here (within its budgets); only the
|
|
479
|
+
// requested slice crosses back.
|
|
480
|
+
const { history, historyBuilt } = await displayHistory(
|
|
481
|
+
sessionId,
|
|
482
|
+
built,
|
|
483
|
+
`${digest.textHash}:${digest.textChars}`,
|
|
484
|
+
fingerprint,
|
|
485
|
+
projection
|
|
486
|
+
);
|
|
487
|
+
const request = slice || {};
|
|
488
|
+
const historyStamp = historyStampOf(sessionId, digest.textHash, digest.textChars, fingerprint, request.epoch);
|
|
489
|
+
const proven = Boolean(request.held) && request.baseHistory === historyStamp;
|
|
490
|
+
const value = projection.storedHistorySlice(
|
|
491
|
+
history.value,
|
|
492
|
+
{ ...request, proven },
|
|
493
|
+
{
|
|
494
|
+
digestOf: request.held && !proven ? await projection.heldRowsDigester() : null,
|
|
495
|
+
rowBytes: (index) => history.rowBytes[index],
|
|
496
|
+
}
|
|
497
|
+
);
|
|
498
|
+
const { windowStamp } = value;
|
|
499
|
+
delete value.windowStamp;
|
|
500
|
+
value.projectionStamp = `${historyStamp}/${windowStamp}`;
|
|
501
|
+
const bytes = Buffer.byteLength(JSON.stringify(value));
|
|
381
502
|
timing.projectMs = performance.now() - projectStartedAt;
|
|
382
|
-
return { ...digest, value, lifecycle: built.lifecycle };
|
|
503
|
+
return { ...digest, value, bytes, historyBuilt, lifecycle: built.lifecycle };
|
|
383
504
|
} finally {
|
|
384
505
|
if (!submitted) baseBuilds.release(ticket);
|
|
385
506
|
}
|
|
@@ -388,6 +509,9 @@ async function project({ sessionId, recordPath, itemLimit, known }) {
|
|
|
388
509
|
|
|
389
510
|
if (!isMainThread && workerData?.kind === WORKER_KIND) {
|
|
390
511
|
serveWorkerRequests((payload) => {
|
|
391
|
-
|
|
512
|
+
if (!payload?.forget) return project(payload);
|
|
513
|
+
historyRetention.forget(payload.forget);
|
|
514
|
+
historyBuilds.delete(payload.forget);
|
|
515
|
+
return baseBuilds.forget(payload.forget);
|
|
392
516
|
});
|
|
393
517
|
}
|
|
@@ -31,6 +31,7 @@ export {
|
|
|
31
31
|
_removeSessionSummary,
|
|
32
32
|
} from './store-summary-index.mjs';
|
|
33
33
|
import { _sessionForDisk, _ensureLifecycleFields } from './store/serialize.mjs';
|
|
34
|
+
import { captureTranscriptSnapshot, recordLandedTranscript } from './store/transcript-durability.mjs';
|
|
34
35
|
import {
|
|
35
36
|
_cacheSessionSummary,
|
|
36
37
|
_rollbackCachedSessionSummary,
|
|
@@ -337,6 +338,7 @@ function _doSaveSync(payload) {
|
|
|
337
338
|
// rebuilt from them, never re-read from the later mutable live session.
|
|
338
339
|
let attempted = null;
|
|
339
340
|
try {
|
|
341
|
+
const transcript = captureTranscriptSnapshot(session);
|
|
340
342
|
const disk = _sessionForDisk(session);
|
|
341
343
|
attempted = JSON.stringify(disk);
|
|
342
344
|
// The lifecycle these exact bytes carry, recorded with the commit stamp.
|
|
@@ -382,6 +384,7 @@ function _doSaveSync(payload) {
|
|
|
382
384
|
_recordOwnSessionCommit(target, scratch, lifecycle);
|
|
383
385
|
_publishLandedWriteEpoch(opts, epoch);
|
|
384
386
|
_untrackSaveTmp(tmp);
|
|
387
|
+
recordLandedTranscript(session, transcript, epoch);
|
|
385
388
|
if (mayMutate()) {
|
|
386
389
|
if (publishSummary) _queueSessionSummaryUpsert(session, summaryVersion);
|
|
387
390
|
_clearSaveStateIfCurrent(id, epoch);
|
|
@@ -627,6 +630,7 @@ async function _doSave(payload) {
|
|
|
627
630
|
// payload, never the live session as it looks at settlement time.
|
|
628
631
|
let attempted = null;
|
|
629
632
|
try {
|
|
633
|
+
const transcript = captureTranscriptSnapshot(session);
|
|
630
634
|
const disk = _sessionForDisk(session);
|
|
631
635
|
attempted = JSON.stringify(disk);
|
|
632
636
|
// Captured before the await: the lifecycle of exactly these bytes.
|
|
@@ -671,6 +675,7 @@ async function _doSave(payload) {
|
|
|
671
675
|
_recordOwnSessionCommit(target, scratch, lifecycle);
|
|
672
676
|
_publishLandedWriteEpoch(opts, epoch);
|
|
673
677
|
_untrackSaveTmp(tmp);
|
|
678
|
+
recordLandedTranscript(session, transcript, epoch);
|
|
674
679
|
if (mayMutate()) {
|
|
675
680
|
_queueSessionSummaryUpsert(session, summaryVersion);
|
|
676
681
|
_clearSaveStateIfCurrent(id, epoch);
|
|
@@ -45,6 +45,11 @@ const RUNTIME_CONTROL_SOURCES = new Set([
|
|
|
45
45
|
'task-notification',
|
|
46
46
|
]);
|
|
47
47
|
const ENVELOPE_OPEN_RE = new RegExp(`^\\s*<${SYNTHETIC_USER_ENVELOPE_TAG}\\b`, 'i');
|
|
48
|
+
// The stored crash marker reads like a user cancel ("Request interrupted ..."),
|
|
49
|
+
// and models answered it with "stopped as you asked" and dropped the work.
|
|
50
|
+
// On the wire it names the restart and asks to resume.
|
|
51
|
+
const PROCESS_RESTART_MARKER = '[Request interrupted by process restart]';
|
|
52
|
+
const PROCESS_RESTART_WIRE_TEXT = '[mixdog-runtime] The app restarted mid-turn. Continue from where you left off.';
|
|
48
53
|
|
|
49
54
|
function messageText(message) {
|
|
50
55
|
if (typeof message?.content === 'string') return message.content;
|
|
@@ -128,7 +133,8 @@ export function projectSyntheticUserEnvelopes(messages) {
|
|
|
128
133
|
const projected = messages.map((message) => {
|
|
129
134
|
const kind = classifySyntheticUserMessage(message);
|
|
130
135
|
if (!kind) return message;
|
|
131
|
-
const
|
|
136
|
+
const source = messageText(message).trim() === PROCESS_RESTART_MARKER ? PROCESS_RESTART_WIRE_TEXT : message.content;
|
|
137
|
+
const content = envelopeContent(source, kind);
|
|
132
138
|
if (content === message.content) return message;
|
|
133
139
|
changed = true;
|
|
134
140
|
stats.wrapped += 1;
|
|
@@ -119,7 +119,15 @@ export function matchTailReminder(context, rules = TAIL_REMINDER_RULES) {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
/** `messages` plus the tail reminder for this request (a copy; the input is untouched). */
|
|
122
|
-
|
|
122
|
+
// The session's own response language (as its prompt and settings notices
|
|
123
|
+
// carry it, session/manager/prompt-settings.mjs); a session without one (an
|
|
124
|
+
// agent, an older record) reads the config.
|
|
125
|
+
export function withTailReminder(
|
|
126
|
+
messages,
|
|
127
|
+
{ session, provider, model },
|
|
128
|
+
// null is a recorded "no language", not a missing record.
|
|
129
|
+
language = session?.responseLanguage !== undefined ? session.responseLanguage : _buildLeadLanguage()
|
|
130
|
+
) {
|
|
123
131
|
const text = matchTailReminder({
|
|
124
132
|
provider: session?.provider || provider?.name || '',
|
|
125
133
|
model,
|
|
@@ -260,7 +260,7 @@ export function isStatusOnlyAgentCompletionNotification(text) {
|
|
|
260
260
|
return !(hasAgentResponseResultText(result) || hasAgentResponseResultText(text));
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
-
|
|
263
|
+
function hasAgentResponseResultText(text) {
|
|
264
264
|
const value = String(text || '').trim();
|
|
265
265
|
if (!value) return false;
|
|
266
266
|
const notification = parseTaskNotification(value);
|
|
@@ -685,7 +685,9 @@ export function restoreTranscriptItems(messages, { sessionId = 'session', itemLi
|
|
|
685
685
|
export function sessionContextSnapshotProjection(session, contextStatus) {
|
|
686
686
|
if (!contextStatus) return {};
|
|
687
687
|
return {
|
|
688
|
-
|
|
688
|
+
// The composer's usage readout reads the session totals from the same
|
|
689
|
+
// stats a live runtime publishes; a cold open has no runtime to add them.
|
|
690
|
+
stats: { ...contextMeasurementStats(contextStatus), usageReadout: contextStatus.usage?.usageReadout ?? null },
|
|
689
691
|
contextWindow: Math.max(0, Number(session?.contextWindow || contextStatus.effectiveContextWindow || 0)),
|
|
690
692
|
rawContextWindow: Math.max(0, Number(session?.rawContextWindow || contextStatus.rawContextWindow || 0)),
|
|
691
693
|
effectiveContextWindowPercent: Number(
|
|
@@ -99,7 +99,7 @@ function feedbackDisplay(body) {
|
|
|
99
99
|
return lines.join('\n');
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
function withVisualizeFeedbackDisplay(text) {
|
|
103
103
|
const value = String(text ?? '');
|
|
104
104
|
if (!value.includes(FEEDBACK_OPEN)) return value;
|
|
105
105
|
return value.replace(FEEDBACK_BLOCK, (_block, body) => feedbackDisplay(body));
|
|
@@ -121,7 +121,7 @@ const PASTED_LINES = /· (\d+) lines?$/;
|
|
|
121
121
|
const PASTED_TEXT_MAX_BYTES = 1024 * 1024;
|
|
122
122
|
/** Blob bytes one transcript load may read to count the lines of pastes
|
|
123
123
|
* whose stored name does not carry the count (pastes stored before it did). */
|
|
124
|
-
|
|
124
|
+
const PASTED_LINE_READ_BUDGET_BYTES = 4 * 1024 * 1024;
|
|
125
125
|
|
|
126
126
|
/** A stored plain-text prompt part's text within the load's byte budget, else ''. */
|
|
127
127
|
function offloadedPromptText(part, budget) {
|
|
@@ -137,11 +137,9 @@ export const PROVIDER_SSE_IDLE_TIMEOUT_MS = resolveTimeoutMs('MIXDOG_PROVIDER_SS
|
|
|
137
137
|
// silent-window token rate a steady ~92 tok/s, i.e. live generation, not a
|
|
138
138
|
// wedge). So a "semantic-silent" stream is NOT necessarily dead.
|
|
139
139
|
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
// live long-thinking turns (regex-chess / circuit-fibsqrt: ttft ~1.5s, then
|
|
144
|
-
// killed at exactly 135s of silent thinking, 4 attempts ≈ 552s per turn).
|
|
140
|
+
// Deriving this window from the agent stall budget (warn − tick ≈ 285s) would
|
|
141
|
+
// let a harness that tightens STALL_TIMEOUT_S to 300s collapse it to 135s,
|
|
142
|
+
// which deterministically beheads live long-thinking turns.
|
|
145
143
|
// Reference behavior: abort only after a 300s single-gap silence, and fall
|
|
146
144
|
// back to non-streaming instead of killing the turn. The default is
|
|
147
145
|
// therefore a FIXED 300s, decoupled from the warn math. The only remaining
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { registerBackgroundTask, renderBackgroundTask } from '../../../../../shared/background-tasks.mjs';
|
|
2
|
+
import { stampShellJobCycle } from '../../../../../shared/background-wait.mjs';
|
|
2
3
|
import { killShellJob, watchBackgroundShellJob } from '../shell-jobs.mjs';
|
|
3
4
|
import { renderBackgroundPartialOutput } from '../shell-output.mjs';
|
|
4
5
|
import { readShellTaskOutput } from '../lib/shell-task-output.mjs';
|
|
@@ -65,7 +66,9 @@ export function renderBackgroundedResult({
|
|
|
65
66
|
}) {
|
|
66
67
|
let task = null;
|
|
67
68
|
if (result.jobId) {
|
|
68
|
-
|
|
69
|
+
// The owner's user cycle at start decides whether it is waited on
|
|
70
|
+
// (background-wait.mjs), however the job reached the background.
|
|
71
|
+
task = stampShellJobCycle(registerPromotedTask({ result, command, cwd, options, startedAtMs }));
|
|
69
72
|
try {
|
|
70
73
|
watchBackgroundShellJob(result.jobId, {
|
|
71
74
|
notifyFn: typeof options?.notifyFn === 'function' ? options.notifyFn : null,
|
|
@@ -25,6 +25,9 @@ import {
|
|
|
25
25
|
* when the last observed survivor exits, `cancel` terminates them. */
|
|
26
26
|
function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs } = {}) {
|
|
27
27
|
if (!handle?.taskId) return null;
|
|
28
|
+
// Once cancelled, every observation pass terminates survivors that ignored
|
|
29
|
+
// the first kill, so a retry is not needed to finish the job.
|
|
30
|
+
let cancelled = false;
|
|
28
31
|
try {
|
|
29
32
|
const task = startBackgroundTask({
|
|
30
33
|
taskId: handle.taskId,
|
|
@@ -36,10 +39,10 @@ function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs
|
|
|
36
39
|
meta: { task_id: handle.taskId, stdout: null, stderr: null, cwd, timeoutMs: 0 },
|
|
37
40
|
resultType: 'shell_task_result',
|
|
38
41
|
run: async () => {
|
|
39
|
-
await waitForShellDescendants(handle);
|
|
42
|
+
await waitForShellDescendants(handle, { sweep: () => cancelled });
|
|
40
43
|
// The folder reservation the finished command handed to its
|
|
41
44
|
// survivors ends with the last of them.
|
|
42
|
-
releaseShellJobWorkspace(handle.taskId);
|
|
45
|
+
await releaseShellJobWorkspace(handle.taskId);
|
|
43
46
|
return {
|
|
44
47
|
task_id: handle.taskId,
|
|
45
48
|
status: 'completed',
|
|
@@ -48,6 +51,7 @@ function trackSurvivingDescendants(handle, { command, cwd, options, startedAtMs
|
|
|
48
51
|
},
|
|
49
52
|
// The kill's own re-observation is what `task cancel` reports.
|
|
50
53
|
cancel: () => {
|
|
54
|
+
cancelled = true;
|
|
51
55
|
task.cancelOutcome = killShellDescendants(handle);
|
|
52
56
|
},
|
|
53
57
|
});
|
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
// to background + task wait);
|
|
6
6
|
// 2. a plain leading `cd <dir>` moves into the `cwd` argument;
|
|
7
7
|
// 3. a shell file read (cat/Get-Content/grep/ls …) gets a pointer to the
|
|
8
|
-
// read / grep / list tools — a note now, a rejection when the mode flips
|
|
8
|
+
// read / grep / list tools — a note now, a rejection when the mode flips;
|
|
9
|
+
// 4. a command mentioning `git … worktree add` is rejected (worktrees go
|
|
10
|
+
// through the git tool; a textual check, so mentions as data are too).
|
|
9
11
|
import { shellSplitPipelineSegments, shellSplitSegments, shellTokenize } from '../shell-analysis.mjs';
|
|
10
12
|
import { resolveShellFor } from '../shell-runtime.mjs';
|
|
11
13
|
import { formatShellToolFailure } from './result-format.mjs';
|
|
14
|
+
import { addsUnmanagedWorktree } from './worktree-add-guard.mjs';
|
|
12
15
|
|
|
13
16
|
/** `warn` runs the read with a note; `reject` returns the block without running. */
|
|
14
|
-
|
|
17
|
+
const SHELL_FILE_READ_MODE = 'warn';
|
|
15
18
|
export const SHELL_FILE_READ_NOTE = 'Note: use the read / grep / list tools for files instead of the shell.';
|
|
16
19
|
const SHELL_FILE_READ_BLOCK =
|
|
17
20
|
'Blocked: use read / grep / list for files instead of the shell (read takes offset/limit for a window of a large file).';
|
|
@@ -194,6 +197,20 @@ function detectShellFileRead(command, shellType) {
|
|
|
194
197
|
return operands.length >= minOperands ? { tool, command: name } : null;
|
|
195
198
|
}
|
|
196
199
|
|
|
200
|
+
// ── 4. unmanaged worktrees ───────────────────────────────────────────────────
|
|
201
|
+
|
|
202
|
+
// A worktree added from the shell is invisible to the managed cleanup and
|
|
203
|
+
// outlives the session that made it, so `git … worktree add` never runs here.
|
|
204
|
+
// The check is textual (worktree-add-guard.mjs): a command that only mentions
|
|
205
|
+
// the phrase is refused too, so the message says how to go on either way.
|
|
206
|
+
const SHELL_WORKTREE_ADD_BLOCK =
|
|
207
|
+
'Blocked: this shell command mentions `git … worktree add`, which does not run from the shell; ' +
|
|
208
|
+
'Mixdog manages worktrees so they are cleaned up. To create one, use the git tool: command ' +
|
|
209
|
+
'"git worktree add --detach <path> [<commit>]" makes a read-only snapshot (removed when the turn ends; ' +
|
|
210
|
+
'delegated workers too), and the Lead uses "git worktree add -b <branch> <path>" or action:"worktree" for a ' +
|
|
211
|
+
'branch worktree. The check is textual: to search for that text use the grep tool, and keep the phrase out ' +
|
|
212
|
+
'of shell commands (echo, commit messages, heredocs).';
|
|
213
|
+
|
|
197
214
|
// ── the guard ────────────────────────────────────────────────────────────────
|
|
198
215
|
|
|
199
216
|
/** The syntax family of the shell a call asks for (`args.shell`, as foreign adapters set it), else the default shell's. */
|
|
@@ -209,7 +226,7 @@ function recordFileRead(telemetry, entry) {
|
|
|
209
226
|
}
|
|
210
227
|
|
|
211
228
|
/**
|
|
212
|
-
* Apply the
|
|
229
|
+
* Apply the four guards to a shell call.
|
|
213
230
|
* @returns {{ failure: string } | { args: object, notes: string[] }} the
|
|
214
231
|
* rejection, or the call to run (a leading `cd` moved into `cwd`) with the
|
|
215
232
|
* lines to add to its result.
|
|
@@ -230,6 +247,7 @@ export function guardShellCall(
|
|
|
230
247
|
const sleepFailure = leadingSleepFailure(guarded.command, shellType);
|
|
231
248
|
if (sleepFailure) return { failure: sleepFailure };
|
|
232
249
|
}
|
|
250
|
+
if (addsUnmanagedWorktree(guarded.command)) return { failure: formatShellToolFailure(SHELL_WORKTREE_ADD_BLOCK) };
|
|
233
251
|
const read = detectShellFileRead(guarded.command, shellType);
|
|
234
252
|
if (read) {
|
|
235
253
|
recordFileRead(telemetry, { mode: fileReadMode, tool: read.tool, command: read.command, agent, sessionId });
|
|
@@ -75,7 +75,7 @@ export function _finalizeShellResult(completedExit, text) {
|
|
|
75
75
|
|
|
76
76
|
export function _shellFailureStatus(result, timeout) {
|
|
77
77
|
// Prefer the signal reported by the process. `killed` is only a fallback
|
|
78
|
-
// for platforms (notably
|
|
78
|
+
// for platforms (notably a Windows tree kill) that close without one.
|
|
79
79
|
const signal = result.signal || (result.killed ? 'SIGKILL' : null);
|
|
80
80
|
const exitCode = signal ? null : result.exitCode;
|
|
81
81
|
const shellToolFailed = result.failurePhase === 'tool' || !!result.outputCaptureError;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Whether a shell command mentions `git … worktree add`. A worktree added from
|
|
2
|
+
// the shell is invisible to the managed cleanup and outlives the session that
|
|
3
|
+
// made it, so the shell guard refuses it and points to the git tool.
|
|
4
|
+
//
|
|
5
|
+
// Deliberately textual, conservative and linear-time: no shell is parsed. The
|
|
6
|
+
// command is normalized once (escape and quote characters of every shell
|
|
7
|
+
// dropped, whitespace collapsed; a PowerShell -EncodedCommand decoded), then
|
|
8
|
+
// refused when `git` is followed anywhere later by `worktree … add`. Commands
|
|
9
|
+
// that only mention the phrase as data (echo, grep, a heredoc, a commit
|
|
10
|
+
// message) are refused too; the refusal says how to proceed.
|
|
11
|
+
|
|
12
|
+
const QUOTES = /['"\u2018\u2019\u201a\u201b\u201c\u201d\u201e]/g;
|
|
13
|
+
const GIT_WORD = /\bgit\b/i;
|
|
14
|
+
// `worktree` ending a token that is not an option: `worktree`, `$(worktree`, `alias.wa=worktree`.
|
|
15
|
+
const WORKTREE_TOKEN = /(?:^|[^\w-])worktree$/i;
|
|
16
|
+
const ADD_TOKEN = /^add\b/i;
|
|
17
|
+
// powershell/pwsh -EncodedCommand (any accepted prefix: -e, -ec, -enc, …) and its base64 argument.
|
|
18
|
+
const ENCODED_COMMAND = /(?:^|[\s'"])[-/]e(?:c|n[a-z]*)?\s+['"]?([A-Za-z0-9+/]{4,}={0,2})/gi;
|
|
19
|
+
|
|
20
|
+
/** The command with every shell's escapes and quotes dropped and whitespace collapsed.
|
|
21
|
+
* `joiner` replaces a line continuation: '' as POSIX joins `a\<newline>dd` into one
|
|
22
|
+
* word, ' ' where the continuation separates words. */
|
|
23
|
+
function normalize(text, joiner) {
|
|
24
|
+
return (
|
|
25
|
+
text
|
|
26
|
+
.replace(/[\\`]\r?\n/g, joiner)
|
|
27
|
+
// Hex escapes ($'\x61dd', "\x61dd").
|
|
28
|
+
.replace(/\\x([0-9a-fA-F]{2})/g, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
|
|
29
|
+
// The `$` of a POSIX $'…' / $"…" string.
|
|
30
|
+
.replace(/\$(?=['"])/g, '')
|
|
31
|
+
// PowerShell backtick and cmd caret escapes.
|
|
32
|
+
.replace(/[`^]/g, '')
|
|
33
|
+
.replace(QUOTES, '')
|
|
34
|
+
.replace(/\s+/g, ' ')
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** True when some `git` word comes before a `worktree … add` in `text`. One pass
|
|
39
|
+
* over the tokens: options (`-…`) between `worktree` and `add` are skipped and
|
|
40
|
+
* never start a match, so every token is visited once. */
|
|
41
|
+
function gitThenWorktreeAdd(text) {
|
|
42
|
+
const tokens = text.split(/[\s,]+/);
|
|
43
|
+
let gitSeen = false;
|
|
44
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
45
|
+
const token = tokens[i];
|
|
46
|
+
if (!gitSeen) {
|
|
47
|
+
gitSeen = GIT_WORD.test(token);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (token.startsWith('-') || !WORKTREE_TOKEN.test(token)) continue;
|
|
51
|
+
let next = i + 1;
|
|
52
|
+
while (next < tokens.length && tokens[next].startsWith('-')) next += 1;
|
|
53
|
+
if (next < tokens.length && ADD_TOKEN.test(tokens[next])) return true;
|
|
54
|
+
i = next - 1;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** True when `command` would (or might) run `git … worktree add`. */
|
|
60
|
+
export function addsUnmanagedWorktree(command) {
|
|
61
|
+
const raw = String(command ?? '');
|
|
62
|
+
const texts = [raw];
|
|
63
|
+
for (const [, encoded] of raw.matchAll(ENCODED_COMMAND)) {
|
|
64
|
+
texts.push(Buffer.from(encoded, 'base64').toString('utf16le'));
|
|
65
|
+
}
|
|
66
|
+
return texts.some((text) =>
|
|
67
|
+
['', ' '].some((joiner) => {
|
|
68
|
+
const normalized = normalize(text, joiner);
|
|
69
|
+
// A backslash is a POSIX escape (`a\dd` is `add`) or a Windows path separator
|
|
70
|
+
// (`C:\Git\cmd\git.exe`): both readings are checked.
|
|
71
|
+
return (
|
|
72
|
+
gitThenWorktreeAdd(normalized.replace(/\\(?=[A-Za-z])/g, '')) ||
|
|
73
|
+
gitThenWorktreeAdd(normalized.replaceAll('\\', '/'))
|
|
74
|
+
);
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
}
|