mixdog 0.9.3 → 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 +7 -3
- package/scripts/bench/lead-review-tasks-r3.json +20 -0
- package/scripts/bench/lead-review-tasks.json +20 -0
- package/scripts/bench/r4-mixed-tasks.json +20 -0
- package/scripts/bench/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/freevar-smoke.mjs +95 -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/provider-toolcall-test.mjs +7 -3
- 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 +23 -63
- package/scripts/tui-render-smoke.mjs +90 -0
- package/scripts/webhook-smoke.mjs +208 -0
- package/src/agents/debugger/AGENT.md +4 -1
- package/src/agents/heavy-worker/AGENT.md +6 -5
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +2 -1
- package/src/agents/worker/AGENT.md +8 -4
- package/src/lib/rules-builder.cjs +4 -0
- package/src/mixdog-session-runtime.mjs +632 -2042
- 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/rules/agent/00-common.md +2 -0
- package/src/rules/lead/lead-brief.md +12 -0
- package/src/rules/lead/lead-tool.md +0 -11
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
- package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
- package/src/runtime/agent/orchestrator/config.mjs +69 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +297 -2123
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +130 -1002
- 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/session/compact/budget.mjs +288 -0
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
- package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
- package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
- package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
- package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +251 -397
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
- package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
- package/src/runtime/agent/orchestrator/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 +32 -41
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
- package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
- package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
- package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
- package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
- package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
- package/src/runtime/channels/backends/discord-access.mjs +32 -0
- package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
- package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
- package/src/runtime/channels/backends/discord.mjs +12 -292
- package/src/runtime/channels/index.mjs +229 -663
- package/src/runtime/channels/lib/backend-dispatch.mjs +44 -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/output-forwarder.mjs +1 -1
- package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
- package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
- package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
- package/src/runtime/channels/lib/session-discovery.mjs +56 -4
- package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
- package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
- package/src/runtime/channels/lib/webhook/deliveries.mjs +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/tool-defs.mjs +11 -130
- package/src/runtime/memory/index.mjs +201 -1948
- package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
- package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
- package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
- package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
- package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
- package/src/runtime/memory/lib/memory-embed.mjs +149 -0
- package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
- package/src/runtime/memory/lib/query-handlers.mjs +780 -0
- package/src/runtime/memory/lib/recall-format.mjs +55 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
- package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
- package/src/runtime/memory/tool-defs.mjs +5 -13
- package/src/runtime/search/lib/http-fetch.mjs +274 -0
- package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
- package/src/runtime/search/lib/web-tools.mjs +24 -602
- package/src/runtime/shared/atomic-file.mjs +26 -1
- package/src/runtime/shared/launcher-control.mjs +2 -2
- package/src/runtime/shared/tool-primitives.mjs +308 -0
- package/src/runtime/shared/tool-result-summary.mjs +515 -0
- package/src/runtime/shared/tool-surface.mjs +80 -898
- package/src/runtime/shared/transcript-writer.mjs +23 -0
- package/src/runtime/shared/update-checker.mjs +7 -4
- package/src/session-runtime/config-helpers.mjs +84 -2
- package/src/session-runtime/config-lifecycle.mjs +232 -0
- package/src/session-runtime/cwd-plugins.mjs +226 -0
- package/src/session-runtime/mcp-glue.mjs +177 -0
- package/src/session-runtime/model-recency.mjs +111 -0
- package/src/session-runtime/native-search.mjs +247 -0
- package/src/session-runtime/output-styles.mjs +11 -9
- package/src/session-runtime/prewarm.mjs +142 -0
- package/src/session-runtime/provider-models.mjs +278 -0
- package/src/session-runtime/provider-usage.mjs +120 -0
- package/src/session-runtime/quick-model-rows.mjs +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/settings-api.mjs +319 -0
- package/src/session-runtime/tool-catalog.mjs +29 -29
- package/src/session-runtime/tool-defs.mjs +84 -0
- package/src/session-runtime/warmup-schedulers.mjs +201 -0
- package/src/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 +110 -671
- package/src/standalone/channel-worker.mjs +4 -7
- package/src/standalone/explore-tool.mjs +30 -9
- package/src/standalone/hook-bus/config.mjs +207 -0
- package/src/standalone/hook-bus/constants.mjs +90 -0
- package/src/standalone/hook-bus/handlers.mjs +481 -0
- package/src/standalone/hook-bus/payload.mjs +31 -0
- package/src/standalone/hook-bus/rules.mjs +77 -0
- package/src/standalone/hook-bus.mjs +77 -870
- package/src/standalone/memory-runtime-proxy.mjs +7 -0
- package/src/standalone/opencode-go-login.mjs +5 -1
- package/src/standalone/provider-admin.mjs +1 -16
- package/src/standalone/usage-dashboard.mjs +3 -1
- package/src/tui/App.jsx +945 -8094
- 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 +23 -101
- 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 +52 -594
- package/src/tui/components/TranscriptItem.jsx +105 -0
- package/src/tui/components/UsagePanel.jsx +18 -4
- package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
- package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
- package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
- package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
- package/src/tui/components/tool-execution/text-format.mjs +161 -0
- package/src/tui/display-width.mjs +20 -3
- package/src/tui/dist/index.mjs +19652 -18630
- package/src/tui/engine/agent-job-feed.mjs +133 -0
- package/src/tui/engine/notification-plan.mjs +76 -0
- package/src/tui/engine/render-timing.mjs +17 -0
- package/src/tui/engine/tool-approval.mjs +94 -0
- package/src/tui/engine/tool-card-results.mjs +234 -0
- package/src/tui/engine/tool-result-status.mjs +135 -0
- package/src/tui/engine.mjs +122 -562
- package/src/tui/figures.mjs +5 -0
- package/src/tui/index.jsx +105 -0
- package/src/tui/input-editing.mjs +2 -2
- package/src/tui/markdown/format-token.mjs +4 -1
- package/src/tui/statusline-ansi-bridge.mjs +11 -3
- package/src/tui/theme.mjs +6 -0
- package/src/ui/statusline-agents.mjs +213 -0
- package/src/ui/statusline-format.mjs +146 -0
- package/src/ui/statusline-segments.mjs +148 -0
- package/src/ui/statusline.mjs +67 -501
- package/src/ui/tool-card.mjs +0 -1
- package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
- package/src/workflows/default/WORKFLOW.md +1 -1
- package/src/workflows/sequential/WORKFLOW.md +1 -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/external-tool-adapters.test.mjs +0 -162
- 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/task-notification-envelope.test.mjs +0 -107
- package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
- package/src/standalone/agent-task-status.test.mjs +0 -76
- package/src/tui/components/tool-output-format.test.mjs +0 -399
- package/src/tui/display-width.test.mjs +0 -35
- package/src/tui/engine-runtime-notification.test.mjs +0 -115
- package/src/tui/engine-tool-result-text.test.mjs +0 -75
- package/src/tui/input-editing.selection.test.mjs +0 -75
- package/src/tui/markdown/format-token.test.mjs +0 -354
- package/src/tui/markdown/render-ansi.test.mjs +0 -108
- package/src/tui/markdown/stream-fence.test.mjs +0 -26
- package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
- package/src/tui/paste-fix.test.mjs +0 -119
- package/src/tui/prompt-history-store.test.mjs +0 -52
- package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
- package/src/tui/transcript-tool-failures.test.mjs +0 -111
- package/src/ui/markdown.test.mjs +0 -70
- package/src/ui/statusline-context-label.test.mjs +0 -15
- package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
- package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import React, { useEffect, useLayoutEffect, useState, useRef } from 'react';
|
|
19
19
|
import { Box, Text, useInput, usePaste, useStdin } from 'ink';
|
|
20
|
-
import
|
|
20
|
+
import { displayWidth } from '../display-width.mjs';
|
|
21
21
|
import { theme, surfaceBackground } from '../theme.mjs';
|
|
22
22
|
import {
|
|
23
23
|
caretPosition,
|
|
@@ -40,48 +40,29 @@ import {
|
|
|
40
40
|
verticalOffset,
|
|
41
41
|
wordRangeAt,
|
|
42
42
|
} from '../input-editing.mjs';
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
import {
|
|
44
|
+
hintStyle,
|
|
45
|
+
insertText,
|
|
46
|
+
normalizePastedText,
|
|
47
|
+
singleTrailingLineBreakPrefix,
|
|
48
|
+
draftStateEqual,
|
|
49
|
+
isModifiedEnterSequence,
|
|
50
|
+
isAnyModifiedEnterSequence,
|
|
51
|
+
} from './prompt-input/edit-helpers.mjs';
|
|
52
|
+
import {
|
|
53
|
+
VOICE_TICK_MS,
|
|
54
|
+
voiceIndicatorTextFor,
|
|
55
|
+
} from './prompt-input/voice-indicator.mjs';
|
|
50
56
|
|
|
51
57
|
// Windows Terminal IME composition can clip a glyph that starts exactly at the
|
|
52
58
|
// left edge of the editable text node. The rounded prompt box already adds a
|
|
53
59
|
// paddingX of 1, so the typing start can sit directly against that padding
|
|
54
60
|
// without an extra guard column.
|
|
55
61
|
const IME_LEFT_GUARD_COLUMNS = 0;
|
|
56
|
-
|
|
57
|
-
// Monotone voice indicator glyphs — right end of the prompt box. All frames
|
|
58
|
-
// are 1-cell-wide (no emoji, no string-width special-casing needed). Modes:
|
|
59
|
-
// 'off' — voice disabled and no install in flight: renders nothing,
|
|
60
|
-
// zero reserved columns.
|
|
61
|
-
// 'installing' — voice-runtime download in progress (progressHint active):
|
|
62
|
-
// braille spinner only.
|
|
63
|
-
// 'idle' — voice enabled, recorder idle: a slow "breathing" pulse
|
|
64
|
-
// (◎ ◍ ◉ ◍) so the indicator isn't a dead static glyph.
|
|
65
|
-
// 'recording' — steady ◉ + a braille spinner riding next to it (2 cells).
|
|
66
|
-
// 'transcribing' — braille spinner only (recording just stopped, awaiting
|
|
67
|
-
// the whisper-server round-trip).
|
|
68
|
-
// A single ~120ms interval drives BOTH the fast braille cycle and the slower
|
|
69
|
-
// idle pulse (idle advances one frame every VOICE_IDLE_FRAME_TICKS ticks) —
|
|
70
|
-
// one timer instead of two, and it only exists while the indicator is
|
|
71
|
-
// visible (mode !== 'off'); it's torn down otherwise, never a permanent timer.
|
|
72
|
-
const VOICE_BRAILLE_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧'];
|
|
73
|
-
const VOICE_IDLE_FRAMES = ['◎', '◍', '◉', '◍'];
|
|
74
|
-
const VOICE_TICK_MS = 120;
|
|
75
|
-
const VOICE_IDLE_FRAME_TICKS = 5; // ~600ms per idle frame (5 * 120ms)
|
|
76
62
|
// Coalesce prompt mouse-drag extend commits (SGR motion can fire faster than ink
|
|
77
63
|
// needs to immediate-render). Matches transcript selection paint cadence.
|
|
78
64
|
const MOUSE_EXTEND_COALESCE_MS = 24;
|
|
79
65
|
|
|
80
|
-
function insertText(draft, input) {
|
|
81
|
-
if (!input) return draft;
|
|
82
|
-
return replaceSelection(draft, input);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
66
|
function renderSelectedText(displayValue, range, trailingSpace = false) {
|
|
86
67
|
if (!range) return trailingSpace ? `${displayValue} ` : displayValue;
|
|
87
68
|
const start = Math.max(0, Math.min(displayValue.length, range.start));
|
|
@@ -98,57 +79,6 @@ function renderSelectedText(displayValue, range, trailingSpace = false) {
|
|
|
98
79
|
);
|
|
99
80
|
}
|
|
100
81
|
|
|
101
|
-
function normalizePastedText(text) {
|
|
102
|
-
return String(text ?? '').replace(/\r\n?/g, '\n');
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function singleTrailingLineBreakPrefix(text) {
|
|
106
|
-
const normalized = normalizePastedText(text);
|
|
107
|
-
if (!normalized.endsWith('\n')) return null;
|
|
108
|
-
const prefix = normalized.slice(0, -1);
|
|
109
|
-
return prefix.includes('\n') ? null : prefix;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function draftStateEqual(a, b) {
|
|
113
|
-
return (
|
|
114
|
-
a.value === b.value
|
|
115
|
-
&& a.cursor === b.cursor
|
|
116
|
-
&& a.selectionAnchor === b.selectionAnchor
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Recognize a MODIFIED Enter delivered via the kitty keyboard protocol
|
|
121
|
-
// (\x1b[13;<mod>u) or modifyOtherKeys (\x1b[27;<mod>;13~). The xterm modifier
|
|
122
|
-
// param is (1 + bitmask) where the bitmask bits are shift=1, alt=2, ctrl=4. We
|
|
123
|
-
// treat Ctrl+Enter AND Shift+Enter (the two common "insert newline" chords) as a
|
|
124
|
-
// newline, so we match when the shift OR ctrl bit is set. Ctrl+J is handled
|
|
125
|
-
// separately as the protocol-independent fallback.
|
|
126
|
-
const MODIFIED_ENTER_SHIFT_OR_CTRL = 1 | 4;
|
|
127
|
-
function isModifiedEnterSequence(input) {
|
|
128
|
-
const text = String(input ?? '');
|
|
129
|
-
const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
|
|
130
|
-
if (!body) return false;
|
|
131
|
-
const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
|
|
132
|
-
if (kitty) return ((Number(kitty[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0;
|
|
133
|
-
const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
|
|
134
|
-
return Boolean(modifyOtherKeys && (((Number(modifyOtherKeys[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0));
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Recognize ANY modified Enter (any modifier bitmask, e.g. Alt+Enter \x1b[13;3u
|
|
138
|
-
// / \x1b[27;3;13~). Used to CONSUME modified-Enter sequences we don't map to a
|
|
139
|
-
// newline (Alt-only, etc.) so they aren't typed into the prompt as raw CSI text
|
|
140
|
-
// under modifyOtherKeys. Plain Enter (mod param = 1, bitmask 0) is intentionally
|
|
141
|
-
// NOT matched, so it still submits.
|
|
142
|
-
function isAnyModifiedEnterSequence(input) {
|
|
143
|
-
const text = String(input ?? '');
|
|
144
|
-
const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
|
|
145
|
-
if (!body) return false;
|
|
146
|
-
const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
|
|
147
|
-
if (kitty) return (Number(kitty[1]) - 1) !== 0;
|
|
148
|
-
const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
|
|
149
|
-
return Boolean(modifyOtherKeys && ((Number(modifyOtherKeys[1]) - 1) !== 0));
|
|
150
|
-
}
|
|
151
|
-
|
|
152
82
|
export function PromptInput({
|
|
153
83
|
onSubmit,
|
|
154
84
|
disabled = false,
|
|
@@ -204,12 +134,13 @@ export function PromptInput({
|
|
|
204
134
|
const preferredColumnRef = useRef(null);
|
|
205
135
|
const mouseExtendCoalesceRef = useRef({ pendingNext: null, timer: null, t: 0 });
|
|
206
136
|
// Voice indicator animation tick. Runs a single ~120ms interval ONLY while
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
//
|
|
137
|
+
// an ANIMATED mode is active (installing/recording/transcribing) — 'idle'
|
|
138
|
+
// renders a static glyph and 'off' renders nothing, so neither keeps a
|
|
139
|
+
// timer alive (the old idle "breathing" pulse spun constantly whenever
|
|
140
|
+
// voice was merely enabled, reading as phantom activity).
|
|
210
141
|
const [voiceTick, setVoiceTick] = useState(0);
|
|
211
142
|
useEffect(() => {
|
|
212
|
-
if (voiceIndicatorMode === 'off') return undefined;
|
|
143
|
+
if (voiceIndicatorMode === 'off' || voiceIndicatorMode === 'idle') return undefined;
|
|
213
144
|
const timer = setInterval(() => setVoiceTick((t) => (t + 1) % 1000000), VOICE_TICK_MS);
|
|
214
145
|
timer.unref?.();
|
|
215
146
|
return () => clearInterval(timer);
|
|
@@ -308,7 +239,7 @@ export function PromptInput({
|
|
|
308
239
|
// following cell — pass hasTrailingContent=true so it rolls to row N+1
|
|
309
240
|
// exactly as ink wraps the trailing space.
|
|
310
241
|
? caretPosition(d.value, d.cursor, contentWidth, d.cursor >= d.value.length ? true : undefined)
|
|
311
|
-
: { row: 0, col:
|
|
242
|
+
: { row: 0, col: displayWidth(d.value.slice(0, d.cursor)) };
|
|
312
243
|
return w > 0
|
|
313
244
|
? { ...caret, col: caret.col + guardColumns }
|
|
314
245
|
: caret;
|
|
@@ -1064,19 +995,10 @@ export function PromptInput({
|
|
|
1064
995
|
const hintMeta = hintStyle(hintTone);
|
|
1065
996
|
// Monotone voice indicator glyph text — zero-width (rendered as null) when
|
|
1066
997
|
// mode is 'off'. Braille frame drives installing/recording/transcribing;
|
|
1067
|
-
//
|
|
1068
|
-
|
|
1069
|
-
const voiceBrailleFrame = VOICE_BRAILLE_FRAMES[voiceTick % VOICE_BRAILLE_FRAMES.length];
|
|
1070
|
-
const voiceIdleFrame = VOICE_IDLE_FRAMES[Math.floor(voiceTick / VOICE_IDLE_FRAME_TICKS) % VOICE_IDLE_FRAMES.length];
|
|
1071
|
-
const voiceIndicatorText = voiceIndicatorMode === 'installing' || voiceIndicatorMode === 'transcribing'
|
|
1072
|
-
? voiceBrailleFrame
|
|
1073
|
-
: voiceIndicatorMode === 'recording'
|
|
1074
|
-
? `◉${voiceBrailleFrame}`
|
|
1075
|
-
: voiceIndicatorMode === 'idle'
|
|
1076
|
-
? voiceIdleFrame
|
|
1077
|
-
: '';
|
|
998
|
+
// 'idle' is a static ○ (no animation, no timer).
|
|
999
|
+
const voiceIndicatorText = voiceIndicatorTextFor(voiceIndicatorMode, voiceTick);
|
|
1078
1000
|
// stringWidth is unnecessary here — every glyph above is a single
|
|
1079
|
-
// 1-column codepoint (
|
|
1001
|
+
// 1-column codepoint (○ ● and the braille frames), and 'recording'
|
|
1080
1002
|
// concatenates exactly two 1-cell glyphs, so plain .length gives the
|
|
1081
1003
|
// correct cell count without pulling in emoji-width special-casing.
|
|
1082
1004
|
voiceIndicatorWidthRef.current = voiceIndicatorText.length;
|
|
@@ -60,7 +60,11 @@ export function SlashCommandPalette({ commands, selectedIndex = 0, title = 'Comm
|
|
|
60
60
|
start = Math.max(0, end - MAX_VISIBLE);
|
|
61
61
|
}
|
|
62
62
|
const visible = commands.slice(start, end);
|
|
63
|
-
|
|
63
|
+
// No-match frames keep the palette mounted at the SAME fixed height so the
|
|
64
|
+
// slash session never unmounts/remounts the 14-row panel per keystroke
|
|
65
|
+
// (Windows fullscreen repaint made that oscillation a hard flicker).
|
|
66
|
+
const noMatches = total === 0;
|
|
67
|
+
const blankRows = Math.max(0, MAX_VISIBLE - visible.length - (noMatches ? 1 : 0));
|
|
64
68
|
const labelWidth = Math.max(12, Math.min(COMMAND_LABEL_WIDTH, Math.max(12, Math.floor(columns * 0.45))));
|
|
65
69
|
const descriptionWidth = Math.max(0, columns - labelWidth - 12);
|
|
66
70
|
// Standard panel rhythm: title row, blank, description/hint row, blank, content.
|
|
@@ -84,6 +88,9 @@ export function SlashCommandPalette({ commands, selectedIndex = 0, title = 'Comm
|
|
|
84
88
|
<Text> </Text>
|
|
85
89
|
<Text color={theme.subtle}>{description || ' '}</Text>
|
|
86
90
|
<Text> </Text>
|
|
91
|
+
{noMatches ? (
|
|
92
|
+
<Text color={theme.subtle} wrap="truncate">No matching commands</Text>
|
|
93
|
+
) : null}
|
|
87
94
|
{visible.map((item, index) => (
|
|
88
95
|
<CommandRow
|
|
89
96
|
key={item.name}
|
|
@@ -482,6 +482,29 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
482
482
|
Number(activeTools.search?.startedAt) || 0,
|
|
483
483
|
].join('|')
|
|
484
484
|
: '';
|
|
485
|
+
// Stable primitive signatures so the render effect's dep array doesn't
|
|
486
|
+
// churn on new array/object identities carrying unchanged content — a new
|
|
487
|
+
// `agentWorkers`/`agentJobs` array (or `stats` object) reference on every
|
|
488
|
+
// render was clearing the pending 150ms debounce timer before it could
|
|
489
|
+
// fire, starving the boot full-render. Only tag|stage per worker/job and
|
|
490
|
+
// the numeric stats fields actually consumed here are covered.
|
|
491
|
+
const agentWorkersSignature = Array.isArray(agentWorkers)
|
|
492
|
+
? agentWorkers.map((w) => `${w?.tag || w?.agent || w?.name || ''}|${w?.stage || w?.status || ''}|${localTimeMs(w?.startedAt || w?.startTime || w?.createdAt)}`).join(',')
|
|
493
|
+
: '';
|
|
494
|
+
const agentJobsSignature = Array.isArray(agentJobs)
|
|
495
|
+
? agentJobs.map((j) => `${j?.tag || j?.agent || j?.name || ''}|${j?.status || j?.stage || ''}|${localTimeMs(j?.startedAt || j?.startTime || j?.createdAt)}`).join(',')
|
|
496
|
+
: '';
|
|
497
|
+
const statsForSignature = stats && typeof stats === 'object' ? stats : {};
|
|
498
|
+
const statsSignature = [
|
|
499
|
+
localNum(statsForSignature.currentContextTokens),
|
|
500
|
+
localNum(statsForSignature.currentEstimatedContextTokens),
|
|
501
|
+
localNum(statsForSignature.inputTokens),
|
|
502
|
+
localNum(statsForSignature.latestInputTokens),
|
|
503
|
+
localNum(statsForSignature.promptTokens),
|
|
504
|
+
localNum(statsForSignature.turns),
|
|
505
|
+
localNum(statsForSignature.contextTokens),
|
|
506
|
+
String(statsForSignature.currentContextSource || ''),
|
|
507
|
+
].join('|');
|
|
485
508
|
const refreshMs = hasActiveStatuslineWork(line, agentWorkers, agentJobs, activeTools) ? STATUSLINE_ACTIVE_REFRESH_MS : STATUSLINE_REFRESH_MS;
|
|
486
509
|
|
|
487
510
|
useEffect(() => {
|
|
@@ -498,6 +521,7 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
498
521
|
|
|
499
522
|
useEffect(() => {
|
|
500
523
|
let alive = true;
|
|
524
|
+
let bootRetryTimer = null;
|
|
501
525
|
const effectId = renderEffectIdRef.current + 1;
|
|
502
526
|
renderEffectIdRef.current = effectId;
|
|
503
527
|
const isCurrentEffect = () => alive && renderEffectIdRef.current === effectId;
|
|
@@ -508,23 +532,27 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
508
532
|
lastImmediateArgsRef.current,
|
|
509
533
|
);
|
|
510
534
|
// ROUTE identity = the subset that actually changes the async full line's L1
|
|
511
|
-
// usage/quota segment (provider/model/session/effort/fast
|
|
512
|
-
//
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
516
|
-
//
|
|
517
|
-
//
|
|
535
|
+
// usage/quota segment (provider/model/session/effort/fast). agentRevision,
|
|
536
|
+
// compactBoundaryTokens, autoCompactTokenLimit, stats-reset AND the context
|
|
537
|
+
// window fields (contextWindow/displayContextWindow/rawContextWindow) are
|
|
538
|
+
// NON-ROUTE: the first prompt's API response publishes displayContextWindow
|
|
539
|
+
// 0→N (engine syncContextDisplayFields), which only moves the ctx% bar —
|
|
540
|
+
// never the `5H …/7D …` usage windows. Treating it as route wiped the cached
|
|
541
|
+
// full line and snapped to the usage-less local line for one frame (the
|
|
542
|
+
// "usage blinks once on first prompt" bug). A real route switch that changes
|
|
543
|
+
// usage windows always changes provider/model/session anyway. Only a true
|
|
544
|
+
// route/session switch may wipe the cached full line; non-route churn keeps
|
|
545
|
+
// the last good full line (identityChanged still snaps, but via the cached
|
|
546
|
+
// graft path below, so usage survives and the async render refreshes ctx%
|
|
547
|
+
// within ~150ms). (lastImmediateArgsRef holds these fields, captured at the
|
|
548
|
+
// end of the previous effect run.)
|
|
518
549
|
const prevImmediate = lastImmediateArgsRef.current;
|
|
519
550
|
const routeChanged = !prevImmediate
|
|
520
551
|
|| prevImmediate.sessionId !== args.sessionId
|
|
521
552
|
|| prevImmediate.provider !== args.provider
|
|
522
553
|
|| prevImmediate.model !== args.model
|
|
523
554
|
|| prevImmediate.effort !== args.effort
|
|
524
|
-
|| prevImmediate.fast !== args.fast
|
|
525
|
-
|| prevImmediate.contextWindow !== args.contextWindow
|
|
526
|
-
|| prevImmediate.displayContextWindow !== args.displayContextWindow
|
|
527
|
-
|| prevImmediate.rawContextWindow !== args.rawContextWindow;
|
|
555
|
+
|| prevImmediate.fast !== args.fast;
|
|
528
556
|
// A theme switch must re-tone the footer immediately: the stored `line`
|
|
529
557
|
// holds already-normalized ANSI with the OLD palette, so re-running
|
|
530
558
|
// normalizeStatusLine on it is a no-op. Force a fresh local rebuild (new
|
|
@@ -607,9 +635,31 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
607
635
|
const timer = setTimeout(() => {
|
|
608
636
|
if (bootFullDoneRef.current !== true) {
|
|
609
637
|
if (!bootFullRenderEligible(mountAtRef.current, lineRef.current, args.agentWorkers, args.agentJobs, args.activeTools)) {
|
|
638
|
+
// Not eligible yet (boot delay not elapsed). Don't just bail and wait
|
|
639
|
+
// for the next refreshTick interval (250ms/2000ms) — arm a follow-up
|
|
640
|
+
// timeout for the REMAINING boot delay so the first full render still
|
|
641
|
+
// fires on schedule instead of stalling/flickering until the next tick.
|
|
642
|
+
const active = hasActiveStatuslineWork(lineRef.current, args.agentWorkers, args.agentJobs, args.activeTools);
|
|
643
|
+
const bootDelay = active ? STATUSLINE_BOOT_FULL_DELAY_ACTIVE_MS : STATUSLINE_BOOT_FULL_DELAY_MS;
|
|
644
|
+
const elapsed = Date.now() - mountAtRef.current;
|
|
645
|
+
const remaining = Math.max(150, bootDelay - elapsed);
|
|
646
|
+
bootRetryTimer = setTimeout(() => {
|
|
647
|
+
if (!isCurrentEffect()) return;
|
|
648
|
+
setRefreshTick((tick) => (tick + 1) % 1_000_000);
|
|
649
|
+
}, remaining);
|
|
650
|
+
bootRetryTimer.unref?.();
|
|
610
651
|
return;
|
|
611
652
|
}
|
|
612
653
|
if (!canAttemptBootFullRender(bootFullNextAttemptAtRef.current)) {
|
|
654
|
+
// Backoff window not elapsed yet — arm a follow-up timeout for exactly
|
|
655
|
+
// the remaining backoff so the retry fires on time instead of waiting
|
|
656
|
+
// for the next refreshTick interval.
|
|
657
|
+
const remaining = Math.max(150, bootFullNextAttemptAtRef.current - Date.now());
|
|
658
|
+
bootRetryTimer = setTimeout(() => {
|
|
659
|
+
if (!isCurrentEffect()) return;
|
|
660
|
+
setRefreshTick((tick) => (tick + 1) % 1_000_000);
|
|
661
|
+
}, remaining);
|
|
662
|
+
bootRetryTimer.unref?.();
|
|
613
663
|
return;
|
|
614
664
|
}
|
|
615
665
|
}
|
|
@@ -644,8 +694,9 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
|
|
|
644
694
|
return () => {
|
|
645
695
|
alive = false;
|
|
646
696
|
clearTimeout(timer);
|
|
697
|
+
clearTimeout(bootRetryTimer);
|
|
647
698
|
};
|
|
648
|
-
}, [sessionId, clientHostPid, provider, model, effort, fast, cwd,
|
|
699
|
+
}, [sessionId, clientHostPid, provider, model, effort, fast, cwd, statsSignature, contextWindow, displayContextWindow, compactBoundaryTokens, autoCompactTokenLimit, rawContextWindow, resizeEpoch, agentRevision, agentWorkersSignature, agentJobsSignature, activeToolsSignature, refreshTick, themeEpoch]);
|
|
649
700
|
|
|
650
701
|
const lines = line ? line.split('\n').slice(0, 2) : [' ', ' '];
|
|
651
702
|
const workflowLabel = workflowModeLabel(workflow, remoteEnabled);
|
|
@@ -159,6 +159,7 @@ function isAnyModifiedEnterSequence(input) {
|
|
|
159
159
|
export function TextEntryPanel({
|
|
160
160
|
title,
|
|
161
161
|
hint = '',
|
|
162
|
+
detail = '',
|
|
162
163
|
initialValue = '',
|
|
163
164
|
mask = false,
|
|
164
165
|
columns = 80,
|
|
@@ -465,6 +466,10 @@ export function TextEntryPanel({
|
|
|
465
466
|
// The hint is collapsed to one line and width-truncated so a long manual
|
|
466
467
|
// OAuth URL can never wrap and push the bordered title off the top.
|
|
467
468
|
const hintText = truncateText(singleLine(hint), Math.max(0, columns - 4));
|
|
469
|
+
// Optional wrapped detail block (e.g. the manual OAuth URL). Lives INSIDE the
|
|
470
|
+
// live panel — never pushed to the transcript — so it disappears completely
|
|
471
|
+
// when the panel closes instead of lingering in terminal scrollback.
|
|
472
|
+
const detailText = String(detail || '').trim();
|
|
468
473
|
|
|
469
474
|
return (
|
|
470
475
|
<Box flexDirection="column" flexShrink={0} width="100%">
|
|
@@ -475,6 +480,12 @@ export function TextEntryPanel({
|
|
|
475
480
|
</Box>
|
|
476
481
|
<Text> </Text>
|
|
477
482
|
<Text color={theme.subtle}>{hintText || ' '}</Text>
|
|
483
|
+
{detailText ? (
|
|
484
|
+
<Box flexDirection="column" width="100%">
|
|
485
|
+
<Text> </Text>
|
|
486
|
+
<Text color={theme.subtle} wrap="wrap">{detailText}</Text>
|
|
487
|
+
</Box>
|
|
488
|
+
) : null}
|
|
478
489
|
<Text> </Text>
|
|
479
490
|
<Box ref={boxRef} flexDirection="row" width="100%" backgroundColor={surfaceBackground()}>
|
|
480
491
|
<Text color={theme.inactive}>{promptLabel}</Text>
|