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,437 +0,0 @@
1
- /**
2
- * InterruptManager - Manages user interruptions with priority queuing
3
- * Handles interrupt prioritization, deferred execution, and smooth transitions
4
- */
5
- import { EventEmitter } from 'events';
6
- export var InterruptPriority;
7
- (function (InterruptPriority) {
8
- InterruptPriority[InterruptPriority["CRITICAL"] = 100] = "CRITICAL";
9
- InterruptPriority[InterruptPriority["HIGH"] = 75] = "HIGH";
10
- InterruptPriority[InterruptPriority["NORMAL"] = 50] = "NORMAL";
11
- InterruptPriority[InterruptPriority["LOW"] = 25] = "LOW";
12
- InterruptPriority[InterruptPriority["BACKGROUND"] = 0] = "BACKGROUND";
13
- })(InterruptPriority || (InterruptPriority = {}));
14
- export class InterruptManager extends EventEmitter {
15
- constructor(policy = {}) {
16
- super();
17
- this.pendingQueue = [];
18
- this.activeInterrupts = new Map();
19
- this.deferredInterrupts = new Map();
20
- this.isProcessing = false;
21
- this.transitionTimer = null;
22
- this.policy = {
23
- maxQueueSize: 100,
24
- maxDeferrals: 3,
25
- defaultTTL: 30000, // 30 seconds default TTL
26
- allowConcurrent: false,
27
- transitionDuration: 200,
28
- ...policy,
29
- };
30
- }
31
- /**
32
- * Queue a new interrupt
33
- */
34
- queue(config) {
35
- const id = this.generateId();
36
- const interrupt = {
37
- ...config,
38
- id,
39
- timestamp: Date.now(),
40
- ttl: config.ttl || this.policy.defaultTTL,
41
- deferrable: config.deferrable ?? true,
42
- blocking: config.blocking ?? false,
43
- status: 'pending',
44
- deferredCount: 0,
45
- };
46
- // Check queue size limit
47
- if (this.pendingQueue.length >= this.policy.maxQueueSize) {
48
- // Remove lowest priority expired or old interrupts
49
- this.pruneQueue();
50
- if (this.pendingQueue.length >= this.policy.maxQueueSize) {
51
- this.emit('interrupt:rejected', {
52
- interrupt,
53
- reason: 'queue-full',
54
- });
55
- return '';
56
- }
57
- }
58
- // Insert based on priority
59
- const insertIndex = this.findInsertIndex(interrupt.priority);
60
- this.pendingQueue.splice(insertIndex, 0, interrupt);
61
- this.emit('interrupt:queued', interrupt);
62
- // Start expiry timer if TTL is set
63
- if (interrupt.ttl && interrupt.ttl > 0) {
64
- this.scheduleExpiry(interrupt);
65
- }
66
- // Process queue
67
- this.processQueue();
68
- return id;
69
- }
70
- /**
71
- * Process the interrupt queue
72
- */
73
- async processQueue() {
74
- if (this.isProcessing) {
75
- return;
76
- }
77
- this.isProcessing = true;
78
- try {
79
- while (this.pendingQueue.length > 0) {
80
- const interrupt = this.pendingQueue[0];
81
- if (!interrupt)
82
- break;
83
- // Check if interrupt has expired
84
- if (this.isExpired(interrupt)) {
85
- this.expireInterrupt(interrupt);
86
- continue;
87
- }
88
- // Check if we can activate this interrupt
89
- if (!this.canActivate(interrupt)) {
90
- // If it's deferrable and hasn't exceeded max deferrals, defer it
91
- if (interrupt.deferrable && interrupt.deferredCount < this.policy.maxDeferrals) {
92
- this.deferInterrupt(interrupt);
93
- }
94
- break; // Wait for active interrupts to complete
95
- }
96
- // Remove from queue and activate
97
- this.pendingQueue.shift();
98
- await this.activateInterrupt(interrupt);
99
- // If this interrupt is blocking, wait for it to complete
100
- if (interrupt.blocking) {
101
- await this.waitForCompletion(interrupt.id);
102
- }
103
- }
104
- }
105
- finally {
106
- this.isProcessing = false;
107
- }
108
- // Process deferred interrupts if queue is empty
109
- if (this.pendingQueue.length === 0 && this.deferredInterrupts.size > 0) {
110
- this.restoreDeferredInterrupts();
111
- this.processQueue();
112
- }
113
- }
114
- /**
115
- * Check if interrupt can be activated
116
- */
117
- canActivate(interrupt) {
118
- // If no concurrent interrupts allowed and there are active ones
119
- if (!this.policy.allowConcurrent && this.activeInterrupts.size > 0) {
120
- // Check if this interrupt has higher priority than all active ones
121
- for (const active of this.activeInterrupts.values()) {
122
- if (active.priority >= interrupt.priority) {
123
- return false;
124
- }
125
- }
126
- // Higher priority interrupt can preempt if active ones are deferrable
127
- for (const active of this.activeInterrupts.values()) {
128
- if (!active.deferrable) {
129
- return false;
130
- }
131
- }
132
- }
133
- return true;
134
- }
135
- /**
136
- * Activate an interrupt
137
- */
138
- async activateInterrupt(interrupt) {
139
- interrupt.status = 'active';
140
- interrupt.activatedAt = Date.now();
141
- this.activeInterrupts.set(interrupt.id, interrupt);
142
- // Handle smooth transition
143
- if (this.policy.transitionDuration > 0) {
144
- await this.smoothTransition('in', interrupt);
145
- }
146
- this.emit('interrupt:activated', interrupt);
147
- // Execute handler if provided
148
- if (interrupt.handler) {
149
- try {
150
- await interrupt.handler(interrupt);
151
- this.completeInterrupt(interrupt.id);
152
- }
153
- catch (error) {
154
- this.emit('interrupt:error', {
155
- interrupt,
156
- error,
157
- });
158
- this.cancelInterrupt(interrupt.id);
159
- }
160
- }
161
- }
162
- /**
163
- * Complete an interrupt
164
- */
165
- completeInterrupt(id) {
166
- const interrupt = this.activeInterrupts.get(id);
167
- if (!interrupt)
168
- return;
169
- interrupt.status = 'completed';
170
- interrupt.completedAt = Date.now();
171
- this.activeInterrupts.delete(id);
172
- // Handle smooth transition
173
- if (this.policy.transitionDuration > 0) {
174
- this.smoothTransition('out', interrupt);
175
- }
176
- this.emit('interrupt:completed', interrupt);
177
- // Process next in queue
178
- this.processQueue();
179
- }
180
- /**
181
- * Cancel an interrupt
182
- */
183
- cancelInterrupt(id) {
184
- // Check in queue
185
- const queueIndex = this.pendingQueue.findIndex((i) => i.id === id);
186
- if (queueIndex !== -1) {
187
- const interrupt = this.pendingQueue[queueIndex];
188
- if (interrupt) {
189
- interrupt.status = 'cancelled';
190
- this.pendingQueue.splice(queueIndex, 1);
191
- this.emit('interrupt:cancelled', interrupt);
192
- }
193
- return;
194
- }
195
- // Check in active
196
- const active = this.activeInterrupts.get(id);
197
- if (active) {
198
- active.status = 'cancelled';
199
- this.activeInterrupts.delete(id);
200
- this.emit('interrupt:cancelled', active);
201
- this.processQueue();
202
- return;
203
- }
204
- // Check in deferred
205
- const deferred = this.deferredInterrupts.get(id);
206
- if (deferred) {
207
- deferred.status = 'cancelled';
208
- this.deferredInterrupts.delete(id);
209
- this.emit('interrupt:cancelled', deferred);
210
- }
211
- }
212
- /**
213
- * Defer an interrupt
214
- */
215
- deferInterrupt(interrupt) {
216
- this.pendingQueue.shift(); // Remove from queue
217
- interrupt.status = 'deferred';
218
- interrupt.deferredCount++;
219
- this.deferredInterrupts.set(interrupt.id, interrupt);
220
- this.emit('interrupt:deferred', interrupt);
221
- }
222
- /**
223
- * Restore deferred interrupts to queue
224
- */
225
- restoreDeferredInterrupts() {
226
- const deferred = Array.from(this.deferredInterrupts.values());
227
- this.deferredInterrupts.clear();
228
- for (const interrupt of deferred) {
229
- interrupt.status = 'pending';
230
- const insertIndex = this.findInsertIndex(interrupt.priority);
231
- this.pendingQueue.splice(insertIndex, 0, interrupt);
232
- this.emit('interrupt:restored', interrupt);
233
- }
234
- }
235
- /**
236
- * Expire an interrupt
237
- */
238
- expireInterrupt(interrupt) {
239
- interrupt.status = 'expired';
240
- this.pendingQueue.shift();
241
- this.emit('interrupt:expired', interrupt);
242
- }
243
- /**
244
- * Check if interrupt has expired
245
- */
246
- isExpired(interrupt) {
247
- if (!interrupt.ttl || interrupt.ttl <= 0) {
248
- return false;
249
- }
250
- const age = Date.now() - interrupt.timestamp;
251
- return age > interrupt.ttl;
252
- }
253
- /**
254
- * Schedule interrupt expiry
255
- */
256
- scheduleExpiry(interrupt) {
257
- if (!interrupt.ttl || interrupt.ttl <= 0)
258
- return;
259
- setTimeout(() => {
260
- if (interrupt.status === 'pending') {
261
- const index = this.pendingQueue.indexOf(interrupt);
262
- if (index !== -1) {
263
- this.expireInterrupt(interrupt);
264
- this.processQueue();
265
- }
266
- }
267
- }, interrupt.ttl);
268
- }
269
- /**
270
- * Wait for interrupt completion
271
- */
272
- waitForCompletion(id) {
273
- return new Promise((resolve) => {
274
- const checkCompletion = () => {
275
- if (!this.activeInterrupts.has(id)) {
276
- resolve();
277
- }
278
- else {
279
- setTimeout(checkCompletion, 50);
280
- }
281
- };
282
- checkCompletion();
283
- });
284
- }
285
- /**
286
- * Handle smooth transitions
287
- */
288
- async smoothTransition(direction, interrupt) {
289
- return new Promise((resolve) => {
290
- this.emit('interrupt:transition', {
291
- direction,
292
- interrupt,
293
- duration: this.policy.transitionDuration,
294
- });
295
- setTimeout(resolve, this.policy.transitionDuration);
296
- });
297
- }
298
- /**
299
- * Find insertion index based on priority
300
- */
301
- findInsertIndex(priority) {
302
- for (let i = 0; i < this.pendingQueue.length; i++) {
303
- const item = this.pendingQueue[i];
304
- if (item && item.priority < priority) {
305
- return i;
306
- }
307
- }
308
- return this.pendingQueue.length;
309
- }
310
- /**
311
- * Prune expired and low-priority interrupts from queue
312
- */
313
- pruneQueue() {
314
- // Remove expired interrupts
315
- this.pendingQueue = this.pendingQueue.filter((interrupt) => {
316
- if (this.isExpired(interrupt)) {
317
- interrupt.status = 'expired';
318
- this.emit('interrupt:expired', interrupt);
319
- return false;
320
- }
321
- return true;
322
- });
323
- // If still over limit, remove lowest priority
324
- while (this.pendingQueue.length >= this.policy.maxQueueSize) {
325
- const removed = this.pendingQueue.pop();
326
- if (removed) {
327
- removed.status = 'cancelled';
328
- this.emit('interrupt:cancelled', removed);
329
- }
330
- }
331
- }
332
- /**
333
- * Generate unique interrupt ID
334
- */
335
- generateId() {
336
- return `interrupt-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
337
- }
338
- /**
339
- * Get interrupt by ID
340
- */
341
- getInterrupt(id) {
342
- // Check active
343
- if (this.activeInterrupts.has(id)) {
344
- return this.activeInterrupts.get(id);
345
- }
346
- // Check queue
347
- const queued = this.pendingQueue.find((i) => i.id === id);
348
- if (queued)
349
- return queued;
350
- // Check deferred
351
- return this.deferredInterrupts.get(id);
352
- }
353
- /**
354
- * Get all interrupts with a specific status
355
- */
356
- getInterruptsByStatus(status) {
357
- const results = [];
358
- if (status === 'active') {
359
- results.push(...this.activeInterrupts.values());
360
- }
361
- else if (status === 'pending') {
362
- results.push(...this.pendingQueue);
363
- }
364
- else if (status === 'deferred') {
365
- results.push(...this.deferredInterrupts.values());
366
- }
367
- return results;
368
- }
369
- /**
370
- * Get queue statistics
371
- */
372
- getStatistics() {
373
- const allInterrupts = [
374
- ...this.pendingQueue,
375
- ...this.activeInterrupts.values(),
376
- ...this.deferredInterrupts.values(),
377
- ];
378
- const avgPriority = allInterrupts.length > 0
379
- ? allInterrupts.reduce((sum, i) => sum + i.priority, 0) / allInterrupts.length
380
- : 0;
381
- const oldestTimestamp = allInterrupts.length > 0
382
- ? Math.min(...allInterrupts.map((i) => i.timestamp))
383
- : null;
384
- return {
385
- queueLength: this.pendingQueue.length,
386
- activeCount: this.activeInterrupts.size,
387
- deferredCount: this.deferredInterrupts.size,
388
- averagePriority: avgPriority,
389
- oldestTimestamp,
390
- };
391
- }
392
- /**
393
- * Clear all interrupts
394
- */
395
- clearAll() {
396
- // Cancel all active
397
- for (const interrupt of this.activeInterrupts.values()) {
398
- interrupt.status = 'cancelled';
399
- this.emit('interrupt:cancelled', interrupt);
400
- }
401
- this.activeInterrupts.clear();
402
- // Cancel all queued
403
- for (const interrupt of this.pendingQueue) {
404
- interrupt.status = 'cancelled';
405
- this.emit('interrupt:cancelled', interrupt);
406
- }
407
- this.pendingQueue = [];
408
- // Cancel all deferred
409
- for (const interrupt of this.deferredInterrupts.values()) {
410
- interrupt.status = 'cancelled';
411
- this.emit('interrupt:cancelled', interrupt);
412
- }
413
- this.deferredInterrupts.clear();
414
- this.emit('interrupt:cleared');
415
- }
416
- /**
417
- * Update interrupt policy
418
- */
419
- updatePolicy(policy) {
420
- this.policy = {
421
- ...this.policy,
422
- ...policy,
423
- };
424
- this.emit('policy:updated', this.policy);
425
- }
426
- /**
427
- * Dispose of the manager
428
- */
429
- dispose() {
430
- this.clearAll();
431
- this.removeAllListeners();
432
- if (this.transitionTimer) {
433
- clearTimeout(this.transitionTimer);
434
- this.transitionTimer = null;
435
- }
436
- }
437
- }
@@ -1,139 +0,0 @@
1
- import { theme } from './theme.js';
2
- import { isPlainOutputMode } from './outputMode.js';
3
- const MIN_WIDTH = 42;
4
- const MAX_WIDTH = 110;
5
- const ANSI_REGEX = /\u001B\[[0-9;]*m/g;
6
- export function getTerminalColumns(defaultWidth = 80) {
7
- if (typeof process.stdout.columns === 'number' &&
8
- Number.isFinite(process.stdout.columns) &&
9
- process.stdout.columns > 0) {
10
- return process.stdout.columns;
11
- }
12
- return defaultWidth;
13
- }
14
- export function getContentWidth() {
15
- const columns = getTerminalColumns();
16
- const usable = typeof columns === 'number' && Number.isFinite(columns) ? columns - 6 : MAX_WIDTH;
17
- return clampWidth(usable, columns);
18
- }
19
- export function wrapParagraph(text, width) {
20
- const words = text.split(/\s+/).filter(Boolean);
21
- if (!words.length) {
22
- return [''];
23
- }
24
- const lines = [];
25
- let current = words.shift();
26
- for (const word of words) {
27
- if (measure(`${current} ${word}`) > width) {
28
- lines.push(current);
29
- current = word;
30
- }
31
- else {
32
- current += ` ${word}`;
33
- }
34
- }
35
- lines.push(current);
36
- return lines;
37
- }
38
- export function wrapPreformatted(text, width) {
39
- if (!text) {
40
- return [''];
41
- }
42
- const result = [];
43
- let remaining = text;
44
- while (measure(remaining) > width) {
45
- result.push(remaining.slice(0, width));
46
- remaining = remaining.slice(width);
47
- }
48
- if (remaining) {
49
- result.push(remaining);
50
- }
51
- return result.length ? result : [''];
52
- }
53
- export function normalizePanelWidth(width) {
54
- if (typeof width === 'number' && Number.isFinite(width)) {
55
- return clampWidth(width, getTerminalColumns());
56
- }
57
- return clampWidth(getContentWidth(), getTerminalColumns());
58
- }
59
- export function renderPanel(lines, options = {}) {
60
- // Check if plain output mode is enabled for clipboard-friendly text
61
- if (isPlainOutputMode()) {
62
- return renderPlainPanel(lines, options);
63
- }
64
- const width = normalizePanelWidth(options.width);
65
- const accent = options.accentColor ?? theme.primary;
66
- const iconSegment = options.icon ? `${options.icon} ` : '';
67
- const titleText = options.title ? `${iconSegment}${options.title}` : '';
68
- const output = [];
69
- // Add empty line for spacing
70
- output.push('');
71
- if (titleText) {
72
- const paddedTitle = padLine(accent(truncate(titleText, width)), width);
73
- output.push(paddedTitle);
74
- output.push('');
75
- }
76
- if (!lines.length) {
77
- lines = [''];
78
- }
79
- for (const line of lines) {
80
- const padded = padLine(line, width);
81
- output.push(padded);
82
- }
83
- // Add empty line for spacing
84
- output.push('');
85
- return output.join('\n');
86
- }
87
- /**
88
- * Renders a panel in plain text mode without box-drawing characters.
89
- * Outputs clean text that's clipboard-friendly.
90
- */
91
- function renderPlainPanel(lines, options = {}) {
92
- const accent = options.accentColor ?? theme.primary;
93
- const iconSegment = options.icon ? `${options.icon} ` : '';
94
- const titleText = options.title ? `${iconSegment}${options.title}` : '';
95
- const output = [];
96
- if (titleText) {
97
- output.push(`[${accent(titleText)}]`);
98
- output.push('');
99
- }
100
- if (!lines.length) {
101
- lines = [''];
102
- }
103
- for (const line of lines) {
104
- output.push(line.trimEnd());
105
- }
106
- return output.join('\n');
107
- }
108
- export function measure(text) {
109
- return stripAnsi(text).length;
110
- }
111
- export function stripAnsi(text) {
112
- return text.replace(ANSI_REGEX, '');
113
- }
114
- function clampWidth(value, columns) {
115
- const maxWidth = typeof columns === 'number' && Number.isFinite(columns) && columns > 0
116
- ? Math.max(10, Math.floor(columns - 6))
117
- : MAX_WIDTH;
118
- const minWidth = Math.min(MIN_WIDTH, maxWidth);
119
- const normalized = Math.min(MAX_WIDTH, Math.floor(value));
120
- return Math.max(minWidth, Math.min(normalized, maxWidth));
121
- }
122
- function padLine(text, width) {
123
- const visible = measure(text);
124
- if (visible === width) {
125
- return text;
126
- }
127
- if (visible > width) {
128
- return truncate(text, width);
129
- }
130
- return `${text}${' '.repeat(width - visible)}`;
131
- }
132
- function truncate(text, width) {
133
- const visible = stripAnsi(text);
134
- if (visible.length <= width) {
135
- return text;
136
- }
137
- const truncated = visible.slice(0, Math.max(1, width - 1));
138
- return `${truncated}…`;
139
- }