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
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* settings-picker.mjs — the SETTINGS picker cluster.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from App.jsx behavior-preservingly as a dependency-injection
|
|
5
|
+
* factory. The function body is the original App logic verbatim, with closure
|
|
6
|
+
* identifiers threaded through the factory argument. openSettingsPicker
|
|
7
|
+
* self-references (for light refresh) via the local const; all other openers it
|
|
8
|
+
* routes to are threaded as lazy getter wrappers so they resolve the live
|
|
9
|
+
* binding at call time.
|
|
10
|
+
*/
|
|
11
|
+
import { outputStyleNotice } from './route-pickers.mjs';
|
|
12
|
+
|
|
13
|
+
export function createSettingsPicker({
|
|
14
|
+
store,
|
|
15
|
+
state,
|
|
16
|
+
setPicker,
|
|
17
|
+
setProviderPrompt,
|
|
18
|
+
setChannelPrompt,
|
|
19
|
+
setHookPrompt,
|
|
20
|
+
setSettingsPrompt,
|
|
21
|
+
settingsHeavyCacheRef,
|
|
22
|
+
formatDuration,
|
|
23
|
+
displayModelName,
|
|
24
|
+
routeModelLabel,
|
|
25
|
+
workflowDisplayName,
|
|
26
|
+
workflowSwitchNotice,
|
|
27
|
+
themeNotice,
|
|
28
|
+
openModelPicker,
|
|
29
|
+
openSearchPicker,
|
|
30
|
+
openAgentsPicker,
|
|
31
|
+
openWorkflowPicker,
|
|
32
|
+
openOutputStylePicker,
|
|
33
|
+
openBridgePicker,
|
|
34
|
+
openToolsPicker,
|
|
35
|
+
openProviderSetupPicker,
|
|
36
|
+
openThemePicker,
|
|
37
|
+
openAutoClearPicker,
|
|
38
|
+
openProfilePicker,
|
|
39
|
+
openMemoryCorePicker,
|
|
40
|
+
openMcpPicker,
|
|
41
|
+
openPluginsPicker,
|
|
42
|
+
openHooksPicker,
|
|
43
|
+
openSkillsPicker,
|
|
44
|
+
openUpdatePicker,
|
|
45
|
+
openChannelSettingTypePicker,
|
|
46
|
+
}) {
|
|
47
|
+
const openSettingsPicker = (opts = {}) => {
|
|
48
|
+
const light = opts.light === true;
|
|
49
|
+
const overrides = opts.overrides || null;
|
|
50
|
+
const heavyCache = light ? settingsHeavyCacheRef.current : null;
|
|
51
|
+
const autoClear = store.getAutoClear?.() || {};
|
|
52
|
+
const compaction = store.getCompactionSettings?.() || {};
|
|
53
|
+
const memory = store.getMemorySettings?.() || { enabled: true };
|
|
54
|
+
const channels = store.getChannelSettings?.({ includeStatus: false }) || { enabled: true };
|
|
55
|
+
const outputStyle = store.getOutputStyle?.() || store.listOutputStyles?.() || {};
|
|
56
|
+
const workflow = state.workflow || {};
|
|
57
|
+
const mcp = heavyCache ? heavyCache.mcp : (store.mcpStatus?.() || { connectedCount: 0, configuredCount: 0, failedCount: 0 });
|
|
58
|
+
const hooks = heavyCache ? heavyCache.hooks : (store.hooksStatus?.() || { ruleCount: 0 });
|
|
59
|
+
const plugins = heavyCache ? heavyCache.plugins : (store.pluginsStatus?.() || { count: 0 });
|
|
60
|
+
const skills = heavyCache ? heavyCache.skills : (store.skillsStatus?.() || { count: 0 });
|
|
61
|
+
const channelWorker = store.getChannelWorkerStatus?.();
|
|
62
|
+
let channelBackend = 'discord';
|
|
63
|
+
if (heavyCache) {
|
|
64
|
+
channelBackend = heavyCache.channelBackend || 'discord';
|
|
65
|
+
} else {
|
|
66
|
+
try {
|
|
67
|
+
channelBackend = store.getChannelSetup?.()?.backend || 'discord';
|
|
68
|
+
} catch {
|
|
69
|
+
channelBackend = 'discord';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (overrides && Object.prototype.hasOwnProperty.call(overrides, 'channelBackend')) {
|
|
73
|
+
channelBackend = overrides.channelBackend;
|
|
74
|
+
}
|
|
75
|
+
// Refresh the cache every build (light or full) so the next light
|
|
76
|
+
// refresh reuses whatever was most recently known, and so an
|
|
77
|
+
// optimistic override (e.g. channel backend cycle) sticks without
|
|
78
|
+
// re-running the heavy getter it came from.
|
|
79
|
+
settingsHeavyCacheRef.current = { mcp, hooks, plugins, skills, channelBackend };
|
|
80
|
+
const channelBackendLabel = channelBackend === 'telegram' ? 'Telegram' : 'Discord';
|
|
81
|
+
const remoteEnabled = store.isRemoteEnabled?.() === true;
|
|
82
|
+
const remoteRuntimeDescription = channelWorker?.running
|
|
83
|
+
? `runtime running · pid ${channelWorker.pid}`
|
|
84
|
+
: 'runtime stopped';
|
|
85
|
+
const compactType = compaction.compactType || compaction.type || 'semantic';
|
|
86
|
+
const compactTypeLabel = compactType === 'recall-fasttrack' ? 'Fast-track' : 'Default';
|
|
87
|
+
const outputStyleLabel = outputStyle?.current?.label || outputStyle?.current?.id || outputStyle?.configured || 'Default';
|
|
88
|
+
const workflowLabel = workflowDisplayName(workflow);
|
|
89
|
+
const boolLabel = (enabled) => enabled ? 'On' : 'Off';
|
|
90
|
+
const compactTypeDescription = compactType === 'recall-fasttrack'
|
|
91
|
+
? (memory.enabled === false
|
|
92
|
+
? 'Injects raw transcript lines (Recap off: no LLM chunking).'
|
|
93
|
+
: 'Uses Memory recall to rebuild context faster on large histories.')
|
|
94
|
+
: 'Uses semantic summarization for predictable context compaction.';
|
|
95
|
+
const applyAutoClear = (patch = {}) => {
|
|
96
|
+
try {
|
|
97
|
+
const next = store.setAutoClear?.(patch);
|
|
98
|
+
if (!next) store.pushNotice('autoclear unavailable', 'warn');
|
|
99
|
+
else store.pushNotice(next.enabled ? `Auto-clear on · idle ${formatDuration(next.idleMs)}` : 'Auto-clear off', 'info');
|
|
100
|
+
} catch (e) {
|
|
101
|
+
store.pushNotice(`autoclear failed: ${e?.message || e}`, 'error');
|
|
102
|
+
}
|
|
103
|
+
openSettingsPicker({ light: true });
|
|
104
|
+
};
|
|
105
|
+
// On/Off toggle only — idle-window override lives in the Advanced picker
|
|
106
|
+
// (openAutoClearPicker), opened via Enter on this row.
|
|
107
|
+
const autoClearEnabled = autoClear.enabled !== false;
|
|
108
|
+
const toggleAutoClear = () => applyAutoClear({ enabled: !autoClearEnabled });
|
|
109
|
+
const applyCompaction = (patch = {}) => {
|
|
110
|
+
void Promise.resolve(store.setCompactionSettings?.(patch))
|
|
111
|
+
.then((next) => {
|
|
112
|
+
if (!next) {
|
|
113
|
+
store.pushNotice('compaction setting is busy', 'warn');
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
store.pushNotice(`Compaction ${next.auto !== false ? 'auto on' : 'auto off'} · ${next.compactType === 'recall-fasttrack' ? 'Fast-track' : 'Default'}`, 'info');
|
|
117
|
+
})
|
|
118
|
+
.catch((e) => store.pushNotice(`compaction failed: ${e?.message || e}`, 'error'))
|
|
119
|
+
.finally(() => openSettingsPicker({ light: true }));
|
|
120
|
+
};
|
|
121
|
+
const applyMemory = (enabled) => {
|
|
122
|
+
void Promise.resolve(store.setMemoryEnabled?.(enabled))
|
|
123
|
+
.then((next) => {
|
|
124
|
+
if (!next) {
|
|
125
|
+
store.pushNotice('recap setting is busy', 'warn');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
store.pushNotice(`Recap ${next.enabled ? 'on' : 'off'}`, 'info');
|
|
129
|
+
})
|
|
130
|
+
.catch((e) => store.pushNotice(`recap setting failed: ${e?.message || e}`, 'error'))
|
|
131
|
+
.finally(() => openSettingsPicker({ light: true }));
|
|
132
|
+
};
|
|
133
|
+
const applyChannels = (enabled) => {
|
|
134
|
+
void Promise.resolve(store.setChannelsEnabled?.(enabled))
|
|
135
|
+
.then((next) => {
|
|
136
|
+
if (!next) {
|
|
137
|
+
store.pushNotice('channel setting is busy', 'warn');
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
store.pushNotice(`Channels ${next.enabled ? 'on' : 'off'}`, 'info');
|
|
141
|
+
})
|
|
142
|
+
.catch((e) => store.pushNotice(`channel setting failed: ${e?.message || e}`, 'error'))
|
|
143
|
+
.finally(() => openSettingsPicker({ light: true }));
|
|
144
|
+
};
|
|
145
|
+
const cycleOutputStyle = (direction = 1) => {
|
|
146
|
+
let status = null;
|
|
147
|
+
try { status = store.listOutputStyles?.() || null; } catch (e) {
|
|
148
|
+
store.pushNotice(`could not list output styles: ${e?.message || e}`, 'error');
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const styles = Array.isArray(status?.styles) ? status.styles : [];
|
|
152
|
+
if (!styles.length) {
|
|
153
|
+
store.pushNotice('no output styles available', 'warn');
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const currentId = status?.current?.id || 'default';
|
|
157
|
+
const currentIndex = Math.max(0, styles.findIndex((style) => style.id === currentId));
|
|
158
|
+
const next = styles[(currentIndex + direction + styles.length) % styles.length];
|
|
159
|
+
void store.setOutputStyle?.(next.id)
|
|
160
|
+
.then((result) => {
|
|
161
|
+
if (!result) {
|
|
162
|
+
store.pushNotice('Output style switch is already running.', 'warn');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
store.pushNotice(outputStyleNotice(result), 'info');
|
|
166
|
+
})
|
|
167
|
+
.catch((e) => store.pushNotice(`Couldn’t switch output style: ${e?.message || e}`, 'error'))
|
|
168
|
+
.finally(() => openSettingsPicker({ light: true }));
|
|
169
|
+
};
|
|
170
|
+
const cycleWorkflow = (direction = 1) => {
|
|
171
|
+
let workflows = [];
|
|
172
|
+
try { workflows = store.listWorkflows?.() || []; } catch (e) {
|
|
173
|
+
store.pushNotice(`could not list workflows: ${e?.message || e}`, 'error');
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!workflows.length) {
|
|
177
|
+
store.pushNotice('no workflows available', 'warn');
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const activeIndex = workflows.findIndex((item) => item.active);
|
|
181
|
+
const currentIndex = activeIndex >= 0 ? activeIndex : Math.max(0, workflows.findIndex((item) => item.id === workflow.id));
|
|
182
|
+
const next = workflows[(currentIndex + direction + workflows.length) % workflows.length];
|
|
183
|
+
void store.setWorkflow?.(next.id)
|
|
184
|
+
.then((result) => {
|
|
185
|
+
if (!result) {
|
|
186
|
+
store.pushNotice('Workflow switch is already running.', 'warn');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
store.pushNotice(workflowSwitchNotice(result), 'info');
|
|
190
|
+
})
|
|
191
|
+
.catch((e) => store.pushNotice(`Couldn’t switch workflow: ${e?.message || e}`, 'error'))
|
|
192
|
+
.finally(() => openSettingsPicker({ light: true }));
|
|
193
|
+
};
|
|
194
|
+
const cycleTheme = (direction = 1) => {
|
|
195
|
+
let themes = [];
|
|
196
|
+
try { themes = store.listThemes?.() || []; } catch (e) {
|
|
197
|
+
store.pushNotice(`could not list themes: ${e?.message || e}`, 'error');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (!themes.length) {
|
|
201
|
+
store.pushNotice('no themes available', 'warn');
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const currentId = store.getTheme?.() || themes.find((t) => t.current)?.id || themes[0]?.id;
|
|
205
|
+
const currentIndex = Math.max(0, themes.findIndex((t) => t.id === currentId));
|
|
206
|
+
const next = themes[(currentIndex + direction + themes.length) % themes.length];
|
|
207
|
+
try {
|
|
208
|
+
const applied = store.setTheme?.(next.id, { persist: true });
|
|
209
|
+
store.pushNotice(themeNotice(applied || next), 'info');
|
|
210
|
+
} catch (e) {
|
|
211
|
+
store.pushNotice(`Couldn’t set theme: ${e?.message || e}`, 'error');
|
|
212
|
+
}
|
|
213
|
+
openSettingsPicker({ light: true });
|
|
214
|
+
};
|
|
215
|
+
const applyRemoteRuntime = () => {
|
|
216
|
+
const enabled = store.toggleRemote?.() === true;
|
|
217
|
+
store.pushNotice(enabled ? 'Remote mode ON' : 'Remote mode OFF', 'info');
|
|
218
|
+
openSettingsPicker({ light: true });
|
|
219
|
+
};
|
|
220
|
+
const cycleChannelBackend = (direction = 1) => {
|
|
221
|
+
const backends = ['discord', 'telegram'];
|
|
222
|
+
const currentIndex = Math.max(0, backends.indexOf(channelBackend));
|
|
223
|
+
const chosen = backends[(currentIndex + direction + backends.length) % backends.length];
|
|
224
|
+
if (chosen === channelBackend) {
|
|
225
|
+
openSettingsPicker({ light: true, overrides: { channelBackend } });
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
try {
|
|
229
|
+
store.setBackend(chosen);
|
|
230
|
+
const label = chosen === 'telegram' ? 'Telegram' : 'Discord';
|
|
231
|
+
const restartHint = (store.isRemoteEnabled?.() === true || channelWorker?.running)
|
|
232
|
+
? `Channel set to ${label}. Restart remote to apply.`
|
|
233
|
+
: `Channel set to ${label}.`;
|
|
234
|
+
store.pushNotice(restartHint, 'info');
|
|
235
|
+
} catch (e) {
|
|
236
|
+
store.pushNotice(`channel backend failed: ${e?.message || e}`, 'error');
|
|
237
|
+
}
|
|
238
|
+
openSettingsPicker({ light: true, overrides: { channelBackend: chosen } });
|
|
239
|
+
};
|
|
240
|
+
const items = [
|
|
241
|
+
{
|
|
242
|
+
value: 'profile',
|
|
243
|
+
label: 'Profile',
|
|
244
|
+
meta: (() => {
|
|
245
|
+
try {
|
|
246
|
+
const p = store.getProfile?.();
|
|
247
|
+
const lang = p?.languageEntry?.label || 'System';
|
|
248
|
+
return p?.title ? `${p.title} · ${lang}` : lang;
|
|
249
|
+
} catch { return 'System'; }
|
|
250
|
+
})(),
|
|
251
|
+
description: 'Your title and response language.',
|
|
252
|
+
_action: 'profile',
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
value: 'autoclear',
|
|
256
|
+
label: 'Auto-clear',
|
|
257
|
+
meta: autoClearEnabled ? `On (${formatDuration(autoClear.idleMs)})` : 'Off',
|
|
258
|
+
description: autoClearEnabled
|
|
259
|
+
? `Clear idle sessions after ${formatDuration(autoClear.idleMs)}${autoClear.custom ? '' : ` (${autoClear.provider || 'default'} default)`}. Enter for options.`
|
|
260
|
+
: 'Idle auto-clear disabled. Enter for options.',
|
|
261
|
+
_action: 'autoclear',
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
value: 'autocompact',
|
|
265
|
+
label: 'Auto-compact',
|
|
266
|
+
meta: boolLabel(compaction.auto !== false),
|
|
267
|
+
description: 'Compact when context is high.',
|
|
268
|
+
_action: 'autocompact',
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
value: 'compact-type',
|
|
272
|
+
label: 'Compact type',
|
|
273
|
+
meta: compactTypeLabel,
|
|
274
|
+
description: compactTypeDescription,
|
|
275
|
+
_action: 'compact-type',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
value: 'core-memory',
|
|
279
|
+
label: 'Recap',
|
|
280
|
+
meta: boolLabel(memory.enabled !== false),
|
|
281
|
+
description: 'Recap on/off, list and edit memories.',
|
|
282
|
+
_action: 'core-memory',
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
value: 'channels',
|
|
286
|
+
label: 'Channels enabled',
|
|
287
|
+
meta: boolLabel(channels.enabled !== false),
|
|
288
|
+
description: channels.enabled === false
|
|
289
|
+
? 'Channel tools disabled.'
|
|
290
|
+
: 'Discord, schedules, and webhooks.',
|
|
291
|
+
_action: 'channels',
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
value: 'remote-runtime',
|
|
295
|
+
label: 'Remote Runtime',
|
|
296
|
+
meta: boolLabel(remoteEnabled),
|
|
297
|
+
description: remoteRuntimeDescription,
|
|
298
|
+
_action: 'remote-runtime',
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
value: 'channel-backend',
|
|
302
|
+
label: 'Channel',
|
|
303
|
+
meta: channelBackendLabel,
|
|
304
|
+
description: 'Left/Right or Enter changes channel type (Discord or Telegram).',
|
|
305
|
+
_action: 'channel-backend',
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
value: 'channel-setting',
|
|
309
|
+
label: 'Setting',
|
|
310
|
+
description: 'Configure credentials and main channel/chat for the active type.',
|
|
311
|
+
_action: 'channel-setting',
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
value: 'output-style',
|
|
315
|
+
label: 'Output style',
|
|
316
|
+
meta: outputStyleLabel,
|
|
317
|
+
description: 'Response tone and format.',
|
|
318
|
+
_action: 'output-style',
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
value: 'theme',
|
|
322
|
+
label: 'Theme',
|
|
323
|
+
meta: (() => {
|
|
324
|
+
try {
|
|
325
|
+
const id = store.getTheme?.();
|
|
326
|
+
const entry = (store.listThemes?.() || []).find((t) => t.id === id);
|
|
327
|
+
return entry?.label || id || 'Default';
|
|
328
|
+
} catch { return 'Default'; }
|
|
329
|
+
})(),
|
|
330
|
+
description: 'TUI color theme.',
|
|
331
|
+
_action: 'theme',
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
value: 'workflow',
|
|
335
|
+
label: 'Workflow',
|
|
336
|
+
meta: workflowLabel,
|
|
337
|
+
description: 'Active agent routing profile.',
|
|
338
|
+
_action: 'workflow',
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
value: 'model',
|
|
342
|
+
label: 'Model',
|
|
343
|
+
meta: displayModelName(state.model, state.provider),
|
|
344
|
+
description: 'Main chat model.',
|
|
345
|
+
_action: 'model',
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
value: 'search',
|
|
349
|
+
label: 'Search model',
|
|
350
|
+
meta: routeModelLabel(store.getSearchRoute?.()),
|
|
351
|
+
description: 'Native search model.',
|
|
352
|
+
_action: 'search',
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
value: 'providers',
|
|
356
|
+
label: 'Providers',
|
|
357
|
+
description: 'Auth, API keys, OAuth, local.',
|
|
358
|
+
_action: 'providers',
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
value: 'mcp',
|
|
362
|
+
label: 'MCP servers',
|
|
363
|
+
description: `${mcp.connectedCount || 0}/${mcp.configuredCount || 0} connected${mcp.failedCount ? ` · ${mcp.failedCount} failed` : ''}`,
|
|
364
|
+
_action: 'mcp',
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
value: 'plugins',
|
|
368
|
+
label: 'Plugins',
|
|
369
|
+
description: `${plugins.count || 0} detected`,
|
|
370
|
+
_action: 'plugins',
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
value: 'hooks',
|
|
374
|
+
label: 'Hooks',
|
|
375
|
+
description: `${hooks.ruleCount || 0} before-tool rules`,
|
|
376
|
+
_action: 'hooks',
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
value: 'skills',
|
|
380
|
+
label: 'Skills',
|
|
381
|
+
description: `${skills.count || 0} available`,
|
|
382
|
+
_action: 'skills',
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
value: 'update',
|
|
386
|
+
label: 'Update',
|
|
387
|
+
meta: (() => {
|
|
388
|
+
try {
|
|
389
|
+
const upd = store.getUpdateSettings?.() || {};
|
|
390
|
+
const current = upd.currentVersion || 'unknown';
|
|
391
|
+
if (upd.updateAvailable && upd.latestVersion) return `${current} → ${upd.latestVersion}`;
|
|
392
|
+
if (!upd.currentVersion) return 'unknown';
|
|
393
|
+
return `${current} (latest)`;
|
|
394
|
+
} catch { return 'unknown'; }
|
|
395
|
+
})(),
|
|
396
|
+
description: 'Check version and update mixdog.',
|
|
397
|
+
_action: 'update',
|
|
398
|
+
},
|
|
399
|
+
];
|
|
400
|
+
setProviderPrompt(null);
|
|
401
|
+
setChannelPrompt(null);
|
|
402
|
+
setHookPrompt(null);
|
|
403
|
+
setSettingsPrompt(null);
|
|
404
|
+
setPicker({
|
|
405
|
+
title: 'Settings',
|
|
406
|
+
description: 'Runtime, model, tools, and integrations.',
|
|
407
|
+
help: '↑/↓ Select · ←/→ Change · Enter Open/Toggle · Esc Close',
|
|
408
|
+
indexMode: 'always',
|
|
409
|
+
labelWidth: 18,
|
|
410
|
+
metaWidth: 18,
|
|
411
|
+
items,
|
|
412
|
+
initialIndex: opts.focus ? Math.max(0, items.findIndex((item) => item.value === opts.focus)) : undefined,
|
|
413
|
+
onLeft: (item) => {
|
|
414
|
+
if (item?._action === 'autoclear') toggleAutoClear();
|
|
415
|
+
else if (item?._action === 'autocompact') applyCompaction({ auto: !(compaction.auto !== false) });
|
|
416
|
+
else if (item?._action === 'compact-type') {
|
|
417
|
+
const nextType = compactType === 'recall-fasttrack' ? 'semantic' : 'recall-fasttrack';
|
|
418
|
+
applyCompaction({ compactType: nextType });
|
|
419
|
+
}
|
|
420
|
+
else if (item?._action === 'core-memory') applyMemory(!(memory.enabled !== false));
|
|
421
|
+
else if (item?._action === 'channels') applyChannels(!(channels.enabled !== false));
|
|
422
|
+
else if (item?._action === 'remote-runtime') applyRemoteRuntime();
|
|
423
|
+
else if (item?._action === 'channel-backend') cycleChannelBackend(-1);
|
|
424
|
+
else if (item?._action === 'output-style') cycleOutputStyle(-1);
|
|
425
|
+
else if (item?._action === 'theme') cycleTheme(-1);
|
|
426
|
+
else if (item?._action === 'workflow') cycleWorkflow(-1);
|
|
427
|
+
},
|
|
428
|
+
onRight: (item) => {
|
|
429
|
+
if (item?._action === 'autoclear') toggleAutoClear();
|
|
430
|
+
else if (item?._action === 'autocompact') applyCompaction({ auto: !(compaction.auto !== false) });
|
|
431
|
+
else if (item?._action === 'compact-type') {
|
|
432
|
+
const nextType = compactType === 'recall-fasttrack' ? 'semantic' : 'recall-fasttrack';
|
|
433
|
+
applyCompaction({ compactType: nextType });
|
|
434
|
+
}
|
|
435
|
+
else if (item?._action === 'core-memory') applyMemory(!(memory.enabled !== false));
|
|
436
|
+
else if (item?._action === 'channels') applyChannels(!(channels.enabled !== false));
|
|
437
|
+
else if (item?._action === 'remote-runtime') applyRemoteRuntime();
|
|
438
|
+
else if (item?._action === 'channel-backend') cycleChannelBackend(1);
|
|
439
|
+
else if (item?._action === 'output-style') cycleOutputStyle(1);
|
|
440
|
+
else if (item?._action === 'theme') cycleTheme(1);
|
|
441
|
+
else if (item?._action === 'workflow') cycleWorkflow(1);
|
|
442
|
+
},
|
|
443
|
+
onSelect: (_value, item) => {
|
|
444
|
+
setPicker(null);
|
|
445
|
+
if (item._action === 'autoclear') openAutoClearPicker({ returnTo: openSettingsPicker });
|
|
446
|
+
else if (item._action === 'profile') openProfilePicker({ returnTo: openSettingsPicker });
|
|
447
|
+
else if (item._action === 'autocompact') applyCompaction({ auto: !(compaction.auto !== false) });
|
|
448
|
+
else if (item._action === 'compact-type') {
|
|
449
|
+
const nextType = compactType === 'recall-fasttrack' ? 'semantic' : 'recall-fasttrack';
|
|
450
|
+
applyCompaction({ compactType: nextType });
|
|
451
|
+
}
|
|
452
|
+
else if (item._action === 'core-memory') openMemoryCorePicker({ returnTo: () => openSettingsPicker() });
|
|
453
|
+
else if (item._action === 'channels') applyChannels(!(channels.enabled !== false));
|
|
454
|
+
else if (item._action === 'remote-runtime') applyRemoteRuntime();
|
|
455
|
+
else if (item._action === 'channel-backend') cycleChannelBackend(1);
|
|
456
|
+
else if (item._action === 'channel-setting') openChannelSettingTypePicker({ returnTo: openSettingsPicker });
|
|
457
|
+
else if (item._action === 'output-style') openOutputStylePicker({ returnTo: openSettingsPicker });
|
|
458
|
+
else if (item._action === 'theme') openThemePicker({ returnTo: openSettingsPicker });
|
|
459
|
+
else if (item._action === 'workflow') openWorkflowPicker({ returnTo: openSettingsPicker });
|
|
460
|
+
else if (item._action === 'model') openModelPicker({
|
|
461
|
+
returnTo: openSettingsPicker,
|
|
462
|
+
returnLabel: 'Settings',
|
|
463
|
+
returnOnNestedCancel: true,
|
|
464
|
+
onAfterSelect: openSettingsPicker,
|
|
465
|
+
});
|
|
466
|
+
else if (item._action === 'search') openSearchPicker({
|
|
467
|
+
returnTo: openSettingsPicker,
|
|
468
|
+
returnLabel: 'Settings',
|
|
469
|
+
returnOnNestedCancel: true,
|
|
470
|
+
});
|
|
471
|
+
else if (item._action === 'providers') void openProviderSetupPicker({
|
|
472
|
+
returnTo: openSettingsPicker,
|
|
473
|
+
onCancel: openSettingsPicker,
|
|
474
|
+
continueLabel: 'Back to settings',
|
|
475
|
+
continueDescription: 'return to settings',
|
|
476
|
+
});
|
|
477
|
+
else if (item._action === 'mcp') openMcpPicker();
|
|
478
|
+
else if (item._action === 'plugins') openPluginsPicker();
|
|
479
|
+
else if (item._action === 'hooks') openHooksPicker();
|
|
480
|
+
else if (item._action === 'skills') openSkillsPicker();
|
|
481
|
+
else if (item._action === 'update') openUpdatePicker({ returnTo: openSettingsPicker });
|
|
482
|
+
},
|
|
483
|
+
onCancel: () => {
|
|
484
|
+
setPicker(null);
|
|
485
|
+
},
|
|
486
|
+
});
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
return { openSettingsPicker };
|
|
490
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* slash-commands.mjs — the /command registry plus the pure string/matching
|
|
3
|
+
* helpers that operate on it. Extracted verbatim from App.jsx (behavior-
|
|
4
|
+
* preserving): no hooks, no App state, no closures — plain data + pure fns.
|
|
5
|
+
*/
|
|
6
|
+
export const SLASH_COMMANDS = [
|
|
7
|
+
{ name: 'clear', usage: '/clear', aliases: ['new'], aliasUsage: ['new'], description: 'Start a fresh chat' },
|
|
8
|
+
{ name: 'project', usage: '/project', aliases: ['projects'], aliasUsage: ['projects'], showAliasUsage: false, description: 'Switch working directory (project)' },
|
|
9
|
+
{ name: 'compact', usage: '/compact', description: 'Compact older conversation context' },
|
|
10
|
+
{ name: 'autoclear', usage: '/autoclear', description: 'Reduce cache-miss cost after long idle gaps' },
|
|
11
|
+
{ name: 'resume', usage: '/resume', description: 'Resume a saved chat' },
|
|
12
|
+
{ name: 'context', usage: '/context', description: 'Show current context surface' },
|
|
13
|
+
{ name: 'usage', usage: '/usage', params: '[refresh]', description: 'Show total provider quota / balance' },
|
|
14
|
+
{ name: 'model', usage: '/model', description: 'Switch model for subsequent turns' },
|
|
15
|
+
{ name: 'search', usage: '/search', description: 'Set the web search provider/model' },
|
|
16
|
+
{ name: 'workflow', usage: '/workflow', description: 'Switch the active workflow' },
|
|
17
|
+
{ name: 'outputstyle', usage: '/OutputStyle', aliases: ['output-style', 'style'], aliasUsage: ['style'], showAliasUsage: false, params: '[name]', description: 'Switch Lead output style' },
|
|
18
|
+
{ name: 'theme', usage: '/theme', params: '[id]', description: 'Change the TUI color theme' },
|
|
19
|
+
{ name: 'agents', usage: '/agents', description: 'Show available workflow agents' },
|
|
20
|
+
{ name: 'effort', usage: '/effort', params: '[level]', description: 'Set reasoning effort for the current model' },
|
|
21
|
+
{ name: 'fast', usage: '/fast', params: '[on|off]', description: 'Toggle Fast mode for the current model' },
|
|
22
|
+
{ name: 'mcp', usage: '/mcp', description: 'Manage MCP servers and tools' },
|
|
23
|
+
{ name: 'skills', usage: '/skills', description: 'Choose a skill for the next request' },
|
|
24
|
+
{ name: 'memory', usage: '/memory', description: 'List and edit core memories' },
|
|
25
|
+
{ name: 'recap', usage: '/recap', params: '[on|off]', description: 'Toggle background memory recap cycles' },
|
|
26
|
+
{ name: 'plugins', usage: '/plugins', description: 'Manage local plugin integrations' },
|
|
27
|
+
{ name: 'hooks', usage: '/hooks', description: 'Manage before-tool hook rules and events' },
|
|
28
|
+
{ name: 'providers', usage: '/providers', description: 'Manage auth, API keys, OAuth, and local endpoints' },
|
|
29
|
+
{ name: 'channels', usage: '/channels', description: 'Manage Discord, channels, schedules, webhooks' },
|
|
30
|
+
{ name: 'remote', usage: '/remote', description: 'Claim remote for this session (takes over from any other session)' },
|
|
31
|
+
{ name: 'schedules', usage: '/schedules', description: 'Manage schedules' },
|
|
32
|
+
{ name: 'webhooks', usage: '/webhooks', description: 'Manage inbound webhooks' },
|
|
33
|
+
{ name: 'settings', usage: '/setting', aliases: ['setting', 'config'], aliasUsage: ['settings', 'config'], showAliasUsage: false, description: 'Open runtime settings' },
|
|
34
|
+
{ name: 'profile', usage: '/profile', description: 'Set your title and response language' },
|
|
35
|
+
{ name: 'update', usage: '/update', description: 'Check version and update mixdog' },
|
|
36
|
+
{ name: 'voice', usage: '/voice', description: 'Toggle voice input (Ctrl+Space to record)' },
|
|
37
|
+
{ name: 'quit', usage: '/quit', aliases: ['exit', 'q'], aliasUsage: ['exit', 'q'], description: 'Quit the TUI' },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
export function slashQuery(value) {
|
|
41
|
+
const text = String(value ?? '');
|
|
42
|
+
if (!/^\/[^\s]*$/.test(text)) return null;
|
|
43
|
+
return text.slice(1).toLowerCase();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function slashCommandMatches(command, query) {
|
|
47
|
+
const needle = String(query || '').toLowerCase();
|
|
48
|
+
if (!needle) return true;
|
|
49
|
+
if (String(command?.name || '').toLowerCase().startsWith(needle)) return true;
|
|
50
|
+
return (command?.aliases || []).some((alias) => String(alias || '').toLowerCase().startsWith(needle));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function compareSlashCommands(a, b) {
|
|
54
|
+
return String(a?.name || '').localeCompare(String(b?.name || ''), 'en', { sensitivity: 'base' });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Prompt-owned overlays absorb PageUp/PageDown and wheel scroll instead of the transcript. */
|
|
58
|
+
export function overlayBlocksGlobalTranscriptScroll(owner = {}) {
|
|
59
|
+
return !!(
|
|
60
|
+
owner.slashPaletteOpen ||
|
|
61
|
+
owner.picker ||
|
|
62
|
+
owner.toolApproval ||
|
|
63
|
+
owner.contextPanel ||
|
|
64
|
+
owner.usagePanel ||
|
|
65
|
+
owner.providerPrompt ||
|
|
66
|
+
owner.channelPrompt ||
|
|
67
|
+
owner.hookPrompt ||
|
|
68
|
+
owner.settingsPrompt
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function normalizeSlashCommandName(cmd) {
|
|
73
|
+
const name = String(cmd || '').toLowerCase();
|
|
74
|
+
const command = SLASH_COMMANDS.find((item) => item.name === name || (item.aliases || []).includes(name));
|
|
75
|
+
return command?.name || name;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function slashCommandTokenForPaletteAccept(command, draftValue = '') {
|
|
79
|
+
if (!command) return '';
|
|
80
|
+
const text = String(draftValue ?? '').trim();
|
|
81
|
+
const typedToken = text.startsWith('/') ? text.slice(1).split(/\s+/)[0]?.toLowerCase() : '';
|
|
82
|
+
const canonical = String(command.name || '').toLowerCase();
|
|
83
|
+
const aliases = (command.aliases || []).map((alias) => String(alias || '').toLowerCase());
|
|
84
|
+
if (typedToken && (typedToken === canonical || aliases.includes(typedToken))) {
|
|
85
|
+
return typedToken;
|
|
86
|
+
}
|
|
87
|
+
return command.name;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function slashCommandForName(cmd) {
|
|
91
|
+
const name = normalizeSlashCommandName(cmd);
|
|
92
|
+
return SLASH_COMMANDS.find((item) => item.name === name) || null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function slashArgumentHint(value) {
|
|
96
|
+
const text = String(value ?? '');
|
|
97
|
+
const match = text.match(/^\/([^\s]+)\s+$/);
|
|
98
|
+
if (!match) return '';
|
|
99
|
+
const command = slashCommandForName(match[1]);
|
|
100
|
+
return command?.params ? `${command.usage} ${command.params}` : '';
|
|
101
|
+
}
|