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,57 @@
1
+ import { createLogger } from './logger.js';
2
+ /**
3
+ * Filters out local command messages from conversation history
4
+ */
5
+ export class MessageFilter {
6
+ logger;
7
+ filteredPrefixes = [
8
+ 'Caveat: ',
9
+ '<command-name>',
10
+ '<local-command-stdout>'
11
+ ];
12
+ constructor() {
13
+ this.logger = createLogger('MessageFilter');
14
+ }
15
+ /**
16
+ * Filter an array of conversation messages
17
+ */
18
+ filterMessages(messages) {
19
+ return messages.filter(message => this.shouldKeepMessage(message));
20
+ }
21
+ /**
22
+ * Determine if a message should be kept (not filtered out)
23
+ */
24
+ shouldKeepMessage(message) {
25
+ // Only filter user messages with text content
26
+ if (message.type !== 'user') {
27
+ return true;
28
+ }
29
+ const textContent = this.extractTextContent(message.message);
30
+ if (!textContent) {
31
+ return true; // Keep messages without text content
32
+ }
33
+ // Check if the text starts with any filtered prefix
34
+ const shouldFilter = this.filteredPrefixes.some(prefix => textContent.trim().startsWith(prefix));
35
+ return !shouldFilter;
36
+ }
37
+ /**
38
+ * Extract text content from Anthropic message object
39
+ */
40
+ extractTextContent(message) {
41
+ if (typeof message === 'string') {
42
+ return message;
43
+ }
44
+ if (message.content) {
45
+ if (typeof message.content === 'string') {
46
+ return message.content;
47
+ }
48
+ if (Array.isArray(message.content)) {
49
+ // Find first text content block
50
+ const textBlock = message.content.find((block) => block.type === 'text');
51
+ return textBlock && 'text' in textBlock ? textBlock.text : null;
52
+ }
53
+ }
54
+ return null;
55
+ }
56
+ }
57
+ //# sourceMappingURL=message-filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-filter.js","sourceRoot":"","sources":["../../src/services/message-filter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAExD;;GAEG;AACH,MAAM,OAAO,aAAa;IAChB,MAAM,CAAS;IACf,gBAAgB,GAAa;QACnC,UAAU;QACV,gBAAgB;QAChB,wBAAwB;KACzB,CAAC;IAEF;QACE,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,QAA+B;QAC5C,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,OAA4B;QACpD,8CAA8C;QAC9C,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC7D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC,CAAC,qCAAqC;QACpD,CAAC;QAED,oDAAoD;QACpD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CACvD,WAAW,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CACtC,CAAC;QAEF,OAAO,CAAC,YAAY,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,OAA4D;QACrF,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACxC,OAAO,OAAO,CAAC,OAAO,CAAC;YACzB,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,gCAAgC;gBAChC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;gBACzE,OAAO,SAAS,IAAI,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAClE,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
@@ -0,0 +1,45 @@
1
+ import { PermissionRequest } from '../types/index.js';
2
+ export interface Notification {
3
+ title: string;
4
+ message: string;
5
+ priority: 'min' | 'low' | 'default' | 'high' | 'urgent';
6
+ tags: string[];
7
+ sessionId: string;
8
+ streamingId: string;
9
+ permissionRequestId?: string;
10
+ }
11
+ /**
12
+ * Service for sending push notifications via ntfy.sh
13
+ */
14
+ export declare class NotificationService {
15
+ private logger;
16
+ private configService;
17
+ private machineId;
18
+ private webPushService;
19
+ constructor();
20
+ /**
21
+ * Get machine ID from config
22
+ */
23
+ private getMachineId;
24
+ /**
25
+ * Check if notifications are enabled
26
+ */
27
+ private isEnabled;
28
+ /**
29
+ * Get the ntfy URL from preferences
30
+ */
31
+ private getNtfyUrl;
32
+ /**
33
+ * Send a notification for a permission request
34
+ */
35
+ sendPermissionNotification(request: PermissionRequest, sessionId?: string, summary?: string): Promise<void>;
36
+ /**
37
+ * Send a notification when a conversation ends
38
+ */
39
+ sendConversationEndNotification(streamingId: string, sessionId: string, summary?: string): Promise<void>;
40
+ /**
41
+ * Send a notification to ntfy
42
+ */
43
+ private sendNotification;
44
+ }
45
+ //# sourceMappingURL=notification-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-service.d.ts","sourceRoot":"","sources":["../../src/services/notification-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAKrD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;IACxD,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,cAAc,CAAiB;;IAQvC;;OAEG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;YACW,SAAS;IAKvB;;OAEG;YACW,UAAU;IAKxB;;OAEG;IACG,0BAA0B,CAC9B,OAAO,EAAE,iBAAiB,EAC1B,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IA0DhB;;OAEG;IACG,+BAA+B,CACnC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAuDhB;;OAEG;YACW,gBAAgB;CA8B/B"}
@@ -0,0 +1,184 @@
1
+ import { createLogger } from './logger.js';
2
+ import { ConfigService } from './config-service.js';
3
+ import { WebPushService } from './web-push-service.js';
4
+ /**
5
+ * Service for sending push notifications via ntfy.sh
6
+ */
7
+ export class NotificationService {
8
+ logger;
9
+ configService;
10
+ machineId = null;
11
+ webPushService;
12
+ constructor() {
13
+ this.logger = createLogger('NotificationService');
14
+ this.configService = ConfigService.getInstance();
15
+ this.webPushService = WebPushService.getInstance();
16
+ }
17
+ /**
18
+ * Get machine ID from config
19
+ */
20
+ getMachineId() {
21
+ if (!this.machineId) {
22
+ try {
23
+ const config = this.configService.getConfig();
24
+ this.machineId = config.machine_id;
25
+ }
26
+ catch (error) {
27
+ this.logger.error('Failed to get machine ID from config', error);
28
+ this.machineId = 'unknown';
29
+ }
30
+ }
31
+ return this.machineId;
32
+ }
33
+ /**
34
+ * Check if notifications are enabled
35
+ */
36
+ async isEnabled() {
37
+ const config = this.configService.getConfig();
38
+ return config.interface.notifications?.enabled ?? false;
39
+ }
40
+ /**
41
+ * Get the ntfy URL from preferences
42
+ */
43
+ async getNtfyUrl() {
44
+ const config = this.configService.getConfig();
45
+ return config.interface.notifications?.ntfyUrl || 'https://ntfy.sh';
46
+ }
47
+ /**
48
+ * Send a notification for a permission request
49
+ */
50
+ async sendPermissionNotification(request, sessionId, summary) {
51
+ if (!(await this.isEnabled())) {
52
+ this.logger.debug('Notifications disabled, skipping permission notification');
53
+ return;
54
+ }
55
+ try {
56
+ const machineId = this.getMachineId();
57
+ const topic = `claudia-${machineId}`;
58
+ const ntfyUrl = await this.getNtfyUrl();
59
+ const notification = {
60
+ title: 'Claudia Permission Request',
61
+ message: summary
62
+ ? `${summary} - ${request.toolName}`
63
+ : `${request.toolName} tool: ${JSON.stringify(request.toolInput).substring(0, 100)}...`,
64
+ priority: 'default',
65
+ tags: ['claudia-permission'],
66
+ sessionId: sessionId || 'unknown',
67
+ streamingId: request.streamingId,
68
+ permissionRequestId: request.id
69
+ };
70
+ // Send via ntfy
71
+ await this.sendNotification(ntfyUrl, topic, notification);
72
+ // Also broadcast via native web push (best-effort)
73
+ try {
74
+ await this.webPushService.initialize();
75
+ if (this.webPushService.getEnabled()) {
76
+ await this.webPushService.broadcast({
77
+ title: notification.title,
78
+ message: notification.message,
79
+ tag: notification.tags[0],
80
+ data: {
81
+ sessionId: notification.sessionId,
82
+ streamingId: notification.streamingId,
83
+ permissionRequestId: notification.permissionRequestId,
84
+ type: 'permission',
85
+ },
86
+ });
87
+ }
88
+ }
89
+ catch (err) {
90
+ this.logger.debug('Web push broadcast failed (non-fatal)', { error: err?.message });
91
+ }
92
+ this.logger.info('Permission notification sent', {
93
+ requestId: request.id,
94
+ toolName: request.toolName,
95
+ topic
96
+ });
97
+ }
98
+ catch (error) {
99
+ this.logger.error('Failed to send permission notification', error, {
100
+ requestId: request.id
101
+ });
102
+ }
103
+ }
104
+ /**
105
+ * Send a notification when a conversation ends
106
+ */
107
+ async sendConversationEndNotification(streamingId, sessionId, summary) {
108
+ if (!(await this.isEnabled())) {
109
+ this.logger.debug('Notifications disabled, skipping conversation end notification');
110
+ return;
111
+ }
112
+ try {
113
+ const machineId = this.getMachineId();
114
+ const topic = `claudia-${machineId}`;
115
+ const ntfyUrl = await this.getNtfyUrl();
116
+ const notification = {
117
+ title: 'Task Finished',
118
+ message: summary || 'Task completed',
119
+ priority: 'default',
120
+ tags: ['claudia-complete'],
121
+ sessionId,
122
+ streamingId
123
+ };
124
+ // Send via ntfy
125
+ await this.sendNotification(ntfyUrl, topic, notification);
126
+ // Also broadcast via native web push (best-effort)
127
+ try {
128
+ await this.webPushService.initialize();
129
+ if (this.webPushService.getEnabled()) {
130
+ await this.webPushService.broadcast({
131
+ title: notification.title,
132
+ message: notification.message,
133
+ tag: notification.tags[0],
134
+ data: {
135
+ sessionId: notification.sessionId,
136
+ streamingId: notification.streamingId,
137
+ type: 'conversation-end',
138
+ },
139
+ });
140
+ }
141
+ }
142
+ catch (err) {
143
+ this.logger.debug('Web push broadcast failed (non-fatal)', { error: err?.message });
144
+ }
145
+ this.logger.info('Conversation end notification sent', {
146
+ sessionId,
147
+ streamingId,
148
+ topic
149
+ });
150
+ }
151
+ catch (error) {
152
+ this.logger.error('Failed to send conversation end notification', error, {
153
+ sessionId,
154
+ streamingId
155
+ });
156
+ }
157
+ }
158
+ /**
159
+ * Send a notification to ntfy
160
+ */
161
+ async sendNotification(ntfyUrl, topic, notification) {
162
+ const url = `${ntfyUrl}/${topic}`;
163
+ const headers = {
164
+ 'Title': notification.title,
165
+ 'Priority': notification.priority,
166
+ 'Tags': notification.tags.join(',')
167
+ };
168
+ // Add custom headers for CUI metadata
169
+ headers['X-CUI-SessionId'] = notification.sessionId;
170
+ headers['X-CUI-StreamingId'] = notification.streamingId;
171
+ if (notification.permissionRequestId) {
172
+ headers['X-CUI-PermissionRequestId'] = notification.permissionRequestId;
173
+ }
174
+ const response = await fetch(url, {
175
+ method: 'POST',
176
+ headers,
177
+ body: notification.message
178
+ });
179
+ if (!response.ok) {
180
+ throw new Error(`Ntfy returned ${response.status}: ${await response.text()}`);
181
+ }
182
+ }
183
+ }
184
+ //# sourceMappingURL=notification-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-service.js","sourceRoot":"","sources":["../../src/services/notification-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { EventEmitter } from 'events';
2
+ import { PermissionRequest } from '../types/index.js';
3
+ import { NotificationService } from './notification-service.js';
4
+ import { ConversationStatusManager } from './conversation-status-manager.js';
5
+ import { ClaudeHistoryReader } from './claude-history-reader.js';
6
+ /**
7
+ * Service to track permission requests from Claude CLI via MCP
8
+ */
9
+ export declare class PermissionTracker extends EventEmitter {
10
+ private permissionRequests;
11
+ private notificationService?;
12
+ private conversationStatusManager?;
13
+ private historyReader?;
14
+ constructor();
15
+ /**
16
+ * Set the notification service
17
+ */
18
+ setNotificationService(service: NotificationService): void;
19
+ /**
20
+ * Set the conversation status manager
21
+ */
22
+ setConversationStatusManager(manager: ConversationStatusManager): void;
23
+ /**
24
+ * Set the history reader
25
+ */
26
+ setHistoryReader(reader: ClaudeHistoryReader): void;
27
+ /**
28
+ * Add a new permission request
29
+ */
30
+ addPermissionRequest(toolName: string, toolInput: Record<string, unknown>, streamingId?: string): PermissionRequest;
31
+ /**
32
+ * Get all permission requests
33
+ */
34
+ getAllPermissionRequests(): PermissionRequest[];
35
+ /**
36
+ * Get permission requests filtered by criteria
37
+ */
38
+ getPermissionRequests(filter?: {
39
+ streamingId?: string;
40
+ status?: 'pending' | 'approved' | 'denied';
41
+ }): PermissionRequest[];
42
+ /**
43
+ * Get a specific permission request by ID
44
+ */
45
+ getPermissionRequest(id: string): PermissionRequest | undefined;
46
+ /**
47
+ * Update permission request status (for future use when we implement approval/denial)
48
+ */
49
+ updatePermissionStatus(id: string, status: 'approved' | 'denied', options?: {
50
+ modifiedInput?: Record<string, unknown>;
51
+ denyReason?: string;
52
+ }): boolean;
53
+ /**
54
+ * Clear all permission requests (for testing)
55
+ */
56
+ clear(): void;
57
+ /**
58
+ * Get the number of permission requests
59
+ */
60
+ size(): number;
61
+ /**
62
+ * Remove all permissions for a specific streaming ID
63
+ * Used for cleanup when a conversation ends
64
+ */
65
+ removePermissionsByStreamingId(streamingId: string): number;
66
+ }
67
+ //# sourceMappingURL=permission-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-tracker.d.ts","sourceRoot":"","sources":["../../src/services/permission-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,kBAAkB,CAA6C;IACvE,OAAO,CAAC,mBAAmB,CAAC,CAAsB;IAClD,OAAO,CAAC,yBAAyB,CAAC,CAA4B;IAC9D,OAAO,CAAC,aAAa,CAAC,CAAsB;;IAM5C;;OAEG;IACH,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI1D;;OAEG;IACH,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI;IAItE;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAInD;;OAEG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,iBAAiB;IAsDnH;;OAEG;IACH,wBAAwB,IAAI,iBAAiB,EAAE;IAI/C;;OAEG;IACH,qBAAqB,CAAC,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAA;KAAE,GAAG,iBAAiB,EAAE;IAczH;;OAEG;IACH,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAI/D;;OAEG;IACH,sBAAsB,CACpB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,UAAU,GAAG,QAAQ,EAC7B,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GACzE,OAAO;IAqBV;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,MAAM;IAId;;;OAGG;IACH,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;CAsB5D"}
@@ -0,0 +1,161 @@
1
+ import { EventEmitter } from 'events';
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import { logger } from '../services/logger.js';
4
+ /**
5
+ * Service to track permission requests from Claude CLI via MCP
6
+ */
7
+ export class PermissionTracker extends EventEmitter {
8
+ permissionRequests = new Map();
9
+ notificationService;
10
+ conversationStatusManager;
11
+ historyReader;
12
+ constructor() {
13
+ super();
14
+ }
15
+ /**
16
+ * Set the notification service
17
+ */
18
+ setNotificationService(service) {
19
+ this.notificationService = service;
20
+ }
21
+ /**
22
+ * Set the conversation status manager
23
+ */
24
+ setConversationStatusManager(manager) {
25
+ this.conversationStatusManager = manager;
26
+ }
27
+ /**
28
+ * Set the history reader
29
+ */
30
+ setHistoryReader(reader) {
31
+ this.historyReader = reader;
32
+ }
33
+ /**
34
+ * Add a new permission request
35
+ */
36
+ addPermissionRequest(toolName, toolInput, streamingId) {
37
+ const id = uuidv4();
38
+ const request = {
39
+ id,
40
+ streamingId: streamingId || 'unknown',
41
+ toolName,
42
+ toolInput,
43
+ timestamp: new Date().toISOString(),
44
+ status: 'pending',
45
+ };
46
+ this.permissionRequests.set(id, request);
47
+ logger.info('Permission request added', { id, toolName, streamingId });
48
+ // Emit event for new permission request
49
+ this.emit('permission_request', request);
50
+ // Send notification if services are available
51
+ if (this.notificationService && this.conversationStatusManager && this.historyReader) {
52
+ // Get session ID from streaming ID
53
+ const sessionId = this.conversationStatusManager.getSessionId(streamingId || '');
54
+ if (sessionId) {
55
+ // Try to get conversation summary
56
+ this.historyReader.fetchConversationDirect(sessionId)
57
+ .then(({ metadata }) => {
58
+ if (this.notificationService) {
59
+ return this.notificationService.sendPermissionNotification(request, sessionId, metadata?.summary);
60
+ }
61
+ })
62
+ .catch(error => {
63
+ logger.error('Failed to fetch conversation metadata for notification', error);
64
+ // Fall back to sending without summary
65
+ if (this.notificationService) {
66
+ this.notificationService.sendPermissionNotification(request, sessionId)
67
+ .catch(err => logger.error('Failed to send permission notification', err));
68
+ }
69
+ });
70
+ }
71
+ else {
72
+ // No session ID available, send without session info
73
+ this.notificationService.sendPermissionNotification(request)
74
+ .catch(error => {
75
+ logger.error('Failed to send permission notification', error);
76
+ });
77
+ }
78
+ }
79
+ return request;
80
+ }
81
+ /**
82
+ * Get all permission requests
83
+ */
84
+ getAllPermissionRequests() {
85
+ return Array.from(this.permissionRequests.values());
86
+ }
87
+ /**
88
+ * Get permission requests filtered by criteria
89
+ */
90
+ getPermissionRequests(filter) {
91
+ let requests = Array.from(this.permissionRequests.values());
92
+ if (filter?.streamingId) {
93
+ requests = requests.filter(req => req.streamingId === filter.streamingId);
94
+ }
95
+ if (filter?.status) {
96
+ requests = requests.filter(req => req.status === filter.status);
97
+ }
98
+ return requests;
99
+ }
100
+ /**
101
+ * Get a specific permission request by ID
102
+ */
103
+ getPermissionRequest(id) {
104
+ return this.permissionRequests.get(id);
105
+ }
106
+ /**
107
+ * Update permission request status (for future use when we implement approval/denial)
108
+ */
109
+ updatePermissionStatus(id, status, options) {
110
+ const request = this.permissionRequests.get(id);
111
+ if (!request) {
112
+ logger.warn('Permission request not found', { id });
113
+ return false;
114
+ }
115
+ request.status = status;
116
+ if (status === 'approved' && options?.modifiedInput) {
117
+ request.modifiedInput = options.modifiedInput;
118
+ }
119
+ if (status === 'denied' && options?.denyReason) {
120
+ request.denyReason = options.denyReason;
121
+ }
122
+ logger.info('Permission request updated', { id, status });
123
+ this.emit('permission_updated', request);
124
+ return true;
125
+ }
126
+ /**
127
+ * Clear all permission requests (for testing)
128
+ */
129
+ clear() {
130
+ this.permissionRequests.clear();
131
+ }
132
+ /**
133
+ * Get the number of permission requests
134
+ */
135
+ size() {
136
+ return this.permissionRequests.size;
137
+ }
138
+ /**
139
+ * Remove all permissions for a specific streaming ID
140
+ * Used for cleanup when a conversation ends
141
+ */
142
+ removePermissionsByStreamingId(streamingId) {
143
+ const toRemove = [];
144
+ // Find all permissions with this streamingId
145
+ for (const [id, request] of this.permissionRequests.entries()) {
146
+ if (request.streamingId === streamingId) {
147
+ toRemove.push(id);
148
+ }
149
+ }
150
+ // Remove them
151
+ toRemove.forEach(id => this.permissionRequests.delete(id));
152
+ if (toRemove.length > 0) {
153
+ logger.info('Removed permissions for streaming session', {
154
+ streamingId,
155
+ removedCount: toRemove.length
156
+ });
157
+ }
158
+ return toRemove.length;
159
+ }
160
+ }
161
+ //# sourceMappingURL=permission-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permission-tracker.js","sourceRoot":"","sources":["../../src/services/permission-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
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 { ClaudeHistoryReader } from './claude-history-reader.js';
11
+ import { ConversationStatusManager } from './conversation-status-manager.js';
12
+ import { ToolMetricsService } from './ToolMetricsService.js';
13
+ import { SessionInfoService } from './session-info-service.js';
14
+ import { FileSystemService } from './file-system-service.js';
15
+ export type ProcessManagerMode = 'direct' | 'daemon';
16
+ export interface ProcessManagerFactoryOptions {
17
+ mode?: ProcessManagerMode;
18
+ daemonSocketPath?: string;
19
+ historyReader?: ClaudeHistoryReader;
20
+ statusTracker?: ConversationStatusManager;
21
+ toolMetricsService?: ToolMetricsService;
22
+ sessionInfoService?: SessionInfoService;
23
+ fileSystemService?: FileSystemService;
24
+ }
25
+ /**
26
+ * Unified process manager type - wraps either implementation
27
+ * and provides a consistent interface to cui-server.
28
+ */
29
+ export declare class UnifiedProcessManager extends EventEmitter {
30
+ private _direct;
31
+ private _client;
32
+ private _mode;
33
+ private _activeSessions;
34
+ constructor(mode: ProcessManagerMode);
35
+ get mode(): ProcessManagerMode;
36
+ /**
37
+ * Initialize with direct process manager
38
+ */
39
+ initDirect(manager: ClaudeProcessManager): void;
40
+ /**
41
+ * Initialize with daemon client
42
+ */
43
+ initClient(client: ProcessManagerClient): Promise<void>;
44
+ startConversation(config: Parameters<ClaudeProcessManager['startConversation']>[0]): Promise<{
45
+ streamingId: string;
46
+ systemInit: import("../types/index.js").SystemInitMessage;
47
+ }>;
48
+ stopConversation(streamingId: string): Promise<boolean>;
49
+ forceKillConversation(streamingId: string): boolean | Promise<boolean>;
50
+ /**
51
+ * Get active sessions - SYNCHRONOUS for backwards compatibility
52
+ * Uses local cache that's kept in sync via events
53
+ */
54
+ getActiveSessions(): string[];
55
+ /**
56
+ * Check if session is active - SYNCHRONOUS for backwards compatibility
57
+ */
58
+ isSessionActive(streamingId: string): boolean;
59
+ /**
60
+ * Send question answer
61
+ */
62
+ sendQuestionAnswer(streamingId: string, answer: string): boolean;
63
+ /**
64
+ * Send stdin message
65
+ */
66
+ sendStdinMessage(streamingId: string, message: string): boolean;
67
+ setMCPConfigPath(path: string): void;
68
+ setConversationStatusManager(service: ConversationStatusManager): void;
69
+ setNotificationService(service: unknown): void;
70
+ setRouterService(service: unknown): void;
71
+ /**
72
+ * Disconnect from daemon (daemon mode) or cleanup (direct mode)
73
+ * Must be called during server shutdown to prevent reconnection loops
74
+ */
75
+ disconnect(): void;
76
+ }
77
+ /**
78
+ * Create a process manager based on configuration
79
+ */
80
+ export declare function createProcessManager(options: ProcessManagerFactoryOptions): Promise<UnifiedProcessManager>;
81
+ //# sourceMappingURL=process-manager-factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-manager-factory.d.ts","sourceRoot":"","sources":["../../src/services/process-manager-factory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAM7D,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErD,MAAM,WAAW,4BAA4B;IAC3C,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,aAAa,CAAC,EAAE,yBAAyB,CAAC;IAC1C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED;;;GAGG;AACH,qBAAa,qBAAsB,SAAQ,YAAY;IACrD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,eAAe,CAA0B;gBAErC,IAAI,EAAE,kBAAkB;IAKpC,IAAI,IAAI,IAAI,kBAAkB,CAE7B;IAED;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAe/C;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BvD,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;;;;IAUlF,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU7D,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAUtE;;;OAGG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAI7B;;OAEG;IACH,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAchE;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAkB/D,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOpC,4BAA4B,CAAC,OAAO,EAAE,yBAAyB,GAAG,IAAI;IAOtE,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAO9C,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAOxC;;;OAGG;IACH,UAAU,IAAI,IAAI;CAOnB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,4BAA4B,GACpC,OAAO,CAAC,qBAAqB,CAAC,CAiChC"}