@golba98/codexa 1.0.3 → 1.0.5
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 +17 -18
- package/bin/codexa.js +62 -144
- package/package.json +4 -3
- package/src/app.tsx +642 -303
- package/src/commands/handler.ts +7 -18
- package/src/config/buildInfo.ts +2 -2
- package/src/config/layeredConfig.ts +1 -1
- package/src/config/runtimeConfig.ts +1 -1
- package/src/config/settings.ts +1 -1
- package/src/config/trustStore.ts +1 -1
- package/src/core/README.md +52 -0
- package/src/core/agent/loop.ts +282 -0
- package/src/core/agent/protocol.ts +211 -0
- package/src/core/agent/tools.ts +414 -0
- package/src/core/{codexExecArgs.ts → codex/codexExecArgs.ts} +2 -2
- package/src/core/{codexLaunch.ts → codex/codexLaunch.ts} +3 -3
- package/src/core/{codexPrompt.ts → codex/codexPrompt.ts} +3 -3
- package/src/core/debug/modelStateDebug.ts +34 -0
- package/src/core/executables/antigravityExecutable.ts +48 -0
- package/src/core/executables/executableResolver.ts +5 -1
- package/src/core/models/codexModelCapabilities.ts +57 -4
- package/src/core/models/codexModelsCacheSeed.ts +153 -0
- package/src/core/models/providerModelCache.ts +106 -0
- package/src/core/perf/renderDebug.ts +10 -6
- package/src/core/process/CommandRunner.ts +12 -1
- package/src/core/providerLauncher/registry.ts +64 -18
- package/src/core/providerLauncher/types.ts +12 -9
- package/src/core/providerLauncher/workspaceConfig.ts +41 -26
- package/src/core/providerRuntime/anthropic.ts +10 -6
- package/src/core/providerRuntime/antigravity.ts +461 -0
- package/src/core/providerRuntime/claudeCodeDiscovery.ts +724 -446
- package/src/core/providerRuntime/claudeCodeDiscoveryDebug.ts +55 -0
- package/src/core/providerRuntime/contextMetadata.ts +12 -24
- package/src/core/providerRuntime/local.ts +129 -51
- package/src/core/providerRuntime/mistralVibe.ts +663 -0
- package/src/core/providerRuntime/models.ts +40 -15
- package/src/core/providerRuntime/reasoning.ts +9 -6
- package/src/core/providerRuntime/registry.ts +76 -4
- package/src/core/providerRuntime/types.ts +20 -14
- package/src/core/providers/codexSubprocess.ts +2 -2
- package/src/core/providers/types.ts +1 -1
- package/src/core/{attachments.ts → shared/attachments.ts} +27 -4
- package/src/core/{cleanupFastFail.ts → shared/cleanupFastFail.ts} +1 -1
- package/src/core/{hollowResponseFormat.ts → shared/hollowResponseFormat.ts} +1 -1
- package/src/core/terminal/clearFrameBoundary.ts +814 -0
- package/src/core/terminal/frameLock.ts +109 -0
- package/src/core/terminal/inkRenderReset.ts +123 -0
- package/src/core/terminal/terminalControl.ts +22 -0
- package/src/core/terminal/terminalTitle.ts +16 -102
- package/src/core/{channel.ts → version/channel.ts} +1 -1
- package/src/core/{updateCheck.ts → version/updateCheck.ts} +10 -5
- package/src/core/{launchContext.ts → workspace/launchContext.ts} +9 -16
- package/src/core/{planStorage.ts → workspace/planStorage.ts} +2 -2
- package/src/core/{workspaceGuard.ts → workspace/workspaceGuard.ts} +97 -13
- package/src/headless/execRunner.ts +2 -2
- package/src/index.tsx +66 -98
- package/src/session/appSession.ts +10 -7
- package/src/session/chatLifecycle.ts +1 -1
- package/src/session/liveRenderScheduler.ts +1 -1
- package/src/session/types.ts +1 -1
- package/src/test/runtimeTestUtils.ts +90 -0
- package/src/ui/{ActivityBars.tsx → chrome/ActivityBars.tsx} +1 -1
- package/src/ui/{ActivityIndicator.tsx → chrome/ActivityIndicator.tsx} +3 -3
- package/src/ui/{AnimatedStatusText.tsx → chrome/AnimatedStatusText.tsx} +3 -3
- package/src/ui/chrome/AppShell.tsx +672 -0
- package/src/ui/{BottomComposer.tsx → chrome/BottomComposer.tsx} +159 -158
- package/src/ui/{DashCard.tsx → chrome/DashCard.tsx} +2 -2
- package/src/ui/{RunFooter.tsx → chrome/RunFooter.tsx} +3 -3
- package/src/ui/chrome/RuntimeStatusBar.tsx +108 -0
- package/src/ui/{Spinner.tsx → chrome/Spinner.tsx} +1 -1
- package/src/ui/{TopHeader.tsx → chrome/TopHeader.tsx} +54 -38
- package/src/ui/{UpdateAvailableCard.tsx → chrome/UpdateAvailableCard.tsx} +5 -5
- package/src/ui/{commandNormalize.ts → input/commandNormalize.ts} +1 -1
- package/src/ui/{focus.ts → input/focus.ts} +1 -1
- package/src/ui/{inputBuffer.ts → input/inputBuffer.ts} +3 -3
- package/src/ui/layout.ts +298 -24
- package/src/ui/{AttachmentImportPanel.tsx → panels/AttachmentImportPanel.tsx} +3 -3
- package/src/ui/{AuthPanel.tsx → panels/AuthPanel.tsx} +5 -5
- package/src/ui/{BackendPicker.tsx → panels/BackendPicker.tsx} +2 -2
- package/src/ui/{ModePicker.tsx → panels/ModePicker.tsx} +2 -2
- package/src/ui/{ModelPicker.tsx → panels/ModelPicker.tsx} +2 -2
- package/src/ui/{ModelPickerScreen.tsx → panels/ModelPickerScreen.tsx} +224 -42
- package/src/ui/{ModelReasoningPicker.tsx → panels/ModelReasoningPicker.tsx} +5 -5
- package/src/ui/{Panel.tsx → panels/Panel.tsx} +1 -1
- package/src/ui/{PermissionsPanel.tsx → panels/PermissionsPanel.tsx} +3 -3
- package/src/ui/{PlanActionPicker.tsx → panels/PlanActionPicker.tsx} +2 -2
- package/src/ui/{PlanReviewPanel.tsx → panels/PlanReviewPanel.tsx} +5 -5
- package/src/ui/panels/ProviderPicker.tsx +737 -0
- package/src/ui/{ReasoningPicker.tsx → panels/ReasoningPicker.tsx} +3 -3
- package/src/ui/{SelectionPanel.tsx → panels/SelectionPanel.tsx} +5 -1
- package/src/ui/{SettingsPanel.tsx → panels/SettingsPanel.tsx} +4 -4
- package/src/ui/{TextEntryPanel.tsx → panels/TextEntryPanel.tsx} +4 -4
- package/src/ui/{ThemePicker.tsx → panels/ThemePicker.tsx} +2 -2
- package/src/ui/{UpdatePromptPanel.tsx → panels/UpdatePromptPanel.tsx} +17 -23
- package/src/ui/{Markdown.tsx → render/Markdown.tsx} +2 -2
- package/src/ui/{diffRenderer.ts → render/diffRenderer.ts} +1 -1
- package/src/ui/{logoVariants.ts → render/logoVariants.ts} +4 -8
- package/src/ui/{modeDisplay.ts → render/modeDisplay.ts} +2 -2
- package/src/ui/{outputPipeline.ts → render/outputPipeline.ts} +2 -2
- package/src/ui/{runtimeDisplay.ts → render/runtimeDisplay.ts} +23 -10
- package/src/ui/{textLayout.ts → render/textLayout.ts} +15 -4
- package/src/ui/{ActionRequiredBlock.tsx → timeline/ActionRequiredBlock.tsx} +3 -3
- package/src/ui/{AgentBlock.tsx → timeline/AgentBlock.tsx} +10 -10
- package/src/ui/{StaticIntroItem.tsx → timeline/StaticIntroItem.tsx} +2 -2
- package/src/ui/{ThinkingBlock.tsx → timeline/ThinkingBlock.tsx} +4 -4
- package/src/ui/{Timeline.tsx → timeline/Timeline.tsx} +1620 -1471
- package/src/ui/timeline/TranscriptShell.tsx +322 -0
- package/src/ui/{TurnGroup.tsx → timeline/TurnGroup.tsx} +15 -15
- package/src/ui/timeline/layoutListWindow.ts +145 -0
- package/src/ui/{progressEntries.ts → timeline/progressEntries.ts} +3 -3
- package/src/ui/{runActivityView.ts → timeline/runActivityView.ts} +1 -1
- package/src/ui/{timelineMeasure.ts → timeline/timelineMeasure.ts} +206 -134
- package/src/core/codex.ts +0 -124
- package/src/ui/AppShell.tsx +0 -706
- package/src/ui/ProviderPicker.tsx +0 -321
- package/src/ui/StaticTranscriptItem.tsx +0 -56
- /package/src/core/{inputDebug.ts → debug/inputDebug.ts} +0 -0
- /package/src/core/{clipboard.ts → shared/clipboard.ts} +0 -0
- /package/src/core/{githubDiagnostics.ts → shared/githubDiagnostics.ts} +0 -0
- /package/src/core/{projectInstructions.ts → workspace/projectInstructions.ts} +0 -0
- /package/src/core/{workspaceActivity.ts → workspace/workspaceActivity.ts} +0 -0
- /package/src/core/{workspaceRoot.ts → workspace/workspaceRoot.ts} +0 -0
- /package/src/ui/{busyStatusAnimation.ts → chrome/busyStatusAnimation.ts} +0 -0
- /package/src/ui/{slashCommands.ts → input/slashCommands.ts} +0 -0
- /package/src/ui/{terminalAnswerFormat.ts → render/terminalAnswerFormat.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { type ReasoningEffortCapability } from "
|
|
3
|
-
import { formatReasoningLabel } from "
|
|
4
|
-
import { FOCUS_IDS } from "
|
|
2
|
+
import { type ReasoningEffortCapability } from "../../core/models/codexModelCapabilities.js";
|
|
3
|
+
import { formatReasoningLabel } from "../../config/settings.js";
|
|
4
|
+
import { FOCUS_IDS } from "../input/focus.js";
|
|
5
5
|
import { SelectionPanel } from "./SelectionPanel.js";
|
|
6
6
|
|
|
7
7
|
interface ReasoningPickerProps {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text, useFocus, useInput } from "ink";
|
|
3
3
|
import SelectInput from "ink-select-input";
|
|
4
|
-
import { useTheme } from "
|
|
4
|
+
import { useTheme } from "../theme.js";
|
|
5
5
|
|
|
6
6
|
interface SelectionPanelProps {
|
|
7
7
|
focusId: string;
|
|
@@ -53,6 +53,7 @@ export function SelectionPanel({
|
|
|
53
53
|
paddingY={1}
|
|
54
54
|
marginTop={1}
|
|
55
55
|
width="100%"
|
|
56
|
+
flexDirection="column"
|
|
56
57
|
>
|
|
57
58
|
<SelectInput
|
|
58
59
|
items={items}
|
|
@@ -61,6 +62,9 @@ export function SelectionPanel({
|
|
|
61
62
|
onSelect={(item) => onSelect(item.value)}
|
|
62
63
|
onHighlight={(item) => onHighlight?.(item.value)}
|
|
63
64
|
/>
|
|
65
|
+
<Box marginTop={1}>
|
|
66
|
+
<Text color={theme.textDim}>Esc to close · Enter to confirm</Text>
|
|
67
|
+
</Box>
|
|
64
68
|
</Box>
|
|
65
69
|
</Box>
|
|
66
70
|
);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useMemo, useState } from "react";
|
|
2
2
|
import { Box, Text, useFocus, useInput } from "ink";
|
|
3
|
-
import type { SettingDefinition } from "
|
|
4
|
-
import type { FocusTargetId } from "
|
|
5
|
-
import { useTheme } from "
|
|
3
|
+
import type { SettingDefinition } from "../../config/settings.js";
|
|
4
|
+
import type { FocusTargetId } from "../input/focus.js";
|
|
5
|
+
import { useTheme } from "../theme.js";
|
|
6
6
|
|
|
7
7
|
export interface SettingsPanelProps<TKey extends string> {
|
|
8
8
|
focusId: FocusTargetId;
|
|
@@ -39,7 +39,7 @@ export function SettingsPanel<TKey extends string>({
|
|
|
39
39
|
|
|
40
40
|
const activeSetting = settings[selectedIndex] ?? settings[0];
|
|
41
41
|
const subtitle = useMemo(() => {
|
|
42
|
-
const instructions = "↑↓ setting ←→ option Enter
|
|
42
|
+
const instructions = "↑↓ setting ←→ option Esc to close · Enter to confirm";
|
|
43
43
|
if (!activeSetting?.description) {
|
|
44
44
|
return instructions;
|
|
45
45
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useMemo, useState } from "react";
|
|
2
2
|
import { Box, Text, useFocus, useInput } from "ink";
|
|
3
|
-
import type { FocusTargetId } from "
|
|
4
|
-
import { useTheme } from "
|
|
5
|
-
import { stripMouseEscapes } from "
|
|
3
|
+
import type { FocusTargetId } from "../input/focus.js";
|
|
4
|
+
import { useTheme } from "../theme.js";
|
|
5
|
+
import { stripMouseEscapes } from "../input/inputBuffer.js";
|
|
6
6
|
|
|
7
7
|
interface TextEntryPanelProps {
|
|
8
8
|
focusId: FocusTargetId;
|
|
@@ -27,7 +27,7 @@ export function TextEntryPanel({
|
|
|
27
27
|
placeholder = "",
|
|
28
28
|
initialValue = "",
|
|
29
29
|
inputLabel = "Input",
|
|
30
|
-
footerHint = "Enter
|
|
30
|
+
footerHint = "Esc to close · Enter to confirm",
|
|
31
31
|
onSubmit,
|
|
32
32
|
onCancel,
|
|
33
33
|
}: TextEntryPanelProps) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { AVAILABLE_THEMES, formatThemeLabel } from "
|
|
3
|
-
import { FOCUS_IDS } from "
|
|
2
|
+
import { AVAILABLE_THEMES, formatThemeLabel } from "../../config/settings.js";
|
|
3
|
+
import { FOCUS_IDS } from "../input/focus.js";
|
|
4
4
|
import { SelectionPanel } from "./SelectionPanel.js";
|
|
5
5
|
|
|
6
6
|
interface ThemePickerProps {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { useEffect, useRef, useState } from "react";
|
|
2
2
|
import { Box, Text, useFocus, useInput } from "ink";
|
|
3
3
|
import { spawn } from "child_process";
|
|
4
|
-
import { useTheme } from "
|
|
5
|
-
import { CODEXA_NPM_PACKAGE, CODEXA_UPDATE_COMMAND } from "
|
|
4
|
+
import { useTheme } from "../theme.js";
|
|
5
|
+
import { CODEXA_NPM_PACKAGE, CODEXA_UPDATE_COMMAND, formatVersionLabel } from "../../core/version/updateCheck.js";
|
|
6
6
|
|
|
7
7
|
type Phase = "menu" | "running" | "done" | "error";
|
|
8
8
|
|
|
@@ -38,6 +38,10 @@ export function UpdatePromptPanel({
|
|
|
38
38
|
const spawnStartedRef = useRef(false);
|
|
39
39
|
|
|
40
40
|
useInput((input, key) => {
|
|
41
|
+
if (key.escape) {
|
|
42
|
+
onSkip();
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
41
45
|
if (phase === "menu") {
|
|
42
46
|
if (key.upArrow || input === "k") {
|
|
43
47
|
setSelectedIndex((i) => Math.max(0, i - 1));
|
|
@@ -57,12 +61,8 @@ export function UpdatePromptPanel({
|
|
|
57
61
|
}
|
|
58
62
|
return;
|
|
59
63
|
}
|
|
60
|
-
if (key.escape) {
|
|
61
|
-
onSkip();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
64
|
} else if (phase === "done" || phase === "error") {
|
|
65
|
-
if (key.return
|
|
65
|
+
if (key.return) {
|
|
66
66
|
onSkip();
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -107,9 +107,9 @@ export function UpdatePromptPanel({
|
|
|
107
107
|
};
|
|
108
108
|
}, [phase]);
|
|
109
109
|
|
|
110
|
-
const
|
|
111
|
-
? "
|
|
112
|
-
: "
|
|
110
|
+
const footerText = phase === "menu"
|
|
111
|
+
? "Esc to close · Enter to confirm"
|
|
112
|
+
: "Esc to close";
|
|
113
113
|
|
|
114
114
|
return (
|
|
115
115
|
<Box flexDirection="column" width="100%" marginTop={1}>
|
|
@@ -122,11 +122,10 @@ export function UpdatePromptPanel({
|
|
|
122
122
|
flexDirection="column"
|
|
123
123
|
>
|
|
124
124
|
<Box>
|
|
125
|
-
<Text color={theme.accent} bold>Update available
|
|
126
|
-
<Text color={theme.textMuted}>{hintText}</Text>
|
|
125
|
+
<Text color={theme.accent} bold>{`Update available: Codexa ${formatVersionLabel(latestVersion)}`}</Text>
|
|
127
126
|
</Box>
|
|
128
127
|
<Box marginTop={1}>
|
|
129
|
-
<Text color={theme.text}>{
|
|
128
|
+
<Text color={theme.text}>{`${formatVersionLabel(currentVersion)} -> ${formatVersionLabel(latestVersion)}`}</Text>
|
|
130
129
|
</Box>
|
|
131
130
|
<Box>
|
|
132
131
|
<Text color={theme.textMuted}>{`Package: ${CODEXA_NPM_PACKAGE}`}</Text>
|
|
@@ -138,7 +137,7 @@ export function UpdatePromptPanel({
|
|
|
138
137
|
|
|
139
138
|
<Box
|
|
140
139
|
borderStyle="round"
|
|
141
|
-
borderColor={theme.borderFocused}
|
|
140
|
+
borderColor={phase === "menu" ? theme.borderFocused : theme.border}
|
|
142
141
|
paddingX={2}
|
|
143
142
|
paddingY={1}
|
|
144
143
|
marginTop={1}
|
|
@@ -160,9 +159,6 @@ export function UpdatePromptPanel({
|
|
|
160
159
|
</Text>
|
|
161
160
|
</Box>
|
|
162
161
|
))}
|
|
163
|
-
<Box marginTop={1}>
|
|
164
|
-
<Text color={theme.textDim}>Press enter to continue</Text>
|
|
165
|
-
</Box>
|
|
166
162
|
</>
|
|
167
163
|
)}
|
|
168
164
|
|
|
@@ -179,9 +175,6 @@ export function UpdatePromptPanel({
|
|
|
179
175
|
<>
|
|
180
176
|
<Text color={theme.success}>{"Codexa was updated successfully."}</Text>
|
|
181
177
|
<Text color={theme.textMuted}>{"Restart Codexa to use the new version."}</Text>
|
|
182
|
-
<Box marginTop={1}>
|
|
183
|
-
<Text color={theme.textDim}>Press Enter to close</Text>
|
|
184
|
-
</Box>
|
|
185
178
|
</>
|
|
186
179
|
)}
|
|
187
180
|
|
|
@@ -192,11 +185,12 @@ export function UpdatePromptPanel({
|
|
|
192
185
|
{outputLines.slice(-5).map((line, i) => (
|
|
193
186
|
<Text key={i} color={theme.textDim}>{line}</Text>
|
|
194
187
|
))}
|
|
195
|
-
<Box marginTop={1}>
|
|
196
|
-
<Text color={theme.textDim}>Press Enter to close</Text>
|
|
197
|
-
</Box>
|
|
198
188
|
</>
|
|
199
189
|
)}
|
|
190
|
+
|
|
191
|
+
<Box marginTop={1}>
|
|
192
|
+
<Text color={theme.textDim}>{footerText}</Text>
|
|
193
|
+
</Box>
|
|
200
194
|
</Box>
|
|
201
195
|
</Box>
|
|
202
196
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import { useTheme } from "
|
|
4
|
-
import { Panel } from "
|
|
3
|
+
import { useTheme } from "../theme.js";
|
|
4
|
+
import { Panel } from "../panels/Panel.js";
|
|
5
5
|
import { maybeRenderDiff, type DiffRenderLineType } from "./diffRenderer.js";
|
|
6
6
|
import { formatLocalPathForTerminal, formatTerminalAnswerInline } from "./terminalAnswerFormat.js";
|
|
7
7
|
|
|
@@ -10,8 +10,8 @@ import { getTextWidth } from "./textLayout.js";
|
|
|
10
10
|
// The companion `wrap="truncate"` rule keeps each row on exactly one terminal
|
|
11
11
|
// line regardless of the surrounding Ink flex layout.
|
|
12
12
|
|
|
13
|
-
// Canonical Codexa brand wordmark — the ██ block art is the authoritative
|
|
14
|
-
//
|
|
13
|
+
// Canonical Codexa brand wordmark — the ██ block art is the authoritative
|
|
14
|
+
// large logo for wide/max layouts.
|
|
15
15
|
export const CODEXA_WORDMARK = [
|
|
16
16
|
" ██████╗ ██████╗ ██████╗ ███████╗██╗ ██╗ █████╗ ",
|
|
17
17
|
"██╔════╝██╔═══██╗██╔══██╗██╔════╝╚██╗██╔╝██╔══██╗",
|
|
@@ -48,16 +48,13 @@ export const LOGO_COMPACT_MIN_COLS = 48;
|
|
|
48
48
|
// Minimum terminal rows each variant needs to render without crowding out the
|
|
49
49
|
// metadata + composer. A wide-but-short terminal (e.g. VS Code's bottom panel)
|
|
50
50
|
// must step DOWN to a smaller logo instead of dropping straight to text-only.
|
|
51
|
-
export const LOGO_LARGE_MIN_ROWS =
|
|
51
|
+
export const LOGO_LARGE_MIN_ROWS = 35;
|
|
52
52
|
export const LOGO_MEDIUM_MIN_ROWS = 16;
|
|
53
53
|
export const LOGO_COMPACT_MIN_ROWS = 12;
|
|
54
54
|
|
|
55
|
-
// LOGO_MEDIUM is kept as an exported constant but intentionally omitted from
|
|
56
|
-
// LOGO_VARIANTS. At 72+ cols, LOGO_LARGE_MIN_COLS = LOGO_MEDIUM_MIN_COLS = 72,
|
|
57
|
-
// so LOGO_LARGE always wins. Below 72 cols the viewport is too narrow for the
|
|
58
|
-
// thin ASCII art to add value over the compact single-line fallback.
|
|
59
55
|
const LOGO_VARIANTS: readonly { logo: readonly string[]; minCols: number; minRows: number }[] = [
|
|
60
56
|
{ logo: LOGO_LARGE, minCols: LOGO_LARGE_MIN_COLS, minRows: LOGO_LARGE_MIN_ROWS },
|
|
57
|
+
{ logo: LOGO_MEDIUM, minCols: LOGO_MEDIUM_MIN_COLS, minRows: LOGO_MEDIUM_MIN_ROWS },
|
|
61
58
|
{ logo: LOGO_COMPACT, minCols: LOGO_COMPACT_MIN_COLS, minRows: LOGO_COMPACT_MIN_ROWS },
|
|
62
59
|
];
|
|
63
60
|
|
|
@@ -92,7 +89,6 @@ export function selectLogoVariantForViewport(cols: number, rows: number): readon
|
|
|
92
89
|
if (process.env["CODEXA_COMPACT_LOGO"] === "1") {
|
|
93
90
|
return rows >= LOGO_COMPACT_MIN_ROWS ? LOGO_COMPACT : [];
|
|
94
91
|
}
|
|
95
|
-
if (cols >= LOGO_LARGE_MIN_COLS) return LOGO_LARGE;
|
|
96
92
|
for (const variant of LOGO_VARIANTS) {
|
|
97
93
|
if (cols >= variant.minCols && rows >= variant.minRows) {
|
|
98
94
|
return variant.logo;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isNoiseLine } from "
|
|
2
|
-
import { sanitizeTerminalOutput } from "
|
|
1
|
+
import { isNoiseLine } from "../../core/providers/codexTranscript.js";
|
|
2
|
+
import { sanitizeTerminalOutput } from "../../core/terminal/terminalSanitize.js";
|
|
3
3
|
import { parseMarkdown, type Segment } from "./Markdown.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { formatModeLabel, formatReasoningLabel } from "
|
|
2
|
-
import type { RuntimeSummary } from "
|
|
3
|
-
import type { CodexModelCapability } from "
|
|
4
|
-
import type { ModelSpec } from "
|
|
5
|
-
import type { ModelContextMetadata } from "
|
|
6
|
-
import { contextMetadataToModelSpec, formatContextCompact } from "
|
|
7
|
-
import type { ActiveProviderRoute } from "
|
|
1
|
+
import { formatModeLabel, formatReasoningLabel } from "../../config/settings.js";
|
|
2
|
+
import type { RuntimeSummary } from "../../config/runtimeConfig.js";
|
|
3
|
+
import type { CodexModelCapability } from "../../core/models/codexModelCapabilities.js";
|
|
4
|
+
import type { ModelSpec } from "../../core/models/modelSpecs.js";
|
|
5
|
+
import type { ModelContextMetadata } from "../../core/providerRuntime/contextMetadata.js";
|
|
6
|
+
import { contextMetadataToModelSpec, formatContextCompact } from "../../core/providerRuntime/contextMetadata.js";
|
|
7
|
+
import type { ActiveProviderRoute } from "../../core/providerRuntime/types.js";
|
|
8
|
+
import { getAntigravityModelLabel } from "../../core/providerRuntime/antigravity.js";
|
|
8
9
|
|
|
9
10
|
export interface ActiveRuntimeDisplayInput {
|
|
10
11
|
route: ActiveProviderRoute;
|
|
@@ -28,7 +29,9 @@ const PROVIDER_DISPLAY: Record<string, string> = {
|
|
|
28
29
|
openai: "OpenAI Codex CLI",
|
|
29
30
|
anthropic: "Claude Code CLI",
|
|
30
31
|
google: "Gemini CLI",
|
|
32
|
+
mistral: "Mistral Vibe CLI",
|
|
31
33
|
local: "Local",
|
|
34
|
+
antigravity: "Antigravity CLI",
|
|
32
35
|
};
|
|
33
36
|
|
|
34
37
|
function formatContextLimit(value: number): string {
|
|
@@ -53,6 +56,9 @@ function getModelLabel(route: ActiveProviderRoute, capability?: CodexModelCapabi
|
|
|
53
56
|
if (route.providerId === "anthropic") {
|
|
54
57
|
return capability?.label ?? route.modelId;
|
|
55
58
|
}
|
|
59
|
+
if (route.providerId === "antigravity") {
|
|
60
|
+
return getAntigravityModelLabel(route.modelId);
|
|
61
|
+
}
|
|
56
62
|
return route.modelId;
|
|
57
63
|
}
|
|
58
64
|
|
|
@@ -65,7 +71,10 @@ export function buildActiveRuntimeDisplay({
|
|
|
65
71
|
contextMetadata = null,
|
|
66
72
|
}: ActiveRuntimeDisplayInput): ActiveRuntimeDisplay {
|
|
67
73
|
const providerLabel = PROVIDER_DISPLAY[route.providerId] ?? route.providerId;
|
|
68
|
-
const
|
|
74
|
+
const rawReasoning = route.providerId === "antigravity"
|
|
75
|
+
? route.reasoning
|
|
76
|
+
: route.reasoning ?? reasoningLevel;
|
|
77
|
+
const reasoning = rawReasoning ? formatReasoningLabel(rawReasoning) : null;
|
|
69
78
|
const modelLabel = getModelLabel(route, modelCapability);
|
|
70
79
|
const validContextMetadata = isContextForRoute(contextMetadata, route) ? contextMetadata : null;
|
|
71
80
|
const contextDisplay = validContextMetadata?.contextLength != null
|
|
@@ -82,8 +91,12 @@ export function buildActiveRuntimeDisplay({
|
|
|
82
91
|
|
|
83
92
|
return {
|
|
84
93
|
providerLabel,
|
|
85
|
-
modelDisplay:
|
|
86
|
-
|
|
94
|
+
modelDisplay: reasoning
|
|
95
|
+
? `${providerLabel} / ${modelLabel} / reasoning: ${reasoning}`
|
|
96
|
+
: `${providerLabel} / ${modelLabel}`,
|
|
97
|
+
footerModelDisplay: reasoning
|
|
98
|
+
? `${providerLabel} / ${modelLabel} (${reasoning})`
|
|
99
|
+
: `${providerLabel} / ${modelLabel}`,
|
|
87
100
|
contextDisplay,
|
|
88
101
|
modeLabel: formatModeLabel(mode),
|
|
89
102
|
modelSpec,
|
|
@@ -198,9 +198,14 @@ export function splitTextAtColumn(text: string, column: number): { before: strin
|
|
|
198
198
|
|
|
199
199
|
// ─── Text wrapping ────────────────────────────────────────────────────────────
|
|
200
200
|
|
|
201
|
-
export function wrapTextRows(
|
|
201
|
+
export function wrapTextRows(
|
|
202
|
+
text: string,
|
|
203
|
+
maxWidth: number,
|
|
204
|
+
firstLineWidth: number = maxWidth,
|
|
205
|
+
): WrappedTextRow[] {
|
|
202
206
|
const normalized = normalizeLineBreaks(text);
|
|
203
207
|
const safeWidth = Math.max(1, maxWidth);
|
|
208
|
+
const safeFirstWidth = Math.max(1, firstLineWidth);
|
|
204
209
|
const rows: WrappedTextRow[] = [];
|
|
205
210
|
let rowStart = 0;
|
|
206
211
|
let rowText = "";
|
|
@@ -220,7 +225,9 @@ export function wrapTextRows(text: string, maxWidth: number): WrappedTextRow[] {
|
|
|
220
225
|
continue;
|
|
221
226
|
}
|
|
222
227
|
|
|
223
|
-
|
|
228
|
+
// Only the first emitted row honors firstLineWidth; later rows use maxWidth.
|
|
229
|
+
const limit = rows.length === 0 ? safeFirstWidth : safeWidth;
|
|
230
|
+
if (rowText.length > 0 && rowWidth + unit.width > limit) {
|
|
224
231
|
rows.push({
|
|
225
232
|
text: rowText,
|
|
226
233
|
start: rowStart,
|
|
@@ -252,8 +259,12 @@ export function wrapTextRows(text: string, maxWidth: number): WrappedTextRow[] {
|
|
|
252
259
|
}];
|
|
253
260
|
}
|
|
254
261
|
|
|
255
|
-
export function wrapPlainText(
|
|
256
|
-
|
|
262
|
+
export function wrapPlainText(
|
|
263
|
+
text: string,
|
|
264
|
+
maxWidth: number,
|
|
265
|
+
firstLineWidth: number = maxWidth,
|
|
266
|
+
): string[] {
|
|
267
|
+
return wrapTextRows(text, maxWidth, firstLineWidth).map((row) => row.text);
|
|
257
268
|
}
|
|
258
269
|
|
|
259
270
|
export function wrapCommandText(text: string, maxWidth: number): string[] {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import { getUsableShellWidth } from "
|
|
4
|
-
import { wrapPlainText } from "
|
|
5
|
-
import { useTheme } from "
|
|
3
|
+
import { getUsableShellWidth } from "../layout.js";
|
|
4
|
+
import { wrapPlainText } from "../render/textLayout.js";
|
|
5
|
+
import { useTheme } from "../theme.js";
|
|
6
6
|
|
|
7
7
|
interface ActionRequiredBlockProps {
|
|
8
8
|
cols: number;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import React, { memo, useDeferredValue, useMemo } from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import type { AssistantEvent, RunEvent } from "
|
|
4
|
-
import { getAssistantContent } from "
|
|
5
|
-
import { MemoizedRenderMessage } from "
|
|
6
|
-
import { getUsableShellWidth } from "
|
|
7
|
-
import { useTheme } from "
|
|
8
|
-
import { wrapPlainText } from "
|
|
9
|
-
import { RUN_OUTPUT_TRUNCATION_NOTICE } from "
|
|
10
|
-
import { sanitizeTerminalOutput } from "
|
|
3
|
+
import type { AssistantEvent, RunEvent } from "../../session/types.js";
|
|
4
|
+
import { getAssistantContent } from "../../session/types.js";
|
|
5
|
+
import { MemoizedRenderMessage } from "../render/Markdown.js";
|
|
6
|
+
import { getUsableShellWidth } from "../layout.js";
|
|
7
|
+
import { useTheme } from "../theme.js";
|
|
8
|
+
import { wrapPlainText } from "../render/textLayout.js";
|
|
9
|
+
import { RUN_OUTPUT_TRUNCATION_NOTICE } from "../../session/chatLifecycle.js";
|
|
10
|
+
import { sanitizeTerminalOutput } from "../../core/terminal/terminalSanitize.js";
|
|
11
11
|
import {
|
|
12
12
|
sanitizeOutput,
|
|
13
13
|
sanitizeStreamChunk,
|
|
14
14
|
normalizeOutput,
|
|
15
15
|
classifyOutput,
|
|
16
16
|
formatForBox,
|
|
17
|
-
} from "
|
|
18
|
-
import { DashCard } from "
|
|
17
|
+
} from "../render/outputPipeline.js";
|
|
18
|
+
import { DashCard } from "../chrome/DashCard.js";
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
function formatDuration(ms: number): string {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box } from "ink";
|
|
3
|
-
import type { CodexAuthState } from "
|
|
4
|
-
import { getShellWidth, type Layout, type StartupHeaderMode } from "
|
|
3
|
+
import type { CodexAuthState } from "../../core/auth/codexAuth.js";
|
|
4
|
+
import { getShellWidth, type Layout, type StartupHeaderMode } from "../layout.js";
|
|
5
5
|
import { buildIntroRenderItem, TimelineRowView } from "./Timeline.js";
|
|
6
6
|
import type { TimelineRow } from "./timelineMeasure.js";
|
|
7
7
|
import { buildTimelineSnapshot } from "./timelineMeasure.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Box, Text } from "ink";
|
|
3
|
-
import type { RunEvent } from "
|
|
4
|
-
import { clampVisualText, getUsableShellWidth } from "
|
|
5
|
-
import { useTheme } from "
|
|
6
|
-
import { DashCard } from "
|
|
3
|
+
import type { RunEvent } from "../../session/types.js";
|
|
4
|
+
import { clampVisualText, getUsableShellWidth } from "../layout.js";
|
|
5
|
+
import { useTheme } from "../theme.js";
|
|
6
|
+
import { DashCard } from "../chrome/DashCard.js";
|
|
7
7
|
import {
|
|
8
8
|
formatProgressBlockBodyLines,
|
|
9
9
|
getProgressUpdateCount,
|