mixdog 1.2.5 → 1.3.0
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/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/gate-scheduler.mjs +2 -2
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +5 -14
- package/scripts/provider-pingpong-live.mjs +9 -9
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +5 -4
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -0
- package/src/defaults/skills/browser-use/SKILL.md +7 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +56 -7
- package/src/output-styles/common.md +22 -6
- package/src/output-styles/detailed.md +7 -5
- package/src/output-styles/minimal.md +7 -3
- package/src/output-styles/simple.md +2 -3
- package/src/rules/agent/AGENT.md +7 -1
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +21 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +9 -4
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
- package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
- package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
- package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
- package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
- package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
- package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/office-extract.mjs +11 -9
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
- package/src/runtime/office/core/tabular.mjs +1 -1
- package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
- package/src/runtime/office/portable/docx-formatting.mjs +1 -1
- package/src/runtime/office/portable/docx-runs.mjs +1 -1
- package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
- package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
- package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
- package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
- package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
- package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
- package/src/runtime/office/portable/portable-opc.mjs +27 -13
- package/src/runtime/office/portable/portable-pivot.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
- package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
- package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
- package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
- package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
- package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
- package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
- package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
- package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
- package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
- package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
- package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
- package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
- package/src/runtime/office/portable/portable-xml.mjs +1 -1
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +36 -14
- package/src/runtime/shared/background-tasks.mjs +60 -20
- package/src/runtime/shared/child-spawn-gate.mjs +26 -16
- package/src/runtime/shared/config.mjs +8 -11
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/file-lock.mjs +7 -1
- package/src/runtime/shared/file-permissions-worker.mjs +38 -0
- package/src/runtime/shared/file-permissions.d.mts +19 -4
- package/src/runtime/shared/file-permissions.mjs +310 -4
- package/src/runtime/shared/git-runner-worker.mjs +6 -78
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/llm/http-agent.mjs +7 -3
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
- package/src/runtime/shared/memory-snapshot.mjs +5 -1
- package/src/runtime/shared/notify-trace.mjs +8 -1
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -0
- package/src/runtime/shared/pristine-execution-contract.json +5 -1
- package/src/runtime/shared/process-runner-worker.mjs +7 -0
- package/src/runtime/shared/process-runner.mjs +38 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -1
- package/src/runtime/shared/provider-api-key.mjs +0 -1
- package/src/runtime/shared/read-row-numbers.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +60 -18
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/run-child.mjs +84 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/session-activity-signal.mjs +23 -0
- package/src/runtime/shared/shell-output-summary.mjs +23 -0
- package/src/runtime/shared/singleton-owner.mjs +126 -42
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +56 -0
- package/src/runtime/shared/user-data-guard.mjs +131 -34
- package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
- package/src/runtime/shared/worktrees/git-head.mjs +20 -2
- package/src/runtime/shared/worktrees/lock.mjs +3 -2
- package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
- package/src/runtime/tidy/runners/biome.mjs +3 -1
- package/src/runtime/tidy/shadow.mjs +2 -1
- package/src/runtime/web-search/index.mjs +5 -7
- package/src/runtime/web-search/lib/formatter.mjs +42 -6
- package/src/runtime/web-search/tool-defs.mjs +6 -1
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +25 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +5 -2
- package/src/session-runtime/lifecycle-api.mjs +3 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/set-route.mjs +14 -3
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/provider-auth/login.mjs +10 -6
- package/src/session-runtime/provider-auth/setup.mjs +19 -2
- package/src/session-runtime/provider-catalog-cache.mjs +101 -25
- package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
- package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
- package/src/session-runtime/provider-models.mjs +76 -10
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
- package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
- package/src/session-runtime/services/agent-tool.mjs +20 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +166 -59
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
- package/src/session-runtime/services/usage-dashboard.mjs +27 -69
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +238 -29
- package/src/session-runtime/turn/session-ops.mjs +10 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon-session-control.mjs +11 -2
- package/src/standalone/daemon.mjs +61 -17
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +28 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/standalone/session-transport/routes.mjs +7 -6
- package/src/tui/app/model-options.mjs +39 -2
- package/src/tui/app/model-picker.mjs +16 -2
- package/src/tui/app/provider-setup-picker.mjs +1 -2
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +487 -128
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -4
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +12 -13
- package/src/tui/session/session-api/integrations.mjs +9 -5
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +48 -3
- package/src/tui/session/session-flow/drain.mjs +20 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +104 -24
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +6 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +56 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +50 -7
- package/src/ui/statusline.mjs +1 -6
- package/src/ui/streaming-markdown-heal.mjs +24 -7
- package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
- package/src/workflows/default/WORKFLOW.md +9 -13
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
// In-process write lock for git work on one repository.
|
|
2
|
+
//
|
|
3
|
+
// Why it exists: Mixdog runs several sessions and sub-agents against one
|
|
4
|
+
// repository at once, and some of its own git work is a multi-step transaction
|
|
5
|
+
// that git's lock files cannot make atomic:
|
|
6
|
+
// - a managed worktree mutation (worktrees/lock.mjs: create, checkout,
|
|
7
|
+
// merge, remove, reconcile) inspects state, verifies it is clean or free,
|
|
8
|
+
// then mutates refs, worktrees and the registry; an agent commit, checkout
|
|
9
|
+
// or `worktree add` landing between the check and the mutation would be
|
|
10
|
+
// lost or contradict it;
|
|
11
|
+
// - `git action:stage` re-runs the diff, verifies it against the snapshot,
|
|
12
|
+
// then applies the selection to the index; another write to that index in
|
|
13
|
+
// between would stage a patch built from a stale view;
|
|
14
|
+
// - two writes to one worktree (checkout + commit) must not interleave.
|
|
15
|
+
// The previous repository-wide read/write lock covered these by making every
|
|
16
|
+
// git tool call, reads included, queue on one lock, so one long read
|
|
17
|
+
// (`git log -S`) held back a writer and that queued writer held back every
|
|
18
|
+
// later read in every worktree of the repository.
|
|
19
|
+
//
|
|
20
|
+
// Policy:
|
|
21
|
+
// - Reads take no lock. Git publishes the index and refs by atomic rename,
|
|
22
|
+
// so a read always sees a consistent index and ref state; the git tool runs
|
|
23
|
+
// reads with optional locks off, so `git status` never takes index.lock
|
|
24
|
+
// beside a write (`git diff` may still refresh it briefly, which the write
|
|
25
|
+
// retry absorbs). A read during a same-worktree write sees git's state at
|
|
26
|
+
// that instant, as any second terminal (or the shell tool) does.
|
|
27
|
+
// - A write names the worktrees it touches (the cwd's worktree, or the
|
|
28
|
+
// target paths of `worktree add/remove/move`). Writes conflict only when
|
|
29
|
+
// those sets intersect; a whole-repository write (managed mutations,
|
|
30
|
+
// object pruning, init/clone, an unresolved worktree target) conflicts
|
|
31
|
+
// with every write of the repository.
|
|
32
|
+
// - Fair FIFO without convoys: a waiting write is granted once it conflicts
|
|
33
|
+
// with no running write and no earlier waiting write. A later write never
|
|
34
|
+
// overtakes an earlier one it conflicts with, so no write starves; a later
|
|
35
|
+
// write that conflicts with nothing ahead of it runs at once.
|
|
36
|
+
// - Git's own lock files still guard index, refs and config against other
|
|
37
|
+
// processes; the git tool retries a write that git refused on one of them.
|
|
1
38
|
import { pathKey } from '../../../../shared/worktrees/paths.mjs';
|
|
2
39
|
|
|
3
40
|
const states = new Map();
|
|
@@ -10,52 +47,45 @@ export function gitRepoLockKey(repo) {
|
|
|
10
47
|
return pathKey(String(repo || '.'));
|
|
11
48
|
}
|
|
12
49
|
|
|
13
|
-
function keyFor(repo) {
|
|
14
|
-
return gitRepoLockKey(repo);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
50
|
function stateFor(key) {
|
|
18
51
|
let state = states.get(key);
|
|
19
52
|
if (!state) {
|
|
20
|
-
state = {
|
|
53
|
+
state = { running: new Set(), queue: [] };
|
|
21
54
|
states.set(key, state);
|
|
22
55
|
}
|
|
23
56
|
return state;
|
|
24
57
|
}
|
|
25
58
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
if (state.readers === 0) states.delete(key);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (state.readers === 0 && state.queue[0].mode === 'write') {
|
|
34
|
-
const entry = state.queue.shift();
|
|
35
|
-
state.writer = true;
|
|
36
|
-
entry.granted = true;
|
|
37
|
-
entry.signal?.removeEventListener?.('abort', entry.onAbort);
|
|
38
|
-
entry.resolve(releaseFor(key, state, 'write'));
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
while (state.queue[0]?.mode === 'read' && !state.writer) {
|
|
42
|
-
const entry = state.queue.shift();
|
|
43
|
-
state.readers++;
|
|
44
|
-
entry.granted = true;
|
|
45
|
-
entry.signal?.removeEventListener?.('abort', entry.onAbort);
|
|
46
|
-
entry.resolve(releaseFor(key, state, 'read'));
|
|
47
|
-
}
|
|
59
|
+
// `scopes` null is the whole repository.
|
|
60
|
+
function conflicts(left, right) {
|
|
61
|
+
if (!left.scopes || !right.scopes) return true;
|
|
62
|
+
return left.scopes.some((scope) => right.scopes.includes(scope));
|
|
48
63
|
}
|
|
49
64
|
|
|
50
|
-
function
|
|
65
|
+
function grant(key, state, entry) {
|
|
66
|
+
entry.granted = true;
|
|
67
|
+
entry.signal?.removeEventListener?.('abort', entry.onAbort);
|
|
68
|
+
state.running.add(entry);
|
|
51
69
|
let released = false;
|
|
52
|
-
|
|
70
|
+
entry.resolve(() => {
|
|
53
71
|
if (released) return;
|
|
54
72
|
released = true;
|
|
55
|
-
|
|
56
|
-
else state.readers = Math.max(0, state.readers - 1);
|
|
73
|
+
state.running.delete(entry);
|
|
57
74
|
drain(key, state);
|
|
58
|
-
};
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function drain(key, state) {
|
|
79
|
+
const waiting = [];
|
|
80
|
+
for (const entry of state.queue) {
|
|
81
|
+
const blocked =
|
|
82
|
+
[...state.running].some((running) => conflicts(running, entry)) ||
|
|
83
|
+
waiting.some((earlier) => conflicts(earlier, entry));
|
|
84
|
+
if (blocked) waiting.push(entry);
|
|
85
|
+
else grant(key, state, entry);
|
|
86
|
+
}
|
|
87
|
+
state.queue = waiting;
|
|
88
|
+
if (state.running.size === 0 && waiting.length === 0) states.delete(key);
|
|
59
89
|
}
|
|
60
90
|
|
|
61
91
|
function abortError(signal) {
|
|
@@ -63,12 +93,12 @@ function abortError(signal) {
|
|
|
63
93
|
return Object.assign(new Error('git repository lock aborted'), { name: 'AbortError', code: 'ABORT_ERR' });
|
|
64
94
|
}
|
|
65
95
|
|
|
66
|
-
function acquire(repo,
|
|
96
|
+
function acquire(repo, scopes, signal) {
|
|
67
97
|
if (signal?.aborted) return Promise.reject(abortError(signal));
|
|
68
|
-
const key =
|
|
98
|
+
const key = gitRepoLockKey(repo);
|
|
69
99
|
const state = stateFor(key);
|
|
70
100
|
return new Promise((resolveLock, rejectLock) => {
|
|
71
|
-
const entry = {
|
|
101
|
+
const entry = { scopes, resolve: resolveLock, signal, onAbort: null, granted: false };
|
|
72
102
|
entry.onAbort = () => {
|
|
73
103
|
if (entry.granted) return;
|
|
74
104
|
const index = state.queue.indexOf(entry);
|
|
@@ -83,9 +113,9 @@ function acquire(repo, mode, signal) {
|
|
|
83
113
|
});
|
|
84
114
|
}
|
|
85
115
|
|
|
86
|
-
async function withLock(repo,
|
|
116
|
+
async function withLock(repo, scopes, fn, options = {}) {
|
|
87
117
|
const signal = options?.signal || null;
|
|
88
|
-
const release = await acquire(repo,
|
|
118
|
+
const release = await acquire(repo, scopes, signal);
|
|
89
119
|
try {
|
|
90
120
|
if (signal?.aborted) throw abortError(signal);
|
|
91
121
|
return await fn();
|
|
@@ -94,10 +124,29 @@ async function withLock(repo, mode, fn, options = {}) {
|
|
|
94
124
|
}
|
|
95
125
|
}
|
|
96
126
|
|
|
97
|
-
|
|
98
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Run `fn` holding the write lock of the whole repository.
|
|
129
|
+
* @template T
|
|
130
|
+
* @param {string} repo canonical common git dir (or the path being created)
|
|
131
|
+
* @param {() => Promise<T>|T} fn
|
|
132
|
+
* @param {{ signal?: AbortSignal }} [options]
|
|
133
|
+
* @returns {Promise<T>}
|
|
134
|
+
*/
|
|
135
|
+
export function withGitRepoWriteLock(repo, fn, options = {}) {
|
|
136
|
+
return withLock(repo, null, fn, options);
|
|
99
137
|
}
|
|
100
138
|
|
|
101
|
-
|
|
102
|
-
|
|
139
|
+
/**
|
|
140
|
+
* Run `fn` holding the write lock of the named worktrees only; no (or no
|
|
141
|
+
* non-empty) worktree list holds the whole repository.
|
|
142
|
+
* @template T
|
|
143
|
+
* @param {string} repo canonical common git dir
|
|
144
|
+
* @param {string[]|null} worktrees worktree roots (or target paths) the write touches
|
|
145
|
+
* @param {() => Promise<T>|T} fn
|
|
146
|
+
* @param {{ signal?: AbortSignal }} [options]
|
|
147
|
+
* @returns {Promise<T>}
|
|
148
|
+
*/
|
|
149
|
+
export function withGitWorktreeWriteLock(repo, worktrees, fn, options = {}) {
|
|
150
|
+
const scopes = [...new Set((worktrees || []).filter(Boolean).map((path) => gitRepoLockKey(path)))];
|
|
151
|
+
return withLock(repo, scopes.length ? scopes : null, fn, options);
|
|
103
152
|
}
|
|
@@ -4,6 +4,7 @@ import { normalizeErrorMessage } from '../path-diagnostics.mjs';
|
|
|
4
4
|
import { isBinaryBuffer } from '../binary-file.mjs';
|
|
5
5
|
import { isUncPath, isWindowsDevicePath, hasUnsafeWin32Component } from '../device-paths.mjs';
|
|
6
6
|
import { normalizeOutputPath, resolveAgainstCwd } from '../path-utils.mjs';
|
|
7
|
+
import { windowMarker } from '../tool-output-limit.mjs';
|
|
7
8
|
|
|
8
9
|
/** Report the requested path's result; suggestions never retarget the operation. */
|
|
9
10
|
export async function readFamilyPathEnoentOrError(workDir, fullPath, inputPath, err) {
|
|
@@ -52,8 +53,23 @@ export function guardedWalkRoot(inputPath, workDir) {
|
|
|
52
53
|
return { fullPath };
|
|
53
54
|
}
|
|
54
55
|
|
|
56
|
+
// Code-unit path order: the tiebreak that makes a size/mtime sort total, so
|
|
57
|
+
// equal keys cannot reorder with the walk (and shift across offset pages).
|
|
58
|
+
export function comparePathsStable(a, b) {
|
|
59
|
+
const x = String(a);
|
|
60
|
+
const y = String(b);
|
|
61
|
+
if (x === y) return 0;
|
|
62
|
+
return x < y ? -1 : 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
55
65
|
export function pageContinuationLine(offset, shown, total) {
|
|
56
|
-
return
|
|
66
|
+
return windowMarker({
|
|
67
|
+
unit: 'entries',
|
|
68
|
+
from: offset + 1,
|
|
69
|
+
to: offset + shown,
|
|
70
|
+
total,
|
|
71
|
+
nextOffset: offset + shown,
|
|
72
|
+
});
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
const LINE_COUNT_MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// One shape for every piece of shell output handed to an agent — a foreground
|
|
2
|
+
// result, a background move, task wait/read and a completion notice:
|
|
3
|
+
// 1. ANSI stripped, then `\r` progress frames folded to their last frame
|
|
4
|
+
// (before anything is counted or cut);
|
|
5
|
+
// 2. a line longer than DELIVERY_LINE_MAX_CHARS is cut: `… [N chars cut]`;
|
|
6
|
+
// 3. DELIVERY_FULL_CHARS or less goes whole; otherwise a head of at most
|
|
7
|
+
// DELIVERY_HEAD_LINES lines (≤ DELIVERY_HEAD_MAX_CHARS), the marker, and
|
|
8
|
+
// the last ~DELIVERY_TAIL_CHARS;
|
|
9
|
+
// 4. the marker is the same everywhere and always ends with the full log:
|
|
10
|
+
// `[… N lines, X KB omitted — read with offset/limit or grep, full log: <path>]`;
|
|
11
|
+
// 5. anything shaped like a harness/system tag is escaped.
|
|
12
|
+
// MIXDOG_SHELL_DELIVERY_MAX_CHARS is the one knob (the whole-delivery cap); the
|
|
13
|
+
// head and tail sizes are fixed. It is separate from the 50 KB
|
|
14
|
+
// MIXDOG_TOOL_OUTPUT_MAX_BYTES that the other tools use.
|
|
15
|
+
import { randomBytes } from 'node:crypto';
|
|
16
|
+
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { getPluginData } from '../../../config.mjs';
|
|
19
|
+
import { stripAnsi } from '../../shell-exec-output.mjs';
|
|
20
|
+
import { createCarriageReturnFolder } from '../shell-lossless-compact.mjs';
|
|
21
|
+
import { positiveEnvInt } from '../../../../../shared/tool-output-limit.mjs';
|
|
22
|
+
import { escapeHarnessTags } from '../../../../../shared/shell-output-summary.mjs';
|
|
23
|
+
|
|
24
|
+
export const DELIVERY_FULL_CHARS = positiveEnvInt('MIXDOG_SHELL_DELIVERY_MAX_CHARS', 6_000);
|
|
25
|
+
const DELIVERY_HEAD_LINES = 10;
|
|
26
|
+
const DELIVERY_HEAD_MAX_CHARS = 1_000;
|
|
27
|
+
const DELIVERY_TAIL_CHARS = 2_000;
|
|
28
|
+
export const DELIVERY_LINE_MAX_CHARS = 2_000;
|
|
29
|
+
|
|
30
|
+
export { createCarriageReturnFolder };
|
|
31
|
+
|
|
32
|
+
const newlines = (text) => {
|
|
33
|
+
let count = 0;
|
|
34
|
+
for (let i = text.indexOf('\n'); i >= 0; i = text.indexOf('\n', i + 1)) count += 1;
|
|
35
|
+
return count;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export function formatKb(bytes) {
|
|
39
|
+
return `${(Math.max(0, bytes) / 1024).toFixed(1)} KB`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The omission marker — identical on every delivery path, path last. */
|
|
43
|
+
export function omissionMarker({ lines, bytes, path }) {
|
|
44
|
+
return `[… ${lines} lines, ${formatKb(bytes)} omitted — read with offset/limit or grep, full log: ${path}]`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// `cut` is the number of chars removed from over-long lines.
|
|
48
|
+
function cutLongLines(text) {
|
|
49
|
+
if (text.length <= DELIVERY_LINE_MAX_CHARS) return { text, cut: 0 };
|
|
50
|
+
let cut = 0;
|
|
51
|
+
const cutText = text
|
|
52
|
+
.split('\n')
|
|
53
|
+
.map((line) => {
|
|
54
|
+
if (line.length <= DELIVERY_LINE_MAX_CHARS) return line;
|
|
55
|
+
cut += line.length - DELIVERY_LINE_MAX_CHARS;
|
|
56
|
+
return `${line.slice(0, DELIVERY_LINE_MAX_CHARS)} … [${line.length - DELIVERY_LINE_MAX_CHARS} chars cut]`;
|
|
57
|
+
})
|
|
58
|
+
.join('\n');
|
|
59
|
+
return { text: cutText, cut };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Step 1 for one chunk (the cut of step 2 is made where the text is
|
|
63
|
+
* delivered, so the uncut text can be archived). `fold` carries `\r` state
|
|
64
|
+
* across chunks of the same stream; omitted, the chunk is folded on its own. */
|
|
65
|
+
export function prepareShellText(text, fold = createCarriageReturnFolder()) {
|
|
66
|
+
return fold(stripAnsi(String(text ?? '')));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// `scale` is the share of the delivery budget a stream was given.
|
|
70
|
+
function headOf(text, scale = 1) {
|
|
71
|
+
let end = 0;
|
|
72
|
+
for (let line = 0; line < DELIVERY_HEAD_LINES && end < text.length; line += 1) {
|
|
73
|
+
const newline = text.indexOf('\n', end);
|
|
74
|
+
end = newline < 0 ? text.length : newline + 1;
|
|
75
|
+
}
|
|
76
|
+
return text.slice(0, Math.min(end, Math.floor(DELIVERY_HEAD_MAX_CHARS * scale)));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function tailOf(text, floor = 0, scale = 1) {
|
|
80
|
+
const start = Math.max(floor, text.length - Math.floor(DELIVERY_TAIL_CHARS * scale));
|
|
81
|
+
if (start === floor) return text.slice(start);
|
|
82
|
+
// Start on a line boundary when one is near.
|
|
83
|
+
const newline = text.indexOf('\n', start);
|
|
84
|
+
return newline >= 0 && newline - start < 200 && newline + 1 < text.length
|
|
85
|
+
? text.slice(newline + 1)
|
|
86
|
+
: text.slice(start);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** head + marker + tail; `omitted` counts what lies between them. */
|
|
90
|
+
function joinHeadTail(head, tail, omitted) {
|
|
91
|
+
const gap = head && !head.endsWith('\n') ? '\n' : '';
|
|
92
|
+
return `${head}${gap}${omissionMarker(omitted)}\n${tail}`;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// One stream's delivery: `natural` is the length it would have whole (escaped,
|
|
96
|
+
// markers included; Infinity when it can only be shown at its ends) and
|
|
97
|
+
// `render(budget)` the text within `budget` chars. Streams share one budget.
|
|
98
|
+
export const EMPTY_PIECE = { natural: 0, render: () => '' };
|
|
99
|
+
|
|
100
|
+
/** Step 3 when only the two ends of a long range were read: `total` is the
|
|
101
|
+
* whole range's bytes and lines. */
|
|
102
|
+
export function edgesPiece(headText, tailText, { totalBytes, totalLines, path }) {
|
|
103
|
+
return {
|
|
104
|
+
natural: Number.POSITIVE_INFINITY,
|
|
105
|
+
render: (budget) => {
|
|
106
|
+
const scale = budget / DELIVERY_FULL_CHARS;
|
|
107
|
+
const head = headOf(escapeHarnessTags(headText), scale);
|
|
108
|
+
const tail = tailOf(escapeHarnessTags(tailText), 0, scale);
|
|
109
|
+
return joinHeadTail(head, tail, {
|
|
110
|
+
lines: Math.max(0, totalLines - newlines(head) - newlines(tail)),
|
|
111
|
+
bytes: Math.max(0, totalBytes - Buffer.byteLength(head) - Buffer.byteLength(tail)),
|
|
112
|
+
path,
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export { newlines as countNewlines };
|
|
119
|
+
|
|
120
|
+
/** Steps 2, 3 and 5 on prepared text. `path` names where the whole (uncut)
|
|
121
|
+
* text can be read; it is resolved only when something is removed. */
|
|
122
|
+
export function textPiece(text, { path }) {
|
|
123
|
+
let archive;
|
|
124
|
+
const where = () => (archive ??= typeof path === 'function' ? path() : path);
|
|
125
|
+
const { text: cutText, cut } = cutLongLines(text);
|
|
126
|
+
const shown = escapeHarnessTags(cutText);
|
|
127
|
+
// Cut long lines are removed content too: the whole text carries the marker.
|
|
128
|
+
const whole = cut
|
|
129
|
+
? `${shown}${shown.endsWith('\n') ? '' : '\n'}${omissionMarker({ lines: 0, bytes: cut, path: where() })}\n`
|
|
130
|
+
: shown;
|
|
131
|
+
return {
|
|
132
|
+
natural: whole.length,
|
|
133
|
+
render: (budget) => {
|
|
134
|
+
if (whole.length <= budget) return whole;
|
|
135
|
+
const scale = budget / DELIVERY_FULL_CHARS;
|
|
136
|
+
const head = headOf(shown, scale);
|
|
137
|
+
const tail = tailOf(shown, head.length, scale);
|
|
138
|
+
const middle = shown.slice(head.length, shown.length - tail.length);
|
|
139
|
+
return joinHeadTail(head, tail, { lines: newlines(middle), bytes: Buffer.byteLength(middle), path: where() });
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Max-min fair split of `budget` over the streams' natural lengths: a stream
|
|
145
|
+
* that fits its fair share is given exactly what it needs, the rest share
|
|
146
|
+
* what remains. */
|
|
147
|
+
function shareBudget(lengths, budget) {
|
|
148
|
+
const shares = lengths.map(() => 0);
|
|
149
|
+
let open = lengths.map((_, index) => index);
|
|
150
|
+
let left = Math.max(0, budget);
|
|
151
|
+
while (open.length) {
|
|
152
|
+
const fair = left / open.length;
|
|
153
|
+
const fits = open.filter((index) => lengths[index] <= fair);
|
|
154
|
+
if (!fits.length) {
|
|
155
|
+
for (const index of open) shares[index] = fair;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
for (const index of fits) {
|
|
159
|
+
shares[index] = lengths[index];
|
|
160
|
+
left -= lengths[index];
|
|
161
|
+
}
|
|
162
|
+
open = open.filter((index) => !fits.includes(index));
|
|
163
|
+
}
|
|
164
|
+
return shares;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Deliver streams within one shared budget (default: the whole-delivery cap),
|
|
168
|
+
* each escaped; the caller deducts what it adds around them. */
|
|
169
|
+
export function fitPieces(pieces, budget = DELIVERY_FULL_CHARS) {
|
|
170
|
+
const shares = shareBudget(
|
|
171
|
+
pieces.map((piece) => piece.natural),
|
|
172
|
+
budget
|
|
173
|
+
);
|
|
174
|
+
return pieces.map((piece, index) => escapeHarnessTags(piece.render(shares[index])));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Text that has no log of its own is kept where the marker can name it:
|
|
178
|
+
* the shell-output folder, swept with the spill files. */
|
|
179
|
+
export function persistDeliveryLog(text, label = 'output') {
|
|
180
|
+
const dir = join(getPluginData(), 'shell-output');
|
|
181
|
+
mkdirSync(dir, { recursive: true });
|
|
182
|
+
const file = join(dir, `delivered_${Date.now().toString(36)}_${randomBytes(4).toString('hex')}.${label}`);
|
|
183
|
+
writeFileSync(file, text);
|
|
184
|
+
return file;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/** Steps 1–5 for a whole string, as a piece. Without `path`, the original
|
|
188
|
+
* (uncut) text is saved when anything is removed, so the marker can name it. */
|
|
189
|
+
export function shellTextPiece(text, { path = null, label = 'output', fold } = {}) {
|
|
190
|
+
const prepared = prepareShellText(text, fold);
|
|
191
|
+
return textPiece(prepared, { path: path || (() => persistDeliveryLog(prepared, label)) });
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function deliverShellText(text, options) {
|
|
195
|
+
return fitPieces([shellTextPiece(text, options)])[0];
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Step 5 alone, for text the caller already capped. */
|
|
199
|
+
export { escapeHarnessTags };
|
|
@@ -339,11 +339,23 @@ export function releaseShellJobWorkspace(jobId) {
|
|
|
339
339
|
if (workspaceLeases.get(key) === leave) workspaceLeases.delete(key);
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
/** True once `sessionId` closed in this runtime. */
|
|
343
|
+
export function isShellOwnerSessionClosed(sessionId) {
|
|
344
|
+
return closedOwnerSessions.has(String(sessionId || '').trim());
|
|
345
|
+
}
|
|
346
|
+
|
|
342
347
|
/** Flag a still-open job record as "termination unconfirmed" for the readouts. */
|
|
343
348
|
export function markShellJobTerminationUnconfirmed(jobId) {
|
|
344
349
|
return patchRunningShellJobRecord(jobId, { terminationUnconfirmed: true });
|
|
345
350
|
}
|
|
346
351
|
|
|
352
|
+
/** Record the pids a held job's termination watch last found alive, so a
|
|
353
|
+
* reader in another process can tell a live hold from a stale one. */
|
|
354
|
+
export function noteShellJobSurvivors(jobId, pids) {
|
|
355
|
+
const survivorPids = (pids || []).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0);
|
|
356
|
+
return patchRunningShellJobRecord(jobId, { survivorPids });
|
|
357
|
+
}
|
|
358
|
+
|
|
347
359
|
function patchRunningShellJobRecord(jobId, patch) {
|
|
348
360
|
const key = validJobId(jobId);
|
|
349
361
|
if (!key) return Promise.resolve(false);
|