erosolar-cli 1.7.14 → 1.7.16

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 (61) 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 +10 -0
  6. package/dist/shell/interactiveShell.d.ts.map +1 -1
  7. package/dist/shell/interactiveShell.js +80 -0
  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/persistentPrompt.d.ts +4 -0
  14. package/dist/ui/persistentPrompt.d.ts.map +1 -1
  15. package/dist/ui/persistentPrompt.js +10 -11
  16. package/dist/ui/persistentPrompt.js.map +1 -1
  17. package/package.json +1 -1
  18. package/dist/bin/core/agent.js +0 -362
  19. package/dist/bin/core/agentProfileManifest.js +0 -187
  20. package/dist/bin/core/agentProfiles.js +0 -34
  21. package/dist/bin/core/agentRulebook.js +0 -135
  22. package/dist/bin/core/agentSchemaLoader.js +0 -233
  23. package/dist/bin/core/contextManager.js +0 -412
  24. package/dist/bin/core/contextWindow.js +0 -122
  25. package/dist/bin/core/customCommands.js +0 -80
  26. package/dist/bin/core/errors/apiKeyErrors.js +0 -114
  27. package/dist/bin/core/errors/errorTypes.js +0 -340
  28. package/dist/bin/core/errors/safetyValidator.js +0 -304
  29. package/dist/bin/core/errors.js +0 -32
  30. package/dist/bin/core/modelDiscovery.js +0 -755
  31. package/dist/bin/core/preferences.js +0 -224
  32. package/dist/bin/core/schemaValidator.js +0 -92
  33. package/dist/bin/core/secretStore.js +0 -199
  34. package/dist/bin/core/sessionStore.js +0 -187
  35. package/dist/bin/core/toolRuntime.js +0 -290
  36. package/dist/bin/core/types.js +0 -1
  37. package/dist/bin/shell/bracketedPasteManager.js +0 -350
  38. package/dist/bin/shell/fileChangeTracker.js +0 -65
  39. package/dist/bin/shell/interactiveShell.js +0 -2908
  40. package/dist/bin/shell/liveStatus.js +0 -78
  41. package/dist/bin/shell/shellApp.js +0 -290
  42. package/dist/bin/shell/systemPrompt.js +0 -60
  43. package/dist/bin/shell/updateManager.js +0 -108
  44. package/dist/bin/ui/ShellUIAdapter.js +0 -459
  45. package/dist/bin/ui/UnifiedUIController.js +0 -183
  46. package/dist/bin/ui/animation/AnimationScheduler.js +0 -430
  47. package/dist/bin/ui/codeHighlighter.js +0 -854
  48. package/dist/bin/ui/designSystem.js +0 -121
  49. package/dist/bin/ui/display.js +0 -1222
  50. package/dist/bin/ui/interrupts/InterruptManager.js +0 -437
  51. package/dist/bin/ui/layout.js +0 -139
  52. package/dist/bin/ui/orchestration/StatusOrchestrator.js +0 -403
  53. package/dist/bin/ui/outputMode.js +0 -38
  54. package/dist/bin/ui/persistentPrompt.js +0 -183
  55. package/dist/bin/ui/richText.js +0 -338
  56. package/dist/bin/ui/shortcutsHelp.js +0 -87
  57. package/dist/bin/ui/telemetry/UITelemetry.js +0 -443
  58. package/dist/bin/ui/textHighlighter.js +0 -210
  59. package/dist/bin/ui/theme.js +0 -116
  60. package/dist/bin/ui/toolDisplay.js +0 -423
  61. 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
- }