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,11 +1,34 @@
|
|
|
1
|
+
// Incremental delivery of a shell task's output. Each task (the authorized
|
|
2
|
+
// task object) owns one cursor per stream; every wait, read, background move
|
|
3
|
+
// and completion notice delivers only the bytes after it, in the shared
|
|
4
|
+
// delivery shape (lib/shell-delivery.mjs). The cursor always advances over the
|
|
5
|
+
// whole unseen range, even when its middle is omitted: omitted bytes are never
|
|
6
|
+
// re-sent, the marker's log path is how to get them back.
|
|
1
7
|
import { closeSync, fstatSync, openSync, readSync } from 'node:fs';
|
|
2
8
|
import { stripAnsi } from '../../shell-exec-output.mjs';
|
|
3
9
|
import { FileEncodingSniffer, ShellStreamDecoder, alignedOffset, oemTextEncoding } from '../../shell-codepage.mjs';
|
|
10
|
+
import {
|
|
11
|
+
DELIVERY_FULL_CHARS,
|
|
12
|
+
countNewlines,
|
|
13
|
+
createCarriageReturnFolder,
|
|
14
|
+
edgesPiece,
|
|
15
|
+
escapeHarnessTags,
|
|
16
|
+
fitPieces,
|
|
17
|
+
formatKb,
|
|
18
|
+
omissionMarker,
|
|
19
|
+
persistDeliveryLog,
|
|
20
|
+
prepareShellText,
|
|
21
|
+
textPiece,
|
|
22
|
+
} from './shell-delivery.mjs';
|
|
4
23
|
|
|
5
|
-
import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../../../../../shared/tool-output-budget.mjs';
|
|
6
24
|
const cursors = new WeakMap();
|
|
7
25
|
const ESC = '\x1b';
|
|
8
26
|
const PENDING_ANSI_INTRODUCER = new RegExp(`${ESC}(?:\\[[0-?]*[ -/]*|\\](?:(?!${ESC}\\\\)[^\x07\x9c])*)?$`);
|
|
27
|
+
// An unseen range up to this size is read whole; a longer one only at its two
|
|
28
|
+
// ends (the middle is counted, never loaded).
|
|
29
|
+
const FULL_READ_BYTES = 64 * 1024;
|
|
30
|
+
const EDGE_READ_BYTES = 16 * 1024;
|
|
31
|
+
const COUNT_CHUNK_BYTES = 1 << 20;
|
|
9
32
|
|
|
10
33
|
function newCursor() {
|
|
11
34
|
return {
|
|
@@ -13,6 +36,7 @@ function newCursor() {
|
|
|
13
36
|
preview: '',
|
|
14
37
|
decoder: new ShellStreamDecoder(),
|
|
15
38
|
ansi: '',
|
|
39
|
+
fold: createCarriageReturnFolder(),
|
|
16
40
|
sniffer: new FileEncodingSniffer(),
|
|
17
41
|
committed: false,
|
|
18
42
|
};
|
|
@@ -26,13 +50,6 @@ function pendingAnsiIntroducer(sequence) {
|
|
|
26
50
|
return '\x1b';
|
|
27
51
|
}
|
|
28
52
|
|
|
29
|
-
// First index at or after `start` that does not sit inside a UTF-8 sequence.
|
|
30
|
-
function utf8Boundary(bytes, start, end) {
|
|
31
|
-
let index = start;
|
|
32
|
-
while (index < end && (bytes[index] & 0xc0) === 0x80) index++;
|
|
33
|
-
return index;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
53
|
function visibleText(cursor, text) {
|
|
37
54
|
const value = cursor.ansi + text;
|
|
38
55
|
// Retain only the introducer of an unfinished CSI/OSC, not its potentially
|
|
@@ -45,21 +62,123 @@ function visibleText(cursor, text) {
|
|
|
45
62
|
return stripAnsi(value.slice(0, pending.index));
|
|
46
63
|
}
|
|
47
64
|
|
|
65
|
+
function readBytes(fd, start, length) {
|
|
66
|
+
const buffer = Buffer.alloc(Math.max(0, length));
|
|
67
|
+
const count = length > 0 ? readSync(fd, buffer, 0, length, start) : 0;
|
|
68
|
+
return buffer.subarray(0, count);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function countNewlinesInRange(fd, start, end) {
|
|
72
|
+
let count = 0;
|
|
73
|
+
const buffer = Buffer.alloc(Math.min(COUNT_CHUNK_BYTES, Math.max(1, end - start)));
|
|
74
|
+
for (let position = start; position < end; ) {
|
|
75
|
+
const bytes = readSync(fd, buffer, 0, Math.min(buffer.length, end - position), position);
|
|
76
|
+
if (bytes <= 0) break;
|
|
77
|
+
for (let i = 0; i < bytes; i += 1) if (buffer[i] === 10) count += 1;
|
|
78
|
+
position += bytes;
|
|
79
|
+
}
|
|
80
|
+
return count;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function decodeVisible(cursor, bytes, flush) {
|
|
84
|
+
let decoded = cursor.decoder.write(bytes);
|
|
85
|
+
if (flush) decoded += cursor.decoder.end();
|
|
86
|
+
return prepareShellText(visibleText(cursor, decoded), cursor.fold);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// One unseen file range [start, end) in the delivery shape. A long range is
|
|
90
|
+
// read only at its ends; the tail starts a fresh decoder at a character
|
|
91
|
+
// boundary, as the original paging did when it skipped bytes.
|
|
92
|
+
function readRange(fd, cursor, { start, end, label, flush, path }) {
|
|
93
|
+
const total = end - start;
|
|
94
|
+
if (total <= FULL_READ_BYTES) {
|
|
95
|
+
const text = decodeVisible(cursor, readBytes(fd, start, total), flush);
|
|
96
|
+
return { piece: textPiece(text, { path }), bytes: total, lines: countNewlines(text), text };
|
|
97
|
+
}
|
|
98
|
+
const headText = decodeVisible(cursor, readBytes(fd, start, EDGE_READ_BYTES), false);
|
|
99
|
+
const tailStart = alignedOffset(fd, end - EDGE_READ_BYTES, label || 'utf-8');
|
|
100
|
+
cursor.decoder = new ShellStreamDecoder(oemTextEncoding(), label);
|
|
101
|
+
cursor.ansi = '';
|
|
102
|
+
cursor.fold = createCarriageReturnFolder();
|
|
103
|
+
const tailText = decodeVisible(cursor, readBytes(fd, tailStart, end - tailStart), flush);
|
|
104
|
+
const lines = countNewlinesInRange(fd, start, end);
|
|
105
|
+
return {
|
|
106
|
+
piece: edgesPiece(headText, tailText, { totalBytes: total, totalLines: lines, path }),
|
|
107
|
+
bytes: total,
|
|
108
|
+
lines,
|
|
109
|
+
text: tailText,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const PERCENT_RE = /(\d{1,3}(?:\.\d+)?)\s?%/g;
|
|
114
|
+
const ETA_RE = /\b(?:ETA|eta|remaining|left)\b[:=\s]*(\d+(?::\d{2}){1,2}|\d+(?:\.\d+)?\s?(?:h|m|s|min|sec)\b)/g;
|
|
115
|
+
|
|
116
|
+
function lastMatch(pattern, text) {
|
|
117
|
+
let found = null;
|
|
118
|
+
for (const match of text.matchAll(pattern)) found = match;
|
|
119
|
+
return found;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** What changed since the agent last saw the job: growth, last line, any
|
|
123
|
+
* visible percent/ETA. Used where a still-running job is reported. */
|
|
124
|
+
function progressDigest(growth) {
|
|
125
|
+
const bytes = growth.reduce((sum, entry) => sum + entry.bytes, 0);
|
|
126
|
+
const lines = growth.reduce((sum, entry) => sum + entry.lines, 0);
|
|
127
|
+
const text = growth
|
|
128
|
+
.map((entry) => entry.text)
|
|
129
|
+
.filter(Boolean)
|
|
130
|
+
.join('\n');
|
|
131
|
+
const parts = [
|
|
132
|
+
bytes > 0 ? `+${formatKb(bytes)}, +${lines} lines since you last saw it` : 'no new output since you last saw it',
|
|
133
|
+
];
|
|
134
|
+
const last = text
|
|
135
|
+
.split('\n')
|
|
136
|
+
.reverse()
|
|
137
|
+
.find((line) => line.trim());
|
|
138
|
+
if (last) parts.push(`last line: ${JSON.stringify(last.trim().slice(0, 200))}`);
|
|
139
|
+
const percent = lastMatch(PERCENT_RE, text);
|
|
140
|
+
if (percent && Number(percent[1]) <= 100) parts.push(`${percent[1]}%`);
|
|
141
|
+
const eta = lastMatch(ETA_RE, text);
|
|
142
|
+
if (eta) parts.push(`ETA ${eta[1].trim()}`);
|
|
143
|
+
return `[progress] ${parts.join(' · ')} — still running, not an error`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** A whole finished log as a piece of the delivery (a foreground command whose
|
|
147
|
+
* capture spilled to disk), read with a fresh cursor. */
|
|
148
|
+
export function shellLogPiece(path) {
|
|
149
|
+
const cursor = newCursor();
|
|
150
|
+
let fd;
|
|
151
|
+
try {
|
|
152
|
+
fd = openSync(path, 'r');
|
|
153
|
+
const size = fstatSync(fd).size;
|
|
154
|
+
const label = cursor.sniffer.probe(fd, size, true);
|
|
155
|
+
if (label) cursor.decoder.force(label);
|
|
156
|
+
return readRange(fd, cursor, { start: 0, end: size, label, flush: true, path }).piece;
|
|
157
|
+
} finally {
|
|
158
|
+
if (fd !== undefined) closeSync(fd);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
48
162
|
// Cursor ownership follows the authorized task object, not a globally supplied
|
|
49
163
|
// task id. Bounded synchronous reads make concurrent task reads non-overlapping.
|
|
50
164
|
// Only bytes actually read advance the cursor; previews never stand in for a
|
|
51
165
|
// file offset, since a preview may contain an omitted middle.
|
|
52
|
-
// Explicit tail reads never change the incremental cursor.
|
|
53
|
-
//
|
|
54
|
-
|
|
166
|
+
// Explicit tail reads (`output: 'tail'`) never change the incremental cursor.
|
|
167
|
+
// `terminal` flushes the decoders (the producer finished); `digest` prefixes
|
|
168
|
+
// the progress digest for a job reported while still running.
|
|
169
|
+
export function readShellTaskOutput(
|
|
170
|
+
task,
|
|
171
|
+
result = {},
|
|
172
|
+
{ output = 'new', terminal = task.status !== 'running', digest = false } = {}
|
|
173
|
+
) {
|
|
55
174
|
const replay = output === 'tail';
|
|
56
|
-
const
|
|
57
|
-
const limit = terminal || replay ? TOOL_OUTPUT_TAIL_BYTES : TOOL_OUTPUT_PAGE_BYTES;
|
|
175
|
+
const growth = [];
|
|
58
176
|
let streams = replay ? new Map() : cursors.get(task);
|
|
59
177
|
if (!streams) {
|
|
60
178
|
streams = new Map();
|
|
61
179
|
cursors.set(task, streams);
|
|
62
180
|
}
|
|
181
|
+
// A note, or a stream's body: stdout and stderr share one delivery budget.
|
|
63
182
|
const sections = [];
|
|
64
183
|
for (const stream of ['stdout', 'stderr']) {
|
|
65
184
|
const path = result[`${stream}_path`];
|
|
@@ -73,15 +192,15 @@ export function readShellTaskOutput(task, result = {}, { output = 'new' } = {})
|
|
|
73
192
|
if (!path) {
|
|
74
193
|
const preview = String(result[`${stream}_preview`] || '');
|
|
75
194
|
const delta = preview.startsWith(cursor.preview) ? preview.slice(cursor.preview.length) : preview;
|
|
76
|
-
const
|
|
77
|
-
const start = utf8Boundary(bytes, Math.max(0, bytes.length - limit), bytes.length);
|
|
78
|
-
if (start) {
|
|
79
|
-
sections.push(`[${stream}: ${start} preview bytes omitted; no original log path available]`);
|
|
80
|
-
cursor.ansi = '';
|
|
81
|
-
}
|
|
82
|
-
const text = visibleText(cursor, bytes.subarray(start).toString('utf8'));
|
|
195
|
+
const text = prepareShellText(visibleText(cursor, delta), cursor.fold);
|
|
83
196
|
cursor.preview = preview;
|
|
84
|
-
|
|
197
|
+
growth.push({ bytes: Buffer.byteLength(delta), lines: countNewlines(text), text });
|
|
198
|
+
// A preview has no log of its own: a capped one is saved for the marker.
|
|
199
|
+
if (text)
|
|
200
|
+
sections.push({
|
|
201
|
+
prefix: `[${stream}]\n`,
|
|
202
|
+
piece: textPiece(text, { path: () => persistDeliveryLog(text, stream) }),
|
|
203
|
+
});
|
|
85
204
|
continue;
|
|
86
205
|
}
|
|
87
206
|
let fd;
|
|
@@ -102,30 +221,37 @@ export function readShellTaskOutput(task, result = {}, { output = 'new' } = {})
|
|
|
102
221
|
cursor.decoder.force(label);
|
|
103
222
|
}
|
|
104
223
|
const readEnd = label ? size : cursor.sniffer.safeEnd(size);
|
|
105
|
-
let start =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
224
|
+
let start = cursor.offset;
|
|
225
|
+
let earlier = '';
|
|
226
|
+
if (replay && readEnd - start > FULL_READ_BYTES) {
|
|
227
|
+
// A replay shows the recent part; everything before it is counted.
|
|
228
|
+
start = Math.min(readEnd, alignedOffset(fd, readEnd - FULL_READ_BYTES, label || 'utf-8'));
|
|
229
|
+
earlier = omissionMarker({ lines: countNewlinesInRange(fd, 0, start), bytes: start, path });
|
|
109
230
|
cursor.decoder = new ShellStreamDecoder(oemTextEncoding(), label);
|
|
110
|
-
cursor.ansi = '';
|
|
111
|
-
}
|
|
112
|
-
const buffer = Buffer.alloc(Math.min(limit, Math.max(0, readEnd - start)));
|
|
113
|
-
const count = buffer.length ? readSync(fd, buffer, 0, buffer.length, start) : 0;
|
|
114
|
-
cursor.offset = start + count;
|
|
115
|
-
let decoded = cursor.decoder.write(buffer.subarray(0, count));
|
|
116
|
-
if (terminal && cursor.offset === size) decoded += cursor.decoder.end();
|
|
117
|
-
const text = visibleText(cursor, decoded);
|
|
118
|
-
if (text) sections.push(`[${stream}]\n${text}`);
|
|
119
|
-
if (cursor.offset < size) {
|
|
120
|
-
sections.push(
|
|
121
|
-
`[${stream}: ${size - cursor.offset} unread bytes; task read continues, read ${path} for the original log]`
|
|
122
|
-
);
|
|
123
231
|
}
|
|
232
|
+
const range = readRange(fd, cursor, { start, end: readEnd, label, flush: terminal && readEnd === size, path });
|
|
233
|
+
cursor.offset = readEnd;
|
|
234
|
+
growth.push(range);
|
|
235
|
+
if (range.piece.natural)
|
|
236
|
+
sections.push({ prefix: `[${stream}]\n${earlier ? `${earlier}\n` : ''}`, piece: range.piece });
|
|
124
237
|
} catch (error) {
|
|
125
238
|
sections.push(`[${stream} read error: ${error.message}]`);
|
|
126
239
|
} finally {
|
|
127
240
|
if (fd !== undefined) closeSync(fd);
|
|
128
241
|
}
|
|
129
242
|
}
|
|
130
|
-
|
|
243
|
+
// Notes and prefixes come off the budget; the streams split what is left.
|
|
244
|
+
const fixed = sections.reduce(
|
|
245
|
+
(sum, item) => sum + (item.prefix ?? item).length,
|
|
246
|
+
2 * Math.max(0, sections.length - 1)
|
|
247
|
+
);
|
|
248
|
+
const pieces = sections.filter((item) => item.piece);
|
|
249
|
+
const bodies = fitPieces(
|
|
250
|
+
pieces.map((item) => item.piece),
|
|
251
|
+
DELIVERY_FULL_CHARS - fixed
|
|
252
|
+
);
|
|
253
|
+
const body =
|
|
254
|
+
sections.map((item) => (item.piece ? `${item.prefix}${bodies[pieces.indexOf(item)]}` : item)).join('\n\n') ||
|
|
255
|
+
(replay ? '(no output)' : '(no new output)');
|
|
256
|
+
return escapeHarnessTags(digest ? `${progressDigest(growth)}\n\n${body}` : body);
|
|
131
257
|
}
|
|
@@ -6,10 +6,16 @@ import { markScopedCacheIncomplete, markScopedCacheUnsafe } from '../../session/
|
|
|
6
6
|
import { cacheGet, cacheSet, lstatPathsForMtime } from './cache-layers.mjs';
|
|
7
7
|
import { runScopedSearchInFlight } from './lib/scoped-search-flight.mjs';
|
|
8
8
|
import { NOISE_DIR_NAMES, walkDir } from './glob-walk.mjs';
|
|
9
|
-
import { TOOL_OUTPUT_MAX_BYTES } from './tool-output-limit.mjs';
|
|
9
|
+
import { TOOL_OUTPUT_MAX_BYTES, capMarker } from './tool-output-limit.mjs';
|
|
10
10
|
import { runRgWindowedLines } from './native-search-runner.mjs';
|
|
11
11
|
import { tryServeListMetadata } from './native-search-client.mjs';
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
countTextFileLines,
|
|
14
|
+
guardedWalkRoot,
|
|
15
|
+
comparePathsStable,
|
|
16
|
+
normalizeListHeadLimit,
|
|
17
|
+
pageContinuationLine,
|
|
18
|
+
} from './lib/list-helpers.mjs';
|
|
13
19
|
import { reportToolProgress } from './lib/tool-progress.mjs';
|
|
14
20
|
import { displayRelPath, statWalkRoot } from './list-tool-shared.mjs';
|
|
15
21
|
import { executeFindFilesTool } from './find-files-tool.mjs';
|
|
@@ -338,9 +344,9 @@ async function fillRowMetadata(rows, workDir, options) {
|
|
|
338
344
|
}
|
|
339
345
|
|
|
340
346
|
function sortListRows(rows, sort) {
|
|
341
|
-
if (sort === 'mtime') rows.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
342
|
-
else if (sort === 'size') rows.sort((a, b) => b.size - a.size);
|
|
343
|
-
else rows.sort((a, b) => a.path.localeCompare(b.path));
|
|
347
|
+
if (sort === 'mtime') rows.sort((a, b) => b.mtimeMs - a.mtimeMs || comparePathsStable(a.path, b.path));
|
|
348
|
+
else if (sort === 'size') rows.sort((a, b) => b.size - a.size || comparePathsStable(a.path, b.path));
|
|
349
|
+
else rows.sort((a, b) => a.path.localeCompare(b.path) || comparePathsStable(a.path, b.path));
|
|
344
350
|
}
|
|
345
351
|
|
|
346
352
|
// What an empty page means: offset past the end is a windowing condition,
|
|
@@ -390,15 +396,17 @@ async function scanList(request, cacheKey, workDir, options) {
|
|
|
390
396
|
if (root.error) return root.error;
|
|
391
397
|
if (!root.stat.isDirectory()) {
|
|
392
398
|
if (!root.stat.isFile()) return `Error: not a directory — ${normalizeOutputPath(fullPath)}`;
|
|
393
|
-
const out = listFileLine(
|
|
399
|
+
const out = listFileLine(
|
|
400
|
+
fullPath,
|
|
401
|
+
root.stat,
|
|
402
|
+
meta,
|
|
403
|
+
meta ? await countTextFileLines(fullPath, root.stat.size) : null
|
|
404
|
+
);
|
|
394
405
|
cacheSet(cacheKey, out, { scopes: [fullPath] });
|
|
395
406
|
return out;
|
|
396
407
|
}
|
|
397
|
-
const { rows, walkResult, walkWarnings, truncatedByCap, nativeDeep, cacheSafe, nativeMetaMissing } =
|
|
398
|
-
request,
|
|
399
|
-
workDir,
|
|
400
|
-
options
|
|
401
|
-
);
|
|
408
|
+
const { rows, walkResult, walkWarnings, truncatedByCap, nativeDeep, cacheSafe, nativeMetaMissing } =
|
|
409
|
+
await collectListRows(request, workDir, options);
|
|
402
410
|
const rootFailure = walkRootFailureLine(options, walkResult, walkWarnings, 'list walk');
|
|
403
411
|
if (rootFailure) return rootFailure;
|
|
404
412
|
if (!nativeDeep && needsGlobalStat) await fillRowMetadata(rows, workDir, options);
|
|
@@ -439,7 +447,11 @@ async function renderListPage({ request, rows, walkWarnings, truncatedByCap, nat
|
|
|
439
447
|
if (paged) lines.push(pageContinuationLine(offset, sliced.length, rows.length));
|
|
440
448
|
if (truncatedByCap) {
|
|
441
449
|
lines.push(
|
|
442
|
-
|
|
450
|
+
capMarker({
|
|
451
|
+
limit: `${LIST_ABSOLUTE_CAP} rows or ${LIST_WALK_TIMEOUT_MS}ms`,
|
|
452
|
+
shown: 'listing incomplete',
|
|
453
|
+
narrow: 'narrow the path or lower depth',
|
|
454
|
+
})
|
|
443
455
|
);
|
|
444
456
|
}
|
|
445
457
|
for (const warning of walkWarnings) lines.push(directoryReadFailureLine(warning, true));
|
|
@@ -516,7 +528,7 @@ function renderTreeOutput(lines, walkWarnings, { headLimit, offset }) {
|
|
|
516
528
|
outputCharTruncated = true;
|
|
517
529
|
out =
|
|
518
530
|
out.slice(0, TOOL_OUTPUT_MAX_BYTES) +
|
|
519
|
-
`\n
|
|
531
|
+
`\n${capMarker({ limit: TOOL_OUTPUT_MAX_BYTES, narrow: 'narrow path or lower depth' })}`;
|
|
520
532
|
}
|
|
521
533
|
return { out, outputCharTruncated };
|
|
522
534
|
}
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
//
|
|
9
9
|
// MIXDOG_SEARCH_SERVER=0 disables; MIXDOG_SEARCH_SERVER_BIN overrides the
|
|
10
10
|
// executable.
|
|
11
|
-
import { existsSync } from 'node:fs';
|
|
11
|
+
import { existsSync, lstatSync, mkdirSync, realpathSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { basename, dirname, isAbsolute, join, resolve as resolvePath, sep } from 'node:path';
|
|
12
13
|
import { bindChildLifecycle, createNativeSearchTransport } from './native-search-transport.mjs';
|
|
13
14
|
import { invalidateBuiltinResultCache } from './cache-layers.mjs';
|
|
14
15
|
import { getPluginData } from '../../config.mjs';
|
|
@@ -254,6 +255,32 @@ export async function shutdownNativeSearchServer(reason = 'process-exit', timeou
|
|
|
254
255
|
|
|
255
256
|
export { bindChildLifecycle as _bindNativeSearchServerLifecycle };
|
|
256
257
|
|
|
258
|
+
// Inventories persisted before search roots were canonicalized (see
|
|
259
|
+
// canonicalPath) can hold another spelling of a folder's files under the
|
|
260
|
+
// folder's canonical key; loading one would keep serving every file twice.
|
|
261
|
+
// Drop that snapshot once per data dir, before a server of this process loads
|
|
262
|
+
// it. The marker records that the remaining snapshot was written by servers
|
|
263
|
+
// that only ever saw canonical roots.
|
|
264
|
+
const INVENTORY_SNAPSHOT_FILE = 'file-inventories-v1.bin';
|
|
265
|
+
const CANONICAL_ROOTS_MARKER = 'file-inventories-v1.canonical-roots';
|
|
266
|
+
let _inventorySnapshotChecked = false;
|
|
267
|
+
|
|
268
|
+
function dropAliasSpelledInventorySnapshot() {
|
|
269
|
+
if (_inventorySnapshotChecked) return;
|
|
270
|
+
_inventorySnapshotChecked = true;
|
|
271
|
+
const dir = join(getPluginData(), 'search-index');
|
|
272
|
+
const marker = join(dir, CANONICAL_ROOTS_MARKER);
|
|
273
|
+
if (existsSync(marker)) return;
|
|
274
|
+
try {
|
|
275
|
+
rmSync(join(dir, INVENTORY_SNAPSHOT_FILE), { force: true });
|
|
276
|
+
mkdirSync(dir, { recursive: true });
|
|
277
|
+
writeFileSync(marker, '');
|
|
278
|
+
} catch {
|
|
279
|
+
// A snapshot that cannot be removed now (held open by another server) is
|
|
280
|
+
// retried by the next process; search itself does not depend on it.
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
257
284
|
function _ensureServer() {
|
|
258
285
|
if (_server) return _server;
|
|
259
286
|
if (
|
|
@@ -261,6 +288,7 @@ function _ensureServer() {
|
|
|
261
288
|
Date.now() - _lastFailureAt < RESTART_BACKOFF_MS
|
|
262
289
|
)
|
|
263
290
|
return null;
|
|
291
|
+
dropAliasSpelledInventorySnapshot();
|
|
264
292
|
let transport;
|
|
265
293
|
try {
|
|
266
294
|
transport = createNativeSearchTransport({
|
|
@@ -633,15 +661,93 @@ function consumedDeadline(response, deadlineMs) {
|
|
|
633
661
|
);
|
|
634
662
|
}
|
|
635
663
|
|
|
664
|
+
// The server walks a root as the request spells it, but its file-change
|
|
665
|
+
// updates carry the resolved path. Any other spelling of the same folder —
|
|
666
|
+
// letter case on Windows, a junction or symlink, a `..` segment — therefore
|
|
667
|
+
// listed every file twice (one copy per spelling). Roots are resolved once,
|
|
668
|
+
// here, so the first walk, later updates and the inventory key agree.
|
|
669
|
+
function canonicalPath(path) {
|
|
670
|
+
try {
|
|
671
|
+
return realpathSync.native(path);
|
|
672
|
+
} catch {
|
|
673
|
+
return path;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
// One positional operand resolved against the canonical cwd. An operand that
|
|
678
|
+
// is already canonical is sent unchanged. An exact file that is itself a
|
|
679
|
+
// symlink keeps its own name: --glob/--type filter the name the caller asked
|
|
680
|
+
// for. `file` tells restoreOperandSpelling how the server prints the operand.
|
|
681
|
+
function canonicalOperand(cwd, operand) {
|
|
682
|
+
const joined = isAbsolute(operand) ? operand : `${cwd}${sep}${operand}`;
|
|
683
|
+
let canonical;
|
|
684
|
+
let file;
|
|
685
|
+
try {
|
|
686
|
+
file = statSync(joined).isFile();
|
|
687
|
+
canonical =
|
|
688
|
+
file && lstatSync(joined).isSymbolicLink()
|
|
689
|
+
? join(realpathSync.native(dirname(joined)), basename(joined))
|
|
690
|
+
: realpathSync.native(joined);
|
|
691
|
+
} catch {
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
if (canonical === (isAbsolute(operand) ? operand : resolvePath(cwd, operand))) return null;
|
|
695
|
+
// The server prints results with `/` when the operand only uses `/`.
|
|
696
|
+
const sent = operand.includes('/') && !operand.includes('\\') ? canonical.replaceAll('\\', '/') : canonical;
|
|
697
|
+
if (sent === operand) return null;
|
|
698
|
+
// A directory is printed with its trailing separators trimmed.
|
|
699
|
+
const printed = (path) => (file ? path : path.replace(/[\\/]+$/, ''));
|
|
700
|
+
return { sent, from: printed(sent), to: printed(operand), file };
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
// Canonical cwd and operands for a search request, plus the operands whose
|
|
704
|
+
// spelling restoreOperandSpelling puts back into the result lines. Positional
|
|
705
|
+
// operands follow the last `--` (search-builders emits it before them; a `--`
|
|
706
|
+
// pattern is always an `-e` value before it).
|
|
707
|
+
function canonicalSearchRequest(cwd, argsList) {
|
|
708
|
+
const root = canonicalPath(cwd);
|
|
709
|
+
const args = argsList.map(String);
|
|
710
|
+
const remaps = [];
|
|
711
|
+
const operandsAt = args.lastIndexOf('--') + 1;
|
|
712
|
+
if (operandsAt > 0) {
|
|
713
|
+
for (let i = operandsAt; i < args.length; i += 1) {
|
|
714
|
+
const remap = canonicalOperand(root, args[i]);
|
|
715
|
+
if (!remap) continue;
|
|
716
|
+
args[i] = remap.sent;
|
|
717
|
+
remaps.push(remap);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
remaps.sort((a, b) => b.from.length - a.from.length);
|
|
721
|
+
return { cwd: root, args, remaps };
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Results under a canonicalized operand are printed by the server as
|
|
725
|
+
// `<operand><sep><relative>` (a directory) or as the operand itself followed
|
|
726
|
+
// by `:`/`-` fields (an exact file); show them under the caller's spelling.
|
|
727
|
+
function restoreOperandSpelling(lines, remaps) {
|
|
728
|
+
if (remaps.length === 0) return lines;
|
|
729
|
+
return lines.map((line) => {
|
|
730
|
+
if (typeof line !== 'string') return line;
|
|
731
|
+
for (const { from, to, file } of remaps) {
|
|
732
|
+
if (!line.startsWith(from)) continue;
|
|
733
|
+
const rest = line.slice(from.length);
|
|
734
|
+
if (rest !== '' && !(file ? /^[:-]/ : /^[\\/]/).test(rest)) continue;
|
|
735
|
+
return `${to}${rest}`;
|
|
736
|
+
}
|
|
737
|
+
return line;
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
|
|
636
741
|
/** Returns a runRgWindowedLines-shaped result, or null when the native server
|
|
637
742
|
* is disabled or the response carries no line list. */
|
|
638
743
|
export async function tryServeSearch(argsList, execOptions = {}, opts = {}) {
|
|
639
744
|
if (searchServerDisabled()) return null;
|
|
640
745
|
const deadlineMs = callerDeadlineMs(execOptions, REQUEST_TIMEOUT_MS);
|
|
746
|
+
const canonical = canonicalSearchRequest(String(execOptions.cwd || process.cwd()), argsList);
|
|
641
747
|
const buildRequest = (server, remaining) => ({
|
|
642
748
|
id: ++server.sequence,
|
|
643
|
-
cwd:
|
|
644
|
-
args:
|
|
749
|
+
cwd: canonical.cwd,
|
|
750
|
+
args: [...canonical.args],
|
|
645
751
|
offset: Math.max(0, Math.floor(Number(opts.offset) || 0)),
|
|
646
752
|
limit: Number.isFinite(Number(opts.limit)) && Number(opts.limit) > 0 ? Math.floor(Number(opts.limit)) : 0,
|
|
647
753
|
deadlineMs: softDeadlineMs(remaining),
|
|
@@ -701,7 +807,7 @@ export async function tryServeSearch(argsList, execOptions = {}, opts = {}) {
|
|
|
701
807
|
? response.walkErrorDetails.map(String).slice(0, 8)
|
|
702
808
|
: [];
|
|
703
809
|
return {
|
|
704
|
-
lines: response.lines,
|
|
810
|
+
lines: restoreOperandSpelling(response.lines, canonical.remaps),
|
|
705
811
|
complete: response.complete === true,
|
|
706
812
|
totalSeen: Math.max(0, Math.floor(Number(response.totalSeen) || 0)),
|
|
707
813
|
partial: response.partial === true,
|
|
@@ -731,7 +837,8 @@ export async function tryServeFuzzySearch(args, execOptions = {}) {
|
|
|
731
837
|
const response = await requestNativeWithRestart(
|
|
732
838
|
(server, remaining) => ({
|
|
733
839
|
id: ++server.sequence,
|
|
734
|
-
|
|
840
|
+
// Matches are relative to cwd, so only the root needs canonicalizing.
|
|
841
|
+
cwd: canonicalPath(String(args?.cwd || execOptions.cwd || process.cwd())),
|
|
735
842
|
fuzzy: String(args?.query || ''),
|
|
736
843
|
limit: Math.max(1, Math.min(1_000, Math.floor(Number(args?.limit) || 25))),
|
|
737
844
|
hidden: args?.hidden !== false,
|
|
@@ -813,4 +920,5 @@ export function _resetNativeSearchClientForTest() {
|
|
|
813
920
|
_binaryResolveStarted = false;
|
|
814
921
|
_warmPromise = null;
|
|
815
922
|
_lastTimeoutRecycleAt = 0;
|
|
923
|
+
_inventorySnapshotChecked = false;
|
|
816
924
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { READ_BATCH_RANGE_COALESCE_GAP_LINES } from './read-constants.mjs';
|
|
2
|
+
import { windowMarker } from './tool-output-limit.mjs';
|
|
2
3
|
|
|
3
4
|
// Slices a `read` body (full mode) to the line window [origOffset+1,
|
|
4
5
|
// origOffset+origLimit] (1-based line numbers in the body). Lines whose
|
|
@@ -81,15 +82,15 @@ export function sliceReadBodyByLines(body, origOffset, origLimit, readOffsetBase
|
|
|
81
82
|
else if (finiteLast) requestedLast = lastLine;
|
|
82
83
|
const emittedStart = keptFirst ?? firstLine;
|
|
83
84
|
const emittedLast = keptLast !== null ? Math.min(requestedLast, keptLast) : requestedLast;
|
|
84
|
-
const totalPart = haveTotal ? ` of ${totalNum}` : '';
|
|
85
85
|
const moreToRead = haveTotal ? emittedLast < totalNum : finiteLast;
|
|
86
86
|
// Report the next caller coordinate without prescribing another read;
|
|
87
87
|
// whatever remains fits one wider read, not a walk window by window.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
88
|
+
const newFooter = windowMarker({
|
|
89
|
+
from: emittedStart,
|
|
90
|
+
to: emittedLast,
|
|
91
|
+
total: haveTotal ? totalNum : null,
|
|
92
|
+
nextOffset: moreToRead && Number.isFinite(emittedLast) ? emittedLast + readOffsetBase : null,
|
|
93
|
+
});
|
|
93
94
|
return kept.join('\n') + (kept.length ? '\n' : '') + newFooter;
|
|
94
95
|
}
|
|
95
96
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { READ_LINE_NO_SEP } from '../../../../shared/read-row-numbers.mjs';
|
|
2
2
|
import { mergeReadRanges } from './read-ranges.mjs';
|
|
3
|
-
import { TOOL_OUTPUT_MAX_BYTES, positiveEnvInt } from './tool-output-limit.mjs';
|
|
3
|
+
import { TOOL_OUTPUT_MAX_BYTES, capMarker, positiveEnvInt } from './tool-output-limit.mjs';
|
|
4
4
|
|
|
5
5
|
// Smart-truncate cap: a no-window read returns the file until this cap, past
|
|
6
6
|
// which head+tail are shown and the model pages the rest with offset (footer
|
|
@@ -18,9 +18,23 @@ const READ_MAX_RENDERED_LINE_CHARS = 2_000;
|
|
|
18
18
|
// (runtime/shared/read-row-numbers.mjs).
|
|
19
19
|
export const LINE_NO_SEP = READ_LINE_NO_SEP;
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Cap marker for the elided middle of a no-window read. With the omitted
|
|
22
|
+
// line span it names the continuation offset; without, narrowing advice.
|
|
23
|
+
export function buildSmartReadTruncationMarker(totalLines, fileBytes, omitted = null) {
|
|
22
24
|
const kb = Math.max(1, Math.round((Number(fileBytes) || 0) / 1024));
|
|
23
|
-
|
|
25
|
+
const limit = fileBytes > SMART_READ_MAX_BYTES ? SMART_READ_MAX_BYTES : `${SMART_READ_MAX_LINES} lines`;
|
|
26
|
+
if (!omitted) {
|
|
27
|
+
return capMarker({
|
|
28
|
+
limit,
|
|
29
|
+
shown: `${totalLines} lines / ${kb} KB`,
|
|
30
|
+
narrow: 'read located windows with {file_path, offset, limit}',
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return capMarker({
|
|
34
|
+
limit,
|
|
35
|
+
shown: `lines ${omitted.from}-${omitted.to} of ${totalLines} omitted (${kb} KB file)`,
|
|
36
|
+
nextOffset: omitted.from,
|
|
37
|
+
});
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
function rangeFromRenderedReadRows(rows, fallbackStartLine = 1) {
|
|
@@ -56,9 +70,10 @@ export function smartReadTruncate(renderedWithLineNos, totalLines, fileBytes) {
|
|
|
56
70
|
const tailRows = rows.slice(tailStart);
|
|
57
71
|
const head = headRows.join('\n');
|
|
58
72
|
const tail = tailRows.join('\n');
|
|
59
|
-
const marker = buildSmartReadTruncationMarker(totalLines, fileBytes);
|
|
73
|
+
const marker = buildSmartReadTruncationMarker(totalLines, fileBytes, { from: headCount + 1, to: tailStart });
|
|
60
74
|
return {
|
|
61
75
|
text: `${head}\n${marker}\n${tail}`,
|
|
76
|
+
marker,
|
|
62
77
|
truncated: true,
|
|
63
78
|
totalLines,
|
|
64
79
|
ranges: mergeReadRanges(
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { READ_MAX_LINE_COLLECT_BYTES } from './read-constants.mjs';
|
|
6
6
|
import { renderReadLine } from './read-formatting.mjs';
|
|
7
7
|
import { maybeRecordReadRangeAnchor } from './read-range-index.mjs';
|
|
8
|
+
import { capMarker, windowMarker } from './tool-output-limit.mjs';
|
|
8
9
|
|
|
9
10
|
export function createReadLineCollector({ offset, limit, bodyOutputBytes, rangeIndex, startLine, fileSize = 0 }) {
|
|
10
11
|
const collected = [];
|
|
@@ -148,10 +149,11 @@ export function createReadLineCollector({ offset, limit, bodyOutputBytes, rangeI
|
|
|
148
149
|
let out = collected.join('\n');
|
|
149
150
|
if (truncated) {
|
|
150
151
|
const nextOffset = (lastEmitted || offset) + readOffsetBase;
|
|
151
|
-
const ofFile = fileSize > 0 ?
|
|
152
|
-
out += `\n\n
|
|
152
|
+
const ofFile = fileSize > 0 ? `${Math.max(1, Math.round(fileSize / 1024))} KB file` : '';
|
|
153
|
+
out += `\n\n${capMarker({ limit: maxOutputBytes, shown: ofFile, nextOffset })}`;
|
|
153
154
|
} else if (stoppedAtLimit) {
|
|
154
|
-
|
|
155
|
+
const nextOffset = offset + collected.length + readOffsetBase;
|
|
156
|
+
out += `${out ? '\n' : ''}${windowMarker({ from: offset + 1, to: offset + collected.length, nextOffset })}`;
|
|
155
157
|
} else if (!out && offset >= lineIdx) {
|
|
156
158
|
out = `(no lines in range; file has ${lineIdx} lines)`;
|
|
157
159
|
}
|