dexto 1.5.4 → 1.5.6
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 +371 -408
- package/dist/agents/agent-template.yml +1 -1
- package/dist/agents/coding-agent/coding-agent.yml +16 -2
- package/dist/agents/podcast-agent/podcast-agent.yml +1 -1
- package/dist/cli/cli-subscriber.d.ts +0 -1
- package/dist/cli/cli-subscriber.d.ts.map +1 -1
- package/dist/cli/cli-subscriber.js +0 -8
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.js +2 -0
- package/dist/cli/commands/interactive-commands/export/index.d.ts +13 -0
- package/dist/cli/commands/interactive-commands/export/index.d.ts.map +1 -0
- package/dist/cli/commands/interactive-commands/export/index.js +21 -0
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +45 -23
- package/dist/cli/commands/interactive-commands/system/system-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/system/system-commands.js +2 -3
- package/dist/cli/commands/setup.js +106 -27
- package/dist/cli/commands/sync-agents.d.ts +44 -0
- package/dist/cli/commands/sync-agents.d.ts.map +1 -0
- package/dist/cli/commands/sync-agents.js +483 -0
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts +14 -1
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/InkCLIRefactored.js +7 -2
- package/dist/cli/ink-cli/components/Footer.d.ts +4 -1
- package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/Footer.js +62 -18
- package/dist/cli/ink-cli/components/StatusBar.d.ts +5 -1
- package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/StatusBar.js +16 -4
- package/dist/cli/ink-cli/components/TodoPanel.d.ts +26 -0
- package/dist/cli/ink-cli/components/TodoPanel.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/TodoPanel.js +62 -0
- package/dist/cli/ink-cli/components/chat/Header.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/Header.js +1 -1
- package/dist/cli/ink-cli/components/chat/styled-boxes/LogConfigBox.js +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +15 -5
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +3 -2
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.js +4 -3
- package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts +22 -0
- package/dist/cli/ink-cli/components/overlays/ExportWizard.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/ExportWizard.js +308 -0
- package/dist/cli/ink-cli/components/overlays/LogLevelSelector.js +1 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.js +28 -1
- package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/processingPhrases.js +7 -0
- package/dist/cli/ink-cli/constants/tips.js +2 -2
- package/dist/cli/ink-cli/containers/InputContainer.d.ts +3 -1
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +4 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +5 -1
- package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts +8 -2
- package/dist/cli/ink-cli/hooks/useAgentEvents.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useAgentEvents.js +69 -3
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts +4 -2
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +11 -0
- package/dist/cli/ink-cli/hooks/useInputOrchestrator.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useInputOrchestrator.js +5 -0
- package/dist/cli/ink-cli/services/processStream.d.ts +2 -0
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +26 -55
- package/dist/cli/ink-cli/state/initialState.d.ts.map +1 -1
- package/dist/cli/ink-cli/state/initialState.js +1 -0
- package/dist/cli/ink-cli/state/types.d.ts +31 -1
- package/dist/cli/ink-cli/state/types.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/commandOverlays.js +1 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +2 -1
- package/dist/cli/utils/api-key-setup.d.ts.map +1 -1
- package/dist/cli/utils/api-key-setup.js +13 -90
- package/dist/cli/utils/options.d.ts.map +1 -1
- package/dist/cli/utils/options.js +10 -2
- package/dist/cli/utils/version-check.d.ts +45 -0
- package/dist/cli/utils/version-check.d.ts.map +1 -0
- package/dist/cli/utils/version-check.js +195 -0
- package/dist/config/cli-overrides.d.ts +2 -0
- package/dist/config/cli-overrides.d.ts.map +1 -1
- package/dist/config/cli-overrides.js +9 -0
- package/dist/index.js +67 -37
- package/dist/webui/assets/index-BglIVTSG.css +1 -0
- package/dist/webui/assets/index-DVQWNLpT.js +2059 -0
- package/dist/webui/index.html +2 -2
- package/package.json +10 -8
- package/dist/webui/assets/index-Bh2aB65S.js +0 -2054
- package/dist/webui/assets/index-CUVc7IDL.css +0 -1
|
@@ -21,7 +21,7 @@ import { useTokenCounter } from '../hooks/useTokenCounter.js';
|
|
|
21
21
|
* - Hide spinner during approval wait (user is reviewing, not waiting)
|
|
22
22
|
* - Only show elapsed time after 30s (avoid visual noise for fast operations)
|
|
23
23
|
*/
|
|
24
|
-
export function StatusBar({ agent, isProcessing, isThinking, isCompacting, approvalQueueCount, copyModeEnabled = false, isAwaitingApproval = false, }) {
|
|
24
|
+
export function StatusBar({ agent, isProcessing, isThinking, isCompacting, approvalQueueCount, copyModeEnabled = false, isAwaitingApproval = false, todoExpanded = true, hasTodos = false, }) {
|
|
25
25
|
// Cycle through witty phrases while processing (not during compacting)
|
|
26
26
|
const { phrase } = usePhraseCycler({ isActive: isProcessing && !isCompacting });
|
|
27
27
|
// Track elapsed time during processing
|
|
@@ -42,14 +42,22 @@ export function StatusBar({ agent, isProcessing, isThinking, isCompacting, appro
|
|
|
42
42
|
if (isAwaitingApproval) {
|
|
43
43
|
return null;
|
|
44
44
|
}
|
|
45
|
+
// Build the task toggle hint based on state
|
|
46
|
+
const todoHint = hasTodos
|
|
47
|
+
? todoExpanded
|
|
48
|
+
? 'ctrl+t to hide tasks'
|
|
49
|
+
: 'ctrl+t to show tasks'
|
|
50
|
+
: null;
|
|
45
51
|
// Show compacting state - yellow/orange color to indicate context management
|
|
46
52
|
if (isCompacting) {
|
|
47
53
|
const metaParts = [];
|
|
48
54
|
if (showTime)
|
|
49
55
|
metaParts.push(`(${elapsedTime})`);
|
|
50
56
|
metaParts.push('Esc to cancel');
|
|
57
|
+
if (todoHint)
|
|
58
|
+
metaParts.push(todoHint);
|
|
51
59
|
const metaContent = metaParts.join(' • ');
|
|
52
|
-
return (_jsxs(Box, { paddingX: 1, marginTop: 1,
|
|
60
|
+
return (_jsxs(Box, { paddingX: 1, marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { color: "yellow", children: " \uD83D\uDCE6 Compacting context..." })] }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: metaContent }) })] }));
|
|
53
61
|
}
|
|
54
62
|
// Show initial processing state (before streaming starts) - green/teal color
|
|
55
63
|
// TODO: Rename this event/state to "reasoning" and associate it with actual reasoning tokens
|
|
@@ -61,8 +69,10 @@ export function StatusBar({ agent, isProcessing, isThinking, isCompacting, appro
|
|
|
61
69
|
if (tokenCount)
|
|
62
70
|
metaParts.push(tokenCount);
|
|
63
71
|
metaParts.push('Esc to cancel');
|
|
72
|
+
if (todoHint)
|
|
73
|
+
metaParts.push(todoHint);
|
|
64
74
|
const metaContent = metaParts.join(' • ');
|
|
65
|
-
return (_jsxs(Box, { paddingX: 1, marginTop: 1,
|
|
75
|
+
return (_jsxs(Box, { paddingX: 1, marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsx(Text, { color: "green", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { color: "green", children: [" ", phrase] })] }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: metaContent }) })] }));
|
|
66
76
|
}
|
|
67
77
|
// Show active streaming state - green/teal color
|
|
68
78
|
// Always use 2-line layout: phrase on first line, meta on second
|
|
@@ -73,6 +83,8 @@ export function StatusBar({ agent, isProcessing, isThinking, isCompacting, appro
|
|
|
73
83
|
if (tokenCount)
|
|
74
84
|
metaParts.push(tokenCount);
|
|
75
85
|
metaParts.push('Esc to cancel');
|
|
86
|
+
if (todoHint)
|
|
87
|
+
metaParts.push(todoHint);
|
|
76
88
|
const metaContent = metaParts.join(' • ');
|
|
77
|
-
return (_jsxs(Box, { paddingX: 1, marginTop: 1,
|
|
89
|
+
return (_jsxs(Box, { paddingX: 1, marginTop: 1, flexDirection: "column", children: [_jsxs(Box, { flexDirection: "row", alignItems: "center", children: [_jsx(Text, { color: "green", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { color: "green", children: [" ", phrase] }), approvalQueueCount > 0 && (_jsxs(Text, { color: "yellowBright", children: [" \u2022 ", approvalQueueCount, " queued"] }))] }), _jsx(Box, { marginLeft: 2, children: _jsx(Text, { color: "gray", children: metaContent }) })] }));
|
|
78
90
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TodoPanel Component
|
|
3
|
+
*
|
|
4
|
+
* Displays the current todo list for workflow tracking.
|
|
5
|
+
* Shows todos with their status indicators (pending, in progress, completed).
|
|
6
|
+
*
|
|
7
|
+
* Display modes:
|
|
8
|
+
* - Processing + Collapsed: Shows "Next:" with the next pending/in-progress task
|
|
9
|
+
* - Processing + Expanded: Shows simple checklist with ☐/☑ indicators below status bar
|
|
10
|
+
* - Idle + Expanded: Shows boxed format with header
|
|
11
|
+
* - Idle + Collapsed: Hidden
|
|
12
|
+
*/
|
|
13
|
+
import type { TodoItem } from '../state/types.js';
|
|
14
|
+
interface TodoPanelProps {
|
|
15
|
+
todos: TodoItem[];
|
|
16
|
+
/** Whether to show the full list or just the next task */
|
|
17
|
+
isExpanded: boolean;
|
|
18
|
+
/** Whether the agent is currently processing (affects display style) */
|
|
19
|
+
isProcessing?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* TodoPanel - Shows current todos for workflow tracking
|
|
23
|
+
*/
|
|
24
|
+
export declare function TodoPanel({ todos, isExpanded, isProcessing }: TodoPanelProps): import("react/jsx-runtime").JSX.Element | null;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=TodoPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TodoPanel.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/components/TodoPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,mBAAmB,CAAC;AAE9D,UAAU,cAAc;IACpB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,0DAA0D;IAC1D,UAAU,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAiBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,YAAoB,EAAE,EAAE,cAAc,kDAkHpF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
/**
|
|
4
|
+
* Get status indicator for a todo item (used in boxed mode)
|
|
5
|
+
*/
|
|
6
|
+
function getStatusIndicator(status) {
|
|
7
|
+
switch (status) {
|
|
8
|
+
case 'completed':
|
|
9
|
+
return { icon: '✓', color: 'green' };
|
|
10
|
+
case 'in_progress':
|
|
11
|
+
return { icon: '●', color: 'yellow' };
|
|
12
|
+
case 'pending':
|
|
13
|
+
default:
|
|
14
|
+
return { icon: '○', color: 'gray' };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* TodoPanel - Shows current todos for workflow tracking
|
|
19
|
+
*/
|
|
20
|
+
export function TodoPanel({ todos, isExpanded, isProcessing = false }) {
|
|
21
|
+
if (todos.length === 0) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
// Sort todos by position
|
|
25
|
+
const sortedTodos = [...todos].sort((a, b) => a.position - b.position);
|
|
26
|
+
// Find the next task to work on (in_progress first, then first pending)
|
|
27
|
+
const currentTask = sortedTodos.find((t) => t.status === 'in_progress');
|
|
28
|
+
const nextPendingTask = sortedTodos.find((t) => t.status === 'pending');
|
|
29
|
+
const nextTask = currentTask || nextPendingTask;
|
|
30
|
+
// When idle (not processing)
|
|
31
|
+
if (!isProcessing) {
|
|
32
|
+
// Collapsed + idle = hidden
|
|
33
|
+
if (!isExpanded) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
// Expanded + idle = boxed format
|
|
37
|
+
const completedCount = todos.filter((t) => t.status === 'completed').length;
|
|
38
|
+
const totalCount = todos.length;
|
|
39
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "gray", paddingX: 1, marginX: 1, marginBottom: 1, children: [_jsxs(Box, { children: [_jsxs(Text, { bold: true, color: "cyan", children: ["\uD83D\uDCCB Tasks", ' '] }), _jsxs(Text, { color: "gray", children: ["(", completedCount, "/", totalCount, ")"] }), _jsxs(Text, { color: "gray", dimColor: true, children: [' ', "\u00B7 ctrl+t to hide tasks"] })] }), _jsx(Box, { flexDirection: "column", children: sortedTodos.map((todo) => {
|
|
40
|
+
const { icon, color } = getStatusIndicator(todo.status);
|
|
41
|
+
const isCompleted = todo.status === 'completed';
|
|
42
|
+
const isInProgress = todo.status === 'in_progress';
|
|
43
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { color: color, children: [icon, " "] }), _jsx(Text, { color: isCompleted ? 'gray' : isInProgress ? 'white' : 'gray', strikethrough: isCompleted, dimColor: !isInProgress && !isCompleted, children: isInProgress ? todo.activeForm : todo.content })] }, todo.id));
|
|
44
|
+
}) })] }));
|
|
45
|
+
}
|
|
46
|
+
// When processing - use minimal style
|
|
47
|
+
// Collapsed: show current task being worked on
|
|
48
|
+
if (!isExpanded) {
|
|
49
|
+
if (!currentTask) {
|
|
50
|
+
return null; // No active task
|
|
51
|
+
}
|
|
52
|
+
return (_jsx(Box, { paddingX: 1, marginBottom: 1, children: _jsxs(Box, { marginLeft: 2, children: [_jsx(Text, { color: "gray", children: "\u23BF " }), _jsx(Text, { color: "gray", children: currentTask.activeForm })] }) }));
|
|
53
|
+
}
|
|
54
|
+
// Expanded: show simple checklist
|
|
55
|
+
return (_jsx(Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: sortedTodos.map((todo, index) => {
|
|
56
|
+
const isFirst = index === 0;
|
|
57
|
+
const isCompleted = todo.status === 'completed';
|
|
58
|
+
const isInProgress = todo.status === 'in_progress';
|
|
59
|
+
const checkbox = isCompleted ? '☑' : '☐';
|
|
60
|
+
return (_jsxs(Box, { marginLeft: 2, children: [_jsx(Text, { color: "gray", children: isFirst ? '⎿ ' : ' ' }), _jsxs(Text, { color: isCompleted ? 'green' : isInProgress ? 'yellow' : 'white', children: [checkbox, ' '] }), _jsx(Text, { color: isCompleted ? 'gray' : 'white', dimColor: isCompleted, children: todo.content })] }, todo.id));
|
|
61
|
+
}) }));
|
|
62
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/chat/Header.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,UAAU,WAAW;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"Header.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/chat/Header.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGxD,UAAU,WAAW;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,WAAW,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,WAAW,EAAE,EAAE,WAAW,2CAoF1F"}
|
|
@@ -12,5 +12,5 @@ export function Header({ modelName, sessionId, hasActiveSession, startupInfo })
|
|
|
12
12
|
██║ ██║█████╗ ╚███╔╝ ██║ ██║ ██║
|
|
13
13
|
██║ ██║██╔══╝ ██╔██╗ ██║ ██║ ██║
|
|
14
14
|
██████╔╝███████╗██╔╝ ██╗ ██║ ╚██████╔╝
|
|
15
|
-
╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝` }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Model: " }), _jsx(Text, { color: "white", children: modelName }), hasActiveSession && sessionId && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 Session: " }), _jsx(Text, { color: "white", children: sessionId.slice(0, 8) })] }))] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Servers: " }), _jsx(Text, { color: "white", children: startupInfo.connectedServers.count }), _jsx(Text, { color: "gray", children: " \u2022 Tools: " }), _jsx(Text, { color: "white", children: startupInfo.toolCount })] }), startupInfo.failedConnections.length > 0 && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "yellowBright", children: ["\u26A0\uFE0F Failed: ", startupInfo.failedConnections.join(', ')] }) })), startupInfo.logFile && process.env.
|
|
15
|
+
╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝` }) }), _jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Model: " }), _jsx(Text, { color: "white", children: modelName }), hasActiveSession && sessionId && (_jsxs(_Fragment, { children: [_jsx(Text, { color: "gray", children: " \u2022 Session: " }), _jsx(Text, { color: "white", children: sessionId.slice(0, 8) })] }))] }), _jsxs(Box, { flexDirection: "row", children: [_jsx(Text, { color: "gray", children: "Servers: " }), _jsx(Text, { color: "white", children: startupInfo.connectedServers.count }), _jsx(Text, { color: "gray", children: " \u2022 Tools: " }), _jsx(Text, { color: "white", children: startupInfo.toolCount })] }), startupInfo.failedConnections.length > 0 && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "yellowBright", children: ["\u26A0\uFE0F Failed: ", startupInfo.failedConnections.join(', ')] }) })), startupInfo.logFile && process.env.DEXTO_DEV_MODE === 'true' && (_jsx(Box, { flexDirection: "row", children: _jsxs(Text, { color: "gray", children: ["Logs: ", startupInfo.logFile] }) })), startupInfo.updateInfo && (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsxs(Text, { color: "yellow", children: ["\u2B06\uFE0F Update available: ", startupInfo.updateInfo.current, " \u2192", ' ', startupInfo.updateInfo.latest] }), _jsx(Text, { color: "gray", children: " \u2022 Run: " }), _jsx(Text, { color: "cyan", children: startupInfo.updateInfo.updateCommand })] })), startupInfo.needsAgentSync && (_jsxs(Box, { marginTop: startupInfo.updateInfo ? 0 : 1, flexDirection: "row", children: [_jsx(Text, { color: "yellow", children: "\uD83D\uDD04 Agent configs have updates available. Run: " }), _jsx(Text, { color: "cyan", children: "dexto sync-agents" })] })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: " " }) })] }));
|
|
16
16
|
}
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { StyledBox, StyledRow, StyledListItem } from './StyledBox.js';
|
|
4
4
|
export function LogConfigBox({ data }) {
|
|
5
|
-
return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && process.env.
|
|
5
|
+
return (_jsxs(StyledBox, { title: "Logging Configuration", children: [_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(StyledRow, { label: "Current level", value: data.currentLevel, valueColor: "green" }), data.logFile && process.env.DEXTO_DEV_MODE === 'true' && (_jsx(StyledRow, { label: "Log file", value: data.logFile }))] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { color: "gray", children: "Available levels (least to most verbose):" }), data.availableLevels.map((level) => {
|
|
6
6
|
const isCurrent = level === data.currentLevel;
|
|
7
7
|
return (_jsx(StyledListItem, { icon: isCurrent ? '>' : ' ', text: level, isActive: isCurrent }, level));
|
|
8
8
|
})] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Use /log <level> to change level" }) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlternateBufferCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/AlternateBufferCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"AlternateBufferCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/AlternateBufferCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAW,WAAW,EAAE,MAAM,sBAAsB,CAAC;AA4BjE,UAAU,uBAAuB;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,kBAAkB,CAAC,EAC/B,KAAK,EACL,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,YAAmB,GACtB,EAAE,uBAAuB,2CA0UzB"}
|
|
@@ -23,6 +23,7 @@ import { QueuedMessagesDisplay } from '../chat/QueuedMessagesDisplay.js';
|
|
|
23
23
|
import { StatusBar } from '../StatusBar.js';
|
|
24
24
|
import { HistorySearchBar } from '../HistorySearchBar.js';
|
|
25
25
|
import { Footer } from '../Footer.js';
|
|
26
|
+
import { TodoPanel } from '../TodoPanel.js';
|
|
26
27
|
import { VirtualizedList, SCROLL_TO_ITEM_END, } from '../shared/VirtualizedList.js';
|
|
27
28
|
// Containers
|
|
28
29
|
import { InputContainer } from '../../containers/InputContainer.js';
|
|
@@ -41,7 +42,7 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
41
42
|
listRef.current?.scrollBy(delta);
|
|
42
43
|
}, []);
|
|
43
44
|
// Use shared CLI state with keyboard scroll handler
|
|
44
|
-
const { messages, setMessages, pendingMessages, setPendingMessages, dequeuedBuffer, setDequeuedBuffer, queuedMessages, setQueuedMessages, ui, setUi, input, setInput, session, setSession, approval, setApproval, approvalQueue, setApprovalQueue, inputService, buffer, overlayContainerRef, visibleMessages, } = useCLIState({
|
|
45
|
+
const { messages, setMessages, pendingMessages, setPendingMessages, dequeuedBuffer, setDequeuedBuffer, queuedMessages, setQueuedMessages, todos, setTodos, ui, setUi, input, setInput, session, setSession, approval, setApproval, approvalQueue, setApprovalQueue, inputService, buffer, overlayContainerRef, visibleMessages, } = useCLIState({
|
|
45
46
|
agent,
|
|
46
47
|
initialSessionId,
|
|
47
48
|
startupInfo,
|
|
@@ -98,19 +99,28 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
98
99
|
// Build list data: header as first item, then finalized + pending + dequeued buffer
|
|
99
100
|
// In alternate buffer mode, everything is re-rendered anyway, so we combine all
|
|
100
101
|
// Order: finalized messages → pending/streaming → dequeued user messages (guarantees order)
|
|
102
|
+
// IMPORTANT: Deduplicate by ID to prevent race condition where a message appears in both
|
|
103
|
+
// finalized (messages) and pending during the brief window between setState calls
|
|
101
104
|
const listData = useMemo(() => {
|
|
102
105
|
const items = [{ type: 'header' }];
|
|
106
|
+
const seenIds = new Set();
|
|
103
107
|
for (const msg of visibleMessages) {
|
|
104
108
|
items.push({ type: 'message', message: msg });
|
|
109
|
+
seenIds.add(msg.id);
|
|
105
110
|
}
|
|
106
|
-
// Add pending/streaming messages
|
|
111
|
+
// Add pending/streaming messages (skip if already in finalized - race condition guard)
|
|
107
112
|
for (const msg of pendingMessages) {
|
|
108
|
-
|
|
113
|
+
if (!seenIds.has(msg.id)) {
|
|
114
|
+
items.push({ type: 'message', message: msg });
|
|
115
|
+
seenIds.add(msg.id);
|
|
116
|
+
}
|
|
109
117
|
}
|
|
110
118
|
// Add dequeued buffer (user messages waiting to be flushed to finalized)
|
|
111
119
|
// These render AFTER pending to guarantee correct visual order
|
|
112
120
|
for (const msg of dequeuedBuffer) {
|
|
113
|
-
|
|
121
|
+
if (!seenIds.has(msg.id)) {
|
|
122
|
+
items.push({ type: 'message', message: msg });
|
|
123
|
+
}
|
|
114
124
|
}
|
|
115
125
|
return items;
|
|
116
126
|
}, [visibleMessages, pendingMessages, dequeuedBuffer]);
|
|
@@ -162,5 +172,5 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
162
172
|
return 'header';
|
|
163
173
|
return item.message.id;
|
|
164
174
|
}, []);
|
|
165
|
-
return (_jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [_jsx(Box, { ref: listContainerRef, flexGrow: 1, flexShrink: 1, minHeight: 0, children: _jsx(VirtualizedList, { ref: listRef, data: listData, renderItem: renderListItem, estimatedItemHeight: estimateItemHeight, keyExtractor: getItemKey, initialScrollIndex: SCROLL_TO_ITEM_END, initialScrollOffsetInIndex: SCROLL_TO_ITEM_END }) }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(StatusBar, { agent: agent, isProcessing: ui.isProcessing, isThinking: ui.isThinking, isCompacting: ui.isCompacting, approvalQueueCount: approvalQueue.length, copyModeEnabled: ui.copyModeEnabled, isAwaitingApproval: approval !== null }), selectionHintVisible && (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: "yellowBright", children: "\uD83D\uDCA1 Tip: Hold Option (\u2325) and click to select text, or press Ctrl+S to toggle copy mode" }) })), _jsx(QueuedMessagesDisplay, { messages: queuedMessages }), _jsx(InputContainer, { ref: inputContainerRef, buffer: buffer, input: input, ui: ui, session: session, approval: approval, queuedMessages: queuedMessages, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setPendingMessages: setPendingMessages, setDequeuedBuffer: setDequeuedBuffer, setQueuedMessages: setQueuedMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, onKeyboardScroll: handleKeyboardScroll, useStreaming: useStreaming }), _jsx(OverlayContainer, { ref: overlayContainerRef, ui: ui, input: input, session: session, approval: approval, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, buffer: buffer, onSubmitPromptCommand: handleSubmitPromptCommand }), ui.exitWarningShown && (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "yellowBright", bold: true, children: "\u26A0 Press Ctrl+C again to exit" }), _jsx(Text, { color: "gray", children: " (or press any key to cancel)" })] })), _jsx(Footer, { modelName: session.modelName, cwd: process.cwd(), autoApproveEdits: ui.autoApproveEdits, isShellMode: buffer.text.startsWith('!') }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
175
|
+
return (_jsxs(Box, { flexDirection: "column", height: terminalHeight, children: [_jsx(Box, { ref: listContainerRef, flexGrow: 1, flexShrink: 1, minHeight: 0, children: _jsx(VirtualizedList, { ref: listRef, data: listData, renderItem: renderListItem, estimatedItemHeight: estimateItemHeight, keyExtractor: getItemKey, initialScrollIndex: SCROLL_TO_ITEM_END, initialScrollOffsetInIndex: SCROLL_TO_ITEM_END }) }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(StatusBar, { agent: agent, isProcessing: ui.isProcessing, isThinking: ui.isThinking, isCompacting: ui.isCompacting, approvalQueueCount: approvalQueue.length, copyModeEnabled: ui.copyModeEnabled, isAwaitingApproval: approval !== null, todoExpanded: ui.todoExpanded, hasTodos: todos.some((t) => t.status !== 'completed') }), _jsx(TodoPanel, { todos: todos, isExpanded: ui.todoExpanded, isProcessing: ui.isProcessing }), selectionHintVisible && (_jsx(Box, { paddingX: 1, children: _jsx(Text, { color: "yellowBright", children: "\uD83D\uDCA1 Tip: Hold Option (\u2325) and click to select text, or press Ctrl+S to toggle copy mode" }) })), _jsx(QueuedMessagesDisplay, { messages: queuedMessages }), _jsx(InputContainer, { ref: inputContainerRef, buffer: buffer, input: input, ui: ui, session: session, approval: approval, queuedMessages: queuedMessages, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setPendingMessages: setPendingMessages, setDequeuedBuffer: setDequeuedBuffer, setQueuedMessages: setQueuedMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, setTodos: setTodos, agent: agent, inputService: inputService, onKeyboardScroll: handleKeyboardScroll, useStreaming: useStreaming }), _jsx(OverlayContainer, { ref: overlayContainerRef, ui: ui, input: input, session: session, approval: approval, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, buffer: buffer, onSubmitPromptCommand: handleSubmitPromptCommand }), ui.exitWarningShown && (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "yellowBright", bold: true, children: "\u26A0 Press Ctrl+C again to exit" }), _jsx(Text, { color: "gray", children: " (or press any key to cancel)" })] })), _jsx(Footer, { agent: agent, sessionId: session.id, modelName: session.modelName, cwd: process.cwd(), autoApproveEdits: ui.autoApproveEdits, isShellMode: buffer.text.startsWith('!') }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
166
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StaticCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/StaticCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"StaticCLI.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/modes/StaticCLI.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAM9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAmBxD,UAAU,cAAc;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,gBAAgB,EAChB,WAAW,EACX,YAAmB,GACtB,EAAE,cAAc,2CAoOhB"}
|
|
@@ -28,12 +28,13 @@ import { QueuedMessagesDisplay } from '../chat/QueuedMessagesDisplay.js';
|
|
|
28
28
|
import { StatusBar } from '../StatusBar.js';
|
|
29
29
|
import { HistorySearchBar } from '../HistorySearchBar.js';
|
|
30
30
|
import { Footer } from '../Footer.js';
|
|
31
|
+
import { TodoPanel } from '../TodoPanel.js';
|
|
31
32
|
// Containers
|
|
32
33
|
import { InputContainer } from '../../containers/InputContainer.js';
|
|
33
34
|
import { OverlayContainer } from '../../containers/OverlayContainer.js';
|
|
34
35
|
export function StaticCLI({ agent, initialSessionId, startupInfo, useStreaming = true, }) {
|
|
35
36
|
// Use shared CLI state (no keyboard scroll in Static mode)
|
|
36
|
-
const { messages, setMessages, pendingMessages, setPendingMessages, dequeuedBuffer, setDequeuedBuffer, queuedMessages, setQueuedMessages, ui, setUi, input, setInput, session, setSession, approval, setApproval, approvalQueue, setApprovalQueue, inputService, buffer, overlayContainerRef, visibleMessages, } = useCLIState({
|
|
37
|
+
const { messages, setMessages, pendingMessages, setPendingMessages, dequeuedBuffer, setDequeuedBuffer, queuedMessages, setQueuedMessages, todos, setTodos, ui, setUi, input, setInput, session, setSession, approval, setApproval, approvalQueue, setApprovalQueue, inputService, buffer, overlayContainerRef, visibleMessages, } = useCLIState({
|
|
37
38
|
agent,
|
|
38
39
|
initialSessionId,
|
|
39
40
|
startupInfo,
|
|
@@ -98,5 +99,5 @@ export function StaticCLI({ agent, initialSessionId, startupInfo, useStreaming =
|
|
|
98
99
|
startupInfo,
|
|
99
100
|
terminalWidth,
|
|
100
101
|
]);
|
|
101
|
-
return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, children: [_jsx(Static, { items: staticItems, children: (item) => item }, staticRemountKey), pendingMessages.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), dequeuedBuffer.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(StatusBar, { agent: agent, isProcessing: ui.isProcessing, isThinking: ui.isThinking, isCompacting: ui.isCompacting, approvalQueueCount: approvalQueue.length, copyModeEnabled: ui.copyModeEnabled, isAwaitingApproval: approval !== null }), _jsx(QueuedMessagesDisplay, { messages: queuedMessages }), _jsx(InputContainer, { ref: inputContainerRef, buffer: buffer, input: input, ui: ui, session: session, approval: approval, queuedMessages: queuedMessages, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setPendingMessages: setPendingMessages, setDequeuedBuffer: setDequeuedBuffer, setQueuedMessages: setQueuedMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, useStreaming: useStreaming }), _jsx(OverlayContainer, { ref: overlayContainerRef, ui: ui, input: input, session: session, approval: approval, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, buffer: buffer, refreshStatic: refreshStatic, onSubmitPromptCommand: handleSubmitPromptCommand }), ui.exitWarningShown && (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "yellowBright", bold: true, children: "\u26A0 Press Ctrl+C again to exit" }), _jsx(Text, { color: "gray", children: " (or press any key to cancel)" })] })), _jsx(Footer, { modelName: session.modelName, cwd: process.cwd(), autoApproveEdits: ui.autoApproveEdits, isShellMode: buffer.text.startsWith('!') }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
102
|
+
return (_jsxs(Box, { flexDirection: "column", width: terminalWidth, children: [_jsx(Static, { items: staticItems, children: (item) => item }, staticRemountKey), pendingMessages.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), dequeuedBuffer.map((message) => (_jsx(MessageItem, { message: message, terminalWidth: terminalWidth }, message.id))), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [_jsx(StatusBar, { agent: agent, isProcessing: ui.isProcessing, isThinking: ui.isThinking, isCompacting: ui.isCompacting, approvalQueueCount: approvalQueue.length, copyModeEnabled: ui.copyModeEnabled, isAwaitingApproval: approval !== null, todoExpanded: ui.todoExpanded, hasTodos: todos.some((t) => t.status !== 'completed') }), _jsx(TodoPanel, { todos: todos, isExpanded: ui.todoExpanded, isProcessing: ui.isProcessing }), _jsx(QueuedMessagesDisplay, { messages: queuedMessages }), _jsx(InputContainer, { ref: inputContainerRef, buffer: buffer, input: input, ui: ui, session: session, approval: approval, queuedMessages: queuedMessages, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setPendingMessages: setPendingMessages, setDequeuedBuffer: setDequeuedBuffer, setQueuedMessages: setQueuedMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, setTodos: setTodos, agent: agent, inputService: inputService, useStreaming: useStreaming }), _jsx(OverlayContainer, { ref: overlayContainerRef, ui: ui, input: input, session: session, approval: approval, setInput: setInput, setUi: setUi, setSession: setSession, setMessages: setMessages, setApproval: setApproval, setApprovalQueue: setApprovalQueue, agent: agent, inputService: inputService, buffer: buffer, refreshStatic: refreshStatic, onSubmitPromptCommand: handleSubmitPromptCommand }), ui.exitWarningShown && (_jsxs(Box, { paddingX: 1, children: [_jsx(Text, { color: "yellowBright", bold: true, children: "\u26A0 Press Ctrl+C again to exit" }), _jsx(Text, { color: "gray", children: " (or press any key to cancel)" })] })), _jsx(Footer, { agent: agent, sessionId: session.id, modelName: session.modelName, cwd: process.cwd(), autoApproveEdits: ui.autoApproveEdits, isShellMode: buffer.text.startsWith('!') }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
102
103
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextStatsOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ContextStatsOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAA+D,MAAM,OAAO,CAAC;AAEpF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,UAAU,wBAAwB;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACtC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;
|
|
1
|
+
{"version":3,"file":"ContextStatsOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ContextStatsOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAA+D,MAAM,OAAO,CAAC;AAEpF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,UAAU,wBAAwB;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACtC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA6JD;;GAEG;AACH,QAAA,MAAM,mBAAmB,4GAoWxB,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -202,7 +202,8 @@ const ContextStatsOverlay = forwardRef(function ContextStatsOverlay({ isVisible,
|
|
|
202
202
|
const percent = totalTokenSpace > 0 ? ((tokens / totalTokenSpace) * 100).toFixed(1) : '0.0';
|
|
203
203
|
return `${percent}%`;
|
|
204
204
|
};
|
|
205
|
-
const
|
|
205
|
+
const usedTokens = stats.estimatedTokens + autoCompactBuffer;
|
|
206
|
+
const tokenDisplay = `~${formatTokens(usedTokens)}`;
|
|
206
207
|
const isToolsExpanded = expandedSections.has('tools');
|
|
207
208
|
// Create stacked bar segments
|
|
208
209
|
// Uses maxContextTokens (effective limit) + autoCompactBuffer as the full bar
|
|
@@ -227,7 +228,7 @@ const ContextStatsOverlay = forwardRef(function ContextStatsOverlay({ isVisible,
|
|
|
227
228
|
return (_jsx(Text, { color: "white", children: isHighlighted
|
|
228
229
|
? '▼'.repeat(segment.width)
|
|
229
230
|
: ' '.repeat(segment.width) }, idx));
|
|
230
|
-
}) }), _jsx(Box, { children: barSegments.map((segment, idx) => (_jsx(Text, { color: segment.color, children: segment.char.repeat(segment.width) }, idx))) }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "gray", children: [tokenDisplay, " / ", formatTokens(
|
|
231
|
+
}) }), _jsx(Box, { children: barSegments.map((segment, idx) => (_jsx(Text, { color: segment.color, children: segment.char.repeat(segment.width) }, idx))) }), _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: "gray", children: [tokenDisplay, " / ", formatTokens(totalTokenSpace), " tokens"] }), _jsx(Text, { color: "gray", children: " \u2022 " }), _jsxs(Text, { color: stats.usagePercent > 80
|
|
231
232
|
? 'red'
|
|
232
233
|
: stats.usagePercent > 60
|
|
233
234
|
? 'yellow'
|
|
@@ -235,6 +236,6 @@ const ContextStatsOverlay = forwardRef(function ContextStatsOverlay({ isVisible,
|
|
|
235
236
|
.sort((a, b) => b.tokens - a.tokens)
|
|
236
237
|
.map((tool, idx, arr) => (_jsxs(Text, { color: "gray", dimColor: true, children: [idx === arr.length - 1 ? '└─' : '├─', ' ', _jsx(Text, { color: "yellow", dimColor: true, children: tool.name }), ": ", formatTokens(tool.tokens), " (", pct(tool.tokens), ")"] }, tool.name)))) })), renderRow(2, 'messages', 'Messages', stats.breakdown.messages, false), renderRow(3, 'freeSpace', 'Free space', freeTokens, false), renderRow(4, 'autoCompactBuffer', bufferPercent > 0
|
|
237
238
|
? `Auto compact buffer (${bufferPercent}%)`
|
|
238
|
-
: 'Auto compact buffer', autoCompactBuffer, true)] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Messages: ", stats.filteredMessageCount, " visible (", stats.messageCount, " total)"] }), stats.prunedToolCount > 0 && (_jsxs(Text, { color: "yellow", children: ["\uD83D\uDDD1\uFE0F ", stats.prunedToolCount, " tool output(s) pruned"] })), stats.
|
|
239
|
+
: 'Auto compact buffer', autoCompactBuffer, true)] }), _jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: ["Messages: ", stats.filteredMessageCount, " visible (", stats.messageCount, " total)"] }), stats.prunedToolCount > 0 && (_jsxs(Text, { color: "yellow", children: ["\uD83D\uDDD1\uFE0F ", stats.prunedToolCount, " tool output(s) pruned"] })), stats.hasSummary && (_jsx(Text, { color: "blue", children: "\uD83D\uDCE6 Context has been compacted (summary present)" })), stats.usagePercent > 100 && (_jsx(Text, { color: "yellow", children: "\uD83D\uDCA1 Use /compact to manually compact, or send a message to trigger auto-compaction" }))] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "\u2191\u2193: navigate | Enter: expand/collapse | Esc: close" }) })] }));
|
|
239
240
|
});
|
|
240
241
|
export default ContextStatsOverlay;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExportWizard Component
|
|
3
|
+
* Interactive wizard for exporting conversation to markdown or JSON
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { Key } from '../../hooks/useInputOrchestrator.js';
|
|
7
|
+
import type { DextoAgent } from '@dexto/core';
|
|
8
|
+
interface ExportWizardProps {
|
|
9
|
+
isVisible: boolean;
|
|
10
|
+
agent: DextoAgent;
|
|
11
|
+
sessionId: string | null;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
export interface ExportWizardHandle {
|
|
15
|
+
handleInput: (input: string, key: Key) => boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Interactive wizard for exporting conversation
|
|
19
|
+
*/
|
|
20
|
+
declare const ExportWizard: React.ForwardRefExoticComponent<ExportWizardProps & React.RefAttributes<ExportWizardHandle>>;
|
|
21
|
+
export default ExportWizard;
|
|
22
|
+
//# sourceMappingURL=ExportWizard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportWizard.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/ExportWizard.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA4E,MAAM,OAAO,CAAC;AAIjG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAY9C,UAAU,iBAAiB;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AA4JD;;GAEG;AACH,QAAA,MAAM,YAAY,8FA+UhB,CAAC;AAEH,eAAe,YAAY,CAAC"}
|