@golba98/codexa 1.0.1 → 1.0.3
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 +391 -94
- package/package.json +14 -8
- package/src/app.tsx +196 -63
- package/src/commands/handler.ts +9 -4
- package/src/config/buildInfo.ts +3 -0
- package/src/config/launchArgs.ts +10 -0
- package/src/config/layeredConfig.ts +0 -0
- package/src/config/persistence.ts +51 -0
- package/src/config/runtimeConfig.ts +4 -0
- package/src/config/settings.ts +6 -13
- package/src/config/toml-serialize.ts +0 -0
- package/src/config/trustStore.ts +0 -0
- package/src/config/updateCheckCache.ts +63 -0
- package/src/core/attachments.ts +0 -0
- package/src/core/auth/codexAuth.ts +0 -0
- package/src/core/channel.ts +23 -0
- package/src/core/cleanupFastFail.ts +0 -0
- package/src/core/clipboard.ts +0 -0
- package/src/core/codex.ts +0 -0
- package/src/core/codexExecArgs.ts +0 -0
- package/src/core/codexLaunch.ts +0 -0
- package/src/core/codexPrompt.ts +0 -0
- package/src/core/executables/claudeExecutable.ts +0 -0
- package/src/core/executables/codexExecutable.ts +1 -0
- package/src/core/executables/executableResolver.ts +61 -43
- package/src/core/executables/geminiExecutable.ts +0 -0
- package/src/core/githubDiagnostics.ts +0 -0
- package/src/core/hollowResponseFormat.ts +0 -0
- package/src/core/inputDebug.ts +0 -0
- package/src/core/launchContext.ts +33 -33
- package/src/core/models/codexCapabilities.ts +0 -0
- package/src/core/models/codexModelCapabilities.ts +0 -0
- package/src/core/models/modelSpecs.ts +0 -0
- package/src/core/perf/profiler.ts +0 -0
- package/src/core/perf/renderDebug.ts +0 -0
- package/src/core/planStorage.ts +0 -0
- package/src/core/process/CommandRunner.ts +0 -0
- package/src/core/process/processValidation.ts +9 -5
- package/src/core/projectInstructions.ts +0 -0
- package/src/core/providerLauncher/launcher.ts +59 -42
- package/src/core/providerLauncher/registry.ts +0 -0
- package/src/core/providerLauncher/types.ts +0 -0
- package/src/core/providerLauncher/workspaceConfig.ts +0 -0
- package/src/core/providerRuntime/anthropic.ts +0 -0
- package/src/core/providerRuntime/capabilityProfile.ts +0 -0
- package/src/core/providerRuntime/claudeCodeDiscovery.ts +0 -0
- package/src/core/providerRuntime/contextMetadata.ts +0 -0
- package/src/core/providerRuntime/gemini.ts +0 -0
- package/src/core/providerRuntime/lmstudio.ts +0 -0
- package/src/core/providerRuntime/local.ts +0 -0
- package/src/core/providerRuntime/models.ts +0 -0
- package/src/core/providerRuntime/reasoning.ts +0 -0
- package/src/core/providerRuntime/registry.ts +0 -0
- package/src/core/providerRuntime/types.ts +0 -0
- package/src/core/providers/codexJsonStream.ts +0 -0
- package/src/core/providers/codexSubprocess.ts +0 -0
- package/src/core/providers/codexTranscript.ts +0 -0
- package/src/core/providers/openaiNative.ts +0 -0
- package/src/core/providers/registry.ts +0 -0
- package/src/core/providers/types.ts +0 -0
- package/src/core/terminal/startupClear.ts +20 -0
- package/src/core/terminal/terminalCapabilities.ts +0 -0
- package/src/core/terminal/terminalControl.ts +0 -0
- package/src/core/terminal/terminalSanitize.ts +0 -0
- package/src/core/terminal/terminalSelection.ts +0 -0
- package/src/core/terminal/terminalTitle.ts +0 -0
- package/src/core/updateCheck.ts +188 -0
- package/src/core/workspaceActivity.ts +0 -0
- package/src/core/workspaceGuard.ts +0 -0
- package/src/core/workspaceRoot.ts +0 -0
- package/src/exec.ts +0 -0
- package/src/headless/execArgs.ts +1 -0
- package/src/headless/execRunner.ts +0 -0
- package/src/index.tsx +13 -9
- package/src/session/appSession.ts +0 -0
- package/src/session/chatLifecycle.ts +0 -0
- package/src/session/liveRenderScheduler.ts +0 -0
- package/src/session/planFlow.ts +0 -0
- package/src/session/planTranscript.ts +0 -0
- package/src/session/promptRunSchedule.ts +0 -0
- package/src/session/types.ts +2 -1
- package/src/test/runtimeTestUtils.ts +0 -0
- package/src/types/react-dom.d.ts +0 -0
- package/src/ui/ActionRequiredBlock.tsx +5 -5
- package/src/ui/ActivityBars.tsx +3 -3
- package/src/ui/ActivityIndicator.tsx +6 -6
- package/src/ui/AgentBlock.tsx +6 -6
- package/src/ui/AnimatedStatusText.tsx +1 -1
- package/src/ui/AppShell.tsx +13 -5
- package/src/ui/AttachmentImportPanel.tsx +8 -8
- package/src/ui/AuthPanel.tsx +20 -20
- package/src/ui/BackendPicker.tsx +0 -0
- package/src/ui/BottomComposer.tsx +117 -78
- package/src/ui/DashCard.tsx +3 -3
- package/src/ui/Markdown.tsx +17 -17
- package/src/ui/ModePicker.tsx +0 -0
- package/src/ui/ModelPicker.tsx +0 -0
- package/src/ui/ModelPickerScreen.tsx +10 -10
- package/src/ui/ModelReasoningPicker.tsx +14 -14
- package/src/ui/Panel.tsx +3 -3
- package/src/ui/PermissionsPanel.tsx +0 -0
- package/src/ui/PlanActionPicker.tsx +6 -6
- package/src/ui/PlanReviewPanel.tsx +8 -8
- package/src/ui/ProviderPicker.tsx +18 -18
- package/src/ui/ReasoningPicker.tsx +0 -0
- package/src/ui/RunFooter.tsx +3 -3
- package/src/ui/SelectionPanel.tsx +4 -4
- package/src/ui/SettingsPanel.tsx +8 -8
- package/src/ui/Spinner.tsx +1 -1
- package/src/ui/StaticIntroItem.tsx +0 -0
- package/src/ui/StaticTranscriptItem.tsx +0 -0
- package/src/ui/TextEntryPanel.tsx +10 -10
- package/src/ui/ThemePicker.tsx +0 -0
- package/src/ui/ThinkingBlock.tsx +8 -8
- package/src/ui/Timeline.tsx +21 -17
- package/src/ui/TopHeader.tsx +421 -257
- package/src/ui/TurnGroup.tsx +31 -31
- package/src/ui/UpdateAvailableCard.tsx +41 -0
- package/src/ui/UpdatePromptPanel.tsx +203 -0
- package/src/ui/busyStatusAnimation.ts +0 -0
- package/src/ui/commandNormalize.ts +0 -0
- package/src/ui/diffRenderer.ts +0 -0
- package/src/ui/focus.ts +3 -0
- package/src/ui/inputBuffer.ts +0 -0
- package/src/ui/layout.ts +1 -1
- package/src/ui/logoVariants.ts +107 -0
- package/src/ui/modeDisplay.ts +12 -12
- package/src/ui/outputPipeline.ts +0 -0
- package/src/ui/progressEntries.ts +0 -0
- package/src/ui/runActivityView.ts +0 -0
- package/src/ui/runtimeDisplay.ts +100 -0
- package/src/ui/slashCommands.ts +0 -0
- package/src/ui/terminalAnswerFormat.ts +0 -0
- package/src/ui/textLayout.ts +0 -0
- package/src/ui/theme.tsx +274 -395
- package/src/ui/themeFlow.ts +0 -0
- package/src/ui/timelineMeasure.ts +29 -19
- package/src/ui/useThrottledValue.ts +0 -0
- package/scripts/audit-codexa-capabilities.mjs +0 -466
- package/scripts/smoke-terminal-bench.mjs +0 -35
- package/src/appRenderStability.test.ts +0 -131
- package/src/commands/handler.test.ts +0 -643
- package/src/config/launchArgs.test.ts +0 -158
- package/src/config/layeredConfig.test.ts +0 -143
- package/src/config/persistence.test.ts +0 -110
- package/src/config/runtimeConfig.test.ts +0 -218
- package/src/config/settings.test.ts +0 -155
- package/src/config/trustStore.test.ts +0 -29
- package/src/core/attachments.test.ts +0 -155
- package/src/core/auth/codexAuth.test.ts +0 -68
- package/src/core/cleanupFastFail.test.ts +0 -76
- package/src/core/codexExecArgs.test.ts +0 -195
- package/src/core/codexLaunch.test.ts +0 -205
- package/src/core/codexPrompt.test.ts +0 -252
- package/src/core/executables/codexExecutable.test.ts +0 -212
- package/src/core/executables/executableResolver.test.ts +0 -129
- package/src/core/executables/geminiExecutable.test.ts +0 -116
- package/src/core/executables/pathSanityScan.test.ts +0 -47
- package/src/core/githubDiagnostics.test.ts +0 -92
- package/src/core/hollowResponseFormat.test.ts +0 -58
- package/src/core/launchContext.test.ts +0 -157
- package/src/core/models/codexCapabilities.test.ts +0 -45
- package/src/core/models/codexModelCapabilities.test.ts +0 -246
- package/src/core/models/modelSpecs.test.ts +0 -283
- package/src/core/perf/renderDebug.test.ts +0 -230
- package/src/core/planStorage.test.ts +0 -143
- package/src/core/process/CommandRunner.test.ts +0 -105
- package/src/core/projectInstructions.test.ts +0 -50
- package/src/core/providerLauncher/launcher.test.ts +0 -238
- package/src/core/providerLauncher/registry.test.ts +0 -324
- package/src/core/providerLauncher/workspaceConfig.test.ts +0 -638
- package/src/core/providerRuntime/anthropic.test.ts +0 -1120
- package/src/core/providerRuntime/capabilityProfile.test.ts +0 -311
- package/src/core/providerRuntime/contextMetadata.test.ts +0 -468
- package/src/core/providerRuntime/gemini.test.ts +0 -437
- package/src/core/providerRuntime/lmstudio.test.ts +0 -168
- package/src/core/providerRuntime/local.test.ts +0 -787
- package/src/core/providerRuntime/registry.test.ts +0 -233
- package/src/core/providers/codexJsonStream.test.ts +0 -148
- package/src/core/providers/codexSubprocess.test.ts +0 -68
- package/src/core/providers/codexTranscript.test.ts +0 -284
- package/src/core/terminal/terminalCapabilities.test.ts +0 -93
- package/src/core/terminal/terminalControl.test.ts +0 -75
- package/src/core/terminal/terminalSanitize.test.ts +0 -22
- package/src/core/terminal/terminalSelection.test.ts +0 -42
- package/src/core/terminal/terminalTitle.test.ts +0 -328
- package/src/core/workspaceActivity.test.ts +0 -163
- package/src/core/workspaceGuard.test.ts +0 -151
- package/src/core/workspaceRoot.test.ts +0 -23
- package/src/exec.test.ts +0 -13
- package/src/headless/execArgs.test.ts +0 -147
- package/src/headless/execRunner.test.ts +0 -434
- package/src/index.test.tsx +0 -618
- package/src/session/appSession.test.ts +0 -897
- package/src/session/chatLifecycle.test.ts +0 -64
- package/src/session/liveRenderScheduler.test.ts +0 -201
- package/src/session/planFlow.test.ts +0 -103
- package/src/session/planTranscript.test.ts +0 -65
- package/src/session/promptRunSchedule.test.ts +0 -36
- package/src/ui/ActivityIndicator.test.tsx +0 -58
- package/src/ui/AgentBlock.test.ts +0 -6
- package/src/ui/AnimatedStatusText.test.ts +0 -16
- package/src/ui/AppShell.test.tsx +0 -1739
- package/src/ui/AttachmentImportPanel.test.tsx +0 -204
- package/src/ui/BottomComposer.test.ts +0 -674
- package/src/ui/CodexLogo.tsx +0 -55
- package/src/ui/Markdown.test.ts +0 -157
- package/src/ui/ModelPickerProviderScope.test.tsx +0 -411
- package/src/ui/ModelPickerScreen.test.tsx +0 -99
- package/src/ui/ModelPickerState.test.tsx +0 -151
- package/src/ui/ModelReasoningPicker.test.tsx +0 -447
- package/src/ui/PlanReviewPanel.test.tsx +0 -267
- package/src/ui/PromptCardBorder.test.tsx +0 -161
- package/src/ui/ProviderPicker.test.tsx +0 -289
- package/src/ui/ProviderShortcut.test.tsx +0 -143
- package/src/ui/SettingsPanel.test.tsx +0 -233
- package/src/ui/Timeline.test.ts +0 -2067
- package/src/ui/TimelineNavigation.test.tsx +0 -201
- package/src/ui/TopHeader.test.tsx +0 -239
- package/src/ui/TurnGroup.test.tsx +0 -365
- package/src/ui/busyStatusAnimation.test.ts +0 -30
- package/src/ui/commandNormalize.test.ts +0 -142
- package/src/ui/diffRenderer.test.ts +0 -102
- package/src/ui/focusFlow.test.tsx +0 -1098
- package/src/ui/inputBuffer.test.ts +0 -151
- package/src/ui/layout.test.ts +0 -145
- package/src/ui/modeDisplay.test.ts +0 -42
- package/src/ui/runActivityView.test.ts +0 -89
- package/src/ui/runLifecycleView.test.tsx +0 -237
- package/src/ui/statusRenderIsolation.test.tsx +0 -654
- package/src/ui/terminalAnswerFormat.test.ts +0 -19
- package/src/ui/textLayout.test.ts +0 -18
- package/src/ui/themeFlow.test.ts +0 -53
- package/src/ui/timelineMeasureCache.test.ts +0 -986
|
@@ -98,10 +98,12 @@ export function getTokenBarDisplay(tokensUsed: number, modelSpec: ModelSpec) {
|
|
|
98
98
|
interface BottomComposerProps {
|
|
99
99
|
layout: Layout;
|
|
100
100
|
uiState: UIState;
|
|
101
|
-
themeName?: string;
|
|
102
|
-
mode?: string;
|
|
103
|
-
model?: string;
|
|
104
|
-
|
|
101
|
+
themeName?: string;
|
|
102
|
+
mode?: string;
|
|
103
|
+
model?: string;
|
|
104
|
+
footerModelDisplay?: string;
|
|
105
|
+
reasoningLevel?: string;
|
|
106
|
+
contextDisplay?: string;
|
|
105
107
|
planMode?: boolean;
|
|
106
108
|
showBusyLoader?: boolean;
|
|
107
109
|
tokensUsed?: number;
|
|
@@ -236,7 +238,7 @@ export function measureBottomComposerRows({
|
|
|
236
238
|
|
|
237
239
|
// ALWAYS reserve 1 row for the status line to prevent height shifting between idle and busy states.
|
|
238
240
|
const statusLineReservedRows = 1;
|
|
239
|
-
const showMetadata = layout.mode !== "micro"
|
|
241
|
+
const showMetadata = layout.mode !== "micro";
|
|
240
242
|
const bottomPadding = layout.mode === "micro" || layout.rows <= 24 ? 0 : 1;
|
|
241
243
|
const footerGapRows = getComposerToFooterGapRows(layout);
|
|
242
244
|
|
|
@@ -338,13 +340,53 @@ function getPlaceholder(persona: ComposerPersona): string {
|
|
|
338
340
|
|
|
339
341
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
340
342
|
|
|
343
|
+
function renderFooterRuntime(displayStr: string, theme: any) {
|
|
344
|
+
// e.g. "Claude Code CLI / Sonnet 4.6 (Low)"
|
|
345
|
+
const slashIndex = displayStr.indexOf("/");
|
|
346
|
+
if (slashIndex === -1) {
|
|
347
|
+
return <Text color={theme.model} wrap="truncate">{displayStr}</Text>;
|
|
348
|
+
}
|
|
349
|
+
const providerPart = displayStr.substring(0, slashIndex).trim();
|
|
350
|
+
let remaining = displayStr.substring(slashIndex + 1).trim();
|
|
351
|
+
|
|
352
|
+
const parenIndex = remaining.indexOf("(");
|
|
353
|
+
if (parenIndex === -1) {
|
|
354
|
+
return (
|
|
355
|
+
<Box flexDirection="row" overflow="hidden">
|
|
356
|
+
<Text color={theme.provider}>{providerPart}</Text>
|
|
357
|
+
<Text color={theme.textMuted}>{" / "}</Text>
|
|
358
|
+
<Text color={theme.model}>{remaining}</Text>
|
|
359
|
+
</Box>
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const modelPart = remaining.substring(0, parenIndex).trim();
|
|
364
|
+
let reasoningPart = remaining.substring(parenIndex + 1).trim();
|
|
365
|
+
if (reasoningPart.endsWith(")")) {
|
|
366
|
+
reasoningPart = reasoningPart.substring(0, reasoningPart.length - 1).trim();
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return (
|
|
370
|
+
<Box flexDirection="row" overflow="hidden">
|
|
371
|
+
<Text color={theme.provider}>{providerPart}</Text>
|
|
372
|
+
<Text color={theme.textMuted}>{" / "}</Text>
|
|
373
|
+
<Text color={theme.model}>{modelPart}</Text>
|
|
374
|
+
<Text color={theme.textMuted}>{" ("}</Text>
|
|
375
|
+
<Text color={theme.accentMuted}>{reasoningPart}</Text>
|
|
376
|
+
<Text color={theme.textMuted}>{")"}</Text>
|
|
377
|
+
</Box>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
341
381
|
export function BottomComposer({
|
|
342
382
|
layout,
|
|
343
383
|
uiState,
|
|
344
|
-
themeName = "purple",
|
|
345
|
-
mode = "",
|
|
346
|
-
model = "",
|
|
347
|
-
|
|
384
|
+
themeName = "purple",
|
|
385
|
+
mode = "",
|
|
386
|
+
model = "",
|
|
387
|
+
footerModelDisplay,
|
|
388
|
+
reasoningLevel = "",
|
|
389
|
+
contextDisplay,
|
|
348
390
|
planMode = false,
|
|
349
391
|
showBusyLoader = true,
|
|
350
392
|
tokensUsed = 0,
|
|
@@ -807,16 +849,12 @@ export function BottomComposer({
|
|
|
807
849
|
}
|
|
808
850
|
}, { isActive: isFocused });
|
|
809
851
|
|
|
810
|
-
const
|
|
811
|
-
const
|
|
812
|
-
const
|
|
813
|
-
: tokenDisplay.percentage >= 90 ? theme.ERROR
|
|
814
|
-
: tokenDisplay.percentage >= 70 ? theme.WARNING
|
|
815
|
-
: theme.SUCCESS;
|
|
816
|
-
const reasoningSuffix = reasoningLevel ? ` (${reasoningLevel})` : "";
|
|
852
|
+
const tokenDisplay = getTokenBarDisplay(tokensUsed, modelSpec);
|
|
853
|
+
const reasoningSuffix = reasoningLevel ? ` (${reasoningLevel})` : "";
|
|
854
|
+
const footerRuntimeDisplay = footerModelDisplay ?? `${model}${reasoningSuffix}`;
|
|
817
855
|
const isAnswerMode = persona === "answer";
|
|
818
856
|
const showBusyFooter = shouldRenderBusyFooter(layout, uiState);
|
|
819
|
-
const promptPrefixColor = inputLocked ? theme.
|
|
857
|
+
const promptPrefixColor = inputLocked ? theme.textDim : theme.text;
|
|
820
858
|
const lockedInputText = promptViewport.visibleRows[0]?.text ?? " ";
|
|
821
859
|
|
|
822
860
|
// The prompt line is shared between bordered and non-bordered layouts.
|
|
@@ -826,12 +864,12 @@ export function BottomComposer({
|
|
|
826
864
|
<Box flexDirection="column" flexGrow={1}>
|
|
827
865
|
{value.length === 0 && !inputLocked ? (
|
|
828
866
|
<Box width="100%" overflow="hidden">
|
|
829
|
-
<Text backgroundColor={cursorVisible ? theme.
|
|
830
|
-
<Text color={theme.
|
|
867
|
+
<Text backgroundColor={cursorVisible ? theme.text : undefined} color={cursorVisible ? theme.surface : undefined}>{" "}</Text>
|
|
868
|
+
<Text color={theme.textDim}>{placeholderText}</Text>
|
|
831
869
|
</Box>
|
|
832
870
|
) : inputLocked ? (
|
|
833
871
|
<Box key="busy-locked-input" width="100%" overflow="hidden">
|
|
834
|
-
<Text color={theme.
|
|
872
|
+
<Text color={theme.textDim}>{lockedInputText || " "}</Text>
|
|
835
873
|
</Box>
|
|
836
874
|
) : (
|
|
837
875
|
promptViewport.visibleRows.map((row, index) => {
|
|
@@ -845,14 +883,14 @@ export function BottomComposer({
|
|
|
845
883
|
<Box key={`${row.start}-${row.end}-${index}`} width="100%" overflow="hidden">
|
|
846
884
|
{isCursorRow && segments ? (
|
|
847
885
|
<>
|
|
848
|
-
<Text color={theme.
|
|
849
|
-
<Text backgroundColor={cursorVisible ? theme.
|
|
886
|
+
<Text color={theme.text}>{segments.before}</Text>
|
|
887
|
+
<Text backgroundColor={cursorVisible ? theme.text : undefined} color={cursorVisible ? theme.surface : undefined}>
|
|
850
888
|
{segments.current || " "}
|
|
851
889
|
</Text>
|
|
852
|
-
<Text color={theme.
|
|
890
|
+
<Text color={theme.text}>{segments.after}</Text>
|
|
853
891
|
</>
|
|
854
892
|
) : (
|
|
855
|
-
<Text color={theme.
|
|
893
|
+
<Text color={theme.text}>{row.text || " "}</Text>
|
|
856
894
|
)}
|
|
857
895
|
</Box>
|
|
858
896
|
);
|
|
@@ -876,27 +914,57 @@ export function BottomComposer({
|
|
|
876
914
|
paddingX={1}
|
|
877
915
|
paddingY={0}
|
|
878
916
|
borderStyle="round"
|
|
879
|
-
borderColor={theme.
|
|
917
|
+
borderColor={theme.warning}
|
|
880
918
|
>
|
|
881
919
|
{promptLine}
|
|
882
920
|
</Box>
|
|
883
|
-
) : (
|
|
884
|
-
// Normal mode: clean prompt in rounded border
|
|
885
|
-
<Box
|
|
886
|
-
flexDirection="column"
|
|
921
|
+
) : (
|
|
922
|
+
// Normal mode: clean prompt in rounded border
|
|
923
|
+
<Box
|
|
924
|
+
flexDirection="column"
|
|
887
925
|
width="100%"
|
|
888
926
|
paddingX={1}
|
|
889
927
|
paddingY={0}
|
|
890
928
|
borderStyle="round"
|
|
891
|
-
borderColor={theme.
|
|
929
|
+
borderColor={theme.border}
|
|
892
930
|
>
|
|
893
|
-
{promptLine}
|
|
894
|
-
</Box>
|
|
895
|
-
)}
|
|
896
|
-
|
|
897
|
-
{
|
|
898
|
-
<Box paddingLeft={1} marginTop={0} width="100%"
|
|
899
|
-
<
|
|
931
|
+
{promptLine}
|
|
932
|
+
</Box>
|
|
933
|
+
)}
|
|
934
|
+
|
|
935
|
+
{layoutMode !== "micro" && (
|
|
936
|
+
<Box paddingLeft={1} paddingRight={1} marginTop={0} width="100%" justifyContent="space-between">
|
|
937
|
+
<Box flexGrow={1} flexShrink={1} overflow="hidden">
|
|
938
|
+
{renderFooterRuntime(footerRuntimeDisplay, theme)}
|
|
939
|
+
</Box>
|
|
940
|
+
<Box flexShrink={0}>
|
|
941
|
+
{contextDisplay ? (
|
|
942
|
+
<Box flexDirection="row">
|
|
943
|
+
<Text color={theme.textMuted}>Context: </Text>
|
|
944
|
+
<Text color={theme.context}>{contextDisplay}</Text>
|
|
945
|
+
</Box>
|
|
946
|
+
) : tokenDisplay.hasKnownLimit ? (
|
|
947
|
+
<Box flexDirection="row">
|
|
948
|
+
<Text color={theme.textMuted}>Context: </Text>
|
|
949
|
+
<Text color={theme.context}>{tokenDisplay.usedText}</Text>
|
|
950
|
+
<Text color={theme.textDim}>
|
|
951
|
+
{" / "}{tokenDisplay.limitText}
|
|
952
|
+
{tokenDisplay.percentage !== null ? ` · ${tokenDisplay.isEstimatedLimit ? "~" : ""}${tokenDisplay.percentage}%` : ""}
|
|
953
|
+
</Text>
|
|
954
|
+
</Box>
|
|
955
|
+
) : (
|
|
956
|
+
<Box flexDirection="row">
|
|
957
|
+
<Text color={theme.textMuted}>Context: </Text>
|
|
958
|
+
<Text color={theme.textDim}>Unknown</Text>
|
|
959
|
+
</Box>
|
|
960
|
+
)}
|
|
961
|
+
</Box>
|
|
962
|
+
</Box>
|
|
963
|
+
)}
|
|
964
|
+
|
|
965
|
+
{commandSuggestionState.reserveSuggestionRow && (
|
|
966
|
+
<Box paddingLeft={1} marginTop={0} width="100%" overflow="hidden">
|
|
967
|
+
<Text color={theme.textDim} wrap="truncate">{suggestionText || " "}</Text>
|
|
900
968
|
</Box>
|
|
901
969
|
)}
|
|
902
970
|
|
|
@@ -911,7 +979,7 @@ export function BottomComposer({
|
|
|
911
979
|
<Box flexShrink={1} flexGrow={1} overflow="hidden" flexDirection="row">
|
|
912
980
|
{!!getExternalCliLabel(activeProviderId ?? "") && uiState.kind === "THINKING" && (
|
|
913
981
|
<>
|
|
914
|
-
<Spinner color={theme.
|
|
982
|
+
<Spinner color={theme.accent} />
|
|
915
983
|
<Text>{" "}</Text>
|
|
916
984
|
</>
|
|
917
985
|
)}
|
|
@@ -923,52 +991,21 @@ export function BottomComposer({
|
|
|
923
991
|
</Box>
|
|
924
992
|
{inputLocked && (
|
|
925
993
|
<Box flexShrink={0}>
|
|
926
|
-
<Text color={theme.
|
|
994
|
+
<Text color={theme.textDim}>Esc cancel Ctrl+C quit</Text>
|
|
927
995
|
</Box>
|
|
928
996
|
)}
|
|
929
997
|
{!inputLocked && selectionProfile && (
|
|
930
998
|
<Box flexShrink={0}>
|
|
931
|
-
<Text color={theme.
|
|
999
|
+
<Text color={theme.textDim}>{selectionProfile.shortHint}</Text>
|
|
932
1000
|
</Box>
|
|
933
1001
|
)}
|
|
934
1002
|
</>
|
|
935
1003
|
)}
|
|
936
1004
|
</Box>
|
|
937
1005
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
<Text
|
|
942
|
-
color={modeDisplay.ringColor}
|
|
943
|
-
backgroundColor={modeDisplay.ringFill}
|
|
944
|
-
bold={modeDisplay.ringBold}
|
|
945
|
-
>
|
|
946
|
-
{modeDisplay.ringGlyph}
|
|
947
|
-
</Text>
|
|
948
|
-
<Text color={theme.DIM}>{" "}</Text>
|
|
949
|
-
<Text color={modeDisplay.labelColor} bold={modeDisplay.labelBold}>{modeDisplay.label}</Text>
|
|
950
|
-
<Text color={theme.DIM}>{" "}{model}{reasoningSuffix}{" Ctrl+O Ctrl+Alt+P"}</Text>
|
|
951
|
-
{planMode && <Text color={theme.ACCENT}>{" Plan"}</Text>}
|
|
952
|
-
</Box>
|
|
953
|
-
<Box flexShrink={0}>
|
|
954
|
-
{tokenDisplay.hasKnownLimit ? (
|
|
955
|
-
<>
|
|
956
|
-
<Text color={theme.DIM}>Context: </Text>
|
|
957
|
-
<Text color={theme.TEXT}>{tokenDisplay.usedText}</Text>
|
|
958
|
-
<Text color={theme.DIM}>
|
|
959
|
-
{" / "}{tokenDisplay.limitText}
|
|
960
|
-
{tokenDisplay.percentage !== null ? ` · ${tokenDisplay.isEstimatedLimit ? "~" : ""}${tokenDisplay.percentage}%` : ""}
|
|
961
|
-
</Text>
|
|
962
|
-
</>
|
|
963
|
-
) : (
|
|
964
|
-
<Text color={theme.DIM}>Context: Unknown</Text>
|
|
965
|
-
)}
|
|
966
|
-
</Box>
|
|
967
|
-
</Box>
|
|
968
|
-
)}
|
|
969
|
-
</Box>
|
|
970
|
-
);
|
|
971
|
-
}
|
|
1006
|
+
</Box>
|
|
1007
|
+
);
|
|
1008
|
+
}
|
|
972
1009
|
|
|
973
1010
|
// Helper to extract the relevant uiState kind for comparison
|
|
974
1011
|
function getUiStateKey(uiState: UIState): string {
|
|
@@ -1000,10 +1037,12 @@ export const MemoizedBottomComposer = memo(BottomComposer, (prev, next) => {
|
|
|
1000
1037
|
if (prev.value !== next.value) return false;
|
|
1001
1038
|
if (prev.cursor !== next.cursor) return false;
|
|
1002
1039
|
|
|
1003
|
-
// Re-render if display props change
|
|
1004
|
-
if (prev.mode !== next.mode) return false;
|
|
1005
|
-
if (prev.model !== next.model) return false;
|
|
1006
|
-
if (prev.
|
|
1040
|
+
// Re-render if display props change
|
|
1041
|
+
if (prev.mode !== next.mode) return false;
|
|
1042
|
+
if (prev.model !== next.model) return false;
|
|
1043
|
+
if (prev.footerModelDisplay !== next.footerModelDisplay) return false;
|
|
1044
|
+
if (prev.reasoningLevel !== next.reasoningLevel) return false;
|
|
1045
|
+
if (prev.contextDisplay !== next.contextDisplay) return false;
|
|
1007
1046
|
if (prev.planMode !== next.planMode) return false;
|
|
1008
1047
|
if (prev.showBusyLoader !== next.showBusyLoader) return false;
|
|
1009
1048
|
if (prev.tokensUsed !== next.tokensUsed) return false;
|
package/src/ui/DashCard.tsx
CHANGED
|
@@ -24,9 +24,9 @@ export function DashCard({
|
|
|
24
24
|
children,
|
|
25
25
|
}: DashCardProps) {
|
|
26
26
|
const theme = useTheme();
|
|
27
|
-
const border = borderColor ?? theme.
|
|
28
|
-
const tColor = titleColor ?? theme.
|
|
29
|
-
const bColor = badgeColor ?? theme.
|
|
27
|
+
const border = borderColor ?? theme.border;
|
|
28
|
+
const tColor = titleColor ?? theme.textMuted;
|
|
29
|
+
const bColor = badgeColor ?? theme.textDim;
|
|
30
30
|
|
|
31
31
|
// Account for AppShell gutter (-1) and Timeline paddingX={1} (-2)
|
|
32
32
|
const w = cols - 3;
|
package/src/ui/Markdown.tsx
CHANGED
|
@@ -131,7 +131,7 @@ function InlineText({ parts, color }: { parts: InlinePart[]; color: string }) {
|
|
|
131
131
|
return (
|
|
132
132
|
<Text color={color} wrap="wrap">
|
|
133
133
|
{parts.map((part, index) => {
|
|
134
|
-
if (part.kind === "code") return <Text key={index} color={theme.
|
|
134
|
+
if (part.kind === "code") return <Text key={index} color={theme.info}>{part.text}</Text>;
|
|
135
135
|
if (part.kind === "bold") return <Text key={index} bold>{part.text}</Text>;
|
|
136
136
|
return <Text key={index}>{part.text}</Text>;
|
|
137
137
|
})}
|
|
@@ -148,7 +148,7 @@ function renderTreeLabel(label: string, theme: ReturnType<typeof useTheme>) {
|
|
|
148
148
|
|
|
149
149
|
if (isDirectory) {
|
|
150
150
|
return (
|
|
151
|
-
<Text color={theme.
|
|
151
|
+
<Text color={theme.text} bold>
|
|
152
152
|
{base}
|
|
153
153
|
{slash}
|
|
154
154
|
</Text>
|
|
@@ -156,9 +156,9 @@ function renderTreeLabel(label: string, theme: ReturnType<typeof useTheme>) {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
return (
|
|
159
|
-
<Text color={theme.
|
|
159
|
+
<Text color={theme.text}>
|
|
160
160
|
{base.slice(0, lastDot)}
|
|
161
|
-
<Text color={theme.
|
|
161
|
+
<Text color={theme.textDim}>{base.slice(lastDot)}</Text>
|
|
162
162
|
</Text>
|
|
163
163
|
);
|
|
164
164
|
}
|
|
@@ -171,7 +171,7 @@ function TreeLine({ line }: { line: string }) {
|
|
|
171
171
|
|
|
172
172
|
return (
|
|
173
173
|
<Box width="100%">
|
|
174
|
-
<Text color={theme.
|
|
174
|
+
<Text color={theme.textDim}>{prefix}</Text>
|
|
175
175
|
{renderTreeLabel(label, theme)}
|
|
176
176
|
</Box>
|
|
177
177
|
);
|
|
@@ -184,17 +184,17 @@ function isTreeLine(line: string): boolean {
|
|
|
184
184
|
function getDiffColor(kind: DiffRenderLineType, theme: ReturnType<typeof useTheme>): string {
|
|
185
185
|
switch (kind) {
|
|
186
186
|
case "add":
|
|
187
|
-
return theme.
|
|
187
|
+
return theme.success;
|
|
188
188
|
case "remove":
|
|
189
|
-
return theme.
|
|
189
|
+
return theme.error;
|
|
190
190
|
case "hunk":
|
|
191
|
-
return theme.
|
|
191
|
+
return theme.accent;
|
|
192
192
|
case "file":
|
|
193
193
|
case "meta":
|
|
194
|
-
return theme.
|
|
194
|
+
return theme.info;
|
|
195
195
|
case "context":
|
|
196
196
|
default:
|
|
197
|
-
return theme.
|
|
197
|
+
return theme.textMuted;
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
@@ -245,9 +245,9 @@ export function RenderMessage({ segments, width, brightHeadings = false }: { seg
|
|
|
245
245
|
) : (
|
|
246
246
|
<Box key={lineIndex}>
|
|
247
247
|
<Box width={3} flexShrink={0} marginRight={1} justifyContent="flex-end">
|
|
248
|
-
<Text color={theme.
|
|
248
|
+
<Text color={theme.textDim}>{lineIndex + 1}</Text>
|
|
249
249
|
</Box>
|
|
250
|
-
<Text color={theme.
|
|
250
|
+
<Text color={theme.textMuted} wrap="wrap">{line || " "}</Text>
|
|
251
251
|
</Box>
|
|
252
252
|
)
|
|
253
253
|
))}
|
|
@@ -257,10 +257,10 @@ export function RenderMessage({ segments, width, brightHeadings = false }: { seg
|
|
|
257
257
|
}
|
|
258
258
|
|
|
259
259
|
if (segment.type === "header") {
|
|
260
|
-
const color = segment.level === 1 ? theme.
|
|
260
|
+
const color = segment.level === 1 ? theme.accent : segment.level === 2 ? theme.text : (brightHeadings ? theme.text : theme.textMuted);
|
|
261
261
|
return (
|
|
262
262
|
<Box key={index} flexDirection="column" marginTop={marginTop}>
|
|
263
|
-
{segment.level <= 2 && <Text color={theme.
|
|
263
|
+
{segment.level <= 2 && <Text color={theme.border}>{"───"}</Text>}
|
|
264
264
|
<Box>
|
|
265
265
|
<Text color={color}>{segment.level <= 2 ? "✧ " : "• "}</Text>
|
|
266
266
|
<InlineText parts={segment.parts} color={color} />
|
|
@@ -274,9 +274,9 @@ export function RenderMessage({ segments, width, brightHeadings = false }: { seg
|
|
|
274
274
|
<Box key={index} flexDirection="column" marginTop={marginTop}>
|
|
275
275
|
{segment.items.map((item, itemIndex) => (
|
|
276
276
|
<Box key={itemIndex}>
|
|
277
|
-
<Text color={theme.
|
|
277
|
+
<Text color={theme.accent}>{segment.ordered ? `${item.num}. ` : "• "}</Text>
|
|
278
278
|
<Box flexGrow={1} flexShrink={1}>
|
|
279
|
-
<InlineText parts={item.parts} color={theme.
|
|
279
|
+
<InlineText parts={item.parts} color={theme.text} />
|
|
280
280
|
</Box>
|
|
281
281
|
</Box>
|
|
282
282
|
))}
|
|
@@ -295,7 +295,7 @@ export function RenderMessage({ segments, width, brightHeadings = false }: { seg
|
|
|
295
295
|
if (parts.length === 1 && parts[0]!.kind === "text" && !parts[0]!.text.trim()) {
|
|
296
296
|
return null;
|
|
297
297
|
}
|
|
298
|
-
return <InlineText key={lineIndex} parts={parts} color={theme.
|
|
298
|
+
return <InlineText key={lineIndex} parts={parts} color={theme.text} />;
|
|
299
299
|
})}
|
|
300
300
|
</Box>
|
|
301
301
|
);
|
package/src/ui/ModePicker.tsx
CHANGED
|
File without changes
|
package/src/ui/ModelPicker.tsx
CHANGED
|
File without changes
|
|
@@ -297,28 +297,28 @@ export function ModelPickerScreen({
|
|
|
297
297
|
<Box flexDirection="column" width={panelWidth}>
|
|
298
298
|
<Box
|
|
299
299
|
borderStyle="round"
|
|
300
|
-
borderColor={theme.
|
|
300
|
+
borderColor={theme.prompt}
|
|
301
301
|
paddingX={1}
|
|
302
302
|
paddingY={0}
|
|
303
303
|
width={panelWidth}
|
|
304
304
|
flexDirection="column"
|
|
305
305
|
>
|
|
306
306
|
<Box width="100%" overflow="hidden">
|
|
307
|
-
<Text color={theme.
|
|
307
|
+
<Text color={theme.accent} bold>{title}</Text>
|
|
308
308
|
</Box>
|
|
309
309
|
<Box width="100%" overflow="hidden">
|
|
310
|
-
<Text color={theme.
|
|
310
|
+
<Text color={theme.textMuted}>
|
|
311
311
|
{clampVisualText(routeText, innerWidth)}
|
|
312
312
|
</Text>
|
|
313
313
|
</Box>
|
|
314
314
|
<Box width="100%" overflow="hidden">
|
|
315
|
-
<Text color={reasoningUnavailable ? theme.
|
|
315
|
+
<Text color={reasoningUnavailable ? theme.textDim : theme.textMuted}>
|
|
316
316
|
{clampVisualText(reasoningText, innerWidth)}
|
|
317
317
|
</Text>
|
|
318
318
|
</Box>
|
|
319
319
|
{sourceMarker && (
|
|
320
320
|
<Box width="100%" overflow="hidden">
|
|
321
|
-
<Text color={theme.
|
|
321
|
+
<Text color={theme.textDim}>
|
|
322
322
|
{clampVisualText(sourceMarker, innerWidth)}
|
|
323
323
|
</Text>
|
|
324
324
|
</Box>
|
|
@@ -326,7 +326,7 @@ export function ModelPickerScreen({
|
|
|
326
326
|
|
|
327
327
|
<Box flexDirection="column" marginTop={0} width="100%">
|
|
328
328
|
{models.length === 0 ? (
|
|
329
|
-
<Text color={theme.
|
|
329
|
+
<Text color={theme.textMuted}>
|
|
330
330
|
{isLoading ? "Discovering models from the Codex runtime..." : (emptyMessage ?? "No models available.")}
|
|
331
331
|
</Text>
|
|
332
332
|
) : (
|
|
@@ -389,15 +389,15 @@ function ModelPickerRow({
|
|
|
389
389
|
return (
|
|
390
390
|
<Box width="100%" overflow="hidden">
|
|
391
391
|
<Box width={markerWidth} flexShrink={0}>
|
|
392
|
-
<Text color={isHighlighted ? theme.
|
|
392
|
+
<Text color={isHighlighted ? theme.accent : theme.textDim}>{isHighlighted ? ">" : " "}</Text>
|
|
393
393
|
</Box>
|
|
394
394
|
<Box width={nameWidth} flexShrink={0} overflow="hidden">
|
|
395
|
-
<Text color={isHighlighted ? theme.
|
|
395
|
+
<Text color={isHighlighted ? theme.text : theme.textMuted} bold={isHighlighted}>
|
|
396
396
|
{name}
|
|
397
397
|
</Text>
|
|
398
398
|
</Box>
|
|
399
399
|
<Box width={checkWidth} flexShrink={0}>
|
|
400
|
-
<Text color={theme.
|
|
400
|
+
<Text color={theme.textDim}>{isCurrent ? "✓" : " "}</Text>
|
|
401
401
|
</Box>
|
|
402
402
|
{pillWidth > 0 && (
|
|
403
403
|
<>
|
|
@@ -405,7 +405,7 @@ function ModelPickerRow({
|
|
|
405
405
|
<Text> </Text>
|
|
406
406
|
</Box>
|
|
407
407
|
<Box width={pillWidth} flexShrink={0} overflow="hidden">
|
|
408
|
-
<Text color={theme.
|
|
408
|
+
<Text color={theme.accent} bold>
|
|
409
409
|
{pillText}
|
|
410
410
|
</Text>
|
|
411
411
|
</Box>
|
|
@@ -290,18 +290,18 @@ function LoadingPickerView({
|
|
|
290
290
|
<Box flexDirection="column" width="100%">
|
|
291
291
|
<Box
|
|
292
292
|
borderStyle="round"
|
|
293
|
-
borderColor={theme.
|
|
293
|
+
borderColor={theme.border}
|
|
294
294
|
paddingX={2}
|
|
295
295
|
paddingY={0}
|
|
296
296
|
width="100%"
|
|
297
297
|
>
|
|
298
298
|
<Box flexDirection="column" width="100%">
|
|
299
299
|
<Box>
|
|
300
|
-
<Text color={theme.
|
|
301
|
-
<Text color={theme.
|
|
300
|
+
<Text color={theme.accent} bold>Select model </Text>
|
|
301
|
+
<Text color={theme.textMuted}>Esc cancel</Text>
|
|
302
302
|
</Box>
|
|
303
303
|
<Box marginTop={0}>
|
|
304
|
-
<Text color={theme.
|
|
304
|
+
<Text color={theme.textDim}>
|
|
305
305
|
{isLoading
|
|
306
306
|
? "Discovering models from the Codex runtime…"
|
|
307
307
|
: "No models available yet."}
|
|
@@ -353,18 +353,18 @@ function InteractivePickerView({
|
|
|
353
353
|
return (
|
|
354
354
|
<Box
|
|
355
355
|
borderStyle="round"
|
|
356
|
-
borderColor={theme.
|
|
356
|
+
borderColor={theme.borderFocused}
|
|
357
357
|
paddingX={2}
|
|
358
358
|
paddingY={0}
|
|
359
359
|
width="100%"
|
|
360
360
|
flexDirection="column"
|
|
361
361
|
>
|
|
362
362
|
<Box>
|
|
363
|
-
<Text color={theme.
|
|
364
|
-
<Text color={theme.
|
|
363
|
+
<Text color={theme.accent} bold>Select model </Text>
|
|
364
|
+
<Text color={theme.textMuted}>{subtitle}</Text>
|
|
365
365
|
</Box>
|
|
366
366
|
<Box marginTop={0}>
|
|
367
|
-
<Text color={theme.
|
|
367
|
+
<Text color={theme.textDim}>{reasoningHint}</Text>
|
|
368
368
|
</Box>
|
|
369
369
|
|
|
370
370
|
<Box
|
|
@@ -415,7 +415,7 @@ function ModelRow({
|
|
|
415
415
|
theme,
|
|
416
416
|
}: ModelRowProps) {
|
|
417
417
|
const cursorGlyph = isHighlighted ? "▸ " : " ";
|
|
418
|
-
const nameColor = isHighlighted ? theme.
|
|
418
|
+
const nameColor = isHighlighted ? theme.text : theme.textMuted;
|
|
419
419
|
const commitMark = isCommitted ? " ✓" : "";
|
|
420
420
|
const selectedIndex = availableLevels.findIndex((level) => level.id === selectedReasoning);
|
|
421
421
|
const name = model.label === model.model ? model.model : `${model.label} (${model.model})`;
|
|
@@ -423,10 +423,10 @@ function ModelRow({
|
|
|
423
423
|
const bars = availableLevels.map((level, i) => {
|
|
424
424
|
const isActive = i === selectedIndex;
|
|
425
425
|
const color = !interactive
|
|
426
|
-
? theme.
|
|
426
|
+
? theme.textDim
|
|
427
427
|
: isActive
|
|
428
|
-
? isHighlighted ? theme.
|
|
429
|
-
: theme.
|
|
428
|
+
? isHighlighted ? theme.accent : theme.text
|
|
429
|
+
: theme.textDim;
|
|
430
430
|
|
|
431
431
|
return (
|
|
432
432
|
<Text key={level.id} color={color} bold={isActive && isHighlighted && interactive}>
|
|
@@ -438,7 +438,7 @@ function ModelRow({
|
|
|
438
438
|
return (
|
|
439
439
|
<Box flexDirection="row" width="100%">
|
|
440
440
|
<Box width={3} flexShrink={0}>
|
|
441
|
-
<Text color={isHighlighted ? theme.
|
|
441
|
+
<Text color={isHighlighted ? theme.accent : theme.textDim}>{cursorGlyph}</Text>
|
|
442
442
|
</Box>
|
|
443
443
|
<Box flexGrow={1} flexDirection="row" paddingRight={1}>
|
|
444
444
|
<Box flexShrink={1}>
|
|
@@ -447,7 +447,7 @@ function ModelRow({
|
|
|
447
447
|
</Text>
|
|
448
448
|
</Box>
|
|
449
449
|
<Box flexShrink={0} paddingLeft={1}>
|
|
450
|
-
<Text color={theme.
|
|
450
|
+
<Text color={theme.textDim}>{commitMark}</Text>
|
|
451
451
|
</Box>
|
|
452
452
|
</Box>
|
|
453
453
|
<Box flexDirection="row" gap={1} flexShrink={0}>
|
package/src/ui/Panel.tsx
CHANGED
|
@@ -13,8 +13,8 @@ interface PanelProps {
|
|
|
13
13
|
|
|
14
14
|
export function Panel({ cols, title, rightTitle, borderColor, titleColor, children }: PanelProps) {
|
|
15
15
|
const theme = useTheme();
|
|
16
|
-
const cBorder = borderColor || theme.
|
|
17
|
-
const cTitle = titleColor || theme.
|
|
16
|
+
const cBorder = borderColor || theme.borderFocused;
|
|
17
|
+
const cTitle = titleColor || theme.text;
|
|
18
18
|
|
|
19
19
|
const leftLabel = ` ${title} `;
|
|
20
20
|
const rightLabel = rightTitle ? ` ${rightTitle} ` : "";
|
|
@@ -32,7 +32,7 @@ export function Panel({ cols, title, rightTitle, borderColor, titleColor, childr
|
|
|
32
32
|
{"╭─"}
|
|
33
33
|
<Text color={cTitle}>{leftLabel}</Text>
|
|
34
34
|
{"─".repeat(dashCount)}
|
|
35
|
-
{rightTitle && <Text color={theme.
|
|
35
|
+
{rightTitle && <Text color={theme.textDim}>{rightLabel}</Text>}
|
|
36
36
|
{"╮"}
|
|
37
37
|
</Text>
|
|
38
38
|
<Box
|
|
File without changes
|
|
@@ -85,10 +85,10 @@ export function PlanActionPicker({
|
|
|
85
85
|
const selected = index === selectedIndex;
|
|
86
86
|
return (
|
|
87
87
|
<Text key={row.value}>
|
|
88
|
-
<Text color={selected ? theme.
|
|
88
|
+
<Text color={selected ? theme.accent : theme.textDim}>
|
|
89
89
|
{selected ? "› " : vertical ? " " : ""}
|
|
90
90
|
</Text>
|
|
91
|
-
<Text color={selected ? theme.
|
|
91
|
+
<Text color={selected ? theme.text : theme.textMuted}>
|
|
92
92
|
{`[${row.key}] ${row.label}`}
|
|
93
93
|
</Text>
|
|
94
94
|
</Text>
|
|
@@ -98,7 +98,7 @@ export function PlanActionPicker({
|
|
|
98
98
|
if (vertical) {
|
|
99
99
|
return (
|
|
100
100
|
<Box flexDirection="column">
|
|
101
|
-
<Text color={isFocused ? theme.
|
|
101
|
+
<Text color={isFocused ? theme.text : theme.textMuted} bold={isFocused}>Plan ready</Text>
|
|
102
102
|
{ACTION_ROWS.map(renderAction)}
|
|
103
103
|
</Box>
|
|
104
104
|
);
|
|
@@ -106,12 +106,12 @@ export function PlanActionPicker({
|
|
|
106
106
|
|
|
107
107
|
return (
|
|
108
108
|
<Text>
|
|
109
|
-
<Text color={isFocused ? theme.
|
|
110
|
-
<Text color={theme.
|
|
109
|
+
<Text color={isFocused ? theme.text : theme.textMuted} bold={isFocused}>Plan ready</Text>
|
|
110
|
+
<Text color={theme.textDim}>{" "}</Text>
|
|
111
111
|
{ACTION_ROWS.map((row, index) => (
|
|
112
112
|
<React.Fragment key={row.value}>
|
|
113
113
|
{renderAction(row, index)}
|
|
114
|
-
{index < ACTION_ROWS.length - 1 && <Text color={theme.
|
|
114
|
+
{index < ACTION_ROWS.length - 1 && <Text color={theme.textDim}>{" "}</Text>}
|
|
115
115
|
</React.Fragment>
|
|
116
116
|
))}
|
|
117
117
|
</Text>
|