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.
Files changed (296) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +109 -0
  3. package/dist/cli-parser.d.ts +11 -0
  4. package/dist/cli-parser.d.ts.map +1 -0
  5. package/dist/cli-parser.js +57 -0
  6. package/dist/cli-parser.js.map +1 -0
  7. package/dist/cui-server.d.ts +69 -0
  8. package/dist/cui-server.d.ts.map +1 -0
  9. package/dist/cui-server.js +705 -0
  10. package/dist/cui-server.js.map +1 -0
  11. package/dist/mcp-server/claudia-tools.d.ts +15 -0
  12. package/dist/mcp-server/claudia-tools.d.ts.map +1 -0
  13. package/dist/mcp-server/claudia-tools.js +366 -0
  14. package/dist/mcp-server/claudia-tools.js.map +1 -0
  15. package/dist/mcp-server/index.d.ts +3 -0
  16. package/dist/mcp-server/index.d.ts.map +1 -0
  17. package/dist/mcp-server/index.js +176 -0
  18. package/dist/mcp-server/index.js.map +1 -0
  19. package/dist/middleware/auth.d.ts +18 -0
  20. package/dist/middleware/auth.d.ts.map +1 -0
  21. package/dist/middleware/auth.js +136 -0
  22. package/dist/middleware/auth.js.map +1 -0
  23. package/dist/middleware/cors-setup.d.ts +7 -0
  24. package/dist/middleware/cors-setup.d.ts.map +1 -0
  25. package/dist/middleware/cors-setup.js +8 -0
  26. package/dist/middleware/cors-setup.js.map +1 -0
  27. package/dist/middleware/error-handler.d.ts +4 -0
  28. package/dist/middleware/error-handler.d.ts.map +1 -0
  29. package/dist/middleware/error-handler.js +27 -0
  30. package/dist/middleware/error-handler.js.map +1 -0
  31. package/dist/middleware/query-parser.d.ts +11 -0
  32. package/dist/middleware/query-parser.d.ts.map +1 -0
  33. package/dist/middleware/query-parser.js +68 -0
  34. package/dist/middleware/query-parser.js.map +1 -0
  35. package/dist/middleware/request-logger.d.ts +4 -0
  36. package/dist/middleware/request-logger.d.ts.map +1 -0
  37. package/dist/middleware/request-logger.js +29 -0
  38. package/dist/middleware/request-logger.js.map +1 -0
  39. package/dist/process-daemon/index.d.ts +14 -0
  40. package/dist/process-daemon/index.d.ts.map +1 -0
  41. package/dist/process-daemon/index.js +51 -0
  42. package/dist/process-daemon/index.js.map +1 -0
  43. package/dist/process-daemon/process-daemon.d.ts +78 -0
  44. package/dist/process-daemon/process-daemon.d.ts.map +1 -0
  45. package/dist/process-daemon/process-daemon.js +568 -0
  46. package/dist/process-daemon/process-daemon.js.map +1 -0
  47. package/dist/process-daemon/process-manager-client.d.ts +108 -0
  48. package/dist/process-daemon/process-manager-client.d.ts.map +1 -0
  49. package/dist/process-daemon/process-manager-client.js +314 -0
  50. package/dist/process-daemon/process-manager-client.js.map +1 -0
  51. package/dist/process-daemon/process-manager-interface.d.ts +47 -0
  52. package/dist/process-daemon/process-manager-interface.d.ts.map +1 -0
  53. package/dist/process-daemon/process-manager-interface.js +8 -0
  54. package/dist/process-daemon/process-manager-interface.js.map +1 -0
  55. package/dist/process-daemon/test-daemon.d.ts +12 -0
  56. package/dist/process-daemon/test-daemon.d.ts.map +1 -0
  57. package/dist/process-daemon/test-daemon.js +81 -0
  58. package/dist/process-daemon/test-daemon.js.map +1 -0
  59. package/dist/process-daemon/types.d.ts +85 -0
  60. package/dist/process-daemon/types.d.ts.map +1 -0
  61. package/dist/process-daemon/types.js +8 -0
  62. package/dist/process-daemon/types.js.map +1 -0
  63. package/dist/routes/claudia.routes.d.ts +10 -0
  64. package/dist/routes/claudia.routes.d.ts.map +1 -0
  65. package/dist/routes/claudia.routes.js +123 -0
  66. package/dist/routes/claudia.routes.js.map +1 -0
  67. package/dist/routes/config.routes.d.ts +4 -0
  68. package/dist/routes/config.routes.d.ts.map +1 -0
  69. package/dist/routes/config.routes.js +27 -0
  70. package/dist/routes/config.routes.js.map +1 -0
  71. package/dist/routes/conversation.routes.d.ts +8 -0
  72. package/dist/routes/conversation.routes.d.ts.map +1 -0
  73. package/dist/routes/conversation.routes.js +870 -0
  74. package/dist/routes/conversation.routes.js.map +1 -0
  75. package/dist/routes/filesystem.routes.d.ts +4 -0
  76. package/dist/routes/filesystem.routes.d.ts.map +1 -0
  77. package/dist/routes/filesystem.routes.js +86 -0
  78. package/dist/routes/filesystem.routes.js.map +1 -0
  79. package/dist/routes/gemini.routes.d.ts +4 -0
  80. package/dist/routes/gemini.routes.d.ts.map +1 -0
  81. package/dist/routes/gemini.routes.js +93 -0
  82. package/dist/routes/gemini.routes.js.map +1 -0
  83. package/dist/routes/insights.routes.d.ts +17 -0
  84. package/dist/routes/insights.routes.d.ts.map +1 -0
  85. package/dist/routes/insights.routes.js +417 -0
  86. package/dist/routes/insights.routes.js.map +1 -0
  87. package/dist/routes/license.routes.d.ts +3 -0
  88. package/dist/routes/license.routes.d.ts.map +1 -0
  89. package/dist/routes/license.routes.js +111 -0
  90. package/dist/routes/license.routes.js.map +1 -0
  91. package/dist/routes/log.routes.d.ts +3 -0
  92. package/dist/routes/log.routes.d.ts.map +1 -0
  93. package/dist/routes/log.routes.js +65 -0
  94. package/dist/routes/log.routes.js.map +1 -0
  95. package/dist/routes/notifications.routes.d.ts +4 -0
  96. package/dist/routes/notifications.routes.d.ts.map +1 -0
  97. package/dist/routes/notifications.routes.js +71 -0
  98. package/dist/routes/notifications.routes.js.map +1 -0
  99. package/dist/routes/permission.routes.d.ts +4 -0
  100. package/dist/routes/permission.routes.d.ts.map +1 -0
  101. package/dist/routes/permission.routes.js +116 -0
  102. package/dist/routes/permission.routes.js.map +1 -0
  103. package/dist/routes/question.routes.d.ts +8 -0
  104. package/dist/routes/question.routes.d.ts.map +1 -0
  105. package/dist/routes/question.routes.js +82 -0
  106. package/dist/routes/question.routes.js.map +1 -0
  107. package/dist/routes/streaming.routes.d.ts +4 -0
  108. package/dist/routes/streaming.routes.d.ts.map +1 -0
  109. package/dist/routes/streaming.routes.js +28 -0
  110. package/dist/routes/streaming.routes.js.map +1 -0
  111. package/dist/routes/system.routes.d.ts +5 -0
  112. package/dist/routes/system.routes.d.ts.map +1 -0
  113. package/dist/routes/system.routes.js +103 -0
  114. package/dist/routes/system.routes.js.map +1 -0
  115. package/dist/routes/working-directories.routes.d.ts +4 -0
  116. package/dist/routes/working-directories.routes.d.ts.map +1 -0
  117. package/dist/routes/working-directories.routes.js +25 -0
  118. package/dist/routes/working-directories.routes.js.map +1 -0
  119. package/dist/server.d.ts +3 -0
  120. package/dist/server.d.ts.map +1 -0
  121. package/dist/server.js +34 -0
  122. package/dist/server.js.map +1 -0
  123. package/dist/services/ToolMetricsService.d.ts +53 -0
  124. package/dist/services/ToolMetricsService.d.ts.map +1 -0
  125. package/dist/services/ToolMetricsService.js +230 -0
  126. package/dist/services/ToolMetricsService.js.map +1 -0
  127. package/dist/services/anthropic-service.d.ts +186 -0
  128. package/dist/services/anthropic-service.d.ts.map +1 -0
  129. package/dist/services/anthropic-service.js +1132 -0
  130. package/dist/services/anthropic-service.js.map +1 -0
  131. package/dist/services/claude-history-reader.d.ts +126 -0
  132. package/dist/services/claude-history-reader.d.ts.map +1 -0
  133. package/dist/services/claude-history-reader.js +717 -0
  134. package/dist/services/claude-history-reader.js.map +1 -0
  135. package/dist/services/claude-process-manager.d.ts +108 -0
  136. package/dist/services/claude-process-manager.d.ts.map +1 -0
  137. package/dist/services/claude-process-manager.js +909 -0
  138. package/dist/services/claude-process-manager.js.map +1 -0
  139. package/dist/services/claude-router-service.d.ts +19 -0
  140. package/dist/services/claude-router-service.d.ts.map +1 -0
  141. package/dist/services/claude-router-service.js +160 -0
  142. package/dist/services/claude-router-service.js.map +1 -0
  143. package/dist/services/claudia-service.d.ts +77 -0
  144. package/dist/services/claudia-service.d.ts.map +1 -0
  145. package/dist/services/claudia-service.js +194 -0
  146. package/dist/services/claudia-service.js.map +1 -0
  147. package/dist/services/commands-service.d.ts +18 -0
  148. package/dist/services/commands-service.d.ts.map +1 -0
  149. package/dist/services/commands-service.js +76 -0
  150. package/dist/services/commands-service.js.map +1 -0
  151. package/dist/services/config-service.d.ts +68 -0
  152. package/dist/services/config-service.d.ts.map +1 -0
  153. package/dist/services/config-service.js +429 -0
  154. package/dist/services/config-service.js.map +1 -0
  155. package/dist/services/conversation-cache.d.ts +86 -0
  156. package/dist/services/conversation-cache.d.ts.map +1 -0
  157. package/dist/services/conversation-cache.js +235 -0
  158. package/dist/services/conversation-cache.js.map +1 -0
  159. package/dist/services/conversation-status-manager.d.ts +98 -0
  160. package/dist/services/conversation-status-manager.d.ts.map +1 -0
  161. package/dist/services/conversation-status-manager.js +295 -0
  162. package/dist/services/conversation-status-manager.js.map +1 -0
  163. package/dist/services/cost-tracker.d.ts +87 -0
  164. package/dist/services/cost-tracker.d.ts.map +1 -0
  165. package/dist/services/cost-tracker.js +335 -0
  166. package/dist/services/cost-tracker.js.map +1 -0
  167. package/dist/services/file-system-service.d.ts +61 -0
  168. package/dist/services/file-system-service.d.ts.map +1 -0
  169. package/dist/services/file-system-service.js +348 -0
  170. package/dist/services/file-system-service.js.map +1 -0
  171. package/dist/services/gemini-service.d.ts +72 -0
  172. package/dist/services/gemini-service.d.ts.map +1 -0
  173. package/dist/services/gemini-service.js +431 -0
  174. package/dist/services/gemini-service.js.map +1 -0
  175. package/dist/services/insight-queue.d.ts +99 -0
  176. package/dist/services/insight-queue.d.ts.map +1 -0
  177. package/dist/services/insight-queue.js +277 -0
  178. package/dist/services/insight-queue.js.map +1 -0
  179. package/dist/services/insights-service.d.ts +102 -0
  180. package/dist/services/insights-service.d.ts.map +1 -0
  181. package/dist/services/insights-service.js +1152 -0
  182. package/dist/services/insights-service.js.map +1 -0
  183. package/dist/services/json-lines-parser.d.ts +19 -0
  184. package/dist/services/json-lines-parser.d.ts.map +1 -0
  185. package/dist/services/json-lines-parser.js +56 -0
  186. package/dist/services/json-lines-parser.js.map +1 -0
  187. package/dist/services/license-service.d.ts +69 -0
  188. package/dist/services/license-service.d.ts.map +1 -0
  189. package/dist/services/license-service.js +330 -0
  190. package/dist/services/license-service.js.map +1 -0
  191. package/dist/services/log-formatter.d.ts +5 -0
  192. package/dist/services/log-formatter.d.ts.map +1 -0
  193. package/dist/services/log-formatter.js +77 -0
  194. package/dist/services/log-formatter.js.map +1 -0
  195. package/dist/services/log-stream-buffer.d.ts +11 -0
  196. package/dist/services/log-stream-buffer.d.ts.map +1 -0
  197. package/dist/services/log-stream-buffer.js +36 -0
  198. package/dist/services/log-stream-buffer.js.map +1 -0
  199. package/dist/services/logger.d.ts +71 -0
  200. package/dist/services/logger.d.ts.map +1 -0
  201. package/dist/services/logger.js +215 -0
  202. package/dist/services/logger.js.map +1 -0
  203. package/dist/services/mcp-config-generator.d.ts +32 -0
  204. package/dist/services/mcp-config-generator.d.ts.map +1 -0
  205. package/dist/services/mcp-config-generator.js +126 -0
  206. package/dist/services/mcp-config-generator.js.map +1 -0
  207. package/dist/services/message-filter.d.ts +22 -0
  208. package/dist/services/message-filter.d.ts.map +1 -0
  209. package/dist/services/message-filter.js +57 -0
  210. package/dist/services/message-filter.js.map +1 -0
  211. package/dist/services/notification-service.d.ts +45 -0
  212. package/dist/services/notification-service.d.ts.map +1 -0
  213. package/dist/services/notification-service.js +184 -0
  214. package/dist/services/notification-service.js.map +1 -0
  215. package/dist/services/permission-tracker.d.ts +67 -0
  216. package/dist/services/permission-tracker.d.ts.map +1 -0
  217. package/dist/services/permission-tracker.js +161 -0
  218. package/dist/services/permission-tracker.js.map +1 -0
  219. package/dist/services/process-manager-factory.d.ts +81 -0
  220. package/dist/services/process-manager-factory.d.ts.map +1 -0
  221. package/dist/services/process-manager-factory.js +211 -0
  222. package/dist/services/process-manager-factory.js.map +1 -0
  223. package/dist/services/question-tracker.d.ts +47 -0
  224. package/dist/services/question-tracker.d.ts.map +1 -0
  225. package/dist/services/question-tracker.js +105 -0
  226. package/dist/services/question-tracker.js.map +1 -0
  227. package/dist/services/session-activity-watcher.d.ts +33 -0
  228. package/dist/services/session-activity-watcher.d.ts.map +1 -0
  229. package/dist/services/session-activity-watcher.js +194 -0
  230. package/dist/services/session-activity-watcher.js.map +1 -0
  231. package/dist/services/session-info-service.d.ts +228 -0
  232. package/dist/services/session-info-service.d.ts.map +1 -0
  233. package/dist/services/session-info-service.js +920 -0
  234. package/dist/services/session-info-service.js.map +1 -0
  235. package/dist/services/session-insights-service.d.ts +119 -0
  236. package/dist/services/session-insights-service.d.ts.map +1 -0
  237. package/dist/services/session-insights-service.js +889 -0
  238. package/dist/services/session-insights-service.js.map +1 -0
  239. package/dist/services/stream-manager.d.ts +62 -0
  240. package/dist/services/stream-manager.d.ts.map +1 -0
  241. package/dist/services/stream-manager.js +239 -0
  242. package/dist/services/stream-manager.js.map +1 -0
  243. package/dist/services/web-push-service.d.ts +48 -0
  244. package/dist/services/web-push-service.d.ts.map +1 -0
  245. package/dist/services/web-push-service.js +186 -0
  246. package/dist/services/web-push-service.js.map +1 -0
  247. package/dist/services/working-directories-service.d.ts +19 -0
  248. package/dist/services/working-directories-service.d.ts.map +1 -0
  249. package/dist/services/working-directories-service.js +103 -0
  250. package/dist/services/working-directories-service.js.map +1 -0
  251. package/dist/types/config.d.ts +111 -0
  252. package/dist/types/config.d.ts.map +1 -0
  253. package/dist/types/config.js +14 -0
  254. package/dist/types/config.js.map +1 -0
  255. package/dist/types/express.d.ts +5 -0
  256. package/dist/types/express.d.ts.map +1 -0
  257. package/dist/types/express.js +2 -0
  258. package/dist/types/express.js.map +1 -0
  259. package/dist/types/index.d.ts +325 -0
  260. package/dist/types/index.d.ts.map +1 -0
  261. package/dist/types/index.js +18 -0
  262. package/dist/types/index.js.map +1 -0
  263. package/dist/types/insights.d.ts +99 -0
  264. package/dist/types/insights.d.ts.map +1 -0
  265. package/dist/types/insights.js +7 -0
  266. package/dist/types/insights.js.map +1 -0
  267. package/dist/types/license.d.ts +70 -0
  268. package/dist/types/license.d.ts.map +1 -0
  269. package/dist/types/license.js +5 -0
  270. package/dist/types/license.js.map +1 -0
  271. package/dist/types/router-config.d.ts +13 -0
  272. package/dist/types/router-config.d.ts.map +1 -0
  273. package/dist/types/router-config.js +2 -0
  274. package/dist/types/router-config.js.map +1 -0
  275. package/dist/utils/constants.d.ts +26 -0
  276. package/dist/utils/constants.d.ts.map +1 -0
  277. package/dist/utils/constants.js +28 -0
  278. package/dist/utils/constants.js.map +1 -0
  279. package/dist/utils/machine-id.d.ts +7 -0
  280. package/dist/utils/machine-id.d.ts.map +1 -0
  281. package/dist/utils/machine-id.js +76 -0
  282. package/dist/utils/machine-id.js.map +1 -0
  283. package/dist/utils/server-startup.d.ts +13 -0
  284. package/dist/utils/server-startup.d.ts.map +1 -0
  285. package/dist/utils/server-startup.js +20 -0
  286. package/dist/utils/server-startup.js.map +1 -0
  287. package/dist/web/assets/main-DAc2rjJ2.css +1 -0
  288. package/dist/web/assets/main-DvlZ02mT.js +137 -0
  289. package/dist/web/favicon.png +0 -0
  290. package/dist/web/favicon.svg +22 -0
  291. package/dist/web/icon-192x192.png +0 -0
  292. package/dist/web/icon-512x512.png +0 -0
  293. package/dist/web/index.html +36 -0
  294. package/dist/web/manifest.json +61 -0
  295. package/package.json +174 -0
  296. package/scripts/postinstall.js +30 -0
