mixdog 0.9.2 → 0.9.4
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 +8 -3
- package/scripts/anthropic-maxtokens-test.mjs +119 -0
- 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/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-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 +215 -29
- package/scripts/build-tui.mjs +13 -1
- package/scripts/explore-bench.mjs +124 -0
- package/scripts/freevar-smoke.mjs +95 -0
- package/scripts/hook-bus-test.mjs +191 -0
- package/scripts/internal-comms-bench.mjs +1 -0
- package/scripts/internal-comms-smoke.mjs +10 -9
- 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/path-suffix-test.mjs +57 -0
- package/scripts/provider-toolcall-test.mjs +7 -3
- package/scripts/recall-bench.mjs +207 -0
- package/scripts/recall-usecase-cases.json +18 -0
- package/scripts/recall-usecase-probe.json +6 -0
- package/scripts/session-bench.mjs +152 -6
- package/scripts/tool-smoke.mjs +30 -67
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +5 -2
- package/src/agents/heavy-worker/AGENT.md +21 -11
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +3 -2
- package/src/agents/worker/AGENT.md +21 -11
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +933 -3731
- package/src/output-styles/default.md +34 -9
- package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
- package/src/output-styles/minimal.md +4 -1
- package/src/output-styles/simple.md +22 -7
- package/src/repl.mjs +5 -5
- package/src/rules/agent/00-common.md +2 -0
- package/src/rules/agent/30-explorer.md +8 -11
- package/src/rules/lead/lead-brief.md +12 -0
- package/src/rules/lead/lead-tool.md +2 -9
- package/src/rules/shared/01-tool.md +11 -5
- 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/context/collect.mjs +51 -0
- package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +63 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
- 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 +97 -1343
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +78 -10
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
- 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 +44 -1014
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
- 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 +41 -1142
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +303 -2119
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +140 -995
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -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/opencode-go-usage.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
- 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-debug.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +274 -0
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
- package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
- package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +409 -1304
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +230 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +149 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -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/tool-resolution.mjs +303 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +226 -2114
- 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 +3 -3
- 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 +33 -42
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
- 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 -87
- 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 +78 -304
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +551 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1080 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
- 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 +1 -23
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +10 -74
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
- 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 +12 -292
- package/src/runtime/channels/index.mjs +241 -894
- package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
- package/src/runtime/channels/lib/boot-profile.mjs +23 -0
- package/src/runtime/channels/lib/crash-log.mjs +106 -0
- package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
- package/src/runtime/channels/lib/event-queue.mjs +63 -4
- package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
- package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +9 -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/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/telegram-format.mjs +19 -22
- 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 +312 -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 +36 -570
- package/src/runtime/channels/lib/whisper-language.mjs +42 -0
- package/src/runtime/channels/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +258 -2050
- package/src/runtime/memory/lib/core-memory-store.mjs +351 -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/cycle-signatures.mjs +34 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/http-wire.mjs +57 -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 +72 -837
- 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-scope-filter.mjs +24 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
- package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
- package/src/runtime/memory/lib/memory.mjs +20 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
- package/src/runtime/memory/lib/query-handlers.mjs +780 -0
- package/src/runtime/memory/lib/recall-format.mjs +238 -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 +6 -14
- 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/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/background-tasks.mjs +2 -3
- package/src/runtime/shared/buffered-appender.mjs +149 -0
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/task-notification-envelope.mjs +98 -0
- 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 +52 -2
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +291 -0
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/effort.mjs +128 -0
- package/src/session-runtime/fs-utils.mjs +10 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-capabilities.mjs +130 -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 +126 -0
- package/src/session-runtime/plugin-mcp.mjs +114 -0
- 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 +170 -0
- package/src/session-runtime/quick-search-models.mjs +46 -0
- package/src/session-runtime/session-hooks.mjs +93 -0
- package/src/session-runtime/session-text.mjs +100 -0
- package/src/session-runtime/settings-api.mjs +319 -0
- package/src/session-runtime/statusline-route.mjs +35 -0
- package/src/session-runtime/tool-catalog.mjs +720 -0
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/session-runtime/workflow.mjs +358 -0
- 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 +155 -677
- package/src/standalone/channel-worker.mjs +7 -9
- package/src/standalone/explore-tool.mjs +40 -12
- 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 +110 -746
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +125 -0
- package/src/standalone/provider-admin.mjs +15 -19
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +1163 -7571
- package/src/tui/app/app-format.mjs +206 -0
- package/src/tui/app/channel-pickers.mjs +510 -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 +324 -0
- package/src/tui/app/model-options.mjs +330 -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 +490 -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 +671 -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 +510 -0
- package/src/tui/app/use-transcript-window.mjs +589 -0
- package/src/tui/components/ConfirmBar.jsx +1 -1
- package/src/tui/components/Picker.jsx +32 -4
- package/src/tui/components/PromptInput.jsx +259 -80
- package/src/tui/components/SlashCommandPalette.jsx +8 -1
- package/src/tui/components/StatusLine.jsx +63 -12
- package/src/tui/components/TextEntryPanel.jsx +11 -0
- package/src/tui/components/ToolExecution.jsx +56 -588
- 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/components/tool-output-format.mjs +2 -2
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +18034 -17188
- package/src/tui/engine/agent-envelope.mjs +296 -0
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/boot-profile.mjs +21 -0
- package/src/tui/engine/labels.mjs +67 -0
- package/src/tui/engine/notice-text.mjs +112 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/queue-helpers.mjs +161 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/session-stats.mjs +46 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-call-fields.mjs +23 -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/tool-result-text.mjs +126 -0
- package/src/tui/engine.mjs +405 -1385
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +105 -0
- package/src/tui/input-editing.mjs +60 -10
- package/src/tui/keyboard-protocol.mjs +2 -2
- package/src/tui/lib/voice-recorder.mjs +35 -19
- package/src/tui/markdown/format-token.mjs +11 -9
- package/src/tui/paste-attachments.mjs +38 -0
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/tui/themes/base.mjs +2 -2
- package/src/tui/themes/kanagawa.mjs +4 -4
- package/src/tui/themes/teal.mjs +4 -5
- package/src/tui/themes/utils.mjs +1 -1
- 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 -462
- 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 -9
- package/src/workflows/sequential/WORKFLOW.md +16 -11
- package/src/workflows/solo/WORKFLOW.md +5 -1
- package/vendor/ink/build/display-width.js +19 -3
- package/vendor/ink/build/ink.js +103 -6
- 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/open-config-tool.mjs +0 -26
- package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
- 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/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/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
|
@@ -26,16 +26,23 @@ Lead supervises: delegates, coordinates, judges, decides. Route by complexity:
|
|
|
26
26
|
- SEQUENTIAL within a single complex scope — split it into ordered steps
|
|
27
27
|
rather than handing it off in one shot, with a build/test-green gate
|
|
28
28
|
between steps.
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
contract (token-optimized labeled fragments).
|
|
29
|
+
- Write briefs per the Lead brief contract (token-optimized labeled
|
|
30
|
+
fragments).
|
|
32
31
|
- After spawning async agent(s), END THE TURN — do not poll, guess, or start
|
|
33
|
-
dependent work until the completion notification resumes you
|
|
34
|
-
|
|
32
|
+
dependent work until the completion notification resumes you. Then wait
|
|
33
|
+
and continue automatically.
|
|
35
34
|
3. Review — pair one reviewer 1:1 with each implementation scope, spawned in the
|
|
36
|
-
same turn
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
same turn; never defer or batch the reviewer call — wait for its result.
|
|
36
|
+
Fact-check the agent response and cross-check implementation and review
|
|
37
|
+
results yourself before acting on them. Send fixes back to the original
|
|
38
|
+
scope and loop verify -> fix -> re-verify until clean. Skip review only for
|
|
39
|
+
simple, low-risk tasks. If the user asks for debugging, or a bug survives
|
|
40
|
+
2+ fix cycles, have the debugger investigate first instead of another fix
|
|
41
|
+
round.
|
|
39
42
|
4. Report — deliver the final report: synthesize results (outcome + key
|
|
40
43
|
evidence; never forward raw agent output), state the final state, and ask the
|
|
41
|
-
user whether to ship/deploy when relevant.
|
|
44
|
+
user whether to ship/deploy when relevant. Only after user feedback with no
|
|
45
|
+
issues prepare deploy/build/commit.
|
|
46
|
+
|
|
47
|
+
On any major change or direction shift mid-work, pause and re-consult the user
|
|
48
|
+
before continuing.
|
|
@@ -29,18 +29,23 @@ Lead supervises: delegates, coordinates, judges, decides. Route by complexity:
|
|
|
29
29
|
- SEQUENTIAL within a single complex scope — split it into ordered steps
|
|
30
30
|
rather than handing it off in one shot, with a build/test-green gate
|
|
31
31
|
between steps.
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
contract (token-optimized labeled fragments).
|
|
32
|
+
- Write briefs per the Lead brief contract (token-optimized labeled
|
|
33
|
+
fragments).
|
|
35
34
|
- After spawning an async agent, END THE TURN — do not poll, guess, or start
|
|
36
|
-
dependent or subsequent work until the completion notification resumes
|
|
37
|
-
|
|
38
|
-
automatically.
|
|
35
|
+
dependent or subsequent work until the completion notification resumes
|
|
36
|
+
you. Then wait and continue automatically.
|
|
39
37
|
3. Review — after each implementation scope completes, pair one reviewer 1:1
|
|
40
|
-
with that scope (spawned on its own turn, not batched)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
with that scope (spawned on its own turn, not batched); never defer the
|
|
39
|
+
reviewer call — wait for its result. Fact-check the agent response and
|
|
40
|
+
cross-check implementation and review results yourself before acting on
|
|
41
|
+
them. Send fixes back to the original scope and loop verify -> fix ->
|
|
42
|
+
re-verify until clean. Skip review only for simple, low-risk tasks. If the
|
|
43
|
+
user asks for debugging, or a bug survives 2+ fix cycles, have the debugger
|
|
44
|
+
investigate first instead of another fix round.
|
|
44
45
|
4. Report — deliver the final report: synthesize results (outcome + key
|
|
45
46
|
evidence; never forward raw agent output), state the final state, and ask the
|
|
46
|
-
user whether to ship/deploy when relevant.
|
|
47
|
+
user whether to ship/deploy when relevant. Only after user feedback with no
|
|
48
|
+
issues prepare deploy/build/commit.
|
|
49
|
+
|
|
50
|
+
On any major change or direction shift mid-work, pause and re-consult the user
|
|
51
|
+
before continuing.
|
|
@@ -14,7 +14,11 @@ agents:
|
|
|
14
14
|
3. Verify — Lead checks the result directly, fixes issues directly, and repeats
|
|
15
15
|
until the work is clean or a blocker must be reported.
|
|
16
16
|
4. Report — Lead summarizes the final state, verification result, and any
|
|
17
|
-
remaining risk or requested next step.
|
|
17
|
+
remaining risk or requested next step. Only after user feedback with no
|
|
18
|
+
issues prepare deploy/build/commit.
|
|
19
|
+
|
|
20
|
+
On any major change or direction shift mid-work, pause and re-consult the user
|
|
21
|
+
before continuing.
|
|
18
22
|
|
|
19
23
|
Delegation rule:
|
|
20
24
|
- Do not delegate, spawn, send, or ask any agent to perform work.
|
|
@@ -16,11 +16,21 @@
|
|
|
16
16
|
* overrides and wins. OFF ⇒ identical to plain string-width.
|
|
17
17
|
*/
|
|
18
18
|
import stringWidth from 'string-width';
|
|
19
|
+
// [mixdog fork] Grapheme segmenter for cluster-aware width math (e.g. `↔️` =
|
|
20
|
+
// U+2194 U+FE0F is one cluster, counted once). Kept in sync with
|
|
21
|
+
// src/tui/display-width.mjs.
|
|
22
|
+
const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
19
23
|
|
|
20
24
|
function isProblemCodePoint(cp) {
|
|
21
25
|
return (cp >= 0x2460 && cp <= 0x24ff) || (cp >= 0x2190 && cp <= 0x21ff);
|
|
22
26
|
}
|
|
23
27
|
|
|
28
|
+
// [mixdog fork] Fast precheck for the problem ranges above. Lets the hot path
|
|
29
|
+
// bail before the per-grapheme segmenter loop when a string (the common
|
|
30
|
+
// ASCII/status-text case) contains no widenable glyph. Kept in sync with
|
|
31
|
+
// src/tui/display-width.mjs.
|
|
32
|
+
const PROBLEM_RE = /[\u2190-\u21ff\u2460-\u24ff]/;
|
|
33
|
+
|
|
24
34
|
function resolveAmbiguousWidePolicy(env = process.env) {
|
|
25
35
|
const override = env?.MIXDOG_TUI_AMBIGUOUS_WIDE;
|
|
26
36
|
if (override === '1')
|
|
@@ -38,10 +48,16 @@ export function displayWidthWith(str, wide) {
|
|
|
38
48
|
const base = stringWidth(s);
|
|
39
49
|
if (!wide)
|
|
40
50
|
return base;
|
|
51
|
+
// Fast bail: no problem glyph ⇒ segmenting can only return `base`.
|
|
52
|
+
if (!PROBLEM_RE.test(s))
|
|
53
|
+
return base;
|
|
41
54
|
let extra = 0;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
55
|
+
// Widen per GRAPHEME CLUSTER, not per code point (kept in sync with
|
|
56
|
+
// src/tui/display-width.mjs): a clustered glyph like `↔️` (U+2194 U+FE0F)
|
|
57
|
+
// is counted once, and only when the whole cluster still measures 1 cell.
|
|
58
|
+
for (const { segment } of graphemeSegmenter.segment(s)) {
|
|
59
|
+
const cp = segment.codePointAt(0);
|
|
60
|
+
if (isProblemCodePoint(cp) && stringWidth(segment) === 1)
|
|
45
61
|
extra += 1;
|
|
46
62
|
}
|
|
47
63
|
return base + extra;
|
package/vendor/ink/build/ink.js
CHANGED
|
@@ -86,16 +86,25 @@ const stripKittyQueryResponsesAndTrailingPartial = (buffer) => {
|
|
|
86
86
|
// viewport, leaving stale copies of previous frames behind (#969). Keep the
|
|
87
87
|
// pre-7.0 behavior of fully clearing between fullscreen frames there.
|
|
88
88
|
const isWindowsConsole = process.platform === 'win32' || Boolean(process.env.WT_SESSION);
|
|
89
|
-
const shouldClearTerminalForFrame = ({ isTty, viewportRows, previousOutputHeight, nextOutputHeight, isUnmounting, }) => {
|
|
89
|
+
const shouldClearTerminalForFrame = ({ isTty, viewportRows, previousViewportRows, previousOutputHeight, nextOutputHeight, isUnmounting, }) => {
|
|
90
90
|
if (!isTty) {
|
|
91
91
|
return false;
|
|
92
92
|
}
|
|
93
|
+
const priorViewportRows = previousViewportRows ?? viewportRows;
|
|
93
94
|
const hadPreviousFrame = previousOutputHeight > 0;
|
|
94
|
-
const wasFullscreen = previousOutputHeight >=
|
|
95
|
-
const wasOverflowing = previousOutputHeight >
|
|
95
|
+
const wasFullscreen = previousOutputHeight >= priorViewportRows;
|
|
96
|
+
const wasOverflowing = previousOutputHeight > priorViewportRows;
|
|
96
97
|
const isOverflowing = nextOutputHeight > viewportRows;
|
|
97
98
|
const isFullscreen = nextOutputHeight >= viewportRows;
|
|
98
99
|
const isLeavingFullscreen = wasFullscreen && nextOutputHeight < viewportRows;
|
|
100
|
+
// [mixdog fork] A frame that SHRINKS by more than a line while at/over the
|
|
101
|
+
// viewport can leave stale wrapped rows below the new content on ANY
|
|
102
|
+
// terminal (not just Windows) — the incremental erase only clears the exact
|
|
103
|
+
// delta and a hardware wrap can desync it by a cell. Force a full clear on a
|
|
104
|
+
// meaningful height shrink near/at the viewport edge, cross-platform.
|
|
105
|
+
const isShrinkingAtViewport = hadPreviousFrame &&
|
|
106
|
+
nextOutputHeight < previousOutputHeight &&
|
|
107
|
+
(wasFullscreen || isFullscreen || wasOverflowing || isOverflowing);
|
|
99
108
|
const shouldClearOnUnmount = isUnmounting && wasFullscreen;
|
|
100
109
|
if (isWindowsConsole && (wasFullscreen || isFullscreen)) {
|
|
101
110
|
return true;
|
|
@@ -106,6 +115,8 @@ const shouldClearTerminalForFrame = ({ isTty, viewportRows, previousOutputHeight
|
|
|
106
115
|
(isOverflowing && hadPreviousFrame) ||
|
|
107
116
|
// Clear when shrinking from fullscreen to non-fullscreen output.
|
|
108
117
|
isLeavingFullscreen ||
|
|
118
|
+
// Clear on any height shrink at/over the viewport (cross-platform).
|
|
119
|
+
isShrinkingAtViewport ||
|
|
109
120
|
// Preserve legacy unmount behavior for fullscreen frames: final teardown
|
|
110
121
|
// render should clear once to avoid leaving a scrolled viewport state.
|
|
111
122
|
shouldClearOnUnmount);
|
|
@@ -155,6 +166,7 @@ export default class Ink {
|
|
|
155
166
|
lastOutputToRender;
|
|
156
167
|
lastOutputHeight;
|
|
157
168
|
lastTerminalWidth;
|
|
169
|
+
lastTerminalHeight;
|
|
158
170
|
container;
|
|
159
171
|
rootNode;
|
|
160
172
|
// This variable is used only in debug mode to store full static output
|
|
@@ -165,6 +177,9 @@ export default class Ink {
|
|
|
165
177
|
beforeExitHandler;
|
|
166
178
|
restoreConsole;
|
|
167
179
|
unsubscribeResize;
|
|
180
|
+
// [mixdog fork] Deferred repaint safety-net timer for resized(); cancelled
|
|
181
|
+
// by onRender when a real (App-driven) render lands first.
|
|
182
|
+
resizeRepaintTimer;
|
|
168
183
|
throttledOnRender;
|
|
169
184
|
hasPendingThrottledRender = false;
|
|
170
185
|
kittyProtocolEnabled = false;
|
|
@@ -259,6 +274,7 @@ export default class Ink {
|
|
|
259
274
|
this.lastOutputToRender = '';
|
|
260
275
|
this.lastOutputHeight = 0;
|
|
261
276
|
this.lastTerminalWidth = getWindowSize(this.options.stdout).columns;
|
|
277
|
+
this.lastTerminalHeight = getWindowSize(this.options.stdout).rows;
|
|
262
278
|
// This variable is used only in debug mode to store full static output
|
|
263
279
|
// so that it's rerendered every time, not just new static parts, like in non-debug mode
|
|
264
280
|
this.fullStaticOutput = '';
|
|
@@ -293,16 +309,56 @@ export default class Ink {
|
|
|
293
309
|
}
|
|
294
310
|
resized = () => {
|
|
295
311
|
const currentWidth = getWindowSize(this.options.stdout).columns;
|
|
296
|
-
|
|
297
|
-
|
|
312
|
+
const currentHeight = getWindowSize(this.options.stdout).rows;
|
|
313
|
+
if (currentWidth !== this.lastTerminalWidth || currentHeight !== this.lastTerminalHeight) {
|
|
314
|
+
// [mixdog fork] On viewport size change, full-clear the alt screen to
|
|
315
|
+
// drop the stale frame, but DO NOT immediately re-render with the old
|
|
316
|
+
// React tree at the new size. Ink's own onRender() here fires before
|
|
317
|
+
// App's debounced resizeState state update, so it paints a frame laid
|
|
318
|
+
// out for the PREVIOUS dimensions into the NEW viewport — that is the
|
|
319
|
+
// 2-frame jump/re-settle on resize. Clearing (no re-render) leaves a
|
|
320
|
+
// blank screen for the sub-frame until App's setResizeState commit
|
|
321
|
+
// drives a single, correctly-sized App-owned render. Layout listeners
|
|
322
|
+
// still fire so consumers observe the new size synchronously.
|
|
298
323
|
this.log.clear();
|
|
324
|
+
this.log.reset?.();
|
|
325
|
+
// this.log.clear() only erases the PRIOR log frame's row span. On a
|
|
326
|
+
// fullscreen/alt-screen grow the newly exposed rows (below the old
|
|
327
|
+
// frame) are never touched by that erase, so stale scrollback can
|
|
328
|
+
// remain visible until the next full repaint — which, with the
|
|
329
|
+
// immediate onRender suppressed, may be shorter or delayed. Issue a
|
|
330
|
+
// true whole-screen clear so the viewport is uniformly blank until
|
|
331
|
+
// App's correctly-sized render lands.
|
|
332
|
+
this.writeBestEffort(this.options.stdout, ansiEscapes.clearTerminal);
|
|
299
333
|
this.lastOutput = '';
|
|
300
334
|
this.lastOutputToRender = '';
|
|
335
|
+
this.lastOutputHeight = 0;
|
|
336
|
+
this.calculateLayout();
|
|
337
|
+
dom.emitLayoutListeners(this.rootNode);
|
|
338
|
+
this.lastTerminalWidth = currentWidth;
|
|
339
|
+
this.lastTerminalHeight = currentHeight;
|
|
340
|
+
// Safety net: the early return delegates the repaint to App's stdout
|
|
341
|
+
// 'resize' listener (debounced setResizeState). If that render never
|
|
342
|
+
// arrives (listener not mounted yet, batched-away no-op, consumer
|
|
343
|
+
// without a resize handler), the screen would sit blank. Schedule a
|
|
344
|
+
// deferred onRender() that repaints with whatever tree is current;
|
|
345
|
+
// it is cancelled below whenever a real render happens first, so in
|
|
346
|
+
// the normal path it never fires and the immediate render stays
|
|
347
|
+
// suppressed.
|
|
348
|
+
if (this.resizeRepaintTimer) clearTimeout(this.resizeRepaintTimer);
|
|
349
|
+
this.resizeRepaintTimer = setTimeout(() => {
|
|
350
|
+
this.resizeRepaintTimer = undefined;
|
|
351
|
+
if (this.isUnmounted || this.isUnmounting) return;
|
|
352
|
+
this.onRender();
|
|
353
|
+
}, 200);
|
|
354
|
+
if (typeof this.resizeRepaintTimer.unref === 'function') this.resizeRepaintTimer.unref();
|
|
355
|
+
return;
|
|
301
356
|
}
|
|
302
357
|
this.calculateLayout();
|
|
303
358
|
dom.emitLayoutListeners(this.rootNode);
|
|
304
359
|
this.onRender();
|
|
305
360
|
this.lastTerminalWidth = currentWidth;
|
|
361
|
+
this.lastTerminalHeight = currentHeight;
|
|
306
362
|
};
|
|
307
363
|
resolveExitPromise = () => { };
|
|
308
364
|
rejectExitPromise = () => { };
|
|
@@ -508,6 +564,12 @@ export default class Ink {
|
|
|
508
564
|
};
|
|
509
565
|
onRender = () => {
|
|
510
566
|
this.hasPendingThrottledRender = false;
|
|
567
|
+
// A real render is happening: cancel the resize safety-net timer so the
|
|
568
|
+
// deferred repaint never double-fires in the normal path.
|
|
569
|
+
if (this.resizeRepaintTimer) {
|
|
570
|
+
clearTimeout(this.resizeRepaintTimer);
|
|
571
|
+
this.resizeRepaintTimer = undefined;
|
|
572
|
+
}
|
|
511
573
|
if (this.isUnmounted) {
|
|
512
574
|
return;
|
|
513
575
|
}
|
|
@@ -737,6 +799,12 @@ export default class Ink {
|
|
|
737
799
|
if (typeof this.unsubscribeResize === 'function') {
|
|
738
800
|
this.unsubscribeResize();
|
|
739
801
|
}
|
|
802
|
+
// [mixdog fork] Drop the resize safety-net timer so a deferred
|
|
803
|
+
// repaint cannot fire against a torn-down tree.
|
|
804
|
+
if (this.resizeRepaintTimer) {
|
|
805
|
+
clearTimeout(this.resizeRepaintTimer);
|
|
806
|
+
this.resizeRepaintTimer = undefined;
|
|
807
|
+
}
|
|
740
808
|
// Cancel any in-progress auto-detection before checking protocol state
|
|
741
809
|
if (this.cancelKittyDetection) {
|
|
742
810
|
this.cancelKittyDetection();
|
|
@@ -957,21 +1025,50 @@ export default class Ink {
|
|
|
957
1025
|
// Detect fullscreen: output fills or exceeds terminal height.
|
|
958
1026
|
// Only apply when writing to a real TTY — piped output always gets trailing newlines.
|
|
959
1027
|
const viewportRows = isTty ? getWindowSize(this.options.stdout).rows : 24;
|
|
1028
|
+
const viewportColumns = isTty ? getWindowSize(this.options.stdout).columns : this.lastTerminalWidth;
|
|
1029
|
+
// [mixdog fork] Capture the previous viewport rows (as tracked at the
|
|
1030
|
+
// end of the last frame) before we update it below, so wasFullscreen/
|
|
1031
|
+
// wasOverflowing classify the PREVIOUS frame against the viewport it
|
|
1032
|
+
// was actually rendered into, not the current (possibly resized) one.
|
|
1033
|
+
const previousViewportRows = this.lastTerminalHeight ?? viewportRows;
|
|
960
1034
|
const isFullscreen = isTty && outputHeight >= viewportRows;
|
|
961
1035
|
const outputToRender = isFullscreen ? output : output + '\n';
|
|
962
1036
|
const shouldClearTerminal = shouldClearTerminalForFrame({
|
|
963
1037
|
isTty,
|
|
964
1038
|
viewportRows,
|
|
1039
|
+
previousViewportRows,
|
|
965
1040
|
previousOutputHeight: this.lastOutputHeight,
|
|
966
1041
|
nextOutputHeight: outputHeight,
|
|
967
1042
|
isUnmounting: this.isUnmounting,
|
|
968
1043
|
});
|
|
1044
|
+
const viewportUnchanged = viewportRows === previousViewportRows && viewportColumns === this.lastTerminalWidth;
|
|
1045
|
+
if (isTty) {
|
|
1046
|
+
this.lastTerminalHeight = viewportRows;
|
|
1047
|
+
}
|
|
1048
|
+
// [mixdog fork] Skip redundant full clears: on Windows every fullscreen
|
|
1049
|
+
// frame takes the clearTerminal path, so a commit with IDENTICAL output
|
|
1050
|
+
// (e.g. post-mount tuiReady flip with no layout change) still blanked and
|
|
1051
|
+
// rewrote the whole screen — visible as boot flicker. Nothing changed →
|
|
1052
|
+
// nothing to write. [mixdog fork] Also require the viewport (rows AND
|
|
1053
|
+
// columns) to be unchanged since the last frame: a resize can arrive
|
|
1054
|
+
// with identical output text but must still force a full clear to
|
|
1055
|
+
// avoid ghosting stale cells left outside the new viewport.
|
|
1056
|
+
if (shouldClearTerminal &&
|
|
1057
|
+
!this.isUnmounting &&
|
|
1058
|
+
output === this.lastOutput &&
|
|
1059
|
+
staticOutput === '' &&
|
|
1060
|
+
!this.log.isCursorDirty() &&
|
|
1061
|
+
viewportUnchanged) {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
969
1064
|
if (shouldClearTerminal) {
|
|
970
1065
|
const sync = this.shouldSync();
|
|
971
1066
|
if (sync) {
|
|
972
1067
|
this.options.stdout.write(bsu);
|
|
973
1068
|
}
|
|
974
|
-
|
|
1069
|
+
// [mixdog fork] Reset SGR before erasing so stale style/background
|
|
1070
|
+
// from the previous frame doesn't leak onto the cleared cells.
|
|
1071
|
+
this.options.stdout.write('\u001B[0m' + ansiEscapes.clearTerminal + this.fullStaticOutput + output);
|
|
975
1072
|
this.lastOutput = output;
|
|
976
1073
|
this.lastOutputToRender = outputToRender;
|
|
977
1074
|
this.lastOutputHeight = outputHeight;
|
|
@@ -62,7 +62,9 @@ const createStandard = (stream, { showCursor = false } = {}) => {
|
|
|
62
62
|
};
|
|
63
63
|
render.clear = () => {
|
|
64
64
|
const prefix = buildReturnToBottomPrefix(cursorWasShown, previousLineCount, previousCursorPosition);
|
|
65
|
-
|
|
65
|
+
// [mixdog fork] Reset SGR before erasing so stale style/background from
|
|
66
|
+
// the previous frame doesn't leak onto the cleared cells.
|
|
67
|
+
stream.write(prefix + '\u001B[0m' + ansiEscapes.eraseLines(previousLineCount));
|
|
66
68
|
previousOutput = '';
|
|
67
69
|
previousLineCount = 0;
|
|
68
70
|
previousCursorPosition = undefined;
|
|
@@ -171,7 +173,17 @@ const createIncremental = (stream, { showCursor = false } = {}) => {
|
|
|
171
173
|
if (visibleCount < previousVisible) {
|
|
172
174
|
const previousHadTrailingNewline = previousOutput.endsWith('\n');
|
|
173
175
|
const extraSlot = previousHadTrailingNewline ? 1 : 0;
|
|
174
|
-
|
|
176
|
+
// [mixdog fork] Defensive erase on height shrink: clear ONE extra
|
|
177
|
+
// physical line beyond the counted delta. A hardware line-wrap (wide
|
|
178
|
+
// glyph at the viewport edge) can occupy a physical row the logical
|
|
179
|
+
// line count doesn't account for, leaving a ghost row below the new
|
|
180
|
+
// content. Not Windows-specific — the wrap desync happens on any
|
|
181
|
+
// terminal. We erase the extra line with eraseLine at the current
|
|
182
|
+
// (bottom) row FIRST — this does NOT move the cursor — then run the
|
|
183
|
+
// normal eraseLines walk. This keeps the post-erase cursor origin
|
|
184
|
+
// identical to upstream (cursorUp(visibleCount) still lands right),
|
|
185
|
+
// so only a stray trailing row is removed, layout is untouched.
|
|
186
|
+
buffer.push(ansiEscapes.eraseLine, ansiEscapes.eraseLines(previousVisible - visibleCount + extraSlot), ansiEscapes.cursorUp(visibleCount));
|
|
175
187
|
}
|
|
176
188
|
else {
|
|
177
189
|
buffer.push(ansiEscapes.cursorUp(previousLines.length - 1));
|
|
@@ -205,7 +217,9 @@ const createIncremental = (stream, { showCursor = false } = {}) => {
|
|
|
205
217
|
};
|
|
206
218
|
render.clear = () => {
|
|
207
219
|
const prefix = buildReturnToBottomPrefix(cursorWasShown, previousLines.length, previousCursorPosition);
|
|
208
|
-
|
|
220
|
+
// [mixdog fork] Reset SGR before erasing so stale style/background from
|
|
221
|
+
// the previous frame doesn't leak onto the cleared cells.
|
|
222
|
+
stream.write(prefix + '\u001B[0m' + ansiEscapes.eraseLines(previousLines.length));
|
|
209
223
|
previousOutput = '';
|
|
210
224
|
previousLines = [];
|
|
211
225
|
previousCursorPosition = undefined;
|
|
@@ -1,6 +1,127 @@
|
|
|
1
1
|
import wrapAnsi from 'wrap-ansi';
|
|
2
2
|
import cliTruncate from 'cli-truncate';
|
|
3
|
+
import stripAnsi from 'strip-ansi';
|
|
4
|
+
import { AMBIGUOUS_WIDE, displayStringWidth } from './display-width.js';
|
|
3
5
|
const cache = {};
|
|
6
|
+
// [mixdog fork] wrap-ansi / cli-truncate measure with plain string-width, which
|
|
7
|
+
// counts our problem glyphs (circled digits U+2460–U+24FF, arrows U+2190–U+21FF)
|
|
8
|
+
// as 1 cell while the terminal draws 2. When the policy is ON, their column math
|
|
9
|
+
// under-counts and a wrapped/truncated line can still overflow by one cell,
|
|
10
|
+
// pushing content past the box edge (the ghosting/overlap). We can't cleanly
|
|
11
|
+
// fork wrap-ansi, so we compensate at THIS boundary: re-check each produced line
|
|
12
|
+
// with displayStringWidth. For wrap/hard modes the overflow is REFLOWED onto a
|
|
13
|
+
// new line (no visible content is dropped); only truncate-end may cut.
|
|
14
|
+
const PROBLEM_RE = /[\u2190-\u21ff\u2460-\u24ff]/;
|
|
15
|
+
const ANSI_RE = /^\u001B(?:\[[0-9;]*m|\].*?(?:\u0007|\u001B\\))/;
|
|
16
|
+
const segmenter = new Intl.Segmenter();
|
|
17
|
+
// SGR reset — appended after a mid-line cut so an open style doesn't leak past
|
|
18
|
+
// the split point onto the reflowed remainder / following cells.
|
|
19
|
+
const SGR_RESET = '\u001B[0m';
|
|
20
|
+
// OSC 8 hyperlink open (with a URL) and universal close. Cutting inside a link
|
|
21
|
+
// must close it on head and re-open it on tail, exactly like an open SGR style.
|
|
22
|
+
const OSC8_CLOSE = '\u001B]8;;\u0007';
|
|
23
|
+
const OSC8_RE = /^\u001B\]8;;([^\u0007\u001B]*)(?:\u0007|\u001B\\)/;
|
|
24
|
+
// Split one ANSI line at the first grapheme boundary where VISIBLE displayWidth
|
|
25
|
+
// would exceed `max`. Walks grapheme CLUSTERS (not code points) so a clustered
|
|
26
|
+
// glyph (e.g. `↔️` = U+2194 U+FE0F) is measured/kept whole. Returns
|
|
27
|
+
// { head, tail }: head fits within max (with an SGR reset appended when any
|
|
28
|
+
// style is still open at the cut so styling doesn't bleed); tail is the
|
|
29
|
+
// remaining visible content, prefixed with the carried-over open SGR codes so
|
|
30
|
+
// it renders with the same style it was cut from. ANSI escapes cost 0 width.
|
|
31
|
+
const splitAtDisplayWidth = (line, max) => {
|
|
32
|
+
if (displayStringWidth(line) <= max)
|
|
33
|
+
return { head: line, tail: '' };
|
|
34
|
+
let head = '';
|
|
35
|
+
let width = 0;
|
|
36
|
+
let rest = line;
|
|
37
|
+
// Track SGR open codes seen so far so the tail can re-open them. An empty
|
|
38
|
+
// params reset ('' or '0') clears the carry; anything else accumulates.
|
|
39
|
+
let openSgr = '';
|
|
40
|
+
let sawOpenStyle = false;
|
|
41
|
+
// Track an open OSC 8 hyperlink (empty URL '...8;;\u0007' closes it).
|
|
42
|
+
let openLink = '';
|
|
43
|
+
while (rest.length > 0) {
|
|
44
|
+
const m = ANSI_RE.exec(rest);
|
|
45
|
+
if (m) {
|
|
46
|
+
head += m[0];
|
|
47
|
+
const sgr = /^\u001B\[([0-9;]*)m$/.exec(m[0]);
|
|
48
|
+
if (sgr) {
|
|
49
|
+
const params = sgr[1];
|
|
50
|
+
if (params === '' || params === '0') {
|
|
51
|
+
openSgr = '';
|
|
52
|
+
sawOpenStyle = false;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
openSgr += m[0];
|
|
56
|
+
sawOpenStyle = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const osc = OSC8_RE.exec(m[0]);
|
|
61
|
+
if (osc)
|
|
62
|
+
openLink = osc[1] ? m[0] : '';
|
|
63
|
+
}
|
|
64
|
+
rest = rest.slice(m[0].length);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const { segment } = segmenter.segment(rest)[Symbol.iterator]().next().value;
|
|
68
|
+
const w = displayStringWidth(segment);
|
|
69
|
+
// Progress guarantee: if nothing visible has landed on head yet, force
|
|
70
|
+
// the first grapheme through even when it alone exceeds max (a 1-cluster
|
|
71
|
+
// overflow is unavoidable and preferable to a zero-progress loop).
|
|
72
|
+
if (width + w > max && width > 0)
|
|
73
|
+
break;
|
|
74
|
+
head += segment;
|
|
75
|
+
width += w;
|
|
76
|
+
rest = rest.slice(segment.length);
|
|
77
|
+
}
|
|
78
|
+
// Close any style / link still open at the cut, and re-open on the tail.
|
|
79
|
+
if (openLink)
|
|
80
|
+
head += OSC8_CLOSE;
|
|
81
|
+
if (sawOpenStyle)
|
|
82
|
+
head += SGR_RESET;
|
|
83
|
+
const carry = openSgr + openLink;
|
|
84
|
+
const tail = rest.length > 0 ? carry + rest : '';
|
|
85
|
+
return { head, tail };
|
|
86
|
+
};
|
|
87
|
+
// wrap/hard: no visible content may be dropped. Repeatedly split each produced
|
|
88
|
+
// line at the display-width budget and REFLOW the overflow onto following lines.
|
|
89
|
+
const reflowToDisplayWidth = (line, max) => {
|
|
90
|
+
const out = [];
|
|
91
|
+
let cur = line;
|
|
92
|
+
while (displayStringWidth(cur) > max) {
|
|
93
|
+
const { head, tail } = splitAtDisplayWidth(cur, max);
|
|
94
|
+
// splitAtDisplayWidth now always advances (forces >=1 grapheme onto
|
|
95
|
+
// head), so head carries visible content and tail shrinks each pass.
|
|
96
|
+
// Belt-and-braces: if tail failed to shrink, flush the remainder. Push
|
|
97
|
+
// `head` (not raw `cur`) — head carries the SGR/OSC8 close sequences, so
|
|
98
|
+
// even a single overwide styled/linked glyph doesn't leak its style.
|
|
99
|
+
if (tail === '' || tail === cur) {
|
|
100
|
+
out.push(head || cur);
|
|
101
|
+
return out;
|
|
102
|
+
}
|
|
103
|
+
out.push(head);
|
|
104
|
+
cur = tail;
|
|
105
|
+
}
|
|
106
|
+
out.push(cur);
|
|
107
|
+
return out;
|
|
108
|
+
};
|
|
109
|
+
// truncate-end: cutting is the intended behavior — drop the overflow but still
|
|
110
|
+
// cut on grapheme boundaries and close open styles.
|
|
111
|
+
const hardCutToDisplayWidth = (line, max) => splitAtDisplayWidth(line, max).head;
|
|
112
|
+
// Re-enforce the display-width budget on every produced line when the policy is
|
|
113
|
+
// ON and the source contains a problem glyph. No-op otherwise (byte-identical
|
|
114
|
+
// to upstream wrap-ansi output), so terminals without the wide policy are
|
|
115
|
+
// unaffected.
|
|
116
|
+
const enforceDisplayWidth = (wrapped, maxWidth, mode) => {
|
|
117
|
+
if (!AMBIGUOUS_WIDE || !PROBLEM_RE.test(stripAnsi(wrapped)))
|
|
118
|
+
return wrapped;
|
|
119
|
+
const lines = wrapped.split('\n');
|
|
120
|
+
if (mode === 'truncate')
|
|
121
|
+
return lines.map((line) => hardCutToDisplayWidth(line, maxWidth)).join('\n');
|
|
122
|
+
// wrap/hard: reflow overflow, never drop.
|
|
123
|
+
return lines.flatMap((line) => reflowToDisplayWidth(line, maxWidth)).join('\n');
|
|
124
|
+
};
|
|
4
125
|
const wrapText = (text, maxWidth, wrapType) => {
|
|
5
126
|
const cacheKey = text + String(maxWidth) + String(wrapType);
|
|
6
127
|
const cachedText = cache[cacheKey];
|
|
@@ -13,6 +134,7 @@ const wrapText = (text, maxWidth, wrapType) => {
|
|
|
13
134
|
trim: false,
|
|
14
135
|
hard: true,
|
|
15
136
|
});
|
|
137
|
+
wrappedText = enforceDisplayWidth(wrappedText, maxWidth, 'wrap');
|
|
16
138
|
}
|
|
17
139
|
if (wrapType === 'hard') {
|
|
18
140
|
wrappedText = wrapAnsi(text, maxWidth, {
|
|
@@ -20,6 +142,7 @@ const wrapText = (text, maxWidth, wrapType) => {
|
|
|
20
142
|
hard: true,
|
|
21
143
|
wordWrap: false,
|
|
22
144
|
});
|
|
145
|
+
wrappedText = enforceDisplayWidth(wrappedText, maxWidth, 'wrap');
|
|
23
146
|
}
|
|
24
147
|
if (wrapType.startsWith('truncate')) {
|
|
25
148
|
let position = 'end';
|
|
@@ -30,6 +153,8 @@ const wrapText = (text, maxWidth, wrapType) => {
|
|
|
30
153
|
position = 'start';
|
|
31
154
|
}
|
|
32
155
|
wrappedText = cliTruncate(text, maxWidth, { position });
|
|
156
|
+
if (position === 'end')
|
|
157
|
+
wrappedText = enforceDisplayWidth(wrappedText, maxWidth, 'truncate');
|
|
33
158
|
}
|
|
34
159
|
cache[cacheKey] = wrappedText;
|
|
35
160
|
return wrappedText;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { spawn } from 'node:child_process';
|
|
2
|
-
import { readFileSync } from 'node:fs';
|
|
3
|
-
|
|
4
|
-
const src = readFileSync('src/standalone/folder-dialog.mjs', 'utf8');
|
|
5
|
-
const fn = src.match(/function powershellScript[\s\S]*?return \[([\s\S]*?)\]\.join/);
|
|
6
|
-
if (!fn) throw new Error('parse failed');
|
|
7
|
-
// Re-eval powershellScript by importing - use dynamic compile
|
|
8
|
-
const modUrl = new URL('../src/standalone/folder-dialog.mjs', import.meta.url);
|
|
9
|
-
// Call pickFolder with a hook - instead duplicate minimal import
|
|
10
|
-
const { pickFolder } = await import(modUrl.href);
|
|
11
|
-
|
|
12
|
-
const child = spawn('powershell.exe', [
|
|
13
|
-
'-NoLogo', '-NoProfile', '-STA', '-Command',
|
|
14
|
-
[
|
|
15
|
-
'$ErrorActionPreference = "Continue"',
|
|
16
|
-
'try {',
|
|
17
|
-
...readFileSync('src/standalone/folder-dialog.mjs', 'utf8')
|
|
18
|
-
.split('\n')
|
|
19
|
-
.filter((l) => l.includes('Add-Type -AssemblyName') || l.includes('Add-Type -TypeDefinition') || l.includes('GetDialogOwnerCenter')),
|
|
20
|
-
'} catch { Write-Error $_; exit 1 }',
|
|
21
|
-
].join('; '),
|
|
22
|
-
], { stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
|
|
23
|
-
|
|
24
|
-
let err = '';
|
|
25
|
-
child.stderr.on('data', (d) => { err += d.toString(); });
|
|
26
|
-
child.on('close', (code) => {
|
|
27
|
-
console.log('code', code);
|
|
28
|
-
console.log(err.slice(0, 2000));
|
|
29
|
-
});
|
|
30
|
-
|
package/scripts/fix-brief-fn.mjs
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
const p = "src/runtime/shared/tool-surface.mjs";
|
|
3
|
-
let s = fs.readFileSync(p, "utf8");
|
|
4
|
-
const start = s.indexOf("export function summarizeAgentSurfaceBrief");
|
|
5
|
-
const end = s.indexOf("function pluralize", start);
|
|
6
|
-
if (start < 0 || end < 0) throw new Error("markers");
|
|
7
|
-
const clean = `export function summarizeAgentSurfaceBrief(name, args, resultText, { isError = false, isResponse = false } = {}) {
|
|
8
|
-
const a = parseToolArgs(args);
|
|
9
|
-
const action = String(a?.type || a?.action || "").toLowerCase();
|
|
10
|
-
const text = String(resultText ?? "").trim();
|
|
11
|
-
|
|
12
|
-
if (isResponse && text) {
|
|
13
|
-
const fromResult = summarizeToolResult(name, args, text, isError);
|
|
14
|
-
if (fromResult) return truncateAgentSurfaceBrief(stripInlineMarkdown(fromResult));
|
|
15
|
-
const line = firstAgentResultLine(text);
|
|
16
|
-
if (line) return truncateAgentSurfaceBrief(stripInlineMarkdown(line));
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const outbound = firstText(a?.prompt, a?.message);
|
|
20
|
-
if (outbound && (action === "spawn" || action === "send" || !action)) {
|
|
21
|
-
return truncateAgentSurfaceBrief(outbound);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if ((action === "spawn" || action === "send") && text && !isResponse) {
|
|
25
|
-
const fromResult = summarizeToolResult(name, args, text, isError);
|
|
26
|
-
if (fromResult) return truncateAgentSurfaceBrief(stripInlineMarkdown(fromResult));
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return "";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
`;
|
|
33
|
-
s = s.slice(0, start) + clean + s.slice(end);
|
|
34
|
-
fs.writeFileSync(p, s);
|
|
35
|
-
console.log("summarizeAgentSurfaceBrief cleaned");
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
const p = "src/runtime/shared/tool-surface.mjs";
|
|
3
|
-
let s = fs.readFileSync(p, "utf8");
|
|
4
|
-
const block = `export function formatToolSurface(name, args, opts = {}) {
|
|
5
|
-
const parsed = parseToolArgs(args);
|
|
6
|
-
return {
|
|
7
|
-
label: displayToolName(name, parsed),
|
|
8
|
-
summary: summarizeToolArgs(name, parsed, opts),
|
|
9
|
-
normalizedName: normalizeToolName(name),
|
|
10
|
-
args: parsed,
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
`;
|
|
15
|
-
while (s.includes(block)) {
|
|
16
|
-
s = s.replace(block, "");
|
|
17
|
-
}
|
|
18
|
-
const anchor = `/** Collapsed agent/worker surface card: one-line brief under the header (30-40 chars). */`;
|
|
19
|
-
if (!s.includes(anchor)) throw new Error("anchor missing");
|
|
20
|
-
if (!s.includes("export function formatToolSurface")) {
|
|
21
|
-
s = s.replace(anchor, block + anchor);
|
|
22
|
-
}
|
|
23
|
-
fs.writeFileSync(p, s);
|
|
24
|
-
console.log("fixed formatToolSurface");
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
const p = "src/tui/components/ToolExecution.jsx";
|
|
3
|
-
let s = fs.readFileSync(p, "utf8");
|
|
4
|
-
const bad = ` let visibleDetailLines = detailLines;
|
|
5
|
-
if (isSkillSurface && !showRawResult) {
|
|
6
|
-
visibleDetailLines = [];
|
|
7
|
-
} else if (isAgentSurfaceCard && !showRawResult) {
|
|
8
|
-
if (agentSurfaceBrief) {
|
|
9
|
-
visibleDetailLines = [agentSurfaceBrief];
|
|
10
|
-
} else if (pending) {
|
|
11
|
-
visibleDetailLines = [pendingDetailPlaceholder || 'Running'];
|
|
12
|
-
} else {
|
|
13
|
-
visibleDetailLines = [];
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
} else if (isAgentSurfaceCard && !showRawResult) {
|
|
17
|
-
} else if (isAgentSurfaceCard && !showRawResult) {
|
|
18
|
-
const agentDetailFallback = collapsedDetail
|
|
19
|
-
|| (pending ? (pendingDetailPlaceholder || 'Running') : 'Finished');
|
|
20
|
-
const agentDetailLine = agentSurfaceBrief
|
|
21
|
-
|| truncateToWidth(String(agentDetailFallback), Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars));
|
|
22
|
-
visibleDetailLines = [agentDetailLine];
|
|
23
|
-
}`;
|
|
24
|
-
const good = ` let visibleDetailLines = detailLines;
|
|
25
|
-
if (isSkillSurface && !showRawResult) {
|
|
26
|
-
visibleDetailLines = [];
|
|
27
|
-
} else if (isAgentSurfaceCard && !showRawResult) {
|
|
28
|
-
const agentDetailFallback = collapsedDetail
|
|
29
|
-
|| (pending ? (pendingDetailPlaceholder || 'Running') : 'Finished');
|
|
30
|
-
const agentDetailLine = agentSurfaceBrief
|
|
31
|
-
|| truncateToWidth(String(agentDetailFallback), Math.min(AGENT_SURFACE_BRIEF_MAX, maxResultChars));
|
|
32
|
-
visibleDetailLines = [agentDetailLine];
|
|
33
|
-
}`;
|
|
34
|
-
if (s.includes(bad)) {
|
|
35
|
-
s = s.replace(bad, good);
|
|
36
|
-
fs.writeFileSync(p, s);
|
|
37
|
-
console.log("ToolExecution fixed");
|
|
38
|
-
} else if (s.includes("agentDetailFallback")) {
|
|
39
|
-
console.log("ToolExecution already ok");
|
|
40
|
-
} else {
|
|
41
|
-
throw new Error("ToolExecution pattern not found");
|
|
42
|
-
}
|