mixdog 1.2.5 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/lib/gate-scheduler.mjs +2 -2
- 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 +2 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +10 -0
- package/src/defaults/skills/browser-use/SKILL.md +2 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +1 -1
- 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 +3 -1
- package/src/rules/lead/LEAD.md +4 -3
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +53 -60
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +40 -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 +1 -2
- 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/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-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-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 +2 -3
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +3 -8
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- 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/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +9 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- 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/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -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-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 +306 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +70 -21
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- 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/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-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- 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 +119 -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 +40 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -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 +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +35 -4
- 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/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +7 -5
- 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/atomic-file.mjs +22 -13
- 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 +0 -10
- 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/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/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/run-child.mjs +84 -0
- 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/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/user-data-guard.mjs +28 -9
- 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/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +7 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +19 -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/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/services/agent-tool/close-flow.mjs +2 -1
- 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-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/provider-admin.mjs +92 -20
- 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/turn/session-ops.mjs +2 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon.mjs +43 -13
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +1 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- 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/dist/index.mjs +385 -104
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/session-api/intake/submission.mjs +7 -13
- package/src/tui/session/session-api/integrations.mjs +1 -5
- package/src/tui/session/session-flow/drain.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +46 -0
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +30 -3
- 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
|
@@ -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
|
}
|
|
@@ -9,6 +9,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
9
9
|
import { sameFileVersion } from './file-version.mjs';
|
|
10
10
|
import { canCacheReadFile, READ_PREFIX_HASH_BYTES } from './read-cache-policy.mjs';
|
|
11
11
|
import { decodeUtf16Body, isUtf16Encoding } from './snapshot-helpers.mjs';
|
|
12
|
+
import { capMarker, windowMarker } from './tool-output-limit.mjs';
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
* Encoding-aware decode (fresh read AND raw-content cache hit both flow
|
|
@@ -51,17 +52,27 @@ function rangeFooter(ctx, render, rendered) {
|
|
|
51
52
|
const emittedStart = offset + 1;
|
|
52
53
|
if (byteCapTruncated) {
|
|
53
54
|
const emittedEnd = offset + renderedLineCount;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
return {
|
|
56
|
+
footer: windowMarker({
|
|
57
|
+
from: emittedStart,
|
|
58
|
+
to: emittedEnd,
|
|
59
|
+
total: lineCount,
|
|
60
|
+
capBytes: readMaxOutputBytes,
|
|
61
|
+
nextOffset: emittedEnd < lineCount ? emittedEnd + readOffsetBase : null,
|
|
62
|
+
}),
|
|
63
|
+
};
|
|
57
64
|
}
|
|
58
65
|
if (Buffer.byteLength(rendered, 'utf8') > readMaxOutputBytes) return {};
|
|
59
66
|
const emittedEnd = offset + sliced.length;
|
|
60
67
|
// Continuation uses the originating caller's coordinate base. Remaining
|
|
61
68
|
// content is not automatically required evidence; when it is, it fits one
|
|
62
69
|
// wider read, not a walk window by window.
|
|
63
|
-
const
|
|
64
|
-
|
|
70
|
+
const footer = windowMarker({
|
|
71
|
+
from: emittedStart,
|
|
72
|
+
to: emittedEnd,
|
|
73
|
+
total: lineCount,
|
|
74
|
+
nextOffset: emittedEnd < lineCount ? emittedEnd + readOffsetBase : null,
|
|
75
|
+
});
|
|
65
76
|
return { footer: widenNote ? `${footer}\n${widenNote}` : footer };
|
|
66
77
|
}
|
|
67
78
|
|
|
@@ -110,8 +121,15 @@ function renderReadWindow(content, ctx, helpers) {
|
|
|
110
121
|
const slice = byteCapSlice(rendered, readMaxOutputBytes);
|
|
111
122
|
render.renderedLineCount = Math.max(0, slice.split('\n').length - 1);
|
|
112
123
|
render.byteCapTruncated = true;
|
|
113
|
-
const ofFile = st?.size > 0 ?
|
|
114
|
-
|
|
124
|
+
const ofFile = st?.size > 0 ? `${Math.max(1, Math.round(st.size / 1024))} KB file` : '';
|
|
125
|
+
// A windowed read's footer already carries the cap and continuation.
|
|
126
|
+
out = hasRangeArgs
|
|
127
|
+
? slice
|
|
128
|
+
: `${slice}\n\n${capMarker({
|
|
129
|
+
limit: readMaxOutputBytes,
|
|
130
|
+
shown: ofFile ? `${render.renderedLineCount} of ${lineCount} lines shown (${ofFile})` : '',
|
|
131
|
+
nextOffset: offset + render.renderedLineCount + ctx.readOffsetBase,
|
|
132
|
+
})}`;
|
|
115
133
|
} else {
|
|
116
134
|
out = rendered;
|
|
117
135
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readFile, stat } from 'node:fs/promises';
|
|
2
2
|
import { MAX_PDF_BYTES, MAX_PDF_PAGES, isPdfBuffer } from '../../../../attachments/limits.mjs';
|
|
3
3
|
import { READ_MAX_SIZE_BYTES } from './read-constants.mjs';
|
|
4
|
+
import { capMarker } from './tool-output-limit.mjs';
|
|
4
5
|
import { imageBlocksFromBuffer } from './read-image-resize.mjs';
|
|
5
6
|
import { inspectPdfBuffer } from '../../../../attachments/pdf-extract.mjs';
|
|
6
7
|
|
|
@@ -190,7 +191,7 @@ function capNotebookText(blocks, maxOutputBytes) {
|
|
|
190
191
|
if (truncated) {
|
|
191
192
|
capped.push({
|
|
192
193
|
type: 'text',
|
|
193
|
-
text: `\n\n
|
|
194
|
+
text: `\n\n${capMarker({ limit: maxOutputBytes, shown: 'notebook cells cut', narrow: 'grep the notebook for the cell text you need' })}`,
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
return capped;
|
|
@@ -27,7 +27,9 @@ const bodyTextFor = (value) => {
|
|
|
27
27
|
.join('\n');
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
// The smart-read cap marker (read-formatting.mjs buildSmartReadTruncationMarker):
|
|
31
|
+
// `[output capped at X; lines a-b of N omitted (K KB file); offset:a for more]`.
|
|
32
|
+
const TRUNCATED_MARKER = /\[output capped at [^;\]]+; lines \d+-\d+ of (\d+) omitted \((\d+) KB file\);/;
|
|
31
33
|
// When `read` emitted a smart-cap marker, surface the truncation state in the
|
|
32
34
|
// header so downstream skimming spots it without parsing the body.
|
|
33
35
|
const truncatedSuffix = (textBody) => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { statSync } from 'node:fs';
|
|
2
|
+
import { capMarker, windowMarker } from './tool-output-limit.mjs';
|
|
2
3
|
import { isAbsolute, resolve } from 'node:path';
|
|
3
4
|
import { expandAbsoluteGlobs } from './lib/absolute-glob-expand.mjs';
|
|
4
5
|
import { buildGlobPatternGroups } from './lib/glob-static-prefix.mjs';
|
|
@@ -407,17 +408,22 @@ async function orderGlobPaths(unique, { nativeMtimeTotal, groupCount, sortMode,
|
|
|
407
408
|
|
|
408
409
|
function globIntegritySuffix({ accumTruncated, rgStdoutTruncated, rgStdoutPartial, rgErrors }) {
|
|
409
410
|
let truncSuffix = '';
|
|
410
|
-
|
|
411
|
-
if (
|
|
411
|
+
const narrow = 'narrow the pattern or path';
|
|
412
|
+
if (accumTruncated) {
|
|
413
|
+
truncSuffix = `\n${capMarker({ limit: `${GLOB_ACCUM_CAP} matches`, shown: 'results incomplete', narrow })}`;
|
|
414
|
+
}
|
|
415
|
+
if (rgStdoutTruncated) {
|
|
416
|
+
truncSuffix += `\n${capMarker({ limit: '20 MB of rg stdout', shown: 'results incomplete', narrow })}`;
|
|
417
|
+
}
|
|
412
418
|
if (rgStdoutPartial) truncSuffix += '\n... [warning] rg exit 2 (partial results); listing may be incomplete';
|
|
413
419
|
const errorSuffix = rgErrors.length > 0 ? `\n... [warning] ${rgErrors.join(' | ')}` : '';
|
|
414
420
|
return errorSuffix + truncSuffix;
|
|
415
421
|
}
|
|
416
422
|
|
|
417
|
-
function globMoreSuffix({ rgWindowIncomplete, remaining, totalBeforeOffset, nextOffset }) {
|
|
418
|
-
if (rgWindowIncomplete) return `\n
|
|
423
|
+
function globMoreSuffix({ rgWindowIncomplete, remaining, totalBeforeOffset, from, nextOffset }) {
|
|
424
|
+
if (rgWindowIncomplete) return `\n${windowMarker({ unit: 'entries', from, to: nextOffset, nextOffset })}`;
|
|
419
425
|
if (remaining > 0) {
|
|
420
|
-
return `\n
|
|
426
|
+
return `\n${windowMarker({ unit: 'entries', from, to: nextOffset, total: totalBeforeOffset, nextOffset })}`;
|
|
421
427
|
}
|
|
422
428
|
return '';
|
|
423
429
|
}
|
|
@@ -489,6 +495,7 @@ async function renderGlobPage(scan, merged, { capped, remaining, totalBeforeOffs
|
|
|
489
495
|
rgWindowIncomplete: merged.rgWindowIncomplete,
|
|
490
496
|
remaining,
|
|
491
497
|
totalBeforeOffset,
|
|
498
|
+
from: offset + 1,
|
|
492
499
|
nextOffset: offset + capped.length,
|
|
493
500
|
});
|
|
494
501
|
if (capped.length > 0) return `${capped.join('\n')}${moreSuffix}${errSuffix}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import { isAbsolute } from 'node:path';
|
|
2
|
+
import { isAbsolute, resolve as resolvePath, sep as pathSep } from 'node:path';
|
|
3
3
|
import {
|
|
4
4
|
coerceReadFamilyPathArg,
|
|
5
5
|
GREP_AUTO_CONTEXT_LINES,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
appendNotFoundCwdNote,
|
|
13
13
|
buildNotFoundHintBody,
|
|
14
14
|
finalizeReadFamilyEnoentTail,
|
|
15
|
+
realRootOf,
|
|
15
16
|
} from './search-path-diagnostics.mjs';
|
|
16
17
|
import { buildGrepCacheKey, buildGrepRgArgs } from './search-builders.mjs';
|
|
17
18
|
import { runRg, runRgWindowedLines } from './native-search-runner.mjs';
|
|
@@ -498,10 +499,7 @@ async function runLegacyContextGrep(scope, rgArgs) {
|
|
|
498
499
|
async function runPlainGrep(scope, rgArgs, effectiveHeadLimit) {
|
|
499
500
|
const { options, outputMode, headLimit, offset, cacheKey, grepResolvedPath } = scope;
|
|
500
501
|
const window = await collectGrepWindow(scope, rgArgs, effectiveHeadLimit);
|
|
501
|
-
|
|
502
|
-
if (outputMode === 'files_with_matches' && windowed.length > 1) {
|
|
503
|
-
windowed = await sortNewestFirst(windowed, scope.rgSpawnCwd);
|
|
504
|
-
}
|
|
502
|
+
const { windowed } = window;
|
|
505
503
|
let body = formatGrepOutput({
|
|
506
504
|
windowed,
|
|
507
505
|
totalWindowed: window.totalWindowed,
|
|
@@ -542,7 +540,12 @@ async function runPlainGrep(scope, rgArgs, effectiveHeadLimit) {
|
|
|
542
540
|
// complete.
|
|
543
541
|
async function collectGrepWindow(scope, rgArgs, effectiveHeadLimit) {
|
|
544
542
|
const { outputMode, offset, searchExecOptions } = scope;
|
|
545
|
-
|
|
543
|
+
// The native scan emits content matches in inventory path order (stable, so
|
|
544
|
+
// the streamed content window pages directly). File lists are presented
|
|
545
|
+
// newest-first, so they are pageable only once the WHOLE set is re-ordered;
|
|
546
|
+
// `offset` slices after the sort.
|
|
547
|
+
const fileList = outputMode === 'files_with_matches' || outputMode === 'count';
|
|
548
|
+
if (effectiveHeadLimit !== Infinity && !fileList) {
|
|
546
549
|
const streamed = await runRgWindowedLines(rgArgs, searchExecOptions, {
|
|
547
550
|
offset,
|
|
548
551
|
limit: effectiveHeadLimit,
|
|
@@ -556,7 +559,8 @@ async function collectGrepWindow(scope, rgArgs, effectiveHeadLimit) {
|
|
|
556
559
|
};
|
|
557
560
|
}
|
|
558
561
|
const stdout = await runRg(rgArgs, searchExecOptions);
|
|
559
|
-
|
|
562
|
+
let allLines = String(stdout).split('\n').filter(Boolean);
|
|
563
|
+
if (fileList) allLines = await orderFileListLines(unifyRootSpelling(allLines, scope), outputMode, scope.rgSpawnCwd);
|
|
560
564
|
const windowed = offset > 0 ? allLines.slice(offset) : allLines;
|
|
561
565
|
const boxed = typeof stdout === 'object' ? stdout : {};
|
|
562
566
|
return {
|
|
@@ -568,25 +572,60 @@ async function collectGrepWindow(scope, rgArgs, effectiveHeadLimit) {
|
|
|
568
572
|
};
|
|
569
573
|
}
|
|
570
574
|
|
|
571
|
-
//
|
|
572
|
-
//
|
|
573
|
-
//
|
|
574
|
-
//
|
|
575
|
-
//
|
|
576
|
-
|
|
577
|
-
|
|
575
|
+
// A search root reached through a symlink or junction (macOS /var ->
|
|
576
|
+
// /private/var) can come back from the walker under either spelling: rows that
|
|
577
|
+
// the inventory repaired after a filesystem event carry the realpath while the
|
|
578
|
+
// rest carry the given root. Left alone they sort apart, page twice and print
|
|
579
|
+
// as absolute paths. Rewrite realpath rows to the given spelling, then drop the
|
|
580
|
+
// repeats, so ordering, offset paging and relativization see one spelling.
|
|
581
|
+
function unifyRootSpelling(lines, scope) {
|
|
582
|
+
const given = scope.searchPath;
|
|
583
|
+
const absGiven = resolvePath(scope.rgSpawnCwd, given);
|
|
584
|
+
const real = realRootOf(absGiven);
|
|
585
|
+
if (real === absGiven) return lines;
|
|
586
|
+
const fold = (text) => (process.platform === 'win32' ? text.toLocaleLowerCase() : text);
|
|
587
|
+
const realPrefix = fold(`${real.replace(/\\/g, '/').replace(/\/+$/, '')}/`);
|
|
588
|
+
const sep = given.includes('/') && !given.includes('\\') ? '/' : pathSep;
|
|
589
|
+
const givenPrefix = `${given.replace(/[\\/]+$/, '')}${sep}`;
|
|
590
|
+
const seen = new Set();
|
|
591
|
+
const unified = [];
|
|
592
|
+
for (const line of lines) {
|
|
593
|
+
const fwd = line.replace(/\\/g, '/');
|
|
594
|
+
const row = fold(fwd).startsWith(realPrefix)
|
|
595
|
+
? givenPrefix + fwd.slice(realPrefix.length).replace(/\//g, sep)
|
|
596
|
+
: line;
|
|
597
|
+
if (seen.has(row)) continue;
|
|
598
|
+
seen.add(row);
|
|
599
|
+
unified.push(row);
|
|
600
|
+
}
|
|
601
|
+
return unified;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
function compareCodeUnits(a, b) {
|
|
605
|
+
if (a === b) return 0;
|
|
606
|
+
return a < b ? -1 : 1;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Total order over the complete file list, applied BEFORE offset/limit slice:
|
|
610
|
+
// files_with_matches is newest-first (mtime desc, path tiebreak) so recently
|
|
611
|
+
// edited files surface first; stat-failed entries follow in path order
|
|
612
|
+
// (statting is bounded: 64 workers, 5s deadline). count lines sort by path.
|
|
613
|
+
async function orderFileListLines(lines, outputMode, rgSpawnCwd) {
|
|
614
|
+
if (lines.length < 2) return lines;
|
|
615
|
+
if (outputMode === 'count') {
|
|
616
|
+
const pathOf = (line) => parseGrepCountLine(line)?.path ?? line;
|
|
617
|
+
return [...lines].sort((a, b) => compareCodeUnits(pathOf(a), pathOf(b)) || compareCodeUnits(a, b));
|
|
618
|
+
}
|
|
619
|
+
const withStat = await statPathsForMtime(lines, rgSpawnCwd, 64, { deadlineMs: 5000 });
|
|
578
620
|
const statted = [];
|
|
579
621
|
const unstatted = [];
|
|
580
|
-
for (let i = 0; i <
|
|
622
|
+
for (let i = 0; i < lines.length; i++) {
|
|
581
623
|
const entry = withStat[i];
|
|
582
|
-
if (entry?.stat) statted.push({ line:
|
|
583
|
-
else unstatted.push(
|
|
624
|
+
if (entry?.stat) statted.push({ line: lines[i], mtimeMs: entry.mtimeMs });
|
|
625
|
+
else unstatted.push(lines[i]);
|
|
584
626
|
}
|
|
585
|
-
statted.sort((a, b) =>
|
|
586
|
-
|
|
587
|
-
if (dm !== 0) return dm;
|
|
588
|
-
return a.line.localeCompare(b.line);
|
|
589
|
-
});
|
|
627
|
+
statted.sort((a, b) => b.mtimeMs - a.mtimeMs || compareCodeUnits(a.line, b.line));
|
|
628
|
+
unstatted.sort(compareCodeUnits);
|
|
590
629
|
return [...statted.map((e) => e.line), ...unstatted];
|
|
591
630
|
}
|
|
592
631
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* grep/glob in search-tool.mjs. search-tool.mjs re-exports these for unchanged
|
|
4
4
|
* importers so it can stay a thin executor.
|
|
5
5
|
*/
|
|
6
|
-
import { statSync } from 'node:fs';
|
|
6
|
+
import { realpathSync, statSync } from 'node:fs';
|
|
7
7
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
8
8
|
import { findDirectoryByBasename, findFileByBasename, listSiblings } from './path-diagnostics.mjs';
|
|
9
9
|
import { normalizeOutputPath, resolveAgainstCwd } from './path-utils.mjs';
|
|
@@ -233,16 +233,40 @@ export async function buildNotFoundHintBody(workDir, missingPath, actionVerb, er
|
|
|
233
233
|
return elsewhere.exhaustive === true ? ENOENT_ABSENT : '';
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
+
// The realpath of a working directory, memoized: a search root reached through
|
|
237
|
+
// a symlink or junction (macOS /var -> /private/var) is reported by the walker
|
|
238
|
+
// under its realpath, so results must be relativized against both spellings.
|
|
239
|
+
const realRootCache = new Map();
|
|
240
|
+
const REAL_ROOT_CACHE_MAX = 64;
|
|
241
|
+
export function realRootOf(root) {
|
|
242
|
+
if (realRootCache.has(root)) return realRootCache.get(root);
|
|
243
|
+
let real;
|
|
244
|
+
try {
|
|
245
|
+
real = realpathSync.native(root);
|
|
246
|
+
} catch {
|
|
247
|
+
return root;
|
|
248
|
+
}
|
|
249
|
+
if (realRootCache.size >= REAL_ROOT_CACHE_MAX) realRootCache.clear();
|
|
250
|
+
realRootCache.set(root, real);
|
|
251
|
+
return real;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function relativeUnderRoot(absFwd, root) {
|
|
255
|
+
const rootFwd = root.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
256
|
+
const haystack = process.platform === 'win32' ? absFwd.toLocaleLowerCase() : absFwd;
|
|
257
|
+
const needle = process.platform === 'win32' ? rootFwd.toLocaleLowerCase() : rootFwd;
|
|
258
|
+
if (haystack.startsWith(`${needle}/`) || haystack === needle) return absFwd.slice(rootFwd.length + 1) || '.';
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
|
|
236
262
|
export function relativePathPrefix(pathPrefix, workDir) {
|
|
237
263
|
if (!workDir) return pathPrefix;
|
|
238
|
-
const cwdFwd = workDir.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
239
264
|
const absFwd = String(pathPrefix || '').replace(/\\/g, '/');
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return pathPrefix;
|
|
265
|
+
const given = relativeUnderRoot(absFwd, workDir);
|
|
266
|
+
if (given !== null) return given;
|
|
267
|
+
const real = realRootOf(workDir);
|
|
268
|
+
if (real === workDir) return pathPrefix;
|
|
269
|
+
return relativeUnderRoot(absFwd, real) ?? pathPrefix;
|
|
246
270
|
}
|
|
247
271
|
|
|
248
272
|
export function relativeSearchResultPath(path, workDir) {
|