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.
Files changed (52) hide show
  1. package/dist/capabilities/learnCapability.d.ts +9 -0
  2. package/dist/capabilities/learnCapability.d.ts.map +1 -1
  3. package/dist/capabilities/learnCapability.js +15 -2
  4. package/dist/capabilities/learnCapability.js.map +1 -1
  5. package/dist/shell/interactiveShell.d.ts +2 -0
  6. package/dist/shell/interactiveShell.d.ts.map +1 -1
  7. package/dist/shell/interactiveShell.js +32 -15
  8. package/dist/shell/interactiveShell.js.map +1 -1
  9. package/dist/shell/terminalInput.d.ts +44 -22
  10. package/dist/shell/terminalInput.d.ts.map +1 -1
  11. package/dist/shell/terminalInput.js +235 -260
  12. package/dist/shell/terminalInput.js.map +1 -1
  13. package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
  14. package/dist/shell/terminalInputAdapter.js +5 -2
  15. package/dist/shell/terminalInputAdapter.js.map +1 -1
  16. package/dist/subagents/taskRunner.d.ts.map +1 -1
  17. package/dist/subagents/taskRunner.js +7 -25
  18. package/dist/subagents/taskRunner.js.map +1 -1
  19. package/dist/tools/learnTools.js +127 -4
  20. package/dist/tools/learnTools.js.map +1 -1
  21. package/dist/tools/localExplore.d.ts +225 -0
  22. package/dist/tools/localExplore.d.ts.map +1 -0
  23. package/dist/tools/localExplore.js +1295 -0
  24. package/dist/tools/localExplore.js.map +1 -0
  25. package/dist/ui/ShellUIAdapter.d.ts +28 -0
  26. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  27. package/dist/ui/ShellUIAdapter.js +215 -9
  28. package/dist/ui/ShellUIAdapter.js.map +1 -1
  29. package/dist/ui/compactRenderer.d.ts +139 -0
  30. package/dist/ui/compactRenderer.d.ts.map +1 -0
  31. package/dist/ui/compactRenderer.js +398 -0
  32. package/dist/ui/compactRenderer.js.map +1 -0
  33. package/dist/ui/inPlaceUpdater.d.ts +181 -0
  34. package/dist/ui/inPlaceUpdater.d.ts.map +1 -0
  35. package/dist/ui/inPlaceUpdater.js +515 -0
  36. package/dist/ui/inPlaceUpdater.js.map +1 -0
  37. package/dist/ui/theme.d.ts +108 -3
  38. package/dist/ui/theme.d.ts.map +1 -1
  39. package/dist/ui/theme.js +124 -3
  40. package/dist/ui/theme.js.map +1 -1
  41. package/dist/ui/toolDisplay.d.ts +44 -7
  42. package/dist/ui/toolDisplay.d.ts.map +1 -1
  43. package/dist/ui/toolDisplay.js +201 -85
  44. package/dist/ui/toolDisplay.js.map +1 -1
  45. package/dist/ui/unified/index.d.ts +11 -0
  46. package/dist/ui/unified/index.d.ts.map +1 -1
  47. package/dist/ui/unified/index.js +16 -0
  48. package/dist/ui/unified/index.js.map +1 -1
  49. package/dist/ui/unified/layout.d.ts.map +1 -1
  50. package/dist/ui/unified/layout.js +32 -47
  51. package/dist/ui/unified/layout.js.map +1 -1
  52. package/package.json +1 -1
@@ -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, compact } = input;
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, compact);
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, compact);
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, compact);
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, compact) {
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, compact) {
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
- return `${theme.warning('○')} No matches for "${patternDisplay}"`;
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, compact) {
666
+ function formatGlobResult(args, output, success) {
675
667
  const pattern = args['pattern'] || '*';
668
+ const lines = [];
676
669
  if (!success || !output.trim()) {
677
- return `${theme.warning('○')} No files matching "${pattern}"`;
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 - show comprehensive analysis output
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
- // Show comprehensive analysis - not just a summary
1344
- const lines = [];
1345
- const fileMatch = output.match(/Total files:\s*(\d+)/i);
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
- // Extract entry points
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