claude-code-templates 1.10.1 → 1.11.0
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/README.md +6 -0
- package/bin/create-claude-config.js +1 -0
- package/package.json +2 -2
- package/src/analytics/core/ConversationAnalyzer.js +94 -20
- package/src/analytics/core/FileWatcher.js +146 -11
- package/src/analytics/data/DataCache.js +124 -19
- package/src/analytics/notifications/NotificationManager.js +37 -0
- package/src/analytics/notifications/WebSocketServer.js +1 -1
- package/src/analytics-web/FRONT_ARCHITECTURE.md +46 -0
- package/src/analytics-web/assets/js/{main.js → main.js.deprecated} +32 -3
- package/src/analytics-web/components/AgentsPage.js +2535 -0
- package/src/analytics-web/components/App.js +430 -0
- package/src/analytics-web/components/{Dashboard.js → Dashboard.js.deprecated} +23 -7
- package/src/analytics-web/components/DashboardPage.js +1527 -0
- package/src/analytics-web/components/Sidebar.js +197 -0
- package/src/analytics-web/components/ToolDisplay.js +539 -0
- package/src/analytics-web/index.html +3275 -1792
- package/src/analytics-web/services/DataService.js +89 -16
- package/src/analytics-web/services/StateService.js +9 -0
- package/src/analytics-web/services/WebSocketService.js +17 -5
- package/src/analytics.js +323 -35
- package/src/console-bridge.js +610 -0
- package/src/file-operations.js +143 -23
- package/src/index.js +24 -1
- package/src/templates.js +4 -0
- package/src/test-console-bridge.js +67 -0
|
@@ -91,18 +91,19 @@ class DataService {
|
|
|
91
91
|
|
|
92
92
|
return data;
|
|
93
93
|
} catch (error) {
|
|
94
|
-
console.
|
|
94
|
+
console.warn(`Server not available for ${endpoint}:`, error.message);
|
|
95
95
|
|
|
96
96
|
// Return cached data if available, even if stale
|
|
97
97
|
if (this.cache.has(cacheKey)) {
|
|
98
|
-
console.warn('Using stale cached data due to fetch error');
|
|
99
98
|
return this.cache.get(cacheKey).data;
|
|
100
99
|
}
|
|
101
100
|
|
|
101
|
+
// No fallback data - throw error if server unavailable
|
|
102
102
|
throw error;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
|
|
106
107
|
/**
|
|
107
108
|
* Get conversations data
|
|
108
109
|
* @returns {Promise<Object>} Conversations data
|
|
@@ -111,6 +112,19 @@ class DataService {
|
|
|
111
112
|
return await this.cachedFetch('/api/data');
|
|
112
113
|
}
|
|
113
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Get paginated conversations
|
|
117
|
+
* @param {number} page - Page number (0-based)
|
|
118
|
+
* @param {number} limit - Number of conversations per page
|
|
119
|
+
* @returns {Promise<Object>} Paginated conversations data
|
|
120
|
+
*/
|
|
121
|
+
async getConversationsPaginated(page = 0, limit = 10) {
|
|
122
|
+
const cacheDuration = this.realTimeEnabled ? 30000 : 5000;
|
|
123
|
+
return await this.cachedFetch(`/api/conversations?page=${page}&limit=${limit}`, {
|
|
124
|
+
cacheDuration
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
114
128
|
/**
|
|
115
129
|
* Get conversation states for real-time updates
|
|
116
130
|
* @returns {Promise<Object>} Conversation states
|
|
@@ -160,7 +174,6 @@ class DataService {
|
|
|
160
174
|
*/
|
|
161
175
|
clearCache() {
|
|
162
176
|
this.cache.clear();
|
|
163
|
-
console.log('DataService cache cleared');
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
/**
|
|
@@ -181,34 +194,45 @@ class DataService {
|
|
|
181
194
|
* Setup WebSocket integration for real-time updates
|
|
182
195
|
*/
|
|
183
196
|
setupWebSocketIntegration() {
|
|
184
|
-
if (!this.webSocketService)
|
|
197
|
+
if (!this.webSocketService) {
|
|
198
|
+
this.startFallbackPolling();
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
185
201
|
|
|
186
|
-
console.log('🔌 Setting up WebSocket integration for DataService');
|
|
187
202
|
|
|
188
203
|
// Listen for data refresh events
|
|
189
204
|
this.webSocketService.on('data_refresh', (data) => {
|
|
190
|
-
console.log('📊 Real-time data refresh received');
|
|
191
205
|
this.handleRealTimeDataRefresh(data);
|
|
192
206
|
});
|
|
193
207
|
|
|
194
208
|
// Listen for conversation state changes
|
|
195
209
|
this.webSocketService.on('conversation_state_change', (data) => {
|
|
196
|
-
console.log('🔄 Real-time conversation state change');
|
|
197
210
|
this.handleRealTimeStateChange(data);
|
|
198
211
|
});
|
|
199
212
|
|
|
213
|
+
// Listen for new messages
|
|
214
|
+
this.webSocketService.on('new_message', (data) => {
|
|
215
|
+
this.handleNewMessage(data);
|
|
216
|
+
});
|
|
217
|
+
|
|
200
218
|
// Listen for connection status
|
|
201
219
|
this.webSocketService.on('connected', () => {
|
|
202
|
-
console.log('✅ WebSocket connected - enabling real-time updates');
|
|
203
220
|
this.realTimeEnabled = true;
|
|
204
221
|
this.subscribeToChannels();
|
|
222
|
+
this.stopFallbackPolling(); // Stop polling when WebSocket connects
|
|
205
223
|
});
|
|
206
224
|
|
|
207
225
|
this.webSocketService.on('disconnected', () => {
|
|
208
|
-
console.log('❌ WebSocket disconnected - falling back to polling');
|
|
209
226
|
this.realTimeEnabled = false;
|
|
210
227
|
this.startFallbackPolling();
|
|
211
228
|
});
|
|
229
|
+
|
|
230
|
+
// Start polling immediately as fallback, stop if WebSocket connects successfully
|
|
231
|
+
setTimeout(() => {
|
|
232
|
+
if (!this.realTimeEnabled) {
|
|
233
|
+
this.startFallbackPolling();
|
|
234
|
+
}
|
|
235
|
+
}, 1000); // Give WebSocket 1 second to connect
|
|
212
236
|
}
|
|
213
237
|
|
|
214
238
|
/**
|
|
@@ -221,7 +245,6 @@ class DataService {
|
|
|
221
245
|
await this.webSocketService.subscribe('data_updates');
|
|
222
246
|
await this.webSocketService.subscribe('conversation_updates');
|
|
223
247
|
await this.webSocketService.subscribe('system_updates');
|
|
224
|
-
console.log('📡 Subscribed to real-time channels');
|
|
225
248
|
} catch (error) {
|
|
226
249
|
console.error('Error subscribing to channels:', error);
|
|
227
250
|
}
|
|
@@ -252,6 +275,23 @@ class DataService {
|
|
|
252
275
|
this.notifyListeners('conversation_state_change', data);
|
|
253
276
|
}
|
|
254
277
|
|
|
278
|
+
/**
|
|
279
|
+
* Handle real-time new message
|
|
280
|
+
* @param {Object} data - New message data
|
|
281
|
+
*/
|
|
282
|
+
handleNewMessage(data) {
|
|
283
|
+
|
|
284
|
+
// Clear relevant cache entries for the affected conversation
|
|
285
|
+
this.clearCacheEntry(`/api/conversations/${data.conversationId}/messages`);
|
|
286
|
+
|
|
287
|
+
// Notify listeners about the new message
|
|
288
|
+
this.notifyListeners('new_message', {
|
|
289
|
+
conversationId: data.conversationId,
|
|
290
|
+
message: data.message,
|
|
291
|
+
metadata: data.metadata
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
255
295
|
/**
|
|
256
296
|
* Start periodic data refresh (fallback when WebSocket unavailable)
|
|
257
297
|
* @param {number} interval - Refresh interval in milliseconds
|
|
@@ -259,7 +299,6 @@ class DataService {
|
|
|
259
299
|
startPeriodicRefresh(interval = 30000) {
|
|
260
300
|
// Don't start polling if real-time is enabled
|
|
261
301
|
if (this.realTimeEnabled) {
|
|
262
|
-
console.log('⚡ Real-time updates enabled - skipping periodic refresh');
|
|
263
302
|
return;
|
|
264
303
|
}
|
|
265
304
|
|
|
@@ -267,7 +306,6 @@ class DataService {
|
|
|
267
306
|
clearInterval(this.refreshInterval);
|
|
268
307
|
}
|
|
269
308
|
|
|
270
|
-
console.log('📅 Starting periodic refresh (fallback mode)');
|
|
271
309
|
this.refreshInterval = setInterval(async () => {
|
|
272
310
|
try {
|
|
273
311
|
// Only refresh if real-time is not available
|
|
@@ -292,8 +330,16 @@ class DataService {
|
|
|
292
330
|
*/
|
|
293
331
|
startFallbackPolling() {
|
|
294
332
|
if (!this.refreshInterval) {
|
|
295
|
-
|
|
296
|
-
|
|
333
|
+
this.startPeriodicRefresh(5000); // Very frequent polling as fallback (5 seconds)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Stop fallback polling when WebSocket reconnects
|
|
339
|
+
*/
|
|
340
|
+
stopFallbackPolling() {
|
|
341
|
+
if (this.refreshInterval) {
|
|
342
|
+
this.stopPeriodicRefresh();
|
|
297
343
|
}
|
|
298
344
|
}
|
|
299
345
|
|
|
@@ -312,7 +358,6 @@ class DataService {
|
|
|
312
358
|
*/
|
|
313
359
|
async requestRefresh() {
|
|
314
360
|
if (this.webSocketService && this.realTimeEnabled) {
|
|
315
|
-
console.log('🔄 Requesting refresh via WebSocket');
|
|
316
361
|
try {
|
|
317
362
|
await this.webSocketService.requestRefresh();
|
|
318
363
|
return true;
|
|
@@ -322,11 +367,39 @@ class DataService {
|
|
|
322
367
|
}
|
|
323
368
|
|
|
324
369
|
// Fallback to cache clearing
|
|
325
|
-
console.log('🔄 Falling back to cache clear for refresh');
|
|
326
370
|
this.clearCache();
|
|
327
371
|
return false;
|
|
328
372
|
}
|
|
329
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Clear server-side cache via API
|
|
376
|
+
* @param {string} type - Cache type to clear ('all', 'conversations', or undefined for all)
|
|
377
|
+
* @returns {Promise<boolean>} Success status
|
|
378
|
+
*/
|
|
379
|
+
async clearServerCache(type = 'all') {
|
|
380
|
+
try {
|
|
381
|
+
const response = await fetch('/api/cache/clear', {
|
|
382
|
+
method: 'POST',
|
|
383
|
+
headers: {
|
|
384
|
+
'Content-Type': 'application/json'
|
|
385
|
+
},
|
|
386
|
+
body: JSON.stringify({ type })
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
if (response.ok) {
|
|
390
|
+
const result = await response.json();
|
|
391
|
+
|
|
392
|
+
// Also clear local cache
|
|
393
|
+
this.clearCache();
|
|
394
|
+
return true;
|
|
395
|
+
} else {
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
} catch (error) {
|
|
399
|
+
return false;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
330
403
|
/**
|
|
331
404
|
* Set WebSocket service (for late initialization)
|
|
332
405
|
* @param {WebSocketService} webSocketService - WebSocket service instance
|
|
@@ -113,6 +113,15 @@ class StateService {
|
|
|
113
113
|
}
|
|
114
114
|
});
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Notify listeners with specific action and data (alias for real-time events)
|
|
119
|
+
* @param {string} action - Action type
|
|
120
|
+
* @param {Object} data - Event data
|
|
121
|
+
*/
|
|
122
|
+
notifyListeners(action, data) {
|
|
123
|
+
this.notifySubscribers(action, data);
|
|
124
|
+
}
|
|
116
125
|
|
|
117
126
|
/**
|
|
118
127
|
* Update conversations data
|
|
@@ -8,7 +8,7 @@ class WebSocketService {
|
|
|
8
8
|
this.url = null;
|
|
9
9
|
this.isConnected = false;
|
|
10
10
|
this.reconnectAttempts = 0;
|
|
11
|
-
this.maxReconnectAttempts = 5;
|
|
11
|
+
this.maxReconnectAttempts = 5; // Increase attempts for better reliability
|
|
12
12
|
this.reconnectDelay = 1000;
|
|
13
13
|
this.maxReconnectDelay = 30000;
|
|
14
14
|
this.heartbeatInterval = null;
|
|
@@ -17,7 +17,7 @@ class WebSocketService {
|
|
|
17
17
|
this.eventListeners = new Map();
|
|
18
18
|
this.subscriptions = new Set();
|
|
19
19
|
this.messageQueue = [];
|
|
20
|
-
this.autoReconnect = true;
|
|
20
|
+
this.autoReconnect = true; // Enable auto-reconnect for real-time updates
|
|
21
21
|
|
|
22
22
|
// Message ID tracking for responses
|
|
23
23
|
this.messageId = 0;
|
|
@@ -64,7 +64,7 @@ class WebSocketService {
|
|
|
64
64
|
this.ws.onerror = (event) => {
|
|
65
65
|
this.handleError(event);
|
|
66
66
|
if (!this.isConnected) {
|
|
67
|
-
reject(new Error(
|
|
67
|
+
reject(new Error(`WebSocket connection failed to ${this.url}`));
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
|
|
@@ -120,6 +120,9 @@ class WebSocketService {
|
|
|
120
120
|
case 'data_refresh':
|
|
121
121
|
this.handleDataRefresh(data);
|
|
122
122
|
break;
|
|
123
|
+
case 'new_message':
|
|
124
|
+
this.handleNewMessage(data);
|
|
125
|
+
break;
|
|
123
126
|
case 'system_status':
|
|
124
127
|
this.handleSystemStatus(data);
|
|
125
128
|
break;
|
|
@@ -152,7 +155,7 @@ class WebSocketService {
|
|
|
152
155
|
* @param {CloseEvent} event - Close event
|
|
153
156
|
*/
|
|
154
157
|
handleClose(event) {
|
|
155
|
-
console.
|
|
158
|
+
console.info('ℹ️ WebSocket disconnected (polling mode active)');
|
|
156
159
|
this.isConnected = false;
|
|
157
160
|
this.stopHeartbeat();
|
|
158
161
|
|
|
@@ -170,7 +173,7 @@ class WebSocketService {
|
|
|
170
173
|
* @param {Event} event - Error event
|
|
171
174
|
*/
|
|
172
175
|
handleError(event) {
|
|
173
|
-
console.
|
|
176
|
+
console.warn('⚠️ WebSocket connection failed (using polling mode instead)');
|
|
174
177
|
this.emit('error', { event });
|
|
175
178
|
}
|
|
176
179
|
|
|
@@ -202,6 +205,15 @@ class WebSocketService {
|
|
|
202
205
|
this.emit('data_refresh', data.data);
|
|
203
206
|
}
|
|
204
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Handle new message
|
|
210
|
+
* @param {Object} data - Message data
|
|
211
|
+
*/
|
|
212
|
+
handleNewMessage(data) {
|
|
213
|
+
console.log(`📨 New message received for conversation: ${data.data.conversationId}`);
|
|
214
|
+
this.emit('new_message', data.data);
|
|
215
|
+
}
|
|
216
|
+
|
|
205
217
|
/**
|
|
206
218
|
* Handle system status
|
|
207
219
|
* @param {Object} data - Message data
|