erosolar-cli 1.7.367 → 1.7.369
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/capabilities/learnCapability.d.ts +9 -0
- package/dist/capabilities/learnCapability.d.ts.map +1 -1
- package/dist/capabilities/learnCapability.js +15 -2
- package/dist/capabilities/learnCapability.js.map +1 -1
- package/dist/shell/interactiveShell.d.ts +2 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +32 -15
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/shell/terminalInput.d.ts +44 -22
- package/dist/shell/terminalInput.d.ts.map +1 -1
- package/dist/shell/terminalInput.js +235 -260
- package/dist/shell/terminalInput.js.map +1 -1
- package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
- package/dist/shell/terminalInputAdapter.js +5 -2
- package/dist/shell/terminalInputAdapter.js.map +1 -1
- package/dist/subagents/taskRunner.d.ts.map +1 -1
- package/dist/subagents/taskRunner.js +7 -25
- package/dist/subagents/taskRunner.js.map +1 -1
- package/dist/tools/learnTools.js +127 -4
- package/dist/tools/learnTools.js.map +1 -1
- package/dist/tools/localExplore.d.ts +225 -0
- package/dist/tools/localExplore.d.ts.map +1 -0
- package/dist/tools/localExplore.js +1295 -0
- package/dist/tools/localExplore.js.map +1 -0
- package/dist/ui/ShellUIAdapter.d.ts +28 -0
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +215 -9
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/compactRenderer.d.ts +139 -0
- package/dist/ui/compactRenderer.d.ts.map +1 -0
- package/dist/ui/compactRenderer.js +398 -0
- package/dist/ui/compactRenderer.js.map +1 -0
- package/dist/ui/inPlaceUpdater.d.ts +181 -0
- package/dist/ui/inPlaceUpdater.d.ts.map +1 -0
- package/dist/ui/inPlaceUpdater.js +515 -0
- package/dist/ui/inPlaceUpdater.js.map +1 -0
- package/dist/ui/theme.d.ts +108 -3
- package/dist/ui/theme.d.ts.map +1 -1
- package/dist/ui/theme.js +124 -3
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/toolDisplay.d.ts +44 -7
- package/dist/ui/toolDisplay.d.ts.map +1 -1
- package/dist/ui/toolDisplay.js +201 -85
- package/dist/ui/toolDisplay.js.map +1 -1
- package/dist/ui/unified/index.d.ts +11 -0
- package/dist/ui/unified/index.d.ts.map +1 -1
- package/dist/ui/unified/index.js +16 -0
- package/dist/ui/unified/index.js.map +1 -1
- package/dist/ui/unified/layout.d.ts.map +1 -1
- package/dist/ui/unified/layout.js +32 -47
- package/dist/ui/unified/layout.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/toolDisplay.js
CHANGED
|
@@ -6,9 +6,11 @@
|
|
|
6
6
|
* - Result summaries with status indicators
|
|
7
7
|
* - Expandable content with previews
|
|
8
8
|
* - Diff formatting with colors
|
|
9
|
+
* - Advanced progress indicators
|
|
10
|
+
* - Compact same-line displays
|
|
9
11
|
*/
|
|
10
12
|
import { formatPlan, normalizePlanItems, resolvePlanWidth, wrapPlanText } from '../utils/planFormatter.js';
|
|
11
|
-
import { theme } from './theme.js';
|
|
13
|
+
import { theme, icons, progressChars } from './theme.js';
|
|
12
14
|
/**
|
|
13
15
|
* Format tool call display (Claude Code style)
|
|
14
16
|
*
|
|
@@ -433,7 +435,7 @@ export function formatKeyValue(key, value) {
|
|
|
433
435
|
* @returns Formatted string to display, or null if no display needed
|
|
434
436
|
*/
|
|
435
437
|
export function formatToolResultSummary(input) {
|
|
436
|
-
const { toolName, args, output, success, durationMs
|
|
438
|
+
const { toolName, args, output, success, durationMs } = input;
|
|
437
439
|
// Determine tool category and format accordingly
|
|
438
440
|
switch (toolName) {
|
|
439
441
|
// === FILE OPERATIONS ===
|
|
@@ -447,7 +449,7 @@ export function formatToolResultSummary(input) {
|
|
|
447
449
|
case 'execute_bash':
|
|
448
450
|
case 'execute_bash_stream':
|
|
449
451
|
case 'execute_command':
|
|
450
|
-
return formatBashResult(args, output, success, durationMs
|
|
452
|
+
return formatBashResult(args, output, success, durationMs);
|
|
451
453
|
// === BACKGROUND BASH ===
|
|
452
454
|
case 'BashOutput':
|
|
453
455
|
return formatBashOutputResult(args, output, success);
|
|
@@ -463,11 +465,11 @@ export function formatToolResultSummary(input) {
|
|
|
463
465
|
case 'grep_search':
|
|
464
466
|
case 'search_text':
|
|
465
467
|
case 'search_files':
|
|
466
|
-
return formatGrepResult(args, output, success
|
|
468
|
+
return formatGrepResult(args, output, success);
|
|
467
469
|
case 'Glob':
|
|
468
470
|
case 'glob':
|
|
469
471
|
case 'list_files':
|
|
470
|
-
return formatGlobResult(args, output, success
|
|
472
|
+
return formatGlobResult(args, output, success);
|
|
471
473
|
case 'find_definition':
|
|
472
474
|
return formatFindDefinitionResult(args, output, success);
|
|
473
475
|
// === WEB OPERATIONS ===
|
|
@@ -566,11 +568,13 @@ export function formatToolResultSummary(input) {
|
|
|
566
568
|
// === REPO CHECKS ===
|
|
567
569
|
case 'run_repo_checks':
|
|
568
570
|
return formatRepoChecksResult(args, output, success);
|
|
569
|
-
// === LEARNING ===
|
|
571
|
+
// === LEARNING & EXPLORATION ===
|
|
570
572
|
case 'learn_codebase':
|
|
571
573
|
case 'learn_file':
|
|
572
574
|
case 'learn_topic':
|
|
573
575
|
case 'learn_summary':
|
|
576
|
+
case 'explore':
|
|
577
|
+
case 'explore_index':
|
|
574
578
|
return formatLearnResult(toolName, args, output, success);
|
|
575
579
|
// === DEFAULT: Unknown tools ===
|
|
576
580
|
default:
|
|
@@ -582,23 +586,14 @@ export function formatToolResultSummary(input) {
|
|
|
582
586
|
* Format Bash command result
|
|
583
587
|
* Shows: command executed, exit status, and output preview
|
|
584
588
|
*/
|
|
585
|
-
function formatBashResult(args, output, success, durationMs
|
|
589
|
+
function formatBashResult(args, output, success, durationMs) {
|
|
586
590
|
const command = args['command'] || '';
|
|
587
591
|
const description = args['description'];
|
|
588
|
-
const statusIcon = success ? theme.success('✓') : theme.error('✗');
|
|
589
|
-
const durationStr = durationMs ? ` ${theme.ui.muted(`(${formatDuration(durationMs)})`)}` : '';
|
|
590
|
-
// Compact mode: single line with essential info
|
|
591
|
-
if (compact) {
|
|
592
|
-
const cmdShort = truncateCommand(command, 40);
|
|
593
|
-
const outputLines = output.trim().split('\n').length;
|
|
594
|
-
const outputInfo = output.trim() ? theme.ui.muted(`→ ${outputLines}L`) : '';
|
|
595
|
-
if (description) {
|
|
596
|
-
return `${statusIcon} ${description}${durationStr} ${outputInfo}`;
|
|
597
|
-
}
|
|
598
|
-
return `${statusIcon} ${theme.ui.muted('$')} ${cmdShort}${durationStr} ${outputInfo}`;
|
|
599
|
-
}
|
|
600
592
|
const lines = [];
|
|
593
|
+
// Header with command
|
|
594
|
+
const statusIcon = success ? theme.success('✓') : theme.error('✗');
|
|
601
595
|
const cmdDisplay = truncateCommand(command, 50);
|
|
596
|
+
const durationStr = durationMs ? ` ${theme.ui.muted(`(${formatDuration(durationMs)})`)}` : '';
|
|
602
597
|
if (description) {
|
|
603
598
|
lines.push(`${statusIcon} ${description}${durationStr}`);
|
|
604
599
|
lines.push(` ${theme.ui.muted('$')} ${theme.dim(cmdDisplay)}`);
|
|
@@ -640,20 +635,17 @@ function formatReadResult(args, output, success) {
|
|
|
640
635
|
* Format Grep search result
|
|
641
636
|
* Shows: pattern, matches found, and file list preview
|
|
642
637
|
*/
|
|
643
|
-
function formatGrepResult(args, output, success
|
|
638
|
+
function formatGrepResult(args, output, success) {
|
|
644
639
|
const pattern = args['pattern'] || '';
|
|
645
640
|
const patternDisplay = pattern.length > 30 ? `${pattern.slice(0, 27)}...` : pattern;
|
|
641
|
+
const lines = [];
|
|
646
642
|
if (!success || !output.trim()) {
|
|
647
|
-
|
|
643
|
+
lines.push(`${theme.warning('○')} No matches for "${patternDisplay}"`);
|
|
644
|
+
return lines.join('\n');
|
|
648
645
|
}
|
|
649
646
|
// Count matches/files
|
|
650
647
|
const outputLines = output.trim().split('\n').filter(l => l.trim());
|
|
651
648
|
const matchCount = outputLines.length;
|
|
652
|
-
// Compact mode: single line
|
|
653
|
-
if (compact) {
|
|
654
|
-
return `${theme.success('✓')} grep "${patternDisplay}" ${theme.ui.muted(`→ ${matchCount}`)}`;
|
|
655
|
-
}
|
|
656
|
-
const lines = [];
|
|
657
649
|
lines.push(`${theme.success('✓')} Found ${theme.info(String(matchCount))} match${matchCount === 1 ? '' : 'es'} for "${patternDisplay}"`);
|
|
658
650
|
// Show first few matches
|
|
659
651
|
const maxPreview = 3;
|
|
@@ -671,18 +663,15 @@ function formatGrepResult(args, output, success, compact) {
|
|
|
671
663
|
* Format Glob file search result
|
|
672
664
|
* Shows: pattern and files found
|
|
673
665
|
*/
|
|
674
|
-
function formatGlobResult(args, output, success
|
|
666
|
+
function formatGlobResult(args, output, success) {
|
|
675
667
|
const pattern = args['pattern'] || '*';
|
|
668
|
+
const lines = [];
|
|
676
669
|
if (!success || !output.trim()) {
|
|
677
|
-
|
|
670
|
+
lines.push(`${theme.warning('○')} No files matching "${pattern}"`);
|
|
671
|
+
return lines.join('\n');
|
|
678
672
|
}
|
|
679
673
|
const files = output.trim().split('\n').filter(f => f.trim());
|
|
680
674
|
const fileCount = files.length;
|
|
681
|
-
// Compact mode: single line
|
|
682
|
-
if (compact) {
|
|
683
|
-
return `${theme.success('✓')} glob "${pattern}" ${theme.ui.muted(`→ ${fileCount}`)}`;
|
|
684
|
-
}
|
|
685
|
-
const lines = [];
|
|
686
675
|
lines.push(`${theme.success('✓')} Found ${theme.info(String(fileCount))} file${fileCount === 1 ? '' : 's'} matching "${pattern}"`);
|
|
687
676
|
// Show first few files
|
|
688
677
|
const maxPreview = 4;
|
|
@@ -1332,7 +1321,7 @@ function formatRepoChecksResult(args, output, success) {
|
|
|
1332
1321
|
return `${statusIcon} Repo checks${checkCount > 0 ? ` (${checkCount} checks)` : ''} ${success ? 'passed' : 'failed'}`;
|
|
1333
1322
|
}
|
|
1334
1323
|
/**
|
|
1335
|
-
* Format learn tool result
|
|
1324
|
+
* Format learn tool result
|
|
1336
1325
|
*/
|
|
1337
1326
|
function formatLearnResult(toolName, args, output, success) {
|
|
1338
1327
|
if (!success) {
|
|
@@ -1340,58 +1329,11 @@ function formatLearnResult(toolName, args, output, success) {
|
|
|
1340
1329
|
}
|
|
1341
1330
|
switch (toolName) {
|
|
1342
1331
|
case 'learn_codebase': {
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
const dirMatch = output.match(/Total directories:\s*(\d+)/i);
|
|
1347
|
-
const archMatch = output.match(/Architecture.*?Type:\s*([^\n]+)/i);
|
|
1348
|
-
lines.push(`${theme.success('✓')} ${theme.info('Codebase Analysis Complete')}`);
|
|
1349
|
-
// Extract key stats
|
|
1350
|
-
if (fileMatch || dirMatch) {
|
|
1351
|
-
const stats = [];
|
|
1352
|
-
if (fileMatch)
|
|
1353
|
-
stats.push(`${fileMatch[1]} files`);
|
|
1354
|
-
if (dirMatch)
|
|
1355
|
-
stats.push(`${dirMatch[1]} dirs`);
|
|
1356
|
-
lines.push(` ${theme.ui.muted('Overview:')} ${stats.join(', ')}`);
|
|
1357
|
-
}
|
|
1358
|
-
// Extract architecture type
|
|
1359
|
-
if (archMatch && archMatch[1]) {
|
|
1360
|
-
lines.push(` ${theme.ui.muted('Architecture:')} ${theme.accent(archMatch[1].trim())}`);
|
|
1361
|
-
}
|
|
1362
|
-
// Extract languages (first 3)
|
|
1363
|
-
const langRegex = /- (\w+(?:\s+\w+)?):\s*(\d+)\s*files?\s*\((\d+(?:\.\d+)?)%\)/gi;
|
|
1364
|
-
let langMatch;
|
|
1365
|
-
const languages = [];
|
|
1366
|
-
while ((langMatch = langRegex.exec(output)) !== null && languages.length < 3) {
|
|
1367
|
-
languages.push(`${langMatch[1]} ${langMatch[3]}%`);
|
|
1368
|
-
}
|
|
1369
|
-
if (languages.length > 0) {
|
|
1370
|
-
lines.push(` ${theme.ui.muted('Languages:')} ${languages.join(', ')}`);
|
|
1371
|
-
}
|
|
1372
|
-
// Extract detected patterns
|
|
1373
|
-
const patternMatch = output.match(/## Detected Patterns[\s\S]*?(?=##|$)/);
|
|
1374
|
-
if (patternMatch) {
|
|
1375
|
-
const patterns = patternMatch[0].match(/\*\*([^*]+)\*\*/g);
|
|
1376
|
-
if (patterns && patterns.length > 0) {
|
|
1377
|
-
const patternNames = patterns.slice(0, 3).map(p => p.replace(/\*\*/g, ''));
|
|
1378
|
-
lines.push(` ${theme.ui.muted('Patterns:')} ${theme.secondary(patternNames.join(', '))}`);
|
|
1379
|
-
}
|
|
1332
|
+
const fileMatch = output.match(/(\d+)\s*file/i);
|
|
1333
|
+
if (fileMatch) {
|
|
1334
|
+
return `${theme.success('✓')} Learned codebase: ${fileMatch[1]} files analyzed`;
|
|
1380
1335
|
}
|
|
1381
|
-
|
|
1382
|
-
const entryMatch = output.match(/## Entry Points([\s\S]*?)(?=##|$)/);
|
|
1383
|
-
if (entryMatch && entryMatch[1]) {
|
|
1384
|
-
const entries = entryMatch[1].match(/- ([^\n]+)/g);
|
|
1385
|
-
if (entries && entries.length > 0) {
|
|
1386
|
-
const entry = entries[0]?.replace(/^- /, '').trim();
|
|
1387
|
-
if (entry) {
|
|
1388
|
-
lines.push(` ${theme.ui.muted('Entry:')} ${theme.info(entry)}`);
|
|
1389
|
-
}
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
// Add hint for full output
|
|
1393
|
-
lines.push(` ${theme.dim('(Full analysis in conversation above)')}`);
|
|
1394
|
-
return lines.join('\n');
|
|
1336
|
+
return `${theme.success('✓')} Codebase learned`;
|
|
1395
1337
|
}
|
|
1396
1338
|
case 'learn_file': {
|
|
1397
1339
|
const filePath = (args['file_path'] || args['path']);
|
|
@@ -1410,8 +1352,182 @@ function formatLearnResult(toolName, args, output, success) {
|
|
|
1410
1352
|
case 'learn_summary': {
|
|
1411
1353
|
return `${theme.success('✓')} Summary generated`;
|
|
1412
1354
|
}
|
|
1355
|
+
case 'explore': {
|
|
1356
|
+
const query = (args['query']);
|
|
1357
|
+
const filesMatch = output.match(/Found\s+(\d+)\s+(?:file|relevant)/i);
|
|
1358
|
+
const symbolsMatch = output.match(/Found\s+(\d+)\s+symbol/i);
|
|
1359
|
+
const filesCount = filesMatch ? filesMatch[1] : null;
|
|
1360
|
+
const symbolsCount = symbolsMatch ? symbolsMatch[1] : null;
|
|
1361
|
+
if (filesCount || symbolsCount) {
|
|
1362
|
+
const parts = [];
|
|
1363
|
+
if (filesCount)
|
|
1364
|
+
parts.push(`${filesCount} files`);
|
|
1365
|
+
if (symbolsCount)
|
|
1366
|
+
parts.push(`${symbolsCount} symbols`);
|
|
1367
|
+
return `${theme.success('✓')} Explored: ${parts.join(', ')}`;
|
|
1368
|
+
}
|
|
1369
|
+
if (query) {
|
|
1370
|
+
return `${theme.success('✓')} Explored: "${query.slice(0, 30)}${query.length > 30 ? '...' : ''}"`;
|
|
1371
|
+
}
|
|
1372
|
+
return `${theme.success('✓')} Exploration complete`;
|
|
1373
|
+
}
|
|
1374
|
+
case 'explore_index': {
|
|
1375
|
+
const action = (args['action']);
|
|
1376
|
+
const indexMatch = output.match(/(\d+)\s*files/i);
|
|
1377
|
+
if (action === 'rebuild' && indexMatch) {
|
|
1378
|
+
return `${theme.success('✓')} Index rebuilt: ${indexMatch[1]} files`;
|
|
1379
|
+
}
|
|
1380
|
+
if (action === 'status' && indexMatch) {
|
|
1381
|
+
return `${theme.info('ℹ')} Index: ${indexMatch[1]} files`;
|
|
1382
|
+
}
|
|
1383
|
+
return `${theme.success('✓')} Index ${action || 'managed'}`;
|
|
1384
|
+
}
|
|
1413
1385
|
default:
|
|
1414
1386
|
return `${theme.success('✓')} Learning completed`;
|
|
1415
1387
|
}
|
|
1416
1388
|
}
|
|
1389
|
+
// ============================================================================
|
|
1390
|
+
// ADVANCED PROGRESS INDICATORS
|
|
1391
|
+
// ============================================================================
|
|
1392
|
+
/**
|
|
1393
|
+
* Format a compact progress bar
|
|
1394
|
+
*/
|
|
1395
|
+
export function formatCompactProgressBar(current, total, options = {}) {
|
|
1396
|
+
const { width = 15, style = 'bar' } = options;
|
|
1397
|
+
const percentage = Math.min(100, Math.max(0, Math.round((current / total) * 100)));
|
|
1398
|
+
const filled = Math.round((current / total) * width);
|
|
1399
|
+
const empty = width - filled;
|
|
1400
|
+
let bar;
|
|
1401
|
+
switch (style) {
|
|
1402
|
+
case 'braille': {
|
|
1403
|
+
// Smooth braille progress (8 states per character)
|
|
1404
|
+
const fullBlocks = Math.floor((current / total) * width);
|
|
1405
|
+
const remainder = ((current / total) * width) - fullBlocks;
|
|
1406
|
+
const partials = [' ', '⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿'];
|
|
1407
|
+
const partialIndex = Math.floor(remainder * 8);
|
|
1408
|
+
bar = '⣿'.repeat(fullBlocks);
|
|
1409
|
+
if (fullBlocks < width) {
|
|
1410
|
+
bar += partials[partialIndex] ?? ' ';
|
|
1411
|
+
bar += ' '.repeat(width - fullBlocks - 1);
|
|
1412
|
+
}
|
|
1413
|
+
bar = theme.progress?.bar?.(bar) ?? theme.info(bar);
|
|
1414
|
+
break;
|
|
1415
|
+
}
|
|
1416
|
+
case 'dots':
|
|
1417
|
+
bar = theme.success('●').repeat(filled) + theme.ui.muted('○').repeat(empty);
|
|
1418
|
+
break;
|
|
1419
|
+
case 'bar':
|
|
1420
|
+
default:
|
|
1421
|
+
bar = (theme.progress?.bar ?? theme.info)(progressChars.filled.repeat(filled)) +
|
|
1422
|
+
(theme.progress?.empty ?? theme.ui.muted)(progressChars.empty.repeat(empty));
|
|
1423
|
+
}
|
|
1424
|
+
return `[${bar}] ${(theme.progress?.percentage ?? theme.warning)(`${percentage}%`)}`;
|
|
1425
|
+
}
|
|
1426
|
+
/**
|
|
1427
|
+
* Format a micro progress indicator (fits in status line)
|
|
1428
|
+
*/
|
|
1429
|
+
export function formatMicroProgress(current, total) {
|
|
1430
|
+
const percentage = Math.min(100, Math.max(0, Math.round((current / total) * 100)));
|
|
1431
|
+
// Use single-char block progress
|
|
1432
|
+
const blocks = ['░', '▒', '▓', '█'];
|
|
1433
|
+
const blockIndex = Math.min(3, Math.floor(percentage / 25));
|
|
1434
|
+
const block = blocks[blockIndex] ?? '░';
|
|
1435
|
+
return `${theme.info(block)}${percentage}%`;
|
|
1436
|
+
}
|
|
1437
|
+
/**
|
|
1438
|
+
* Format a spinner with elapsed time
|
|
1439
|
+
*/
|
|
1440
|
+
export function formatSpinnerWithTime(frame, label, elapsedMs) {
|
|
1441
|
+
const elapsed = formatDuration(elapsedMs);
|
|
1442
|
+
return `${theme.info(frame)} ${label} ${theme.ui.muted(`(${elapsed})`)}`;
|
|
1443
|
+
}
|
|
1444
|
+
/**
|
|
1445
|
+
* Format multiple tool operations on a single line
|
|
1446
|
+
*/
|
|
1447
|
+
export function formatCompactToolLine(operations, options = {}) {
|
|
1448
|
+
const { separator = ' · ', maxWidth = 80 } = options;
|
|
1449
|
+
const badges = [];
|
|
1450
|
+
let currentLength = 0;
|
|
1451
|
+
for (const op of operations) {
|
|
1452
|
+
const icon = op.status === 'success' ? icons.success :
|
|
1453
|
+
op.status === 'error' ? icons.error : icons.running;
|
|
1454
|
+
const color = op.status === 'success' ? theme.success :
|
|
1455
|
+
op.status === 'error' ? theme.error : theme.info;
|
|
1456
|
+
let badge = `${color(icon)} ${theme.tool(op.name)}`;
|
|
1457
|
+
if (op.summary) {
|
|
1458
|
+
badge += ` ${theme.ui.muted(op.summary)}`;
|
|
1459
|
+
}
|
|
1460
|
+
const badgeLength = badge.replace(/\u001B\[[0-9;]*m/g, '').length;
|
|
1461
|
+
const sepLength = badges.length > 0 ? separator.replace(/\u001B\[[0-9;]*m/g, '').length : 0;
|
|
1462
|
+
if (currentLength + sepLength + badgeLength > maxWidth - 5) {
|
|
1463
|
+
const remaining = operations.length - badges.length;
|
|
1464
|
+
if (remaining > 0) {
|
|
1465
|
+
badges.push(theme.ui.muted(`+${remaining} more`));
|
|
1466
|
+
}
|
|
1467
|
+
break;
|
|
1468
|
+
}
|
|
1469
|
+
badges.push(badge);
|
|
1470
|
+
currentLength += sepLength + badgeLength;
|
|
1471
|
+
}
|
|
1472
|
+
return badges.join(theme.ui.muted(separator));
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Format a file operation summary with additions/removals
|
|
1476
|
+
*/
|
|
1477
|
+
export function formatFileOpSummary(path, type, stats) {
|
|
1478
|
+
const shortPath = truncatePathForDisplay(path, 40);
|
|
1479
|
+
const icon = type === 'read' ? icons.success :
|
|
1480
|
+
type === 'edit' ? icons.success : icons.success;
|
|
1481
|
+
const color = theme.success;
|
|
1482
|
+
const parts = [
|
|
1483
|
+
`${color(icon)} ${theme.file?.path?.(shortPath) ?? theme.info(shortPath)}`,
|
|
1484
|
+
];
|
|
1485
|
+
if (stats) {
|
|
1486
|
+
const details = [];
|
|
1487
|
+
if (stats.lines !== undefined) {
|
|
1488
|
+
details.push(`${stats.lines} lines`);
|
|
1489
|
+
}
|
|
1490
|
+
if (stats.additions !== undefined && stats.additions > 0) {
|
|
1491
|
+
details.push((theme.file?.additions ?? theme.success)(`+${stats.additions}`));
|
|
1492
|
+
}
|
|
1493
|
+
if (stats.removals !== undefined && stats.removals > 0) {
|
|
1494
|
+
details.push((theme.file?.removals ?? theme.error)(`-${stats.removals}`));
|
|
1495
|
+
}
|
|
1496
|
+
if (details.length > 0) {
|
|
1497
|
+
parts.push(theme.ui.muted(`(${details.join(', ')})`));
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
return parts.join(' ');
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Format a search result summary
|
|
1504
|
+
*/
|
|
1505
|
+
export function formatSearchOpSummary(pattern, matchCount, fileCount, durationMs) {
|
|
1506
|
+
const truncPattern = pattern.length > 25 ? `${pattern.slice(0, 22)}...` : pattern;
|
|
1507
|
+
if (matchCount === 0) {
|
|
1508
|
+
return `${theme.warning(icons.pending)} No matches for "${truncPattern}"`;
|
|
1509
|
+
}
|
|
1510
|
+
const parts = [
|
|
1511
|
+
`${theme.success(icons.success)} Found`,
|
|
1512
|
+
theme.info(`${matchCount}`),
|
|
1513
|
+
matchCount === 1 ? 'match' : 'matches',
|
|
1514
|
+
];
|
|
1515
|
+
if (fileCount && fileCount > 0) {
|
|
1516
|
+
parts.push('in', theme.info(`${fileCount}`), fileCount === 1 ? 'file' : 'files');
|
|
1517
|
+
}
|
|
1518
|
+
parts.push(theme.ui.muted(`for "${truncPattern}"`));
|
|
1519
|
+
if (durationMs) {
|
|
1520
|
+
parts.push(theme.ui.muted(`(${formatDuration(durationMs)})`));
|
|
1521
|
+
}
|
|
1522
|
+
return parts.join(' ');
|
|
1523
|
+
}
|
|
1524
|
+
/**
|
|
1525
|
+
* Format a context usage badge
|
|
1526
|
+
*/
|
|
1527
|
+
export function formatContextBadge(usedPercentage) {
|
|
1528
|
+
const remaining = 100 - usedPercentage;
|
|
1529
|
+
const color = usedPercentage > 80 ? theme.error :
|
|
1530
|
+
usedPercentage > 60 ? theme.warning : theme.success;
|
|
1531
|
+
return `${color(icons.context)}${remaining}%`;
|
|
1532
|
+
}
|
|
1417
1533
|
//# sourceMappingURL=toolDisplay.js.map
|