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.
- package/dist/core/responseVerifier.d.ts +79 -0
- package/dist/core/responseVerifier.d.ts.map +1 -0
- package/dist/core/responseVerifier.js +443 -0
- package/dist/core/responseVerifier.js.map +1 -0
- package/dist/shell/interactiveShell.d.ts +10 -0
- package/dist/shell/interactiveShell.d.ts.map +1 -1
- package/dist/shell/interactiveShell.js +80 -0
- package/dist/shell/interactiveShell.js.map +1 -1
- package/dist/ui/ShellUIAdapter.d.ts +3 -0
- package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
- package/dist/ui/ShellUIAdapter.js +4 -10
- package/dist/ui/ShellUIAdapter.js.map +1 -1
- package/dist/ui/persistentPrompt.d.ts +4 -0
- package/dist/ui/persistentPrompt.d.ts.map +1 -1
- package/dist/ui/persistentPrompt.js +10 -11
- package/dist/ui/persistentPrompt.js.map +1 -1
- package/package.json +1 -1
- package/dist/bin/core/agent.js +0 -362
- package/dist/bin/core/agentProfileManifest.js +0 -187
- package/dist/bin/core/agentProfiles.js +0 -34
- package/dist/bin/core/agentRulebook.js +0 -135
- package/dist/bin/core/agentSchemaLoader.js +0 -233
- package/dist/bin/core/contextManager.js +0 -412
- package/dist/bin/core/contextWindow.js +0 -122
- package/dist/bin/core/customCommands.js +0 -80
- package/dist/bin/core/errors/apiKeyErrors.js +0 -114
- package/dist/bin/core/errors/errorTypes.js +0 -340
- package/dist/bin/core/errors/safetyValidator.js +0 -304
- package/dist/bin/core/errors.js +0 -32
- package/dist/bin/core/modelDiscovery.js +0 -755
- package/dist/bin/core/preferences.js +0 -224
- package/dist/bin/core/schemaValidator.js +0 -92
- package/dist/bin/core/secretStore.js +0 -199
- package/dist/bin/core/sessionStore.js +0 -187
- package/dist/bin/core/toolRuntime.js +0 -290
- package/dist/bin/core/types.js +0 -1
- package/dist/bin/shell/bracketedPasteManager.js +0 -350
- package/dist/bin/shell/fileChangeTracker.js +0 -65
- package/dist/bin/shell/interactiveShell.js +0 -2908
- package/dist/bin/shell/liveStatus.js +0 -78
- package/dist/bin/shell/shellApp.js +0 -290
- package/dist/bin/shell/systemPrompt.js +0 -60
- package/dist/bin/shell/updateManager.js +0 -108
- package/dist/bin/ui/ShellUIAdapter.js +0 -459
- package/dist/bin/ui/UnifiedUIController.js +0 -183
- package/dist/bin/ui/animation/AnimationScheduler.js +0 -430
- package/dist/bin/ui/codeHighlighter.js +0 -854
- package/dist/bin/ui/designSystem.js +0 -121
- package/dist/bin/ui/display.js +0 -1222
- package/dist/bin/ui/interrupts/InterruptManager.js +0 -437
- package/dist/bin/ui/layout.js +0 -139
- package/dist/bin/ui/orchestration/StatusOrchestrator.js +0 -403
- package/dist/bin/ui/outputMode.js +0 -38
- package/dist/bin/ui/persistentPrompt.js +0 -183
- package/dist/bin/ui/richText.js +0 -338
- package/dist/bin/ui/shortcutsHelp.js +0 -87
- package/dist/bin/ui/telemetry/UITelemetry.js +0 -443
- package/dist/bin/ui/textHighlighter.js +0 -210
- package/dist/bin/ui/theme.js +0 -116
- package/dist/bin/ui/toolDisplay.js +0 -423
- package/dist/bin/ui/toolDisplayAdapter.js +0 -357
|
@@ -1,443 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* UITelemetry - Collects and tracks UI performance metrics and user interactions
|
|
3
|
-
* Provides insights into UI responsiveness, user behavior, and system performance
|
|
4
|
-
*/
|
|
5
|
-
import { EventEmitter } from 'events';
|
|
6
|
-
import { performance } from 'perf_hooks';
|
|
7
|
-
export class UITelemetry extends EventEmitter {
|
|
8
|
-
constructor(config = {}) {
|
|
9
|
-
super();
|
|
10
|
-
this.events = [];
|
|
11
|
-
this.metrics = [];
|
|
12
|
-
this.interactions = [];
|
|
13
|
-
this.renderMetrics = [];
|
|
14
|
-
this.errors = [];
|
|
15
|
-
this.marks = new Map();
|
|
16
|
-
this.measures = new Map();
|
|
17
|
-
this.flushTimer = null;
|
|
18
|
-
this.frameCounter = {
|
|
19
|
-
frames: 0,
|
|
20
|
-
dropped: 0,
|
|
21
|
-
lastFrame: performance.now(),
|
|
22
|
-
};
|
|
23
|
-
this.config = {
|
|
24
|
-
enabled: true,
|
|
25
|
-
bufferSize: 10000,
|
|
26
|
-
flushInterval: 60000, // 1 minute
|
|
27
|
-
captureStackTraces: false,
|
|
28
|
-
anonymize: true,
|
|
29
|
-
performanceThresholds: {
|
|
30
|
-
renderTime: 16, // 60 FPS target
|
|
31
|
-
responseTime: 100, // 100ms max response time
|
|
32
|
-
framerate: 30, // Minimum acceptable framerate
|
|
33
|
-
memory: 500 * 1024 * 1024, // 500MB memory threshold
|
|
34
|
-
},
|
|
35
|
-
...config,
|
|
36
|
-
};
|
|
37
|
-
this.sessionStart = Date.now();
|
|
38
|
-
if (this.config.enabled) {
|
|
39
|
-
this.startCollection();
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Start telemetry collection
|
|
44
|
-
*/
|
|
45
|
-
startCollection() {
|
|
46
|
-
// Set up flush timer
|
|
47
|
-
if (this.config.flushInterval > 0) {
|
|
48
|
-
this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
|
|
49
|
-
}
|
|
50
|
-
// Monitor memory usage
|
|
51
|
-
setInterval(() => {
|
|
52
|
-
this.recordMemoryUsage();
|
|
53
|
-
}, 10000); // Every 10 seconds
|
|
54
|
-
this.emit('telemetry:started');
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Record a UI event
|
|
58
|
-
*/
|
|
59
|
-
recordEvent(type, eventMetadata) {
|
|
60
|
-
if (!this.config.enabled)
|
|
61
|
-
return;
|
|
62
|
-
const event = {
|
|
63
|
-
type,
|
|
64
|
-
timestamp: Date.now(),
|
|
65
|
-
metadata: this.config.anonymize ? this.anonymizeData(eventMetadata) : eventMetadata,
|
|
66
|
-
};
|
|
67
|
-
this.events.push(event);
|
|
68
|
-
this.trimBuffer('events');
|
|
69
|
-
this.emit('event:recorded', event);
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Start a performance mark
|
|
73
|
-
*/
|
|
74
|
-
markStart(name) {
|
|
75
|
-
if (!this.config.enabled)
|
|
76
|
-
return;
|
|
77
|
-
this.marks.set(name, performance.now());
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* End a performance mark and record the duration
|
|
81
|
-
*/
|
|
82
|
-
markEnd(name, _metadata) {
|
|
83
|
-
if (!this.config.enabled)
|
|
84
|
-
return 0;
|
|
85
|
-
const start = this.marks.get(name);
|
|
86
|
-
if (!start) {
|
|
87
|
-
console.warn(`No start mark found for: ${name}`);
|
|
88
|
-
return 0;
|
|
89
|
-
}
|
|
90
|
-
const duration = performance.now() - start;
|
|
91
|
-
this.marks.delete(name);
|
|
92
|
-
// Store measure
|
|
93
|
-
if (!this.measures.has(name)) {
|
|
94
|
-
this.measures.set(name, []);
|
|
95
|
-
}
|
|
96
|
-
this.measures.get(name).push(duration);
|
|
97
|
-
// Record metric
|
|
98
|
-
const metric = {
|
|
99
|
-
name,
|
|
100
|
-
value: duration,
|
|
101
|
-
unit: 'ms',
|
|
102
|
-
timestamp: Date.now(),
|
|
103
|
-
};
|
|
104
|
-
this.metrics.push(metric);
|
|
105
|
-
this.trimBuffer('metrics');
|
|
106
|
-
// Check threshold
|
|
107
|
-
this.checkPerformanceThreshold(name, duration);
|
|
108
|
-
this.emit('metric:recorded', metric);
|
|
109
|
-
return duration;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Record a user interaction
|
|
113
|
-
*/
|
|
114
|
-
recordInteraction(type, target) {
|
|
115
|
-
if (!this.config.enabled) {
|
|
116
|
-
return {
|
|
117
|
-
complete: () => { },
|
|
118
|
-
cancel: () => { },
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
const interaction = {
|
|
122
|
-
type,
|
|
123
|
-
target,
|
|
124
|
-
timestamp: Date.now(),
|
|
125
|
-
completed: false,
|
|
126
|
-
};
|
|
127
|
-
this.interactions.push(interaction);
|
|
128
|
-
return {
|
|
129
|
-
complete: () => {
|
|
130
|
-
interaction.completed = true;
|
|
131
|
-
interaction.responseTime = Date.now() - interaction.timestamp;
|
|
132
|
-
this.checkResponseTimeThreshold(interaction.responseTime);
|
|
133
|
-
this.emit('interaction:completed', interaction);
|
|
134
|
-
},
|
|
135
|
-
cancel: () => {
|
|
136
|
-
interaction.completed = false;
|
|
137
|
-
this.emit('interaction:cancelled', interaction);
|
|
138
|
-
},
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Record render metrics
|
|
143
|
-
*/
|
|
144
|
-
recordRender(component, renderTime) {
|
|
145
|
-
if (!this.config.enabled)
|
|
146
|
-
return;
|
|
147
|
-
// Update frame counter
|
|
148
|
-
const now = performance.now();
|
|
149
|
-
const timeSinceLastFrame = now - this.frameCounter.lastFrame;
|
|
150
|
-
if (timeSinceLastFrame > 33.33) { // More than 2 frames at 60fps
|
|
151
|
-
this.frameCounter.dropped++;
|
|
152
|
-
}
|
|
153
|
-
this.frameCounter.frames++;
|
|
154
|
-
this.frameCounter.lastFrame = now;
|
|
155
|
-
const metric = {
|
|
156
|
-
component,
|
|
157
|
-
renderTime,
|
|
158
|
-
frameCount: this.frameCounter.frames,
|
|
159
|
-
dropped: this.frameCounter.dropped,
|
|
160
|
-
timestamp: Date.now(),
|
|
161
|
-
};
|
|
162
|
-
this.renderMetrics.push(metric);
|
|
163
|
-
this.trimBuffer('renderMetrics');
|
|
164
|
-
// Check render time threshold
|
|
165
|
-
if (renderTime > this.config.performanceThresholds.renderTime) {
|
|
166
|
-
this.emit('performance:slow-render', {
|
|
167
|
-
component,
|
|
168
|
-
renderTime,
|
|
169
|
-
threshold: this.config.performanceThresholds.renderTime,
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
this.emit('render:recorded', metric);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Record an error
|
|
176
|
-
*/
|
|
177
|
-
recordError(error, context) {
|
|
178
|
-
if (!this.config.enabled)
|
|
179
|
-
return;
|
|
180
|
-
const errorRecord = {
|
|
181
|
-
error: {
|
|
182
|
-
message: error.message || String(error),
|
|
183
|
-
type: error.constructor?.name || 'Error',
|
|
184
|
-
stack: this.config.captureStackTraces ? error.stack : undefined,
|
|
185
|
-
},
|
|
186
|
-
timestamp: Date.now(),
|
|
187
|
-
context: this.config.anonymize ? this.anonymizeData(context) : context,
|
|
188
|
-
};
|
|
189
|
-
this.errors.push(errorRecord);
|
|
190
|
-
this.trimBuffer('errors');
|
|
191
|
-
this.emit('error:recorded', errorRecord);
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Record memory usage
|
|
195
|
-
*/
|
|
196
|
-
recordMemoryUsage() {
|
|
197
|
-
const usage = process.memoryUsage();
|
|
198
|
-
const metric = {
|
|
199
|
-
name: 'memory.heapUsed',
|
|
200
|
-
value: usage.heapUsed,
|
|
201
|
-
unit: 'bytes',
|
|
202
|
-
timestamp: Date.now(),
|
|
203
|
-
};
|
|
204
|
-
this.metrics.push(metric);
|
|
205
|
-
// Check memory threshold
|
|
206
|
-
if (usage.heapUsed > this.config.performanceThresholds.memory) {
|
|
207
|
-
this.emit('performance:high-memory', {
|
|
208
|
-
usage: usage.heapUsed,
|
|
209
|
-
threshold: this.config.performanceThresholds.memory,
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Check performance threshold
|
|
215
|
-
*/
|
|
216
|
-
checkPerformanceThreshold(name, duration) {
|
|
217
|
-
if (name.includes('render') &&
|
|
218
|
-
duration > this.config.performanceThresholds.renderTime) {
|
|
219
|
-
this.emit('performance:threshold-exceeded', {
|
|
220
|
-
type: 'render',
|
|
221
|
-
name,
|
|
222
|
-
duration,
|
|
223
|
-
threshold: this.config.performanceThresholds.renderTime,
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Check response time threshold
|
|
229
|
-
*/
|
|
230
|
-
checkResponseTimeThreshold(responseTime) {
|
|
231
|
-
if (responseTime > this.config.performanceThresholds.responseTime) {
|
|
232
|
-
this.emit('performance:threshold-exceeded', {
|
|
233
|
-
type: 'response',
|
|
234
|
-
responseTime,
|
|
235
|
-
threshold: this.config.performanceThresholds.responseTime,
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* Trim buffer to prevent memory issues
|
|
241
|
-
*/
|
|
242
|
-
trimBuffer(bufferName) {
|
|
243
|
-
const buffer = this[bufferName];
|
|
244
|
-
if (Array.isArray(buffer) && buffer.length > this.config.bufferSize) {
|
|
245
|
-
// Keep most recent items
|
|
246
|
-
const toRemove = buffer.length - this.config.bufferSize;
|
|
247
|
-
buffer.splice(0, toRemove);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Anonymize sensitive data
|
|
252
|
-
*/
|
|
253
|
-
anonymizeData(data) {
|
|
254
|
-
if (!data)
|
|
255
|
-
return data;
|
|
256
|
-
if (typeof data !== 'object')
|
|
257
|
-
return data;
|
|
258
|
-
const anonymized = { ...data };
|
|
259
|
-
// Remove or hash sensitive fields
|
|
260
|
-
const sensitiveFields = ['password', 'token', 'key', 'secret', 'email', 'username'];
|
|
261
|
-
for (const field of sensitiveFields) {
|
|
262
|
-
if (field in anonymized) {
|
|
263
|
-
anonymized[field] = '[REDACTED]';
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
// Recursively anonymize nested objects
|
|
267
|
-
for (const key in anonymized) {
|
|
268
|
-
if (typeof anonymized[key] === 'object' && anonymized[key] !== null) {
|
|
269
|
-
anonymized[key] = this.anonymizeData(anonymized[key]);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return anonymized;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Get current telemetry snapshot
|
|
276
|
-
*/
|
|
277
|
-
getSnapshot() {
|
|
278
|
-
const now = Date.now();
|
|
279
|
-
const period = {
|
|
280
|
-
start: this.sessionStart,
|
|
281
|
-
end: now,
|
|
282
|
-
};
|
|
283
|
-
// Calculate event statistics
|
|
284
|
-
const eventsByType = {};
|
|
285
|
-
for (const event of this.events) {
|
|
286
|
-
eventsByType[event.type] = (eventsByType[event.type] || 0) + 1;
|
|
287
|
-
}
|
|
288
|
-
// Calculate performance metrics
|
|
289
|
-
const renderTimes = this.renderMetrics.map(m => m.renderTime);
|
|
290
|
-
const avgRenderTime = renderTimes.length > 0
|
|
291
|
-
? renderTimes.reduce((a, b) => a + b, 0) / renderTimes.length
|
|
292
|
-
: 0;
|
|
293
|
-
const responseTimes = this.interactions
|
|
294
|
-
.filter(i => i.responseTime !== undefined)
|
|
295
|
-
.map(i => i.responseTime);
|
|
296
|
-
const avgResponseTime = responseTimes.length > 0
|
|
297
|
-
? responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length
|
|
298
|
-
: 0;
|
|
299
|
-
const framerate = this.frameCounter.frames > 0
|
|
300
|
-
? (this.frameCounter.frames - this.frameCounter.dropped) /
|
|
301
|
-
((now - this.sessionStart) / 1000)
|
|
302
|
-
: 0;
|
|
303
|
-
// Calculate interaction statistics
|
|
304
|
-
const completedInteractions = this.interactions.filter(i => i.completed).length;
|
|
305
|
-
const cancelledInteractions = this.interactions.filter(i => !i.completed).length;
|
|
306
|
-
// Calculate error statistics
|
|
307
|
-
const errorsByType = {};
|
|
308
|
-
for (const error of this.errors) {
|
|
309
|
-
const type = error.error.type || 'Unknown';
|
|
310
|
-
errorsByType[type] = (errorsByType[type] || 0) + 1;
|
|
311
|
-
}
|
|
312
|
-
return {
|
|
313
|
-
timestamp: now,
|
|
314
|
-
period,
|
|
315
|
-
events: {
|
|
316
|
-
total: this.events.length,
|
|
317
|
-
byType: eventsByType,
|
|
318
|
-
},
|
|
319
|
-
performance: {
|
|
320
|
-
avgRenderTime,
|
|
321
|
-
avgResponseTime,
|
|
322
|
-
framerate,
|
|
323
|
-
memoryUsage: process.memoryUsage(),
|
|
324
|
-
cpuUsage: process.cpuUsage(),
|
|
325
|
-
},
|
|
326
|
-
interactions: {
|
|
327
|
-
total: this.interactions.length,
|
|
328
|
-
completed: completedInteractions,
|
|
329
|
-
cancelled: cancelledInteractions,
|
|
330
|
-
avgResponseTime,
|
|
331
|
-
},
|
|
332
|
-
errors: {
|
|
333
|
-
total: this.errors.length,
|
|
334
|
-
byType: errorsByType,
|
|
335
|
-
},
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Get performance summary
|
|
340
|
-
*/
|
|
341
|
-
getPerformanceSummary() {
|
|
342
|
-
const summary = {};
|
|
343
|
-
for (const [name, durations] of this.measures) {
|
|
344
|
-
if (durations.length === 0)
|
|
345
|
-
continue;
|
|
346
|
-
summary[name] = {
|
|
347
|
-
avg: durations.reduce((a, b) => a + b, 0) / durations.length,
|
|
348
|
-
min: Math.min(...durations),
|
|
349
|
-
max: Math.max(...durations),
|
|
350
|
-
count: durations.length,
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
// Find slowest operations
|
|
354
|
-
const allOperations = [];
|
|
355
|
-
for (const metric of this.metrics) {
|
|
356
|
-
if (metric.unit === 'ms') {
|
|
357
|
-
allOperations.push({ name: metric.name, duration: metric.value });
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
const slowestOperations = allOperations
|
|
361
|
-
.sort((a, b) => b.duration - a.duration)
|
|
362
|
-
.slice(0, 10);
|
|
363
|
-
return {
|
|
364
|
-
measures: summary,
|
|
365
|
-
slowestOperations,
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* Flush telemetry data
|
|
370
|
-
*/
|
|
371
|
-
flush() {
|
|
372
|
-
const snapshot = this.getSnapshot();
|
|
373
|
-
this.emit('telemetry:flush', snapshot);
|
|
374
|
-
// Clear old data based on buffer size
|
|
375
|
-
const cutoff = Date.now() - this.config.flushInterval;
|
|
376
|
-
this.events = this.events.filter(e => e.timestamp > cutoff);
|
|
377
|
-
this.metrics = this.metrics.filter(m => m.timestamp > cutoff);
|
|
378
|
-
this.interactions = this.interactions.filter(i => i.timestamp > cutoff);
|
|
379
|
-
this.renderMetrics = this.renderMetrics.filter(m => m.timestamp > cutoff);
|
|
380
|
-
this.errors = this.errors.filter(e => e.timestamp > cutoff);
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Enable or disable telemetry
|
|
384
|
-
*/
|
|
385
|
-
setEnabled(enabled) {
|
|
386
|
-
this.config.enabled = enabled;
|
|
387
|
-
if (!enabled) {
|
|
388
|
-
this.stop();
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
this.startCollection();
|
|
392
|
-
}
|
|
393
|
-
this.emit('telemetry:status-changed', { enabled });
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Update configuration
|
|
397
|
-
*/
|
|
398
|
-
updateConfig(config) {
|
|
399
|
-
const wasEnabled = this.config.enabled;
|
|
400
|
-
this.config = { ...this.config, ...config };
|
|
401
|
-
if (wasEnabled !== this.config.enabled) {
|
|
402
|
-
this.setEnabled(this.config.enabled);
|
|
403
|
-
}
|
|
404
|
-
this.emit('telemetry:config-updated', this.config);
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* Reset all telemetry data
|
|
408
|
-
*/
|
|
409
|
-
reset() {
|
|
410
|
-
this.events = [];
|
|
411
|
-
this.metrics = [];
|
|
412
|
-
this.interactions = [];
|
|
413
|
-
this.renderMetrics = [];
|
|
414
|
-
this.errors = [];
|
|
415
|
-
this.marks.clear();
|
|
416
|
-
this.measures.clear();
|
|
417
|
-
this.frameCounter = {
|
|
418
|
-
frames: 0,
|
|
419
|
-
dropped: 0,
|
|
420
|
-
lastFrame: performance.now(),
|
|
421
|
-
};
|
|
422
|
-
this.sessionStart = Date.now();
|
|
423
|
-
this.emit('telemetry:reset');
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Stop telemetry collection
|
|
427
|
-
*/
|
|
428
|
-
stop() {
|
|
429
|
-
if (this.flushTimer) {
|
|
430
|
-
clearInterval(this.flushTimer);
|
|
431
|
-
this.flushTimer = null;
|
|
432
|
-
}
|
|
433
|
-
this.emit('telemetry:stopped');
|
|
434
|
-
}
|
|
435
|
-
/**
|
|
436
|
-
* Dispose of telemetry
|
|
437
|
-
*/
|
|
438
|
-
dispose() {
|
|
439
|
-
this.stop();
|
|
440
|
-
this.removeAllListeners();
|
|
441
|
-
this.reset();
|
|
442
|
-
}
|
|
443
|
-
}
|
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Text Highlighter - Claude Code style
|
|
3
|
-
* Applies sophisticated coloring to different text types
|
|
4
|
-
*/
|
|
5
|
-
import { theme } from './theme.js';
|
|
6
|
-
/**
|
|
7
|
-
* Highlight file paths (Claude Code style)
|
|
8
|
-
* Example: src/ui/display.ts
|
|
9
|
-
*/
|
|
10
|
-
export function highlightFilePath(path) {
|
|
11
|
-
const parts = path.split('/');
|
|
12
|
-
const file = parts.pop() || '';
|
|
13
|
-
const dir = parts.join('/');
|
|
14
|
-
if (dir) {
|
|
15
|
-
return `${theme.ui.muted(dir + '/')}${theme.info(file)}`;
|
|
16
|
-
}
|
|
17
|
-
return theme.info(file);
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Highlight numbers in text
|
|
21
|
-
* Example: "Read 150 lines" -> "Read [150] lines"
|
|
22
|
-
*/
|
|
23
|
-
export function highlightNumbers(text) {
|
|
24
|
-
return text.replace(/\b(\d+)\b/g, (match) => theme.ui.number(match));
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Highlight code blocks (inline)
|
|
28
|
-
* Example: `const foo = 'bar'`
|
|
29
|
-
*/
|
|
30
|
-
export function highlightInlineCode(text) {
|
|
31
|
-
return text.replace(/`([^`]+)`/g, (_, code) => theme.ui.code(code));
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Highlight quoted strings
|
|
35
|
-
* Example: "hello world"
|
|
36
|
-
*/
|
|
37
|
-
export function highlightQuotedStrings(text) {
|
|
38
|
-
return text.replace(/"([^"]*)"/g, (_, str) => theme.ui.string(`"${str}"`));
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Highlight keywords (Claude Code style)
|
|
42
|
-
* Example: function, class, const, let, etc.
|
|
43
|
-
*/
|
|
44
|
-
export function highlightKeywords(text) {
|
|
45
|
-
const keywords = [
|
|
46
|
-
'function', 'class', 'const', 'let', 'var',
|
|
47
|
-
'import', 'export', 'from', 'default',
|
|
48
|
-
'async', 'await', 'return', 'if', 'else',
|
|
49
|
-
'for', 'while', 'do', 'switch', 'case',
|
|
50
|
-
'try', 'catch', 'finally', 'throw',
|
|
51
|
-
'new', 'this', 'super', 'extends', 'implements',
|
|
52
|
-
];
|
|
53
|
-
let result = text;
|
|
54
|
-
for (const keyword of keywords) {
|
|
55
|
-
const regex = new RegExp(`\\b(${keyword})\\b`, 'g');
|
|
56
|
-
result = result.replace(regex, (match) => theme.ui.keyword(match));
|
|
57
|
-
}
|
|
58
|
-
return result;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Highlight URLs
|
|
62
|
-
*/
|
|
63
|
-
export function highlightUrls(text) {
|
|
64
|
-
const urlRegex = /(https?:\/\/[^\s]+)/g;
|
|
65
|
-
return text.replace(urlRegex, (url) => theme.link.url(url));
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Highlight error messages
|
|
69
|
-
* Makes errors stand out with proper coloring
|
|
70
|
-
*/
|
|
71
|
-
export function highlightError(text) {
|
|
72
|
-
// Highlight error type
|
|
73
|
-
text = text.replace(/^(Error|TypeError|SyntaxError|ReferenceError):/i, (match) => theme.error.bold(match));
|
|
74
|
-
// Highlight stack trace lines
|
|
75
|
-
text = text.replace(/^\s+at\s+(.+):(\d+):(\d+)/gm, (_, location, line, col) => ` at ${theme.ui.muted(location)}:${theme.warning(line)}:${theme.warning(col)}`);
|
|
76
|
-
return text;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Highlight success messages
|
|
80
|
-
*/
|
|
81
|
-
export function highlightSuccess(text) {
|
|
82
|
-
const successWords = ['success', 'completed', 'passed', 'done', 'ok'];
|
|
83
|
-
let result = text;
|
|
84
|
-
for (const word of successWords) {
|
|
85
|
-
const regex = new RegExp(`\\b(${word})\\b`, 'gi');
|
|
86
|
-
result = result.replace(regex, (match) => theme.success.bold(match));
|
|
87
|
-
}
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Highlight warning messages
|
|
92
|
-
*/
|
|
93
|
-
export function highlightWarning(text) {
|
|
94
|
-
const warningWords = ['warning', 'deprecated', 'caution', 'attention'];
|
|
95
|
-
let result = text;
|
|
96
|
-
for (const word of warningWords) {
|
|
97
|
-
const regex = new RegExp(`\\b(${word})\\b`, 'gi');
|
|
98
|
-
result = result.replace(regex, (match) => theme.warning.bold(match));
|
|
99
|
-
}
|
|
100
|
-
return result;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Highlight tool names (Claude Code style)
|
|
104
|
-
*/
|
|
105
|
-
export function highlightToolName(name) {
|
|
106
|
-
return theme.info.bold(name);
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Highlight command output (Claude Code style)
|
|
110
|
-
* Applies context-aware highlighting
|
|
111
|
-
*/
|
|
112
|
-
export function highlightCommandOutput(output, command) {
|
|
113
|
-
let result = output;
|
|
114
|
-
// Git commands
|
|
115
|
-
if (command?.includes('git')) {
|
|
116
|
-
result = highlightGitOutput(result);
|
|
117
|
-
}
|
|
118
|
-
// npm commands
|
|
119
|
-
else if (command?.includes('npm')) {
|
|
120
|
-
result = highlightNpmOutput(result);
|
|
121
|
-
}
|
|
122
|
-
// General highlighting
|
|
123
|
-
else {
|
|
124
|
-
result = highlightNumbers(result);
|
|
125
|
-
result = highlightUrls(result);
|
|
126
|
-
result = highlightFilePaths(result);
|
|
127
|
-
}
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Highlight file paths in text
|
|
132
|
-
*/
|
|
133
|
-
function highlightFilePaths(text) {
|
|
134
|
-
// Match common file path patterns
|
|
135
|
-
const pathRegex = /([a-zA-Z0-9_\-./]+\.(ts|js|tsx|jsx|json|md|txt|yml|yaml|css|scss|html))/g;
|
|
136
|
-
return text.replace(pathRegex, (match) => highlightFilePath(match));
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Highlight git output
|
|
140
|
-
*/
|
|
141
|
-
function highlightGitOutput(text) {
|
|
142
|
-
let result = text;
|
|
143
|
-
// Branch names
|
|
144
|
-
result = result.replace(/On branch (\w+)/g, (_, branch) => `On branch ${theme.info.bold(branch)}`);
|
|
145
|
-
// File statuses
|
|
146
|
-
result = result.replace(/^\s*modified:/gm, (match) => theme.warning(match));
|
|
147
|
-
result = result.replace(/^\s*deleted:/gm, (match) => theme.error(match));
|
|
148
|
-
result = result.replace(/^\s*new file:/gm, (match) => theme.success(match));
|
|
149
|
-
// Ahead/behind
|
|
150
|
-
result = result.replace(/ahead (\d+)/g, (_, num) => `ahead ${theme.success.bold(num)}`);
|
|
151
|
-
result = result.replace(/behind (\d+)/g, (_, num) => `behind ${theme.warning.bold(num)}`);
|
|
152
|
-
return result;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Highlight npm output
|
|
156
|
-
*/
|
|
157
|
-
function highlightNpmOutput(text) {
|
|
158
|
-
let result = text;
|
|
159
|
-
// Package names
|
|
160
|
-
result = result.replace(/(@[\w-]+\/[\w-]+|[\w-]+@[\d.]+)/g, (match) => theme.info(match));
|
|
161
|
-
// Warnings
|
|
162
|
-
result = result.replace(/WARN/g, theme.warning.bold('WARN'));
|
|
163
|
-
// Errors
|
|
164
|
-
result = result.replace(/ERR!/g, theme.error.bold('ERR!'));
|
|
165
|
-
return result;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Apply all highlighting (auto-detect)
|
|
169
|
-
*/
|
|
170
|
-
export function highlightText(text, context) {
|
|
171
|
-
let result = text;
|
|
172
|
-
switch (context) {
|
|
173
|
-
case 'error':
|
|
174
|
-
result = highlightError(result);
|
|
175
|
-
break;
|
|
176
|
-
case 'code':
|
|
177
|
-
result = highlightKeywords(result);
|
|
178
|
-
result = highlightQuotedStrings(result);
|
|
179
|
-
result = highlightNumbers(result);
|
|
180
|
-
break;
|
|
181
|
-
case 'command':
|
|
182
|
-
result = highlightCommandOutput(result);
|
|
183
|
-
break;
|
|
184
|
-
case 'log':
|
|
185
|
-
result = highlightSuccess(result);
|
|
186
|
-
result = highlightWarning(result);
|
|
187
|
-
result = highlightNumbers(result);
|
|
188
|
-
break;
|
|
189
|
-
default:
|
|
190
|
-
// Auto-detect and apply all
|
|
191
|
-
result = highlightNumbers(result);
|
|
192
|
-
result = highlightUrls(result);
|
|
193
|
-
result = highlightInlineCode(result);
|
|
194
|
-
result = highlightSuccess(result);
|
|
195
|
-
result = highlightWarning(result);
|
|
196
|
-
}
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Highlight important text (bold + colored)
|
|
201
|
-
*/
|
|
202
|
-
export function highlightImportant(text) {
|
|
203
|
-
return theme.ui.highlight(text);
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Emphasize text (less prominent than important)
|
|
207
|
-
*/
|
|
208
|
-
export function emphasizeText(text) {
|
|
209
|
-
return theme.ui.emphasis(text);
|
|
210
|
-
}
|