claudia-orchestrator 0.1.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/LICENSE +201 -0
- package/README.md +109 -0
- package/dist/cli-parser.d.ts +11 -0
- package/dist/cli-parser.d.ts.map +1 -0
- package/dist/cli-parser.js +57 -0
- package/dist/cli-parser.js.map +1 -0
- package/dist/cui-server.d.ts +69 -0
- package/dist/cui-server.d.ts.map +1 -0
- package/dist/cui-server.js +705 -0
- package/dist/cui-server.js.map +1 -0
- package/dist/mcp-server/claudia-tools.d.ts +15 -0
- package/dist/mcp-server/claudia-tools.d.ts.map +1 -0
- package/dist/mcp-server/claudia-tools.js +366 -0
- package/dist/mcp-server/claudia-tools.js.map +1 -0
- package/dist/mcp-server/index.d.ts +3 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +176 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +18 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +136 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/cors-setup.d.ts +7 -0
- package/dist/middleware/cors-setup.d.ts.map +1 -0
- package/dist/middleware/cors-setup.js +8 -0
- package/dist/middleware/cors-setup.js.map +1 -0
- package/dist/middleware/error-handler.d.ts +4 -0
- package/dist/middleware/error-handler.d.ts.map +1 -0
- package/dist/middleware/error-handler.js +27 -0
- package/dist/middleware/error-handler.js.map +1 -0
- package/dist/middleware/query-parser.d.ts +11 -0
- package/dist/middleware/query-parser.d.ts.map +1 -0
- package/dist/middleware/query-parser.js +68 -0
- package/dist/middleware/query-parser.js.map +1 -0
- package/dist/middleware/request-logger.d.ts +4 -0
- package/dist/middleware/request-logger.d.ts.map +1 -0
- package/dist/middleware/request-logger.js +29 -0
- package/dist/middleware/request-logger.js.map +1 -0
- package/dist/process-daemon/index.d.ts +14 -0
- package/dist/process-daemon/index.d.ts.map +1 -0
- package/dist/process-daemon/index.js +51 -0
- package/dist/process-daemon/index.js.map +1 -0
- package/dist/process-daemon/process-daemon.d.ts +78 -0
- package/dist/process-daemon/process-daemon.d.ts.map +1 -0
- package/dist/process-daemon/process-daemon.js +568 -0
- package/dist/process-daemon/process-daemon.js.map +1 -0
- package/dist/process-daemon/process-manager-client.d.ts +108 -0
- package/dist/process-daemon/process-manager-client.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-client.js +314 -0
- package/dist/process-daemon/process-manager-client.js.map +1 -0
- package/dist/process-daemon/process-manager-interface.d.ts +47 -0
- package/dist/process-daemon/process-manager-interface.d.ts.map +1 -0
- package/dist/process-daemon/process-manager-interface.js +8 -0
- package/dist/process-daemon/process-manager-interface.js.map +1 -0
- package/dist/process-daemon/test-daemon.d.ts +12 -0
- package/dist/process-daemon/test-daemon.d.ts.map +1 -0
- package/dist/process-daemon/test-daemon.js +81 -0
- package/dist/process-daemon/test-daemon.js.map +1 -0
- package/dist/process-daemon/types.d.ts +85 -0
- package/dist/process-daemon/types.d.ts.map +1 -0
- package/dist/process-daemon/types.js +8 -0
- package/dist/process-daemon/types.js.map +1 -0
- package/dist/routes/claudia.routes.d.ts +10 -0
- package/dist/routes/claudia.routes.d.ts.map +1 -0
- package/dist/routes/claudia.routes.js +123 -0
- package/dist/routes/claudia.routes.js.map +1 -0
- package/dist/routes/config.routes.d.ts +4 -0
- package/dist/routes/config.routes.d.ts.map +1 -0
- package/dist/routes/config.routes.js +27 -0
- package/dist/routes/config.routes.js.map +1 -0
- package/dist/routes/conversation.routes.d.ts +8 -0
- package/dist/routes/conversation.routes.d.ts.map +1 -0
- package/dist/routes/conversation.routes.js +870 -0
- package/dist/routes/conversation.routes.js.map +1 -0
- package/dist/routes/filesystem.routes.d.ts +4 -0
- package/dist/routes/filesystem.routes.d.ts.map +1 -0
- package/dist/routes/filesystem.routes.js +86 -0
- package/dist/routes/filesystem.routes.js.map +1 -0
- package/dist/routes/gemini.routes.d.ts +4 -0
- package/dist/routes/gemini.routes.d.ts.map +1 -0
- package/dist/routes/gemini.routes.js +93 -0
- package/dist/routes/gemini.routes.js.map +1 -0
- package/dist/routes/insights.routes.d.ts +17 -0
- package/dist/routes/insights.routes.d.ts.map +1 -0
- package/dist/routes/insights.routes.js +417 -0
- package/dist/routes/insights.routes.js.map +1 -0
- package/dist/routes/license.routes.d.ts +3 -0
- package/dist/routes/license.routes.d.ts.map +1 -0
- package/dist/routes/license.routes.js +111 -0
- package/dist/routes/license.routes.js.map +1 -0
- package/dist/routes/log.routes.d.ts +3 -0
- package/dist/routes/log.routes.d.ts.map +1 -0
- package/dist/routes/log.routes.js +65 -0
- package/dist/routes/log.routes.js.map +1 -0
- package/dist/routes/notifications.routes.d.ts +4 -0
- package/dist/routes/notifications.routes.d.ts.map +1 -0
- package/dist/routes/notifications.routes.js +71 -0
- package/dist/routes/notifications.routes.js.map +1 -0
- package/dist/routes/permission.routes.d.ts +4 -0
- package/dist/routes/permission.routes.d.ts.map +1 -0
- package/dist/routes/permission.routes.js +116 -0
- package/dist/routes/permission.routes.js.map +1 -0
- package/dist/routes/question.routes.d.ts +8 -0
- package/dist/routes/question.routes.d.ts.map +1 -0
- package/dist/routes/question.routes.js +82 -0
- package/dist/routes/question.routes.js.map +1 -0
- package/dist/routes/streaming.routes.d.ts +4 -0
- package/dist/routes/streaming.routes.d.ts.map +1 -0
- package/dist/routes/streaming.routes.js +28 -0
- package/dist/routes/streaming.routes.js.map +1 -0
- package/dist/routes/system.routes.d.ts +5 -0
- package/dist/routes/system.routes.d.ts.map +1 -0
- package/dist/routes/system.routes.js +103 -0
- package/dist/routes/system.routes.js.map +1 -0
- package/dist/routes/working-directories.routes.d.ts +4 -0
- package/dist/routes/working-directories.routes.d.ts.map +1 -0
- package/dist/routes/working-directories.routes.js +25 -0
- package/dist/routes/working-directories.routes.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +34 -0
- package/dist/server.js.map +1 -0
- package/dist/services/ToolMetricsService.d.ts +53 -0
- package/dist/services/ToolMetricsService.d.ts.map +1 -0
- package/dist/services/ToolMetricsService.js +230 -0
- package/dist/services/ToolMetricsService.js.map +1 -0
- package/dist/services/anthropic-service.d.ts +186 -0
- package/dist/services/anthropic-service.d.ts.map +1 -0
- package/dist/services/anthropic-service.js +1132 -0
- package/dist/services/anthropic-service.js.map +1 -0
- package/dist/services/claude-history-reader.d.ts +126 -0
- package/dist/services/claude-history-reader.d.ts.map +1 -0
- package/dist/services/claude-history-reader.js +717 -0
- package/dist/services/claude-history-reader.js.map +1 -0
- package/dist/services/claude-process-manager.d.ts +108 -0
- package/dist/services/claude-process-manager.d.ts.map +1 -0
- package/dist/services/claude-process-manager.js +909 -0
- package/dist/services/claude-process-manager.js.map +1 -0
- package/dist/services/claude-router-service.d.ts +19 -0
- package/dist/services/claude-router-service.d.ts.map +1 -0
- package/dist/services/claude-router-service.js +160 -0
- package/dist/services/claude-router-service.js.map +1 -0
- package/dist/services/claudia-service.d.ts +77 -0
- package/dist/services/claudia-service.d.ts.map +1 -0
- package/dist/services/claudia-service.js +194 -0
- package/dist/services/claudia-service.js.map +1 -0
- package/dist/services/commands-service.d.ts +18 -0
- package/dist/services/commands-service.d.ts.map +1 -0
- package/dist/services/commands-service.js +76 -0
- package/dist/services/commands-service.js.map +1 -0
- package/dist/services/config-service.d.ts +68 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +429 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/services/conversation-cache.d.ts +86 -0
- package/dist/services/conversation-cache.d.ts.map +1 -0
- package/dist/services/conversation-cache.js +235 -0
- package/dist/services/conversation-cache.js.map +1 -0
- package/dist/services/conversation-status-manager.d.ts +98 -0
- package/dist/services/conversation-status-manager.d.ts.map +1 -0
- package/dist/services/conversation-status-manager.js +295 -0
- package/dist/services/conversation-status-manager.js.map +1 -0
- package/dist/services/cost-tracker.d.ts +87 -0
- package/dist/services/cost-tracker.d.ts.map +1 -0
- package/dist/services/cost-tracker.js +335 -0
- package/dist/services/cost-tracker.js.map +1 -0
- package/dist/services/file-system-service.d.ts +61 -0
- package/dist/services/file-system-service.d.ts.map +1 -0
- package/dist/services/file-system-service.js +348 -0
- package/dist/services/file-system-service.js.map +1 -0
- package/dist/services/gemini-service.d.ts +72 -0
- package/dist/services/gemini-service.d.ts.map +1 -0
- package/dist/services/gemini-service.js +431 -0
- package/dist/services/gemini-service.js.map +1 -0
- package/dist/services/insight-queue.d.ts +99 -0
- package/dist/services/insight-queue.d.ts.map +1 -0
- package/dist/services/insight-queue.js +277 -0
- package/dist/services/insight-queue.js.map +1 -0
- package/dist/services/insights-service.d.ts +102 -0
- package/dist/services/insights-service.d.ts.map +1 -0
- package/dist/services/insights-service.js +1152 -0
- package/dist/services/insights-service.js.map +1 -0
- package/dist/services/json-lines-parser.d.ts +19 -0
- package/dist/services/json-lines-parser.d.ts.map +1 -0
- package/dist/services/json-lines-parser.js +56 -0
- package/dist/services/json-lines-parser.js.map +1 -0
- package/dist/services/license-service.d.ts +69 -0
- package/dist/services/license-service.d.ts.map +1 -0
- package/dist/services/license-service.js +330 -0
- package/dist/services/license-service.js.map +1 -0
- package/dist/services/log-formatter.d.ts +5 -0
- package/dist/services/log-formatter.d.ts.map +1 -0
- package/dist/services/log-formatter.js +77 -0
- package/dist/services/log-formatter.js.map +1 -0
- package/dist/services/log-stream-buffer.d.ts +11 -0
- package/dist/services/log-stream-buffer.d.ts.map +1 -0
- package/dist/services/log-stream-buffer.js +36 -0
- package/dist/services/log-stream-buffer.js.map +1 -0
- package/dist/services/logger.d.ts +71 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +215 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/mcp-config-generator.d.ts +32 -0
- package/dist/services/mcp-config-generator.d.ts.map +1 -0
- package/dist/services/mcp-config-generator.js +126 -0
- package/dist/services/mcp-config-generator.js.map +1 -0
- package/dist/services/message-filter.d.ts +22 -0
- package/dist/services/message-filter.d.ts.map +1 -0
- package/dist/services/message-filter.js +57 -0
- package/dist/services/message-filter.js.map +1 -0
- package/dist/services/notification-service.d.ts +45 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +184 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/permission-tracker.d.ts +67 -0
- package/dist/services/permission-tracker.d.ts.map +1 -0
- package/dist/services/permission-tracker.js +161 -0
- package/dist/services/permission-tracker.js.map +1 -0
- package/dist/services/process-manager-factory.d.ts +81 -0
- package/dist/services/process-manager-factory.d.ts.map +1 -0
- package/dist/services/process-manager-factory.js +211 -0
- package/dist/services/process-manager-factory.js.map +1 -0
- package/dist/services/question-tracker.d.ts +47 -0
- package/dist/services/question-tracker.d.ts.map +1 -0
- package/dist/services/question-tracker.js +105 -0
- package/dist/services/question-tracker.js.map +1 -0
- package/dist/services/session-activity-watcher.d.ts +33 -0
- package/dist/services/session-activity-watcher.d.ts.map +1 -0
- package/dist/services/session-activity-watcher.js +194 -0
- package/dist/services/session-activity-watcher.js.map +1 -0
- package/dist/services/session-info-service.d.ts +228 -0
- package/dist/services/session-info-service.d.ts.map +1 -0
- package/dist/services/session-info-service.js +920 -0
- package/dist/services/session-info-service.js.map +1 -0
- package/dist/services/session-insights-service.d.ts +119 -0
- package/dist/services/session-insights-service.d.ts.map +1 -0
- package/dist/services/session-insights-service.js +889 -0
- package/dist/services/session-insights-service.js.map +1 -0
- package/dist/services/stream-manager.d.ts +62 -0
- package/dist/services/stream-manager.d.ts.map +1 -0
- package/dist/services/stream-manager.js +239 -0
- package/dist/services/stream-manager.js.map +1 -0
- package/dist/services/web-push-service.d.ts +48 -0
- package/dist/services/web-push-service.d.ts.map +1 -0
- package/dist/services/web-push-service.js +186 -0
- package/dist/services/web-push-service.js.map +1 -0
- package/dist/services/working-directories-service.d.ts +19 -0
- package/dist/services/working-directories-service.d.ts.map +1 -0
- package/dist/services/working-directories-service.js +103 -0
- package/dist/services/working-directories-service.js.map +1 -0
- package/dist/types/config.d.ts +111 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +14 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/express.d.ts +5 -0
- package/dist/types/express.d.ts.map +1 -0
- package/dist/types/express.js +2 -0
- package/dist/types/express.js.map +1 -0
- package/dist/types/index.d.ts +325 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +18 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/insights.d.ts +99 -0
- package/dist/types/insights.d.ts.map +1 -0
- package/dist/types/insights.js +7 -0
- package/dist/types/insights.js.map +1 -0
- package/dist/types/license.d.ts +70 -0
- package/dist/types/license.d.ts.map +1 -0
- package/dist/types/license.js +5 -0
- package/dist/types/license.js.map +1 -0
- package/dist/types/router-config.d.ts +13 -0
- package/dist/types/router-config.d.ts.map +1 -0
- package/dist/types/router-config.js +2 -0
- package/dist/types/router-config.js.map +1 -0
- package/dist/utils/constants.d.ts +26 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +28 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/machine-id.d.ts +7 -0
- package/dist/utils/machine-id.d.ts.map +1 -0
- package/dist/utils/machine-id.js +76 -0
- package/dist/utils/machine-id.js.map +1 -0
- package/dist/utils/server-startup.d.ts +13 -0
- package/dist/utils/server-startup.d.ts.map +1 -0
- package/dist/utils/server-startup.js +20 -0
- package/dist/utils/server-startup.js.map +1 -0
- package/dist/web/assets/main-DAc2rjJ2.css +1 -0
- package/dist/web/assets/main-DvlZ02mT.js +137 -0
- package/dist/web/favicon.png +0 -0
- package/dist/web/favicon.svg +22 -0
- package/dist/web/icon-192x192.png +0 -0
- package/dist/web/icon-512x512.png +0 -0
- package/dist/web/index.html +36 -0
- package/dist/web/manifest.json +61 -0
- package/package.json +174 -0
- package/scripts/postinstall.js +30 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Manager Factory
|
|
3
|
+
*
|
|
4
|
+
* Creates either a direct ClaudeProcessManager or a ProcessManagerClient
|
|
5
|
+
* depending on configuration. This allows cui-server to work with either mode.
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from 'events';
|
|
8
|
+
import { ClaudeProcessManager } from './claude-process-manager.js';
|
|
9
|
+
import { ProcessManagerClient } from '../process-daemon/process-manager-client.js';
|
|
10
|
+
import { DEFAULT_SOCKET_PATH } from '../process-daemon/types.js';
|
|
11
|
+
import { createLogger } from './logger.js';
|
|
12
|
+
const logger = createLogger('ProcessManagerFactory');
|
|
13
|
+
/**
|
|
14
|
+
* Unified process manager type - wraps either implementation
|
|
15
|
+
* and provides a consistent interface to cui-server.
|
|
16
|
+
*/
|
|
17
|
+
export class UnifiedProcessManager extends EventEmitter {
|
|
18
|
+
_direct = null;
|
|
19
|
+
_client = null;
|
|
20
|
+
_mode;
|
|
21
|
+
_activeSessions = new Set();
|
|
22
|
+
constructor(mode) {
|
|
23
|
+
super();
|
|
24
|
+
this._mode = mode;
|
|
25
|
+
}
|
|
26
|
+
get mode() {
|
|
27
|
+
return this._mode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize with direct process manager
|
|
31
|
+
*/
|
|
32
|
+
initDirect(manager) {
|
|
33
|
+
this._direct = manager;
|
|
34
|
+
// Forward events
|
|
35
|
+
manager.on('claude-message', (data) => {
|
|
36
|
+
this._activeSessions.add(data.streamingId);
|
|
37
|
+
this.emit('claude-message', data);
|
|
38
|
+
});
|
|
39
|
+
manager.on('process-closed', (data) => {
|
|
40
|
+
this._activeSessions.delete(data.streamingId);
|
|
41
|
+
this.emit('process-closed', data);
|
|
42
|
+
});
|
|
43
|
+
manager.on('process-error', (data) => this.emit('process-error', data));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Initialize with daemon client
|
|
47
|
+
*/
|
|
48
|
+
async initClient(client) {
|
|
49
|
+
this._client = client;
|
|
50
|
+
await client.connect();
|
|
51
|
+
// Forward events
|
|
52
|
+
client.on('claude-message', (data) => {
|
|
53
|
+
this._activeSessions.add(data.streamingId);
|
|
54
|
+
this.emit('claude-message', data);
|
|
55
|
+
});
|
|
56
|
+
client.on('process-closed', (data) => {
|
|
57
|
+
this._activeSessions.delete(data.streamingId);
|
|
58
|
+
this.emit('process-closed', data);
|
|
59
|
+
});
|
|
60
|
+
client.on('process-error', (data) => this.emit('process-error', data));
|
|
61
|
+
// Sync initial active sessions from daemon
|
|
62
|
+
try {
|
|
63
|
+
const sessions = await client.getActiveSessions();
|
|
64
|
+
for (const s of sessions) {
|
|
65
|
+
this._activeSessions.add(s);
|
|
66
|
+
}
|
|
67
|
+
logger.info('Synced active sessions from daemon', { count: sessions.length });
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
logger.warn('Failed to sync active sessions from daemon', { error });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Unified Interface - matches ClaudeProcessManager signature
|
|
75
|
+
// ============================================================================
|
|
76
|
+
async startConversation(config) {
|
|
77
|
+
if (this._direct) {
|
|
78
|
+
return this._direct.startConversation(config);
|
|
79
|
+
}
|
|
80
|
+
if (this._client) {
|
|
81
|
+
return this._client.startConversation(config);
|
|
82
|
+
}
|
|
83
|
+
throw new Error('Process manager not initialized');
|
|
84
|
+
}
|
|
85
|
+
async stopConversation(streamingId) {
|
|
86
|
+
if (this._direct) {
|
|
87
|
+
return this._direct.stopConversation(streamingId);
|
|
88
|
+
}
|
|
89
|
+
if (this._client) {
|
|
90
|
+
return this._client.stopConversation(streamingId);
|
|
91
|
+
}
|
|
92
|
+
throw new Error('Process manager not initialized');
|
|
93
|
+
}
|
|
94
|
+
forceKillConversation(streamingId) {
|
|
95
|
+
if (this._direct) {
|
|
96
|
+
return this._direct.forceKillConversation(streamingId);
|
|
97
|
+
}
|
|
98
|
+
if (this._client) {
|
|
99
|
+
return this._client.forceKillConversation(streamingId);
|
|
100
|
+
}
|
|
101
|
+
throw new Error('Process manager not initialized');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get active sessions - SYNCHRONOUS for backwards compatibility
|
|
105
|
+
* Uses local cache that's kept in sync via events
|
|
106
|
+
*/
|
|
107
|
+
getActiveSessions() {
|
|
108
|
+
return Array.from(this._activeSessions);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if session is active - SYNCHRONOUS for backwards compatibility
|
|
112
|
+
*/
|
|
113
|
+
isSessionActive(streamingId) {
|
|
114
|
+
return this._activeSessions.has(streamingId);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Send question answer
|
|
118
|
+
*/
|
|
119
|
+
sendQuestionAnswer(streamingId, answer) {
|
|
120
|
+
if (this._direct) {
|
|
121
|
+
return this._direct.sendQuestionAnswer(streamingId, answer);
|
|
122
|
+
}
|
|
123
|
+
if (this._client) {
|
|
124
|
+
// Fire and forget for sync interface
|
|
125
|
+
this._client.sendQuestionAnswer(streamingId, answer).catch((err) => {
|
|
126
|
+
logger.error('Failed to send question answer', err);
|
|
127
|
+
});
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Send stdin message
|
|
134
|
+
*/
|
|
135
|
+
sendStdinMessage(streamingId, message) {
|
|
136
|
+
if (this._direct) {
|
|
137
|
+
return this._direct.sendStdinMessage(streamingId, message);
|
|
138
|
+
}
|
|
139
|
+
if (this._client) {
|
|
140
|
+
// Fire and forget for sync interface
|
|
141
|
+
this._client.sendStdinMessage(streamingId, message).catch((err) => {
|
|
142
|
+
logger.error('Failed to send stdin message', err);
|
|
143
|
+
});
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
// ============================================================================
|
|
149
|
+
// Configuration Methods (delegated or no-op)
|
|
150
|
+
// ============================================================================
|
|
151
|
+
setMCPConfigPath(path) {
|
|
152
|
+
if (this._direct) {
|
|
153
|
+
this._direct.setMCPConfigPath(path);
|
|
154
|
+
}
|
|
155
|
+
// No-op in client mode - daemon handles this
|
|
156
|
+
}
|
|
157
|
+
setConversationStatusManager(service) {
|
|
158
|
+
if (this._direct) {
|
|
159
|
+
this._direct.setConversationStatusManager(service);
|
|
160
|
+
}
|
|
161
|
+
// No-op in client mode
|
|
162
|
+
}
|
|
163
|
+
setNotificationService(service) {
|
|
164
|
+
if (this._direct) {
|
|
165
|
+
this._direct.setNotificationService(service);
|
|
166
|
+
}
|
|
167
|
+
// No-op in client mode
|
|
168
|
+
}
|
|
169
|
+
setRouterService(service) {
|
|
170
|
+
if (this._direct) {
|
|
171
|
+
this._direct.setRouterService(service);
|
|
172
|
+
}
|
|
173
|
+
// No-op in client mode
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Disconnect from daemon (daemon mode) or cleanup (direct mode)
|
|
177
|
+
* Must be called during server shutdown to prevent reconnection loops
|
|
178
|
+
*/
|
|
179
|
+
disconnect() {
|
|
180
|
+
if (this._client) {
|
|
181
|
+
logger.info('Disconnecting from process daemon');
|
|
182
|
+
this._client.disconnect();
|
|
183
|
+
}
|
|
184
|
+
// Direct mode: nothing to disconnect, processes are managed directly
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Create a process manager based on configuration
|
|
189
|
+
*/
|
|
190
|
+
export async function createProcessManager(options) {
|
|
191
|
+
// Always use daemon mode - the daemon runs independently and survives server restarts
|
|
192
|
+
const mode = options.mode || 'daemon';
|
|
193
|
+
const socketPath = options.daemonSocketPath || process.env.CUI_DAEMON_SOCKET || DEFAULT_SOCKET_PATH;
|
|
194
|
+
logger.info('Creating process manager', { mode, socketPath: mode === 'daemon' ? socketPath : undefined });
|
|
195
|
+
const unified = new UnifiedProcessManager(mode);
|
|
196
|
+
if (mode === 'daemon') {
|
|
197
|
+
const client = new ProcessManagerClient(socketPath);
|
|
198
|
+
await unified.initClient(client);
|
|
199
|
+
logger.info('Process manager initialized in daemon mode');
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
if (!options.historyReader || !options.statusTracker) {
|
|
203
|
+
throw new Error('Direct mode requires historyReader and statusTracker');
|
|
204
|
+
}
|
|
205
|
+
const direct = new ClaudeProcessManager(options.historyReader, options.statusTracker, undefined, undefined, options.toolMetricsService, options.sessionInfoService, options.fileSystemService);
|
|
206
|
+
unified.initDirect(direct);
|
|
207
|
+
logger.info('Process manager initialized in direct mode');
|
|
208
|
+
}
|
|
209
|
+
return unified;
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=process-manager-factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-manager-factory.js","sourceRoot":"","sources":["../../src/services/process-manager-factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { QuestionRequest, QuestionDefinition } from '../types/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Service to track AskUserQuestion requests from Claude CLI.
|
|
5
|
+
* Unlike permissions (which use MCP polling), questions are answered via stdin.
|
|
6
|
+
*/
|
|
7
|
+
export declare class QuestionTracker extends EventEmitter {
|
|
8
|
+
private questionRequests;
|
|
9
|
+
constructor();
|
|
10
|
+
/**
|
|
11
|
+
* Add a new question request from AskUserQuestion tool
|
|
12
|
+
*/
|
|
13
|
+
addQuestionRequest(toolUseId: string, questions: QuestionDefinition[], streamingId: string): QuestionRequest;
|
|
14
|
+
/**
|
|
15
|
+
* Get all question requests
|
|
16
|
+
*/
|
|
17
|
+
getAllQuestionRequests(): QuestionRequest[];
|
|
18
|
+
/**
|
|
19
|
+
* Get question requests filtered by criteria
|
|
20
|
+
*/
|
|
21
|
+
getQuestionRequests(filter?: {
|
|
22
|
+
streamingId?: string;
|
|
23
|
+
status?: 'pending' | 'answered';
|
|
24
|
+
}): QuestionRequest[];
|
|
25
|
+
/**
|
|
26
|
+
* Get a specific question request by ID
|
|
27
|
+
*/
|
|
28
|
+
getQuestionRequest(id: string): QuestionRequest | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Mark a question as answered
|
|
31
|
+
*/
|
|
32
|
+
markAnswered(id: string, answers: Record<string, string>): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Clear all question requests (for testing)
|
|
35
|
+
*/
|
|
36
|
+
clear(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get the number of question requests
|
|
39
|
+
*/
|
|
40
|
+
size(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Remove all questions for a specific streaming ID
|
|
43
|
+
* Used for cleanup when a conversation ends
|
|
44
|
+
*/
|
|
45
|
+
removeQuestionsByStreamingId(streamingId: string): number;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=question-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-tracker.d.ts","sourceRoot":"","sources":["../../src/services/question-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGvE;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,gBAAgB,CAA2C;;IAMnE;;OAEG;IACH,kBAAkB,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,kBAAkB,EAAE,EAC/B,WAAW,EAAE,MAAM,GAClB,eAAe;IAoBlB;;OAEG;IACH,sBAAsB,IAAI,eAAe,EAAE;IAI3C;;OAEG;IACH,mBAAmB,CAAC,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,CAAA;KAAE,GAAG,eAAe,EAAE;IAc1G;;OAEG;IACH,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI3D;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO;IAgBlE;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;;OAGG;IACH,4BAA4B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;CAoB1D"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
3
|
+
import { logger } from '../services/logger.js';
|
|
4
|
+
/**
|
|
5
|
+
* Service to track AskUserQuestion requests from Claude CLI.
|
|
6
|
+
* Unlike permissions (which use MCP polling), questions are answered via stdin.
|
|
7
|
+
*/
|
|
8
|
+
export class QuestionTracker extends EventEmitter {
|
|
9
|
+
questionRequests = new Map();
|
|
10
|
+
constructor() {
|
|
11
|
+
super();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Add a new question request from AskUserQuestion tool
|
|
15
|
+
*/
|
|
16
|
+
addQuestionRequest(toolUseId, questions, streamingId) {
|
|
17
|
+
const id = uuidv4();
|
|
18
|
+
const request = {
|
|
19
|
+
id,
|
|
20
|
+
streamingId,
|
|
21
|
+
toolUseId,
|
|
22
|
+
questions,
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
status: 'pending',
|
|
25
|
+
};
|
|
26
|
+
this.questionRequests.set(id, request);
|
|
27
|
+
logger.info('Question request added', { id, toolUseId, streamingId, questionCount: questions.length });
|
|
28
|
+
// Emit event for new question request
|
|
29
|
+
this.emit('question_request', request);
|
|
30
|
+
return request;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get all question requests
|
|
34
|
+
*/
|
|
35
|
+
getAllQuestionRequests() {
|
|
36
|
+
return Array.from(this.questionRequests.values());
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get question requests filtered by criteria
|
|
40
|
+
*/
|
|
41
|
+
getQuestionRequests(filter) {
|
|
42
|
+
let requests = Array.from(this.questionRequests.values());
|
|
43
|
+
if (filter?.streamingId) {
|
|
44
|
+
requests = requests.filter(req => req.streamingId === filter.streamingId);
|
|
45
|
+
}
|
|
46
|
+
if (filter?.status) {
|
|
47
|
+
requests = requests.filter(req => req.status === filter.status);
|
|
48
|
+
}
|
|
49
|
+
return requests;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get a specific question request by ID
|
|
53
|
+
*/
|
|
54
|
+
getQuestionRequest(id) {
|
|
55
|
+
return this.questionRequests.get(id);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Mark a question as answered
|
|
59
|
+
*/
|
|
60
|
+
markAnswered(id, answers) {
|
|
61
|
+
const request = this.questionRequests.get(id);
|
|
62
|
+
if (!request) {
|
|
63
|
+
logger.warn('Question request not found', { id });
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
request.status = 'answered';
|
|
67
|
+
request.answers = answers;
|
|
68
|
+
logger.info('Question request answered', { id, answers });
|
|
69
|
+
this.emit('question_answered', request);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Clear all question requests (for testing)
|
|
74
|
+
*/
|
|
75
|
+
clear() {
|
|
76
|
+
this.questionRequests.clear();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get the number of question requests
|
|
80
|
+
*/
|
|
81
|
+
size() {
|
|
82
|
+
return this.questionRequests.size;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove all questions for a specific streaming ID
|
|
86
|
+
* Used for cleanup when a conversation ends
|
|
87
|
+
*/
|
|
88
|
+
removeQuestionsByStreamingId(streamingId) {
|
|
89
|
+
const toRemove = [];
|
|
90
|
+
for (const [id, request] of this.questionRequests.entries()) {
|
|
91
|
+
if (request.streamingId === streamingId) {
|
|
92
|
+
toRemove.push(id);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
toRemove.forEach(id => this.questionRequests.delete(id));
|
|
96
|
+
if (toRemove.length > 0) {
|
|
97
|
+
logger.info('Removed questions for streaming session', {
|
|
98
|
+
streamingId,
|
|
99
|
+
removedCount: toRemove.length
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return toRemove.length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=question-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question-tracker.js","sourceRoot":"","sources":["../../src/services/question-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
/**
|
|
3
|
+
* Watches Claude session JSONL files for changes and emits activity updates
|
|
4
|
+
*/
|
|
5
|
+
export declare class SessionActivityWatcher extends EventEmitter {
|
|
6
|
+
private logger;
|
|
7
|
+
private insightsService;
|
|
8
|
+
private historyReader;
|
|
9
|
+
private watchers;
|
|
10
|
+
private debounceTimers;
|
|
11
|
+
private projectsDir;
|
|
12
|
+
private isWatching;
|
|
13
|
+
private readonly DEBOUNCE_MS;
|
|
14
|
+
constructor();
|
|
15
|
+
/**
|
|
16
|
+
* Start watching for session file changes
|
|
17
|
+
*/
|
|
18
|
+
start(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Emit an insights update event (called by InsightsEventHandler)
|
|
21
|
+
*/
|
|
22
|
+
emitInsightsUpdate(sessionId: string, type: 'generated' | 'patched'): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Stop watching
|
|
25
|
+
*/
|
|
26
|
+
stop(): void;
|
|
27
|
+
private watchDirectory;
|
|
28
|
+
private watchProjectDirectory;
|
|
29
|
+
private handleFileChange;
|
|
30
|
+
private extractAndEmit;
|
|
31
|
+
}
|
|
32
|
+
export declare function getSessionActivityWatcher(): SessionActivityWatcher;
|
|
33
|
+
//# sourceMappingURL=session-activity-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-activity-watcher.d.ts","sourceRoot":"","sources":["../../src/services/session-activity-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AA0BtC;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,YAAY;IACtD,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,eAAe,CAAyB;IAChD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAO;;IASnC;;OAEG;IACH,KAAK,IAAI,IAAI;IA6Bb;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BzF;;OAEG;IACH,IAAI,IAAI,IAAI;IAgBZ,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,gBAAgB;YAqBV,cAAc;CAgC7B;AAKD,wBAAgB,yBAAyB,IAAI,sBAAsB,CAKlE"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import { createLogger } from './logger.js';
|
|
6
|
+
import { SessionInsightsService } from './session-insights-service.js';
|
|
7
|
+
import { ClaudeHistoryReader } from './claude-history-reader.js';
|
|
8
|
+
/**
|
|
9
|
+
* Watches Claude session JSONL files for changes and emits activity updates
|
|
10
|
+
*/
|
|
11
|
+
export class SessionActivityWatcher extends EventEmitter {
|
|
12
|
+
logger = createLogger('SessionActivityWatcher');
|
|
13
|
+
insightsService;
|
|
14
|
+
historyReader;
|
|
15
|
+
watchers = new Map();
|
|
16
|
+
debounceTimers = new Map();
|
|
17
|
+
projectsDir;
|
|
18
|
+
isWatching = false;
|
|
19
|
+
// Debounce file changes to avoid rapid-fire updates
|
|
20
|
+
DEBOUNCE_MS = 100;
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.historyReader = new ClaudeHistoryReader();
|
|
24
|
+
this.insightsService = new SessionInsightsService(this.historyReader);
|
|
25
|
+
this.projectsDir = path.join(os.homedir(), '.claude', 'projects');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start watching for session file changes
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
if (this.isWatching)
|
|
32
|
+
return;
|
|
33
|
+
this.logger.info('Starting session activity watcher', { projectsDir: this.projectsDir });
|
|
34
|
+
try {
|
|
35
|
+
// Watch the projects directory for new project folders
|
|
36
|
+
this.watchDirectory(this.projectsDir);
|
|
37
|
+
// Watch existing project directories
|
|
38
|
+
if (fs.existsSync(this.projectsDir)) {
|
|
39
|
+
const projects = fs.readdirSync(this.projectsDir);
|
|
40
|
+
for (const project of projects) {
|
|
41
|
+
const projectPath = path.join(this.projectsDir, project);
|
|
42
|
+
if (fs.statSync(projectPath).isDirectory()) {
|
|
43
|
+
this.watchProjectDirectory(projectPath);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
this.isWatching = true;
|
|
48
|
+
this.logger.info('Session activity watcher started', {
|
|
49
|
+
watcherCount: this.watchers.size
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
this.logger.error('Failed to start session activity watcher', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Emit an insights update event (called by InsightsEventHandler)
|
|
58
|
+
*/
|
|
59
|
+
async emitInsightsUpdate(sessionId, type) {
|
|
60
|
+
// Try to fetch identity image to include in the update
|
|
61
|
+
let identityImage;
|
|
62
|
+
try {
|
|
63
|
+
const { SessionInfoService } = await import('./session-info-service.js');
|
|
64
|
+
const sessionInfoService = SessionInfoService.getInstance();
|
|
65
|
+
const sessionInfo = await sessionInfoService.getSessionInfo(sessionId);
|
|
66
|
+
identityImage = sessionInfo.identity_image ?? undefined;
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
// Identity image not available yet, that's okay
|
|
70
|
+
this.logger.debug('No identity image available for insights update', {
|
|
71
|
+
sessionId: sessionId.slice(0, 8)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const update = {
|
|
75
|
+
sessionId,
|
|
76
|
+
type,
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
identityImage
|
|
79
|
+
};
|
|
80
|
+
this.logger.debug('Emitting insights update', {
|
|
81
|
+
sessionId: sessionId.slice(0, 8),
|
|
82
|
+
type,
|
|
83
|
+
hasIdentityImage: !!identityImage
|
|
84
|
+
});
|
|
85
|
+
this.emit('insights', update);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Stop watching
|
|
89
|
+
*/
|
|
90
|
+
stop() {
|
|
91
|
+
this.logger.info('Stopping session activity watcher');
|
|
92
|
+
for (const [path, watcher] of this.watchers) {
|
|
93
|
+
watcher.close();
|
|
94
|
+
}
|
|
95
|
+
this.watchers.clear();
|
|
96
|
+
for (const timer of this.debounceTimers.values()) {
|
|
97
|
+
clearTimeout(timer);
|
|
98
|
+
}
|
|
99
|
+
this.debounceTimers.clear();
|
|
100
|
+
this.isWatching = false;
|
|
101
|
+
}
|
|
102
|
+
watchDirectory(dirPath) {
|
|
103
|
+
if (this.watchers.has(dirPath))
|
|
104
|
+
return;
|
|
105
|
+
try {
|
|
106
|
+
const watcher = fs.watch(dirPath, { persistent: false }, (eventType, filename) => {
|
|
107
|
+
if (!filename)
|
|
108
|
+
return;
|
|
109
|
+
const fullPath = path.join(dirPath, filename);
|
|
110
|
+
// Check if it's a new project directory
|
|
111
|
+
if (fs.existsSync(fullPath) && fs.statSync(fullPath).isDirectory()) {
|
|
112
|
+
this.watchProjectDirectory(fullPath);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
this.watchers.set(dirPath, watcher);
|
|
116
|
+
this.logger.debug('Watching directory', { dirPath });
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
this.logger.warn('Failed to watch directory', { dirPath, error });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
watchProjectDirectory(projectPath) {
|
|
123
|
+
if (this.watchers.has(projectPath))
|
|
124
|
+
return;
|
|
125
|
+
try {
|
|
126
|
+
const watcher = fs.watch(projectPath, { persistent: false }, (eventType, filename) => {
|
|
127
|
+
if (!filename || !filename.endsWith('.jsonl'))
|
|
128
|
+
return;
|
|
129
|
+
const filePath = path.join(projectPath, filename);
|
|
130
|
+
this.handleFileChange(filePath, filename);
|
|
131
|
+
});
|
|
132
|
+
this.watchers.set(projectPath, watcher);
|
|
133
|
+
this.logger.debug('Watching project directory', { projectPath });
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
this.logger.warn('Failed to watch project directory', { projectPath, error });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
handleFileChange(filePath, filename) {
|
|
140
|
+
// Extract session ID from filename (e.g., "abc123-def456.jsonl" -> "abc123-def456")
|
|
141
|
+
const sessionId = filename.replace('.jsonl', '');
|
|
142
|
+
this.logger.debug('File change detected', {
|
|
143
|
+
sessionId: sessionId.slice(0, 8),
|
|
144
|
+
filename
|
|
145
|
+
});
|
|
146
|
+
// Debounce rapid changes
|
|
147
|
+
const existingTimer = this.debounceTimers.get(sessionId);
|
|
148
|
+
if (existingTimer) {
|
|
149
|
+
clearTimeout(existingTimer);
|
|
150
|
+
}
|
|
151
|
+
this.debounceTimers.set(sessionId, setTimeout(async () => {
|
|
152
|
+
this.debounceTimers.delete(sessionId);
|
|
153
|
+
await this.extractAndEmit(sessionId, filePath);
|
|
154
|
+
}, this.DEBOUNCE_MS));
|
|
155
|
+
}
|
|
156
|
+
async extractAndEmit(sessionId, filePath) {
|
|
157
|
+
try {
|
|
158
|
+
const { messages } = await this.historyReader.fetchConversationDirect(sessionId);
|
|
159
|
+
const recentActions = this.insightsService.extractRecentActions(messages, 10);
|
|
160
|
+
// Only emit when we have something to show
|
|
161
|
+
if (recentActions.length === 0) {
|
|
162
|
+
this.logger.debug('Skipping empty activity update', {
|
|
163
|
+
sessionId: sessionId.slice(0, 8)
|
|
164
|
+
});
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
const update = {
|
|
168
|
+
sessionId,
|
|
169
|
+
recentActions,
|
|
170
|
+
timestamp: Date.now()
|
|
171
|
+
};
|
|
172
|
+
this.logger.debug('Emitting activity update', {
|
|
173
|
+
sessionId: sessionId.slice(0, 8),
|
|
174
|
+
actionCount: recentActions.length
|
|
175
|
+
});
|
|
176
|
+
this.emit('activity', update);
|
|
177
|
+
}
|
|
178
|
+
catch (error) {
|
|
179
|
+
this.logger.debug('Failed to extract activity', {
|
|
180
|
+
sessionId: sessionId.slice(0, 8),
|
|
181
|
+
error
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Singleton instance
|
|
187
|
+
let instance = null;
|
|
188
|
+
export function getSessionActivityWatcher() {
|
|
189
|
+
if (!instance) {
|
|
190
|
+
instance = new SessionActivityWatcher();
|
|
191
|
+
}
|
|
192
|
+
return instance;
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=session-activity-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-activity-watcher.js","sourceRoot":"","sources":["../../src/services/session-activity-watcher.ts"],"names":[],"mappings":"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"}
|