mixdog 0.9.3 → 0.9.5
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/README.md +112 -38
- package/package.json +10 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/r5-orchestrated-task.json +7 -0
- package/scripts/bench/review-tasks.json +20 -0
- package/scripts/bench/round-codex.json +114 -0
- package/scripts/bench/round-mixdog-lead-r3.json +269 -0
- package/scripts/bench/round-mixdog-lead.json +269 -0
- package/scripts/bench/round-mixdog.json +126 -0
- package/scripts/bench/round-r10-bigsample.json +679 -0
- package/scripts/bench/round-r11-codexalign.json +257 -0
- package/scripts/bench/round-r13-clientmeta.json +464 -0
- package/scripts/bench/round-r14-betafeatures.json +466 -0
- package/scripts/bench/round-r15-fulldefault.json +462 -0
- package/scripts/bench/round-r16-sessionid.json +466 -0
- package/scripts/bench/round-r17-wirebytes.json +456 -0
- package/scripts/bench/round-r18-prewarm.json +468 -0
- package/scripts/bench/round-r19-clean.json +472 -0
- package/scripts/bench/round-r20-prewarm-clean.json +475 -0
- package/scripts/bench/round-r21-delta-retry.json +473 -0
- package/scripts/bench/round-r22-full-probe.json +693 -0
- package/scripts/bench/round-r23-itemprobe.json +701 -0
- package/scripts/bench/round-r24-shapefix.json +677 -0
- package/scripts/bench/round-r25-serial.json +464 -0
- package/scripts/bench/round-r26-parallel3.json +671 -0
- package/scripts/bench/round-r27-parallel10.json +894 -0
- package/scripts/bench/round-r28-parallel10-stagger.json +882 -0
- package/scripts/bench/round-r29-parallel10-stagger166.json +886 -0
- package/scripts/bench/round-r30-instid.json +253 -0
- package/scripts/bench/round-r31-upgradeprobe.json +256 -0
- package/scripts/bench/round-r32-vs-codex-lead.json +254 -0
- package/scripts/bench/round-r33-vs-codex-codex.json +115 -0
- package/scripts/bench/round-r34-orchestrated.json +120 -0
- package/scripts/bench/round-r35-orchestrated-codex.json +61 -0
- package/scripts/bench/round-r36-orchestrated-capped.json +128 -0
- package/scripts/bench/round-r4-codex.json +114 -0
- package/scripts/bench/round-r4-mixed.json +225 -0
- package/scripts/bench/round-r5-gpt-lead.json +259 -0
- package/scripts/bench/round-r6-codex.json +114 -0
- package/scripts/bench/round-r6-solo.json +257 -0
- package/scripts/bench/round-r7-full.json +254 -0
- package/scripts/bench/round-r8-fulldefault.json +255 -0
- package/scripts/bench-run.mjs +251 -32
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/internal-comms-bench.mjs +3 -4
- package/scripts/internal-comms-smoke.mjs +10 -9
- package/scripts/model-catalog-audit.mjs +209 -0
- package/scripts/model-list-sanitize-test.mjs +37 -0
- package/scripts/mouse-probe.mjs +45 -0
- package/scripts/output-style-bench.mjs +13 -6
- package/scripts/output-style-smoke.mjs +4 -4
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-bench.mjs +76 -13
- package/scripts/recall-quality-cases.json +12 -0
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +25 -65
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +9 -8
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/scheduler-task/AGENT.md +2 -3
- package/src/agents/webhook-handler/AGENT.md +2 -3
- package/src/agents/worker/AGENT.md +10 -7
- package/src/app.mjs +12 -1
- package/src/headless-role.mjs +7 -1
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +647 -2056
- package/src/output-styles/default.md +30 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +8 -6
- package/src/output-styles/simple.md +21 -7
- package/src/rules/agent/00-common.md +6 -3
- package/src/rules/agent/30-explorer.md +16 -5
- package/src/rules/lead/01-general.md +5 -5
- package/src/rules/lead/lead-brief.md +15 -0
- package/src/rules/lead/lead-tool.md +6 -15
- package/src/rules/shared/01-tool.md +17 -21
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +8 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +105 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +356 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +740 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +349 -2131
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +143 -1002
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +465 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +275 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +278 -402
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +35 -44
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +27 -318
- package/src/runtime/channels/backends/telegram.mjs +8 -12
- package/src/runtime/channels/index.mjs +247 -701
- package/src/runtime/channels/lib/backend-dispatch.mjs +46 -0
- package/src/runtime/channels/lib/config.mjs +37 -149
- package/src/runtime/channels/lib/event-pipeline.mjs +22 -5
- package/src/runtime/channels/lib/event-queue.mjs +78 -13
- package/src/runtime/channels/lib/inbound-routing.mjs +74 -0
- package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/scheduler.mjs +27 -113
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +313 -0
- package/src/runtime/channels/lib/webhook/log.mjs +42 -0
- package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
- package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
- package/src/runtime/channels/lib/webhook.mjs +43 -616
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +210 -1948
- package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/ko-morph.mjs +195 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +69 -12
- package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +802 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/config.mjs +14 -4
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/markdown-frontmatter.mjs +19 -0
- package/src/runtime/shared/schedules-store.mjs +13 -3
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +119 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +205 -0
- package/src/session-runtime/quick-search-models.mjs +47 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/settings-api.mjs +352 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/session-runtime/workflow.mjs +1 -1
- package/src/standalone/agent-tool/helpers.mjs +237 -0
- package/src/standalone/agent-tool/notify.mjs +107 -0
- package/src/standalone/agent-tool/provider-init.mjs +143 -0
- package/src/standalone/agent-tool/render.mjs +152 -0
- package/src/standalone/agent-tool/tool-def.mjs +55 -0
- package/src/standalone/agent-tool.mjs +138 -669
- package/src/standalone/channel-admin.mjs +102 -90
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +64 -14
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +1059 -8110
- package/src/tui/app/app-format.mjs +213 -0
- package/src/tui/app/channel-pickers.mjs +508 -0
- package/src/tui/app/clipboard.mjs +67 -0
- package/src/tui/app/core-memory-picker.mjs +210 -0
- package/src/tui/app/extension-pickers.mjs +506 -0
- package/src/tui/app/input-parsers.mjs +193 -0
- package/src/tui/app/maintenance-pickers.mjs +356 -0
- package/src/tui/app/model-options.mjs +334 -0
- package/src/tui/app/model-picker.mjs +365 -0
- package/src/tui/app/onboarding-steps.mjs +400 -0
- package/src/tui/app/project-picker.mjs +247 -0
- package/src/tui/app/provider-setup-picker.mjs +580 -0
- package/src/tui/app/resume-picker.mjs +55 -0
- package/src/tui/app/route-pickers.mjs +419 -0
- package/src/tui/app/settings-picker.mjs +489 -0
- package/src/tui/app/slash-commands.mjs +101 -0
- package/src/tui/app/slash-dispatch.mjs +427 -0
- package/src/tui/app/text-layout.mjs +46 -0
- package/src/tui/app/theme-effort-pickers.mjs +154 -0
- package/src/tui/app/transcript-window.mjs +677 -0
- package/src/tui/app/use-mouse-input.mjs +460 -0
- package/src/tui/app/use-prompt-handlers.mjs +310 -0
- package/src/tui/app/use-transcript-scroll.mjs +512 -0
- package/src/tui/app/use-transcript-window.mjs +607 -0
- package/src/tui/components/ConfirmBar.jsx +10 -7
- package/src/tui/components/Picker.jsx +64 -15
- package/src/tui/components/PromptInput.jsx +33 -102
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +69 -15
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +13553 -12384
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +170 -574
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +65 -1
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +77 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +16 -18
- package/src/workflows/sequential/WORKFLOW.md +16 -18
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +112 -7
- package/vendor/ink/build/log-update.js +17 -3
- package/vendor/ink/build/wrap-text.js +125 -0
- package/scripts/_test-folder-dialog.mjs +0 -30
- package/scripts/fix-brief-fn.mjs +0 -35
- package/scripts/fix-format-tool-surface.mjs +0 -24
- package/scripts/fix-tool-exec-visible.mjs +0 -42
- package/scripts/patch-agent-brief.mjs +0 -48
- package/scripts/patch-app.mjs +0 -21
- package/scripts/patch-app2.mjs +0 -18
- package/scripts/patch-dist-brief.mjs +0 -96
- package/scripts/patch-tool-exec.mjs +0 -70
- package/src/examples/schedules/SCHEDULE.example.md +0 -32
- package/src/examples/webhooks/WEBHOOK.example.md +0 -40
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
- package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
- package/src/runtime/channels/lib/holidays.mjs +0 -138
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TranscriptItem.jsx — per-item transcript renderer (Item) + the hook-denial
|
|
3
|
+
* tool card. Extracted verbatim from App.jsx.
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { Box, Text } from 'ink';
|
|
7
|
+
import stringWidth from 'string-width';
|
|
8
|
+
import stripAnsi from 'strip-ansi';
|
|
9
|
+
import { theme, TURN_MARKER, RESULT_GUTTER } from '../theme.mjs';
|
|
10
|
+
import { AssistantMessage, UserMessage, NoticeMessage } from './Message.jsx';
|
|
11
|
+
import { ToolExecution } from './ToolExecution.jsx';
|
|
12
|
+
import { StatusDone, TurnDone } from './TurnDone.jsx';
|
|
13
|
+
import { ItemRightHintOverprint } from './ItemRightHintOverprint.jsx';
|
|
14
|
+
import { formatToolSurface } from '../../runtime/shared/tool-surface.mjs';
|
|
15
|
+
import {
|
|
16
|
+
formatHookDenialDetail,
|
|
17
|
+
isHookApprovalDenialToolItem,
|
|
18
|
+
shouldSuppressFullyFailedToolItem,
|
|
19
|
+
toolItemResultText,
|
|
20
|
+
} from '../transcript-tool-failures.mjs';
|
|
21
|
+
|
|
22
|
+
export function ToolHookDenialCard({ item, columns = 80 }) {
|
|
23
|
+
const { label, summary } = formatToolSurface(item.name, item.args);
|
|
24
|
+
const detail = formatHookDenialDetail(toolItemResultText(item));
|
|
25
|
+
const safeLabel = stripAnsi(String(label || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
26
|
+
const safeSummary = stripAnsi(String(summary || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
27
|
+
const safeDetail = stripAnsi(String(detail || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
|
|
28
|
+
const summaryText = safeSummary ? ` (${safeSummary})` : '';
|
|
29
|
+
const rowWidth = Math.max(1, Number(columns || 80));
|
|
30
|
+
const detailWidth = Math.max(1, rowWidth - stringWidth(RESULT_GUTTER));
|
|
31
|
+
return (
|
|
32
|
+
<Box flexDirection="column" marginTop={1} width={rowWidth} overflow="hidden">
|
|
33
|
+
<Box flexDirection="row" width={rowWidth} overflow="hidden">
|
|
34
|
+
<Box flexShrink={0} minWidth={2}>
|
|
35
|
+
<Text color={theme.error}>{TURN_MARKER}</Text>
|
|
36
|
+
</Box>
|
|
37
|
+
<Box flexGrow={1} flexShrink={1} overflow="hidden" minWidth={0}>
|
|
38
|
+
<Text wrap="truncate">
|
|
39
|
+
<Text bold color={theme.text}>{safeLabel}</Text>
|
|
40
|
+
{summaryText ? <Text color={theme.text}>{summaryText}</Text> : null}
|
|
41
|
+
<Text color={theme.error}> · Denied</Text>
|
|
42
|
+
</Text>
|
|
43
|
+
</Box>
|
|
44
|
+
</Box>
|
|
45
|
+
{safeDetail ? (
|
|
46
|
+
<Box flexDirection="row" width={rowWidth} overflow="hidden">
|
|
47
|
+
<Box flexShrink={0} width={stringWidth(RESULT_GUTTER)}>
|
|
48
|
+
<Text color={theme.subtle}>{RESULT_GUTTER}</Text>
|
|
49
|
+
</Box>
|
|
50
|
+
<Box flexShrink={0} width={detailWidth} overflow="hidden">
|
|
51
|
+
<Text color={theme.error} wrap="truncate">{safeDetail}</Text>
|
|
52
|
+
</Box>
|
|
53
|
+
</Box>
|
|
54
|
+
) : null}
|
|
55
|
+
</Box>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// `themeEpoch` is read but not used in the body: it is a memo-busting prop. The
|
|
60
|
+
// active theme mutates `theme` in-place, so a switch must force every mounted
|
|
61
|
+
// transcript row (which reads theme.* directly) to re-render. Threading the
|
|
62
|
+
// epoch through Item → AssistantMessage/UserMessage/ToolExecution breaks
|
|
63
|
+
// React.memo's shallow equality on a theme change without a broad refactor.
|
|
64
|
+
export const Item = React.memo(function Item({ item, prevKind, columns, toolOutputExpanded, rightMessage = '', rightTone = 'info', rightMessageWidth = 24, themeEpoch = 0 }) {
|
|
65
|
+
const hintOnTurnDoneRow = item.kind === 'turndone' || item.kind === 'statusdone';
|
|
66
|
+
let node = null;
|
|
67
|
+
switch (item.kind) {
|
|
68
|
+
case 'user':
|
|
69
|
+
node = <UserMessage text={item.text} attached={prevKind === 'user'} columns={columns} themeEpoch={themeEpoch} />;
|
|
70
|
+
break;
|
|
71
|
+
case 'assistant':
|
|
72
|
+
node = <AssistantMessage text={item.text} streaming={item.streaming} columns={columns} themeEpoch={themeEpoch} assistantId={item.id} />;
|
|
73
|
+
break;
|
|
74
|
+
case 'tool': {
|
|
75
|
+
if (shouldSuppressFullyFailedToolItem(item)) return null;
|
|
76
|
+
if (isHookApprovalDenialToolItem(item)) {
|
|
77
|
+
node = <ToolHookDenialCard item={item} columns={columns} />;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
node = <ToolExecution name={item.name} args={item.args} result={item.result} rawResult={item.rawResult} isError={item.isError} errorCount={item.errorCount} expanded={toolOutputExpanded || item.expanded} columns={columns} attached={false} count={item.count} completedCount={item.completedCount} startedAt={item.startedAt} completedAt={item.completedAt} aggregate={item.aggregate} categories={item.categories} headerFinalized={item.headerFinalized} deferredDisplayReady={item.deferredDisplayReady} themeEpoch={themeEpoch} />;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case 'notice':
|
|
84
|
+
node = <NoticeMessage text={item.text} tone={item.tone} columns={columns} />;
|
|
85
|
+
break;
|
|
86
|
+
case 'turndone':
|
|
87
|
+
node = <TurnDone elapsedMs={item.elapsedMs} status={item.status} outputTokens={item.outputTokens} thinkingElapsedMs={item.thinkingElapsedMs} verb={item.verb} rightMessage={rightMessage} rightTone={rightTone} rightMessageWidth={rightMessageWidth} />;
|
|
88
|
+
break;
|
|
89
|
+
case 'statusdone':
|
|
90
|
+
node = <StatusDone label={item.label} detail={item.detail} rightMessage={rightMessage} rightTone={rightTone} rightMessageWidth={rightMessageWidth} />;
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (!node || hintOnTurnDoneRow || !rightMessage) return node;
|
|
96
|
+
return (
|
|
97
|
+
<ItemRightHintOverprint
|
|
98
|
+
rightMessage={rightMessage}
|
|
99
|
+
rightTone={rightTone}
|
|
100
|
+
rightMessageWidth={rightMessageWidth}
|
|
101
|
+
>
|
|
102
|
+
{node}
|
|
103
|
+
</ItemRightHintOverprint>
|
|
104
|
+
);
|
|
105
|
+
});
|
|
@@ -108,6 +108,12 @@ function windowValue(w) {
|
|
|
108
108
|
const limitCredits = Number(w?.limitCredits);
|
|
109
109
|
const usedPct = Number(w?.usedPct);
|
|
110
110
|
const prefix = estimated ? 'est ' : '';
|
|
111
|
+
// Percent first: windows that carry usedPct (OAuth quotas, OpenCode Go
|
|
112
|
+
// console) all render as "5H 17%" so provider rows stay uniform; dollar
|
|
113
|
+
// remaining is the fallback for billing-style windows without a percent.
|
|
114
|
+
if (hasFiniteNumber(w?.usedPct)) {
|
|
115
|
+
return { text: `${prefix}${Math.round(usedPct)}%`, color: estimated ? theme.warning : pctColor(usedPct) };
|
|
116
|
+
}
|
|
111
117
|
if (hasFiniteNumber(w?.remainingUsd)) {
|
|
112
118
|
return { text: `${prefix}${money(remainingUsd)}`, color: estimated ? theme.warning : remainingUsdColor(remainingUsd) };
|
|
113
119
|
}
|
|
@@ -123,9 +129,6 @@ function windowValue(w) {
|
|
|
123
129
|
if (hasFiniteNumber(w?.usedCredits) && hasFiniteNumber(w?.limitCredits)) {
|
|
124
130
|
return { text: `${prefix}${compactNumber(usedCredits)}/${compactNumber(limitCredits)}`, color: estimated ? theme.warning : creditsColor(w) };
|
|
125
131
|
}
|
|
126
|
-
if (hasFiniteNumber(w?.usedPct)) {
|
|
127
|
-
return { text: `${prefix}${Math.round(usedPct)}%`, color: estimated ? theme.warning : pctColor(usedPct) };
|
|
128
|
-
}
|
|
129
132
|
return { text: '', color: theme.subtle };
|
|
130
133
|
}
|
|
131
134
|
|
|
@@ -171,7 +174,15 @@ function rowStatusParts(row, columns = 80, statusWidth = 0) {
|
|
|
171
174
|
const showCredit = hasCredit && (columns >= 80 || windows.length === 0);
|
|
172
175
|
if (windows.length || showCredit) {
|
|
173
176
|
const maxWindows = windows.length ? maxStatusWindows(columns, statusWidth, showCredit) : 0;
|
|
174
|
-
|
|
177
|
+
let visibleWindows = windows.slice(0, maxWindows);
|
|
178
|
+
if (windows.length > maxWindows && maxWindows > 0) {
|
|
179
|
+
// Don't let an actively-used window (e.g. monthly at 17%) get cut in
|
|
180
|
+
// favor of idle 0% windows; keep the top-usage windows in list order.
|
|
181
|
+
const ranked = [...windows]
|
|
182
|
+
.sort((a, b) => (Number(b?.usedPct) || 0) - (Number(a?.usedPct) || 0))
|
|
183
|
+
.slice(0, maxWindows);
|
|
184
|
+
visibleWindows = windows.filter((w) => ranked.includes(w));
|
|
185
|
+
}
|
|
175
186
|
for (const window of visibleWindows) {
|
|
176
187
|
pushStatusSeparator(parts);
|
|
177
188
|
parts.push(...windowSegmentParts(window));
|
|
@@ -186,6 +197,9 @@ function rowStatusParts(row, columns = 80, statusWidth = 0) {
|
|
|
186
197
|
case 'checking':
|
|
187
198
|
return [{ text: 'checking...', color: theme.inactive }];
|
|
188
199
|
case 'hidden':
|
|
200
|
+
// Provider balance can't be accurately refreshed (no/failed balance
|
|
201
|
+
// API): show an explicit "-" placeholder instead of a blank cell.
|
|
202
|
+
return [{ text: row?.primary || '-', color: theme.inactive }];
|
|
189
203
|
case 'missing':
|
|
190
204
|
case 'local':
|
|
191
205
|
case 'error':
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* components/prompt-input/edit-helpers.mjs — pure prompt-editor helpers (no
|
|
3
|
+
* React): hint styling, insert/draft-compare, pasted-text normalization, and
|
|
4
|
+
* modified-Enter (kitty / modifyOtherKeys) sequence recognition. Extracted
|
|
5
|
+
* verbatim from PromptInput.jsx — behavior unchanged.
|
|
6
|
+
*/
|
|
7
|
+
import { theme } from '../../theme.mjs';
|
|
8
|
+
import { replaceSelection } from '../../input-editing.mjs';
|
|
9
|
+
|
|
10
|
+
export function hintStyle(tone) {
|
|
11
|
+
if (tone === 'error') return { textColor: theme.error };
|
|
12
|
+
if (tone === 'warn' || tone === 'cancel') return { textColor: theme.warning };
|
|
13
|
+
if (tone === 'plain') return { textColor: theme.subtle };
|
|
14
|
+
return { textColor: theme.inactive };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function insertText(draft, input) {
|
|
18
|
+
if (!input) return draft;
|
|
19
|
+
return replaceSelection(draft, input);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function normalizePastedText(text) {
|
|
23
|
+
return String(text ?? '').replace(/\r\n?/g, '\n');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function singleTrailingLineBreakPrefix(text) {
|
|
27
|
+
const normalized = normalizePastedText(text);
|
|
28
|
+
if (!normalized.endsWith('\n')) return null;
|
|
29
|
+
const prefix = normalized.slice(0, -1);
|
|
30
|
+
return prefix.includes('\n') ? null : prefix;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function draftStateEqual(a, b) {
|
|
34
|
+
return (
|
|
35
|
+
a.value === b.value
|
|
36
|
+
&& a.cursor === b.cursor
|
|
37
|
+
&& a.selectionAnchor === b.selectionAnchor
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Recognize a MODIFIED Enter delivered via the kitty keyboard protocol
|
|
42
|
+
// (\x1b[13;<mod>u) or modifyOtherKeys (\x1b[27;<mod>;13~). The xterm modifier
|
|
43
|
+
// param is (1 + bitmask) where the bitmask bits are shift=1, alt=2, ctrl=4. We
|
|
44
|
+
// treat Ctrl+Enter AND Shift+Enter (the two common "insert newline" chords) as a
|
|
45
|
+
// newline, so we match when the shift OR ctrl bit is set. Ctrl+J is handled
|
|
46
|
+
// separately as the protocol-independent fallback.
|
|
47
|
+
const MODIFIED_ENTER_SHIFT_OR_CTRL = 1 | 4;
|
|
48
|
+
|
|
49
|
+
export function isModifiedEnterSequence(input) {
|
|
50
|
+
const text = String(input ?? '');
|
|
51
|
+
const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
|
|
52
|
+
if (!body) return false;
|
|
53
|
+
const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
|
|
54
|
+
if (kitty) return ((Number(kitty[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0;
|
|
55
|
+
const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
|
|
56
|
+
return Boolean(modifyOtherKeys && (((Number(modifyOtherKeys[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Recognize ANY modified Enter (any modifier bitmask, e.g. Alt+Enter \x1b[13;3u
|
|
60
|
+
// / \x1b[27;3;13~). Used to CONSUME modified-Enter sequences we don't map to a
|
|
61
|
+
// newline (Alt-only, etc.) so they aren't typed into the prompt as raw CSI text
|
|
62
|
+
// under modifyOtherKeys. Plain Enter (mod param = 1, bitmask 0) is intentionally
|
|
63
|
+
// NOT matched, so it still submits.
|
|
64
|
+
export function isAnyModifiedEnterSequence(input) {
|
|
65
|
+
const text = String(input ?? '');
|
|
66
|
+
const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
|
|
67
|
+
if (!body) return false;
|
|
68
|
+
const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
|
|
69
|
+
if (kitty) return (Number(kitty[1]) - 1) !== 0;
|
|
70
|
+
const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
|
|
71
|
+
return Boolean(modifyOtherKeys && ((Number(modifyOtherKeys[1]) - 1) !== 0));
|
|
72
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* components/prompt-input/voice-indicator.mjs — voice-indicator glyph frames,
|
|
3
|
+
* timing constants, and frame-selection helper for the prompt box right edge.
|
|
4
|
+
* Pure (no React). Extracted verbatim from PromptInput.jsx — behavior unchanged.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Monotone voice indicator glyphs — right end of the prompt box. All frames
|
|
8
|
+
// are 1-cell-wide (no emoji, no string-width special-casing needed). Modes:
|
|
9
|
+
// 'off' — voice disabled and no install in flight: renders nothing,
|
|
10
|
+
// zero reserved columns.
|
|
11
|
+
// 'installing' — voice-runtime download in progress (progressHint active):
|
|
12
|
+
// braille spinner only.
|
|
13
|
+
// 'idle' — voice enabled, recorder idle: a STATIC ○ glyph. No
|
|
14
|
+
// animation — an animated idle reads as "something is
|
|
15
|
+
// running" when nothing is, and the old pulse frames
|
|
16
|
+
// (◎ ◍ ◉ ◍) rendered as tofu/odd-width glyphs in common
|
|
17
|
+
// Windows Terminal fonts (◍ U+25CD especially).
|
|
18
|
+
// 'recording' — steady ● + a braille spinner riding next to it (2 cells).
|
|
19
|
+
// 'transcribing' — braille spinner only (recording just stopped, awaiting
|
|
20
|
+
// the whisper-server round-trip).
|
|
21
|
+
// A single ~120ms interval drives the braille cycle, and it only exists
|
|
22
|
+
// while an ANIMATED mode is active (installing/recording/transcribing) —
|
|
23
|
+
// 'idle' and 'off' need no timer at all.
|
|
24
|
+
export const VOICE_BRAILLE_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧'];
|
|
25
|
+
export const VOICE_IDLE_GLYPH = '○';
|
|
26
|
+
export const VOICE_TICK_MS = 120;
|
|
27
|
+
|
|
28
|
+
// Resolve the indicator glyph text for a given mode + animation tick. Returns
|
|
29
|
+
// '' (rendered as null / zero reserved columns) when the indicator is hidden.
|
|
30
|
+
export function voiceIndicatorTextFor(mode, tick) {
|
|
31
|
+
const voiceBrailleFrame = VOICE_BRAILLE_FRAMES[tick % VOICE_BRAILLE_FRAMES.length];
|
|
32
|
+
return mode === 'installing' || mode === 'transcribing'
|
|
33
|
+
? voiceBrailleFrame
|
|
34
|
+
: mode === 'recording'
|
|
35
|
+
? `●${voiceBrailleFrame}`
|
|
36
|
+
: mode === 'idle'
|
|
37
|
+
? VOICE_IDLE_GLYPH
|
|
38
|
+
: '';
|
|
39
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* components/tool-execution/ResultBody.jsx — the multi-line result body under
|
|
3
|
+
* the ⎿ gutter (COLLAPSED fitted summary or EXPANDED raw). Extracted verbatim
|
|
4
|
+
* from ToolExecution.jsx — behavior unchanged.
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { Box, Text } from 'ink';
|
|
8
|
+
import { theme, RESULT_GUTTER, RESULT_GUTTER_CONT } from '../../theme.mjs';
|
|
9
|
+
import { formatExpandedResult, wrapExpandedResultLines } from '../tool-output-format.mjs';
|
|
10
|
+
import { deltaTextParts, fitResultLine } from './text-format.mjs';
|
|
11
|
+
|
|
12
|
+
export function renderDeltaText(text) {
|
|
13
|
+
return deltaTextParts(text).map((part, index) => (
|
|
14
|
+
part.color ? <Text key={index} color={part.color}>{part.text}</Text> : part.text
|
|
15
|
+
));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Shared multi-line result body: `└` on the first row, `│` continuation rail on
|
|
19
|
+
// every following row, body text in one flex column so wrapping stays aligned
|
|
20
|
+
// under the head gutter.
|
|
21
|
+
//
|
|
22
|
+
// Two render paths:
|
|
23
|
+
// - COLLAPSED (raw=false): a single fitted summary line, diff(+/-) colored via
|
|
24
|
+
// renderDeltaText.
|
|
25
|
+
// - EXPANDED (raw=true): formatExpandedResult then wrapExpandedResultLines so
|
|
26
|
+
// each physical row fits the body width before render (rail rows stay 1:1;
|
|
27
|
+
// ink does not re-wrap). Physical row mount cap: MIXDOG_TUI_TOOL_OUTPUT_MAX_RENDER_LINES
|
|
28
|
+
// (default 600; 0 disables). Shell/script bodies keep the newest tail when capped.
|
|
29
|
+
export function ResultBody({ lines, rawText, pathArg = '', isShell = false, columns, color, raw }) {
|
|
30
|
+
const renderLines = raw
|
|
31
|
+
? wrapExpandedResultLines(
|
|
32
|
+
formatExpandedResult(rawText, { pathArg, isShell }),
|
|
33
|
+
columns,
|
|
34
|
+
{ isShell },
|
|
35
|
+
)
|
|
36
|
+
: (lines || []);
|
|
37
|
+
if (!renderLines || renderLines.length === 0) return null;
|
|
38
|
+
return (
|
|
39
|
+
<Box flexDirection="row">
|
|
40
|
+
<Box flexShrink={0} flexDirection="column">
|
|
41
|
+
{renderLines.map((_, i) => (
|
|
42
|
+
<Text key={i} color={theme.subtle}>{i === 0 ? RESULT_GUTTER : RESULT_GUTTER_CONT}</Text>
|
|
43
|
+
))}
|
|
44
|
+
</Box>
|
|
45
|
+
<Box flexDirection="column" flexShrink={1} flexGrow={1}>
|
|
46
|
+
{renderLines.map((line, i) => (
|
|
47
|
+
<Text key={i} color={raw ? undefined : color} wrap="truncate">
|
|
48
|
+
{raw
|
|
49
|
+
? (line || ' ')
|
|
50
|
+
: renderDeltaText(fitResultLine(line || ' ', columns))}
|
|
51
|
+
</Text>
|
|
52
|
+
))}
|
|
53
|
+
</Box>
|
|
54
|
+
</Box>
|
|
55
|
+
);
|
|
56
|
+
}
|