@@ -0,0 +1,705 @@
1
+ import express from 'express';
2
+ import * as path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { dirname } from 'path';
5
+ import { displayServerStartup } from './utils/server-startup.js';
6
+ // Get the directory of this module for serving static files
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ import { createProcessManager } from './services/process-manager-factory.js';
10
+ import { StreamManager } from './services/stream-manager.js';
11
+ import { ClaudeHistoryReader } from './services/claude-history-reader.js';
12
+ import { PermissionTracker } from './services/permission-tracker.js';
13
+ import { QuestionTracker } from './services/question-tracker.js';
14
+ import { MCPConfigGenerator } from './services/mcp-config-generator.js';
15
+ import { FileSystemService } from './services/file-system-service.js';
16
+ import { ConfigService } from './services/config-service.js';
17
+ import { SessionInfoService } from './services/session-info-service.js';
18
+ import { ConversationStatusManager } from './services/conversation-status-manager.js';
19
+ import { WorkingDirectoriesService } from './services/working-directories-service.js';
20
+ import { ToolMetricsService } from './services/ToolMetricsService.js';
21
+ import { NotificationService } from './services/notification-service.js';
22
+ import { WebPushService } from './services/web-push-service.js';
23
+ import { geminiService } from './services/gemini-service.js';
24
+ import { anthropicService } from './services/anthropic-service.js';
25
+ import { SessionInsightsService } from './services/session-insights-service.js';
26
+ import { ClaudeRouterService } from './services/claude-router-service.js';
27
+ import { CUIError } from './types/index.js';
28
+ import { createLogger } from './services/logger.js';
29
+ import { createConversationRoutes } from './routes/conversation.routes.js';
30
+ import { createSystemRoutes } from './routes/system.routes.js';
31
+ import { createPermissionRoutes } from './routes/permission.routes.js';
32
+ import { createQuestionRoutes } from './routes/question.routes.js';
33
+ import { createFileSystemRoutes } from './routes/filesystem.routes.js';
34
+ import { createLogRoutes } from './routes/log.routes.js';
35
+ import { createStreamingRoutes } from './routes/streaming.routes.js';
36
+ import { createWorkingDirectoriesRoutes } from './routes/working-directories.routes.js';
37
+ import { createConfigRoutes } from './routes/config.routes.js';
38
+ import { createGeminiRoutes } from './routes/gemini.routes.js';
39
+ import { createNotificationsRoutes } from './routes/notifications.routes.js';
40
+ import { createInsightsRoutes } from './routes/insights.routes.js';
41
+ import { createClaudiaRoutes } from './routes/claudia.routes.js';
42
+ import { ClaudiaService } from './services/claudia-service.js';
43
+ import { createLicenseRoutes } from './routes/license.routes.js';
44
+ import { errorHandler } from './middleware/error-handler.js';
45
+ import { requestLogger } from './middleware/request-logger.js';
46
+ import { createCorsMiddleware } from './middleware/cors-setup.js';
47
+ import { queryParser } from './middleware/query-parser.js';
48
+ import { authMiddleware, createAuthMiddleware } from './middleware/auth.js';
49
+ // ViteExpress will be imported dynamically in initialize() if needed
50
+ let ViteExpress;
51
+ /**
52
+ * Main CUI server class
53
+ */
54
+ export class CUIServer {
55
+ app;
56
+ server;
57
+ processManager; // Initialized in initialize()
58
+ streamManager;
59
+ historyReader;
60
+ statusTracker;
61
+ permissionTracker;
62
+ questionTracker;
63
+ mcpConfigGenerator;
64
+ fileSystemService;
65
+ configService;
66
+ sessionInfoService;
67
+ conversationStatusManager;
68
+ workingDirectoriesService;
69
+ toolMetricsService;
70
+ notificationService;
71
+ webPushService;
72
+ routerService;
73
+ logger;
74
+ port;
75
+ host;
76
+ configOverrides;
77
+ constructor(configOverrides) {
78
+ this.app = express();
79
+ this.configOverrides = configOverrides;
80
+ this.logger = createLogger('CUIServer');
81
+ // TEST: Add debug log right at the start
82
+ this.logger.debug('🔍 TEST: CUIServer constructor started - this should be visible if debug logging works');
83
+ // Initialize config service first
84
+ this.configService = ConfigService.getInstance();
85
+ // Will be set after config is loaded
86
+ this.port = 0;
87
+ this.host = '';
88
+ this.logger.debug('Initializing CUIServer', {
89
+ nodeEnv: process.env.NODE_ENV,
90
+ configOverrides
91
+ });
92
+ // Initialize services
93
+ this.logger.debug('Initializing services');
94
+ // Use singleton to ensure event handlers get the same initialized instance
95
+ this.sessionInfoService = SessionInfoService.getInstance();
96
+ this.historyReader = new ClaudeHistoryReader(this.sessionInfoService);
97
+ // Create a single instance of ConversationStatusManager for both statusTracker and conversationStatusManager
98
+ this.conversationStatusManager = new ConversationStatusManager();
99
+ this.statusTracker = this.conversationStatusManager; // Use the same instance for backward compatibility
100
+ this.toolMetricsService = new ToolMetricsService();
101
+ this.fileSystemService = new FileSystemService();
102
+ // processManager is initialized in initialize() to support daemon mode
103
+ this.streamManager = new StreamManager();
104
+ this.permissionTracker = new PermissionTracker();
105
+ this.questionTracker = new QuestionTracker();
106
+ this.mcpConfigGenerator = new MCPConfigGenerator(this.fileSystemService);
107
+ this.workingDirectoriesService = new WorkingDirectoriesService(this.historyReader, this.logger);
108
+ this.notificationService = new NotificationService();
109
+ this.webPushService = WebPushService.getInstance();
110
+ // Wire up services that don't depend on processManager
111
+ this.permissionTracker.setNotificationService(this.notificationService);
112
+ this.permissionTracker.setConversationStatusManager(this.conversationStatusManager);
113
+ this.permissionTracker.setHistoryReader(this.historyReader);
114
+ // Set up background insights computation when sessions end
115
+ const insightsService = new SessionInsightsService(this.historyReader, this.sessionInfoService);
116
+ this.conversationStatusManager.on('session-ended', ({ claudeSessionId }) => {
117
+ // Compute insights in background (fire and forget)
118
+ insightsService.computeInsights(claudeSessionId)
119
+ .then(insights => insightsService.cacheInsights(claudeSessionId, insights))
120
+ .catch(err => this.logger.debug('Background insights computation failed', { claudeSessionId, error: err }));
121
+ });
122
+ this.logger.debug('Services initialized (processManager deferred to initialize())');
123
+ this.setupMiddleware();
124
+ // Routes and processManager integration are set up in initialize()
125
+ }
126
+ /**
127
+ * Get the Express app instance
128
+ */
129
+ getApp() {
130
+ return this.app;
131
+ }
132
+ /**
133
+ * Get the configured port
134
+ */
135
+ getPort() {
136
+ return this.port;
137
+ }
138
+ /**
139
+ * Get the configured host
140
+ */
141
+ getHost() {
142
+ return this.host;
143
+ }
144
+ /**
145
+ * Initialize services without starting the HTTP server
146
+ */
147
+ async initialize() {
148
+ this.logger.debug('Initialize method called');
149
+ try {
150
+ // Initialize configuration first
151
+ this.logger.debug('Initializing configuration');
152
+ await this.configService.initialize();
153
+ const config = this.configService.getConfig();
154
+ // Initialize session info service
155
+ this.logger.debug('Initializing session info service');
156
+ await this.sessionInfoService.initialize();
157
+ this.logger.debug('Session info service initialized successfully');
158
+ // Initialize process manager
159
+ this.logger.debug('Initializing process manager');
160
+ this.processManager = await createProcessManager({
161
+ historyReader: this.historyReader,
162
+ statusTracker: this.statusTracker,
163
+ toolMetricsService: this.toolMetricsService,
164
+ sessionInfoService: this.sessionInfoService,
165
+ fileSystemService: this.fileSystemService
166
+ });
167
+ this.processManager.setNotificationService(this.notificationService);
168
+ this.processManager.setConversationStatusManager(this.conversationStatusManager);
169
+ // Set up event listeners now that processManager exists
170
+ this.setupProcessManagerIntegration();
171
+ this.setupPermissionTrackerIntegration();
172
+ this.setupQuestionTrackerIntegration();
173
+ this.logger.debug('Process manager initialized successfully');
174
+ this.logger.debug('Initializing Gemini service');
175
+ await geminiService.initialize();
176
+ this.logger.debug('Gemini service initialized successfully');
177
+ this.logger.debug('Initializing Anthropic service');
178
+ await anthropicService.initialize();
179
+ this.logger.debug('Anthropic service initialized successfully');
180
+ // Initialize cost tracker for LLM usage monitoring
181
+ this.logger.debug('Initializing cost tracker');
182
+ const { getCostTracker } = await import('./services/cost-tracker.js');
183
+ await getCostTracker().initialize();
184
+ this.logger.debug('Cost tracker initialized successfully');
185
+ // Initialize insights service (unified event-driven system)
186
+ this.logger.debug('Initializing insights service');
187
+ const { initializeInsightsService } = await import('./services/insights-service.js');
188
+ initializeInsightsService();
189
+ this.logger.debug('Insights service initialized successfully');
190
+ // Initialize router service if configured
191
+ await this.initializeOrReloadRouter(config);
192
+ // Apply overrides if provided (for tests and CLI options)
193
+ this.port = this.configOverrides?.port ?? config.server.port;
194
+ this.host = this.configOverrides?.host ?? config.server.host;
195
+ this.logger.info('Configuration loaded', {
196
+ machineId: config.machine_id,
197
+ port: this.port,
198
+ host: this.host,
199
+ overrides: this.configOverrides ? Object.keys(this.configOverrides) : []
200
+ });
201
+ // Set up routes after services are initialized
202
+ // This allows tests to override services before routes are created
203
+ this.logger.debug('Setting up routes');
204
+ this.setupRoutes();
205
+ // Generate MCP config before starting server
206
+ try {
207
+ const mcpConfigPath = await this.mcpConfigGenerator.generateConfig(this.port);
208
+ this.processManager.setMCPConfigPath(mcpConfigPath);
209
+ this.logger.debug('MCP config generated and set', { path: mcpConfigPath });
210
+ }
211
+ catch (error) {
212
+ const isNonProduction = process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development';
213
+ if (isNonProduction) {
214
+ this.logger.warn('MCP config generation failed in non-production environment, proceeding without MCP', {
215
+ error: error instanceof Error ? error.message : String(error),
216
+ nodeEnv: process.env.NODE_ENV
217
+ });
218
+ // Don't set MCP config path - conversations will run without MCP
219
+ }
220
+ else {
221
+ this.logger.error('MCP config generation failed in production environment', {
222
+ error: error instanceof Error ? error.message : String(error)
223
+ });
224
+ throw new CUIError('MCP_CONFIG_REQUIRED', `MCP server files are required in production but not found: ${error instanceof Error ? error.message : String(error)}`, 500);
225
+ }
226
+ }
227
+ // Subscribe to configuration changes to hot-reload router when needed
228
+ this.configService.onChange(async (newConfig) => {
229
+ try {
230
+ await this.initializeOrReloadRouter(newConfig);
231
+ }
232
+ catch (error) {
233
+ this.logger.error('Failed to reload router after config change', error);
234
+ }
235
+ });
236
+ }
237
+ catch (error) {
238
+ this.logger.error('Failed to initialize server:', error, {
239
+ errorType: error instanceof Error ? error.constructor.name : typeof error,
240
+ errorMessage: error instanceof Error ? error.message : String(error)
241
+ });
242
+ if (error instanceof CUIError) {
243
+ throw error;
244
+ }
245
+ else {
246
+ throw new CUIError('SERVER_INIT_FAILED', `Server initialization failed: ${error}`, 500);
247
+ }
248
+ }
249
+ }
250
+ /**
251
+ * Start the server
252
+ */
253
+ async start() {
254
+ this.logger.debug('Start method called');
255
+ try {
256
+ // Initialize all services
257
+ await this.initialize();
258
+ // Start Express server
259
+ const isDev = process.env.NODE_ENV === 'development';
260
+ this.logger.debug('Creating HTTP server listener', {
261
+ useViteExpress: isDev,
262
+ environment: process.env.NODE_ENV
263
+ });
264
+ // Import ViteExpress dynamically if in development mode
265
+ if (isDev && !ViteExpress) {
266
+ const viteExpressModule = await import('vite-express');
267
+ ViteExpress = viteExpressModule.default;
268
+ }
269
+ await new Promise((resolve, reject) => {
270
+ // Use ViteExpress only in development
271
+ if (isDev && ViteExpress) {
272
+ try {
273
+ this.server = this.app.listen(this.port, this.host, () => {
274
+ this.logger.debug('Server successfully bound to port (dev mode)', {
275
+ port: this.port,
276
+ host: this.host,
277
+ address: this.server?.address()
278
+ });
279
+ // Display startup info now that server is actually listening
280
+ const config = this.configService.getConfig();
281
+ displayServerStartup({
282
+ host: this.host,
283
+ port: this.port,
284
+ authToken: this.configOverrides?.token ?? config.authToken,
285
+ skipAuthToken: this.configOverrides?.skipAuthToken,
286
+ logger: this.logger
287
+ });
288
+ // Configure and bind ViteExpress AFTER server is listening
289
+ ViteExpress.config({
290
+ mode: 'development',
291
+ viteConfigFile: 'vite.config.mts'
292
+ });
293
+ ViteExpress.bind(this.app, this.server);
294
+ this.logger.info(`CUI development server running on http://${this.host}:${this.port}`);
295
+ resolve();
296
+ });
297
+ }
298
+ catch (error) {
299
+ this.logger.error('Failed to start ViteExpress server', error);
300
+ reject(error);
301
+ }
302
+ }
303
+ else {
304
+ // Production/test mode - regular Express server
305
+ this.server = this.app.listen(this.port, this.host, () => {
306
+ this.logger.debug('Server successfully bound to port', {
307
+ port: this.port,
308
+ host: this.host,
309
+ address: this.server?.address(),
310
+ mode: process.env.NODE_ENV || 'production'
311
+ });
312
+ // Display startup info now that server is actually listening
313
+ const config = this.configService.getConfig();
314
+ displayServerStartup({
315
+ host: this.host,
316
+ port: this.port,
317
+ authToken: this.configOverrides?.token ?? config.authToken,
318
+ skipAuthToken: this.configOverrides?.skipAuthToken,
319
+ logger: this.logger
320
+ });
321
+ resolve();
322
+ });
323
+ }
324
+ if (this.server) {
325
+ this.server.on('error', (error) => {
326
+ this.logger.error('Failed to start HTTP server:', error, {
327
+ errorCode: error.code,
328
+ errorSyscall: error.syscall,
329
+ port: this.port,
330
+ host: this.host
331
+ });
332
+ reject(new CUIError('HTTP_SERVER_START_FAILED', `Failed to start HTTP server: ${error.message}`, 500));
333
+ });
334
+ }
335
+ });
336
+ }
337
+ catch (error) {
338
+ this.logger.error('Failed to start server:', error, {
339
+ errorType: error instanceof Error ? error.constructor.name : typeof error,
340
+ errorMessage: error instanceof Error ? error.message : String(error)
341
+ });
342
+ // Attempt cleanup on startup failure
343
+ await this.cleanup();
344
+ if (error instanceof CUIError) {
345
+ throw error;
346
+ }
347
+ else {
348
+ throw new CUIError('SERVER_START_FAILED', `Server startup failed: ${error}`, 500);
349
+ }
350
+ }
351
+ }
352
+ /**
353
+ * Stop the server gracefully
354
+ */
355
+ async stop() {
356
+ this.logger.debug('Stop method called', {
357
+ hasServer: !!this.server,
358
+ activeSessions: this.processManager.getActiveSessions().length,
359
+ connectedClients: this.streamManager.getTotalClientCount()
360
+ });
361
+ if (this.routerService) {
362
+ await this.routerService.stop();
363
+ }
364
+ // Stop all active Claude processes (only in direct mode - daemon keeps them alive)
365
+ if (this.processManager.mode === 'direct') {
366
+ const activeSessions = this.processManager.getActiveSessions();
367
+ if (activeSessions.length > 0) {
368
+ this.logger.info(`Stopping ${activeSessions.length} active sessions...`);
369
+ this.logger.debug('Active sessions to stop', { sessionIds: activeSessions });
370
+ const stopResults = await Promise.allSettled(activeSessions.map(streamingId => this.processManager.stopConversation(streamingId)
371
+ .catch(error => this.logger.error(`Error stopping session ${streamingId}:`, error))));
372
+ this.logger.debug('Session stop results', {
373
+ total: stopResults.length,
374
+ fulfilled: stopResults.filter(r => r.status === 'fulfilled').length,
375
+ rejected: stopResults.filter(r => r.status === 'rejected').length
376
+ });
377
+ }
378
+ }
379
+ else {
380
+ this.logger.info('Daemon mode: keeping Claude processes alive through restart');
381
+ }
382
+ // Disconnect from daemon to stop reconnection loop
383
+ this.processManager.disconnect();
384
+ // Disconnect all streaming clients (sends close events and ends responses)
385
+ this.logger.debug('Disconnecting all streaming clients');
386
+ this.streamManager.disconnectAll();
387
+ // Clean up MCP config
388
+ this.logger.debug('Cleaning up MCP config');
389
+ this.mcpConfigGenerator.cleanup();
390
+ // Close HTTP server to release port
391
+ if (this.server) {
392
+ this.logger.debug('Closing HTTP server');
393
+ // Force close all connections after ending SSE streams
394
+ // This ensures we don't wait for clients that haven't acknowledged the close
395
+ if (typeof this.server.closeAllConnections === 'function') {
396
+ this.server.closeAllConnections();
397
+ }
398
+ // Close with timeout - don't block shutdown forever
399
+ await new Promise((resolve) => {
400
+ const timeout = setTimeout(() => {
401
+ this.logger.warn('HTTP server close timed out after 2s, forcing shutdown');
402
+ resolve();
403
+ }, 2000);
404
+ this.server.close(() => {
405
+ clearTimeout(timeout);
406
+ this.logger.info('HTTP server closed successfully');
407
+ resolve();
408
+ });
409
+ });
410
+ }
411
+ }
412
+ /**
413
+ * Cleanup resources during failed startup
414
+ */
415
+ async cleanup() {
416
+ this.logger.info('Performing cleanup after startup failure...');
417
+ this.logger.debug('Cleanup initiated', {
418
+ hasServer: !!this.server,
419
+ hasActiveStreams: this.streamManager.getTotalClientCount() > 0
420
+ });
421
+ try {
422
+ // Close HTTP server if it was started
423
+ if (this.server) {
424
+ await new Promise((resolve) => {
425
+ this.server.close(() => {
426
+ this.logger.info('HTTP server closed during cleanup');
427
+ resolve();
428
+ });
429
+ });
430
+ }
431
+ // Disconnect streaming clients
432
+ this.streamManager.disconnectAll();
433
+ this.logger.info('Cleanup completed');
434
+ }
435
+ catch (error) {
436
+ this.logger.error('Error during cleanup:', error, {
437
+ errorType: error instanceof Error ? error.constructor.name : typeof error
438
+ });
439
+ }
440
+ }
441
+ setupMiddleware() {
442
+ this.app.use(createCorsMiddleware());
443
+ this.app.use(express.json({ limit: '10mb' }));
444
+ // Static file serving
445
+ const isDev = process.env.NODE_ENV === 'development';
446
+ if (!isDev) {
447
+ // In production/test, serve built static files
448
+ // In production, __dirname will be /path/to/node_modules/cui-server/dist
449
+ // We need to serve from dist/web
450
+ const staticPath = path.join(__dirname, 'web');
451
+ this.logger.debug('Serving static files from', { path: staticPath });
452
+ this.app.use(express.static(staticPath));
453
+ }
454
+ // In development, ViteExpress handles static file serving
455
+ // Request logging
456
+ this.app.use(requestLogger);
457
+ // Query parameter parsing - convert strings to proper types
458
+ this.app.use(queryParser);
459
+ }
460
+ setupRoutes() {
461
+ // System routes (includes health check) - before auth
462
+ this.app.use('/api/system', createSystemRoutes(this.processManager, this.historyReader));
463
+ this.app.use('/', createSystemRoutes(this.processManager, this.historyReader)); // For /health at root
464
+ // Permission routes - before auth (needed for MCP server communication)
465
+ this.app.use('/api/permissions', createPermissionRoutes(this.permissionTracker));
466
+ // Notifications routes - before auth (needed for service worker subscription on first load)
467
+ this.app.use('/api/notifications', createNotificationsRoutes(this.webPushService));
468
+ // Apply auth middleware to all other API routes unless skipAuthToken is set
469
+ if (!this.configOverrides?.skipAuthToken) {
470
+ if (this.configOverrides?.token) {
471
+ // Use custom auth middleware with token override
472
+ this.app.use('/api', createAuthMiddleware(this.configOverrides.token));
473
+ this.logger.info('Using custom authentication token from CLI');
474
+ }
475
+ else {
476
+ // Use default auth middleware
477
+ this.app.use('/api', authMiddleware);
478
+ }
479
+ }
480
+ else {
481
+ this.logger.warn('Authentication middleware is disabled - API endpoints are not protected!');
482
+ }
483
+ // API routes
484
+ // IMPORTANT: Insights routes must be registered BEFORE conversation routes
485
+ // because conversation routes have a /:sessionId catch-all pattern that would
486
+ // otherwise match paths like /activity-check
487
+ this.app.use('/api/conversations', createInsightsRoutes(this.historyReader, this.sessionInfoService));
488
+ this.app.use('/api/conversations', createConversationRoutes(this.processManager, this.historyReader, this.statusTracker, this.sessionInfoService, this.conversationStatusManager, this.toolMetricsService));
489
+ this.app.use('/api/filesystem', createFileSystemRoutes(this.fileSystemService));
490
+ this.app.use('/api/logs', createLogRoutes());
491
+ this.app.use('/api/stream', createStreamingRoutes(this.streamManager));
492
+ this.app.use('/api/working-directories', createWorkingDirectoriesRoutes(this.workingDirectoriesService));
493
+ this.app.use('/api/config', createConfigRoutes(this.configService));
494
+ this.app.use('/api/gemini', createGeminiRoutes(geminiService));
495
+ this.app.use('/api/questions', createQuestionRoutes(this.questionTracker, this.processManager));
496
+ // Claudia orchestrator routes
497
+ const claudiaService = ClaudiaService.getInstance({
498
+ processManager: this.processManager,
499
+ historyReader: this.historyReader,
500
+ statusManager: this.conversationStatusManager
501
+ });
502
+ this.app.use('/api/claudia', createClaudiaRoutes(claudiaService));
503
+ // License routes
504
+ this.app.use('/api/license', createLicenseRoutes());
505
+ // React Router catch-all - must be after all API routes
506
+ const isDev = process.env.NODE_ENV === 'development';
507
+ if (!isDev) {
508
+ // In production/test, serve index.html for all non-API routes
509
+ this.app.get('*', (req, res) => {
510
+ res.sendFile(path.join(__dirname, 'web', 'index.html'));
511
+ });
512
+ }
513
+ // In development, ViteExpress handles React routing
514
+ // Error handling - MUST be last
515
+ this.app.use(errorHandler);
516
+ }
517
+ setupProcessManagerIntegration() {
518
+ this.logger.debug('Setting up ProcessManager integration with StreamManager');
519
+ // Set up tool metrics service to listen to claude messages
520
+ this.toolMetricsService.listenToClaudeMessages(this.processManager);
521
+ // Forward Claude messages to stream
522
+ this.processManager.on('claude-message', ({ streamingId, message }) => {
523
+ this.logger.debug('Received claude-message event', {
524
+ streamingId,
525
+ messageType: message?.type,
526
+ messageSubtype: message?.subtype,
527
+ hasContent: !!message?.content,
528
+ contentLength: message?.content?.length || 0,
529
+ messageKeys: message ? Object.keys(message) : []
530
+ });
531
+ // Skip broadcasting system init messages as they're now included in API response
532
+ if (message && message.type === 'system' && message.subtype === 'init') {
533
+ this.logger.debug('Skipping broadcast of system init message (included in API response)', {
534
+ streamingId,
535
+ sessionId: message.session_id
536
+ });
537
+ return;
538
+ }
539
+ // Detect AskUserQuestion tool_use and register with QuestionTracker
540
+ if (message && message.type === 'assistant' && message.message?.content) {
541
+ const content = message.message.content;
542
+ if (Array.isArray(content)) {
543
+ for (const block of content) {
544
+ if (block.type === 'tool_use' && block.name === 'AskUserQuestion') {
545
+ const input = block.input;
546
+ if (input.questions) {
547
+ this.questionTracker.addQuestionRequest(block.id, input.questions, streamingId);
548
+ }
549
+ }
550
+ }
551
+ }
552
+ }
553
+ // Stream other Claude messages as normal
554
+ this.logger.debug('Broadcasting message to StreamManager', {
555
+ streamingId,
556
+ messageType: message?.type,
557
+ messageSubtype: message?.subtype
558
+ });
559
+ this.streamManager.broadcast(streamingId, message);
560
+ });
561
+ // Handle process closure
562
+ this.processManager.on('process-closed', ({ streamingId, code }) => {
563
+ this.logger.debug('Received process-closed event, closing StreamManager session', {
564
+ streamingId,
565
+ exitCode: code,
566
+ clientCount: this.streamManager.getClientCount(streamingId),
567
+ wasSuccessful: code === 0
568
+ });
569
+ // Unregister session from status tracker
570
+ this.logger.debug('Unregistering session from status tracker', { streamingId });
571
+ this.statusTracker.unregisterActiveSession(streamingId);
572
+ // Clean up conversation context (handled automatically in unregisterActiveSession)
573
+ // Clean up permissions for this streaming session
574
+ const removedCount = this.permissionTracker.removePermissionsByStreamingId(streamingId);
575
+ if (removedCount > 0) {
576
+ this.logger.debug('Cleaned up permissions for closed session', {
577
+ streamingId,
578
+ removedPermissions: removedCount
579
+ });
580
+ }
581
+ // Clean up questions for this streaming session
582
+ const removedQuestions = this.questionTracker.removeQuestionsByStreamingId(streamingId);
583
+ if (removedQuestions > 0) {
584
+ this.logger.debug('Cleaned up questions for closed session', {
585
+ streamingId,
586
+ removedQuestions
587
+ });
588
+ }
589
+ if (code === 0) {
590
+ // Session completion notification removed
591
+ }
592
+ this.streamManager.closeSession(streamingId);
593
+ });
594
+ // Handle process errors
595
+ this.processManager.on('process-error', ({ streamingId, error }) => {
596
+ this.logger.debug('Received process-error event, forwarding to StreamManager', {
597
+ streamingId,
598
+ error,
599
+ errorLength: error?.toString().length || 0,
600
+ clientCount: this.streamManager.getClientCount(streamingId)
601
+ });
602
+ // Unregister session from status tracker on error
603
+ this.logger.debug('Unregistering session from status tracker due to error', { streamingId });
604
+ this.statusTracker.unregisterActiveSession(streamingId);
605
+ // Clean up conversation context on error (handled automatically in unregisterActiveSession)
606
+ const errorEvent = {
607
+ type: 'error',
608
+ error: error.toString(),
609
+ streamingId: streamingId,
610
+ timestamp: new Date().toISOString()
611
+ };
612
+ this.logger.debug('Broadcasting error event to clients', {
613
+ streamingId,
614
+ errorEventKeys: Object.keys(errorEvent)
615
+ });
616
+ this.streamManager.broadcast(streamingId, errorEvent);
617
+ });
618
+ this.logger.debug('ProcessManager integration setup complete', {
619
+ totalEventListeners: this.processManager.listenerCount('claude-message') +
620
+ this.processManager.listenerCount('process-closed') +
621
+ this.processManager.listenerCount('process-error')
622
+ });
623
+ }
624
+ setupPermissionTrackerIntegration() {
625
+ this.logger.debug('Setting up PermissionTracker integration');
626
+ // Forward permission events to stream
627
+ this.permissionTracker.on('permission_request', (request) => {
628
+ this.logger.debug('Permission request event received', {
629
+ id: request.id,
630
+ toolName: request.toolName,
631
+ streamingId: request.streamingId
632
+ });
633
+ // Broadcast to the appropriate streaming session
634
+ if (request.streamingId && request.streamingId !== 'unknown') {
635
+ const event = {
636
+ type: 'permission_request',
637
+ data: request,
638
+ streamingId: request.streamingId,
639
+ timestamp: new Date().toISOString()
640
+ };
641
+ this.streamManager.broadcast(request.streamingId, event);
642
+ // Permission request notification removed
643
+ }
644
+ });
645
+ this.logger.debug('PermissionTracker integration setup complete');
646
+ }
647
+ setupQuestionTrackerIntegration() {
648
+ this.logger.debug('Setting up QuestionTracker integration');
649
+ // Forward question events to stream
650
+ this.questionTracker.on('question_request', (request) => {
651
+ this.logger.debug('Question request event received', {
652
+ id: request.id,
653
+ toolUseId: request.toolUseId,
654
+ streamingId: request.streamingId,
655
+ questionCount: request.questions.length
656
+ });
657
+ // Broadcast to the appropriate streaming session
658
+ if (request.streamingId && request.streamingId !== 'unknown') {
659
+ const event = {
660
+ type: 'question_request',
661
+ data: request,
662
+ streamingId: request.streamingId,
663
+ timestamp: new Date().toISOString()
664
+ };
665
+ this.streamManager.broadcast(request.streamingId, event);
666
+ }
667
+ });
668
+ this.logger.debug('QuestionTracker integration setup complete');
669
+ }
670
+ async initializeOrReloadRouter(config) {
671
+ // If router is disabled, ensure it is stopped
672
+ if (!config.router?.enabled) {
673
+ if (this.routerService) {
674
+ this.logger.info('Router disabled in configuration, stopping router service');
675
+ await this.routerService.stop();
676
+ this.routerService = undefined;
677
+ this.processManager.setRouterService(undefined);
678
+ }
679
+ else {
680
+ this.logger.info('Router service is disabled');
681
+ }
682
+ return;
683
+ }
684
+ // If router is enabled
685
+ try {
686
+ // If there is an existing router, stop it first
687
+ if (this.routerService) {
688
+ this.logger.info('Reloading router service due to configuration change...');
689
+ await this.routerService.stop();
690
+ this.routerService = undefined;
691
+ }
692
+ else {
693
+ this.logger.debug('Router service is enabled, attempting to initialize...');
694
+ }
695
+ this.routerService = new ClaudeRouterService(config.router);
696
+ await this.routerService.initialize();
697
+ this.processManager.setRouterService(this.routerService);
698
+ this.logger.info('Router service initialized');
699
+ }
700
+ catch (error) {
701
+ this.logger.error('Router initialization failed, continuing without router', error);
702
+ }
703
+ }
704
+ }
705
+ //# sourceMappingURL=cui-server.js.map