erosolar-cli 1.7.13 → 1.7.15

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 (65) hide show
  1. package/dist/core/responseVerifier.d.ts +79 -0
  2. package/dist/core/responseVerifier.d.ts.map +1 -0
  3. package/dist/core/responseVerifier.js +443 -0
  4. package/dist/core/responseVerifier.js.map +1 -0
  5. package/dist/shell/interactiveShell.d.ts +5 -0
  6. package/dist/shell/interactiveShell.d.ts.map +1 -1
  7. package/dist/shell/interactiveShell.js +45 -14
  8. package/dist/shell/interactiveShell.js.map +1 -1
  9. package/dist/ui/ShellUIAdapter.d.ts +3 -0
  10. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  11. package/dist/ui/ShellUIAdapter.js +4 -10
  12. package/dist/ui/ShellUIAdapter.js.map +1 -1
  13. package/dist/ui/display.d.ts +15 -0
  14. package/dist/ui/display.d.ts.map +1 -1
  15. package/dist/ui/display.js +57 -0
  16. package/dist/ui/display.js.map +1 -1
  17. package/dist/ui/persistentPrompt.d.ts +4 -0
  18. package/dist/ui/persistentPrompt.d.ts.map +1 -1
  19. package/dist/ui/persistentPrompt.js +10 -11
  20. package/dist/ui/persistentPrompt.js.map +1 -1
  21. package/package.json +1 -1
  22. package/dist/bin/core/agent.js +0 -362
  23. package/dist/bin/core/agentProfileManifest.js +0 -187
  24. package/dist/bin/core/agentProfiles.js +0 -34
  25. package/dist/bin/core/agentRulebook.js +0 -135
  26. package/dist/bin/core/agentSchemaLoader.js +0 -233
  27. package/dist/bin/core/contextManager.js +0 -412
  28. package/dist/bin/core/contextWindow.js +0 -122
  29. package/dist/bin/core/customCommands.js +0 -80
  30. package/dist/bin/core/errors/apiKeyErrors.js +0 -114
  31. package/dist/bin/core/errors/errorTypes.js +0 -340
  32. package/dist/bin/core/errors/safetyValidator.js +0 -304
  33. package/dist/bin/core/errors.js +0 -32
  34. package/dist/bin/core/modelDiscovery.js +0 -755
  35. package/dist/bin/core/preferences.js +0 -224
  36. package/dist/bin/core/schemaValidator.js +0 -92
  37. package/dist/bin/core/secretStore.js +0 -199
  38. package/dist/bin/core/sessionStore.js +0 -187
  39. package/dist/bin/core/toolRuntime.js +0 -290
  40. package/dist/bin/core/types.js +0 -1
  41. package/dist/bin/shell/bracketedPasteManager.js +0 -350
  42. package/dist/bin/shell/fileChangeTracker.js +0 -65
  43. package/dist/bin/shell/interactiveShell.js +0 -2908
  44. package/dist/bin/shell/liveStatus.js +0 -78
  45. package/dist/bin/shell/shellApp.js +0 -290
  46. package/dist/bin/shell/systemPrompt.js +0 -60
  47. package/dist/bin/shell/updateManager.js +0 -108
  48. package/dist/bin/ui/ShellUIAdapter.js +0 -459
  49. package/dist/bin/ui/UnifiedUIController.js +0 -183
  50. package/dist/bin/ui/animation/AnimationScheduler.js +0 -430
  51. package/dist/bin/ui/codeHighlighter.js +0 -854
  52. package/dist/bin/ui/designSystem.js +0 -121
  53. package/dist/bin/ui/display.js +0 -1222
  54. package/dist/bin/ui/interrupts/InterruptManager.js +0 -437
  55. package/dist/bin/ui/layout.js +0 -139
  56. package/dist/bin/ui/orchestration/StatusOrchestrator.js +0 -403
  57. package/dist/bin/ui/outputMode.js +0 -38
  58. package/dist/bin/ui/persistentPrompt.js +0 -183
  59. package/dist/bin/ui/richText.js +0 -338
  60. package/dist/bin/ui/shortcutsHelp.js +0 -87
  61. package/dist/bin/ui/telemetry/UITelemetry.js +0 -443
  62. package/dist/bin/ui/textHighlighter.js +0 -210
  63. package/dist/bin/ui/theme.js +0 -116
  64. package/dist/bin/ui/toolDisplay.js +0 -423
  65. package/dist/bin/ui/toolDisplayAdapter.js +0 -357
