erosolar-cli 1.7.410 → 1.7.411
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 +6 -6
- package/dist/StringUtils.d.ts +1 -4
- package/dist/StringUtils.d.ts.map +1 -1
- package/dist/StringUtils.js +2 -8
- package/dist/StringUtils.js.map +1 -1
- package/dist/browser/BrowserSessionManager.d.ts +1 -3
- package/dist/browser/BrowserSessionManager.d.ts.map +1 -1
- package/dist/browser/BrowserSessionManager.js +4 -24
- package/dist/browser/BrowserSessionManager.js.map +1 -1
- package/dist/capabilities/askUserCapability.d.ts.map +1 -1
- package/dist/capabilities/askUserCapability.js +64 -10
- package/dist/capabilities/askUserCapability.js.map +1 -1
- package/dist/capabilities/toolRegistry.d.ts +2 -0
- package/dist/capabilities/toolRegistry.d.ts.map +1 -1
- package/dist/capabilities/toolRegistry.js +40 -5
- package/dist/capabilities/toolRegistry.js.map +1 -1
- package/dist/contracts/agent-profiles.schema.json +5 -5
- package/dist/contracts/agent-schemas.json +6 -16
- package/dist/contracts/schemas/agent.schema.json +1 -5
- package/dist/contracts/schemas/tool-selection.schema.json +1 -7
- package/dist/contracts/tools.schema.json +80 -207
- package/dist/contracts/unified-schema.json +4 -5
- package/dist/contracts/v1/agent.d.ts +0 -3
- package/dist/contracts/v1/agent.d.ts.map +1 -1
- package/dist/contracts/v1/provider.d.ts +1 -2
- package/dist/contracts/v1/provider.d.ts.map +1 -1
- package/dist/contracts/v1/toolAccess.d.ts +1 -1
- package/dist/contracts/v1/toolAccess.d.ts.map +1 -1
- package/dist/core/agent.d.ts +1 -7
- package/dist/core/agent.d.ts.map +1 -1
- package/dist/core/agent.js +2 -131
- package/dist/core/agent.js.map +1 -1
- package/dist/core/alphaZeroEngine.d.ts +0 -8
- package/dist/core/alphaZeroEngine.d.ts.map +1 -1
- package/dist/core/alphaZeroEngine.js +35 -149
- package/dist/core/alphaZeroEngine.js.map +1 -1
- package/dist/core/alphaZeroOrchestrator.d.ts +0 -17
- package/dist/core/alphaZeroOrchestrator.d.ts.map +1 -1
- package/dist/core/alphaZeroOrchestrator.js +8 -95
- package/dist/core/alphaZeroOrchestrator.js.map +1 -1
- package/dist/core/claudeCodeFeatures.d.ts +2 -1
- package/dist/core/claudeCodeFeatures.d.ts.map +1 -1
- package/dist/core/claudeCodeFeatures.js +2 -1
- package/dist/core/claudeCodeFeatures.js.map +1 -1
- package/dist/core/cliTestHarness.d.ts +0 -5
- package/dist/core/cliTestHarness.d.ts.map +1 -1
- package/dist/core/cliTestHarness.js +3 -14
- package/dist/core/cliTestHarness.js.map +1 -1
- package/dist/core/contextManager.d.ts +0 -30
- package/dist/core/contextManager.d.ts.map +1 -1
- package/dist/core/contextManager.js +5 -87
- package/dist/core/contextManager.js.map +1 -1
- package/dist/core/contextWindow.d.ts +4 -4
- package/dist/core/contextWindow.js +9 -9
- package/dist/core/contextWindow.js.map +1 -1
- package/dist/core/modelDiscovery.js +3 -3
- package/dist/core/modelDiscovery.js.map +1 -1
- package/dist/core/preferences.d.ts +2 -3
- package/dist/core/preferences.d.ts.map +1 -1
- package/dist/core/preferences.js +11 -18
- package/dist/core/preferences.js.map +1 -1
- package/dist/core/secretStore.d.ts.map +1 -1
- package/dist/core/secretStore.js +31 -0
- package/dist/core/secretStore.js.map +1 -1
- package/dist/core/toolPreconditions.d.ts.map +1 -1
- package/dist/core/toolPreconditions.js +0 -60
- package/dist/core/toolPreconditions.js.map +1 -1
- package/dist/core/toolRuntime.d.ts.map +1 -1
- package/dist/core/toolRuntime.js +0 -17
- package/dist/core/toolRuntime.js.map +1 -1
- package/dist/core/types.d.ts +1 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/headless/headlessApp.d.ts.map +1 -1
- package/dist/headless/headlessApp.js +6 -22
- package/dist/headless/headlessApp.js.map +1 -1
- package/dist/plugins/providers/google/index.js +3 -2
- package/dist/plugins/providers/google/index.js.map +1 -1
- package/dist/providers/openaiChatCompletionsProvider.d.ts.map +1 -1
- package/dist/providers/openaiChatCompletionsProvider.js +6 -60
- package/dist/providers/openaiChatCompletionsProvider.js.map +1 -1
- package/dist/runtime/agentController.d.ts.map +1 -1
- package/dist/runtime/agentController.js +6 -27
- package/dist/runtime/agentController.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +30 -79
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +726 -1511
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/shellApp.d.ts.map +1 -1
- package/dist/shell/shellApp.js +41 -15
- package/dist/shell/shellApp.js.map +1 -1
- package/dist/shell/systemPrompt.d.ts.map +1 -1
- package/dist/shell/systemPrompt.js +0 -1
- package/dist/shell/systemPrompt.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +21 -85
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +60 -517
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts +16 -37
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +22 -44
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/shell/updateManager.d.ts.map +1 -1
- package/dist/shell/updateManager.js +17 -1
- package/dist/shell/updateManager.js.map +1 -1
- package/dist/subagents/parallelAgentManager.d.ts.map +1 -1
- package/dist/subagents/parallelAgentManager.js +2 -1
- package/dist/subagents/parallelAgentManager.js.map +1 -1
- package/dist/tools/buildTools.d.ts.map +1 -1
- package/dist/tools/buildTools.js +76 -19
- package/dist/tools/buildTools.js.map +1 -1
- package/dist/tools/editTools.js +1 -1
- package/dist/tools/editTools.js.map +1 -1
- package/dist/tools/enhancedCodeIntelligenceTools.js +2 -1
- package/dist/tools/enhancedCodeIntelligenceTools.js.map +1 -1
- package/dist/tools/fileTools.js +0 -3
- package/dist/tools/fileTools.js.map +1 -1
- package/dist/tools/frontendTestingTools.js +1 -1
- package/dist/tools/frontendTestingTools.js.map +1 -1
- package/dist/tools/interactionTools.d.ts.map +1 -1
- package/dist/tools/interactionTools.js +82 -15
- package/dist/tools/interactionTools.js.map +1 -1
- package/dist/tools/learnTools.d.ts +0 -2
- package/dist/tools/learnTools.d.ts.map +1 -1
- package/dist/tools/learnTools.js +81 -29
- package/dist/tools/learnTools.js.map +1 -1
- package/dist/tools/localExplore.d.ts.map +1 -1
- package/dist/tools/localExplore.js +1 -0
- package/dist/tools/localExplore.js.map +1 -1
- package/dist/tools/notebookEditTools.js.map +1 -1
- package/dist/tools/repoChecksTools.js +3 -4
- package/dist/tools/repoChecksTools.js.map +1 -1
- package/dist/tools/searchTools.js +0 -4
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/softwareEngineeringTools.d.ts.map +1 -1
- package/dist/tools/softwareEngineeringTools.js +0 -1
- package/dist/tools/softwareEngineeringTools.js.map +1 -1
- package/dist/tools/webTools.d.ts.map +1 -1
- package/dist/tools/webTools.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +17 -54
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +90 -378
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/display.d.ts +38 -19
- package/dist/ui/display.d.ts.map +1 -1
- package/dist/ui/display.js +311 -96
- package/dist/ui/display.js.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.js +3 -5
- package/dist/ui/orchestration/UIUpdateCoordinator.js.map +1 -1
- package/dist/ui/shortcutsHelp.d.ts +11 -1
- package/dist/ui/shortcutsHelp.d.ts.map +1 -1
- package/dist/ui/shortcutsHelp.js +54 -8
- package/dist/ui/shortcutsHelp.js.map +1 -1
- package/dist/ui/streamingFormatter.d.ts +16 -0
- package/dist/ui/streamingFormatter.d.ts.map +1 -0
- package/dist/ui/streamingFormatter.js +62 -0
- package/dist/ui/streamingFormatter.js.map +1 -0
- package/dist/ui/theme.d.ts +100 -100
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +3 -3
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +8 -7
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/index.d.ts +3 -2
- package/dist/ui/unified/index.d.ts.map +1 -1
- package/dist/ui/unified/index.js +1 -0
- package/dist/ui/unified/index.js.map +1 -1
- package/dist/ui/unified/layout.d.ts +23 -0
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +113 -11
- package/dist/ui/unified/layout.js.map +1 -1
- package/package.json +24 -37
- package/dist/core/alphaZeroConfig.d.ts +0 -11
- package/dist/core/alphaZeroConfig.d.ts.map +0 -1
- package/dist/core/alphaZeroConfig.js +0 -59
- package/dist/core/alphaZeroConfig.js.map +0 -1
- package/dist/core/alphaZeroEnhanced.d.ts +0 -125
- package/dist/core/alphaZeroEnhanced.d.ts.map +0 -1
- package/dist/core/alphaZeroEnhanced.js +0 -386
- package/dist/core/alphaZeroEnhanced.js.map +0 -1
- package/dist/core/autonomousVerification.d.ts +0 -103
- package/dist/core/autonomousVerification.d.ts.map +0 -1
- package/dist/core/autonomousVerification.js +0 -583
- package/dist/core/autonomousVerification.js.map +0 -1
- package/dist/core/offsecAlphaZeroEnhanced.d.ts +0 -98
- package/dist/core/offsecAlphaZeroEnhanced.d.ts.map +0 -1
- package/dist/core/offsecAlphaZeroEnhanced.js +0 -441
- package/dist/core/offsecAlphaZeroEnhanced.js.map +0 -1
- package/dist/core/parallelAgentOrchestrator.d.ts +0 -171
- package/dist/core/parallelAgentOrchestrator.d.ts.map +0 -1
- package/dist/core/parallelAgentOrchestrator.js +0 -459
- package/dist/core/parallelAgentOrchestrator.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/dist/tools/detectCommands.d.ts +0 -8
- package/dist/tools/detectCommands.d.ts.map +0 -1
- package/dist/tools/detectCommands.js +0 -183
- package/dist/tools/detectCommands.js.map +0 -1
- package/dist/ui/assistantBlockRenderer.d.ts +0 -30
- package/dist/ui/assistantBlockRenderer.d.ts.map +0 -1
- package/dist/ui/assistantBlockRenderer.js +0 -121
- package/dist/ui/assistantBlockRenderer.js.map +0 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Advanced UI Features:
|
|
6
6
|
* - Compact same-line tool displays
|
|
7
|
-
* -
|
|
7
|
+
* - In-place progress updates
|
|
8
8
|
* - Grouped operation summaries
|
|
9
9
|
* - Dynamic status badges
|
|
10
10
|
*/
|
|
@@ -14,6 +14,8 @@ import { getTerminalColumns } from './layout.js';
|
|
|
14
14
|
import { theme, icons } from './theme.js';
|
|
15
15
|
import { UIUpdateCoordinator } from './orchestration/UIUpdateCoordinator.js';
|
|
16
16
|
import { compactRenderer } from './compactRenderer.js';
|
|
17
|
+
import { inPlaceUpdater } from './inPlaceUpdater.js';
|
|
18
|
+
import { formatTip } from './shortcutsHelp.js';
|
|
17
19
|
export class ShellUIAdapter {
|
|
18
20
|
uiController;
|
|
19
21
|
display;
|
|
@@ -30,8 +32,9 @@ export class ShellUIAdapter {
|
|
|
30
32
|
maxCompletedOps = 8;
|
|
31
33
|
compactDisplayMode = true; // Enable compact same-line displays
|
|
32
34
|
toolWarnings = new Map();
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
// Tips display tracking - show tips periodically (Claude Code style)
|
|
36
|
+
toolResultCount = 0;
|
|
37
|
+
tipInterval = 5; // Show tip every N tool results
|
|
35
38
|
constructor(writeStream, display, config = {}, updateCoordinator) {
|
|
36
39
|
this.display = display;
|
|
37
40
|
this.config = {
|
|
@@ -106,7 +109,7 @@ export class ShellUIAdapter {
|
|
|
106
109
|
// Update status bar to show active tool
|
|
107
110
|
if (this._toolStatusCallback) {
|
|
108
111
|
const actionDesc = this.getToolActionDescription(call);
|
|
109
|
-
this._toolStatusCallback(
|
|
112
|
+
this._toolStatusCallback(actionDesc);
|
|
110
113
|
}
|
|
111
114
|
this.uiController.onToolStart(call);
|
|
112
115
|
},
|
|
@@ -121,34 +124,27 @@ export class ShellUIAdapter {
|
|
|
121
124
|
total: progress.total ?? progress.current,
|
|
122
125
|
message: progress.message,
|
|
123
126
|
});
|
|
124
|
-
// Update status bar with progress
|
|
127
|
+
// Update status bar with progress - use in-place update for supported terminals
|
|
125
128
|
if (this._toolStatusCallback) {
|
|
126
129
|
const description = this.getToolActionDescription(call, progress);
|
|
127
130
|
if (description) {
|
|
128
|
-
this._toolStatusCallback(
|
|
131
|
+
this._toolStatusCallback(description);
|
|
129
132
|
}
|
|
130
133
|
}
|
|
131
|
-
//
|
|
132
|
-
if (progress.total && progress.total > 1) {
|
|
133
|
-
|
|
134
|
-
this.streamProgressUpdate(call.id, progressLine);
|
|
135
|
-
}
|
|
136
|
-
else if (progress.message) {
|
|
137
|
-
this.streamProgressUpdate(call.id, `${theme.info(icons.action)} ${theme.tool(call.name)} ${progress.message}`);
|
|
134
|
+
// Show progress bar for file operations and long-running tools
|
|
135
|
+
if (inPlaceUpdater.hasTTY && progress.total && progress.total > 1) {
|
|
136
|
+
inPlaceUpdater.showToolProgress(call.name, progress.message || '', { current: progress.current, total: progress.total });
|
|
138
137
|
}
|
|
139
138
|
},
|
|
140
139
|
onToolWarning: (call, warning) => {
|
|
141
140
|
const toolName = theme.tool(call.name);
|
|
142
141
|
const warningText = this.formatToolWarning(warning);
|
|
143
142
|
const line = `${theme.warning(icons.warning)} ${toolName} ${theme.ui.muted('preflight')} ${warningText}`;
|
|
144
|
-
this.recordToolWarning(call.id,
|
|
143
|
+
this.recordToolWarning(call.id, warningText);
|
|
145
144
|
// Use display.stream() to work with scroll regions
|
|
146
145
|
this.display.stream(`\n${line}\n`);
|
|
147
146
|
if (this._toolStatusCallback) {
|
|
148
|
-
this._toolStatusCallback({
|
|
149
|
-
text: `Warning: ${this.getToolActionDescription(call)}`,
|
|
150
|
-
stage: 'progress',
|
|
151
|
-
});
|
|
147
|
+
this._toolStatusCallback(`Warning: ${this.getToolActionDescription(call)}`);
|
|
152
148
|
}
|
|
153
149
|
},
|
|
154
150
|
onToolResult: (call, output) => {
|
|
@@ -172,21 +168,26 @@ export class ShellUIAdapter {
|
|
|
172
168
|
this.fileChangeCallback(fileChange.path, fileChange.type, fileChange.additions, fileChange.removals);
|
|
173
169
|
}
|
|
174
170
|
}
|
|
175
|
-
//
|
|
176
|
-
this.
|
|
171
|
+
// Use compact display for quick single-result tools
|
|
172
|
+
if (this.compactDisplayMode && this.isCompactTool(call.name)) {
|
|
173
|
+
this.displayCompactResult(call, output, true);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
// Claude Code style: Display tool result with ⎿ prefix
|
|
177
|
+
this.displayToolResultSummary(call, output, true);
|
|
178
|
+
}
|
|
177
179
|
// Surface any captured preflight warnings in a structured block
|
|
178
180
|
this.flushToolWarnings(call.id, call.name);
|
|
181
|
+
// Show tip periodically (Claude Code style)
|
|
182
|
+
this.toolResultCount++;
|
|
183
|
+
if (this.toolResultCount % this.tipInterval === 0) {
|
|
184
|
+
this.display.stream(`${formatTip()}\n`);
|
|
185
|
+
}
|
|
179
186
|
// Clear status bar after showing result
|
|
180
187
|
if (this._toolStatusCallback) {
|
|
181
|
-
|
|
182
|
-
this._toolStatusCallback({
|
|
183
|
-
text: completed ? `Completed ${completed}` : 'Tool complete',
|
|
184
|
-
stage: 'result',
|
|
185
|
-
});
|
|
186
|
-
this._toolStatusCallback({ text: null, stage: 'complete' });
|
|
188
|
+
this._toolStatusCallback(null);
|
|
187
189
|
}
|
|
188
190
|
this.uiController.onToolComplete(call.id, output);
|
|
189
|
-
this.toolProgressState.delete(call.id);
|
|
190
191
|
},
|
|
191
192
|
onToolError: (call, message) => {
|
|
192
193
|
// Complete the operation tracking with error
|
|
@@ -198,20 +199,20 @@ export class ShellUIAdapter {
|
|
|
198
199
|
this.pendingOperations.delete(call.id);
|
|
199
200
|
this.completedOperations.push(op);
|
|
200
201
|
}
|
|
201
|
-
//
|
|
202
|
-
this.
|
|
202
|
+
// Use compact display for errors too
|
|
203
|
+
if (this.compactDisplayMode && this.isCompactTool(call.name)) {
|
|
204
|
+
this.displayCompactResult(call, message, false);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
// Claude Code style: Display error with ⎿ prefix (error color)
|
|
208
|
+
this.displayToolResultSummary(call, message, false);
|
|
209
|
+
}
|
|
203
210
|
this.flushToolWarnings(call.id, call.name);
|
|
204
211
|
// Clear status bar after showing error
|
|
205
212
|
if (this._toolStatusCallback) {
|
|
206
|
-
|
|
207
|
-
this._toolStatusCallback({
|
|
208
|
-
text: failed ? `Failed ${failed}` : 'Tool failed',
|
|
209
|
-
stage: 'error',
|
|
210
|
-
});
|
|
211
|
-
this._toolStatusCallback({ text: null, stage: 'complete' });
|
|
213
|
+
this._toolStatusCallback(null);
|
|
212
214
|
}
|
|
213
215
|
this.uiController.onToolError(call.id, { message });
|
|
214
|
-
this.toolProgressState.delete(call.id);
|
|
215
216
|
},
|
|
216
217
|
onCacheHit: (call) => {
|
|
217
218
|
// Track as cached operation
|
|
@@ -230,21 +231,24 @@ export class ShellUIAdapter {
|
|
|
230
231
|
const badge = compactRenderer.formatToolBadge(operation);
|
|
231
232
|
this.display.stream(`${badge}\n`);
|
|
232
233
|
}
|
|
233
|
-
if (this._toolStatusCallback) {
|
|
234
|
-
const cached = this.getToolActionDescription(call);
|
|
235
|
-
this._toolStatusCallback({
|
|
236
|
-
text: cached ? `Cached ${cached}` : 'Tool cache hit',
|
|
237
|
-
stage: 'result',
|
|
238
|
-
});
|
|
239
|
-
this._toolStatusCallback({ text: null, stage: 'complete' });
|
|
240
|
-
}
|
|
241
234
|
this.flushToolWarnings(call.id, call.name);
|
|
242
235
|
this.uiController.onToolStart(call);
|
|
243
236
|
this.uiController.onToolComplete(call.id, 'cache-hit');
|
|
244
|
-
this.toolProgressState.delete(call.id);
|
|
245
237
|
},
|
|
246
238
|
};
|
|
247
239
|
}
|
|
240
|
+
/**
|
|
241
|
+
* Check if a tool should use compact (single-line) display
|
|
242
|
+
*/
|
|
243
|
+
isCompactTool(toolName) {
|
|
244
|
+
const compactTools = new Set([
|
|
245
|
+
'Read', 'read_file',
|
|
246
|
+
'Glob', 'glob',
|
|
247
|
+
'TodoWrite', 'todo_write',
|
|
248
|
+
'WebFetch', 'web_fetch',
|
|
249
|
+
]);
|
|
250
|
+
return compactTools.has(toolName);
|
|
251
|
+
}
|
|
248
252
|
/**
|
|
249
253
|
* Normalize preflight warnings for consistent display.
|
|
250
254
|
*/
|
|
@@ -259,15 +263,10 @@ export class ShellUIAdapter {
|
|
|
259
263
|
/**
|
|
260
264
|
* Track warnings for a tool call so we can show them after the result too.
|
|
261
265
|
*/
|
|
262
|
-
recordToolWarning(callId,
|
|
266
|
+
recordToolWarning(callId, warningText) {
|
|
263
267
|
const existing = this.toolWarnings.get(callId) ?? [];
|
|
264
268
|
existing.push(warningText);
|
|
265
269
|
this.toolWarnings.set(callId, existing);
|
|
266
|
-
this.recentWarnings.push({ tool: toolName, text: warningText, time: Date.now() });
|
|
267
|
-
// Keep recent warnings list compact
|
|
268
|
-
if (this.recentWarnings.length > 20) {
|
|
269
|
-
this.recentWarnings.shift();
|
|
270
|
-
}
|
|
271
270
|
}
|
|
272
271
|
/**
|
|
273
272
|
* Render any captured warnings for the given tool call as a structured block.
|
|
@@ -283,42 +282,6 @@ export class ShellUIAdapter {
|
|
|
283
282
|
const body = warnings.map(text => ` ${bullet} ${text}`).join('\n');
|
|
284
283
|
this.display.stream(`\n${header}\n${body}\n`);
|
|
285
284
|
}
|
|
286
|
-
/**
|
|
287
|
-
* Render progress updates as streaming lines rather than in-place redraws.
|
|
288
|
-
*/
|
|
289
|
-
formatStreamingProgress(call, progress) {
|
|
290
|
-
const pct = progress.total ? Math.round((progress.current / progress.total) * 100) : null;
|
|
291
|
-
const parts = [];
|
|
292
|
-
parts.push(theme.info(icons.action));
|
|
293
|
-
parts.push(theme.tool(call.name));
|
|
294
|
-
if (pct !== null && Number.isFinite(pct)) {
|
|
295
|
-
parts.push(theme.progress.percentage(`${pct}%`));
|
|
296
|
-
parts.push(theme.ui.muted(`(${progress.current}/${progress.total})`));
|
|
297
|
-
}
|
|
298
|
-
if (progress.message) {
|
|
299
|
-
parts.push(progress.message);
|
|
300
|
-
}
|
|
301
|
-
return parts.join(' ');
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Only stream distinct progress updates to avoid noisy duplicates.
|
|
305
|
-
*/
|
|
306
|
-
streamProgressUpdate(callId, line) {
|
|
307
|
-
const previous = this.toolProgressState.get(callId);
|
|
308
|
-
if (previous === line) {
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
this.toolProgressState.set(callId, line);
|
|
312
|
-
this.display.stream(`${line}\n`);
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Return preflight warnings captured since a timestamp.
|
|
316
|
-
*/
|
|
317
|
-
getRecentWarnings(since) {
|
|
318
|
-
return this.recentWarnings
|
|
319
|
-
.filter((entry) => entry.time >= since)
|
|
320
|
-
.map((entry) => ({ tool: entry.tool, text: entry.text }));
|
|
321
|
-
}
|
|
322
285
|
/**
|
|
323
286
|
* Get a short summary for tool operation
|
|
324
287
|
*/
|
|
@@ -418,6 +381,21 @@ export class ShellUIAdapter {
|
|
|
418
381
|
return 'done';
|
|
419
382
|
}
|
|
420
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Display compact single-line result
|
|
386
|
+
*/
|
|
387
|
+
displayCompactResult(call, output, success) {
|
|
388
|
+
const op = {
|
|
389
|
+
id: call.id,
|
|
390
|
+
name: call.name,
|
|
391
|
+
status: success ? 'success' : 'error',
|
|
392
|
+
summary: this.extractResultSummary(call, output),
|
|
393
|
+
startedAt: Date.now(),
|
|
394
|
+
};
|
|
395
|
+
const badge = compactRenderer.formatToolBadge(op);
|
|
396
|
+
// Add newline after result for visual separation
|
|
397
|
+
this.display.stream(`${badge}\n\n`);
|
|
398
|
+
}
|
|
421
399
|
/**
|
|
422
400
|
* Determine if a tool should show initial ⏺ display
|
|
423
401
|
* Returns true for tools with streaming/progressive output
|
|
@@ -852,19 +830,6 @@ export class ShellUIAdapter {
|
|
|
852
830
|
setToolStatusCallback(callback) {
|
|
853
831
|
this._toolStatusCallback = callback;
|
|
854
832
|
}
|
|
855
|
-
/**
|
|
856
|
-
* Expose a snapshot of tool operations for external summary displays.
|
|
857
|
-
* Returns both completed and in-flight operations, optionally filtered by start time.
|
|
858
|
-
*/
|
|
859
|
-
getToolOperationsSince(sinceMs) {
|
|
860
|
-
const cutoff = sinceMs ?? 0;
|
|
861
|
-
const completed = this.completedOperations.map(op => ({ ...op }));
|
|
862
|
-
const pending = Array.from(this.pendingOperations.values()).map(op => ({ ...op }));
|
|
863
|
-
const all = [...completed, ...pending];
|
|
864
|
-
return all
|
|
865
|
-
.filter(op => op.startedAt >= cutoff)
|
|
866
|
-
.sort((a, b) => (a.startedAt || 0) - (b.startedAt || 0));
|
|
867
|
-
}
|
|
868
833
|
/**
|
|
869
834
|
* Parse file changes from Edit/Write/NotebookEdit tool output
|
|
870
835
|
*/
|
|
@@ -909,283 +874,29 @@ export class ShellUIAdapter {
|
|
|
909
874
|
};
|
|
910
875
|
}
|
|
911
876
|
/**
|
|
912
|
-
* Display tool result summary
|
|
913
|
-
*
|
|
877
|
+
* Display tool result summary using Claude Code style.
|
|
878
|
+
* Format: ⎿ Summary text (ctrl+o to expand)
|
|
879
|
+
* Routes through display module to work with scroll regions
|
|
914
880
|
*/
|
|
915
881
|
displayToolResultSummary(call, output, success) {
|
|
916
|
-
const summaryLine = this.formatCompactToolLine(call, output, success);
|
|
917
|
-
const preview = this.formatToolPreview(call, output, success);
|
|
918
|
-
if (!summaryLine && !preview) {
|
|
919
|
-
return;
|
|
920
|
-
}
|
|
921
|
-
const blocks = [];
|
|
922
|
-
if (summaryLine)
|
|
923
|
-
blocks.push(summaryLine);
|
|
924
|
-
if (preview)
|
|
925
|
-
blocks.push(preview);
|
|
926
|
-
// Add newline for separation while keeping output compact
|
|
927
|
-
this.display.stream(`\n${blocks.join('\n')}\n\n`);
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* Display full tool output directly under the summary block.
|
|
931
|
-
* Now uses the same compact preview system to keep verbose tools readable.
|
|
932
|
-
*/
|
|
933
|
-
displayFullToolOutput(call, output, success) {
|
|
934
|
-
const normalized = typeof output === 'string' ? output.trimEnd() : '';
|
|
935
|
-
if (!normalized) {
|
|
936
|
-
return;
|
|
937
|
-
}
|
|
938
|
-
// Use the same preview builder to keep verbose output compact
|
|
939
|
-
const preview = this.formatToolPreview(call, normalized, success, true);
|
|
940
|
-
const summary = this.formatCompactToolLine(call, normalized, success);
|
|
941
|
-
const parts = [];
|
|
942
|
-
if (summary)
|
|
943
|
-
parts.push(summary);
|
|
944
|
-
if (preview)
|
|
945
|
-
parts.push(preview);
|
|
946
|
-
if (parts.length) {
|
|
947
|
-
this.display.stream(`\n${parts.join('\n')}\n\n`);
|
|
948
|
-
}
|
|
949
|
-
}
|
|
950
|
-
/**
|
|
951
|
-
* Format tool result summary in Claude Code style
|
|
952
|
-
* Returns compact summary like "Found 4 files" or "Read 50 lines"
|
|
953
|
-
*/
|
|
954
|
-
formatCompactToolLine(call, output, success) {
|
|
955
|
-
const { main, detail } = this.buildToolSummaryParts(call, output, success);
|
|
956
|
-
const summary = main || this.getToolSummary(call) || call.name;
|
|
957
|
-
return compactRenderer.formatInlineResult(call.name, success ? 'success' : 'error', summary, detail);
|
|
958
|
-
}
|
|
959
|
-
/**
|
|
960
|
-
* Build compact summary + detail parts for a tool result line.
|
|
961
|
-
* Keeps the main text meaningful (path/query) and pushes counts into detail.
|
|
962
|
-
*/
|
|
963
|
-
buildToolSummaryParts(call, output, success) {
|
|
964
882
|
const args = call.arguments || {};
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
}
|
|
975
|
-
case 'Write':
|
|
976
|
-
case 'write_file': {
|
|
977
|
-
const path = this.extractPath(args, ['file_path', 'path']);
|
|
978
|
-
const content = args['content'] || output;
|
|
979
|
-
const lines = this.countOutputLines(content);
|
|
980
|
-
return {
|
|
981
|
-
main: path ? theme.info(this.truncatePath(path, 60)) : 'Write',
|
|
982
|
-
detail: `${lines} line${lines === 1 ? '' : 's'}`,
|
|
983
|
-
};
|
|
984
|
-
}
|
|
985
|
-
case 'Edit':
|
|
986
|
-
case 'edit_file':
|
|
987
|
-
case 'NotebookEdit': {
|
|
988
|
-
const change = this.parseFileChange(call, output);
|
|
989
|
-
const path = change?.path || this.extractPath(args, ['file_path', 'path', 'notebook_path']);
|
|
990
|
-
const detailParts = [];
|
|
991
|
-
if (change) {
|
|
992
|
-
detailParts.push(`+${change.additions}/-${change.removals}`);
|
|
993
|
-
}
|
|
994
|
-
else if (lineCount > 0) {
|
|
995
|
-
detailParts.push(`${lineCount} line${lineCount === 1 ? '' : 's'}`);
|
|
996
|
-
}
|
|
997
|
-
const action = call.name === 'NotebookEdit' ? 'Notebook' : 'Edit';
|
|
998
|
-
return {
|
|
999
|
-
main: path ? `${action} ${theme.info(this.truncatePath(path, 60))}` : action,
|
|
1000
|
-
detail: detailParts.join(' · ') || undefined,
|
|
1001
|
-
};
|
|
1002
|
-
}
|
|
1003
|
-
case 'Grep':
|
|
1004
|
-
case 'grep': {
|
|
1005
|
-
const pattern = args['pattern'] || '';
|
|
1006
|
-
const path = this.extractPath(args, ['path', 'directory']);
|
|
1007
|
-
const matches = output.trim() ? output.trim().split('\n').filter(l => l.trim()).length : 0;
|
|
1008
|
-
const detailParts = [`${matches} match${matches === 1 ? '' : 'es'}`];
|
|
1009
|
-
if (path && path !== '.') {
|
|
1010
|
-
detailParts.push(`in ${this.truncatePath(path, 40)}`);
|
|
1011
|
-
}
|
|
1012
|
-
return {
|
|
1013
|
-
main: pattern ? `"${pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern}"` : 'Grep',
|
|
1014
|
-
detail: detailParts.join(' · '),
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
case 'Glob':
|
|
1018
|
-
case 'glob': {
|
|
1019
|
-
const pattern = args['pattern'] || '*';
|
|
1020
|
-
const files = output.trim() ? output.trim().split('\n').filter(f => f.trim()).length : 0;
|
|
1021
|
-
const path = this.extractPath(args, ['path', 'directory']);
|
|
1022
|
-
const detailParts = [`${files} file${files === 1 ? '' : 's'}`];
|
|
1023
|
-
if (path && path !== '.') {
|
|
1024
|
-
detailParts.push(`in ${this.truncatePath(path, 40)}`);
|
|
1025
|
-
}
|
|
1026
|
-
return {
|
|
1027
|
-
main: pattern ? theme.info(pattern) : 'Glob',
|
|
1028
|
-
detail: detailParts.join(' · '),
|
|
1029
|
-
};
|
|
1030
|
-
}
|
|
1031
|
-
case 'Bash':
|
|
1032
|
-
case 'bash': {
|
|
1033
|
-
const command = args['command'] || '';
|
|
1034
|
-
const shortCmd = command.split('\n')[0]?.trim() || command;
|
|
1035
|
-
const main = shortCmd
|
|
1036
|
-
? `${theme.ui.muted('$')} ${shortCmd.length > 70 ? `${shortCmd.slice(0, 67)}...` : shortCmd}`
|
|
1037
|
-
: 'Shell';
|
|
1038
|
-
const detail = lineCount === 0 ? 'no output' : `${lineCount} line${lineCount === 1 ? '' : 's'}`;
|
|
1039
|
-
return { main, detail };
|
|
1040
|
-
}
|
|
1041
|
-
case 'WebFetch':
|
|
1042
|
-
case 'web_fetch': {
|
|
1043
|
-
const url = args['url'] || '';
|
|
1044
|
-
let host = url;
|
|
1045
|
-
try {
|
|
1046
|
-
host = new URL(url).hostname;
|
|
1047
|
-
}
|
|
1048
|
-
catch {
|
|
1049
|
-
// Keep original
|
|
1050
|
-
}
|
|
1051
|
-
const sizeStr = output.length > 1024 ? `${(output.length / 1024).toFixed(1)}KB` : `${output.length}B`;
|
|
1052
|
-
return { main: host ? `Fetch ${theme.info(host)}` : 'Fetch', detail: sizeStr };
|
|
1053
|
-
}
|
|
1054
|
-
case 'WebSearch':
|
|
1055
|
-
case 'web_search': {
|
|
1056
|
-
const query = args['query'] || '';
|
|
1057
|
-
const queryDisplay = query.length > 50 ? `${query.slice(0, 47)}...` : query;
|
|
1058
|
-
const resultMatches = output.match(/^\d+\./gm);
|
|
1059
|
-
const count = resultMatches ? resultMatches.length : this.countOutputLines(output);
|
|
1060
|
-
return { main: queryDisplay ? `Search "${queryDisplay}"` : 'Search', detail: `${count} result${count === 1 ? '' : 's'}` };
|
|
1061
|
-
}
|
|
1062
|
-
case 'Task':
|
|
1063
|
-
case 'task': {
|
|
1064
|
-
const desc = args['description'] || '';
|
|
1065
|
-
const trimmed = desc.length > 60 ? `${desc.slice(0, 57)}...` : desc;
|
|
1066
|
-
return { main: trimmed || 'Task', detail: success ? 'done' : 'incomplete' };
|
|
1067
|
-
}
|
|
1068
|
-
case 'TodoWrite':
|
|
1069
|
-
case 'todo_write': {
|
|
1070
|
-
const todos = args['todos'];
|
|
1071
|
-
const total = todos?.length || 0;
|
|
1072
|
-
return { main: 'Todos', detail: total ? `${total} item${total === 1 ? '' : 's'}` : undefined };
|
|
1073
|
-
}
|
|
1074
|
-
case 'run_tests': {
|
|
1075
|
-
const pattern = (args['pattern'] || args['filter']);
|
|
1076
|
-
const counts = this.parseTestCounts(output);
|
|
1077
|
-
const detailParts = [];
|
|
1078
|
-
if (counts.passed > 0)
|
|
1079
|
-
detailParts.push(`${counts.passed} pass`);
|
|
1080
|
-
if (counts.failed > 0)
|
|
1081
|
-
detailParts.push(`${counts.failed} fail`);
|
|
1082
|
-
if (counts.skipped > 0)
|
|
1083
|
-
detailParts.push(`${counts.skipped} skip`);
|
|
1084
|
-
if (detailParts.length === 0 && lineCount > 0) {
|
|
1085
|
-
detailParts.push(`${lineCount} line${lineCount === 1 ? '' : 's'}`);
|
|
1086
|
-
}
|
|
1087
|
-
return {
|
|
1088
|
-
main: pattern ? `Tests "${pattern}"` : 'Tests',
|
|
1089
|
-
detail: detailParts.join(' · ') || (success ? 'all passed' : 'failed'),
|
|
1090
|
-
};
|
|
1091
|
-
}
|
|
1092
|
-
case 'run_build': {
|
|
1093
|
-
const target = (args['target'] || args['script']);
|
|
1094
|
-
const errors = (output.match(/error/gi) || []).length;
|
|
1095
|
-
const detail = errors > 0
|
|
1096
|
-
? `${errors} error${errors === 1 ? '' : 's'}`
|
|
1097
|
-
: `${lineCount} line${lineCount === 1 ? '' : 's'}`;
|
|
1098
|
-
return { main: target ? `Build ${target}` : 'Build', detail };
|
|
1099
|
-
}
|
|
1100
|
-
default: {
|
|
1101
|
-
const summary = this.extractResultSummary(call, output);
|
|
1102
|
-
if (summary) {
|
|
1103
|
-
return { main: summary };
|
|
1104
|
-
}
|
|
1105
|
-
const claudeSummary = this.formatClaudeCodeResultSummary(call.name, args, output, success);
|
|
1106
|
-
if (claudeSummary) {
|
|
1107
|
-
return { main: claudeSummary };
|
|
1108
|
-
}
|
|
1109
|
-
return { main: call.name, detail: lineCount ? `${lineCount} line${lineCount === 1 ? '' : 's'}` : undefined };
|
|
1110
|
-
}
|
|
883
|
+
// Get compact summary for the result
|
|
884
|
+
const summary = this.formatClaudeCodeResultSummary(call.name, args, output, success);
|
|
885
|
+
if (summary) {
|
|
886
|
+
// Claude Code style: ⎿ Summary (indented under tool call)
|
|
887
|
+
const prefix = success
|
|
888
|
+
? theme.success(icons.subaction)
|
|
889
|
+
: theme.error(icons.subaction);
|
|
890
|
+
// Add newline after result for visual separation
|
|
891
|
+
this.display.stream(` ${prefix} ${summary}\n\n`);
|
|
1111
892
|
}
|
|
1112
893
|
}
|
|
1113
894
|
/**
|
|
1114
|
-
*
|
|
895
|
+
* Format tool result summary in Claude Code style
|
|
896
|
+
* Returns compact summary like "Found 4 files (ctrl+o to expand)" or "Read 50 lines"
|
|
1115
897
|
*/
|
|
1116
|
-
formatToolPreview(call, output, success, force = false) {
|
|
1117
|
-
const previewLines = this.buildPreviewLines(call, output, success, force);
|
|
1118
|
-
if (!previewLines.length) {
|
|
1119
|
-
return null;
|
|
1120
|
-
}
|
|
1121
|
-
const gutter = theme.ui.muted('│');
|
|
1122
|
-
return previewLines.map(line => ` ${gutter} ${line}`).join('\n');
|
|
1123
|
-
}
|
|
1124
|
-
buildPreviewLines(call, output, success, force) {
|
|
1125
|
-
const normalized = (output || '').trim();
|
|
1126
|
-
const allLines = normalized ? normalized.split('\n').filter(l => l.trim()) : [];
|
|
1127
|
-
const limit = this.getPreviewLineLimit(call.name, success);
|
|
1128
|
-
if (limit <= 0 && !force) {
|
|
1129
|
-
return [];
|
|
1130
|
-
}
|
|
1131
|
-
const maxLines = limit > 0 ? limit : force ? Math.min(1, allLines.length) : 0;
|
|
1132
|
-
if (maxLines === 0 || allLines.length === 0) {
|
|
1133
|
-
return [];
|
|
1134
|
-
}
|
|
1135
|
-
const preview = allLines.slice(0, maxLines).map(line => this.truncatePreviewLine(line));
|
|
1136
|
-
const remaining = allLines.length - maxLines;
|
|
1137
|
-
if (remaining > 0) {
|
|
1138
|
-
preview.push(theme.ui.muted(`… +${remaining} more`));
|
|
1139
|
-
}
|
|
1140
|
-
return preview;
|
|
1141
|
-
}
|
|
1142
|
-
getPreviewLineLimit(toolName, success) {
|
|
1143
|
-
switch (toolName) {
|
|
1144
|
-
case 'Read':
|
|
1145
|
-
case 'read_file':
|
|
1146
|
-
return success ? 0 : 1;
|
|
1147
|
-
case 'Glob':
|
|
1148
|
-
case 'glob':
|
|
1149
|
-
return 3;
|
|
1150
|
-
case 'Grep':
|
|
1151
|
-
case 'grep':
|
|
1152
|
-
return 4;
|
|
1153
|
-
case 'Bash':
|
|
1154
|
-
case 'bash':
|
|
1155
|
-
return success ? 3 : 4;
|
|
1156
|
-
case 'run_tests':
|
|
1157
|
-
return success ? 2 : 4;
|
|
1158
|
-
case 'Edit':
|
|
1159
|
-
case 'edit_file':
|
|
1160
|
-
case 'NotebookEdit':
|
|
1161
|
-
return success ? 30 : 4; // Show more diff context for successful edits
|
|
1162
|
-
default:
|
|
1163
|
-
return success ? 2 : 3;
|
|
1164
|
-
}
|
|
1165
|
-
}
|
|
1166
|
-
truncatePreviewLine(line, maxLen = 100) {
|
|
1167
|
-
const trimmed = line.trim();
|
|
1168
|
-
if (trimmed.length <= maxLen) {
|
|
1169
|
-
return theme.dim(trimmed);
|
|
1170
|
-
}
|
|
1171
|
-
return theme.dim(`${trimmed.slice(0, maxLen - 3)}...`);
|
|
1172
|
-
}
|
|
1173
|
-
countOutputLines(output) {
|
|
1174
|
-
if (!output || !output.trim())
|
|
1175
|
-
return 0;
|
|
1176
|
-
return output.trimEnd().split('\n').length;
|
|
1177
|
-
}
|
|
1178
|
-
parseTestCounts(output) {
|
|
1179
|
-
const passMatch = output.match(/(\d+)\s*(?:passing|passed|✓)/i);
|
|
1180
|
-
const failMatch = output.match(/(\d+)\s*(?:failing|failed|✗)/i);
|
|
1181
|
-
const skipMatch = output.match(/(\d+)\s*(?:skipped|pending)/i);
|
|
1182
|
-
return {
|
|
1183
|
-
passed: passMatch ? parseInt(passMatch[1] || '0', 10) : 0,
|
|
1184
|
-
failed: failMatch ? parseInt(failMatch[1] || '0', 10) : 0,
|
|
1185
|
-
skipped: skipMatch ? parseInt(skipMatch[1] || '0', 10) : 0,
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
898
|
formatClaudeCodeResultSummary(toolName, args, output, success) {
|
|
899
|
+
const expandHint = theme.ui.muted('(ctrl+o to expand)');
|
|
1189
900
|
if (!success) {
|
|
1190
901
|
// Error case - show error message
|
|
1191
902
|
const errorMsg = output.length > 60 ? `${output.slice(0, 57)}...` : output;
|
|
@@ -1227,9 +938,9 @@ export class ShellUIAdapter {
|
|
|
1227
938
|
return theme.ui.muted('No matches found');
|
|
1228
939
|
}
|
|
1229
940
|
if (outputMode === 'content') {
|
|
1230
|
-
return `Found ${theme.info(String(count))} lines`;
|
|
941
|
+
return `Found ${theme.info(String(count))} lines ${expandHint}`;
|
|
1231
942
|
}
|
|
1232
|
-
return `Found ${theme.info(String(count))} files`;
|
|
943
|
+
return `Found ${theme.info(String(count))} files ${expandHint}`;
|
|
1233
944
|
}
|
|
1234
945
|
case 'Glob':
|
|
1235
946
|
case 'glob': {
|
|
@@ -1238,7 +949,7 @@ export class ShellUIAdapter {
|
|
|
1238
949
|
if (count === 0) {
|
|
1239
950
|
return theme.ui.muted('No files found');
|
|
1240
951
|
}
|
|
1241
|
-
return `Found ${theme.info(String(count))} file${count === 1 ? '' : 's'}`;
|
|
952
|
+
return `Found ${theme.info(String(count))} file${count === 1 ? '' : 's'} ${expandHint}`;
|
|
1242
953
|
}
|
|
1243
954
|
case 'Bash':
|
|
1244
955
|
case 'bash': {
|
|
@@ -1246,7 +957,7 @@ export class ShellUIAdapter {
|
|
|
1246
957
|
if (lines === 0) {
|
|
1247
958
|
return theme.ui.muted('Completed (no output)');
|
|
1248
959
|
}
|
|
1249
|
-
return `Output: ${theme.info(String(lines))} lines`;
|
|
960
|
+
return `Output: ${theme.info(String(lines))} lines ${expandHint}`;
|
|
1250
961
|
}
|
|
1251
962
|
case 'WebFetch':
|
|
1252
963
|
case 'web_fetch': {
|
|
@@ -1258,7 +969,7 @@ export class ShellUIAdapter {
|
|
|
1258
969
|
case 'web_search': {
|
|
1259
970
|
const resultMatches = output.match(/^\d+\./gm);
|
|
1260
971
|
const count = resultMatches ? resultMatches.length : 'multiple';
|
|
1261
|
-
return `Found ${theme.info(String(count))} results`;
|
|
972
|
+
return `Found ${theme.info(String(count))} results ${expandHint}`;
|
|
1262
973
|
}
|
|
1263
974
|
case 'Task':
|
|
1264
975
|
case 'task': {
|
|
@@ -1292,7 +1003,7 @@ export class ShellUIAdapter {
|
|
|
1292
1003
|
if (lines <= 3) {
|
|
1293
1004
|
return 'Completed';
|
|
1294
1005
|
}
|
|
1295
|
-
return `${theme.info(String(lines))} lines`;
|
|
1006
|
+
return `${theme.info(String(lines))} lines ${expandHint}`;
|
|
1296
1007
|
}
|
|
1297
1008
|
}
|
|
1298
1009
|
}
|
|
@@ -1301,10 +1012,11 @@ export class ShellUIAdapter {
|
|
|
1301
1012
|
* Example output:
|
|
1302
1013
|
* Read 100 lines
|
|
1303
1014
|
* Found 4 lines
|
|
1304
|
-
* +31 more tool uses
|
|
1015
|
+
* +31 more tool uses (ctrl+o to expand)
|
|
1305
1016
|
*/
|
|
1306
1017
|
formatAgentResultSummary(output) {
|
|
1307
1018
|
const lines = [];
|
|
1019
|
+
const expandHint = theme.ui.muted('(ctrl+o to expand)');
|
|
1308
1020
|
// Parse output for tool use summaries
|
|
1309
1021
|
// Look for patterns like "Read X lines", "Found X files", "Output: X lines", etc.
|
|
1310
1022
|
const toolPatterns = [
|
|
@@ -1337,13 +1049,13 @@ export class ShellUIAdapter {
|
|
|
1337
1049
|
lines.push(use);
|
|
1338
1050
|
}
|
|
1339
1051
|
if (remaining > 0) {
|
|
1340
|
-
lines.push(`+${remaining} more tool uses`);
|
|
1052
|
+
lines.push(`+${remaining} more tool uses ${expandHint}`);
|
|
1341
1053
|
}
|
|
1342
1054
|
else if (lines.length === 0) {
|
|
1343
1055
|
// Fallback if no tool uses found
|
|
1344
1056
|
const outputLines = output.trim().split('\n').filter(l => l.trim()).length;
|
|
1345
1057
|
if (outputLines > 0) {
|
|
1346
|
-
return `${theme.info(String(outputLines))} lines`;
|
|
1058
|
+
return `${theme.info(String(outputLines))} lines ${expandHint}`;
|
|
1347
1059
|
}
|
|
1348
1060
|
return 'Completed';
|
|
1349
1061
|
}
|