dexto 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agent-registry.json +9 -0
- package/dist/agents/coding-agent/coding-agent.yml +53 -6
- package/dist/agents/explore-agent/explore-agent.yml +124 -0
- package/dist/cli/approval/cli-approval-handler.d.ts +28 -0
- package/dist/cli/approval/cli-approval-handler.d.ts.map +1 -0
- package/dist/cli/approval/cli-approval-handler.js +146 -0
- package/dist/cli/approval/index.d.ts +7 -0
- package/dist/cli/approval/index.d.ts.map +1 -0
- package/dist/cli/approval/index.js +6 -0
- package/dist/cli/cli-subscriber.d.ts +4 -1
- package/dist/cli/cli-subscriber.d.ts.map +1 -1
- package/dist/cli/cli-subscriber.js +31 -1
- package/dist/cli/commands/interactive-commands/commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/commands.js +2 -1
- package/dist/cli/commands/interactive-commands/general-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/general-commands.js +163 -3
- package/dist/cli/commands/interactive-commands/session/index.d.ts +2 -1
- package/dist/cli/commands/interactive-commands/session/index.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/index.js +2 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts +7 -0
- package/dist/cli/commands/interactive-commands/session/session-commands.d.ts.map +1 -1
- package/dist/cli/commands/interactive-commands/session/session-commands.js +16 -0
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts +3 -1
- package/dist/cli/ink-cli/InkCLIRefactored.d.ts.map +1 -1
- package/dist/cli/ink-cli/InkCLIRefactored.js +36 -7
- package/dist/cli/ink-cli/components/ApprovalPrompt.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/ApprovalPrompt.js +10 -2
- package/dist/cli/ink-cli/components/Footer.d.ts +3 -1
- package/dist/cli/ink-cli/components/Footer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/Footer.js +4 -2
- package/dist/cli/ink-cli/components/StatusBar.d.ts +2 -1
- package/dist/cli/ink-cli/components/StatusBar.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/StatusBar.js +12 -3
- package/dist/cli/ink-cli/components/TextBufferInput.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/TextBufferInput.js +3 -2
- package/dist/cli/ink-cli/components/chat/MessageItem.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/chat/MessageItem.js +21 -3
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/AlternateBufferCLI.js +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/modes/StaticCLI.js +1 -1
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts +26 -0
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/ContextStatsOverlay.js +240 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts +21 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.d.ts.map +1 -0
- package/dist/cli/ink-cli/components/overlays/SessionRenameOverlay.js +63 -0
- package/dist/cli/ink-cli/components/overlays/SessionSelectorRefactored.js +2 -2
- package/dist/cli/ink-cli/components/renderers/SearchRenderer.d.ts.map +1 -1
- package/dist/cli/ink-cli/components/renderers/SearchRenderer.js +15 -1
- package/dist/cli/ink-cli/components/shared/MarkdownText.js +2 -2
- package/dist/cli/ink-cli/constants/processingPhrases.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/processingPhrases.js +15 -4
- package/dist/cli/ink-cli/constants/tips.d.ts.map +1 -1
- package/dist/cli/ink-cli/constants/tips.js +4 -1
- package/dist/cli/ink-cli/containers/InputContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/InputContainer.js +8 -0
- package/dist/cli/ink-cli/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/cli/ink-cli/containers/OverlayContainer.js +53 -2
- package/dist/cli/ink-cli/contexts/SoundContext.d.ts +23 -0
- package/dist/cli/ink-cli/contexts/SoundContext.d.ts.map +1 -0
- package/dist/cli/ink-cli/contexts/SoundContext.js +22 -0
- package/dist/cli/ink-cli/contexts/index.d.ts +1 -0
- package/dist/cli/ink-cli/contexts/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/contexts/index.js +1 -0
- package/dist/cli/ink-cli/hooks/useCLIState.d.ts.map +1 -1
- package/dist/cli/ink-cli/hooks/useCLIState.js +1 -0
- package/dist/cli/ink-cli/services/processStream.d.ts +4 -0
- package/dist/cli/ink-cli/services/processStream.d.ts.map +1 -1
- package/dist/cli/ink-cli/services/processStream.js +152 -14
- 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 +25 -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 +4 -0
- package/dist/cli/ink-cli/utils/index.d.ts +1 -0
- package/dist/cli/ink-cli/utils/index.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/index.js +2 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts +24 -0
- package/dist/cli/ink-cli/utils/messageFormatting.d.ts.map +1 -1
- package/dist/cli/ink-cli/utils/messageFormatting.js +43 -4
- package/dist/cli/ink-cli/utils/soundNotification.d.ts +71 -0
- package/dist/cli/ink-cli/utils/soundNotification.d.ts.map +1 -0
- package/dist/cli/ink-cli/utils/soundNotification.js +203 -0
- package/dist/index.js +10 -15
- package/dist/webui/assets/{index-8j-KMkX1.js → index-Bh2aB65S.js} +209 -209
- package/dist/webui/assets/index-CUVc7IDL.css +1 -0
- package/dist/webui/index.html +2 -2
- package/package.json +7 -7
- package/dist/webui/assets/index-c_AX24V4.css +0 -1
|
@@ -162,5 +162,5 @@ export function AlternateBufferCLI({ agent, initialSessionId, startupInfo, onSel
|
|
|
162
162
|
return 'header';
|
|
163
163
|
return item.message.id;
|
|
164
164
|
}, []);
|
|
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, 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 }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
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 }))] })] }));
|
|
166
166
|
}
|
|
@@ -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;AAkBxD,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,
|
|
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;AAkBxD,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,2CAsNhB"}
|
|
@@ -98,5 +98,5 @@ export function StaticCLI({ agent, initialSessionId, startupInfo, useStreaming =
|
|
|
98
98
|
startupInfo,
|
|
99
99
|
terminalWidth,
|
|
100
100
|
]);
|
|
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, 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 }), ui.historySearch.isActive && (_jsx(HistorySearchBar, { query: ui.historySearch.query, hasMatch: historySearchHasMatch }))] })] }));
|
|
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
102
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextStatsOverlay Component
|
|
3
|
+
* Interactive overlay for viewing context window usage statistics
|
|
4
|
+
* Features:
|
|
5
|
+
* - Stacked colored progress bar showing breakdown
|
|
6
|
+
* - Navigate with arrow keys to highlight items
|
|
7
|
+
* - Press Enter to expand/collapse sections (e.g., Tools)
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import type { Key } from '../../hooks/useInputOrchestrator.js';
|
|
11
|
+
import type { DextoAgent } from '@dexto/core';
|
|
12
|
+
interface ContextStatsOverlayProps {
|
|
13
|
+
isVisible: boolean;
|
|
14
|
+
onClose: () => void;
|
|
15
|
+
agent: DextoAgent;
|
|
16
|
+
sessionId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ContextStatsOverlayHandle {
|
|
19
|
+
handleInput: (input: string, key: Key) => boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Context stats overlay with selectable breakdown items
|
|
23
|
+
*/
|
|
24
|
+
declare const ContextStatsOverlay: React.ForwardRefExoticComponent<ContextStatsOverlayProps & React.RefAttributes<ContextStatsOverlayHandle>>;
|
|
25
|
+
export default ContextStatsOverlay;
|
|
26
|
+
//# sourceMappingURL=ContextStatsOverlay.d.ts.map
|
|
@@ -0,0 +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;AA8JD;;GAEG;AACH,QAAA,MAAM,mBAAmB,4GAsWxB,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* ContextStatsOverlay Component
|
|
4
|
+
* Interactive overlay for viewing context window usage statistics
|
|
5
|
+
* Features:
|
|
6
|
+
* - Stacked colored progress bar showing breakdown
|
|
7
|
+
* - Navigate with arrow keys to highlight items
|
|
8
|
+
* - Press Enter to expand/collapse sections (e.g., Tools)
|
|
9
|
+
*/
|
|
10
|
+
import { useState, useEffect, forwardRef, useImperativeHandle } from 'react';
|
|
11
|
+
import { Box, Text } from 'ink';
|
|
12
|
+
const BREAKDOWN_ITEMS = [
|
|
13
|
+
'systemPrompt',
|
|
14
|
+
'tools',
|
|
15
|
+
'messages',
|
|
16
|
+
'freeSpace',
|
|
17
|
+
'autoCompactBuffer',
|
|
18
|
+
];
|
|
19
|
+
// Colors for each breakdown category
|
|
20
|
+
const ITEM_COLORS = {
|
|
21
|
+
systemPrompt: 'cyan',
|
|
22
|
+
tools: 'yellow',
|
|
23
|
+
messages: 'blue',
|
|
24
|
+
freeSpace: 'gray',
|
|
25
|
+
autoCompactBuffer: 'magenta',
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Format token count for display (e.g., 1500 -> "1.5k")
|
|
29
|
+
*/
|
|
30
|
+
function formatTokens(tokens) {
|
|
31
|
+
if (tokens >= 1000) {
|
|
32
|
+
return `${(tokens / 1000).toFixed(1)}k`;
|
|
33
|
+
}
|
|
34
|
+
return tokens.toLocaleString();
|
|
35
|
+
}
|
|
36
|
+
function createStackedBar(breakdown, maxContextTokens, thresholdPercent, totalWidth = 40) {
|
|
37
|
+
const segments = [];
|
|
38
|
+
// Calculate auto compact buffer (the reserved margin for early compaction)
|
|
39
|
+
// maxContextTokens already has thresholdPercent applied, so derive buffer as:
|
|
40
|
+
// buffer = maxContextTokens * (1 - thresholdPercent) / thresholdPercent
|
|
41
|
+
const autoCompactBuffer = thresholdPercent > 0 && thresholdPercent < 1.0
|
|
42
|
+
? Math.floor((maxContextTokens * (1 - thresholdPercent)) / thresholdPercent)
|
|
43
|
+
: 0;
|
|
44
|
+
// Total space = effective limit + buffer
|
|
45
|
+
const totalTokenSpace = maxContextTokens + autoCompactBuffer;
|
|
46
|
+
// Calculate widths for each segment (proportional to token count)
|
|
47
|
+
const usedTokens = breakdown.systemPrompt + breakdown.tools.total + breakdown.messages;
|
|
48
|
+
const freeTokens = Math.max(0, maxContextTokens - usedTokens);
|
|
49
|
+
// Helper to calculate width (minimum 1 char if tokens > 0, proportional otherwise)
|
|
50
|
+
const getWidth = (tokens) => {
|
|
51
|
+
if (tokens <= 0)
|
|
52
|
+
return 0;
|
|
53
|
+
const proportional = Math.round((tokens / totalTokenSpace) * totalWidth);
|
|
54
|
+
return Math.max(1, proportional);
|
|
55
|
+
};
|
|
56
|
+
// Add used segments
|
|
57
|
+
const sysWidth = getWidth(breakdown.systemPrompt);
|
|
58
|
+
const toolsWidth = getWidth(breakdown.tools.total);
|
|
59
|
+
const msgsWidth = getWidth(breakdown.messages);
|
|
60
|
+
const freeWidth = getWidth(freeTokens);
|
|
61
|
+
const reservedWidth = getWidth(autoCompactBuffer);
|
|
62
|
+
// Adjust to fit total width (take from free space)
|
|
63
|
+
const totalUsed = sysWidth + toolsWidth + msgsWidth + freeWidth + reservedWidth;
|
|
64
|
+
const adjustment = totalUsed - totalWidth;
|
|
65
|
+
// Apply adjustment to free space (it's the most flexible)
|
|
66
|
+
const adjustedFreeWidth = Math.max(0, freeWidth - adjustment);
|
|
67
|
+
if (sysWidth > 0) {
|
|
68
|
+
segments.push({
|
|
69
|
+
char: '█',
|
|
70
|
+
color: ITEM_COLORS.systemPrompt,
|
|
71
|
+
width: sysWidth,
|
|
72
|
+
item: 'systemPrompt',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (toolsWidth > 0) {
|
|
76
|
+
segments.push({ char: '█', color: ITEM_COLORS.tools, width: toolsWidth, item: 'tools' });
|
|
77
|
+
}
|
|
78
|
+
if (msgsWidth > 0) {
|
|
79
|
+
segments.push({
|
|
80
|
+
char: '█',
|
|
81
|
+
color: ITEM_COLORS.messages,
|
|
82
|
+
width: msgsWidth,
|
|
83
|
+
item: 'messages',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
if (adjustedFreeWidth > 0) {
|
|
87
|
+
segments.push({ char: '░', color: 'gray', width: adjustedFreeWidth, item: 'freeSpace' });
|
|
88
|
+
}
|
|
89
|
+
if (reservedWidth > 0) {
|
|
90
|
+
segments.push({
|
|
91
|
+
char: '▒',
|
|
92
|
+
color: ITEM_COLORS.autoCompactBuffer,
|
|
93
|
+
width: reservedWidth,
|
|
94
|
+
item: 'autoCompactBuffer',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return segments;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Context stats overlay with selectable breakdown items
|
|
101
|
+
*/
|
|
102
|
+
const ContextStatsOverlay = forwardRef(function ContextStatsOverlay({ isVisible, onClose, agent, sessionId }, ref) {
|
|
103
|
+
const [stats, setStats] = useState(null);
|
|
104
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
105
|
+
const [error, setError] = useState(null);
|
|
106
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
107
|
+
const [expandedSections, setExpandedSections] = useState(new Set());
|
|
108
|
+
// Fetch stats when overlay becomes visible
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
if (!isVisible) {
|
|
111
|
+
setStats(null);
|
|
112
|
+
setError(null);
|
|
113
|
+
setSelectedIndex(0);
|
|
114
|
+
setExpandedSections(new Set());
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
let cancelled = false;
|
|
118
|
+
setIsLoading(true);
|
|
119
|
+
const fetchStats = async () => {
|
|
120
|
+
try {
|
|
121
|
+
const contextStats = await agent.getContextStats(sessionId);
|
|
122
|
+
if (!cancelled) {
|
|
123
|
+
setStats(contextStats);
|
|
124
|
+
setIsLoading(false);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (err) {
|
|
128
|
+
if (!cancelled) {
|
|
129
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
130
|
+
setIsLoading(false);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
fetchStats();
|
|
135
|
+
return () => {
|
|
136
|
+
cancelled = true;
|
|
137
|
+
};
|
|
138
|
+
}, [isVisible, agent, sessionId]);
|
|
139
|
+
// Handle keyboard input
|
|
140
|
+
useImperativeHandle(ref, () => ({
|
|
141
|
+
handleInput: (_input, key) => {
|
|
142
|
+
if (!isVisible)
|
|
143
|
+
return false;
|
|
144
|
+
// Escape or 'q' to close
|
|
145
|
+
if (key.escape || _input === 'q') {
|
|
146
|
+
onClose();
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
// Arrow keys for navigation
|
|
150
|
+
if (key.upArrow) {
|
|
151
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
if (key.downArrow) {
|
|
155
|
+
setSelectedIndex((prev) => Math.min(BREAKDOWN_ITEMS.length - 1, prev + 1));
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
// Enter to expand/collapse
|
|
159
|
+
if (key.return) {
|
|
160
|
+
const item = BREAKDOWN_ITEMS[selectedIndex];
|
|
161
|
+
// Only tools is expandable for now
|
|
162
|
+
if (item === 'tools') {
|
|
163
|
+
setExpandedSections((prev) => {
|
|
164
|
+
const next = new Set(prev);
|
|
165
|
+
if (next.has(item)) {
|
|
166
|
+
next.delete(item);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
next.add(item);
|
|
170
|
+
}
|
|
171
|
+
return next;
|
|
172
|
+
});
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
},
|
|
178
|
+
}), [isVisible, onClose, selectedIndex]);
|
|
179
|
+
if (!isVisible)
|
|
180
|
+
return null;
|
|
181
|
+
// Loading state
|
|
182
|
+
if (isLoading) {
|
|
183
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCCA Context Usage" }), _jsx(Text, { color: "gray", children: "Loading..." })] }));
|
|
184
|
+
}
|
|
185
|
+
// Error state
|
|
186
|
+
if (error) {
|
|
187
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "red", paddingX: 2, paddingY: 1, children: [_jsx(Text, { color: "red", bold: true, children: "\u274C Error" }), _jsx(Text, { color: "gray", children: error }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "Press Esc to close" }) })] }));
|
|
188
|
+
}
|
|
189
|
+
if (!stats)
|
|
190
|
+
return null;
|
|
191
|
+
// Calculate auto compact buffer early so it's available for pct()
|
|
192
|
+
// maxContextTokens already has thresholdPercent applied, so we need to derive
|
|
193
|
+
// the buffer as: maxContextTokens * (1 - thresholdPercent) / thresholdPercent
|
|
194
|
+
const autoCompactBuffer = stats.thresholdPercent > 0 && stats.thresholdPercent < 1.0
|
|
195
|
+
? Math.floor((stats.maxContextTokens * (1 - stats.thresholdPercent)) /
|
|
196
|
+
stats.thresholdPercent)
|
|
197
|
+
: 0;
|
|
198
|
+
// Total token space = effective limit + buffer (matches the visual bar)
|
|
199
|
+
const totalTokenSpace = stats.maxContextTokens + autoCompactBuffer;
|
|
200
|
+
// Calculate percentage helper (relative to total token space for bar consistency)
|
|
201
|
+
const pct = (tokens) => {
|
|
202
|
+
const percent = totalTokenSpace > 0 ? ((tokens / totalTokenSpace) * 100).toFixed(1) : '0.0';
|
|
203
|
+
return `${percent}%`;
|
|
204
|
+
};
|
|
205
|
+
const tokenDisplay = `~${formatTokens(stats.estimatedTokens)}`;
|
|
206
|
+
const isToolsExpanded = expandedSections.has('tools');
|
|
207
|
+
// Create stacked bar segments
|
|
208
|
+
// Uses maxContextTokens (effective limit) + autoCompactBuffer as the full bar
|
|
209
|
+
const barSegments = createStackedBar(stats.breakdown, stats.maxContextTokens, stats.thresholdPercent);
|
|
210
|
+
// Helper to render a breakdown row with colored indicator
|
|
211
|
+
const renderRow = (index, item, label, tokens, isLast, expandable) => {
|
|
212
|
+
const isSelected = selectedIndex === index;
|
|
213
|
+
const prefix = isLast ? '└─' : '├─';
|
|
214
|
+
const expandIcon = expandable ? (isToolsExpanded ? '▼' : '▶') : ' ';
|
|
215
|
+
const itemColor = ITEM_COLORS[item];
|
|
216
|
+
// Use different characters for different types
|
|
217
|
+
const indicator = item === 'freeSpace' ? '░' : item === 'autoCompactBuffer' ? '▒' : '█';
|
|
218
|
+
return (_jsxs(Box, { children: [_jsxs(Text, { color: isSelected ? 'white' : 'gray', children: [prefix, " "] }), _jsx(Text, { color: itemColor, bold: isSelected, children: indicator }), _jsxs(Text, { color: isSelected ? 'white' : 'gray', bold: isSelected, children: [' ', expandIcon, " ", label, ": ", formatTokens(tokens), " (", pct(tokens), ")"] }), isSelected && expandable && (_jsxs(Text, { color: "gray", dimColor: true, children: [' ', "(Enter to ", isToolsExpanded ? 'collapse' : 'expand', ")"] }))] }, item));
|
|
219
|
+
};
|
|
220
|
+
// Calculate free space using the actual/estimated tokens
|
|
221
|
+
// maxContextTokens is already the effective limit (with threshold applied)
|
|
222
|
+
const freeTokens = Math.max(0, stats.maxContextTokens - stats.estimatedTokens);
|
|
223
|
+
// Buffer percent for display (autoCompactBuffer already calculated above)
|
|
224
|
+
const bufferPercent = Math.round((1 - stats.thresholdPercent) * 100);
|
|
225
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 2, paddingY: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", bold: true, children: "\uD83D\uDCCA Context Usage" }), _jsxs(Text, { color: "gray", children: [" - ", stats.modelDisplayName] })] }), _jsx(Box, { children: barSegments.map((segment, idx) => {
|
|
226
|
+
const isHighlighted = BREAKDOWN_ITEMS[selectedIndex] === segment.item;
|
|
227
|
+
return (_jsx(Text, { color: "white", children: isHighlighted
|
|
228
|
+
? '▼'.repeat(segment.width)
|
|
229
|
+
: ' '.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(stats.maxContextTokens), " tokens"] }), _jsx(Text, { color: "gray", children: " \u2022 " }), _jsxs(Text, { color: stats.usagePercent > 80
|
|
231
|
+
? 'red'
|
|
232
|
+
: stats.usagePercent > 60
|
|
233
|
+
? 'yellow'
|
|
234
|
+
: 'green', children: [stats.usagePercent, "% used"] })] }), _jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "white", children: "Breakdown:" }), renderRow(0, 'systemPrompt', 'System prompt', stats.breakdown.systemPrompt, false), renderRow(1, 'tools', `Tools (${stats.breakdown.tools.perTool.length})`, stats.breakdown.tools.total, false, true), isToolsExpanded && (_jsx(Box, { flexDirection: "column", marginLeft: 4, children: stats.breakdown.tools.perTool.length === 0 ? (_jsx(Text, { color: "gray", dimColor: true, children: "No tools registered" })) : ([...stats.breakdown.tools.perTool]
|
|
235
|
+
.sort((a, b) => b.tokens - a.tokens)
|
|
236
|
+
.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
|
+
? `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.compactionCount > 0 && (_jsxs(Text, { color: "blue", children: ["\uD83D\uDCE6 Compacted ", stats.compactionCount, " time", stats.compactionCount > 1 ? 's' : ''] })), 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
|
+
export default ContextStatsOverlay;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionRenameOverlay Component
|
|
3
|
+
* Interactive overlay for renaming the current session
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import type { Key } from '../../hooks/useInputOrchestrator.js';
|
|
7
|
+
export interface SessionRenameOverlayProps {
|
|
8
|
+
isVisible: boolean;
|
|
9
|
+
currentTitle: string | undefined;
|
|
10
|
+
onRename: (newTitle: string) => void;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}
|
|
13
|
+
export interface SessionRenameOverlayHandle {
|
|
14
|
+
handleInput: (input: string, key: Key) => boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Session rename overlay - allows user to edit the session title
|
|
18
|
+
*/
|
|
19
|
+
declare const SessionRenameOverlay: React.ForwardRefExoticComponent<SessionRenameOverlayProps & React.RefAttributes<SessionRenameOverlayHandle>>;
|
|
20
|
+
export default SessionRenameOverlay;
|
|
21
|
+
//# sourceMappingURL=SessionRenameOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionRenameOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/overlays/SessionRenameOverlay.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA4E,MAAM,OAAO,CAAC;AAEjG,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAE/D,MAAM,WAAW,yBAAyB;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IACvC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED;;GAEG;AACH,QAAA,MAAM,oBAAoB,8GAkHzB,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* SessionRenameOverlay Component
|
|
4
|
+
* Interactive overlay for renaming the current session
|
|
5
|
+
*/
|
|
6
|
+
import { useState, useEffect, forwardRef, useImperativeHandle, useCallback } from 'react';
|
|
7
|
+
import { Box, Text } from 'ink';
|
|
8
|
+
/**
|
|
9
|
+
* Session rename overlay - allows user to edit the session title
|
|
10
|
+
*/
|
|
11
|
+
const SessionRenameOverlay = forwardRef(function SessionRenameOverlay({ isVisible, currentTitle, onRename, onClose }, ref) {
|
|
12
|
+
const [title, setTitle] = useState(currentTitle || '');
|
|
13
|
+
const [error, setError] = useState(null);
|
|
14
|
+
// Reset when becoming visible
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (isVisible) {
|
|
17
|
+
setTitle(currentTitle || '');
|
|
18
|
+
setError(null);
|
|
19
|
+
}
|
|
20
|
+
}, [isVisible, currentTitle]);
|
|
21
|
+
const handleSubmit = useCallback(() => {
|
|
22
|
+
const trimmedTitle = title.trim();
|
|
23
|
+
if (!trimmedTitle) {
|
|
24
|
+
setError('Title cannot be empty');
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
onRename(trimmedTitle);
|
|
28
|
+
}, [title, onRename]);
|
|
29
|
+
// Handle keyboard input
|
|
30
|
+
useImperativeHandle(ref, () => ({
|
|
31
|
+
handleInput: (input, key) => {
|
|
32
|
+
if (!isVisible)
|
|
33
|
+
return false;
|
|
34
|
+
// Escape to close
|
|
35
|
+
if (key.escape) {
|
|
36
|
+
onClose();
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// Enter to submit
|
|
40
|
+
if (key.return) {
|
|
41
|
+
handleSubmit();
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
// Backspace
|
|
45
|
+
if (key.backspace || key.delete) {
|
|
46
|
+
setTitle((prev) => prev.slice(0, -1));
|
|
47
|
+
setError(null);
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
// Regular character input
|
|
51
|
+
if (input && !key.ctrl && !key.meta) {
|
|
52
|
+
setTitle((prev) => prev + input);
|
|
53
|
+
setError(null);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
},
|
|
58
|
+
}), [isVisible, onClose, handleSubmit]);
|
|
59
|
+
if (!isVisible)
|
|
60
|
+
return null;
|
|
61
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Rename Session" }) }), currentTitle && (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "gray", children: "Current: " }), _jsx(Text, { color: "white", children: currentTitle })] })), _jsx(Box, { flexDirection: "column", children: _jsx(Text, { bold: true, children: "Enter new title:" }) }), _jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "> " }), _jsx(Text, { children: title }), _jsx(Text, { color: "cyan", children: "_" })] }), error && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: error }) })), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "gray", children: "Enter to save \u2022 Esc to cancel" }) })] }));
|
|
62
|
+
});
|
|
63
|
+
export default SessionRenameOverlay;
|
|
@@ -84,12 +84,12 @@ const SessionSelector = forwardRef(function SessionSelector({ isVisible, onSelec
|
|
|
84
84
|
// Format session for display
|
|
85
85
|
const formatSession = (session) => {
|
|
86
86
|
const parts = [];
|
|
87
|
-
// Add title if available, otherwise use "Session" as fallback
|
|
87
|
+
// Add title if available, otherwise use "New Session" as fallback
|
|
88
88
|
if (session.metadata?.title) {
|
|
89
89
|
parts.push(session.metadata.title);
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
|
-
parts.push('Session');
|
|
92
|
+
parts.push('New Session');
|
|
93
93
|
}
|
|
94
94
|
// Always show short ID
|
|
95
95
|
parts.push(session.id.slice(0, 8));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/renderers/SearchRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"SearchRenderer.d.ts","sourceRoot":"","sources":["../../../../../src/cli/ink-cli/components/renderers/SearchRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAerD,UAAU,mBAAmB;IACzB,2CAA2C;IAC3C,IAAI,EAAE,iBAAiB,CAAC;IACxB,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,UAAc,EAAE,EAAE,mBAAmB,2CA8B3E"}
|
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import path from 'path';
|
|
2
3
|
import { Box, Text } from 'ink';
|
|
4
|
+
/**
|
|
5
|
+
* Convert absolute path to relative path from cwd
|
|
6
|
+
*/
|
|
7
|
+
function toRelativePath(absolutePath) {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
const relative = path.relative(cwd, absolutePath);
|
|
10
|
+
if (relative === '')
|
|
11
|
+
return '.';
|
|
12
|
+
if (!relative.startsWith('..') && !path.isAbsolute(relative)) {
|
|
13
|
+
return relative;
|
|
14
|
+
}
|
|
15
|
+
return absolutePath;
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
18
|
* Renders search results with file paths and line numbers.
|
|
5
19
|
* Uses ⎿ character for continuation lines.
|
|
@@ -8,5 +22,5 @@ export function SearchRenderer({ data, maxMatches = 5 }) {
|
|
|
8
22
|
const { pattern, matches, totalMatches, truncated: dataTruncated } = data;
|
|
9
23
|
const displayMatches = matches.slice(0, maxMatches);
|
|
10
24
|
const truncated = dataTruncated || matches.length > maxMatches;
|
|
11
|
-
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', totalMatches, " match", totalMatches !== 1 ? 'es' : '', " for \"", pattern, "\"", truncated && ' (truncated)'] }), displayMatches.map((match, i) => (_jsxs(Text, { color: "gray", wrap: "truncate", children: [' ⎿ ', match.file, match.line > 0 && `:${match.line}`] }, i))), matches.length > maxMatches && (_jsxs(Text, { color: "gray", children: [' ⎿ ', "... ", matches.length - maxMatches, " more"] }))] }));
|
|
25
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Text, { color: "gray", children: [' ⎿ ', totalMatches, " match", totalMatches !== 1 ? 'es' : '', " for \"", pattern, "\"", truncated && ' (truncated)'] }), displayMatches.map((match, i) => (_jsxs(Text, { color: "gray", wrap: "truncate", children: [' ⎿ ', toRelativePath(match.file), match.line > 0 && `:${match.line}`] }, i))), matches.length > maxMatches && (_jsxs(Text, { color: "gray", children: [' ⎿ ', "... ", matches.length - maxMatches, " more"] }))] }));
|
|
12
26
|
}
|
|
@@ -156,8 +156,8 @@ const WrappedParagraphInternal = ({ text, defaultColor, bulletPrefix, isFirstPar
|
|
|
156
156
|
// Parse markdown and convert to ANSI string
|
|
157
157
|
const segments = parseInlineMarkdown(text);
|
|
158
158
|
const ansiString = segmentsToAnsi(segments, defaultColor);
|
|
159
|
-
// Calculate available width
|
|
160
|
-
const prefixWidth = bulletPrefix
|
|
159
|
+
// Calculate available width - always account for bullet indent since all lines get it
|
|
160
|
+
const prefixWidth = bulletPrefix ? stringWidth(bulletPrefix) : 0;
|
|
161
161
|
const availableWidth = Math.max(20, terminalWidth - prefixWidth);
|
|
162
162
|
// Word-wrap the ANSI string
|
|
163
163
|
const wrapped = wrapAnsi(ansiString, availableWidth, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"processingPhrases.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/processingPhrases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EA4ErC,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAGxC"}
|
|
@@ -33,6 +33,7 @@ export const processingPhrases = [
|
|
|
33
33
|
'Elementary, my dear Watson…',
|
|
34
34
|
'Identity theft is not a joke, Jim! …',
|
|
35
35
|
"I'm not superstitious, but I am a little stitious…",
|
|
36
|
+
'Why waste time say lot word when few word do trick?…',
|
|
36
37
|
// Playful
|
|
37
38
|
'Let me cook…',
|
|
38
39
|
'Manifesting greatness…',
|
|
@@ -50,17 +51,27 @@ export const processingPhrases = [
|
|
|
50
51
|
'Zapping…',
|
|
51
52
|
'Braining…',
|
|
52
53
|
'Using all 3 brain cells…',
|
|
54
|
+
"I'm not lazy, I'm just on energy-saving mode…",
|
|
55
|
+
'I came. I saw. I made it awkward…',
|
|
56
|
+
'My boss told me to have a good day, so I went home…',
|
|
57
|
+
"I put the 'pro' in procrastination…",
|
|
58
|
+
'Delulu is the solulu…',
|
|
59
|
+
'Zombies eat brains. You are safe…',
|
|
53
60
|
//'Installing malware (just kidding)…',
|
|
54
61
|
// Vines
|
|
55
62
|
'Look at all those chickens…',
|
|
56
|
-
'What are those
|
|
63
|
+
'What are those!!…',
|
|
57
64
|
'He needs some milk…',
|
|
58
65
|
'Something came in the mail today…',
|
|
59
|
-
'Road work ahead?
|
|
66
|
+
'Road work ahead? I sure hope it does…',
|
|
60
67
|
'Merry Chrysler…',
|
|
61
|
-
"I'm in me mum's car.
|
|
62
|
-
'I could have dropped my croissant
|
|
68
|
+
"I'm in me mum's car. Vroom vroom…",
|
|
69
|
+
'Stop! I could have dropped my croissant!…',
|
|
63
70
|
'That was legitness…',
|
|
71
|
+
'Why are you running?…',
|
|
72
|
+
'What da dog doin?…',
|
|
73
|
+
'Can I pet that dawg?…',
|
|
74
|
+
'And they were roommates!…',
|
|
64
75
|
// Nerdy
|
|
65
76
|
'Attention is all I need…',
|
|
66
77
|
'Transformer powers activate…',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"tips.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/constants/tips.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,IAAI,EAAE,MAAM,EA2CxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
|
|
@@ -17,12 +17,14 @@ export const tips = [
|
|
|
17
17
|
'Use /tools to see all available tools…',
|
|
18
18
|
'Use /prompts to browse, add and delete custom prompts…',
|
|
19
19
|
'Use /log to change logging verbosity…',
|
|
20
|
-
'Use /clear to clear the
|
|
20
|
+
'Use /clear to clear the session context…',
|
|
21
21
|
'Use /exit or /quit to close dexto…',
|
|
22
22
|
'Use /docs to access documentation…',
|
|
23
23
|
'Use /copy to copy the previous response…',
|
|
24
24
|
'Use /shortcuts to see all available shortcuts…',
|
|
25
25
|
'Use /sysprompt to see the current system prompt…',
|
|
26
|
+
'Use /context to see the current token usage…',
|
|
27
|
+
'Use /compact to summarize the current session…',
|
|
26
28
|
// Keyboard shortcut tips
|
|
27
29
|
'Press Escape to cancel the current request…',
|
|
28
30
|
'Press Ctrl+C twice to exit dexto…',
|
|
@@ -31,6 +33,7 @@ export const tips = [
|
|
|
31
33
|
'Press Enter to submit your message…',
|
|
32
34
|
'Press Ctrl+T to collapse/expand large pastes…',
|
|
33
35
|
'Press Ctrl+R to search previous prompts…',
|
|
36
|
+
'Press Shift+Enter to insert a new line…',
|
|
34
37
|
// Feature tips
|
|
35
38
|
'Start with ! to run bash commands directly…',
|
|
36
39
|
'Paste copied images with Ctrl+V…',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/InputContainer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAoC,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAiB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/InputContainer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAA0E,MAAM,OAAO,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAoC,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/F,OAAO,EAAE,YAAY,EAAiB,MAAM,sBAAsB,CAAC;AAEnE,OAAO,KAAK,EACR,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EAGf,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAMtE,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,yEAAyE;IACzE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,UAAU,mBAAmB;IACzB,yCAAyC;IACzC,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,UAAU,CAAC;IAClB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,8CAA8C;IAC9C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,2DAA2D;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,mEAAmE;IACnE,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,iFAAiF;IACjF,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnE,iCAAiC;IACjC,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzE,8EAA8E;IAC9E,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,yEAAyE;IACzE,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,GAAG,MAAM,KAAK,IAAI,CAAC;IACtD,6EAA6E;IAC7E,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,kGA6rB1B,CAAC"}
|
|
@@ -9,6 +9,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
9
9
|
import { useCallback, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
|
|
10
10
|
import { InputArea } from '../components/input/InputArea.js';
|
|
11
11
|
import { processStream } from '../services/index.js';
|
|
12
|
+
import { useSoundService } from '../contexts/index.js';
|
|
12
13
|
import { createUserMessage } from '../utils/messageFormatting.js';
|
|
13
14
|
import { generateMessageId } from '../utils/idGenerator.js';
|
|
14
15
|
import { capture } from '../../../analytics/index.js';
|
|
@@ -19,6 +20,8 @@ import { capture } from '../../../analytics/index.js';
|
|
|
19
20
|
export const InputContainer = forwardRef(function InputContainer({ buffer, input, ui, session, approval, queuedMessages, setInput, setUi, setSession, setMessages, setPendingMessages, setDequeuedBuffer, setQueuedMessages, setApproval, setApprovalQueue, agent, inputService, onKeyboardScroll, useStreaming = true, }, ref) {
|
|
20
21
|
// Track pending session creation to prevent race conditions
|
|
21
22
|
const sessionCreationPromiseRef = useRef(null);
|
|
23
|
+
// Sound notification service from context
|
|
24
|
+
const soundService = useSoundService();
|
|
22
25
|
// Ref to track autoApproveEdits so processStream can read latest value mid-stream
|
|
23
26
|
const autoApproveEditsRef = useRef(ui.autoApproveEdits);
|
|
24
27
|
useEffect(() => {
|
|
@@ -388,6 +391,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
|
|
|
388
391
|
setPendingMessages,
|
|
389
392
|
setDequeuedBuffer,
|
|
390
393
|
setUi,
|
|
394
|
+
setSession,
|
|
391
395
|
setQueuedMessages,
|
|
392
396
|
setApproval,
|
|
393
397
|
setApprovalQueue,
|
|
@@ -395,6 +399,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
|
|
|
395
399
|
useStreaming,
|
|
396
400
|
autoApproveEditsRef,
|
|
397
401
|
eventBus: agent.agentEventBus,
|
|
402
|
+
...(soundService && { soundService }),
|
|
398
403
|
});
|
|
399
404
|
return; // processStream handles UI state
|
|
400
405
|
}
|
|
@@ -492,6 +497,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
|
|
|
492
497
|
setPendingMessages,
|
|
493
498
|
setDequeuedBuffer,
|
|
494
499
|
setUi,
|
|
500
|
+
setSession,
|
|
495
501
|
setQueuedMessages,
|
|
496
502
|
setApproval,
|
|
497
503
|
setApprovalQueue,
|
|
@@ -499,6 +505,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
|
|
|
499
505
|
useStreaming,
|
|
500
506
|
autoApproveEditsRef,
|
|
501
507
|
eventBus: agent.agentEventBus,
|
|
508
|
+
...(soundService && { soundService }),
|
|
502
509
|
});
|
|
503
510
|
if (isFirstMessage) {
|
|
504
511
|
agent.generateSessionTitle(currentSessionId).catch(() => {
|
|
@@ -542,6 +549,7 @@ export const InputContainer = forwardRef(function InputContainer({ buffer, input
|
|
|
542
549
|
ui.activeOverlay,
|
|
543
550
|
session.id,
|
|
544
551
|
useStreaming,
|
|
552
|
+
soundService,
|
|
545
553
|
]);
|
|
546
554
|
// Determine if input should be active (not blocked by approval/overlay/history search)
|
|
547
555
|
// Input stays active for filter-type overlays (so user can keep typing to filter)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAmD,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../../../src/cli/ink-cli/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAmD,MAAM,aAAa,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAgFzC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAK3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,UAAU,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGAi8D5B,CAAC"}
|