@@ -1,338 +0,0 @@
1
- import { icons, theme } from './theme.js';
2
- import { getContentWidth, measure, normalizePanelWidth, renderPanel, wrapParagraph, wrapPreformatted, } from './layout.js';
3
- import { highlightAndWrapCode } from './codeHighlighter.js';
4
- import { isPlainOutputMode } from './outputMode.js';
5
- export function formatRichContent(content, width) {
6
- const blocks = parseBlocks(content);
7
- const lines = [];
8
- for (const block of blocks) {
9
- let blockLines = [];
10
- switch (block.type) {
11
- case 'paragraph': {
12
- const formatted = formatInlineText(block.text);
13
- blockLines = wrapParagraph(formatted, width);
14
- break;
15
- }
16
- case 'list':
17
- blockLines = formatList(block.items, width);
18
- break;
19
- case 'code':
20
- blockLines = formatCodeBlock(block.content, width, block.language);
21
- break;
22
- case 'diff':
23
- blockLines = formatDiffBlock(block.content, width);
24
- break;
25
- case 'heading':
26
- blockLines = formatHeadingBlock(block, width);
27
- break;
28
- case 'quote':
29
- blockLines = formatQuoteBlock(block.lines, width);
30
- break;
31
- case 'divider':
32
- blockLines = [formatDivider(width)];
33
- break;
34
- default:
35
- blockLines = [];
36
- }
37
- if (!blockLines.length) {
38
- continue;
39
- }
40
- if (lines.length) {
41
- const lastLine = lines[lines.length - 1];
42
- if (lastLine?.trim()) {
43
- lines.push('');
44
- }
45
- }
46
- lines.push(...blockLines);
47
- }
48
- while (lines.length) {
49
- const lastLine = lines[lines.length - 1];
50
- if (lastLine?.trim()) {
51
- break;
52
- }
53
- lines.pop();
54
- }
55
- return lines;
56
- }
57
- export function renderMessagePanel(content, options) {
58
- const width = normalizePanelWidth(options.width ?? getContentWidth());
59
- const lines = formatRichContent(content, width);
60
- return renderPanel(lines, { ...options, width });
61
- }
62
- export function renderMessageBody(content, width) {
63
- const normalizedWidth = normalizePanelWidth(width ?? getContentWidth());
64
- const lines = formatRichContent(content, normalizedWidth);
65
- return lines.join('\n');
66
- }
67
- export function formatDiffBlock(diff, width) {
68
- const lines = diff.replace(/\t/g, ' ').split('\n');
69
- const result = [];
70
- for (const line of lines) {
71
- if (!line.trim()) {
72
- result.push('');
73
- continue;
74
- }
75
- const color = pickDiffColor(line);
76
- const chunks = wrapPreformatted(line, width);
77
- chunks.forEach((chunk) => result.push(color(chunk)));
78
- }
79
- return result;
80
- }
81
- function parseBlocks(content) {
82
- const blocks = [];
83
- const lines = content.split('\n');
84
- let fence = null;
85
- let paragraph = [];
86
- let blockquote = null;
87
- const flushParagraph = () => {
88
- if (!paragraph.length) {
89
- return;
90
- }
91
- const merged = paragraph.join('\n');
92
- const trimmedLines = merged
93
- .split('\n')
94
- .map((line) => line.trim())
95
- .filter(Boolean);
96
- if (!trimmedLines.length) {
97
- paragraph = [];
98
- return;
99
- }
100
- const isList = trimmedLines.every((line) => /^(\*|-|•|\d+\.)\s+/.test(line));
101
- if (isList) {
102
- blocks.push({
103
- type: 'list',
104
- items: trimmedLines.map((line) => line.replace(/^(\*|-|•|\d+\.)\s+/, '')),
105
- });
106
- }
107
- else {
108
- blocks.push({ type: 'paragraph', text: trimmedLines.join(' ') });
109
- }
110
- paragraph = [];
111
- };
112
- const flushBlockquote = () => {
113
- if (!blockquote?.length) {
114
- blockquote = null;
115
- return;
116
- }
117
- blocks.push({ type: 'quote', lines: blockquote });
118
- blockquote = null;
119
- };
120
- for (const line of lines) {
121
- if (line.trimStart().startsWith('```')) {
122
- const raw = line.trim();
123
- if (fence) {
124
- blocks.push(fence.language.includes('diff')
125
- ? { type: 'diff', content: fence.buffer.join('\n') }
126
- : { type: 'code', content: fence.buffer.join('\n'), language: fence.language });
127
- fence = null;
128
- continue;
129
- }
130
- flushParagraph();
131
- flushBlockquote();
132
- const language = raw.slice(3).trim().toLowerCase();
133
- fence = { language, buffer: [] };
134
- continue;
135
- }
136
- if (fence) {
137
- fence.buffer.push(line);
138
- continue;
139
- }
140
- const trimmed = line.trim();
141
- if (!trimmed) {
142
- flushParagraph();
143
- flushBlockquote();
144
- continue;
145
- }
146
- const quoteMatch = line.match(/^\s*>\s?(.*)$/);
147
- if (quoteMatch) {
148
- flushParagraph();
149
- blockquote = blockquote ?? [];
150
- blockquote.push(quoteMatch[1] ?? '');
151
- continue;
152
- }
153
- flushBlockquote();
154
- const headingMatch = trimmed.match(/^(#{1,6})\s+(.*)$/);
155
- if (headingMatch) {
156
- flushParagraph();
157
- const hashes = headingMatch[1] ?? '';
158
- const text = headingMatch[2] ?? '';
159
- blocks.push({ type: 'heading', level: hashes.length, text: text.trim() });
160
- continue;
161
- }
162
- if (/^(-{3,}|_{3,}|\*{3,})$/.test(trimmed)) {
163
- flushParagraph();
164
- blocks.push({ type: 'divider' });
165
- continue;
166
- }
167
- paragraph.push(line);
168
- }
169
- flushParagraph();
170
- flushBlockquote();
171
- return blocks;
172
- }
173
- function formatList(items, width) {
174
- const lines = [];
175
- const bullet = theme.secondary(`${icons.bullet} `);
176
- const bulletWidth = measure(`${icons.bullet} `);
177
- const contentWidth = Math.max(10, width - bulletWidth);
178
- for (const item of items) {
179
- const formatted = formatInlineText(item);
180
- const wrapped = wrapParagraph(formatted, contentWidth);
181
- wrapped.forEach((segment, index) => {
182
- if (index === 0) {
183
- lines.push(`${bullet}${segment}`);
184
- }
185
- else {
186
- lines.push(`${' '.repeat(bulletWidth)}${segment}`);
187
- }
188
- });
189
- }
190
- return lines;
191
- }
192
- function formatCodeBlock(code, width, language) {
193
- const gutterRaw = isPlainOutputMode() ? '' : '│ ';
194
- const gutter = theme.ui.muted(gutterRaw);
195
- const available = Math.max(16, width - measure(gutterRaw));
196
- const { lines, languageLabel } = highlightAndWrapCode(code, language, available);
197
- const headerLabel = (languageLabel ?? 'CODE').toUpperCase();
198
- const result = [];
199
- if (isPlainOutputMode()) {
200
- result.push(theme.ui.muted(`[${headerLabel}]`));
201
- for (const line of lines) {
202
- result.push(line);
203
- }
204
- }
205
- else {
206
- result.push(`${gutter}${theme.ui.muted(buildCodeDivider(headerLabel, available))}`);
207
- for (const line of lines) {
208
- result.push(`${gutter}${line}`);
209
- }
210
- }
211
- return result;
212
- }
213
- function formatHeadingBlock(block, width) {
214
- const wrapped = wrapParagraph(formatInlineText(block.text), width);
215
- if (!wrapped.length) {
216
- return [];
217
- }
218
- const accent = pickHeadingAccent(block.level);
219
- const content = wrapped.map((line) => accent(theme.bold(line)));
220
- if (block.level <= 2 && !isPlainOutputMode()) {
221
- content.push(accent('─'.repeat(width)));
222
- }
223
- return content;
224
- }
225
- function formatQuoteBlock(lines, width) {
226
- if (!lines.length) {
227
- return [];
228
- }
229
- const gutterText = isPlainOutputMode() ? '> ' : '│ ';
230
- const gutter = theme.ui.muted(gutterText);
231
- const available = Math.max(12, width - measure(gutterText));
232
- const result = [];
233
- for (const line of lines) {
234
- if (!line.trim()) {
235
- result.push(gutter);
236
- continue;
237
- }
238
- const wrapped = wrapParagraph(formatInlineText(line), available);
239
- wrapped.forEach((segment) => {
240
- result.push(`${gutter}${segment}`);
241
- });
242
- }
243
- return result;
244
- }
245
- function formatDivider(width) {
246
- if (isPlainOutputMode()) {
247
- return theme.ui.muted('---');
248
- }
249
- return theme.ui.muted('─'.repeat(width));
250
- }
251
- function buildCodeDivider(label, width) {
252
- const normalized = label.trim() || 'CODE';
253
- const targetWidth = Math.max(8, width);
254
- const title = ` ${normalized} `;
255
- if (title.length >= targetWidth) {
256
- return title.slice(0, targetWidth);
257
- }
258
- const remaining = targetWidth - title.length;
259
- const left = '─'.repeat(Math.floor(remaining / 2));
260
- const right = '─'.repeat(remaining - left.length);
261
- return `${left}${title}${right}`;
262
- }
263
- function pickDiffColor(line) {
264
- if (line.startsWith('+++') || line.startsWith('---')) {
265
- return theme.diff.header;
266
- }
267
- if (line.startsWith('@@')) {
268
- return theme.diff.hunk;
269
- }
270
- if (line.startsWith('+')) {
271
- return theme.diff.added;
272
- }
273
- if (line.startsWith('-')) {
274
- return theme.diff.removed;
275
- }
276
- if (line.startsWith('diff')) {
277
- return theme.diff.meta;
278
- }
279
- return theme.ui.text;
280
- }
281
- function formatInlineText(text) {
282
- if (!text) {
283
- return '';
284
- }
285
- const codeSpans = [];
286
- const linkSpans = [];
287
- const LINK_PLACEHOLDER = '\u0001';
288
- let result = text.replace(/`([^`]+)`/g, (_, inner) => {
289
- codeSpans.push(inner);
290
- return `\u0000${codeSpans.length - 1}\u0000`;
291
- });
292
- const formatBold = (_match, value) => theme.bold(value);
293
- result = result.replace(/\*\*(.+?)\*\*/g, formatBold);
294
- result = result.replace(/__(.+?)__/g, formatBold);
295
- const formatItalics = (_match, value) => theme.italic(value);
296
- result = result.replace(/(?<!\*)\*(?!\*)([^*]+?)(?<!\*)\*(?!\*)/g, formatItalics);
297
- result = result.replace(/(?<!_)_(?!_)([^_]+?)(?<!_)_(?!_)/g, formatItalics);
298
- result = result.replace(/~~(.+?)~~/g, (_match, value) => theme.dim(value));
299
- result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, label, url) => {
300
- linkSpans.push(formatMarkdownLink(label, url));
301
- return `${LINK_PLACEHOLDER}${linkSpans.length - 1}${LINK_PLACEHOLDER}`;
302
- });
303
- result = result.replace(/(\bhttps?:\/\/[^\s)]+)([)\]}>,.;:!?"]*)/g, (_match, url, trailing = '') => {
304
- linkSpans.push(`${formatBareLink(url)}${trailing}`);
305
- return `${LINK_PLACEHOLDER}${linkSpans.length - 1}${LINK_PLACEHOLDER}`;
306
- });
307
- result = result.replace(new RegExp(`${LINK_PLACEHOLDER}(\\d+)${LINK_PLACEHOLDER}`, 'g'), (_match, index) => linkSpans[Number.parseInt(index, 10)] ?? '');
308
- result = result.replace(/\u0000(\d+)\u0000/g, (_match, index) => formatInlineCode(codeSpans[Number.parseInt(index, 10)] ?? ''));
309
- return result;
310
- }
311
- function formatInlineCode(value) {
312
- const normalized = value.length ? value.trim() : value;
313
- const display = normalized.length ? normalized : value;
314
- const snippet = display.replace(/\s+/g, ' ');
315
- return theme.ui.background(theme.ui.text(` ${snippet} `));
316
- }
317
- function formatMarkdownLink(label, url) {
318
- const cleanUrl = url.trim();
319
- const cleanLabel = label.trim() || cleanUrl;
320
- const labelColor = theme.link?.label ?? theme.secondary;
321
- const urlColor = theme.link?.url ?? theme.info;
322
- const styledLabel = labelColor(cleanLabel);
323
- const styledUrl = urlColor(`(${cleanUrl})`);
324
- return `${styledLabel} ${styledUrl}`;
325
- }
326
- function formatBareLink(url) {
327
- const colorize = theme.link?.url ?? theme.info;
328
- return colorize(url.trim());
329
- }
330
- function pickHeadingAccent(level) {
331
- if (level <= 1) {
332
- return theme.primary;
333
- }
334
- if (level === 2) {
335
- return theme.secondary;
336
- }
337
- return theme.assistant;
338
- }
@@ -1,87 +0,0 @@
1
- /**
2
- * Keyboard Shortcuts Help Display (Claude Code style)
3
- */
4
- import { theme } from './theme.js';
5
- import { getTerminalColumns } from './layout.js';
6
- const EROSOLAR_SHORTCUTS = [
7
- {
8
- title: 'Navigation',
9
- shortcuts: [
10
- { keys: 'ctrl+c', description: 'Cancel current operation' },
11
- { keys: 'ctrl+d', description: 'Exit (when input is empty)' },
12
- { keys: 'up/down', description: 'Navigate command history' },
13
- ],
14
- },
15
- {
16
- title: 'Editing',
17
- shortcuts: [
18
- { keys: 'ctrl+a', description: 'Move to start of line' },
19
- { keys: 'ctrl+e', description: 'Move to end of line' },
20
- { keys: 'ctrl+k', description: 'Delete to end of line' },
21
- { keys: 'ctrl+u', description: 'Delete to start of line' },
22
- { keys: 'ctrl+w', description: 'Delete previous word' },
23
- ],
24
- },
25
- {
26
- title: 'Composable Messages',
27
- shortcuts: [
28
- { keys: 'ctrl+g', description: 'Edit pasted content blocks' },
29
- { keys: 'shift+tab', description: 'Cycle paste preview options' },
30
- { keys: 'enter', description: 'Send message with blocks' },
31
- ],
32
- },
33
- {
34
- title: 'Special',
35
- shortcuts: [
36
- { keys: '/', description: 'Trigger slash commands' },
37
- { keys: '?', description: 'Show this help' },
38
- { keys: 'ctrl+o', description: 'Expand collapsed output' },
39
- ],
40
- },
41
- ];
42
- /**
43
- * Format keyboard shortcuts help in Claude Code style
44
- */
45
- export function formatShortcutsHelp() {
46
- const width = Math.min(getTerminalColumns(), 80);
47
- const lines = [];
48
- // Title
49
- lines.push('');
50
- lines.push(theme.gradient.primary('Keyboard Shortcuts'));
51
- lines.push(theme.ui.muted('─'.repeat(width - 1)));
52
- lines.push('');
53
- // Groups
54
- for (const group of EROSOLAR_SHORTCUTS) {
55
- lines.push(theme.bold(` ${group.title}`));
56
- lines.push('');
57
- for (const shortcut of group.shortcuts) {
58
- const keys = theme.info(shortcut.keys.padEnd(20));
59
- const desc = theme.ui.muted(shortcut.description);
60
- lines.push(` ${keys} ${desc}`);
61
- }
62
- lines.push('');
63
- }
64
- // Footer
65
- lines.push(theme.ui.muted('─'.repeat(width - 1)));
66
- lines.push(theme.ui.muted(' Press any key to continue...'));
67
- lines.push('');
68
- return lines.join('\n');
69
- }
70
- /**
71
- * Format inline shortcut hint (Claude Code style)
72
- */
73
- export function formatShortcutHint(keys, description) {
74
- return `${theme.info(keys)} ${theme.ui.muted(description)}`;
75
- }
76
- /**
77
- * Quick shortcuts reference (one-line)
78
- */
79
- export function formatQuickShortcuts() {
80
- const hints = [
81
- '? for help',
82
- '/ for commands',
83
- 'ctrl+c to cancel',
84
- 'ctrl+d to exit',
85
- ];
86
- return hints.map(h => theme.ui.muted(h)).join(' · ');
87
- }