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
|
@@ -263,10 +263,20 @@ export function diagnoseDiscordTokenValue(value, config = {}) {
|
|
|
263
263
|
const discord = config?.discord && typeof config.discord === 'object' ? config.discord : {}
|
|
264
264
|
const appId = String(discord.applicationId || '').trim()
|
|
265
265
|
if (appId && token === appId) return 'Bot token field contains the Application ID, not the bot token.'
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
// Single main channel: check the `channel` object. Legacy `channelsConfig`
|
|
267
|
+
// is still read here (read-only) so the diagnostic keeps working on configs
|
|
268
|
+
// that predate the single-channel collapse.
|
|
269
|
+
const candidateEntries = []
|
|
270
|
+
if (config?.channel && typeof config.channel === 'object') candidateEntries.push(config.channel)
|
|
271
|
+
if (config?.channelsConfig && typeof config.channelsConfig === 'object') {
|
|
272
|
+
candidateEntries.push(...Object.values(config.channelsConfig))
|
|
273
|
+
}
|
|
274
|
+
for (const ch of candidateEntries) {
|
|
275
|
+
if (!ch || typeof ch !== 'object') continue
|
|
276
|
+
for (const id of [ch.channelId, ch.discordChannelId, ch.telegramChatId]) {
|
|
277
|
+
const channelId = String(id || '').trim()
|
|
278
|
+
if (channelId && token === channelId) return 'Bot token field contains a Channel ID, not the bot token.'
|
|
279
|
+
}
|
|
270
280
|
}
|
|
271
281
|
if (isDiscordSnowflake(token)) return 'Bot token field contains a numeric Discord ID, not the bot token.'
|
|
272
282
|
return null
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// path. A `mixdog`-launched session can be "managed": the launcher
|
|
5
5
|
// (setup/mixdog.mjs) owns the child process and exposes a file-based
|
|
6
6
|
// command queue under the runtime root. Internal commands (/clear,
|
|
7
|
-
// /reload-plugins) are enqueued by the MCP server (
|
|
7
|
+
// /reload-plugins) are enqueued by the MCP server (inject_input)
|
|
8
8
|
// and the launcher delivers them to the child's stdin — no terminal keystroke
|
|
9
9
|
// injection, no new window. Works on Windows / macOS / Linux.
|
|
10
10
|
//
|
|
@@ -166,7 +166,7 @@ export function managedLaunchId() {
|
|
|
166
166
|
|
|
167
167
|
let enqueueSequence = 0;
|
|
168
168
|
|
|
169
|
-
// Writer side (
|
|
169
|
+
// Writer side (inject_input): publish one command for the
|
|
170
170
|
// launcher to deliver. Prefers the canonical Rust backend; the JS writer (temp
|
|
171
171
|
// name + rename so the watcher never sees a partial file) is the fallback.
|
|
172
172
|
// Returns the published path.
|
|
@@ -44,6 +44,25 @@ export function readMarkdownDocument(markdown) {
|
|
|
44
44
|
};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Serialize a single-file frontmatter markdown document:
|
|
48
|
+
// ---
|
|
49
|
+
// key: value
|
|
50
|
+
// ---
|
|
51
|
+
//
|
|
52
|
+
// <body>
|
|
53
|
+
// Values are stringified as-is (enabled:false -> "false"); the reader casts
|
|
54
|
+
// types back. Mirrors the WORKFLOW.md / SKILL.md single-file convention,
|
|
55
|
+
// where `name` and `description` lead the frontmatter.
|
|
56
|
+
export function serializeFrontmatterDoc(meta = {}, body = '') {
|
|
57
|
+
const lines = ['---'];
|
|
58
|
+
for (const [key, value] of Object.entries(meta)) {
|
|
59
|
+
if (value === undefined || value === null) continue;
|
|
60
|
+
lines.push(`${key}: ${value}`);
|
|
61
|
+
}
|
|
62
|
+
lines.push('---', '');
|
|
63
|
+
return `${lines.join('\n')}\n${String(body || '').trim()}\n`;
|
|
64
|
+
}
|
|
65
|
+
|
|
47
66
|
export function normalizeAgentPermission(value) {
|
|
48
67
|
const key = clean(value).toLowerCase();
|
|
49
68
|
return AGENT_PERMISSION_ALIASES.get(key) || null;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* `<Mixdog data dir>/schedules/<name>/` is the single source of truth.
|
|
5
5
|
* Each schedule directory contains a single `SCHEDULE.md` — YAML-ish
|
|
6
|
-
* frontmatter (
|
|
7
|
-
*
|
|
6
|
+
* frontmatter (name/description lead per the SKILL.md convention, then
|
|
7
|
+
* metadata: time/timezone/days/channel/model/enabled) plus a markdown
|
|
8
|
+
* body (the prompt). Both the setup UI (POST /schedules) and the
|
|
8
9
|
* `schedule-add` skill write the same one file; every reader —
|
|
9
10
|
* setup-server (GET /schedules), channels/lib/config.mjs (loadConfig),
|
|
10
11
|
* status/aggregator.mjs — must go through listSchedules() so a single
|
|
@@ -35,9 +36,12 @@ function readTextFile(path) {
|
|
|
35
36
|
*
|
|
36
37
|
* Return shape per entry: `{ name, ...frontmatter, prompt }`.
|
|
37
38
|
* - `name` is the directory name (slug).
|
|
39
|
+
* - `description` from frontmatter (display-only; defaults to '').
|
|
38
40
|
* - Spread of `SCHEDULE.md` frontmatter keys (time/timezone/days/channel/
|
|
39
41
|
* model/enabled). All frontmatter values arrive as strings; `enabled` is
|
|
40
42
|
* cast to a boolean here so downstream `s.enabled !== false` filters work.
|
|
43
|
+
* Frontmatter `name` is display-only and never overrides the dir slug used
|
|
44
|
+
* for identity/routing.
|
|
41
45
|
* - `prompt` carries the `SCHEDULE.md` body (empty string when the file is
|
|
42
46
|
* missing — caller decides whether that is a hard error).
|
|
43
47
|
*
|
|
@@ -66,7 +70,13 @@ export function listSchedules() {
|
|
|
66
70
|
if (Object.prototype.hasOwnProperty.call(cfg, 'enabled')) {
|
|
67
71
|
cfg.enabled = cfg.enabled !== 'false' && cfg.enabled !== false;
|
|
68
72
|
}
|
|
69
|
-
|
|
73
|
+
// Dir name is canonical identity; frontmatter `name` is display-only and
|
|
74
|
+
// must not override the slug. `description` defaults to '' (backward compat
|
|
75
|
+
// for old files with no such key).
|
|
76
|
+
const description = String(cfg.description || '');
|
|
77
|
+
delete cfg.name;
|
|
78
|
+
delete cfg.description;
|
|
79
|
+
out.push({ name, description, ...cfg, prompt: body });
|
|
70
80
|
}
|
|
71
81
|
return out;
|
|
72
82
|
}
|
|
@@ -2,10 +2,10 @@ export const TOOL_SYNC_EXECUTION_CONTRACT =
|
|
|
2
2
|
'Runs synchronously in this tool call.';
|
|
3
3
|
|
|
4
4
|
export const TOOL_ASYNC_EXECUTION_CONTRACT =
|
|
5
|
-
'Async returns task_id; completion notification follows. status/read/wait are
|
|
5
|
+
'Async returns task_id; completion notification follows. status/read/wait are recovery/blocking only.';
|
|
6
6
|
|
|
7
7
|
export const TOOL_MANUAL_CONTROL_CONTRACT =
|
|
8
|
-
'
|
|
8
|
+
'wait/read/status/cancel are for explicit blocking or recovery only.';
|
|
9
9
|
|
|
10
10
|
function clean(value) {
|
|
11
11
|
return String(value ?? '').trim();
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { displayModelName as sharedDisplayModelName } from '../../ui/model-display.mjs';
|
|
2
|
+
|
|
3
|
+
// Default cap for tool-arg summaries (header parenthetical, channel tool lines).
|
|
4
|
+
// Unified at 80 so every tool surface line — header arg summary and collapsed
|
|
5
|
+
// detail alike — shares one width ceiling; per-call sites still clamp lower
|
|
6
|
+
// (header 48, channel 50) where a tighter line is wanted.
|
|
7
|
+
export const DEFAULT_SUMMARY_MAX = 80;
|
|
8
|
+
// Semantic cap for collapsed tool/agent/task card one-liners — the second row
|
|
9
|
+
// under the ⎿ gutter (spawn, send, response, generic/shell result summaries).
|
|
10
|
+
// Kept at 80 so every collapsed detail line is truncated to the same width
|
|
11
|
+
// regardless of terminal columns; ctrl+o expand still shows the full body.
|
|
12
|
+
export const AGENT_SURFACE_BRIEF_MAX = 80;
|
|
13
|
+
export const STATUS_SEPARATOR = ' · ';
|
|
14
|
+
|
|
15
|
+
export function stripToolPrefix(name) {
|
|
16
|
+
const text = rawToolName(name);
|
|
17
|
+
const mcp = parseMcpToolName(text);
|
|
18
|
+
return mcp ? mcp.tool : text;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function rawToolName(name) {
|
|
22
|
+
return String(name || 'tool').replace(/^functions\./, '');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function parseMcpToolName(name) {
|
|
26
|
+
const text = rawToolName(name);
|
|
27
|
+
const match = /^mcp__(.+?)__(.+)$/.exec(text);
|
|
28
|
+
if (!match) return null;
|
|
29
|
+
return { server: match[1], tool: match[2] };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function isMcpToolName(name) {
|
|
33
|
+
return Boolean(parseMcpToolName(name));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function normalizeToolName(name) {
|
|
37
|
+
return stripToolPrefix(name).replace(/-/g, '_').toLowerCase();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function truncateToolText(value, max = DEFAULT_SUMMARY_MAX) {
|
|
41
|
+
const text = String(value ?? '').trim();
|
|
42
|
+
return text.length > max ? `${text.slice(0, max)}...` : text;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function truncateSingleLine(value, max = DEFAULT_SUMMARY_MAX) {
|
|
46
|
+
return truncateToolText(String(value ?? '').replace(/\s+/g, ' '), max);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function truncateCommand(value, max = DEFAULT_SUMMARY_MAX) {
|
|
50
|
+
const text = String(value ?? '').trim();
|
|
51
|
+
if (!text) return '';
|
|
52
|
+
const lines = text.split('\n');
|
|
53
|
+
let out = lines.length > 2 ? `${lines.slice(0, 2).join(' ')}...` : lines.join(' ');
|
|
54
|
+
out = out.replace(/\s+/g, ' ').trim();
|
|
55
|
+
return out.length > max ? `${out.slice(0, Math.max(1, max - 3))}...` : out;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function parseToolArgs(args) {
|
|
59
|
+
if (!args) return {};
|
|
60
|
+
if (typeof args === 'string') {
|
|
61
|
+
try {
|
|
62
|
+
const parsed = JSON.parse(args);
|
|
63
|
+
return parsed && typeof parsed === 'object' ? parsed : { value: args };
|
|
64
|
+
} catch {
|
|
65
|
+
return { value: args };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (typeof args === 'object') {
|
|
69
|
+
if (args.input && typeof args.input === 'object') return args.input;
|
|
70
|
+
return args;
|
|
71
|
+
}
|
|
72
|
+
return { value: args };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function displayToolPath(path) {
|
|
76
|
+
const text = String(path ?? '');
|
|
77
|
+
return text.replace(/\\/g, '/').split('/').filter(Boolean).at(-1) || text;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function compactParts(parts) {
|
|
81
|
+
return parts.filter((part) => part != null && String(part).trim()).map((part) => String(part).trim()).join(STATUS_SEPARATOR);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function compactSlash(left, right) {
|
|
85
|
+
const a = String(left ?? '').trim();
|
|
86
|
+
const b = String(right ?? '').trim();
|
|
87
|
+
return a && b ? `${a}/${b}` : a || b;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function mcpToolTarget(name, max = DEFAULT_SUMMARY_MAX) {
|
|
91
|
+
const mcp = parseMcpToolName(name);
|
|
92
|
+
if (!mcp) return '';
|
|
93
|
+
return truncateToolText(compactSlash(mcp.server, mcp.tool), max);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function quoted(value, max) {
|
|
97
|
+
const text = truncateToolText(value || '', max);
|
|
98
|
+
return text ? `"${text}"` : '';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function firstText(...values) {
|
|
102
|
+
for (const value of values) {
|
|
103
|
+
if (value != null && String(value).trim()) return String(value).trim();
|
|
104
|
+
}
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function splitToolSearchSelection(value) {
|
|
109
|
+
if (Array.isArray(value)) return value.map((item) => String(item || '').trim()).filter(Boolean);
|
|
110
|
+
return String(value || '')
|
|
111
|
+
.split(/[,\s]+/)
|
|
112
|
+
.map((item) => item.trim())
|
|
113
|
+
.filter(Boolean);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function toolSearchTargetKind(value) {
|
|
117
|
+
const lower = String(value || '').trim().toLowerCase();
|
|
118
|
+
if (!lower) return '';
|
|
119
|
+
if (lower.startsWith('mcp__') || lower.includes('_mcp_') || lower.includes('mcp')) return 'MCP';
|
|
120
|
+
if (lower === 'skill' || lower.startsWith('skill:') || lower.startsWith('skill_') || lower.startsWith('skills_') || lower.includes('skill')) return 'Skills';
|
|
121
|
+
return 'Tools';
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function orderedToolSearchKinds(kinds) {
|
|
125
|
+
const set = new Set((kinds || []).filter(Boolean));
|
|
126
|
+
const order = ['Tools', 'MCP', 'Skills'];
|
|
127
|
+
const out = order.filter((kind) => set.has(kind));
|
|
128
|
+
return out.length ? out : ['Tools'];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function inferToolSearchKinds(args = {}) {
|
|
132
|
+
const selected = splitToolSearchSelection(args.select);
|
|
133
|
+
if (selected.length) return orderedToolSearchKinds(selected.map(toolSearchTargetKind));
|
|
134
|
+
|
|
135
|
+
const query = firstText(args.query, args.q, args.text).toLowerCase();
|
|
136
|
+
const kinds = [];
|
|
137
|
+
if (/\bmcp\b|mcp__|mcp[-_\s]?server/.test(query)) kinds.push('MCP');
|
|
138
|
+
if (/\bskills?\b|skill_|use[-_\s]?skill/.test(query)) kinds.push('Skills');
|
|
139
|
+
return orderedToolSearchKinds(kinds);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function toolSearchDisplayLabel(args = {}) {
|
|
143
|
+
return `Load ${inferToolSearchKinds(args).join('/')}`;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function displayToolSearchTarget(value) {
|
|
147
|
+
const text = String(value || '').trim();
|
|
148
|
+
if (/^skill:/i.test(text)) return text.slice('skill:'.length);
|
|
149
|
+
const mcp = /^mcp__(.*?)__(.+)$/.exec(text);
|
|
150
|
+
if (mcp) return `${mcp[1]}.${mcp[2]}`;
|
|
151
|
+
return stripToolPrefix(text);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function titleizeToolName(name) {
|
|
155
|
+
return stripToolPrefix(name)
|
|
156
|
+
.split(/[_\s-]+/)
|
|
157
|
+
.filter(Boolean)
|
|
158
|
+
.map((part) => {
|
|
159
|
+
const lower = part.toLowerCase();
|
|
160
|
+
if (lower === 'ui') return 'UI';
|
|
161
|
+
if (lower === 'mcp') return 'MCP';
|
|
162
|
+
if (lower === 'id') return 'ID';
|
|
163
|
+
return `${lower.slice(0, 1).toUpperCase()}${lower.slice(1)}`;
|
|
164
|
+
})
|
|
165
|
+
.join(' ') || 'Tool';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const AGENT_DISPLAY_NAMES = new Map([
|
|
169
|
+
['explore', 'Explore'],
|
|
170
|
+
['maintainer', 'Maintainer'],
|
|
171
|
+
['worker', 'Worker'],
|
|
172
|
+
['heavy-worker', 'Heavy Worker'],
|
|
173
|
+
['reviewer', 'Reviewer'],
|
|
174
|
+
['debugger', 'Debugger'],
|
|
175
|
+
]);
|
|
176
|
+
|
|
177
|
+
function titleizeDisplayName(value) {
|
|
178
|
+
const text = String(value || '').trim();
|
|
179
|
+
if (!text) return '';
|
|
180
|
+
return text
|
|
181
|
+
.replace(/[_-]+/g, ' ')
|
|
182
|
+
.split(/\s+/)
|
|
183
|
+
.filter(Boolean)
|
|
184
|
+
.map((part) => {
|
|
185
|
+
const lower = part.toLowerCase();
|
|
186
|
+
if (lower === 'ui') return 'UI';
|
|
187
|
+
if (lower === 'mcp') return 'MCP';
|
|
188
|
+
if (lower === 'id') return 'ID';
|
|
189
|
+
return `${lower.slice(0, 1).toUpperCase()}${lower.slice(1)}`;
|
|
190
|
+
})
|
|
191
|
+
.join(' ');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function displayAgentName(value) {
|
|
195
|
+
const text = String(value || '').trim();
|
|
196
|
+
if (!text) return '';
|
|
197
|
+
const key = text.toLowerCase().replace(/[\s_]+/g, '-');
|
|
198
|
+
return AGENT_DISPLAY_NAMES.get(key) || titleizeDisplayName(text);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function displayModelName(model, provider, displayHint) {
|
|
202
|
+
const text = String(model ?? '').trim();
|
|
203
|
+
const modelId = text
|
|
204
|
+
? (text.includes('/') ? (text.split('/').filter(Boolean).at(-1) || text) : text)
|
|
205
|
+
: '';
|
|
206
|
+
const shown = sharedDisplayModelName(modelId, provider, displayHint);
|
|
207
|
+
return shown || modelId;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export function bridgeAgentModelSummary(args) {
|
|
211
|
+
const provider = firstText(args.provider, args.providerId, args.provider_id);
|
|
212
|
+
const modelId = firstText(args.model);
|
|
213
|
+
const displayHint = firstText(args.modelDisplay, args.model_display, args.displayModel);
|
|
214
|
+
return compactParts([
|
|
215
|
+
displayAgentName(firstText(args.agent, args.name, args.subagent_type)),
|
|
216
|
+
displayModelName(modelId, provider, displayHint),
|
|
217
|
+
]);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function summarizeLineWindow(a) {
|
|
221
|
+
const offset = a.offset ?? a.start_line ?? a.startLine ?? a.line;
|
|
222
|
+
const limit = a.limit ?? a.line_count ?? a.lineCount ?? a.lines;
|
|
223
|
+
if (offset == null && limit == null) return '';
|
|
224
|
+
const start = Number(offset);
|
|
225
|
+
const count = Number(limit);
|
|
226
|
+
if (Number.isFinite(start) && Number.isFinite(count) && count > 0) {
|
|
227
|
+
return `lines ${start}-${Math.max(start, start + count - 1)}`;
|
|
228
|
+
}
|
|
229
|
+
if (Number.isFinite(start)) return `from line ${start}`;
|
|
230
|
+
if (Number.isFinite(count)) return `${count} lines`;
|
|
231
|
+
return '';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function summarizePatch(patch, basePath) {
|
|
235
|
+
const text = String(patch ?? '');
|
|
236
|
+
const files = [];
|
|
237
|
+
for (const line of text.split('\n')) {
|
|
238
|
+
const match = /^\*\*\*\s+(?:Update|Add|Delete) File:\s+(.+)\s*$/.exec(line);
|
|
239
|
+
if (match) files.push(displayToolPath(match[1]));
|
|
240
|
+
}
|
|
241
|
+
if (files.length === 1) return files[0];
|
|
242
|
+
if (files.length > 1) return `${files.length} files`;
|
|
243
|
+
if (basePath) return displayToolPath(basePath);
|
|
244
|
+
return text ? 'patch' : '';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export function collectionCount(...values) {
|
|
248
|
+
for (const value of values) {
|
|
249
|
+
if (Array.isArray(value)) {
|
|
250
|
+
const count = value.filter((item) => item != null && String(item).trim()).length;
|
|
251
|
+
return count || value.length || 0;
|
|
252
|
+
}
|
|
253
|
+
if (value && typeof value === 'object') return 1;
|
|
254
|
+
if (value != null && String(value).trim()) return 1;
|
|
255
|
+
}
|
|
256
|
+
return 0;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function formatCountedUnit(count, singular, pluralText = `${singular}s`) {
|
|
260
|
+
const n = Math.max(0, Number(count || 0));
|
|
261
|
+
return n > 0 ? `${n} ${pluralize(n, singular, pluralText)}` : '';
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export function patchFileCount(args = {}) {
|
|
265
|
+
const patchText = String(args.patch ?? '');
|
|
266
|
+
if (patchText) {
|
|
267
|
+
const files = new Set();
|
|
268
|
+
for (const line of patchText.split('\n')) {
|
|
269
|
+
const match = /^\*\*\*\s+(?:Update|Add|Delete) File:\s+(.+)\s*$/.exec(line);
|
|
270
|
+
if (match) files.add(match[1].trim());
|
|
271
|
+
}
|
|
272
|
+
if (files.size > 0) return files.size;
|
|
273
|
+
}
|
|
274
|
+
return collectionCount(args.path, args.file, args.file_path, args.base_path);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export function codeGraphLabel(args) {
|
|
278
|
+
const mode = String(args.mode || args.action || '').toLowerCase();
|
|
279
|
+
if (mode === 'prewarm' || mode === 'index' || mode === 'build' || mode === 'refresh') return 'Setup';
|
|
280
|
+
if (mode === 'search' || mode === 'find_symbol' || mode === 'references' || mode === 'callers' || mode === 'callees') return 'Search';
|
|
281
|
+
return 'Read';
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function codeGraphSummary(args, max) {
|
|
285
|
+
return compactParts([
|
|
286
|
+
args.mode || args.action || '',
|
|
287
|
+
truncateToolText(firstText(args.symbol, Array.isArray(args.symbols) ? args.symbols.join(', ') : '', args.file, args.path, args.query), max),
|
|
288
|
+
]);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export function pluralize(count, singular, pluralText = `${singular}s`) {
|
|
292
|
+
return count === 1 ? singular : pluralText;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
export function titleWord(value) {
|
|
296
|
+
const text = String(value || '');
|
|
297
|
+
return text ? `${text.charAt(0).toUpperCase()}${text.slice(1).toLowerCase()}` : '';
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function titleStatus(value) {
|
|
301
|
+
const text = String(value || '').trim();
|
|
302
|
+
if (!text) return '';
|
|
303
|
+
if (/^ok$/i.test(text)) return 'Ok';
|
|
304
|
+
if (/^(done|success|completed)$/i.test(text)) return 'Finished';
|
|
305
|
+
if (/^(error|failed|fail|killed|timeout)$/i.test(text)) return 'Failed';
|
|
306
|
+
if (/^(cancelled|canceled|cancel)$/i.test(text)) return 'Cancelled';
|
|
307
|
+
return titleWord(text);
|
|
308
|
+
}
|