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
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// session-activity-signal.mjs
|
|
2
|
+
// Process-local "a session's activity state may have changed" pulse: a turn
|
|
3
|
+
// started or settled, a task wait began or ended, a background task was
|
|
4
|
+
// handed off or finished. Status surfaces that project activity from the
|
|
5
|
+
// runtime map (the Agents pool) listen and re-read at once instead of waiting
|
|
6
|
+
// for their next store event. Import-free leaf.
|
|
7
|
+
const listeners = new Set();
|
|
8
|
+
|
|
9
|
+
export function onSessionActivityChange(listener) {
|
|
10
|
+
if (typeof listener !== 'function') return () => {};
|
|
11
|
+
listeners.add(listener);
|
|
12
|
+
return () => listeners.delete(listener);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function emitSessionActivityChange(sessionId = '') {
|
|
16
|
+
for (const listener of [...listeners]) {
|
|
17
|
+
try {
|
|
18
|
+
listener(String(sessionId || ''));
|
|
19
|
+
} catch {
|
|
20
|
+
/* a listener's failure never affects the transition */
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Formatting shared by every surface that hands shell output to an agent.
|
|
2
|
+
// Program output is untrusted text: anything shaped like a harness/system tag
|
|
3
|
+
// is escaped so it can never forge a notice, a result boundary or a reminder.
|
|
4
|
+
// (Capping lives in tools/builtin/lib/shell-delivery.mjs, per-job cursors in
|
|
5
|
+
// tools/builtin/lib/shell-task-output.mjs.)
|
|
6
|
+
|
|
7
|
+
// A tag-looking token: `<name`, `</name`, where the name is a known
|
|
8
|
+
// harness/system/transcript word or any hyphenated/underscored/namespaced
|
|
9
|
+
// name (task-notification, system-reminder, tool_result, ns:tag ...). Plain
|
|
10
|
+
// HTML-ish words like <div> or a comparison `a<b` stay readable.
|
|
11
|
+
const HARNESS_TAG =
|
|
12
|
+
/<(\/?)(?=(?:[a-z][\w]*[-_:][\w:-]*|system|result|results|summary|status|error|user|assistant|human|tool|function|functions|instructions|context|notification|reminder|output|invoke|parameter|thinking)\b)/gi;
|
|
13
|
+
|
|
14
|
+
export function escapeHarnessTags(text) {
|
|
15
|
+
return String(text ?? '').replace(HARNESS_TAG, '<$1');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function formatDuration(ms) {
|
|
19
|
+
if (!(ms >= 0)) return '';
|
|
20
|
+
if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;
|
|
21
|
+
const minutes = Math.floor(ms / 60_000);
|
|
22
|
+
return `${minutes}m ${Math.round((ms % 60_000) / 1000)}s`;
|
|
23
|
+
}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
import { mkdirSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { mkdirSync, renameSync, rmdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { readFile, rename, rm, rmdir, stat, writeFile } from 'node:fs/promises';
|
|
2
3
|
import { dirname } from 'node:path';
|
|
4
|
+
import { withFileLock, withFileLockSync } from './file-lock.mjs';
|
|
3
5
|
import { readJsonSafe } from './json-file.mjs';
|
|
4
6
|
import { isPidAlive } from './pid-liveness.mjs';
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
// Claim-lock protocol shared by the sync and async paths: `<path>.claim.lock`
|
|
9
|
+
// is a file-lock.mjs lock, published atomically with its holder's pid and
|
|
10
|
+
// token. A holder whose pid is alive is waited out however long it holds the
|
|
11
|
+
// lock — a holder stalled mid-refresh still owns it: reclaiming it on age let
|
|
12
|
+
// a successor claim the record and the stalled refresh then overwrite it. Its
|
|
13
|
+
// lock is reclaimed only once that pid is dead, and only the holder's own
|
|
14
|
+
// acquisition (pid + token) is ever released. A lock naming no holder — the
|
|
15
|
+
// bare directory versions before this one took the lock with — is reclaimed
|
|
16
|
+
// once older than CLAIM_LOCK_STALE_MS, as those versions did.
|
|
17
|
+
const CLAIM_LOCK_TIMEOUT_MS = 500;
|
|
18
|
+
const CLAIM_LOCK_STALE_MS = 5000;
|
|
19
|
+
const CLAIM_LOCK_OPTS = Object.freeze({ timeoutMs: CLAIM_LOCK_TIMEOUT_MS, staleMs: CLAIM_LOCK_STALE_MS });
|
|
20
|
+
const BUSY = Symbol('claim lock busy');
|
|
6
21
|
|
|
7
22
|
function writeJsonAtomic(path, value) {
|
|
8
23
|
mkdirSync(dirname(path), { recursive: true });
|
|
@@ -11,28 +26,82 @@ function writeJsonAtomic(path, value) {
|
|
|
11
26
|
renameSync(tmp, path);
|
|
12
27
|
}
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
// Held by another live process or this one's async holder ('busy'). Any other
|
|
30
|
+
// failure (an unwritable data directory) is thrown, as before.
|
|
31
|
+
function claimLockHeld(error) {
|
|
32
|
+
return error?.code === 'ELOCKCONTENDED' || (error?.code === 'ELOCKTIMEOUT' && error.cause?.code === 'EEXIST');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function legacyLockStale(info) {
|
|
36
|
+
return info.isDirectory() && Date.now() - info.mtimeMs > CLAIM_LOCK_STALE_MS;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// An older version's stale bare lock directory is removed with rmdir alone,
|
|
40
|
+
// never recursive or forced: between the stat and the removal a contender may
|
|
41
|
+
// have replaced it with a live owner-named lock file. rmdir refuses a file
|
|
42
|
+
// (ENOENT on Windows, ENOTDIR elsewhere) and a non-empty directory
|
|
43
|
+
// (ENOTEMPTY); a missing path (ENOENT) is already gone. Any refusal (EPERM
|
|
44
|
+
// included) leaves the path untouched to the shared acquire loop below, which
|
|
45
|
+
// waits a live holder out and reclaims only a dead one's lock.
|
|
46
|
+
|
|
47
|
+
// `fn()` under the claim lock, or BUSY. file-lock creates a missing data
|
|
48
|
+
// directory (a first boot, e.g. a daemon an ssh bootstrap starts on a fresh
|
|
49
|
+
// server).
|
|
50
|
+
function withClaimLockSync(path, fn) {
|
|
15
51
|
const lockPath = `${path}.claim.lock`;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
52
|
+
try {
|
|
53
|
+
if (legacyLockStale(statSync(lockPath))) rmdirSync(lockPath);
|
|
54
|
+
} catch {}
|
|
55
|
+
let entered = false;
|
|
56
|
+
try {
|
|
57
|
+
return withFileLockSync(
|
|
58
|
+
lockPath,
|
|
59
|
+
() => {
|
|
60
|
+
entered = true;
|
|
61
|
+
return fn();
|
|
62
|
+
},
|
|
63
|
+
CLAIM_LOCK_OPTS
|
|
64
|
+
);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (!entered && claimLockHeld(error)) return BUSY;
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The same lock taken without blocking the event loop: every file operation
|
|
72
|
+
// and every retry wait is awaited (a synchronous refresh once held the
|
|
73
|
+
// daemon's loop for 20 s in one rmSync under disk contention).
|
|
74
|
+
async function withClaimLock(path, fn) {
|
|
75
|
+
const lockPath = `${path}.claim.lock`;
|
|
76
|
+
try {
|
|
77
|
+
if (legacyLockStale(await stat(lockPath))) await rmdir(lockPath);
|
|
78
|
+
} catch {}
|
|
79
|
+
let entered = false;
|
|
80
|
+
try {
|
|
81
|
+
return await withFileLock(
|
|
82
|
+
lockPath,
|
|
83
|
+
() => {
|
|
84
|
+
entered = true;
|
|
85
|
+
return fn();
|
|
86
|
+
},
|
|
87
|
+
CLAIM_LOCK_OPTS
|
|
88
|
+
);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (!entered && claimLockHeld(error)) return BUSY;
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function namesOtherPid(record, pid) {
|
|
96
|
+
return Boolean(record?.pid) && Number(record.pid) !== Number(pid);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function readJsonSafeAsync(path) {
|
|
100
|
+
try {
|
|
101
|
+
return JSON.parse(await readFile(path, 'utf8'));
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
34
104
|
}
|
|
35
|
-
return null;
|
|
36
105
|
}
|
|
37
106
|
|
|
38
107
|
// A live pid alone does not prove the record's process still owns it: the OS
|
|
@@ -64,18 +133,15 @@ export function claimSingletonOwner(path, { kind = 'runtime', pid = process.pid,
|
|
|
64
133
|
return { owned: false, owner: current };
|
|
65
134
|
}
|
|
66
135
|
|
|
67
|
-
const
|
|
68
|
-
if (!lockPath) return { owned: false, owner: readJsonSafe(path) };
|
|
69
|
-
try {
|
|
136
|
+
const result = withClaimLockSync(path, () => {
|
|
70
137
|
const lockedCurrent = readJsonSafe(path);
|
|
71
138
|
if (livePeer(lockedCurrent)) {
|
|
72
139
|
return { owned: false, owner: lockedCurrent };
|
|
73
140
|
}
|
|
74
141
|
writeJsonAtomic(path, owner);
|
|
75
142
|
return { owned: true, owner };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
}
|
|
143
|
+
});
|
|
144
|
+
return result === BUSY ? { owned: false, owner: readJsonSafe(path) } : result;
|
|
79
145
|
}
|
|
80
146
|
|
|
81
147
|
export function releaseSingletonOwner(path, pid = process.pid) {
|
|
@@ -94,16 +160,37 @@ export function releaseSingletonOwner(path, pid = process.pid) {
|
|
|
94
160
|
// naming another pid is reported, never overwritten ('superseded'); a claim
|
|
95
161
|
// lock held past its wait leaves the record alone ('busy').
|
|
96
162
|
export function refreshSingletonOwner(path, owner) {
|
|
97
|
-
const
|
|
98
|
-
if (!lockPath) return { status: 'busy', owner: null };
|
|
99
|
-
try {
|
|
163
|
+
const result = withClaimLockSync(path, () => {
|
|
100
164
|
const current = readJsonSafe(path);
|
|
101
|
-
if (
|
|
165
|
+
if (namesOtherPid(current, owner.pid)) return { status: 'superseded', owner: current };
|
|
102
166
|
writeJsonAtomic(path, owner);
|
|
103
167
|
return { status: 'refreshed', owner };
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
168
|
+
});
|
|
169
|
+
return result === BUSY ? { status: 'busy', owner: null } : result;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** refreshSingletonOwner without blocking the event loop: the same claim
|
|
173
|
+
* lock (mutually exclusive with the sync claim/refresh/handoff), the same
|
|
174
|
+
* verdicts, every file operation and retry wait awaited. Its awaited write
|
|
175
|
+
* may stall, so the record is read again right before it is replaced: a
|
|
176
|
+
* record another pid wrote meanwhile is reported, never overwritten. */
|
|
177
|
+
export async function refreshSingletonOwnerAsync(path, owner) {
|
|
178
|
+
const result = await withClaimLock(path, async () => {
|
|
179
|
+
const current = await readJsonSafeAsync(path);
|
|
180
|
+
if (namesOtherPid(current, owner.pid)) return { status: 'superseded', owner: current };
|
|
181
|
+
let tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
182
|
+
try {
|
|
183
|
+
await writeFile(tmp, `${JSON.stringify(owner, null, 2)}\n`);
|
|
184
|
+
const latest = await readJsonSafeAsync(path);
|
|
185
|
+
if (namesOtherPid(latest, owner.pid)) return { status: 'superseded', owner: latest };
|
|
186
|
+
await rename(tmp, path);
|
|
187
|
+
tmp = null;
|
|
188
|
+
return { status: 'refreshed', owner };
|
|
189
|
+
} finally {
|
|
190
|
+
if (tmp) await rm(tmp, { force: true }).catch(() => {});
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return result === BUSY ? { status: 'busy', owner: null } : result;
|
|
107
194
|
}
|
|
108
195
|
|
|
109
196
|
// Atomic ownership handoff: replace the owner record from fromPid to toOwner
|
|
@@ -113,11 +200,9 @@ export function refreshSingletonOwner(path, owner) {
|
|
|
113
200
|
// (someone else won), the handoff is refused (owned:false) and the caller
|
|
114
201
|
// should fall back to the winner rather than overwrite it.
|
|
115
202
|
export function handoffSingletonOwner(path, fromPid, toOwner = {}) {
|
|
116
|
-
const
|
|
117
|
-
if (!lockPath) return { owned: false, owner: readJsonSafe(path) };
|
|
118
|
-
try {
|
|
203
|
+
const result = withClaimLockSync(path, () => {
|
|
119
204
|
const current = readJsonSafe(path);
|
|
120
|
-
if (
|
|
205
|
+
if (namesOtherPid(current, fromPid)) {
|
|
121
206
|
return { owned: false, owner: current };
|
|
122
207
|
}
|
|
123
208
|
const owner = {
|
|
@@ -127,7 +212,6 @@ export function handoffSingletonOwner(path, fromPid, toOwner = {}) {
|
|
|
127
212
|
};
|
|
128
213
|
writeJsonAtomic(path, owner);
|
|
129
214
|
return { owned: true, owner };
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
}
|
|
215
|
+
});
|
|
216
|
+
return result === BUSY ? { owned: false, owner: readJsonSafe(path) } : result;
|
|
133
217
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// monotonic clock the owner heartbeat uses (performance.now), completed spans
|
|
4
4
|
// over `minMs` land in a bounded ring, and spans over `slowMs` are logged as
|
|
5
5
|
// `[slow-op] <label> <ms>`. When the event loop stalls, `describe(from, to)`
|
|
6
|
-
// names the spans that overlapped the stall window. Spans carry labels
|
|
7
|
-
// durations
|
|
6
|
+
// names the spans that overlapped the stall window. Spans carry labels and
|
|
7
|
+
// phase durations only — never payloads.
|
|
8
8
|
|
|
9
9
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
10
10
|
import { performance } from 'node:perf_hooks';
|
|
@@ -36,18 +36,11 @@ export function markPhase(name) {
|
|
|
36
36
|
span.mark = t;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/** Records a size (count/bytes) on the caller's span. */
|
|
40
|
-
export function noteSpanSize(size) {
|
|
41
|
-
const span = current.getStore();
|
|
42
|
-
if (span && Number.isFinite(size)) span.size = size;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
39
|
const round = (ms) => Math.round(ms);
|
|
46
40
|
|
|
47
41
|
function formatSpan(span) {
|
|
48
42
|
const phases = span.phases.map(([name, ms]) => `${name}=${round(ms)}`).join(' ');
|
|
49
|
-
|
|
50
|
-
return `${span.label} ${round(span.ms)}ms${phases ? ` ${phases}` : ''}${size}`;
|
|
43
|
+
return `${span.label} ${round(span.ms)}ms${phases ? ` ${phases}` : ''}`;
|
|
51
44
|
}
|
|
52
45
|
|
|
53
46
|
export function createSlowSpans({
|
|
@@ -70,7 +63,6 @@ export function createSlowSpans({
|
|
|
70
63
|
end: span.end,
|
|
71
64
|
ms: span.ms,
|
|
72
65
|
phases: span.phases,
|
|
73
|
-
size: span.size,
|
|
74
66
|
});
|
|
75
67
|
if (ring.length > capacity) ring.shift();
|
|
76
68
|
}
|
|
@@ -90,7 +82,7 @@ export function createSlowSpans({
|
|
|
90
82
|
/** Runs `fn` inside a span; markPhase/annotateSpan inside it attach to this span. */
|
|
91
83
|
async trace(label, fn) {
|
|
92
84
|
const start = now();
|
|
93
|
-
const span = { label: String(label), start, mark: start, now, phases: []
|
|
85
|
+
const span = { label: String(label), start, mark: start, now, phases: [] };
|
|
94
86
|
try {
|
|
95
87
|
return await current.run(span, fn);
|
|
96
88
|
} finally {
|
|
@@ -200,7 +200,8 @@ async function refreshShellJobsStatus(ownerPid) {
|
|
|
200
200
|
// its owner retires the record. Its root pid may be gone while a
|
|
201
201
|
// descendant lives, so the owner's liveness decides, not the root's.
|
|
202
202
|
const unconfirmed = detail?.terminationUnconfirmed === true;
|
|
203
|
-
if (unconfirmed ? !
|
|
203
|
+
if (unconfirmed ? !isHeldShellJobAlive(detail, ownerByJob.get(id)) : !(await isShellJobAlive(detail, p, dir, id)))
|
|
204
|
+
continue;
|
|
204
205
|
// A foreground command is awaited in its own tool card; listing it here
|
|
205
206
|
// made every short command flash in and out of the shell list. Only
|
|
206
207
|
// backgrounded jobs (including promoted ones) are background work.
|
|
@@ -326,6 +327,17 @@ function summarizeShellJobs({ count, oldestMs, jobs, bySession }) {
|
|
|
326
327
|
return { count, elapsedLabel, jobs, sessions };
|
|
327
328
|
}
|
|
328
329
|
|
|
330
|
+
// A held record lives while its owner process does. Once its owner session
|
|
331
|
+
// has closed, it also needs a process left to hold: the root or a survivor
|
|
332
|
+
// its termination watch last reported. Without one it is an orphan whose
|
|
333
|
+
// processes are gone, and it resolves instead of staying unconfirmed.
|
|
334
|
+
function isHeldShellJobAlive(detail, ownerPid) {
|
|
335
|
+
if (!isPidAlive(ownerPid || 0)) return false;
|
|
336
|
+
if (detail?.ownerSessionClosed !== true) return true;
|
|
337
|
+
const survivors = Array.isArray(detail?.survivorPids) ? detail.survivorPids : [];
|
|
338
|
+
return [detail?.pid, ...survivors].some((pid) => isPidAlive(positiveInt(pid)));
|
|
339
|
+
}
|
|
340
|
+
|
|
329
341
|
async function isShellJobAlive(detail, detailPath, dir, id) {
|
|
330
342
|
const pid = positiveInt(detail?.pid);
|
|
331
343
|
if (!pid) return false;
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// context cost of any one tool call is bounded and consistent. Override with
|
|
4
4
|
// MIXDOG_TOOL_OUTPUT_MAX_BYTES. Line-based sub-caps (e.g. bash max lines) stay
|
|
5
5
|
// per-tool; this governs only the byte budget.
|
|
6
|
+
import { capMarker } from './tool-output-marker.mjs';
|
|
7
|
+
export { capMarker, formatCapSize, windowMarker } from './tool-output-marker.mjs';
|
|
6
8
|
// A positive integer from an env var, or `fallback` when unset or invalid.
|
|
7
9
|
export function positiveEnvInt(name, fallback) {
|
|
8
10
|
const v = parseInt(process.env[name], 10);
|
|
@@ -53,7 +55,7 @@ export function capLineOrientedToolOutput(result, maxBytes, footerForPrefix) {
|
|
|
53
55
|
while (lo <= hi) {
|
|
54
56
|
const mid = Math.floor((lo + hi) / 2);
|
|
55
57
|
const kept = lines.slice(0, mid);
|
|
56
|
-
const footer = String(footerForPrefix?.(kept, lines) ||
|
|
58
|
+
const footer = String(footerForPrefix?.(kept, lines) || capMarker({ limit: cap }));
|
|
57
59
|
const candidate = `${kept.join('\n')}${kept.length ? '\n' : ''}${footer}`;
|
|
58
60
|
if (Buffer.byteLength(candidate, 'utf8') <= cap) {
|
|
59
61
|
best = candidate;
|
|
@@ -63,5 +65,5 @@ export function capLineOrientedToolOutput(result, maxBytes, footerForPrefix) {
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
if (best) return best;
|
|
66
|
-
return _prefixByBytes(String(footerForPrefix?.([], lines) ||
|
|
68
|
+
return _prefixByBytes(String(footerForPrefix?.([], lines) || capMarker({ limit: cap })), cap);
|
|
67
69
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// One marker vocabulary for every non-shell tool output that is not the whole
|
|
2
|
+
// answer. Two shapes, never mixed:
|
|
3
|
+
// window `[lines a-b of N; offset:N for more]` the agent asked for this slice
|
|
4
|
+
// cap `[output capped at X KB; …; offset:N for more]` the tool cut it
|
|
5
|
+
// A cap marker always carries the continuation (offset / cursor, else narrowing
|
|
6
|
+
// advice) and, when the complete output was saved, `full output: <path>`.
|
|
7
|
+
|
|
8
|
+
export function formatCapSize(bytes) {
|
|
9
|
+
const n = Number(bytes);
|
|
10
|
+
if (n < 1024) return `${Math.max(0, Math.trunc(n))} bytes`;
|
|
11
|
+
const kb = n / 1024;
|
|
12
|
+
return `${Number.isInteger(kb) ? kb : kb.toFixed(1)} KB`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Requested window: `[lines 5-27 of 90; offset:28 for more]` (no continuation
|
|
17
|
+
* at the end). `capBytes` marks a window the byte cap shortened:
|
|
18
|
+
* `[lines 5-27 of 90; output capped at 50 KB; offset:28 for more]`.
|
|
19
|
+
*/
|
|
20
|
+
export function windowMarker({
|
|
21
|
+
unit = 'lines',
|
|
22
|
+
from,
|
|
23
|
+
to,
|
|
24
|
+
total = null,
|
|
25
|
+
nextOffset = null,
|
|
26
|
+
capBytes = null,
|
|
27
|
+
offsetKey = 'offset',
|
|
28
|
+
}) {
|
|
29
|
+
const of = total == null ? '' : ` of ${total}`;
|
|
30
|
+
const cap = capBytes == null ? '' : `; output capped at ${formatCapSize(capBytes)}`;
|
|
31
|
+
const more = nextOffset == null ? '' : `; ${offsetKey}:${nextOffset} for more`;
|
|
32
|
+
return `[${unit} ${from}-${to}${of}${cap}${more}]`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Cap hit. `limit` is bytes (number) or a ready label ("500 rows"). `shown`
|
|
37
|
+
* says what survived. Continuation is `nextOffset`, else `cursor`, else
|
|
38
|
+
* `narrow` advice (a default is supplied so it is never missing).
|
|
39
|
+
*/
|
|
40
|
+
export function capMarker({
|
|
41
|
+
limit,
|
|
42
|
+
shown = '',
|
|
43
|
+
nextOffset = null,
|
|
44
|
+
offsetKey = 'offset',
|
|
45
|
+
cursor = null,
|
|
46
|
+
narrow = '',
|
|
47
|
+
fullPath = '',
|
|
48
|
+
}) {
|
|
49
|
+
const parts = [`output capped at ${typeof limit === 'number' ? formatCapSize(limit) : limit}`];
|
|
50
|
+
if (shown) parts.push(shown);
|
|
51
|
+
if (nextOffset != null) parts.push(`${offsetKey}:${nextOffset} for more`);
|
|
52
|
+
else if (cursor != null) parts.push(`cursor:${cursor} for more`);
|
|
53
|
+
if (narrow || (nextOffset == null && cursor == null)) {
|
|
54
|
+
parts.push(`narrow: ${narrow || 'restrict the path, pattern or scope'}`);
|
|
55
|
+
}
|
|
56
|
+
if (fullPath) parts.push(`full output: ${fullPath}`);
|
|
57
|
+
return `[${parts.join('; ')}]`;
|
|
58
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// These pure helpers keep live rows, persisted messages and restored rows on
|
|
3
3
|
// the same field contract without rewriting older display-only transcripts.
|
|
4
4
|
import { displayModelName } from './model-display.mjs';
|
|
5
|
+
import { routineTriggerField } from './routine-trigger.mjs';
|
|
5
6
|
|
|
6
7
|
export function transcriptRouteMetadataFields(value) {
|
|
7
8
|
if (!value || typeof value !== 'object') return {};
|
|
@@ -76,10 +77,19 @@ export function persistedUserTranscriptMetadata(value) {
|
|
|
76
77
|
// The turn's change-record key (the outer prompt id), so a restored user
|
|
77
78
|
// row still addresses its turn's Undo/Reapply.
|
|
78
79
|
...(typeof value.checkpointId === 'string' && value.checkpointId ? { checkpointId: value.checkpointId } : {}),
|
|
80
|
+
// Every submission a merged queued batch delivered as this turn.
|
|
81
|
+
...submissionIdsField(value.submissionIds),
|
|
79
82
|
...attachmentsField(value.attachments),
|
|
83
|
+
// A routine fire delivered as this turn (routine-trigger.mjs).
|
|
84
|
+
...routineTriggerField(value),
|
|
80
85
|
};
|
|
81
86
|
}
|
|
82
87
|
|
|
88
|
+
function submissionIdsField(value) {
|
|
89
|
+
const ids = Array.isArray(value) ? value.filter((id) => typeof id === 'string' && id) : [];
|
|
90
|
+
return ids.length ? { submissionIds: ids } : {};
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
function attachmentsField(value) {
|
|
84
94
|
const attachments = normalizeMessageAttachments(value);
|
|
85
95
|
return attachments.length ? { attachments } : {};
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
export const TURN_CHANGE_FILE_PATCH_MAX_BYTES = 8 * 1024 * 1024;
|
|
28
28
|
const APPLY_TIMEOUT_MS = 60_000;
|
|
29
29
|
const APPLY_OUTPUT_MAX_BYTES = 4 * 1024 * 1024;
|
|
30
|
-
const STATUSES = new Set(['A', 'M', 'D', 'R']);
|
|
31
30
|
// Characters a patch header cannot carry unquoted; such a path is recorded but
|
|
32
31
|
// never replayed.
|
|
33
32
|
const UNSAFE_PATH_CHARACTERS = /[\t\n\r"\0]/;
|
|
@@ -37,13 +36,6 @@ export function changePathKey(value) {
|
|
|
37
36
|
return process.platform === 'win32' ? text.toLowerCase() : text;
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
/** git status letter → record status (copies create a new file). */
|
|
41
|
-
export function normalizeChangeStatus(code) {
|
|
42
|
-
const letter = String(code || 'M').charAt(0);
|
|
43
|
-
if (STATUSES.has(letter)) return letter;
|
|
44
|
-
return letter === 'C' ? 'A' : 'M';
|
|
45
|
-
}
|
|
46
|
-
|
|
47
39
|
/** A root-relative forward-slash path that a patch may name, or ''. */
|
|
48
40
|
function safeChangePath(value) {
|
|
49
41
|
const text = clean(value).replace(/\\/g, '/');
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Session-cumulative figures behind the composer's usage readout, kept on the
|
|
2
|
+
// session record (`session.usageReadout`) so they survive restart, reload and
|
|
3
|
+
// compaction. One fold per model call of the session itself; calls of other
|
|
4
|
+
// sessions (delegated sub-agents have their own records) never enter.
|
|
5
|
+
//
|
|
6
|
+
// - cache hit = cacheRead / (input + cacheRead + cacheWrite) over every call
|
|
7
|
+
// whose prompt was measured. A call that could not measure its prompt
|
|
8
|
+
// (promptKnown === false) has unknown zeros, so it adds nothing.
|
|
9
|
+
// - speed = output tokens over generation ms (first visible token → end of the
|
|
10
|
+
// response) of the calls long enough to time. A reply too short says nothing
|
|
11
|
+
// about the model's speed, so each call is held to the floors below BEFORE it
|
|
12
|
+
// is summed.
|
|
13
|
+
// - total tokens = input + cacheRead + cacheWrite + output, from the same sums.
|
|
14
|
+
export const MIN_SPEED_OUTPUT_TOKENS = 20;
|
|
15
|
+
export const MIN_SPEED_MS = 500;
|
|
16
|
+
|
|
17
|
+
function num(value) {
|
|
18
|
+
const n = Number(value);
|
|
19
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The zeroed totals record. */
|
|
23
|
+
export function emptyUsageReadout() {
|
|
24
|
+
return { input: 0, cacheRead: 0, cacheWrite: 0, output: 0, speedOutputTokens: 0, speedMs: 0 };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Fold one `onUsageDelta` event (and the call's generation ms, 0 when it was
|
|
29
|
+
* not timed) into the totals; returns a new record, never mutates `totals`.
|
|
30
|
+
* Providers differ on whether input counts cache; the prompt total does not,
|
|
31
|
+
* so fresh input is the prompt less its cache read/write.
|
|
32
|
+
*/
|
|
33
|
+
export function foldUsageReadout(totals, delta = {}, generationMs = 0) {
|
|
34
|
+
const base = totals || emptyUsageReadout();
|
|
35
|
+
const next = { ...base };
|
|
36
|
+
if (delta.promptKnown !== false) {
|
|
37
|
+
const cacheRead = num(delta.deltaCachedRead);
|
|
38
|
+
const cacheWrite = num(delta.deltaCacheWrite);
|
|
39
|
+
const prompt = num(delta.deltaPrompt) || num(delta.deltaInput) + cacheRead + cacheWrite;
|
|
40
|
+
next.input = num(base.input) + Math.max(0, prompt - cacheRead - cacheWrite);
|
|
41
|
+
next.cacheRead = num(base.cacheRead) + cacheRead;
|
|
42
|
+
next.cacheWrite = num(base.cacheWrite) + cacheWrite;
|
|
43
|
+
}
|
|
44
|
+
const output = num(delta.deltaOutput);
|
|
45
|
+
// Every call's output enters the session's total tokens, timed or not. A
|
|
46
|
+
// record saved before the field existed has no output sum to extend, and a
|
|
47
|
+
// partial one would pass for the whole: it stays without until the session
|
|
48
|
+
// starts over.
|
|
49
|
+
if (Number.isFinite(base.output)) next.output = base.output + output;
|
|
50
|
+
const ms = num(generationMs);
|
|
51
|
+
if (ms >= MIN_SPEED_MS && output >= MIN_SPEED_OUTPUT_TOKENS) {
|
|
52
|
+
next.speedOutputTokens = num(base.speedOutputTokens) + output;
|
|
53
|
+
next.speedMs = num(base.speedMs) + ms;
|
|
54
|
+
}
|
|
55
|
+
return next;
|
|
56
|
+
}
|