mixdog 0.8.1 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -23
- package/package.json +34 -28
- package/scripts/_test-folder-dialog.mjs +30 -0
- package/scripts/agent-parallel-smoke.mjs +388 -0
- package/scripts/agent-tag-reuse-smoke.mjs +183 -0
- package/scripts/background-task-meta-smoke.mjs +38 -0
- package/scripts/boot-smoke.mjs +52 -9
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/compact-active-turn-test.mjs +68 -0
- package/scripts/compact-smoke.mjs +859 -129
- package/scripts/compact-trigger-migration-smoke.mjs +187 -0
- package/scripts/fix-brief-fn.mjs +35 -0
- package/scripts/fix-format-tool-surface.mjs +24 -0
- package/scripts/fix-tool-exec-visible.mjs +42 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/hook-bus-test.mjs +330 -0
- package/scripts/lead-workflow-smoke.mjs +33 -39
- package/scripts/live-worker-smoke.mjs +43 -37
- package/scripts/llm-trace-summary.mjs +315 -0
- package/scripts/memory-meta-concurrency-test.mjs +20 -0
- package/scripts/output-style-smoke.mjs +56 -15
- package/scripts/parent-abort-link-test.mjs +44 -0
- package/scripts/patch-agent-brief.mjs +48 -0
- package/scripts/patch-app.mjs +21 -0
- package/scripts/patch-app2.mjs +18 -0
- package/scripts/patch-dist-brief.mjs +96 -0
- package/scripts/patch-tool-exec.mjs +70 -0
- package/scripts/pretool-ask-runtime-test.mjs +54 -0
- package/scripts/provider-toolcall-test.mjs +376 -0
- package/scripts/reactive-compact-persist-smoke.mjs +124 -0
- package/scripts/sanitize-tool-pairs-test.mjs +260 -0
- package/scripts/session-context-bench.mjs +205 -33
- package/scripts/session-ingest-smoke.mjs +177 -0
- package/scripts/set-effort-config-test.mjs +41 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -0
- package/scripts/smoke-runtime-negative.sh +97 -0
- package/scripts/smoke.mjs +25 -0
- package/scripts/tool-result-hook-test.mjs +48 -0
- package/scripts/tool-smoke.mjs +1222 -90
- package/scripts/toolcall-args-test.mjs +150 -0
- package/scripts/tui-background-failure-smoke.mjs +73 -0
- package/scripts/usage-metrics-epoch-smoke.mjs +114 -0
- package/src/agents/debugger/AGENT.md +8 -0
- package/src/agents/explore/AGENT.md +4 -0
- package/src/agents/heavy-worker/AGENT.md +9 -3
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +8 -0
- package/src/agents/scheduler-task/AGENT.md +12 -0
- package/src/agents/scheduler-task/agent.json +6 -0
- package/src/agents/webhook-handler/AGENT.md +12 -0
- package/src/agents/webhook-handler/agent.json +6 -0
- package/src/agents/worker/AGENT.md +9 -3
- package/src/app.mjs +77 -3
- package/src/defaults/hidden-roles.json +17 -12
- package/src/headless-role.mjs +117 -0
- package/src/help.mjs +30 -0
- package/src/hooks/lib/permission-evaluator.cjs +11 -475
- package/src/lib/keychain-cjs.cjs +9 -1
- package/src/lib/mixdog-debug.cjs +0 -29
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +242 -98
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2211 -446
- package/src/output-styles/default.md +12 -28
- package/src/output-styles/extreme-simple.md +9 -6
- package/src/output-styles/simple.md +22 -9
- package/src/repl.mjs +108 -59
- package/src/rules/agent/00-common.md +15 -0
- package/src/rules/{bridge → agent}/20-skip-protocol.md +1 -2
- package/src/rules/agent/30-explorer.md +22 -0
- package/src/rules/{bridge → agent}/40-cycle1-agent.md +7 -0
- package/src/rules/{bridge → agent}/41-cycle2-agent.md +7 -0
- package/src/rules/{bridge → agent}/42-cycle3-agent.md +7 -0
- package/src/rules/lead/01-general.md +9 -5
- package/src/rules/lead/04-workflow.md +51 -12
- package/src/rules/lead/lead-tool.md +6 -0
- package/src/rules/shared/01-tool.md +12 -1
- package/src/runtime/agent/orchestrator/activity-bus.mjs +7 -18
- package/src/runtime/agent/orchestrator/agent-owner.mjs +11 -0
- package/src/runtime/agent/orchestrator/{smart-bridge/bridge-llm.mjs → agent-runtime/agent-dispatch.mjs} +138 -111
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +94 -0
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/cache-strategy.mjs +32 -23
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/session-builder.mjs +33 -27
- package/src/runtime/agent/orchestrator/{bridge-trace.mjs → agent-trace.mjs} +132 -81
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +0 -21
- package/src/runtime/agent/orchestrator/config.mjs +174 -55
- package/src/runtime/agent/orchestrator/context/collect.mjs +195 -487
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-roles.mjs +77 -29
- package/src/runtime/agent/orchestrator/internal-tools.mjs +5 -6
- package/src/runtime/agent/orchestrator/mcp/client.mjs +15 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +380 -268
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +131 -93
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +236 -4
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +49 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +58 -13
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +67 -149
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +132 -2
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +61 -116
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +79 -255
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +203 -71
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +512 -312
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -518
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +88 -51
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +289 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- package/src/runtime/agent/orchestrator/session/compact.mjs +1173 -267
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +199 -36
- package/src/runtime/agent/orchestrator/session/loop.mjs +840 -612
- package/src/runtime/agent/orchestrator/session/manager.mjs +1574 -459
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +67 -29
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +31 -16
- package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +3 -219
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +35 -8
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -8
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -53
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +60 -37
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +21 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -7
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -3
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +36 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +5 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -36
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +2 -40
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +148 -27
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +43 -75
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +90 -20
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -5
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +86 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4106 -4019
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +33 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +90 -6
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +6 -4
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +8 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -4
- package/src/runtime/channels/index.mjs +149 -51
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -8
- package/src/runtime/channels/lib/runtime-paths.mjs +0 -6
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -6
- package/src/runtime/channels/lib/tool-format.mjs +0 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -12
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +519 -118
- package/src/runtime/memory/lib/agent-ipc.mjs +29 -12
- package/src/runtime/memory/lib/core-memory-store.mjs +2 -2
- package/src/runtime/memory/lib/embedding-model-config.mjs +55 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +31 -4
- package/src/runtime/memory/lib/embedding-worker.mjs +19 -10
- package/src/runtime/memory/lib/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +28 -7
- package/src/runtime/memory/lib/memory-cycle2.mjs +4 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +2 -2
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -2
- package/src/runtime/memory/lib/memory-session-merge.mjs +38 -0
- package/src/runtime/memory/lib/memory.mjs +88 -9
- package/src/runtime/memory/lib/model-profile.mjs +1 -1
- package/src/runtime/memory/lib/pg/adapter.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +80 -21
- package/src/runtime/memory/lib/session-ingest.mjs +196 -0
- package/src/runtime/memory/lib/trace-store.mjs +96 -51
- package/src/runtime/memory/tool-defs.mjs +46 -37
- package/src/runtime/search/index.mjs +104 -473
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +44 -25
- package/src/runtime/search/tool-defs.mjs +16 -23
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +4 -3
- package/src/runtime/shared/background-tasks.mjs +122 -11
- package/src/runtime/shared/child-spawn-gate.mjs +139 -0
- package/src/runtime/shared/config.mjs +7 -4
- package/src/runtime/shared/err-text.mjs +131 -4
- package/src/runtime/shared/llm/cost.mjs +2 -2
- package/src/runtime/shared/llm/http-agent.mjs +23 -7
- package/src/runtime/shared/llm/index.mjs +34 -11
- package/src/runtime/shared/llm/usage-log.mjs +4 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +56 -0
- package/src/runtime/shared/singleton-owner.mjs +104 -0
- package/src/runtime/shared/tool-execution-contract.mjs +199 -20
- package/src/runtime/shared/tool-execution-contract.test.mjs +183 -0
- package/src/runtime/shared/tool-surface.mjs +624 -95
- package/src/runtime/shared/user-data-guard.mjs +0 -2
- package/src/standalone/agent-task-status.mjs +203 -0
- package/src/standalone/agent-task-status.test.mjs +76 -0
- package/src/standalone/agent-tool.mjs +1913 -0
- package/src/standalone/channel-worker.mjs +370 -14
- package/src/standalone/explore-tool.mjs +165 -70
- package/src/standalone/folder-dialog.mjs +314 -0
- package/src/standalone/hook-bus.mjs +898 -22
- package/src/standalone/memory-runtime-proxy.mjs +320 -0
- package/src/standalone/projects.mjs +226 -0
- package/src/standalone/provider-admin.mjs +41 -24
- package/src/standalone/seeds.mjs +1 -78
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4800 -2140
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +14 -4
- package/src/tui/components/Markdown.jsx +43 -77
- package/src/tui/components/MarkdownTable.jsx +9 -184
- package/src/tui/components/Message.jsx +28 -11
- package/src/tui/components/Picker.jsx +95 -56
- package/src/tui/components/PromptInput.jsx +428 -239
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +27 -21
- package/src/tui/components/Spinner.jsx +67 -38
- package/src/tui/components/StatusLine.jsx +606 -38
- package/src/tui/components/TextEntryPanel.jsx +128 -9
- package/src/tui/components/ToolExecution.jsx +597 -362
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +499 -0
- package/src/tui/components/tool-output-format.test.mjs +312 -0
- package/src/tui/dist/index.mjs +9192 -2399
- package/src/tui/engine-runtime-notification.test.mjs +115 -0
- package/src/tui/engine-tool-result-text.test.mjs +75 -0
- package/src/tui/engine.mjs +1455 -279
- package/src/tui/figures.mjs +21 -40
- package/src/tui/index.jsx +75 -31
- package/src/tui/input-editing.mjs +25 -0
- package/src/tui/markdown/format-token.mjs +671 -69
- package/src/tui/markdown/format-token.test.mjs +312 -0
- package/src/tui/markdown/render-ansi.mjs +94 -0
- package/src/tui/markdown/render-ansi.test.mjs +108 -0
- package/src/tui/markdown/stream-fence.mjs +34 -0
- package/src/tui/markdown/stream-fence.test.mjs +26 -0
- package/src/tui/markdown/table-layout.mjs +250 -0
- package/src/tui/paste-attachments.mjs +0 -7
- package/src/tui/spinner-verbs.mjs +1 -2
- package/src/tui/statusline-ansi-bridge.mjs +172 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +159 -0
- package/src/tui/theme.mjs +756 -24
- package/src/tui/time-format.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +67 -0
- package/src/tui/transcript-tool-failures.test.mjs +111 -0
- package/src/ui/ansi.mjs +1 -2
- package/src/ui/markdown.mjs +85 -26
- package/src/ui/markdown.test.mjs +70 -0
- package/src/ui/model-display.mjs +121 -0
- package/src/ui/session-stats.mjs +44 -0
- package/src/ui/statusline-context-label.test.mjs +15 -0
- package/src/ui/statusline.mjs +386 -178
- package/src/ui/tool-card.mjs +2 -13
- package/src/vendor/statusline/bin/statusline-lib.mjs +1 -620
- package/src/vendor/statusline/bin/statusline-route.mjs +169 -37
- package/src/vendor/statusline/bin/statusline-route.test.mjs +80 -0
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +3 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +1 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +44 -6
- package/src/vendor/statusline/src/gateway/session-routes.mjs +1 -1
- package/src/workflows/default/WORKFLOW.md +12 -5
- package/src/workflows/default/workflow.json +0 -1
- package/src/workflows/solo/WORKFLOW.md +15 -0
- package/src/workflows/solo/workflow.json +7 -0
- package/vendor/ink/build/ink.js +54 -8
- package/vendor/ink/build/output.js +6 -1
- package/src/agents/scheduler-task.md +0 -3
- package/src/agents/web-researcher/AGENT.md +0 -3
- package/src/agents/web-researcher/agent.json +0 -6
- package/src/agents/webhook-handler.md +0 -3
- package/src/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- package/src/rules/bridge/00-common.md +0 -5
- package/src/rules/bridge/30-explorer.md +0 -4
- package/src/rules/lead/00-tool-lead.md +0 -5
- package/src/rules/shared/00-language.md +0 -3
- package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
- package/src/runtime/agent/orchestrator/tools/mutation-content-cache.mjs +0 -67
- package/src/runtime/channels/lib/hook-pipe-server.mjs +0 -671
- package/src/runtime/memory/lib/bridge-trace-queries.mjs +0 -120
- package/src/runtime/shared/llm/pid-cleanup.mjs +0 -27
- package/src/standalone/bridge-tool.mjs +0 -1414
- package/src/tui/runtime/shared/process-shutdown.mjs +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* components/QueuedCommands.jsx — queued steering prompts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Queued steering prompts: lines the user typed
|
|
5
5
|
* while a turn is busy wait here as dim rows, pinned just above the input box
|
|
6
6
|
* (part of the input cluster) instead of polluting the transcript. Each queued
|
|
7
7
|
* line is promoted to a real transcript user row only when it starts executing
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* components/SlashCommandPalette.jsx — live slash command palette.
|
|
3
|
-
*
|
|
4
|
-
* This is intentionally display-only: PromptInput owns keyboard focus and
|
|
5
|
-
* forwards arrow / enter / escape decisions to App, so the prompt caret stays
|
|
6
|
-
* anchored while the palette updates above it.
|
|
7
|
-
*/
|
|
1
|
+
/**
|
|
2
|
+
* components/SlashCommandPalette.jsx — live slash command palette.
|
|
3
|
+
*
|
|
4
|
+
* This is intentionally display-only: PromptInput owns keyboard focus and
|
|
5
|
+
* forwards arrow / enter / escape decisions to App, so the prompt caret stays
|
|
6
|
+
* anchored while the palette updates above it.
|
|
7
|
+
*/
|
|
8
8
|
import React from 'react';
|
|
9
9
|
import { Box, Text } from 'ink';
|
|
10
10
|
import stringWidth from 'string-width';
|
|
11
11
|
import { theme } from '../theme.mjs';
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
const MAX_VISIBLE = 8;
|
|
14
14
|
const COMMAND_LABEL_WIDTH = 18;
|
|
15
15
|
const SLASH_HELP = '↑/↓ select · ←/→ change · Enter run · Esc cancel';
|
|
16
|
+
const SLASH_DESCRIPTION = 'Type to filter · Enter runs the highlighted command.';
|
|
16
17
|
const ACRONYM_LABELS = new Map([
|
|
17
18
|
['mcp', 'MCP'],
|
|
18
19
|
]);
|
|
@@ -43,7 +44,7 @@ function queryMatchesAlias(command, query) {
|
|
|
43
44
|
|
|
44
45
|
function commandDisplayLabel(command, query) {
|
|
45
46
|
const usage = String(command?.usage || command?.name || '').replace(/^\/+/, '');
|
|
46
|
-
const aliasText = queryMatchesAlias(command, query) && Array.isArray(command?.aliasUsage) && command.aliasUsage.length > 0
|
|
47
|
+
const aliasText = command?.showAliasUsage !== false && queryMatchesAlias(command, query) && Array.isArray(command?.aliasUsage) && command.aliasUsage.length > 0
|
|
47
48
|
? ` (${command.aliasUsage.join(', ')})`
|
|
48
49
|
: '';
|
|
49
50
|
const label = ACRONYM_LABELS.get(usage.toLowerCase()) || (usage ? `${usage.charAt(0).toUpperCase()}${usage.slice(1)}` : usage);
|
|
@@ -62,20 +63,25 @@ export function SlashCommandPalette({ commands, selectedIndex = 0, title = 'Comm
|
|
|
62
63
|
const blankRows = Math.max(0, MAX_VISIBLE - visible.length);
|
|
63
64
|
const labelWidth = Math.max(12, Math.min(COMMAND_LABEL_WIDTH, Math.max(12, Math.floor(columns * 0.45))));
|
|
64
65
|
const descriptionWidth = Math.max(0, columns - labelWidth - 12);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
66
|
+
// Standard panel rhythm: title row, blank, description/hint row, blank, content.
|
|
67
|
+
const description = truncateText(SLASH_DESCRIPTION, Math.max(0, columns - 4));
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<Box flexDirection="column" flexShrink={0} width="100%">
|
|
71
|
+
<Box
|
|
72
|
+
flexDirection="column"
|
|
73
|
+
borderStyle="round"
|
|
74
|
+
borderColor={theme.promptBorder}
|
|
75
|
+
paddingX={1}
|
|
76
|
+
width="100%"
|
|
77
|
+
>
|
|
78
|
+
<Box flexDirection="row" justifyContent="space-between">
|
|
76
79
|
<Text color={theme.panelTitle}>{title}</Text>
|
|
77
80
|
<Text color={theme.subtle}>{SLASH_HELP}</Text>
|
|
78
81
|
</Box>
|
|
82
|
+
<Text> </Text>
|
|
83
|
+
<Text color={theme.subtle}>{description || ' '}</Text>
|
|
84
|
+
<Text> </Text>
|
|
79
85
|
{visible.map((item, index) => (
|
|
80
86
|
<CommandRow
|
|
81
87
|
key={item.name}
|
|
@@ -93,7 +99,7 @@ export function SlashCommandPalette({ commands, selectedIndex = 0, title = 'Comm
|
|
|
93
99
|
</Box>
|
|
94
100
|
);
|
|
95
101
|
}
|
|
96
|
-
|
|
102
|
+
|
|
97
103
|
const CommandRow = React.memo(function CommandRow({ command, isSelected, labelWidth, descriptionWidth, query }) {
|
|
98
104
|
const label = truncateText(commandDisplayLabel(command, query), labelWidth);
|
|
99
105
|
const description = truncateText(command.description, descriptionWidth);
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* components/Spinner.jsx — the "thinking" indicator
|
|
2
|
+
* components/Spinner.jsx — the "thinking" indicator.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - frames
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
* - verb… verb shimmer: traveling highlight in claudeShimmer with
|
|
9
|
-
* mode-aware glimmer speed (CC GlimmerMessage).
|
|
4
|
+
* Spinner row layout:
|
|
5
|
+
* - frames sweep forward then back.
|
|
6
|
+
* - the glyph sits in a `width={2}` box.
|
|
7
|
+
* - verb… verb shimmer: traveling highlight with mode-aware glimmer speed.
|
|
10
8
|
* - stall detection with exponential smoothing: intensity fades in/out over
|
|
11
|
-
* 2s
|
|
12
|
-
* - thinking shimmer: left-to-right "thinking" label after delay
|
|
13
|
-
* ThinkingShimmerText, inlined from useAnimationFrame).
|
|
9
|
+
* 2s fade.
|
|
10
|
+
* - thinking shimmer: left-to-right "thinking" label after delay.
|
|
14
11
|
* - progressive width gating: timer/tokens/thinking shown left→right only if
|
|
15
|
-
* they fit after the previous segments
|
|
12
|
+
* they fit after the previous segments.
|
|
16
13
|
* - token counter animation: smooth increment toward the current turn's
|
|
17
|
-
* output token count
|
|
18
|
-
* tokens" segment (CC SpinnerAnimationRow + SpinnerModeGlyph). The glyph
|
|
14
|
+
* output token count as a single "<glyph> N tokens" segment. The glyph
|
|
19
15
|
* is mode-driven: up while requesting, down otherwise. Input totals hidden.
|
|
20
|
-
* - elided duration formatting (
|
|
16
|
+
* - elided duration formatting ("0:25" after 60s).
|
|
21
17
|
* - mode prop: 'responding' | 'thinking' | 'tool-use' | 'tool-input' |
|
|
22
18
|
* 'requesting' | 'compacting' | 'resuming' (default 'responding').
|
|
23
19
|
*/
|
|
@@ -29,21 +25,21 @@ import { DOWN_ARROW, UP_ARROW } from '../figures.mjs';
|
|
|
29
25
|
import { formatDuration } from '../time-format.mjs';
|
|
30
26
|
|
|
31
27
|
const FRAME_MS = 130;
|
|
32
|
-
//
|
|
28
|
+
// Play frames forward, then in reverse — a smooth there-and-back sweep.
|
|
33
29
|
const FRAMES = [...SPINNER_FRAMES, ...[...SPINNER_FRAMES].reverse()];
|
|
34
30
|
|
|
35
31
|
// Stall: response must grow within this window or the glyph reddens.
|
|
36
32
|
const STALL_TIMEOUT_MS = 3000;
|
|
37
|
-
const STALL_FADE_MS = 2000; //
|
|
38
|
-
//
|
|
33
|
+
const STALL_FADE_MS = 2000; // fade red over 2s
|
|
34
|
+
// Hide elapsed/token meta on short turns unless verbose/teammates
|
|
39
35
|
// are active. Mixdog has no spinner verbose/teammate row here, so mirror the
|
|
40
36
|
// default 30s threshold.
|
|
41
37
|
const SHOW_TOKENS_AFTER_MS = 30_000;
|
|
42
|
-
// Thinking shimmer starts after this delay
|
|
38
|
+
// Thinking shimmer starts after this delay.
|
|
43
39
|
const THINKING_DELAY_MS = 3000;
|
|
44
40
|
|
|
45
41
|
// One-way shimmer. The tail runs past the final character before restarting.
|
|
46
|
-
const GLIMMER_SPEED_MS = { requesting: 70, compacting: 120, resuming: 120, 'tool-use': 120, responding: 120, thinking: 120, 'tool-input': 120 };
|
|
42
|
+
const GLIMMER_SPEED_MS = { requesting: 70, compacting: 120, 'auto-clear': 120, resuming: 120, 'tool-use': 120, responding: 120, thinking: 120, 'tool-input': 120 };
|
|
47
43
|
const GLIMMER_TRAIL = 4;
|
|
48
44
|
const THINKING_GLIMMER_SPEED_MS = 120;
|
|
49
45
|
const THINKING_GLIMMER_TRAIL = 4;
|
|
@@ -54,6 +50,7 @@ const VERB_CHANGE_PROBABILITY = 0.65;
|
|
|
54
50
|
const MODE_VERBS = {
|
|
55
51
|
requesting: ['Requesting', 'Preparing', 'Routing'],
|
|
56
52
|
compacting: ['Compacting conversation'],
|
|
53
|
+
'auto-clear': ['Auto-clearing conversation'],
|
|
57
54
|
resuming: ['Resuming conversation'],
|
|
58
55
|
thinking: ['Thinking', 'Reasoning', 'Mapping'],
|
|
59
56
|
'tool-use': ['Using tools', 'Checking files', 'Running tools', 'Reading output'],
|
|
@@ -109,11 +106,19 @@ function renderShimmerText(text, head, trail, baseRgb, shimmerRgb, baseColor, ke
|
|
|
109
106
|
);
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
109
|
+
// Parsed RGB tuples are derived from the active theme. They are resolved per
|
|
110
|
+
// render (cheap regex parse) so a live `/theme` switch — which mutates `theme`
|
|
111
|
+
// in-place and re-renders the tree — picks up the new shimmer/glyph colors
|
|
112
|
+
// instead of the colors captured at module load.
|
|
113
|
+
function spinnerRgb() {
|
|
114
|
+
return {
|
|
115
|
+
TEXT_RGB: parseRgb(theme.spinnerText) ?? parseRgb(theme.text),
|
|
116
|
+
SHIMMER_RGB: parseRgb(theme.spinnerShimmer) ?? parseRgb(theme.claudeShimmer),
|
|
117
|
+
SPINNER_GLYPH_RGB: parseRgb(theme.spinnerGlyph) ?? { r: 240, g: 240, b: 240 },
|
|
118
|
+
THINKING_INACTIVE: parseRgb(theme.thinkingBase) ?? parseRgb(theme.thinkingAccent) ?? { r: 153, g: 153, b: 153 },
|
|
119
|
+
THINKING_SHIMMER: parseRgb(theme.thinkingGlow) ?? { r: 255, g: 205, b: 175 },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
117
122
|
|
|
118
123
|
const compactNumberFormatter = new Intl.NumberFormat('en-US', {
|
|
119
124
|
notation: 'compact',
|
|
@@ -147,8 +152,27 @@ function chooseNextVerb(mode, fallback, current) {
|
|
|
147
152
|
return candidates[Math.floor(Math.random() * candidates.length)];
|
|
148
153
|
}
|
|
149
154
|
|
|
155
|
+
// Token-direction glyph by mode:
|
|
156
|
+
// up while uploading the request, down while receiving a response, and no
|
|
157
|
+
// glyph at all for non-streaming modes (compacting/resuming/auto-clear) where
|
|
158
|
+
// the arrow direction would be meaningless.
|
|
159
|
+
function tokenModeGlyph(mode) {
|
|
160
|
+
switch (mode) {
|
|
161
|
+
case 'tool-input':
|
|
162
|
+
case 'tool-use':
|
|
163
|
+
case 'responding':
|
|
164
|
+
case 'thinking':
|
|
165
|
+
return DOWN_ARROW;
|
|
166
|
+
case 'requesting':
|
|
167
|
+
return UP_ARROW;
|
|
168
|
+
default:
|
|
169
|
+
return '';
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
150
173
|
export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens = 0, thinking = false, thinkingActiveSince = 0, mode = 'responding', columns = 80, marginTop = 1 }) {
|
|
151
174
|
useAnimation({ interval: FRAME_MS });
|
|
175
|
+
const { TEXT_RGB, SHIMMER_RGB, SPINNER_GLYPH_RGB, THINKING_INACTIVE, THINKING_SHIMMER } = spinnerRgb();
|
|
152
176
|
const now = Date.now();
|
|
153
177
|
const elapsedMs = startedAt ? Math.max(0, now - startedAt) : 0;
|
|
154
178
|
const frame = Math.floor(elapsedMs / FRAME_MS);
|
|
@@ -158,7 +182,7 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
158
182
|
const displayVerbRef = useRef('');
|
|
159
183
|
const displayVerbModeRef = useRef('');
|
|
160
184
|
const nextVerbCheckRef = useRef(0);
|
|
161
|
-
// Stall smoothing refs (
|
|
185
|
+
// Stall smoothing refs (exponential fade)
|
|
162
186
|
const stallSmoothRef = useRef(0);
|
|
163
187
|
const lastStallTickRef = useRef(0);
|
|
164
188
|
|
|
@@ -173,7 +197,7 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
173
197
|
|
|
174
198
|
const stallMs = now - lastGrowRef.current;
|
|
175
199
|
const isStalled = targetOutputTokens > 0 && stallMs > STALL_TIMEOUT_MS;
|
|
176
|
-
// Stall smoothing: exponential fade toward target
|
|
200
|
+
// Stall smoothing: exponential fade toward target
|
|
177
201
|
const rawIntensity = isStalled
|
|
178
202
|
? Math.min(1, (stallMs - STALL_TIMEOUT_MS) / STALL_FADE_MS)
|
|
179
203
|
: 0;
|
|
@@ -194,7 +218,7 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
194
218
|
|
|
195
219
|
const glyph = FRAMES[frame % FRAMES.length];
|
|
196
220
|
|
|
197
|
-
// Glyph color — interpolate toward red when stalled
|
|
221
|
+
// Glyph color — interpolate toward red when stalled.
|
|
198
222
|
const glyphColor = stalledIntensity > 0
|
|
199
223
|
? toRgbString(interpolateColor(
|
|
200
224
|
SPINNER_GLYPH_RGB,
|
|
@@ -203,7 +227,7 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
203
227
|
))
|
|
204
228
|
: theme.spinnerGlyph;
|
|
205
229
|
|
|
206
|
-
// --- Verb shimmer (
|
|
230
|
+
// --- Verb shimmer (traveling highlight) ---
|
|
207
231
|
if (displayVerbModeRef.current !== mode || !displayVerbRef.current) {
|
|
208
232
|
displayVerbModeRef.current = mode;
|
|
209
233
|
displayVerbRef.current = stableModeVerb(mode, verb);
|
|
@@ -242,18 +266,20 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
242
266
|
return Math.round(ref.current);
|
|
243
267
|
};
|
|
244
268
|
|
|
245
|
-
// Token counter animation —
|
|
246
|
-
// segment (SpinnerAnimationRow + SpinnerModeGlyph). N is the output/response
|
|
269
|
+
// Token counter animation — single "<glyph> N tokens" segment. N is the output/response
|
|
247
270
|
// token count, smoothly incremented toward the current turn's value. The
|
|
248
271
|
// glyph is mode-driven: up while requesting, down otherwise (responding,
|
|
249
272
|
// thinking, tool-use, tool-input). Input token totals are not shown.
|
|
250
273
|
const displayedOutputTokens = advanceCounter(displayedOutputRef, targetOutputTokens);
|
|
251
274
|
|
|
252
|
-
const tokenGlyph = mode
|
|
253
|
-
const
|
|
275
|
+
const tokenGlyph = tokenModeGlyph(mode);
|
|
276
|
+
const tokenCountText = formatNumber(displayedOutputTokens);
|
|
277
|
+
const tokenText = displayedOutputTokens > 0
|
|
278
|
+
? (tokenGlyph ? `${tokenGlyph} ${tokenCountText} tokens` : `${tokenCountText} tokens`)
|
|
279
|
+
: '';
|
|
254
280
|
const tokenW = tokenText.length;
|
|
255
281
|
|
|
256
|
-
// Progressive width gating
|
|
282
|
+
// Progressive width gating: show status parts
|
|
257
283
|
// left→right, each only if it fits after the previous ones. Timer/tokens are
|
|
258
284
|
// hidden for short turns by default; thinking status can still show alone.
|
|
259
285
|
const avail = columns - messageLen - 5; // glyph(2) + ' (' + ')'
|
|
@@ -266,17 +292,20 @@ export function Spinner({ verb = 'Working', startedAt, outputTokens = 0, tokens
|
|
|
266
292
|
? 'thinking'
|
|
267
293
|
: '';
|
|
268
294
|
const thinkingStatusW = thinkingStatusText.length;
|
|
269
|
-
|
|
295
|
+
// Turn elapsed time is the headline metric here, not a thinking sub-stat, so
|
|
296
|
+
// it shows from 1s onward (formatDuration returns '' below 1s). Tokens keep
|
|
297
|
+
// Short-turn gate: tokens only appear once the turn runs long.
|
|
298
|
+
const wantsTokens = elapsedMs > SHOW_TOKENS_AFTER_MS;
|
|
270
299
|
|
|
271
|
-
//
|
|
300
|
+
// Thinking display priority for narrow widths, but renders
|
|
272
301
|
// it after timer/tokens in the final byline.
|
|
273
302
|
const showThinkingStatus = Boolean(thinkingStatusText) && avail > thinkingStatusW;
|
|
274
303
|
const usedAfterThinking = showThinkingStatus ? thinkingStatusW + SEP_WIDTH : 0;
|
|
275
|
-
const showTimer =
|
|
304
|
+
const showTimer = Boolean(timerLabel) && avail > usedAfterThinking + timerW;
|
|
276
305
|
const usedAfterTimer = usedAfterThinking + (showTimer ? timerW + SEP_WIDTH : 0);
|
|
277
|
-
const showTokens =
|
|
306
|
+
const showTokens = wantsTokens && tokenText && avail > usedAfterTimer + tokenW;
|
|
278
307
|
|
|
279
|
-
// Build meta line segments — elapsed, tokens, thinking
|
|
308
|
+
// Build meta line segments — elapsed, tokens, thinking.
|
|
280
309
|
const segments = [];
|
|
281
310
|
if (showTimer) {
|
|
282
311
|
segments.push(
|