erosolar-cli 1.7.402 → 1.7.403
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 +5 -5
- package/dist/contracts/agent-profiles.schema.json +5 -5
- package/dist/contracts/agent-schemas.json +5 -5
- package/dist/contracts/unified-schema.json +3 -3
- package/dist/core/modelDiscovery.js +2 -2
- package/dist/core/modelDiscovery.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +4 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +54 -11
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +18 -12
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +263 -69
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/assistantBlockRenderer.d.ts +1 -0
- package/dist/ui/assistantBlockRenderer.d.ts.map +1 -1
- package/dist/ui/assistantBlockRenderer.js +17 -2
- package/dist/ui/assistantBlockRenderer.js.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +1 -1
- package/dist/ui/orchestration/UIUpdateCoordinator.js +5 -3
- package/dist/ui/orchestration/UIUpdateCoordinator.js.map +1 -1
- package/package.json +1 -1
|
@@ -57,10 +57,6 @@ export declare class ShellUIAdapter {
|
|
|
57
57
|
* Uses compact rendering for same-line displays when appropriate
|
|
58
58
|
*/
|
|
59
59
|
createToolObserver(): ToolRuntimeObserver;
|
|
60
|
-
/**
|
|
61
|
-
* Check if a tool should use compact (single-line) display
|
|
62
|
-
*/
|
|
63
|
-
private isCompactTool;
|
|
64
60
|
/**
|
|
65
61
|
* Normalize preflight warnings for consistent display.
|
|
66
62
|
*/
|
|
@@ -82,10 +78,6 @@ export declare class ShellUIAdapter {
|
|
|
82
78
|
* Includes file paths for file operations so users can see which files were accessed
|
|
83
79
|
*/
|
|
84
80
|
private extractResultSummary;
|
|
85
|
-
/**
|
|
86
|
-
* Display compact single-line result
|
|
87
|
-
*/
|
|
88
|
-
private displayCompactResult;
|
|
89
81
|
/**
|
|
90
82
|
* Determine if a tool should show initial ⏺ display
|
|
91
83
|
* Returns true for tools with streaming/progressive output
|
|
@@ -175,20 +167,34 @@ export declare class ShellUIAdapter {
|
|
|
175
167
|
*/
|
|
176
168
|
private parseFileChange;
|
|
177
169
|
/**
|
|
178
|
-
* Display tool result summary
|
|
179
|
-
*
|
|
180
|
-
* Routes through display module to work with scroll regions
|
|
170
|
+
* Display tool result summary in a compact, badge-driven line with an optional preview block.
|
|
171
|
+
* Routes through display module to work with scroll regions while keeping output minimal.
|
|
181
172
|
*/
|
|
182
173
|
private displayToolResultSummary;
|
|
183
174
|
/**
|
|
184
175
|
* Display full tool output directly under the summary block.
|
|
185
|
-
*
|
|
176
|
+
* Now uses the same compact preview system to keep verbose tools readable.
|
|
186
177
|
*/
|
|
187
178
|
private displayFullToolOutput;
|
|
188
179
|
/**
|
|
189
180
|
* Format tool result summary in Claude Code style
|
|
190
181
|
* Returns compact summary like "Found 4 files (ctrl+o to expand)" or "Read 50 lines"
|
|
191
182
|
*/
|
|
183
|
+
private formatCompactToolLine;
|
|
184
|
+
/**
|
|
185
|
+
* Build compact summary + detail parts for a tool result line.
|
|
186
|
+
* Keeps the main text meaningful (path/query) and pushes counts into detail.
|
|
187
|
+
*/
|
|
188
|
+
private buildToolSummaryParts;
|
|
189
|
+
/**
|
|
190
|
+
* Render a compact preview of tool output (first N lines) with truncation hints.
|
|
191
|
+
*/
|
|
192
|
+
private formatToolPreview;
|
|
193
|
+
private buildPreviewLines;
|
|
194
|
+
private getPreviewLineLimit;
|
|
195
|
+
private truncatePreviewLine;
|
|
196
|
+
private countOutputLines;
|
|
197
|
+
private parseTestCounts;
|
|
192
198
|
private formatClaudeCodeResultSummary;
|
|
193
199
|
/**
|
|
194
200
|
* Format agent/task result summary showing nested tool uses
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShellUIAdapter.d.ts","sourceRoot":"","sources":["../../src/ui/ShellUIAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAA2B,MAAM,wBAAwB,CAAC;AAKtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAK3E,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,CAAC;AAC3F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,qBAAqB,CAAC;CAC9B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,kBAAkB,CAAC,CAAiG;IAC5H,OAAO,CAAC,mBAAmB,CAAC,CAAqC;IACjE,OAAO,CAAC,sBAAsB,CAAC,CAAgC;IAC/D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAsB;IAGxD,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAK;IACrC,OAAO,CAAC,kBAAkB,CAAiB;IAC3C,OAAO,CAAC,YAAY,CAAoC;gBAGtD,WAAW,EAAE,OAAO,OAAO,CAAC,MAAM,EAClC,OAAO,EAAE,OAAO,EAChB,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM,EAC1C,iBAAiB,CAAC,EAAE,mBAAmB;IAyBzC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAY/B;;OAEG;IACH,oBAAoB,IAAI,mBAAmB;IAI3C;;OAEG;IACH,aAAa,IAAI,mBAAmB;IAIpC;;;;OAIG;IACH,kBAAkB,IAAI,mBAAmB;
|
|
1
|
+
{"version":3,"file":"ShellUIAdapter.d.ts","sourceRoot":"","sources":["../../src/ui/ShellUIAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -167,17 +167,10 @@ export class ShellUIAdapter {
|
|
|
167
167
|
this.fileChangeCallback(fileChange.path, fileChange.type, fileChange.additions, fileChange.removals);
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
this.displayCompactResult(call, output, true);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
// Claude Code style: Display tool result with ⎿ prefix
|
|
176
|
-
this.displayToolResultSummary(call, output, true);
|
|
177
|
-
}
|
|
170
|
+
// Render concise tool result + preview instead of verbose blocks
|
|
171
|
+
this.displayToolResultSummary(call, output, true);
|
|
178
172
|
// Surface any captured preflight warnings in a structured block
|
|
179
173
|
this.flushToolWarnings(call.id, call.name);
|
|
180
|
-
this.displayFullToolOutput(call, output, true);
|
|
181
174
|
// Clear status bar after showing result
|
|
182
175
|
if (this._toolStatusCallback) {
|
|
183
176
|
const completed = this.getToolActionDescription(call);
|
|
@@ -199,16 +192,9 @@ export class ShellUIAdapter {
|
|
|
199
192
|
this.pendingOperations.delete(call.id);
|
|
200
193
|
this.completedOperations.push(op);
|
|
201
194
|
}
|
|
202
|
-
//
|
|
203
|
-
|
|
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
|
-
}
|
|
195
|
+
// Render concise error summary + preview instead of verbose blocks
|
|
196
|
+
this.displayToolResultSummary(call, message, false);
|
|
210
197
|
this.flushToolWarnings(call.id, call.name);
|
|
211
|
-
this.displayFullToolOutput(call, message, false);
|
|
212
198
|
// Clear status bar after showing error
|
|
213
199
|
if (this._toolStatusCallback) {
|
|
214
200
|
const failed = this.getToolActionDescription(call);
|
|
@@ -251,18 +237,6 @@ export class ShellUIAdapter {
|
|
|
251
237
|
},
|
|
252
238
|
};
|
|
253
239
|
}
|
|
254
|
-
/**
|
|
255
|
-
* Check if a tool should use compact (single-line) display
|
|
256
|
-
*/
|
|
257
|
-
isCompactTool(toolName) {
|
|
258
|
-
const compactTools = new Set([
|
|
259
|
-
'Read', 'read_file',
|
|
260
|
-
'Glob', 'glob',
|
|
261
|
-
'TodoWrite', 'todo_write',
|
|
262
|
-
'WebFetch', 'web_fetch',
|
|
263
|
-
]);
|
|
264
|
-
return compactTools.has(toolName);
|
|
265
|
-
}
|
|
266
240
|
/**
|
|
267
241
|
* Normalize preflight warnings for consistent display.
|
|
268
242
|
*/
|
|
@@ -395,21 +369,6 @@ export class ShellUIAdapter {
|
|
|
395
369
|
return 'done';
|
|
396
370
|
}
|
|
397
371
|
}
|
|
398
|
-
/**
|
|
399
|
-
* Display compact single-line result
|
|
400
|
-
*/
|
|
401
|
-
displayCompactResult(call, output, success) {
|
|
402
|
-
const op = {
|
|
403
|
-
id: call.id,
|
|
404
|
-
name: call.name,
|
|
405
|
-
status: success ? 'success' : 'error',
|
|
406
|
-
summary: this.extractResultSummary(call, output),
|
|
407
|
-
startedAt: Date.now(),
|
|
408
|
-
};
|
|
409
|
-
const badge = compactRenderer.formatToolBadge(op);
|
|
410
|
-
// Add newline after result for visual separation
|
|
411
|
-
this.display.stream(`${badge}\n\n`);
|
|
412
|
-
}
|
|
413
372
|
/**
|
|
414
373
|
* Determine if a tool should show initial ⏺ display
|
|
415
374
|
* Returns true for tools with streaming/progressive output
|
|
@@ -901,47 +860,282 @@ export class ShellUIAdapter {
|
|
|
901
860
|
};
|
|
902
861
|
}
|
|
903
862
|
/**
|
|
904
|
-
* Display tool result summary
|
|
905
|
-
*
|
|
906
|
-
* Routes through display module to work with scroll regions
|
|
863
|
+
* Display tool result summary in a compact, badge-driven line with an optional preview block.
|
|
864
|
+
* Routes through display module to work with scroll regions while keeping output minimal.
|
|
907
865
|
*/
|
|
908
866
|
displayToolResultSummary(call, output, success) {
|
|
909
|
-
const
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
// Claude Code style: ⎿ Summary (indented under tool call)
|
|
914
|
-
const prefix = success
|
|
915
|
-
? theme.success(icons.subaction)
|
|
916
|
-
: theme.error(icons.subaction);
|
|
917
|
-
// Add newline after result for visual separation
|
|
918
|
-
this.display.stream(`\n ${prefix} ${summary}\n\n`);
|
|
867
|
+
const summaryLine = this.formatCompactToolLine(call, output, success);
|
|
868
|
+
const preview = this.formatToolPreview(call, output, success);
|
|
869
|
+
if (!summaryLine && !preview) {
|
|
870
|
+
return;
|
|
919
871
|
}
|
|
872
|
+
const blocks = [];
|
|
873
|
+
if (summaryLine)
|
|
874
|
+
blocks.push(summaryLine);
|
|
875
|
+
if (preview)
|
|
876
|
+
blocks.push(preview);
|
|
877
|
+
// Add newline for separation while keeping output compact
|
|
878
|
+
this.display.stream(`\n${blocks.join('\n')}\n\n`);
|
|
920
879
|
}
|
|
921
880
|
/**
|
|
922
881
|
* Display full tool output directly under the summary block.
|
|
923
|
-
*
|
|
882
|
+
* Now uses the same compact preview system to keep verbose tools readable.
|
|
924
883
|
*/
|
|
925
884
|
displayFullToolOutput(call, output, success) {
|
|
926
885
|
const normalized = typeof output === 'string' ? output.trimEnd() : '';
|
|
927
886
|
if (!normalized) {
|
|
928
887
|
return;
|
|
929
888
|
}
|
|
930
|
-
|
|
931
|
-
const
|
|
932
|
-
const
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
.
|
|
936
|
-
|
|
937
|
-
.
|
|
938
|
-
|
|
939
|
-
|
|
889
|
+
// Use the same preview builder to keep verbose output compact
|
|
890
|
+
const preview = this.formatToolPreview(call, normalized, success, true);
|
|
891
|
+
const summary = this.formatCompactToolLine(call, normalized, success);
|
|
892
|
+
const parts = [];
|
|
893
|
+
if (summary)
|
|
894
|
+
parts.push(summary);
|
|
895
|
+
if (preview)
|
|
896
|
+
parts.push(preview);
|
|
897
|
+
if (parts.length) {
|
|
898
|
+
this.display.stream(`\n${parts.join('\n')}\n\n`);
|
|
899
|
+
}
|
|
940
900
|
}
|
|
941
901
|
/**
|
|
942
902
|
* Format tool result summary in Claude Code style
|
|
943
903
|
* Returns compact summary like "Found 4 files (ctrl+o to expand)" or "Read 50 lines"
|
|
944
904
|
*/
|
|
905
|
+
formatCompactToolLine(call, output, success) {
|
|
906
|
+
const { main, detail } = this.buildToolSummaryParts(call, output, success);
|
|
907
|
+
const summary = main || this.getToolSummary(call) || call.name;
|
|
908
|
+
return compactRenderer.formatInlineResult(call.name, success ? 'success' : 'error', summary, detail);
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Build compact summary + detail parts for a tool result line.
|
|
912
|
+
* Keeps the main text meaningful (path/query) and pushes counts into detail.
|
|
913
|
+
*/
|
|
914
|
+
buildToolSummaryParts(call, output, success) {
|
|
915
|
+
const args = call.arguments || {};
|
|
916
|
+
const lineCount = this.countOutputLines(output);
|
|
917
|
+
switch (call.name) {
|
|
918
|
+
case 'Read':
|
|
919
|
+
case 'read_file': {
|
|
920
|
+
const path = this.extractPath(args, ['file_path', 'path']);
|
|
921
|
+
return {
|
|
922
|
+
main: path ? theme.info(this.truncatePath(path, 60)) : 'Read',
|
|
923
|
+
detail: `${lineCount} line${lineCount === 1 ? '' : 's'}`,
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
case 'Write':
|
|
927
|
+
case 'write_file': {
|
|
928
|
+
const path = this.extractPath(args, ['file_path', 'path']);
|
|
929
|
+
const content = args['content'] || output;
|
|
930
|
+
const lines = this.countOutputLines(content);
|
|
931
|
+
return {
|
|
932
|
+
main: path ? theme.info(this.truncatePath(path, 60)) : 'Write',
|
|
933
|
+
detail: `${lines} line${lines === 1 ? '' : 's'}`,
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
case 'Edit':
|
|
937
|
+
case 'edit_file':
|
|
938
|
+
case 'NotebookEdit': {
|
|
939
|
+
const change = this.parseFileChange(call, output);
|
|
940
|
+
const path = change?.path || this.extractPath(args, ['file_path', 'path', 'notebook_path']);
|
|
941
|
+
const detailParts = [];
|
|
942
|
+
if (change) {
|
|
943
|
+
detailParts.push(`+${change.additions}/-${change.removals}`);
|
|
944
|
+
}
|
|
945
|
+
else if (lineCount > 0) {
|
|
946
|
+
detailParts.push(`${lineCount} line${lineCount === 1 ? '' : 's'}`);
|
|
947
|
+
}
|
|
948
|
+
const action = call.name === 'NotebookEdit' ? 'Notebook' : 'Edit';
|
|
949
|
+
return {
|
|
950
|
+
main: path ? `${action} ${theme.info(this.truncatePath(path, 60))}` : action,
|
|
951
|
+
detail: detailParts.join(' · ') || undefined,
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
case 'Grep':
|
|
955
|
+
case 'grep': {
|
|
956
|
+
const pattern = args['pattern'] || '';
|
|
957
|
+
const path = this.extractPath(args, ['path', 'directory']);
|
|
958
|
+
const matches = output.trim() ? output.trim().split('\n').filter(l => l.trim()).length : 0;
|
|
959
|
+
const detailParts = [`${matches} match${matches === 1 ? '' : 'es'}`];
|
|
960
|
+
if (path && path !== '.') {
|
|
961
|
+
detailParts.push(`in ${this.truncatePath(path, 40)}`);
|
|
962
|
+
}
|
|
963
|
+
return {
|
|
964
|
+
main: pattern ? `"${pattern.length > 40 ? `${pattern.slice(0, 37)}...` : pattern}"` : 'Grep',
|
|
965
|
+
detail: detailParts.join(' · '),
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
case 'Glob':
|
|
969
|
+
case 'glob': {
|
|
970
|
+
const pattern = args['pattern'] || '*';
|
|
971
|
+
const files = output.trim() ? output.trim().split('\n').filter(f => f.trim()).length : 0;
|
|
972
|
+
const path = this.extractPath(args, ['path', 'directory']);
|
|
973
|
+
const detailParts = [`${files} file${files === 1 ? '' : 's'}`];
|
|
974
|
+
if (path && path !== '.') {
|
|
975
|
+
detailParts.push(`in ${this.truncatePath(path, 40)}`);
|
|
976
|
+
}
|
|
977
|
+
return {
|
|
978
|
+
main: pattern ? theme.info(pattern) : 'Glob',
|
|
979
|
+
detail: detailParts.join(' · '),
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
case 'Bash':
|
|
983
|
+
case 'bash': {
|
|
984
|
+
const command = args['command'] || '';
|
|
985
|
+
const shortCmd = command.split('\n')[0]?.trim() || command;
|
|
986
|
+
const main = shortCmd
|
|
987
|
+
? `${theme.ui.muted('$')} ${shortCmd.length > 70 ? `${shortCmd.slice(0, 67)}...` : shortCmd}`
|
|
988
|
+
: 'Shell';
|
|
989
|
+
const detail = lineCount === 0 ? 'no output' : `${lineCount} line${lineCount === 1 ? '' : 's'}`;
|
|
990
|
+
return { main, detail };
|
|
991
|
+
}
|
|
992
|
+
case 'WebFetch':
|
|
993
|
+
case 'web_fetch': {
|
|
994
|
+
const url = args['url'] || '';
|
|
995
|
+
let host = url;
|
|
996
|
+
try {
|
|
997
|
+
host = new URL(url).hostname;
|
|
998
|
+
}
|
|
999
|
+
catch {
|
|
1000
|
+
// Keep original
|
|
1001
|
+
}
|
|
1002
|
+
const sizeStr = output.length > 1024 ? `${(output.length / 1024).toFixed(1)}KB` : `${output.length}B`;
|
|
1003
|
+
return { main: host ? `Fetch ${theme.info(host)}` : 'Fetch', detail: sizeStr };
|
|
1004
|
+
}
|
|
1005
|
+
case 'WebSearch':
|
|
1006
|
+
case 'web_search': {
|
|
1007
|
+
const query = args['query'] || '';
|
|
1008
|
+
const queryDisplay = query.length > 50 ? `${query.slice(0, 47)}...` : query;
|
|
1009
|
+
const resultMatches = output.match(/^\d+\./gm);
|
|
1010
|
+
const count = resultMatches ? resultMatches.length : this.countOutputLines(output);
|
|
1011
|
+
return { main: queryDisplay ? `Search "${queryDisplay}"` : 'Search', detail: `${count} result${count === 1 ? '' : 's'}` };
|
|
1012
|
+
}
|
|
1013
|
+
case 'Task':
|
|
1014
|
+
case 'task': {
|
|
1015
|
+
const desc = args['description'] || '';
|
|
1016
|
+
const trimmed = desc.length > 60 ? `${desc.slice(0, 57)}...` : desc;
|
|
1017
|
+
return { main: trimmed || 'Task', detail: success ? 'done' : 'incomplete' };
|
|
1018
|
+
}
|
|
1019
|
+
case 'TodoWrite':
|
|
1020
|
+
case 'todo_write': {
|
|
1021
|
+
const todos = args['todos'];
|
|
1022
|
+
const total = todos?.length || 0;
|
|
1023
|
+
return { main: 'Todos', detail: total ? `${total} item${total === 1 ? '' : 's'}` : undefined };
|
|
1024
|
+
}
|
|
1025
|
+
case 'run_tests': {
|
|
1026
|
+
const pattern = (args['pattern'] || args['filter']);
|
|
1027
|
+
const counts = this.parseTestCounts(output);
|
|
1028
|
+
const detailParts = [];
|
|
1029
|
+
if (counts.passed > 0)
|
|
1030
|
+
detailParts.push(`${counts.passed} pass`);
|
|
1031
|
+
if (counts.failed > 0)
|
|
1032
|
+
detailParts.push(`${counts.failed} fail`);
|
|
1033
|
+
if (counts.skipped > 0)
|
|
1034
|
+
detailParts.push(`${counts.skipped} skip`);
|
|
1035
|
+
if (detailParts.length === 0 && lineCount > 0) {
|
|
1036
|
+
detailParts.push(`${lineCount} line${lineCount === 1 ? '' : 's'}`);
|
|
1037
|
+
}
|
|
1038
|
+
return {
|
|
1039
|
+
main: pattern ? `Tests "${pattern}"` : 'Tests',
|
|
1040
|
+
detail: detailParts.join(' · ') || (success ? 'all passed' : 'failed'),
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
case 'run_build': {
|
|
1044
|
+
const target = (args['target'] || args['script']);
|
|
1045
|
+
const errors = (output.match(/error/gi) || []).length;
|
|
1046
|
+
const detail = errors > 0
|
|
1047
|
+
? `${errors} error${errors === 1 ? '' : 's'}`
|
|
1048
|
+
: `${lineCount} line${lineCount === 1 ? '' : 's'}`;
|
|
1049
|
+
return { main: target ? `Build ${target}` : 'Build', detail };
|
|
1050
|
+
}
|
|
1051
|
+
default: {
|
|
1052
|
+
const summary = this.extractResultSummary(call, output);
|
|
1053
|
+
if (summary) {
|
|
1054
|
+
return { main: summary };
|
|
1055
|
+
}
|
|
1056
|
+
const claudeSummary = this.formatClaudeCodeResultSummary(call.name, args, output, success);
|
|
1057
|
+
if (claudeSummary) {
|
|
1058
|
+
return { main: claudeSummary };
|
|
1059
|
+
}
|
|
1060
|
+
return { main: call.name, detail: lineCount ? `${lineCount} line${lineCount === 1 ? '' : 's'}` : undefined };
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
/**
|
|
1065
|
+
* Render a compact preview of tool output (first N lines) with truncation hints.
|
|
1066
|
+
*/
|
|
1067
|
+
formatToolPreview(call, output, success, force = false) {
|
|
1068
|
+
const previewLines = this.buildPreviewLines(call, output, success, force);
|
|
1069
|
+
if (!previewLines.length) {
|
|
1070
|
+
return null;
|
|
1071
|
+
}
|
|
1072
|
+
const gutter = theme.ui.muted('│');
|
|
1073
|
+
return previewLines.map(line => ` ${gutter} ${line}`).join('\n');
|
|
1074
|
+
}
|
|
1075
|
+
buildPreviewLines(call, output, success, force) {
|
|
1076
|
+
const normalized = (output || '').trim();
|
|
1077
|
+
const allLines = normalized ? normalized.split('\n').filter(l => l.trim()) : [];
|
|
1078
|
+
const limit = this.getPreviewLineLimit(call.name, success);
|
|
1079
|
+
if (limit <= 0 && !force) {
|
|
1080
|
+
return [];
|
|
1081
|
+
}
|
|
1082
|
+
const maxLines = limit > 0 ? limit : force ? Math.min(1, allLines.length) : 0;
|
|
1083
|
+
if (maxLines === 0 || allLines.length === 0) {
|
|
1084
|
+
return [];
|
|
1085
|
+
}
|
|
1086
|
+
const preview = allLines.slice(0, maxLines).map(line => this.truncatePreviewLine(line));
|
|
1087
|
+
const remaining = allLines.length - maxLines;
|
|
1088
|
+
if (remaining > 0) {
|
|
1089
|
+
preview.push(theme.ui.muted(`… +${remaining} more`));
|
|
1090
|
+
}
|
|
1091
|
+
return preview;
|
|
1092
|
+
}
|
|
1093
|
+
getPreviewLineLimit(toolName, success) {
|
|
1094
|
+
switch (toolName) {
|
|
1095
|
+
case 'Read':
|
|
1096
|
+
case 'read_file':
|
|
1097
|
+
return success ? 0 : 1;
|
|
1098
|
+
case 'Glob':
|
|
1099
|
+
case 'glob':
|
|
1100
|
+
return 3;
|
|
1101
|
+
case 'Grep':
|
|
1102
|
+
case 'grep':
|
|
1103
|
+
return 4;
|
|
1104
|
+
case 'Bash':
|
|
1105
|
+
case 'bash':
|
|
1106
|
+
return success ? 3 : 4;
|
|
1107
|
+
case 'run_tests':
|
|
1108
|
+
return success ? 2 : 4;
|
|
1109
|
+
case 'Edit':
|
|
1110
|
+
case 'edit_file':
|
|
1111
|
+
case 'NotebookEdit':
|
|
1112
|
+
return success ? 2 : 4;
|
|
1113
|
+
default:
|
|
1114
|
+
return success ? 2 : 3;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
truncatePreviewLine(line, maxLen = 100) {
|
|
1118
|
+
const trimmed = line.trim();
|
|
1119
|
+
if (trimmed.length <= maxLen) {
|
|
1120
|
+
return theme.dim(trimmed);
|
|
1121
|
+
}
|
|
1122
|
+
return theme.dim(`${trimmed.slice(0, maxLen - 3)}...`);
|
|
1123
|
+
}
|
|
1124
|
+
countOutputLines(output) {
|
|
1125
|
+
if (!output || !output.trim())
|
|
1126
|
+
return 0;
|
|
1127
|
+
return output.trimEnd().split('\n').length;
|
|
1128
|
+
}
|
|
1129
|
+
parseTestCounts(output) {
|
|
1130
|
+
const passMatch = output.match(/(\d+)\s*(?:passing|passed|✓)/i);
|
|
1131
|
+
const failMatch = output.match(/(\d+)\s*(?:failing|failed|✗)/i);
|
|
1132
|
+
const skipMatch = output.match(/(\d+)\s*(?:skipped|pending)/i);
|
|
1133
|
+
return {
|
|
1134
|
+
passed: passMatch ? parseInt(passMatch[1] || '0', 10) : 0,
|
|
1135
|
+
failed: failMatch ? parseInt(failMatch[1] || '0', 10) : 0,
|
|
1136
|
+
skipped: skipMatch ? parseInt(skipMatch[1] || '0', 10) : 0,
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
945
1139
|
formatClaudeCodeResultSummary(toolName, args, output, success) {
|
|
946
1140
|
const expandHint = theme.ui.muted('(ctrl+o to expand)');
|
|
947
1141
|
if (!success) {
|