snow-ai 0.3.6 → 0.3.7
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/reviewAgent.d.ts +50 -0
- package/dist/agents/reviewAgent.js +264 -0
- package/dist/api/anthropic.js +104 -71
- package/dist/api/chat.d.ts +1 -1
- package/dist/api/chat.js +60 -41
- package/dist/api/gemini.js +97 -57
- package/dist/api/responses.d.ts +9 -1
- package/dist/api/responses.js +110 -70
- package/dist/api/systemPrompt.d.ts +1 -1
- package/dist/api/systemPrompt.js +36 -7
- package/dist/api/types.d.ts +8 -0
- package/dist/hooks/useCommandHandler.d.ts +1 -0
- package/dist/hooks/useCommandHandler.js +44 -1
- package/dist/hooks/useCommandPanel.js +13 -0
- package/dist/hooks/useConversation.d.ts +4 -1
- package/dist/hooks/useConversation.js +48 -6
- package/dist/hooks/useKeyboardInput.js +19 -0
- package/dist/hooks/useTerminalFocus.js +13 -3
- package/dist/mcp/aceCodeSearch.d.ts +2 -76
- package/dist/mcp/aceCodeSearch.js +31 -467
- package/dist/mcp/bash.d.ts +1 -8
- package/dist/mcp/bash.js +20 -40
- package/dist/mcp/filesystem.d.ts +3 -68
- package/dist/mcp/filesystem.js +32 -348
- package/dist/mcp/ideDiagnostics.js +2 -4
- package/dist/mcp/todo.d.ts +1 -17
- package/dist/mcp/todo.js +11 -15
- package/dist/mcp/types/aceCodeSearch.types.d.ts +92 -0
- package/dist/mcp/types/aceCodeSearch.types.js +4 -0
- package/dist/mcp/types/bash.types.d.ts +13 -0
- package/dist/mcp/types/bash.types.js +4 -0
- package/dist/mcp/types/filesystem.types.d.ts +44 -0
- package/dist/mcp/types/filesystem.types.js +4 -0
- package/dist/mcp/types/todo.types.d.ts +27 -0
- package/dist/mcp/types/todo.types.js +4 -0
- package/dist/mcp/types/websearch.types.d.ts +30 -0
- package/dist/mcp/types/websearch.types.js +4 -0
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.d.ts +34 -0
- package/dist/mcp/utils/aceCodeSearch/filesystem.utils.js +146 -0
- package/dist/mcp/utils/aceCodeSearch/language.utils.d.ts +14 -0
- package/dist/mcp/utils/aceCodeSearch/language.utils.js +99 -0
- package/dist/mcp/utils/aceCodeSearch/search.utils.d.ts +31 -0
- package/dist/mcp/utils/aceCodeSearch/search.utils.js +136 -0
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.d.ts +20 -0
- package/dist/mcp/utils/aceCodeSearch/symbol.utils.js +141 -0
- package/dist/mcp/utils/bash/security.utils.d.ts +20 -0
- package/dist/mcp/utils/bash/security.utils.js +34 -0
- package/dist/mcp/utils/filesystem/code-analysis.utils.d.ts +18 -0
- package/dist/mcp/utils/filesystem/code-analysis.utils.js +165 -0
- package/dist/mcp/utils/filesystem/match-finder.utils.d.ts +16 -0
- package/dist/mcp/utils/filesystem/match-finder.utils.js +85 -0
- package/dist/mcp/utils/filesystem/similarity.utils.d.ts +22 -0
- package/dist/mcp/utils/filesystem/similarity.utils.js +75 -0
- package/dist/mcp/utils/todo/date.utils.d.ts +9 -0
- package/dist/mcp/utils/todo/date.utils.js +14 -0
- package/dist/mcp/utils/websearch/browser.utils.d.ts +8 -0
- package/dist/mcp/utils/websearch/browser.utils.js +58 -0
- package/dist/mcp/utils/websearch/text.utils.d.ts +16 -0
- package/dist/mcp/utils/websearch/text.utils.js +39 -0
- package/dist/mcp/websearch.d.ts +1 -31
- package/dist/mcp/websearch.js +21 -97
- package/dist/ui/components/ChatInput.d.ts +2 -1
- package/dist/ui/components/ChatInput.js +10 -3
- package/dist/ui/components/MarkdownRenderer.d.ts +1 -2
- package/dist/ui/components/MarkdownRenderer.js +16 -153
- package/dist/ui/components/MessageList.js +4 -4
- package/dist/ui/components/SessionListScreen.js +37 -17
- package/dist/ui/components/ToolResultPreview.js +6 -6
- package/dist/ui/components/UsagePanel.d.ts +2 -0
- package/dist/ui/components/UsagePanel.js +360 -0
- package/dist/ui/pages/ChatScreen.d.ts +4 -0
- package/dist/ui/pages/ChatScreen.js +70 -30
- package/dist/ui/pages/ConfigScreen.js +23 -19
- package/dist/ui/pages/HeadlessModeScreen.js +2 -4
- package/dist/ui/pages/SubAgentConfigScreen.js +17 -17
- package/dist/ui/pages/SystemPromptConfigScreen.js +7 -6
- package/dist/utils/commandExecutor.d.ts +3 -3
- package/dist/utils/commandExecutor.js +4 -4
- package/dist/utils/commands/home.d.ts +2 -0
- package/dist/utils/commands/home.js +12 -0
- package/dist/utils/commands/review.d.ts +2 -0
- package/dist/utils/commands/review.js +81 -0
- package/dist/utils/commands/role.d.ts +2 -0
- package/dist/utils/commands/role.js +37 -0
- package/dist/utils/commands/usage.d.ts +2 -0
- package/dist/utils/commands/usage.js +12 -0
- package/dist/utils/contextCompressor.js +99 -367
- package/dist/utils/fileUtils.js +3 -3
- package/dist/utils/mcpToolsManager.js +12 -12
- package/dist/utils/proxyUtils.d.ts +15 -0
- package/dist/utils/proxyUtils.js +50 -0
- package/dist/utils/retryUtils.d.ts +27 -0
- package/dist/utils/retryUtils.js +114 -2
- package/dist/utils/sessionManager.d.ts +2 -5
- package/dist/utils/sessionManager.js +16 -83
- package/dist/utils/terminal.js +4 -3
- package/dist/utils/usageLogger.d.ts +11 -0
- package/dist/utils/usageLogger.js +99 -0
- package/package.json +3 -7
- package/dist/agents/summaryAgent.d.ts +0 -31
- package/dist/agents/summaryAgent.js +0 -256
|
@@ -1,159 +1,22 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Text } from 'ink';
|
|
3
3
|
import { highlight } from 'cli-highlight';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (block.type === 'heading') {
|
|
16
|
-
const headingColors = ['cyan', 'blue', 'magenta', 'yellow'];
|
|
17
|
-
const headingColor = headingColors[block.level - 1] || 'white';
|
|
18
|
-
return (React.createElement(Box, { key: index, marginY: 0 },
|
|
19
|
-
React.createElement(Text, { bold: true, color: headingColor }, renderInlineFormatting(block.content))));
|
|
20
|
-
}
|
|
21
|
-
// Render list
|
|
22
|
-
if (block.type === 'list') {
|
|
23
|
-
return (React.createElement(Box, { key: index, flexDirection: "column", marginY: 0 }, block.items.map((item, itemIndex) => (React.createElement(Box, { key: itemIndex },
|
|
24
|
-
React.createElement(Text, { color: "yellow" }, "\u2022 "),
|
|
25
|
-
React.createElement(Text, { color: color }, renderInlineFormatting(item)))))));
|
|
26
|
-
}
|
|
27
|
-
// Render text with inline formatting
|
|
28
|
-
return (React.createElement(Box, { key: index, flexDirection: "column" }, block.content
|
|
29
|
-
.split('\n')
|
|
30
|
-
.map((line, lineIndex) => (React.createElement(Text, { key: lineIndex, color: color }, line === '' ? ' ' : renderInlineFormatting(line))))));
|
|
31
|
-
})));
|
|
32
|
-
}
|
|
33
|
-
function parseMarkdown(content) {
|
|
34
|
-
const blocks = [];
|
|
35
|
-
const lines = content.split('\n');
|
|
36
|
-
let i = 0;
|
|
37
|
-
while (i < lines.length) {
|
|
38
|
-
const line = lines[i] ?? '';
|
|
39
|
-
// Check for code block - support ```language or just ```
|
|
40
|
-
const codeBlockMatch = line.match(/^```(.*)$/);
|
|
41
|
-
if (codeBlockMatch) {
|
|
42
|
-
const language = codeBlockMatch[1]?.trim() || '';
|
|
43
|
-
const codeLines = [];
|
|
44
|
-
i++;
|
|
45
|
-
// Collect code block lines
|
|
46
|
-
while (i < lines.length) {
|
|
47
|
-
const currentLine = lines[i] ?? '';
|
|
48
|
-
if (currentLine.trim().startsWith('```')) {
|
|
49
|
-
break;
|
|
50
|
-
}
|
|
51
|
-
codeLines.push(currentLine);
|
|
52
|
-
i++;
|
|
53
|
-
}
|
|
54
|
-
blocks.push({
|
|
55
|
-
type: 'code',
|
|
56
|
-
language,
|
|
57
|
-
code: codeLines.join('\n'),
|
|
58
|
-
});
|
|
59
|
-
i++; // Skip closing ```
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
// Check for heading (# ## ### ####)
|
|
63
|
-
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
64
|
-
if (headingMatch) {
|
|
65
|
-
blocks.push({
|
|
66
|
-
type: 'heading',
|
|
67
|
-
level: headingMatch[1].length,
|
|
68
|
-
content: headingMatch[2].trim(),
|
|
69
|
-
});
|
|
70
|
-
i++;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
// Check for list item (* or -)
|
|
74
|
-
const listMatch = line.match(/^[\s]*[*\-]\s+(.+)$/);
|
|
75
|
-
if (listMatch) {
|
|
76
|
-
const listItems = [listMatch[1].trim()];
|
|
77
|
-
i++;
|
|
78
|
-
// Collect consecutive list items
|
|
79
|
-
while (i < lines.length) {
|
|
80
|
-
const currentLine = lines[i] ?? '';
|
|
81
|
-
const nextListMatch = currentLine.match(/^[\s]*[*\-]\s+(.+)$/);
|
|
82
|
-
if (!nextListMatch) {
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
listItems.push(nextListMatch[1].trim());
|
|
86
|
-
i++;
|
|
4
|
+
// @ts-expect-error - cli-markdown doesn't have TypeScript definitions
|
|
5
|
+
import cliMarkdown from 'cli-markdown';
|
|
6
|
+
export default function MarkdownRenderer({ content }) {
|
|
7
|
+
// Use cli-markdown for elegant markdown rendering with syntax highlighting
|
|
8
|
+
const rendered = cliMarkdown(content, {
|
|
9
|
+
// Enable syntax highlighting for code blocks
|
|
10
|
+
code: (code, language) => {
|
|
11
|
+
if (!language)
|
|
12
|
+
return code;
|
|
13
|
+
try {
|
|
14
|
+
return highlight(code, { language, ignoreIllegals: true });
|
|
87
15
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
items: listItems,
|
|
91
|
-
});
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
// Collect text lines until next code block, heading, or list
|
|
95
|
-
const textLines = [];
|
|
96
|
-
while (i < lines.length) {
|
|
97
|
-
const currentLine = lines[i] ?? '';
|
|
98
|
-
if (currentLine.trim().startsWith('```') ||
|
|
99
|
-
currentLine.match(/^#{1,6}\s+/) ||
|
|
100
|
-
currentLine.match(/^[\s]*[*\-]\s+/)) {
|
|
101
|
-
break;
|
|
16
|
+
catch {
|
|
17
|
+
return code;
|
|
102
18
|
}
|
|
103
|
-
|
|
104
|
-
i++;
|
|
105
|
-
}
|
|
106
|
-
if (textLines.length > 0) {
|
|
107
|
-
blocks.push({
|
|
108
|
-
type: 'text',
|
|
109
|
-
content: textLines.join('\n'),
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return blocks;
|
|
114
|
-
}
|
|
115
|
-
function highlightCode(code, language) {
|
|
116
|
-
try {
|
|
117
|
-
// If no language specified, try to auto-detect or just return the code
|
|
118
|
-
if (!language) {
|
|
119
|
-
return code;
|
|
120
|
-
}
|
|
121
|
-
// Map common language aliases to cli-highlight supported names
|
|
122
|
-
const languageMap = {
|
|
123
|
-
js: 'javascript',
|
|
124
|
-
ts: 'typescript',
|
|
125
|
-
py: 'python',
|
|
126
|
-
rb: 'ruby',
|
|
127
|
-
sh: 'bash',
|
|
128
|
-
shell: 'bash',
|
|
129
|
-
cs: 'csharp',
|
|
130
|
-
'c#': 'csharp',
|
|
131
|
-
cpp: 'cpp',
|
|
132
|
-
'c++': 'cpp',
|
|
133
|
-
yml: 'yaml',
|
|
134
|
-
md: 'markdown',
|
|
135
|
-
};
|
|
136
|
-
const mappedLanguage = languageMap[language.toLowerCase()] || language.toLowerCase();
|
|
137
|
-
return highlight(code, { language: mappedLanguage, ignoreIllegals: true });
|
|
138
|
-
}
|
|
139
|
-
catch {
|
|
140
|
-
// If highlighting fails, return the code as-is
|
|
141
|
-
return code;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
function renderInlineFormatting(text) {
|
|
145
|
-
// Handle inline code `code` - remove backticks
|
|
146
|
-
text = text.replace(/`([^`]+)`/g, (_, code) => {
|
|
147
|
-
// Use ANSI codes for inline code styling
|
|
148
|
-
return `\x1b[36m${code}\x1b[0m`;
|
|
149
|
-
});
|
|
150
|
-
// Handle bold **text** or __text__ - remove markers
|
|
151
|
-
text = text.replace(/(\*\*|__)([^*_]+)\1/g, (_, __, content) => {
|
|
152
|
-
return `\x1b[1m${content}\x1b[0m`;
|
|
153
|
-
});
|
|
154
|
-
// Handle italic *text* or _text_ (but not part of bold) - remove markers
|
|
155
|
-
text = text.replace(/(?<!\*)(\*)(?!\*)([^*]+)\1(?!\*)/g, (_, __, content) => {
|
|
156
|
-
return `\x1b[3m${content}\x1b[0m`;
|
|
19
|
+
},
|
|
157
20
|
});
|
|
158
|
-
return
|
|
21
|
+
return React.createElement(Text, null, rendered);
|
|
159
22
|
}
|
|
@@ -24,7 +24,7 @@ const MessageList = memo(({ messages, animationFrame, maxMessages = 6 }) => {
|
|
|
24
24
|
: message.role === 'subagent'
|
|
25
25
|
? '◈'
|
|
26
26
|
: '❆'),
|
|
27
|
-
React.createElement(Box, { marginLeft: 1,
|
|
27
|
+
React.createElement(Box, { marginLeft: 1, flexDirection: "column" }, message.role === 'command' ? (React.createElement(Text, { color: "gray" },
|
|
28
28
|
"\u2514\u2500 ",
|
|
29
29
|
message.commandName)) : message.role === 'subagent' ? (React.createElement(React.Fragment, null,
|
|
30
30
|
React.createElement(Text, { color: "magenta", dimColor: true },
|
|
@@ -32,12 +32,12 @@ const MessageList = memo(({ messages, animationFrame, maxMessages = 6 }) => {
|
|
|
32
32
|
message.subAgent?.agentName,
|
|
33
33
|
message.subAgent?.isComplete ? ' ✓' : ' ...'),
|
|
34
34
|
React.createElement(Box, { marginLeft: 2 },
|
|
35
|
-
React.createElement(
|
|
36
|
-
React.createElement(
|
|
35
|
+
React.createElement(Text, { color: "gray" }, message.content || ' ')))) : (React.createElement(React.Fragment, null,
|
|
36
|
+
message.role === 'user' ? (React.createElement(Text, { color: "gray" }, message.content || ' ')) : (React.createElement(MarkdownRenderer, { content: message.content || ' ' })),
|
|
37
37
|
(message.systemInfo ||
|
|
38
38
|
message.files ||
|
|
39
39
|
message.files ||
|
|
40
|
-
message.images) && (React.createElement(Box, {
|
|
40
|
+
message.images) && (React.createElement(Box, { flexDirection: "column" },
|
|
41
41
|
message.systemInfo && (React.createElement(React.Fragment, null,
|
|
42
42
|
React.createElement(Text, { color: "gray", dimColor: true },
|
|
43
43
|
"\u2514\u2500 Platform: ",
|
|
@@ -3,7 +3,7 @@ import { Box, Text, useInput, useStdout } from 'ink';
|
|
|
3
3
|
import Gradient from 'ink-gradient';
|
|
4
4
|
import { Alert } from '@inkjs/ui';
|
|
5
5
|
import ScrollableSelectInput from './ScrollableSelectInput.js';
|
|
6
|
-
import { sessionManager } from '../../utils/sessionManager.js';
|
|
6
|
+
import { sessionManager, } from '../../utils/sessionManager.js';
|
|
7
7
|
export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
8
8
|
const [sessions, setSessions] = useState([]);
|
|
9
9
|
const [loading, setLoading] = useState(true);
|
|
@@ -53,22 +53,35 @@ export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
|
53
53
|
// Create select items with truncated labels
|
|
54
54
|
const selectItems = useMemo(() => {
|
|
55
55
|
const terminalWidth = stdout?.columns || 80;
|
|
56
|
-
//
|
|
57
|
-
const
|
|
56
|
+
// Reserve space for indicators (✔ + ❯ + spacing) and margins
|
|
57
|
+
const reservedSpace = 30;
|
|
58
|
+
const maxLabelWidth = Math.max(30, terminalWidth - reservedSpace);
|
|
58
59
|
return sessions.map(session => {
|
|
59
60
|
const timeString = formatDate(session.updatedAt);
|
|
60
61
|
const title = session.title || 'Untitled';
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Format: "Title • 5 msgs • 2h ago"
|
|
63
|
+
const messageInfo = `${session.messageCount} msg${session.messageCount !== 1 ? 's' : ''}`;
|
|
64
|
+
const fullLabel = `${title} • ${messageInfo} • ${timeString}`;
|
|
65
|
+
// Truncate if too long - prioritize showing the title
|
|
66
|
+
let truncatedLabel = fullLabel;
|
|
67
|
+
if (fullLabel.length > maxLabelWidth) {
|
|
68
|
+
const ellipsis = '...';
|
|
69
|
+
const suffixLength = messageInfo.length + timeString.length + 6; // " • " x2 + "..."
|
|
70
|
+
const availableForTitle = maxLabelWidth - suffixLength - ellipsis.length;
|
|
71
|
+
if (availableForTitle > 10) {
|
|
72
|
+
const truncatedTitle = title.substring(0, availableForTitle);
|
|
73
|
+
truncatedLabel = `${truncatedTitle}${ellipsis} • ${messageInfo} • ${timeString}`;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// If terminal is too narrow, just truncate the whole thing
|
|
77
|
+
truncatedLabel =
|
|
78
|
+
fullLabel.substring(0, maxLabelWidth - ellipsis.length) + ellipsis;
|
|
79
|
+
}
|
|
67
80
|
}
|
|
68
81
|
return {
|
|
69
82
|
label: truncatedLabel,
|
|
70
83
|
value: session.id,
|
|
71
|
-
isMarked: selectedSessions.has(session.id)
|
|
84
|
+
isMarked: selectedSessions.has(session.id),
|
|
72
85
|
};
|
|
73
86
|
});
|
|
74
87
|
}, [sessions, formatDate, stdout?.columns, selectedSessions]);
|
|
@@ -96,10 +109,14 @@ export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
|
96
109
|
const ids = Array.from(selectedSessions);
|
|
97
110
|
const deletionResults = await Promise.all(ids.map(async (id) => ({
|
|
98
111
|
id,
|
|
99
|
-
success: await sessionManager.deleteSession(id)
|
|
112
|
+
success: await sessionManager.deleteSession(id),
|
|
100
113
|
})));
|
|
101
|
-
const succeededIds = deletionResults
|
|
102
|
-
|
|
114
|
+
const succeededIds = deletionResults
|
|
115
|
+
.filter(result => result.success)
|
|
116
|
+
.map(result => result.id);
|
|
117
|
+
const failedIds = deletionResults
|
|
118
|
+
.filter(result => !result.success)
|
|
119
|
+
.map(result => result.id);
|
|
103
120
|
if (succeededIds.length > 0) {
|
|
104
121
|
setSessions(previous => previous.filter(session => !succeededIds.includes(session.id)));
|
|
105
122
|
setSelectedSessions(previous => {
|
|
@@ -113,13 +130,13 @@ export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
|
113
130
|
if (failedIds.length > 0) {
|
|
114
131
|
setActionMessage({
|
|
115
132
|
type: 'error',
|
|
116
|
-
text: `Failed to delete ${failedIds.length} conversation${failedIds.length > 1 ? 's' : ''}
|
|
133
|
+
text: `Failed to delete ${failedIds.length} conversation${failedIds.length > 1 ? 's' : ''}.`,
|
|
117
134
|
});
|
|
118
135
|
}
|
|
119
136
|
else if (succeededIds.length > 0) {
|
|
120
137
|
setActionMessage({
|
|
121
138
|
type: 'info',
|
|
122
|
-
text: `Deleted ${succeededIds.length} conversation${succeededIds.length > 1 ? 's' : ''}
|
|
139
|
+
text: `Deleted ${succeededIds.length} conversation${succeededIds.length > 1 ? 's' : ''}.`,
|
|
123
140
|
});
|
|
124
141
|
}
|
|
125
142
|
else {
|
|
@@ -182,7 +199,8 @@ export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
|
182
199
|
sessions.length,
|
|
183
200
|
" conversation",
|
|
184
201
|
sessions.length !== 1 ? 's' : '',
|
|
185
|
-
|
|
202
|
+
' ',
|
|
203
|
+
"available"))),
|
|
186
204
|
React.createElement(Box, { marginBottom: 1, flexShrink: 0 },
|
|
187
205
|
React.createElement(ScrollableSelectInput, { items: selectItems, limit: listLimit, onSelect: handleSelect, onToggleItem: handleToggleItem, onDeleteSelection: handleDeleteSelected, selectedValues: selectedSessions, indicator: ({ isSelected }) => (React.createElement(Text, { color: isSelected ? 'green' : 'gray' }, isSelected ? '❯ ' : ' ')), renderItem: ({ isSelected, isMarked, label }) => (React.createElement(Text, null,
|
|
188
206
|
React.createElement(Text, { color: isMarked ? 'green' : 'gray' }, isMarked ? '✔ ' : ' '),
|
|
@@ -192,5 +210,7 @@ export default function SessionListScreen({ onBack, onSelectSession }) {
|
|
|
192
210
|
React.createElement(Alert, { variant: actionMessage.type }, actionMessage.text))) : null,
|
|
193
211
|
React.createElement(Alert, { variant: "info" },
|
|
194
212
|
"\u2191\u2193 navigate \u2022 Space mark \u2022 D delete \u2022 Enter select \u2022 Esc return \u2022 R refresh",
|
|
195
|
-
selectedSessions.size > 0
|
|
213
|
+
selectedSessions.size > 0
|
|
214
|
+
? ` • ${selectedSessions.size} selected`
|
|
215
|
+
: ''))));
|
|
196
216
|
}
|
|
@@ -97,7 +97,7 @@ function renderListPreview(data, maxLines) {
|
|
|
97
97
|
}
|
|
98
98
|
function renderACEPreview(toolName, data, maxLines) {
|
|
99
99
|
// Handle ace-text-search results
|
|
100
|
-
if (toolName === 'ace-text-search' || toolName === '
|
|
100
|
+
if (toolName === 'ace-text-search' || toolName === 'ace-text_search') {
|
|
101
101
|
if (!data || data.length === 0) {
|
|
102
102
|
return (React.createElement(Box, { marginLeft: 2 },
|
|
103
103
|
React.createElement(Text, { color: "gray", dimColor: true }, "\u2514\u2500 No matches found")));
|
|
@@ -120,7 +120,7 @@ function renderACEPreview(toolName, data, maxLines) {
|
|
|
120
120
|
" more matches)"))));
|
|
121
121
|
}
|
|
122
122
|
// Handle ace-search-symbols results
|
|
123
|
-
if (toolName === 'ace-search-symbols' || toolName === '
|
|
123
|
+
if (toolName === 'ace-search-symbols' || toolName === 'ace-search_symbols') {
|
|
124
124
|
const symbols = data.symbols || [];
|
|
125
125
|
if (symbols.length === 0) {
|
|
126
126
|
return (React.createElement(Box, { marginLeft: 2 },
|
|
@@ -144,7 +144,7 @@ function renderACEPreview(toolName, data, maxLines) {
|
|
|
144
144
|
" more symbols)"))));
|
|
145
145
|
}
|
|
146
146
|
// Handle ace-find-references results
|
|
147
|
-
if (toolName === 'ace-find-references' || toolName === '
|
|
147
|
+
if (toolName === 'ace-find-references' || toolName === 'ace-find_references') {
|
|
148
148
|
const references = Array.isArray(data) ? data : [];
|
|
149
149
|
if (references.length === 0) {
|
|
150
150
|
return (React.createElement(Box, { marginLeft: 2 },
|
|
@@ -166,7 +166,7 @@ function renderACEPreview(toolName, data, maxLines) {
|
|
|
166
166
|
" more references)"))));
|
|
167
167
|
}
|
|
168
168
|
// Handle ace-find-definition result
|
|
169
|
-
if (toolName === 'ace-find-definition' || toolName === '
|
|
169
|
+
if (toolName === 'ace-find-definition' || toolName === 'ace-find_definition') {
|
|
170
170
|
if (!data) {
|
|
171
171
|
return (React.createElement(Box, { marginLeft: 2 },
|
|
172
172
|
React.createElement(Text, { color: "gray", dimColor: true }, "\u2514\u2500 Definition not found")));
|
|
@@ -183,7 +183,7 @@ function renderACEPreview(toolName, data, maxLines) {
|
|
|
183
183
|
data.line)));
|
|
184
184
|
}
|
|
185
185
|
// Handle ace-file-outline result
|
|
186
|
-
if (toolName === 'ace-file-outline' || toolName === '
|
|
186
|
+
if (toolName === 'ace-file-outline' || toolName === 'ace-file_outline') {
|
|
187
187
|
const symbols = Array.isArray(data) ? data : [];
|
|
188
188
|
if (symbols.length === 0) {
|
|
189
189
|
return (React.createElement(Box, { marginLeft: 2 },
|
|
@@ -206,7 +206,7 @@ function renderACEPreview(toolName, data, maxLines) {
|
|
|
206
206
|
" more symbols)"))));
|
|
207
207
|
}
|
|
208
208
|
// Handle ace-semantic-search result
|
|
209
|
-
if (toolName === 'ace-semantic-search' || toolName === '
|
|
209
|
+
if (toolName === 'ace-semantic-search' || toolName === 'ace-semantic_search') {
|
|
210
210
|
const totalResults = (data.symbols?.length || 0) + (data.references?.length || 0);
|
|
211
211
|
if (totalResults === 0) {
|
|
212
212
|
return (React.createElement(Box, { marginLeft: 2 },
|