praxis-agent 0.20.18 → 0.20.20
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
CHANGED
|
@@ -88,7 +88,9 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
|
|
|
88
88
|
|
|
89
89
|
## What Praxis provides
|
|
90
90
|
|
|
91
|
-
- **Local agent runtime** — Claude-style responsive TUI with a
|
|
91
|
+
- **Local agent runtime** — Claude-style responsive TUI with a fixed fullscreen
|
|
92
|
+
viewport, non-shrinking composer/status area, and complete bounded welcome
|
|
93
|
+
surface, plus a shared-command
|
|
92
94
|
slash palette, tabbed help and shortcut surfaces, searchable resume picker,
|
|
93
95
|
restored active-branch conversation history, streaming and expandable
|
|
94
96
|
thinking, grouped multi-file reads, globally expandable tool results,
|
package/dist/cli/interactive.js
CHANGED
|
@@ -11,7 +11,7 @@ import { permissionRuleValueToString } from '../permissions/permission-updates.j
|
|
|
11
11
|
import { AgentRunCancelledError } from '../core/runtime.js';
|
|
12
12
|
import { claudePermissionActionKey, claudePermissionRuleMatches, } from '../permissions/claude-permission-resolver.js';
|
|
13
13
|
import { redactSensitiveText, sensitiveEnvironmentValues, } from '../platform/sensitive-data.js';
|
|
14
|
-
import { CommandPalette, BtwPanel, Composer, DiffDashboard, DialogFrame, ExternalEditorWait, HelpMenu, HookDashboard, ListDashboard, MemoryDashboard, MentionPicker, ModelMenu, PermissionDashboard, SelectionMenu, SessionPicker, ThemePicker, CustomThemeEditor, Transcript, WelcomePanel, useTerminalWidth, } from './tui/claude-style.js';
|
|
14
|
+
import { CommandPalette, BtwPanel, Composer, DiffDashboard, DialogFrame, ExternalEditorWait, HelpMenu, HookDashboard, ListDashboard, MemoryDashboard, MentionPicker, ModelMenu, PermissionDashboard, SelectionMenu, SessionPicker, ThemePicker, CustomThemeEditor, Transcript, WelcomePanel, useTerminalRows, useTerminalWidth, } from './tui/claude-style.js';
|
|
15
15
|
import { loadTuiMemoryFiles, openTuiMemoryFolder, } from './tui/memory-files.js';
|
|
16
16
|
import { loadClaudeReleaseNotes } from './tui/release-notes.js';
|
|
17
17
|
import { createClaudeStatusLineInput, StatusLine } from './tui/status-line.js';
|
|
@@ -264,6 +264,7 @@ const HIDDEN_TUI_SLASH_COMMANDS = new Set([
|
|
|
264
264
|
export function InteractiveApp({ factory, initialSessions, initialPrompt, initialHistory = [], initialSessionColor, signal, onCancel, onTurnChange, onCleanup, onRendererChange, onBackground, axScreenReader = false, allowNewSession = true, resume, display = { version: 'dev', cwd: process.cwd() }, terminalWidth, slashCommands = EMPTY_SLASH_COMMANDS, agents = EMPTY_AGENTS, allowDangerouslySkipPermissions = false, additionalDirectories = [], diffLoader, doctorLoader, fileLoader, externalEditor = editTuiPrompt, keybindingsConfigRoot, keybindingsFile = ensureTuiKeybindingsFile, keybindingsLoader = loadTuiKeybindings, keybindingsEditor = openTuiEditorFile, memoryFilesLoader = (configRoot, cwd) => loadTuiMemoryFiles({ configRoot, cwd }), memoryEditor = openTuiEditorFile, memoryFolderOpener = openTuiMemoryFolder, suspendProcess = suspendTuiProcess, clipboardReader = readTuiClipboard, clipboardWriter = writeTuiClipboard, sideQuestionClipboardWriter = writeTuiOsc52Clipboard, exportWriter = writeConversationExport, permissionRuleStore, sandboxStore: suppliedSandboxStore, recentlyDeniedStore: suppliedRecentlyDeniedStore, terminalSetup: terminalSetupOverride, themeStore, initialThemeSettings, initialThemeLoadError, workspaceDirectoryResolver = resolveTuiWorkspaceDirectory, workspaceDirectoryCompleter = completeTuiWorkspaceDirectory, runtimeSettings: suppliedRuntimeSettings, runtimeSettingsTarget, notificationWriter, elicitationUrlOpener = openTuiUrl, releaseNotesLoader = (configRoot) => loadClaudeReleaseNotes({ configRoot }), settingSources, }) {
|
|
265
265
|
const { exit, suspendTerminal, waitUntilRenderFlush } = useApp();
|
|
266
266
|
const width = useTerminalWidth(terminalWidth);
|
|
267
|
+
const rows = useTerminalRows();
|
|
267
268
|
const keybindingsRoot = useMemo(() => resolve(keybindingsConfigRoot ??
|
|
268
269
|
process.env.CLAUDE_CONFIG_DIR ??
|
|
269
270
|
resolve(homedir(), '.claude')), [keybindingsConfigRoot]);
|
|
@@ -320,6 +321,7 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
|
|
|
320
321
|
const [themeSettings, setThemeSettings] = useState(initialThemeSettings ?? DEFAULT_TUI_THEME_SETTINGS);
|
|
321
322
|
const [runtimeSettings, setRuntimeSettings] = useState(suppliedRuntimeSettings ??
|
|
322
323
|
projectRuntimeSettings({ settings: {}, state: {} }));
|
|
324
|
+
const fixedViewport = runtimeSettings.tui === 'fullscreen' && rows !== undefined;
|
|
323
325
|
const runtimeSettingsRef = useRef(runtimeSettings);
|
|
324
326
|
runtimeSettingsRef.current = runtimeSettings;
|
|
325
327
|
runtimeGitignoreRef.current = runtimeSettings.gitignore;
|
|
@@ -5626,7 +5628,9 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
|
|
|
5626
5628
|
}
|
|
5627
5629
|
editComposer();
|
|
5628
5630
|
});
|
|
5629
|
-
return (_jsx(TuiThemeProvider, { settings: themeSettings, children: _jsx(Box, { flexDirection: "column",
|
|
5631
|
+
return (_jsx(TuiThemeProvider, { settings: themeSettings, children: _jsx(Box, { flexDirection: "column", ...(!fixedViewport
|
|
5632
|
+
? {}
|
|
5633
|
+
: { height: rows, overflowY: 'hidden' }), children: selectingSession ? (_jsx(SessionPicker, { sessions: filteredPickerChoices, selectedIndex: selectedIndex, screenReader: axScreenReader, query: sessionSearch })) : (_jsxs(_Fragment, { children: [!axScreenReader && history.length === 0 && !sessionId ? (_jsx(WelcomePanel, { display: runtimeDisplay, width: width, showTips: runtimeSettings.tips })) : null, sessionId ? (_jsxs(Text, { dimColor: true, children: ["Session ", sessionId.slice(0, 8)] })) : null, _jsx(Transcript, { items: history, activeText: activeText, activeThinking: activeThinking, thinkingExpanded: thinkingExpanded, detailedTranscript: thinkingExpanded || runtimeSettings.verbose, screenReader: axScreenReader }), externalEditorRequest !== null ||
|
|
5630
5634
|
keybindingsEditing ||
|
|
5631
5635
|
memoryEditorRequest !== null ? (_jsx(ExternalEditorWait, { screenReader: axScreenReader })) : permission ? (permission.kind === 'tool' && toolPermissionModel ? (_jsx(ToolPermissionDialog, { model: toolPermissionModel, selection: permissionSelection, feedbackMode: permissionFeedbackMode, feedback: input, ruleEditor: permissionRuleEditor, screenReader: axScreenReader })) : (_jsxs(DialogFrame, { title: `Retry interrupted ${permission.call.name}?`, screenReader: axScreenReader, children: [_jsx(Box, { flexDirection: "column", paddingX: 1, paddingY: 1, children: _jsx(Text, { bold: true, children: describeTool(permission.call, sensitiveValues) }) }), _jsx(Text, { children: "Do you want to proceed?" }), _jsxs(Text, { inverse: !axScreenReader && permissionSelection === 0, children: [selectionPrefix(permissionSelection === 0, axScreenReader), "1. Yes"] }), _jsxs(Text, { inverse: !axScreenReader && permissionSelection === 1, children: [selectionPrefix(permissionSelection === 1, axScreenReader), "2. No"] }), permissionFeedbackMode ? (_jsxs(Text, { children: ["\u203A", ' ', input ||
|
|
5632
5636
|
(permissionSelection === 0
|
|
@@ -5762,7 +5766,7 @@ export function InteractiveApp({ factory, initialSessions, initialPrompt, initia
|
|
|
5762
5766
|
sessionName,
|
|
5763
5767
|
usage?.inputTokens,
|
|
5764
5768
|
usage?.outputTokens,
|
|
5765
|
-
].join(':'), ...(settingSources === undefined ? {} : { settingSources }) })] }))] })) }) }));
|
|
5769
|
+
].join(':'), width: width, ...(settingSources === undefined ? {} : { settingSources }) })] }))] })) }) }));
|
|
5766
5770
|
}
|
|
5767
5771
|
export async function runInteractive(options) {
|
|
5768
5772
|
const controller = new AbortController();
|
|
@@ -71,6 +71,7 @@ export interface TuiBtwEntry {
|
|
|
71
71
|
error?: string;
|
|
72
72
|
}
|
|
73
73
|
export declare function useTerminalWidth(override?: number): number;
|
|
74
|
+
export declare function useTerminalRows(override?: number): number | undefined;
|
|
74
75
|
export declare function WelcomePanel({ display, width, showTips, }: {
|
|
75
76
|
display: TuiDisplayMetadata;
|
|
76
77
|
width: number;
|
|
@@ -22,6 +22,23 @@ export function useTerminalWidth(override) {
|
|
|
22
22
|
}, [override, stdout]);
|
|
23
23
|
return Math.max(32, width);
|
|
24
24
|
}
|
|
25
|
+
export function useTerminalRows(override) {
|
|
26
|
+
const { stdout } = useStdout();
|
|
27
|
+
const initialRows = override ?? (stdout.isTTY ? stdout.rows : undefined);
|
|
28
|
+
const [rows, setRows] = useState(initialRows);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (override !== undefined) {
|
|
31
|
+
setRows(override);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const resize = () => setRows(stdout.rows);
|
|
35
|
+
stdout.on('resize', resize);
|
|
36
|
+
return () => {
|
|
37
|
+
stdout.off('resize', resize);
|
|
38
|
+
};
|
|
39
|
+
}, [override, stdout]);
|
|
40
|
+
return rows === undefined ? undefined : Math.max(12, rows);
|
|
41
|
+
}
|
|
25
42
|
function compactPath(cwd) {
|
|
26
43
|
const home = process.env.HOME;
|
|
27
44
|
return home && cwd.startsWith(`${home}/`)
|
|
@@ -44,6 +61,45 @@ function permissionLabel(mode) {
|
|
|
44
61
|
return 'permissions default';
|
|
45
62
|
}
|
|
46
63
|
}
|
|
64
|
+
function compactPermissionLabel(mode) {
|
|
65
|
+
switch (mode) {
|
|
66
|
+
case 'acceptEdits':
|
|
67
|
+
return 'accept edits';
|
|
68
|
+
case 'bypassPermissions':
|
|
69
|
+
return 'bypass';
|
|
70
|
+
case 'dontAsk':
|
|
71
|
+
return 'dont ask';
|
|
72
|
+
case 'plan':
|
|
73
|
+
return 'plan';
|
|
74
|
+
case 'auto':
|
|
75
|
+
return 'auto';
|
|
76
|
+
default:
|
|
77
|
+
return 'default';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Width-prioritized composer footer left text. The footer is one deliberate,
|
|
81
|
+
// non-wrapping line: mode and the busy/effort state always win, while
|
|
82
|
+
// shortcuts/agents/thinking hints are dropped or shortened as width shrinks.
|
|
83
|
+
function composerFooterLeft(width, busy, hasThinking, thinkingExpanded, mode, compactMode, includeHints = true) {
|
|
84
|
+
const cancelOrShortcut = busy ? 'esc to interrupt' : '? for shortcuts';
|
|
85
|
+
if (!includeHints) {
|
|
86
|
+
if (busy)
|
|
87
|
+
return `${width >= 60 ? mode : compactMode} · ${cancelOrShortcut}`;
|
|
88
|
+
return width >= 60 ? mode : compactMode;
|
|
89
|
+
}
|
|
90
|
+
if (width >= 60) {
|
|
91
|
+
let text = `${mode} · ${cancelOrShortcut}`;
|
|
92
|
+
if (width >= 80)
|
|
93
|
+
text += ' · ← for agents';
|
|
94
|
+
if (width >= 100 && hasThinking) {
|
|
95
|
+
text += ` · ctrl+o ${thinkingExpanded ? 'collapse' : 'expand'}`;
|
|
96
|
+
}
|
|
97
|
+
return text;
|
|
98
|
+
}
|
|
99
|
+
if (busy)
|
|
100
|
+
return `${compactMode} · ${cancelOrShortcut}`;
|
|
101
|
+
return width >= 40 ? mode : compactMode;
|
|
102
|
+
}
|
|
47
103
|
function selectionPrefix(selected, screenReader) {
|
|
48
104
|
if (selected)
|
|
49
105
|
return screenReader ? 'Selected: ' : ' ❯ ';
|
|
@@ -54,7 +110,7 @@ export function WelcomePanel({ display, width, showTips, }) {
|
|
|
54
110
|
if (!showTips)
|
|
55
111
|
return null;
|
|
56
112
|
const panelWidth = Math.min(100, Math.max(32, width));
|
|
57
|
-
const wide = panelWidth >=
|
|
113
|
+
const wide = panelWidth >= 72;
|
|
58
114
|
const brand = 'Praxis';
|
|
59
115
|
const model = display.model ?? 'provider default';
|
|
60
116
|
const effort = display.effort ? ` · ${display.effort} effort` : '';
|
|
@@ -63,9 +119,11 @@ export function WelcomePanel({ display, width, showTips, }) {
|
|
|
63
119
|
// ╭───Praxis Code vX.Y.Z ───...───╮
|
|
64
120
|
// Fixed prefix/suffix = "╭───"(4) + "Praxis"(6) + " Code vX.Y.Z "(8 + version)
|
|
65
121
|
// + "╮"(1), so the fill keeps the row exactly at panelWidth.
|
|
66
|
-
const
|
|
67
|
-
const
|
|
68
|
-
|
|
122
|
+
const title = `${brand} Code v${display.version}`;
|
|
123
|
+
const fill = Math.max(1, panelWidth - title.length - 6);
|
|
124
|
+
const leftWidth = Math.max(12, Math.floor((panelWidth - 4) / 2));
|
|
125
|
+
const rightWidth = Math.max(12, panelWidth - leftWidth - 4);
|
|
126
|
+
return (_jsxs(Box, { flexDirection: "column", width: panelWidth, children: [_jsxs(Text, { color: palette.muted, children: ['╭───', _jsx(Text, { color: palette.brand, bold: true, children: brand }), ` Code v${display.version} `, _jsx(Text, { dimColor: true, children: '─'.repeat(fill) }), '╮'] }), _jsxs(Box, { borderStyle: "round", borderColor: palette.muted, borderTop: false, flexDirection: wide ? 'row' : 'column', width: panelWidth, paddingX: 1, children: [_jsxs(Box, { alignItems: wide ? 'center' : undefined, flexDirection: "column", width: wide ? leftWidth : '100%', children: [_jsx(Text, { children: " " }), _jsxs(Text, { bold: true, children: ["Welcome to ", brand] }), _jsx(Text, { children: " " }), _jsx(Text, { color: palette.brand, bold: true, children: "\u2590\u259B\u2588\u2588\u2588\u259C\u258C" }), _jsx(Text, { color: palette.brand, children: "\u259D\u259C\u2588\u2588\u2588\u2588\u2588\u259B\u2598" }), _jsx(Text, { color: palette.brand, children: " \u2598\u2598 \u259D\u259D" }), _jsx(Text, { children: " " }), _jsxs(Text, { wrap: "truncate-end", children: [model, effort] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd })] }), _jsxs(Box, { flexDirection: "column", width: wide ? rightWidth : '100%', marginTop: wide ? 0 : 1, children: [_jsx(Text, { bold: true, children: "Get started" }), _jsx(Text, { wrap: "truncate-end", children: "/init to create CLAUDE.md" }), _jsx(Text, { wrap: "truncate-end", children: "/config to open settings" }), _jsx(Text, { dimColor: true, children: " " }), _jsx(Text, { bold: true, children: "Shared with Claude Code" }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: "Sessions \u00B7 memory \u00B7 skills" })] })] })] }));
|
|
69
127
|
}
|
|
70
128
|
const INLINE_SEGMENT_CACHE_MAX = 4096;
|
|
71
129
|
const inlineSegmentCache = new Map();
|
|
@@ -866,7 +924,12 @@ export function Composer({ input, cursor, busy, clipboardBusy = false, status, d
|
|
|
866
924
|
: `Prompt: ${input}` }));
|
|
867
925
|
const line = '─'.repeat(Math.max(12, Math.min(100, width)));
|
|
868
926
|
const separatorColor = sessionColor === undefined ? undefined : palette.sessionColors[sessionColor];
|
|
869
|
-
|
|
927
|
+
const footerWidth = Math.min(100, width);
|
|
928
|
+
const footerMode = `⏵⏵ ${permissionLabel(display.permissionMode)}`;
|
|
929
|
+
const footerCompactMode = `⏵⏵ ${compactPermissionLabel(display.permissionMode)}`;
|
|
930
|
+
const footerLeft = composerFooterLeft(footerWidth, busy, hasThinking, thinkingExpanded, footerMode, footerCompactMode);
|
|
931
|
+
const footerMessageLeft = composerFooterLeft(footerWidth, busy, hasThinking, thinkingExpanded, footerMode, footerCompactMode, false);
|
|
932
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, flexShrink: 0, children: [usage ? (_jsxs(Text, { dimColor: true, children: ["Context \u00B7 ", usage.inputTokens + usage.outputTokens, " tokens", display.contextWindowTokens
|
|
870
933
|
? ` / ${display.contextWindowTokens} (${Math.min(100, Math.round(((usage.inputTokens + usage.outputTokens) /
|
|
871
934
|
display.contextWindowTokens) *
|
|
872
935
|
100))}%)`
|
|
@@ -878,9 +941,7 @@ export function Composer({ input, cursor, busy, clipboardBusy = false, status, d
|
|
|
878
941
|
? 'Enter a shell command'
|
|
879
942
|
: 'Try "review this project"' }))] })), _jsx(Text, { ...(separatorColor === undefined
|
|
880
943
|
? { dimColor: true }
|
|
881
|
-
: { color: separatorColor }), children: line }), shortcutsVisible ? (_jsx(ShortcutHelp, { width: width })) : (
|
|
882
|
-
? ` · ctrl+o ${thinkingExpanded ? 'collapse' : 'expand'}`
|
|
883
|
-
: ''] })) }), _jsx(Box, { flexGrow: 1 }), footerMessage ? (footerMessage.isError ? (_jsx(Text, { color: palette.error, children: footerMessage.text })) : (_jsx(Text, { dimColor: true, children: footerMessage.text }))) : prStatus ? (_jsx(Text, { dimColor: true, children: prStatus })) : turnDuration ? (_jsxs(Text, { dimColor: true, children: ["Cooked for ", turnDuration] })) : display.effort ? (_jsxs(Text, { children: [_jsxs(Text, { color: palette.accent, children: ["\u25CF ", display.effort] }), _jsxs(Text, { dimColor: true, children: [' ', "\u00B7 ", editorMode === 'vim' ? 'vim' : '/effort'] })] })) : null] }))] }));
|
|
944
|
+
: { color: separatorColor }), children: line }), shortcutsVisible ? (_jsx(ShortcutHelp, { width: width })) : (_jsx(Box, { width: footerWidth, children: _jsx(Text, { wrap: "truncate", children: shellMode ? (_jsx(Text, { dimColor: true, children: "! for bash mode" })) : footerMessage ? (_jsxs(Text, { children: [_jsxs(Text, { dimColor: true, children: [footerMessageLeft, " \u00B7 "] }), footerMessage.isError ? (_jsx(Text, { color: palette.error, children: footerMessage.text })) : (_jsx(Text, { dimColor: true, children: footerMessage.text }))] })) : prStatus ? (_jsxs(Text, { children: [_jsxs(Text, { dimColor: true, children: [footerLeft, " \u00B7 "] }), _jsx(Text, { dimColor: true, children: prStatus })] })) : turnDuration ? (_jsxs(Text, { children: [_jsxs(Text, { dimColor: true, children: [footerLeft, " \u00B7 "] }), _jsxs(Text, { dimColor: true, children: ["Cooked for ", turnDuration] })] })) : display.effort ? (_jsxs(Text, { children: [_jsx(Text, { dimColor: true, children: footerLeft }), _jsx(Text, { dimColor: true, children: " \u00B7 " }), _jsxs(Text, { color: palette.accent, children: ["\u25CF ", display.effort] }), footerWidth >= 100 ? (_jsxs(Text, { dimColor: true, children: [' ', "\u00B7 ", editorMode === 'vim' ? 'vim' : '/effort'] })) : null] })) : (_jsx(Text, { dimColor: true, children: footerLeft })) }) }))] }));
|
|
884
945
|
}
|
|
885
946
|
export function DialogFrame({ title, children, screenReader, }) {
|
|
886
947
|
const palette = useTuiPalette();
|
|
@@ -61,6 +61,7 @@ export declare function executeClaudeStatusLine(setting: ClaudeStatusLineSetting
|
|
|
61
61
|
cwd: string;
|
|
62
62
|
signal?: AbortSignal;
|
|
63
63
|
timeoutMs?: number;
|
|
64
|
+
columns?: number;
|
|
64
65
|
}): Promise<string | undefined>;
|
|
65
66
|
export declare function createClaudeStatusLineInput(options: {
|
|
66
67
|
configRoot: string;
|
|
@@ -78,11 +79,12 @@ export declare function createClaudeStatusLineInput(options: {
|
|
|
78
79
|
contextWindowTokens?: number;
|
|
79
80
|
vimMode?: 'INSERT' | 'NORMAL';
|
|
80
81
|
}): ClaudeStatusLineInput;
|
|
81
|
-
export declare function StatusLine({ configRoot, cwd, input, refreshKey, settingSources, }: {
|
|
82
|
+
export declare function StatusLine({ configRoot, cwd, input, refreshKey, width, settingSources, }: {
|
|
82
83
|
configRoot: string;
|
|
83
84
|
cwd: string;
|
|
84
85
|
input: ClaudeStatusLineInput;
|
|
85
86
|
refreshKey: string;
|
|
87
|
+
width?: number;
|
|
86
88
|
settingSources?: readonly ClaudeResourceScope[];
|
|
87
89
|
}): import("react").JSX.Element | null;
|
|
88
90
|
//# sourceMappingURL=status-line.d.ts.map
|
|
@@ -49,10 +49,16 @@ export async function executeClaudeStatusLine(setting, input, options = {
|
|
|
49
49
|
};
|
|
50
50
|
let child;
|
|
51
51
|
try {
|
|
52
|
+
const env = { ...process.env };
|
|
53
|
+
if (options.columns !== undefined &&
|
|
54
|
+
Number.isFinite(options.columns) &&
|
|
55
|
+
options.columns > 0) {
|
|
56
|
+
env.COLUMNS = String(Math.trunc(options.columns));
|
|
57
|
+
}
|
|
52
58
|
child = spawn(commandShell(), commandShellArguments(setting.command), {
|
|
53
59
|
cwd: options.cwd,
|
|
54
60
|
detached: process.platform !== 'win32',
|
|
55
|
-
env
|
|
61
|
+
env,
|
|
56
62
|
stdio: ['pipe', 'pipe', 'ignore'],
|
|
57
63
|
});
|
|
58
64
|
}
|
|
@@ -169,7 +175,7 @@ export function createClaudeStatusLineInput(options) {
|
|
|
169
175
|
...(options.vimMode ? { vim: { mode: options.vimMode } } : {}),
|
|
170
176
|
};
|
|
171
177
|
}
|
|
172
|
-
export function StatusLine({ configRoot, cwd, input, refreshKey, settingSources, }) {
|
|
178
|
+
export function StatusLine({ configRoot, cwd, input, refreshKey, width, settingSources, }) {
|
|
173
179
|
const [text, setText] = useState();
|
|
174
180
|
const [padding, setPadding] = useState(0);
|
|
175
181
|
const timer = useRef(undefined);
|
|
@@ -193,7 +199,11 @@ export function StatusLine({ configRoot, cwd, input, refreshKey, settingSources,
|
|
|
193
199
|
setText(undefined);
|
|
194
200
|
return;
|
|
195
201
|
}
|
|
196
|
-
const result = await executeClaudeStatusLine(loaded.setting, latestInput.current, {
|
|
202
|
+
const result = await executeClaudeStatusLine(loaded.setting, latestInput.current, {
|
|
203
|
+
cwd,
|
|
204
|
+
signal: current.signal,
|
|
205
|
+
...(width === undefined ? {} : { columns: width }),
|
|
206
|
+
});
|
|
197
207
|
if (!current.signal.aborted)
|
|
198
208
|
setText(result);
|
|
199
209
|
}
|
|
@@ -201,7 +211,7 @@ export function StatusLine({ configRoot, cwd, input, refreshKey, settingSources,
|
|
|
201
211
|
if (!current.signal.aborted)
|
|
202
212
|
setText(undefined);
|
|
203
213
|
}
|
|
204
|
-
}, [configRoot, cwd, settingSources]);
|
|
214
|
+
}, [configRoot, cwd, settingSources, width]);
|
|
205
215
|
const schedule = useCallback(() => {
|
|
206
216
|
if (timer.current)
|
|
207
217
|
clearTimeout(timer.current);
|
|
@@ -229,6 +239,6 @@ export function StatusLine({ configRoot, cwd, input, refreshKey, settingSources,
|
|
|
229
239
|
}, [configRoot, cwd, schedule]);
|
|
230
240
|
if (!text)
|
|
231
241
|
return null;
|
|
232
|
-
return (_jsx(Box, { paddingX: padding, children: _jsx(Text, { dimColor: true, wrap: "truncate", children: text }) }));
|
|
242
|
+
return (_jsx(Box, { paddingX: padding, flexShrink: 0, children: _jsx(Text, { dimColor: true, wrap: "truncate", children: text }) }));
|
|
233
243
|
}
|
|
234
244
|
//# sourceMappingURL=status-line.js.map
|