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
|
@@ -1,285 +0,0 @@
|
|
|
1
|
-
// Server-less diagnostics tool.
|
|
2
|
-
//
|
|
3
|
-
// Mixdog has no resident LSP server. Instead this tool detects the project
|
|
4
|
-
// marker(s) under the target path, runs the matching project CLI ONCE via the
|
|
5
|
-
// same exec path bash-tool uses (execShellCommand + resolveShell), then PARSES
|
|
6
|
-
// the checker's stdout/stderr into structured findings. No watch, no daemon.
|
|
7
|
-
//
|
|
8
|
-
// Graceful contract: a missing marker or a missing checker binary returns a
|
|
9
|
-
// clear "no checker available for X" message — it never throws.
|
|
10
|
-
import { existsSync, readFileSync, statSync } from 'fs';
|
|
11
|
-
import { dirname, isAbsolute, resolve as pathResolve } from 'path';
|
|
12
|
-
import { execShellCommand, stripAnsi } from '../shell-command.mjs';
|
|
13
|
-
import { resolveShell } from './shell-runtime.mjs';
|
|
14
|
-
|
|
15
|
-
const DIAGNOSTICS_TIMEOUT_MS = 120_000;
|
|
16
|
-
|
|
17
|
-
// Probe whether a CLI binary is resolvable on PATH without running real work.
|
|
18
|
-
// Uses the platform command-resolver so an absent checker degrades gracefully
|
|
19
|
-
// into a "no checker available" message instead of a spawn error.
|
|
20
|
-
async function _commandExists(bin, cwd, env) {
|
|
21
|
-
const { shell, shellArg, shellArgs, shellType } = resolveShell();
|
|
22
|
-
const probe = shellType === 'powershell'
|
|
23
|
-
? `Get-Command ${bin} -ErrorAction SilentlyContinue | Select-Object -First 1`
|
|
24
|
-
: `command -v ${bin}`;
|
|
25
|
-
try {
|
|
26
|
-
const r = await execShellCommand({
|
|
27
|
-
shell, shellArg, shellArgs, command: probe,
|
|
28
|
-
env, cwd, timeoutMs: 10_000, abortSignal: null,
|
|
29
|
-
});
|
|
30
|
-
const out = `${r.stdout || ''}`.trim();
|
|
31
|
-
if (shellType === 'powershell') return out.length > 0;
|
|
32
|
-
return r.exitCode === 0 && out.length > 0;
|
|
33
|
-
} catch {
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
async function _runChecker(command, cwd, env) {
|
|
39
|
-
const { shell, shellArg, shellArgs } = resolveShell();
|
|
40
|
-
const r = await execShellCommand({
|
|
41
|
-
shell, shellArg, shellArgs, command,
|
|
42
|
-
env, cwd, timeoutMs: DIAGNOSTICS_TIMEOUT_MS, abortSignal: null,
|
|
43
|
-
});
|
|
44
|
-
return {
|
|
45
|
-
stdout: stripAnsi(r.stdout || ''),
|
|
46
|
-
stderr: stripAnsi(r.stderr || ''),
|
|
47
|
-
exitCode: r.timedOut ? null : r.exitCode,
|
|
48
|
-
timedOut: !!r.timedOut,
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// ---- per-checker output parsers -> [{file,line,col,severity,code,message}] ----
|
|
53
|
-
|
|
54
|
-
function _parseTsc(text) {
|
|
55
|
-
const findings = [];
|
|
56
|
-
const re = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+):\s+(.*)$/;
|
|
57
|
-
for (const line of text.split(/\r?\n/)) {
|
|
58
|
-
const m = re.exec(line.trim());
|
|
59
|
-
if (m) findings.push({ file: m[1], line: +m[2], col: +m[3], severity: m[4], code: m[5], message: m[6] });
|
|
60
|
-
}
|
|
61
|
-
return findings;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function _parseRuff(text) {
|
|
65
|
-
const findings = [];
|
|
66
|
-
// ruff default text: path:line:col: CODE message
|
|
67
|
-
const re = /^(.+?):(\d+):(\d+):\s+([A-Z]+\d+)\s+(.*)$/;
|
|
68
|
-
for (const line of text.split(/\r?\n/)) {
|
|
69
|
-
const m = re.exec(line.trim());
|
|
70
|
-
if (!m) continue;
|
|
71
|
-
const code = m[4];
|
|
72
|
-
const severity = (/^(E9|F)/.test(code)) ? 'error' : 'warning';
|
|
73
|
-
findings.push({ file: m[1], line: +m[2], col: +m[3], severity, code, message: m[5] });
|
|
74
|
-
}
|
|
75
|
-
return findings;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function _parsePyflakes(text) {
|
|
79
|
-
const findings = [];
|
|
80
|
-
// pyflakes: path:line: message (no column)
|
|
81
|
-
const re = /^(.+?):(\d+):\s*(.*)$/;
|
|
82
|
-
for (const line of text.split(/\r?\n/)) {
|
|
83
|
-
const trimmed = line.trim();
|
|
84
|
-
if (!trimmed) continue;
|
|
85
|
-
const m = re.exec(trimmed);
|
|
86
|
-
if (m) findings.push({ file: m[1], line: +m[2], col: null, severity: 'warning', code: null, message: m[3] });
|
|
87
|
-
}
|
|
88
|
-
return findings;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function _parseGoVet(text) {
|
|
92
|
-
const findings = [];
|
|
93
|
-
// go vet: path:line:col: message OR path:line: message
|
|
94
|
-
const re = /^(.+?\.go):(\d+):(?:(\d+):)?\s+(.*)$/;
|
|
95
|
-
for (const line of text.split(/\r?\n/)) {
|
|
96
|
-
const m = re.exec(line.trim());
|
|
97
|
-
if (m) findings.push({ file: m[1], line: +m[2], col: m[3] ? +m[3] : null, severity: 'error', code: 'vet', message: m[4] });
|
|
98
|
-
}
|
|
99
|
-
return findings;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function _parseCargo(text) {
|
|
103
|
-
const findings = [];
|
|
104
|
-
// cargo check --message-format=short: path:line:col: severity[CODE]: message
|
|
105
|
-
const re = /^(.+?):(\d+):(\d+):\s+(warning|error)(?:\[([A-Za-z0-9]+)\])?:\s+(.*)$/;
|
|
106
|
-
for (const line of text.split(/\r?\n/)) {
|
|
107
|
-
const m = re.exec(line.trim());
|
|
108
|
-
if (m) findings.push({ file: m[1], line: +m[2], col: +m[3], severity: m[4], code: m[5] || null, message: m[6] });
|
|
109
|
-
}
|
|
110
|
-
return findings;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// node --check failure shape: "<abs file>:<line>" on its own line, followed
|
|
114
|
-
// by the offending source + caret, then "SyntaxError: <message>".
|
|
115
|
-
function _parseNodeCheck(text) {
|
|
116
|
-
const findings = [];
|
|
117
|
-
const head = /^(.+?):(\d+)\s*$/m.exec(text);
|
|
118
|
-
const err = /^([A-Za-z]*Error):\s+(.*)$/m.exec(text);
|
|
119
|
-
if (head && err) {
|
|
120
|
-
findings.push({ file: head[1], line: +head[2], col: null, severity: 'error', code: err[1], message: err[2] });
|
|
121
|
-
}
|
|
122
|
-
return findings;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function _parseEslintCompact(text) {
|
|
126
|
-
const findings = [];
|
|
127
|
-
// eslint --format compact: path: line N, col M, Severity - message (rule)
|
|
128
|
-
const re = /^(.+?):\s+line\s+(\d+),\s+col\s+(\d+),\s+(Error|Warning)\s+-\s+(.*?)(?:\s+\(([^)]+)\))?$/;
|
|
129
|
-
for (const line of text.split(/\r?\n/)) {
|
|
130
|
-
const m = re.exec(line.trim());
|
|
131
|
-
if (m) findings.push({ file: m[1], line: +m[2], col: +m[3], severity: m[4].toLowerCase(), code: m[6] || null, message: m[5] });
|
|
132
|
-
}
|
|
133
|
-
return findings;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Detect the project marker under projectDir and return the checker plan.
|
|
137
|
-
// Order is deterministic; the first matching marker wins.
|
|
138
|
-
function _detectChecker(projectDir) {
|
|
139
|
-
const has = (f) => existsSync(pathResolve(projectDir, f));
|
|
140
|
-
if (has('tsconfig.json')) {
|
|
141
|
-
return { kind: 'tsc', bin: 'tsc', command: 'tsc --noEmit', parse: _parseTsc, marker: 'tsconfig.json' };
|
|
142
|
-
}
|
|
143
|
-
if (has('pyproject.toml') || has('setup.py')) {
|
|
144
|
-
return { kind: 'python', marker: has('pyproject.toml') ? 'pyproject.toml' : 'setup.py' };
|
|
145
|
-
}
|
|
146
|
-
if (has('go.mod')) {
|
|
147
|
-
return { kind: 'go', bin: 'go', command: 'go vet ./...', parse: _parseGoVet, marker: 'go.mod' };
|
|
148
|
-
}
|
|
149
|
-
if (has('Cargo.toml')) {
|
|
150
|
-
return { kind: 'cargo', bin: 'cargo', command: 'cargo check --message-format=short', parse: _parseCargo, marker: 'Cargo.toml' };
|
|
151
|
-
}
|
|
152
|
-
if (has('package.json')) {
|
|
153
|
-
let usesEslint = false;
|
|
154
|
-
try {
|
|
155
|
-
const pkg = JSON.parse(readFileSync(pathResolve(projectDir, 'package.json'), 'utf8'));
|
|
156
|
-
const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
|
|
157
|
-
usesEslint = Object.prototype.hasOwnProperty.call(deps, 'eslint');
|
|
158
|
-
} catch { /* unreadable/invalid package.json */ }
|
|
159
|
-
const hasEslintConfig = ['.eslintrc', '.eslintrc.js', '.eslintrc.cjs', '.eslintrc.json', '.eslintrc.yml', '.eslintrc.yaml', 'eslint.config.js', 'eslint.config.mjs', 'eslint.config.cjs']
|
|
160
|
-
.some((f) => has(f));
|
|
161
|
-
if (usesEslint || hasEslintConfig) {
|
|
162
|
-
return { kind: 'eslint', bin: 'eslint', command: 'eslint . --format compact', parse: _parseEslintCompact, marker: 'package.json (eslint)' };
|
|
163
|
-
}
|
|
164
|
-
return { kind: 'none', reason: 'package.json present but no eslint dependency/config detected' };
|
|
165
|
-
}
|
|
166
|
-
return { kind: 'none', reason: 'no recognized project marker (tsconfig.json / pyproject.toml / setup.py / go.mod / Cargo.toml / package.json)' };
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function _formatResult({ marker, checker, findings, raw, note }) {
|
|
170
|
-
return JSON.stringify({
|
|
171
|
-
ok: true,
|
|
172
|
-
marker: marker || null,
|
|
173
|
-
checker: checker || null,
|
|
174
|
-
note: note || null,
|
|
175
|
-
count: findings.length,
|
|
176
|
-
findings,
|
|
177
|
-
raw: raw ? raw.slice(0, 4000) : undefined,
|
|
178
|
-
}, null, 2);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
export async function executeDiagnosticsTool(args, workDir, options = {}) {
|
|
182
|
-
const result = await _executeDiagnosticsImpl(args, workDir);
|
|
183
|
-
// ② completion progress (claude "Found N" parity). Best-effort, no-op
|
|
184
|
-
// when onProgress is absent (no progressToken). Never throws — the tool
|
|
185
|
-
// result is returned regardless.
|
|
186
|
-
if (typeof options?.onProgress === 'function') {
|
|
187
|
-
try {
|
|
188
|
-
let _n = null;
|
|
189
|
-
try { _n = JSON.parse(result)?.count; } catch { /* non-JSON envelope */ }
|
|
190
|
-
if (Number.isFinite(_n)) {
|
|
191
|
-
options.onProgress(_n === 0 ? 'no issues' : `${_n} issue${_n === 1 ? '' : 's'}`);
|
|
192
|
-
}
|
|
193
|
-
} catch { /* best-effort */ }
|
|
194
|
-
}
|
|
195
|
-
return result;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async function _executeDiagnosticsImpl(args, workDir) {
|
|
199
|
-
try {
|
|
200
|
-
// Resolve the target path (file or dir). Default: cwd.
|
|
201
|
-
const rawPath = (args && typeof args.path === 'string' && args.path.trim()) ? args.path.trim() : '';
|
|
202
|
-
const absTarget = rawPath
|
|
203
|
-
? (isAbsolute(rawPath) ? rawPath : pathResolve(workDir, rawPath))
|
|
204
|
-
: workDir;
|
|
205
|
-
if (rawPath && !existsSync(absTarget)) {
|
|
206
|
-
return _formatResult({ note: `path not found: ${rawPath}`, findings: [] });
|
|
207
|
-
}
|
|
208
|
-
let projectDir = absTarget;
|
|
209
|
-
try {
|
|
210
|
-
if (statSync(absTarget).isFile()) projectDir = dirname(absTarget);
|
|
211
|
-
} catch { /* fall through with absTarget */ }
|
|
212
|
-
|
|
213
|
-
let plan = _detectChecker(projectDir);
|
|
214
|
-
// A file deep in the tree (src/search/lib/foo.mjs) has its project
|
|
215
|
-
// marker at the repo ROOT — walk parent directories until a marker is
|
|
216
|
-
// found instead of reporting "no recognized project marker" from the
|
|
217
|
-
// file's immediate dirname. Stops at the first directory that yields
|
|
218
|
-
// any non-"no marker" answer (including "package.json present but no
|
|
219
|
-
// eslint"), or at the filesystem root.
|
|
220
|
-
{
|
|
221
|
-
const _noMarker = (p) => p.kind === 'none' && String(p.reason || '').startsWith('no recognized project marker');
|
|
222
|
-
let walk = projectDir;
|
|
223
|
-
while (_noMarker(plan)) {
|
|
224
|
-
const parent = dirname(walk);
|
|
225
|
-
if (!parent || parent === walk) break;
|
|
226
|
-
walk = parent;
|
|
227
|
-
plan = _detectChecker(walk);
|
|
228
|
-
}
|
|
229
|
-
if (!_noMarker(plan)) projectDir = walk;
|
|
230
|
-
}
|
|
231
|
-
if (plan.kind === 'none') {
|
|
232
|
-
// Syntax-check fallback: a JS file target can still be validated
|
|
233
|
-
// with `node --check` even when the project has no lint setup —
|
|
234
|
-
// catch the dominant failure class (parse errors) instead of
|
|
235
|
-
// going dark with "no checker".
|
|
236
|
-
let isJsFile = false;
|
|
237
|
-
try { isJsFile = /\.(mjs|cjs|js)$/i.test(absTarget) && statSync(absTarget).isFile(); } catch { /* keep false */ }
|
|
238
|
-
if (isJsFile) {
|
|
239
|
-
const env = { ...process.env, LANG: 'C.UTF-8', LC_ALL: 'C.UTF-8' };
|
|
240
|
-
if (await _commandExists('node', projectDir, env)) {
|
|
241
|
-
const r = await _runChecker(`node --check "${absTarget}"`, projectDir, env);
|
|
242
|
-
const combined = `${r.stdout}\n${r.stderr}`;
|
|
243
|
-
const findings = _parseNodeCheck(combined);
|
|
244
|
-
return _formatResult({ checker: 'node --check (no-lint fallback)', findings, raw: combined, note: `${plan.reason} — fell back to syntax check only` });
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return _formatResult({ note: `no checker available for this path — ${plan.reason}`, findings: [] });
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const env = { ...process.env, LANG: 'C.UTF-8', LC_ALL: 'C.UTF-8' };
|
|
251
|
-
|
|
252
|
-
// Python is special: prefer ruff, fall back to pyflakes.
|
|
253
|
-
if (plan.kind === 'python') {
|
|
254
|
-
if (await _commandExists('ruff', projectDir, env)) {
|
|
255
|
-
const r = await _runChecker('ruff check .', projectDir, env);
|
|
256
|
-
const findings = _parseRuff(`${r.stdout}\n${r.stderr}`);
|
|
257
|
-
return _formatResult({ marker: plan.marker, checker: 'ruff check', findings, raw: `${r.stdout}\n${r.stderr}` });
|
|
258
|
-
}
|
|
259
|
-
if (await _commandExists('python', projectDir, env)) {
|
|
260
|
-
const r = await _runChecker('python -m pyflakes .', projectDir, env);
|
|
261
|
-
const out = `${r.stdout}\n${r.stderr}`;
|
|
262
|
-
if (/No module named pyflakes/i.test(out)) {
|
|
263
|
-
return _formatResult({ marker: plan.marker, note: 'no checker available for Python — ruff absent and pyflakes module not installed', findings: [] });
|
|
264
|
-
}
|
|
265
|
-
const findings = _parsePyflakes(out);
|
|
266
|
-
return _formatResult({ marker: plan.marker, checker: 'python -m pyflakes (ruff fallback)', findings, raw: out });
|
|
267
|
-
}
|
|
268
|
-
return _formatResult({ marker: plan.marker, note: 'no checker available for Python — neither ruff nor python found on PATH', findings: [] });
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (!(await _commandExists(plan.bin, projectDir, env))) {
|
|
272
|
-
return _formatResult({ marker: plan.marker, note: `no checker available for ${plan.kind} — "${plan.bin}" not found on PATH`, findings: [] });
|
|
273
|
-
}
|
|
274
|
-
const r = await _runChecker(plan.command, projectDir, env);
|
|
275
|
-
const combined = `${r.stdout}\n${r.stderr}`;
|
|
276
|
-
const findings = plan.parse(combined);
|
|
277
|
-
const note = r.timedOut ? `checker timed out after ${DIAGNOSTICS_TIMEOUT_MS}ms` : null;
|
|
278
|
-
return _formatResult({ marker: plan.marker, checker: plan.command, findings, raw: combined, note });
|
|
279
|
-
} catch (err) {
|
|
280
|
-
// Never throw — surface a graceful diagnostic envelope.
|
|
281
|
-
return JSON.stringify({ ok: false, error: `diagnostics failed: ${err && err.message ? err.message : String(err)}`, findings: [] }, null, 2);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export default executeDiagnosticsTool;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// open_config builtin tool.
|
|
2
|
-
//
|
|
3
|
-
// Lives in the always-on `builtin` module (not the gated `agent` module) so
|
|
4
|
-
// the config UI stays reachable even when modules.agent.enabled === false —
|
|
5
|
-
// otherwise a user who disabled the agent module would lose every way to open
|
|
6
|
-
// the settings UI (the old `bun launch.mjs` slash shell-out is gone).
|
|
7
|
-
//
|
|
8
|
-
// Launches the config UI through the resident MCP server. Because this server
|
|
9
|
-
// is a long-lived background process, its spawn of setup-server
|
|
10
|
-
// (windowsHide:true inside launch-core) creates NO console window — unlike the
|
|
11
|
-
// old `!bun launch.mjs` slash-command shell-out, which flashed a conhost. The
|
|
12
|
-
// launch-core import is lazy so its child_process/http deps stay off the hot
|
|
13
|
-
// builtin path until the tool is actually called.
|
|
14
|
-
|
|
15
|
-
export async function executeOpenConfigTool() {
|
|
16
|
-
const { launchConfigUi, LaunchError } = await import(
|
|
17
|
-
new URL('../../../../../setup/launch-core.mjs', import.meta.url).href
|
|
18
|
-
);
|
|
19
|
-
try {
|
|
20
|
-
const url = await launchConfigUi();
|
|
21
|
-
return `Config UI opened at ${url}`;
|
|
22
|
-
} catch (err) {
|
|
23
|
-
if (err instanceof LaunchError) return `Error: ${err.message.trim()}`;
|
|
24
|
-
throw err;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
import {
|
|
4
|
-
channelNotificationModelContent,
|
|
5
|
-
shouldMirrorChannelNotificationToPending,
|
|
6
|
-
} from './channel-notification-routing.mjs';
|
|
7
|
-
|
|
8
|
-
test('channel schedule notification uses instruction as model content', () => {
|
|
9
|
-
const content = channelNotificationModelContent({
|
|
10
|
-
content: ' ',
|
|
11
|
-
meta: {
|
|
12
|
-
type: 'schedule',
|
|
13
|
-
instruction: 'scheduled prompt body',
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
assert.equal(content, 'scheduled prompt body');
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
test('silent channel notification has no model content', () => {
|
|
20
|
-
const content = channelNotificationModelContent({
|
|
21
|
-
content: 'hidden',
|
|
22
|
-
meta: {
|
|
23
|
-
type: 'schedule',
|
|
24
|
-
silent_to_agent: true,
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
assert.equal(content, '');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('non-schedule notification preserves instruction-first routing', () => {
|
|
31
|
-
const content = channelNotificationModelContent({
|
|
32
|
-
content: 'worker result body',
|
|
33
|
-
meta: {
|
|
34
|
-
type: 'webhook',
|
|
35
|
-
instruction: 'relay instruction',
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
assert.equal(content, 'relay instruction');
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('only schedule channel notifications are mirrored to pending fallback', () => {
|
|
42
|
-
assert.equal(shouldMirrorChannelNotificationToPending({ type: 'schedule' }), true);
|
|
43
|
-
assert.equal(shouldMirrorChannelNotificationToPending({ type: 'webhook' }), false);
|
|
44
|
-
assert.equal(shouldMirrorChannelNotificationToPending({}), false);
|
|
45
|
-
});
|
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import {
|
|
4
|
-
isInternalRuntimeNotificationText,
|
|
5
|
-
isModelVisibleToolCompletionWrapper,
|
|
6
|
-
modelVisibleToolCompletionMessage,
|
|
7
|
-
shouldPersistModelVisibleToolCompletion,
|
|
8
|
-
toolCompletionMeta,
|
|
9
|
-
toolCompletionInstruction,
|
|
10
|
-
} from './tool-execution-contract.mjs';
|
|
11
|
-
import { _isInternalRuntimeNotificationText } from '../agent/orchestrator/session/manager.mjs';
|
|
12
|
-
|
|
13
|
-
const completedBackgroundTask = [
|
|
14
|
-
'background task',
|
|
15
|
-
'task_id: task_agent_abc123',
|
|
16
|
-
'surface: agent',
|
|
17
|
-
'operation: run',
|
|
18
|
-
'status: completed',
|
|
19
|
-
'started: 2026-03-28T00:00:00.000Z',
|
|
20
|
-
'finished: 2026-03-28T00:00:05.000Z',
|
|
21
|
-
'',
|
|
22
|
-
'worker finished successfully',
|
|
23
|
-
].join('\n');
|
|
24
|
-
|
|
25
|
-
const runningBackgroundTask = [
|
|
26
|
-
'background task',
|
|
27
|
-
'task_id: task_agent_abc123',
|
|
28
|
-
'surface: agent',
|
|
29
|
-
'operation: run',
|
|
30
|
-
'status: running',
|
|
31
|
-
'started: 2026-03-28T00:00:00.000Z',
|
|
32
|
-
'notification: completion will be delivered to the owner session; use status/read only for manual recovery.',
|
|
33
|
-
].join('\n');
|
|
34
|
-
|
|
35
|
-
test('terminal background task with body should persist as model-visible wrapper', () => {
|
|
36
|
-
const meta = toolCompletionMeta({
|
|
37
|
-
surface: 'agent',
|
|
38
|
-
id: 'task_agent_abc123',
|
|
39
|
-
status: 'completed',
|
|
40
|
-
context: { callerSessionId: 'sess_owner' },
|
|
41
|
-
});
|
|
42
|
-
assert.equal(shouldPersistModelVisibleToolCompletion(completedBackgroundTask, meta), true);
|
|
43
|
-
const visible = modelVisibleToolCompletionMessage(completedBackgroundTask, meta);
|
|
44
|
-
assert.ok(visible);
|
|
45
|
-
assert.equal(isInternalRuntimeNotificationText(visible), false);
|
|
46
|
-
assert.equal(_isInternalRuntimeNotificationText(visible), false);
|
|
47
|
-
assert.equal(isModelVisibleToolCompletionWrapper(visible), true);
|
|
48
|
-
assert.match(visible, /worker finished successfully/);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('model-visible completion wrapper is not a human transcript item', () => {
|
|
52
|
-
const meta = toolCompletionMeta({
|
|
53
|
-
surface: 'agent',
|
|
54
|
-
id: 'task_agent_abc123',
|
|
55
|
-
status: 'completed',
|
|
56
|
-
instruction: toolCompletionInstruction({
|
|
57
|
-
surface: 'agent',
|
|
58
|
-
id: 'task_agent_abc123',
|
|
59
|
-
status: 'completed',
|
|
60
|
-
}),
|
|
61
|
-
context: { callerSessionId: 'sess_owner' },
|
|
62
|
-
});
|
|
63
|
-
const visible = modelVisibleToolCompletionMessage(completedBackgroundTask, meta);
|
|
64
|
-
assert.ok(visible);
|
|
65
|
-
assert.match(visible, /^The async agent task/);
|
|
66
|
-
assert.match(visible, /\n\nResult:\n/);
|
|
67
|
-
assert.equal(isModelVisibleToolCompletionWrapper(visible), true);
|
|
68
|
-
assert.equal(isModelVisibleToolCompletionWrapper('please fix the leak in engine.mjs'), false);
|
|
69
|
-
assert.equal(isModelVisibleToolCompletionWrapper(completedBackgroundTask), false);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
test('running background task stays hidden from model-visible pending drain', () => {
|
|
73
|
-
const meta = toolCompletionMeta({
|
|
74
|
-
surface: 'agent',
|
|
75
|
-
id: 'task_agent_abc123',
|
|
76
|
-
status: 'running',
|
|
77
|
-
context: { callerSessionId: 'sess_owner' },
|
|
78
|
-
});
|
|
79
|
-
assert.equal(shouldPersistModelVisibleToolCompletion(runningBackgroundTask, meta), false);
|
|
80
|
-
assert.equal(modelVisibleToolCompletionMessage(runningBackgroundTask, meta), '');
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test('terminal background task persists when result body mentions task-notification', () => {
|
|
84
|
-
const taskWithTagInBody = [
|
|
85
|
-
...completedBackgroundTask.split('\n').slice(0, -1),
|
|
86
|
-
'log line: saw <task-notification status="completed"> in worker output',
|
|
87
|
-
].join('\n');
|
|
88
|
-
const meta = toolCompletionMeta({
|
|
89
|
-
surface: 'agent',
|
|
90
|
-
id: 'task_agent_abc123',
|
|
91
|
-
status: 'completed',
|
|
92
|
-
context: { callerSessionId: 'sess_owner' },
|
|
93
|
-
});
|
|
94
|
-
assert.equal(shouldPersistModelVisibleToolCompletion(taskWithTagInBody, meta), true);
|
|
95
|
-
const visible = modelVisibleToolCompletionMessage(taskWithTagInBody, meta);
|
|
96
|
-
assert.ok(visible);
|
|
97
|
-
assert.match(visible, /<task-notification/);
|
|
98
|
-
assert.equal(isInternalRuntimeNotificationText(visible), false);
|
|
99
|
-
assert.equal(_isInternalRuntimeNotificationText(visible), false);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('internal task-notification envelope does not persist', () => {
|
|
103
|
-
const internalEnvelope = [
|
|
104
|
-
'<task-notification>',
|
|
105
|
-
'<status>completed</status>',
|
|
106
|
-
'<summary>Agent completed</summary>',
|
|
107
|
-
'<task-id>task_agent_internal</task-id>',
|
|
108
|
-
'</task-notification>',
|
|
109
|
-
].join('\n');
|
|
110
|
-
const meta = toolCompletionMeta({
|
|
111
|
-
surface: 'agent',
|
|
112
|
-
id: 'task_agent_internal',
|
|
113
|
-
status: 'completed',
|
|
114
|
-
context: { callerSessionId: 'sess_owner' },
|
|
115
|
-
});
|
|
116
|
-
assert.equal(shouldPersistModelVisibleToolCompletion(internalEnvelope, meta), false);
|
|
117
|
-
assert.equal(modelVisibleToolCompletionMessage(internalEnvelope, meta), '');
|
|
118
|
-
assert.equal(isInternalRuntimeNotificationText(internalEnvelope), true);
|
|
119
|
-
assert.equal(_isInternalRuntimeNotificationText(internalEnvelope), true);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
test('raw running background task remains internal for manager pending drain', () => {
|
|
123
|
-
assert.equal(isInternalRuntimeNotificationText(runningBackgroundTask), true);
|
|
124
|
-
assert.equal(_isInternalRuntimeNotificationText(runningBackgroundTask), true);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const bracketedShellCompleted = [
|
|
130
|
-
"[task_id: shell_job_1]",
|
|
131
|
-
"[status: completed]",
|
|
132
|
-
"[exit: 0]",
|
|
133
|
-
"",
|
|
134
|
-
"done output",
|
|
135
|
-
].join("\n");
|
|
136
|
-
|
|
137
|
-
const bracketedShellRunning = [
|
|
138
|
-
"[task_id: shell_job_1]",
|
|
139
|
-
"[status: running]",
|
|
140
|
-
"[command: npm test]",
|
|
141
|
-
].join("\n");
|
|
142
|
-
|
|
143
|
-
test("bracketed shell completed raw envelope is internal", () => {
|
|
144
|
-
assert.equal(isInternalRuntimeNotificationText(bracketedShellCompleted), true);
|
|
145
|
-
assert.equal(_isInternalRuntimeNotificationText(bracketedShellCompleted), true);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("bracketed shell running raw envelope is internal", () => {
|
|
149
|
-
assert.equal(isInternalRuntimeNotificationText(bracketedShellRunning), true);
|
|
150
|
-
assert.equal(_isInternalRuntimeNotificationText(bracketedShellRunning), true);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
test("wrapped shell completion stays model-visible and not internal", () => {
|
|
154
|
-
const meta = toolCompletionMeta({
|
|
155
|
-
surface: "shell",
|
|
156
|
-
id: "shell_job_1",
|
|
157
|
-
status: "completed",
|
|
158
|
-
context: { callerSessionId: "sess_owner" },
|
|
159
|
-
});
|
|
160
|
-
const visible = modelVisibleToolCompletionMessage(bracketedShellCompleted, meta);
|
|
161
|
-
assert.ok(visible);
|
|
162
|
-
assert.match(visible, /done output/);
|
|
163
|
-
assert.equal(isInternalRuntimeNotificationText(visible), false);
|
|
164
|
-
assert.equal(_isInternalRuntimeNotificationText(visible), false);
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
test("model-visible wrapper bounds large completion bodies", () => {
|
|
168
|
-
const hugeBody = "x".repeat(20_000);
|
|
169
|
-
const hugeTask = [
|
|
170
|
-
...completedBackgroundTask.split("\n").slice(0, -1),
|
|
171
|
-
hugeBody,
|
|
172
|
-
].join("\n");
|
|
173
|
-
const meta = toolCompletionMeta({
|
|
174
|
-
surface: "agent",
|
|
175
|
-
id: "task_agent_abc123",
|
|
176
|
-
status: "completed",
|
|
177
|
-
context: { callerSessionId: "sess_owner" },
|
|
178
|
-
});
|
|
179
|
-
const visible = modelVisibleToolCompletionMessage(hugeTask, meta);
|
|
180
|
-
assert.ok(visible);
|
|
181
|
-
assert.match(visible, /\[result truncated for model context\]/);
|
|
182
|
-
assert.ok(visible.length < hugeBody.length);
|
|
183
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import {
|
|
4
|
-
appendAgentProgressKv,
|
|
5
|
-
buildAgentTaskProgressFields,
|
|
6
|
-
resolveSilentForSeconds,
|
|
7
|
-
} from './agent-task-status.mjs';
|
|
8
|
-
|
|
9
|
-
test('waiting for first activity explains silence', () => {
|
|
10
|
-
const now = 1_000_000;
|
|
11
|
-
const fields = buildAgentTaskProgressFields({
|
|
12
|
-
now,
|
|
13
|
-
sessionStatus: 'running',
|
|
14
|
-
runtimeStage: 'requesting',
|
|
15
|
-
snapshot: {
|
|
16
|
-
stage: 'requesting',
|
|
17
|
-
waitingForFirstActivity: true,
|
|
18
|
-
modelRequestStartedAt: now - 12_000,
|
|
19
|
-
askStartedAt: now - 12_000,
|
|
20
|
-
lastProgressAt: now - 12_000,
|
|
21
|
-
},
|
|
22
|
-
policy: { firstResponseMs: 120_000, idleStaleMs: 1_800_000, toolRunningMs: 600_000 },
|
|
23
|
-
taskStatus: 'running',
|
|
24
|
-
});
|
|
25
|
-
assert.equal(fields.last_progress, 'awaiting first model response');
|
|
26
|
-
assert.match(fields.diagnostic, /waiting for first response/);
|
|
27
|
-
assert.match(fields.watchdog, /first=120s/);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test('streaming without recent deltas is called out', () => {
|
|
31
|
-
const now = 2_000_000;
|
|
32
|
-
const fields = buildAgentTaskProgressFields({
|
|
33
|
-
now,
|
|
34
|
-
sessionStatus: 'running',
|
|
35
|
-
runtimeStage: 'streaming',
|
|
36
|
-
snapshot: {
|
|
37
|
-
stage: 'streaming',
|
|
38
|
-
waitingForFirstActivity: false,
|
|
39
|
-
lastStreamDeltaAt: now - 23_000,
|
|
40
|
-
lastProgressAt: now - 23_000,
|
|
41
|
-
},
|
|
42
|
-
taskStatus: 'running',
|
|
43
|
-
});
|
|
44
|
-
assert.match(fields.last_progress, /no stream delta for 23s/);
|
|
45
|
-
assert.match(fields.diagnostic, /no visible output yet \(23s\)/);
|
|
46
|
-
assert.equal(fields.silent_for, 23);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test('queued follow-ups surface on idle worker', () => {
|
|
50
|
-
const fields = buildAgentTaskProgressFields({
|
|
51
|
-
sessionStatus: 'idle',
|
|
52
|
-
runtimeStage: 'streaming',
|
|
53
|
-
queuedFollowups: 2,
|
|
54
|
-
taskStatus: 'running',
|
|
55
|
-
});
|
|
56
|
-
assert.equal(fields.queued_followups, 2);
|
|
57
|
-
assert.match(fields.diagnostic, /2 follow-ups queued/);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test('resolveSilentForSeconds uses latest progress signal', () => {
|
|
61
|
-
const now = 10_000;
|
|
62
|
-
const silent = resolveSilentForSeconds(now, { lastProgressAt: now - 5_000 }, { lastStreamDeltaAt: now - 9_000 });
|
|
63
|
-
assert.equal(silent, 5);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test('appendAgentProgressKv keeps base line first', () => {
|
|
67
|
-
const line = appendAgentProgressKv('- job1 spawn running', {
|
|
68
|
-
worker_stage: 'streaming',
|
|
69
|
-
silent_for: 4,
|
|
70
|
-
diagnostic: 'streaming',
|
|
71
|
-
});
|
|
72
|
-
assert.match(line, /^- job1 spawn running /);
|
|
73
|
-
assert.match(line, /stage=streaming/);
|
|
74
|
-
assert.match(line, /hint=streaming/);
|
|
75
|
-
});
|
|
76
|
-
|