crewly 1.0.6 → 1.0.8

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 (321) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +146 -40
  3. package/config/roles/architect/prompt.md +11 -0
  4. package/config/roles/backend-developer/prompt.md +11 -0
  5. package/config/roles/designer/prompt.md +11 -0
  6. package/config/roles/developer/prompt.md +18 -4
  7. package/config/roles/frontend-developer/prompt.md +11 -0
  8. package/config/roles/fullstack-dev/prompt.md +11 -0
  9. package/config/roles/generalist/prompt.md +11 -0
  10. package/config/roles/orchestrator/prompt.md +53 -10
  11. package/config/roles/product-manager/prompt.md +18 -4
  12. package/config/roles/qa/prompt.md +11 -0
  13. package/config/roles/qa-engineer/prompt.md +11 -0
  14. package/config/roles/sales/prompt.md +11 -0
  15. package/config/roles/support/prompt.md +11 -0
  16. package/config/roles/tpm/prompt.md +11 -0
  17. package/config/skills/orchestrator/complete-task/execute.sh +1 -0
  18. package/config/templates/agent-claude-md.md +16 -0
  19. package/config/templates/research-team.json +22 -0
  20. package/config/templates/startup-team.json +22 -0
  21. package/config/templates/web-dev-team.json +22 -0
  22. package/dist/backend/backend/src/constants.d.ts +61 -1
  23. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  24. package/dist/backend/backend/src/constants.js +65 -7
  25. package/dist/backend/backend/src/constants.js.map +1 -1
  26. package/dist/backend/backend/src/controllers/slack/slack.controller.d.ts.map +1 -1
  27. package/dist/backend/backend/src/controllers/slack/slack.controller.js +7 -0
  28. package/dist/backend/backend/src/controllers/slack/slack.controller.js.map +1 -1
  29. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +7 -0
  30. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
  31. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +174 -4
  32. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
  33. package/dist/backend/backend/src/index.d.ts.map +1 -1
  34. package/dist/backend/backend/src/index.js +34 -0
  35. package/dist/backend/backend/src/index.js.map +1 -1
  36. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
  37. package/dist/backend/backend/src/routes/modules/task-management.routes.js +2 -0
  38. package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
  39. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +8 -0
  40. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  41. package/dist/backend/backend/src/services/agent/agent-registration.service.js +75 -17
  42. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  43. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +222 -0
  44. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -0
  45. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +621 -0
  46. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -0
  47. package/dist/backend/backend/src/services/index.d.ts +3 -0
  48. package/dist/backend/backend/src/services/index.d.ts.map +1 -1
  49. package/dist/backend/backend/src/services/index.js +5 -0
  50. package/dist/backend/backend/src/services/index.js.map +1 -1
  51. package/dist/backend/backend/src/services/mcp-client.d.ts +233 -0
  52. package/dist/backend/backend/src/services/mcp-client.d.ts.map +1 -0
  53. package/dist/backend/backend/src/services/mcp-client.js +297 -0
  54. package/dist/backend/backend/src/services/mcp-client.js.map +1 -0
  55. package/dist/backend/backend/src/services/mcp-server.d.ts +167 -0
  56. package/dist/backend/backend/src/services/mcp-server.d.ts.map +1 -0
  57. package/dist/backend/backend/src/services/mcp-server.js +586 -0
  58. package/dist/backend/backend/src/services/mcp-server.js.map +1 -0
  59. package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts +2 -0
  60. package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
  61. package/dist/backend/backend/src/services/messaging/message-queue.service.js +6 -1
  62. package/dist/backend/backend/src/services/messaging/message-queue.service.js.map +1 -1
  63. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +10 -0
  64. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  65. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +94 -38
  66. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  67. package/dist/backend/backend/src/services/quality/index.d.ts +1 -0
  68. package/dist/backend/backend/src/services/quality/index.d.ts.map +1 -1
  69. package/dist/backend/backend/src/services/quality/index.js +1 -0
  70. package/dist/backend/backend/src/services/quality/index.js.map +1 -1
  71. package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts +84 -0
  72. package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts.map +1 -0
  73. package/dist/backend/backend/src/services/quality/task-output-validator.service.js +163 -0
  74. package/dist/backend/backend/src/services/quality/task-output-validator.service.js.map +1 -0
  75. package/dist/backend/backend/src/services/runtime-adapter.d.ts +234 -0
  76. package/dist/backend/backend/src/services/runtime-adapter.d.ts.map +1 -0
  77. package/dist/backend/backend/src/services/runtime-adapter.js +180 -0
  78. package/dist/backend/backend/src/services/runtime-adapter.js.map +1 -0
  79. package/dist/backend/backend/src/services/slack/slack-credentials.service.d.ts +33 -0
  80. package/dist/backend/backend/src/services/slack/slack-credentials.service.d.ts.map +1 -0
  81. package/dist/backend/backend/src/services/slack/slack-credentials.service.js +103 -0
  82. package/dist/backend/backend/src/services/slack/slack-credentials.service.js.map +1 -0
  83. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts +9 -1
  84. package/dist/backend/backend/src/services/slack/slack-initializer.d.ts.map +1 -1
  85. package/dist/backend/backend/src/services/slack/slack-initializer.js +31 -2
  86. package/dist/backend/backend/src/services/slack/slack-initializer.js.map +1 -1
  87. package/dist/backend/backend/src/types/event-bus.types.d.ts +2 -2
  88. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  89. package/dist/backend/backend/src/types/event-bus.types.js +2 -0
  90. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  91. package/dist/backend/backend/src/types/index.d.ts +1 -0
  92. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  93. package/dist/backend/backend/src/types/index.js +2 -0
  94. package/dist/backend/backend/src/types/index.js.map +1 -1
  95. package/dist/backend/backend/src/types/messaging.types.d.ts +9 -6
  96. package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
  97. package/dist/backend/backend/src/types/messaging.types.js +10 -3
  98. package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
  99. package/dist/backend/backend/src/types/task-output.types.d.ts +78 -0
  100. package/dist/backend/backend/src/types/task-output.types.d.ts.map +1 -0
  101. package/dist/backend/backend/src/types/task-output.types.js +27 -0
  102. package/dist/backend/backend/src/types/task-output.types.js.map +1 -0
  103. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +13 -0
  104. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  105. package/dist/backend/backend/src/websocket/terminal.gateway.js +12 -0
  106. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  107. package/dist/cli/backend/src/constants.d.ts +751 -0
  108. package/dist/cli/backend/src/constants.d.ts.map +1 -0
  109. package/dist/cli/backend/src/constants.js +550 -0
  110. package/dist/cli/backend/src/constants.js.map +1 -0
  111. package/dist/cli/backend/src/models/Project.d.ts +18 -0
  112. package/dist/cli/backend/src/models/Project.d.ts.map +1 -0
  113. package/dist/cli/backend/src/models/Project.js +70 -0
  114. package/dist/cli/backend/src/models/Project.js.map +1 -0
  115. package/dist/cli/backend/src/models/ScheduledMessage.d.ts +27 -0
  116. package/dist/cli/backend/src/models/ScheduledMessage.d.ts.map +1 -0
  117. package/dist/cli/backend/src/models/ScheduledMessage.js +50 -0
  118. package/dist/cli/backend/src/models/ScheduledMessage.js.map +1 -0
  119. package/dist/cli/backend/src/models/Team.d.ts +20 -0
  120. package/dist/cli/backend/src/models/Team.d.ts.map +1 -0
  121. package/dist/cli/backend/src/models/Team.js +120 -0
  122. package/dist/cli/backend/src/models/Team.js.map +1 -0
  123. package/dist/cli/backend/src/models/Ticket.d.ts +24 -0
  124. package/dist/cli/backend/src/models/Ticket.d.ts.map +1 -0
  125. package/dist/cli/backend/src/models/Ticket.js +102 -0
  126. package/dist/cli/backend/src/models/Ticket.js.map +1 -0
  127. package/dist/cli/backend/src/models/index.d.ts +5 -0
  128. package/dist/cli/backend/src/models/index.d.ts.map +1 -0
  129. package/dist/cli/backend/src/models/index.js +5 -0
  130. package/dist/cli/backend/src/models/index.js.map +1 -0
  131. package/dist/cli/backend/src/services/core/config.service.d.ts +91 -0
  132. package/dist/cli/backend/src/services/core/config.service.d.ts.map +1 -0
  133. package/dist/cli/backend/src/services/core/config.service.js +246 -0
  134. package/dist/cli/backend/src/services/core/config.service.js.map +1 -0
  135. package/dist/cli/backend/src/services/core/logger.service.d.ts +70 -0
  136. package/dist/cli/backend/src/services/core/logger.service.d.ts.map +1 -0
  137. package/dist/cli/backend/src/services/core/logger.service.js +350 -0
  138. package/dist/cli/backend/src/services/core/logger.service.js.map +1 -0
  139. package/dist/cli/backend/src/services/core/storage.service.d.ts +269 -0
  140. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -0
  141. package/dist/cli/backend/src/services/core/storage.service.js +1406 -0
  142. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -0
  143. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts +92 -0
  144. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts.map +1 -0
  145. package/dist/cli/backend/src/services/core/teams-backup.service.js +120 -0
  146. package/dist/cli/backend/src/services/core/teams-backup.service.js.map +1 -0
  147. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +125 -0
  148. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -0
  149. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +247 -0
  150. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -0
  151. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts +153 -0
  152. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts.map +1 -0
  153. package/dist/cli/backend/src/services/knowledge/knowledge.service.js +409 -0
  154. package/dist/cli/backend/src/services/knowledge/knowledge.service.js.map +1 -0
  155. package/dist/cli/backend/src/services/mcp-server.d.ts +167 -0
  156. package/dist/cli/backend/src/services/mcp-server.d.ts.map +1 -0
  157. package/dist/cli/backend/src/services/mcp-server.js +586 -0
  158. package/dist/cli/backend/src/services/mcp-server.js.map +1 -0
  159. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts +259 -0
  160. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts.map +1 -0
  161. package/dist/cli/backend/src/services/memory/agent-memory.service.js +539 -0
  162. package/dist/cli/backend/src/services/memory/agent-memory.service.js.map +1 -0
  163. package/dist/cli/backend/src/services/memory/memory.service.d.ts +306 -0
  164. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -0
  165. package/dist/cli/backend/src/services/memory/memory.service.js +517 -0
  166. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -0
  167. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +252 -0
  168. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -0
  169. package/dist/cli/backend/src/services/memory/project-memory.service.js +600 -0
  170. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -0
  171. package/dist/cli/backend/src/types/auto-assign.types.d.ts +271 -0
  172. package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +1 -0
  173. package/dist/cli/backend/src/types/auto-assign.types.js +136 -0
  174. package/dist/cli/backend/src/types/auto-assign.types.js.map +1 -0
  175. package/dist/cli/backend/src/types/budget.types.d.ts +217 -0
  176. package/dist/cli/backend/src/types/budget.types.d.ts.map +1 -0
  177. package/dist/cli/backend/src/types/budget.types.js +82 -0
  178. package/dist/cli/backend/src/types/budget.types.js.map +1 -0
  179. package/dist/cli/backend/src/types/chat.types.d.ts +550 -0
  180. package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -0
  181. package/dist/cli/backend/src/types/chat.types.js +743 -0
  182. package/dist/cli/backend/src/types/chat.types.js.map +1 -0
  183. package/dist/cli/backend/src/types/continuation.types.d.ts +237 -0
  184. package/dist/cli/backend/src/types/continuation.types.d.ts.map +1 -0
  185. package/dist/cli/backend/src/types/continuation.types.js +10 -0
  186. package/dist/cli/backend/src/types/continuation.types.js.map +1 -0
  187. package/dist/cli/backend/src/types/index.d.ts +164 -0
  188. package/dist/cli/backend/src/types/index.d.ts.map +1 -0
  189. package/dist/cli/backend/src/types/index.js +25 -0
  190. package/dist/cli/backend/src/types/index.js.map +1 -0
  191. package/dist/cli/backend/src/types/knowledge.types.d.ts +195 -0
  192. package/dist/cli/backend/src/types/knowledge.types.d.ts.map +1 -0
  193. package/dist/cli/backend/src/types/knowledge.types.js +38 -0
  194. package/dist/cli/backend/src/types/knowledge.types.js.map +1 -0
  195. package/dist/cli/backend/src/types/memory.types.d.ts +587 -0
  196. package/dist/cli/backend/src/types/memory.types.d.ts.map +1 -0
  197. package/dist/cli/backend/src/types/memory.types.js +47 -0
  198. package/dist/cli/backend/src/types/memory.types.js.map +1 -0
  199. package/dist/cli/backend/src/types/quality-gate.types.d.ts +171 -0
  200. package/dist/cli/backend/src/types/quality-gate.types.d.ts.map +1 -0
  201. package/dist/cli/backend/src/types/quality-gate.types.js +42 -0
  202. package/dist/cli/backend/src/types/quality-gate.types.js.map +1 -0
  203. package/dist/cli/backend/src/types/role.types.d.ts +260 -0
  204. package/dist/cli/backend/src/types/role.types.d.ts.map +1 -0
  205. package/dist/cli/backend/src/types/role.types.js +238 -0
  206. package/dist/cli/backend/src/types/role.types.js.map +1 -0
  207. package/dist/cli/backend/src/types/scheduler.types.d.ts +254 -0
  208. package/dist/cli/backend/src/types/scheduler.types.d.ts.map +1 -0
  209. package/dist/cli/backend/src/types/scheduler.types.js +32 -0
  210. package/dist/cli/backend/src/types/scheduler.types.js.map +1 -0
  211. package/dist/cli/backend/src/types/settings.types.d.ts +178 -0
  212. package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -0
  213. package/dist/cli/backend/src/types/settings.types.js +206 -0
  214. package/dist/cli/backend/src/types/settings.types.js.map +1 -0
  215. package/dist/cli/backend/src/types/skill.types.d.ts +515 -0
  216. package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -0
  217. package/dist/cli/backend/src/types/skill.types.js +481 -0
  218. package/dist/cli/backend/src/types/skill.types.js.map +1 -0
  219. package/dist/cli/backend/src/types/sop.types.d.ts +224 -0
  220. package/dist/cli/backend/src/types/sop.types.d.ts.map +1 -0
  221. package/dist/cli/backend/src/types/sop.types.js +85 -0
  222. package/dist/cli/backend/src/types/sop.types.js.map +1 -0
  223. package/dist/cli/backend/src/types/task-output.types.d.ts +78 -0
  224. package/dist/cli/backend/src/types/task-output.types.d.ts.map +1 -0
  225. package/dist/cli/backend/src/types/task-output.types.js +27 -0
  226. package/dist/cli/backend/src/types/task-output.types.js.map +1 -0
  227. package/dist/cli/backend/src/utils/file-io.utils.d.ts +102 -0
  228. package/dist/cli/backend/src/utils/file-io.utils.d.ts.map +1 -0
  229. package/dist/cli/backend/src/utils/file-io.utils.js +214 -0
  230. package/dist/cli/backend/src/utils/file-io.utils.js.map +1 -0
  231. package/dist/cli/backend/src/utils/terminal-output.utils.d.ts +54 -0
  232. package/dist/cli/backend/src/utils/terminal-output.utils.d.ts.map +1 -0
  233. package/dist/cli/backend/src/utils/terminal-output.utils.js +97 -0
  234. package/dist/cli/backend/src/utils/terminal-output.utils.js.map +1 -0
  235. package/dist/cli/cli/src/commands/mcp-server.d.ts +38 -0
  236. package/dist/cli/cli/src/commands/mcp-server.d.ts.map +1 -0
  237. package/dist/cli/cli/src/commands/mcp-server.js +49 -0
  238. package/dist/cli/cli/src/commands/mcp-server.js.map +1 -0
  239. package/dist/cli/cli/src/commands/onboard.d.ts +61 -7
  240. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  241. package/dist/cli/cli/src/commands/onboard.js +192 -19
  242. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  243. package/dist/cli/cli/src/commands/publish.d.ts +27 -0
  244. package/dist/cli/cli/src/commands/publish.d.ts.map +1 -0
  245. package/dist/cli/cli/src/commands/publish.js +69 -0
  246. package/dist/cli/cli/src/commands/publish.js.map +1 -0
  247. package/dist/cli/cli/src/commands/start.d.ts.map +1 -1
  248. package/dist/cli/cli/src/commands/start.js +12 -2
  249. package/dist/cli/cli/src/commands/start.js.map +1 -1
  250. package/dist/cli/cli/src/index.js +14 -0
  251. package/dist/cli/cli/src/index.js.map +1 -1
  252. package/dist/cli/cli/src/utils/archive-creator.d.ts +82 -0
  253. package/dist/cli/cli/src/utils/archive-creator.d.ts.map +1 -0
  254. package/dist/cli/cli/src/utils/archive-creator.js +105 -0
  255. package/dist/cli/cli/src/utils/archive-creator.js.map +1 -0
  256. package/dist/cli/cli/src/utils/package-validator.d.ts +62 -0
  257. package/dist/cli/cli/src/utils/package-validator.d.ts.map +1 -0
  258. package/dist/cli/cli/src/utils/package-validator.js +122 -0
  259. package/dist/cli/cli/src/utils/package-validator.js.map +1 -0
  260. package/dist/cli/cli/src/utils/process-cleanup.d.ts +15 -0
  261. package/dist/cli/cli/src/utils/process-cleanup.d.ts.map +1 -0
  262. package/dist/cli/cli/src/utils/process-cleanup.js +76 -0
  263. package/dist/cli/cli/src/utils/process-cleanup.js.map +1 -0
  264. package/dist/cli/cli/src/utils/templates.d.ts +71 -0
  265. package/dist/cli/cli/src/utils/templates.d.ts.map +1 -0
  266. package/dist/cli/cli/src/utils/templates.js +91 -0
  267. package/dist/cli/cli/src/utils/templates.js.map +1 -0
  268. package/frontend/dist/assets/{index-523c7fce.js → index-68d1eb5a.js} +71 -71
  269. package/frontend/dist/assets/{index-4c050f52.css → index-c5043a83.css} +1 -1
  270. package/frontend/dist/assets/nunito-cyrillic-400-normal-e44e669f.woff2 +0 -0
  271. package/frontend/dist/assets/nunito-cyrillic-400-normal-ff8e8bdd.woff +0 -0
  272. package/frontend/dist/assets/nunito-cyrillic-500-normal-2159679b.woff +0 -0
  273. package/frontend/dist/assets/nunito-cyrillic-500-normal-61a3b80e.woff2 +0 -0
  274. package/frontend/dist/assets/nunito-cyrillic-600-normal-ac046097.woff +0 -0
  275. package/frontend/dist/assets/nunito-cyrillic-600-normal-e61eb97b.woff2 +0 -0
  276. package/frontend/dist/assets/nunito-cyrillic-700-normal-8fcefcc9.woff2 +0 -0
  277. package/frontend/dist/assets/nunito-cyrillic-700-normal-b9684104.woff +0 -0
  278. package/frontend/dist/assets/nunito-cyrillic-800-normal-40253beb.woff +0 -0
  279. package/frontend/dist/assets/nunito-cyrillic-800-normal-d80292de.woff2 +0 -0
  280. package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-20d73ae7.woff2 +0 -0
  281. package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-d48c37c9.woff +0 -0
  282. package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-16197abd.woff +0 -0
  283. package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-9dcfe9b5.woff2 +0 -0
  284. package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-d53e9851.woff2 +0 -0
  285. package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-e3d0201f.woff +0 -0
  286. package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-5936f6ac.woff2 +0 -0
  287. package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-c8c02775.woff +0 -0
  288. package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-217b8f51.woff +0 -0
  289. package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-796cf7bd.woff2 +0 -0
  290. package/frontend/dist/assets/nunito-latin-400-normal-a5906e15.woff2 +0 -0
  291. package/frontend/dist/assets/nunito-latin-400-normal-b51e7635.woff +0 -0
  292. package/frontend/dist/assets/nunito-latin-500-normal-23ae3083.woff2 +0 -0
  293. package/frontend/dist/assets/nunito-latin-500-normal-be14dbc6.woff +0 -0
  294. package/frontend/dist/assets/nunito-latin-600-normal-06a9c8b3.woff +0 -0
  295. package/frontend/dist/assets/nunito-latin-600-normal-45f437de.woff2 +0 -0
  296. package/frontend/dist/assets/nunito-latin-700-normal-ce9107dc.woff +0 -0
  297. package/frontend/dist/assets/nunito-latin-700-normal-fa89300b.woff2 +0 -0
  298. package/frontend/dist/assets/nunito-latin-800-normal-0ca02785.woff +0 -0
  299. package/frontend/dist/assets/nunito-latin-800-normal-2363d3ed.woff2 +0 -0
  300. package/frontend/dist/assets/nunito-latin-ext-400-normal-67250a41.woff2 +0 -0
  301. package/frontend/dist/assets/nunito-latin-ext-400-normal-d7e2415e.woff +0 -0
  302. package/frontend/dist/assets/nunito-latin-ext-500-normal-06f35d1c.woff +0 -0
  303. package/frontend/dist/assets/nunito-latin-ext-500-normal-343e7adc.woff2 +0 -0
  304. package/frontend/dist/assets/nunito-latin-ext-600-normal-5a8efd17.woff +0 -0
  305. package/frontend/dist/assets/nunito-latin-ext-600-normal-a7ba5f4f.woff2 +0 -0
  306. package/frontend/dist/assets/nunito-latin-ext-700-normal-0a4e4a02.woff2 +0 -0
  307. package/frontend/dist/assets/nunito-latin-ext-700-normal-0c607961.woff +0 -0
  308. package/frontend/dist/assets/nunito-latin-ext-800-normal-39f54b55.woff2 +0 -0
  309. package/frontend/dist/assets/nunito-latin-ext-800-normal-466d0211.woff +0 -0
  310. package/frontend/dist/assets/nunito-vietnamese-400-normal-2a755616.woff2 +0 -0
  311. package/frontend/dist/assets/nunito-vietnamese-400-normal-9c01ea9f.woff +0 -0
  312. package/frontend/dist/assets/nunito-vietnamese-500-normal-452e5e08.woff +0 -0
  313. package/frontend/dist/assets/nunito-vietnamese-500-normal-dc98d965.woff2 +0 -0
  314. package/frontend/dist/assets/nunito-vietnamese-600-normal-2ffbb85f.woff +0 -0
  315. package/frontend/dist/assets/nunito-vietnamese-600-normal-cf95b95d.woff2 +0 -0
  316. package/frontend/dist/assets/nunito-vietnamese-700-normal-0e29c28c.woff2 +0 -0
  317. package/frontend/dist/assets/nunito-vietnamese-700-normal-7793b75e.woff +0 -0
  318. package/frontend/dist/assets/nunito-vietnamese-800-normal-5baf507e.woff +0 -0
  319. package/frontend/dist/assets/nunito-vietnamese-800-normal-fac6740e.woff2 +0 -0
  320. package/frontend/dist/index.html +2 -2
  321. package/package.json +15 -5
@@ -0,0 +1,743 @@
1
+ /**
2
+ * Chat Types Module
3
+ *
4
+ * Type definitions for the chat-based dashboard. Provides a conversational
5
+ * interface with the Orchestrator, transforming raw terminal output into
6
+ * clean, formatted chat messages.
7
+ *
8
+ * @module types/chat
9
+ */
10
+ import { TERMINAL_FORMATTING_CONSTANTS } from '../constants.js';
11
+ import { stripAnsiCodes } from '../utils/terminal-output.utils.js';
12
+ // =============================================================================
13
+ // Enums and Constants
14
+ // =============================================================================
15
+ /**
16
+ * Valid sender types for chat messages
17
+ */
18
+ export const CHAT_SENDER_TYPES = ['user', 'orchestrator', 'agent', 'system'];
19
+ /**
20
+ * Valid content types for chat messages
21
+ */
22
+ export const CHAT_CONTENT_TYPES = [
23
+ 'text',
24
+ 'status',
25
+ 'task',
26
+ 'error',
27
+ 'system',
28
+ 'code',
29
+ 'markdown',
30
+ ];
31
+ /**
32
+ * Valid message status values
33
+ */
34
+ export const CHAT_MESSAGE_STATUSES = ['sending', 'sent', 'delivered', 'error'];
35
+ /**
36
+ * Chat-related constants
37
+ */
38
+ export const CHAT_CONSTANTS = {
39
+ /** Default limits */
40
+ DEFAULTS: {
41
+ /** Default message limit for pagination */
42
+ MESSAGE_LIMIT: 100,
43
+ /** Default conversation limit for pagination */
44
+ CONVERSATION_LIMIT: 50,
45
+ /** Maximum content length for last message preview */
46
+ PREVIEW_LENGTH: 100,
47
+ },
48
+ /** Response extraction patterns */
49
+ PATTERNS: {
50
+ /** Pattern names */
51
+ EXPLICIT: 'explicit',
52
+ CHAT: 'chat',
53
+ CODEBLOCK: 'codeblock',
54
+ },
55
+ };
56
+ /**
57
+ * Valid Slack delivery statuses for NOTIFY reconciliation
58
+ */
59
+ export const SLACK_DELIVERY_STATUSES = ['pending', 'delivered', 'failed'];
60
+ /**
61
+ * Urgency levels for notifications
62
+ */
63
+ export const NOTIFY_URGENCY_LEVELS = ['low', 'normal', 'high', 'critical'];
64
+ /**
65
+ * Check if a value is a valid NotifyPayload
66
+ *
67
+ * Validates that the payload has a required `message` string field
68
+ * and that optional fields have correct types when present.
69
+ *
70
+ * @param value - Value to check
71
+ * @returns True if value is a valid NotifyPayload
72
+ */
73
+ export function isValidNotifyPayload(value) {
74
+ if (!value || typeof value !== 'object') {
75
+ return false;
76
+ }
77
+ const payload = value;
78
+ // message is required and must be a non-empty string
79
+ if (typeof payload.message !== 'string' || !payload.message.trim()) {
80
+ return false;
81
+ }
82
+ // Optional string fields
83
+ const optionalStringFields = ['conversationId', 'channelId', 'threadTs', 'type', 'title'];
84
+ for (const field of optionalStringFields) {
85
+ if (payload[field] !== undefined && typeof payload[field] !== 'string') {
86
+ return false;
87
+ }
88
+ }
89
+ // urgency must be a valid level if present
90
+ if (payload.urgency !== undefined) {
91
+ if (typeof payload.urgency !== 'string' || !NOTIFY_URGENCY_LEVELS.includes(payload.urgency)) {
92
+ return false;
93
+ }
94
+ }
95
+ return true;
96
+ }
97
+ /** Known header keys that can appear in NOTIFY blocks */
98
+ const KNOWN_HEADER_KEYS = new Set([
99
+ 'conversationId', 'channelId', 'threadTs', 'type', 'title', 'urgency',
100
+ ]);
101
+ /**
102
+ * TUI box-drawing and border characters used by Gemini CLI and other TUI tools.
103
+ * Matches common Unicode box-drawing chars and ASCII pipe characters.
104
+ */
105
+ const TUI_BORDER_CHARS = /[│┃┆┇┊┋╎╏║|]/;
106
+ /**
107
+ * Strip TUI box-drawing border characters from content lines.
108
+ *
109
+ * Gemini CLI wraps terminal output in a TUI with box-drawing borders
110
+ * (│, ┃, |, etc.) that corrupt header parsing and leak into message bodies.
111
+ * This function removes leading/trailing border chars and associated whitespace
112
+ * from each line, plus removes pure border/decoration lines (─, ┌, └, etc.).
113
+ *
114
+ * @param content - Content that may contain TUI border artifacts
115
+ * @returns Content with TUI borders stripped from each line
116
+ */
117
+ function stripTuiBorders(content) {
118
+ return content
119
+ .split('\n')
120
+ .map((line) => {
121
+ // Preserve --- separator lines (used for header-body split)
122
+ if (/^\s*---\s*$/.test(line)) {
123
+ return '---';
124
+ }
125
+ // Skip pure decoration lines (box corners, horizontal rules)
126
+ // that contain only box-drawing characters, not regular dashes
127
+ if (/^[\s│┃┆┇┊┋╎╏║─━┄┅┈┉╌╍═┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬╭╮╰╯]+$/.test(line)) {
128
+ return '';
129
+ }
130
+ // Strip leading border chars and adjacent whitespace, and trailing whitespace + border chars.
131
+ // Only strip whitespace that's adjacent to an actual border character to avoid
132
+ // stripping meaningful whitespace from PTY-wrapped JSON continuation lines.
133
+ return line
134
+ .replace(/^[│┃┆┇┊┋╎╏║|]+\s*/, '')
135
+ .replace(/\s*[│┃┆┇┊┋╎╏║|]+$/, '');
136
+ })
137
+ .join('\n');
138
+ }
139
+ /**
140
+ * Attempt to parse headers from content where a blank line is used as separator
141
+ * instead of `---`. This handles the common LLM behavior of omitting the `---`.
142
+ *
143
+ * Only activates if the first line matches a known header key pattern.
144
+ *
145
+ * @param cleaned - ANSI-stripped, trimmed content
146
+ * @returns Object with headers and body strings, or null if not header-like
147
+ */
148
+ function parseHeadersWithBlankLineSeparator(cleaned) {
149
+ // Check if first line looks like a known header
150
+ const firstNewline = cleaned.indexOf('\n');
151
+ if (firstNewline === -1)
152
+ return null;
153
+ const firstLine = cleaned.slice(0, firstNewline).trim();
154
+ const colonIdx = firstLine.indexOf(':');
155
+ if (colonIdx === -1)
156
+ return null;
157
+ const firstKey = firstLine.slice(0, colonIdx).trim();
158
+ if (!KNOWN_HEADER_KEYS.has(firstKey))
159
+ return null;
160
+ // Split on first blank line (two consecutive newlines)
161
+ const blankMatch = cleaned.match(/^([\s\S]*?)\n\s*\n([\s\S]*)$/);
162
+ if (!blankMatch)
163
+ return null;
164
+ const headers = blankMatch[1].trim();
165
+ const body = blankMatch[2].trim();
166
+ if (!body)
167
+ return null;
168
+ return { headers, body };
169
+ }
170
+ /**
171
+ * Parse raw content from a [NOTIFY]...[/NOTIFY] block into a NotifyPayload.
172
+ *
173
+ * Supports three formats:
174
+ * 1. **Header+body with `---`** (preferred): key-value headers before a `---` separator,
175
+ * with the message body after it. Headers are short (~25 chars), so they are
176
+ * never corrupted by PTY line-wrapping.
177
+ * 2. **Header+body with blank line** (fallback): same as above but with a blank
178
+ * line instead of `---`. Activated only when the first line is a known header.
179
+ * 3. **Legacy JSON** (fallback): if the content starts with `{`, it is parsed as
180
+ * JSON with PTY artifact cleanup for backward compatibility.
181
+ *
182
+ * @param raw - Raw content between [NOTIFY] and [/NOTIFY] markers
183
+ * @returns Parsed NotifyPayload or null if content is invalid
184
+ *
185
+ * @example
186
+ * ```typescript
187
+ * // Header+body format
188
+ * const payload = parseNotifyContent(
189
+ * 'conversationId: conv-abc\ntype: task_completed\n---\n## Done\nTask finished.'
190
+ * );
191
+ * // => { message: '## Done\nTask finished.', conversationId: 'conv-abc', type: 'task_completed' }
192
+ *
193
+ * // Legacy JSON format (auto-detected)
194
+ * const legacy = parseNotifyContent('{"message":"Hello","conversationId":"conv-1"}');
195
+ * // => { message: 'Hello', conversationId: 'conv-1' }
196
+ * ```
197
+ */
198
+ export function parseNotifyContent(raw) {
199
+ // Strip ANSI escape sequences using the canonical utility, then strip
200
+ // TUI box-drawing borders (Gemini CLI wraps output in │...│ borders)
201
+ const cleaned = stripTuiBorders(stripAnsiCodes(raw)).trim();
202
+ if (!cleaned) {
203
+ return null;
204
+ }
205
+ // JSON fallback for transition period
206
+ if (cleaned.startsWith('{')) {
207
+ return parseLegacyJsonNotify(cleaned);
208
+ }
209
+ // Split on --- separator line (separator may be followed by content or end of string)
210
+ // The \n before --- is optional to handle content that starts directly with ---
211
+ const sepMatch = cleaned.match(/^([\s\S]*?)(?:^|\n)---(?:\n([\s\S]*))?$/);
212
+ let headerSection;
213
+ let body;
214
+ if (sepMatch) {
215
+ headerSection = sepMatch[1].trim();
216
+ body = (sepMatch[2] || '').trim();
217
+ }
218
+ else {
219
+ // Fallback: LLMs sometimes use a blank line instead of ---
220
+ // If the content starts with known header-like lines, split on first blank line
221
+ const blankLineResult = parseHeadersWithBlankLineSeparator(cleaned);
222
+ if (blankLineResult) {
223
+ headerSection = blankLineResult.headers;
224
+ body = blankLineResult.body;
225
+ }
226
+ else {
227
+ // No headers — entire content is the message
228
+ const msg = cleaned.trim();
229
+ return msg ? { message: msg } : null;
230
+ }
231
+ }
232
+ if (!body) {
233
+ return null;
234
+ }
235
+ const payload = { message: body };
236
+ for (const line of headerSection.split('\n')) {
237
+ const colonIdx = line.indexOf(':');
238
+ if (colonIdx === -1)
239
+ continue;
240
+ const key = line.slice(0, colonIdx).trim();
241
+ const value = line.slice(colonIdx + 1).trim();
242
+ if (!value)
243
+ continue;
244
+ switch (key) {
245
+ case 'conversationId':
246
+ payload.conversationId = value;
247
+ break;
248
+ case 'channelId':
249
+ payload.channelId = value;
250
+ break;
251
+ case 'threadTs':
252
+ payload.threadTs = value;
253
+ break;
254
+ case 'type':
255
+ payload.type = value;
256
+ break;
257
+ case 'title':
258
+ payload.title = value;
259
+ break;
260
+ case 'urgency':
261
+ if (NOTIFY_URGENCY_LEVELS.includes(value)) {
262
+ payload.urgency = value;
263
+ }
264
+ break;
265
+ }
266
+ }
267
+ return payload;
268
+ }
269
+ /**
270
+ * Parse legacy JSON notify content with PTY artifact cleanup.
271
+ *
272
+ * Cleans terminal line-wrapping artifacts (newlines, padding spaces, orphaned
273
+ * ANSI sequences) before parsing as JSON, then validates via isValidNotifyPayload.
274
+ *
275
+ * @param cleaned - Pre-cleaned content that starts with '{'
276
+ * @returns Parsed NotifyPayload or null if parsing/validation fails
277
+ */
278
+ function parseLegacyJsonNotify(cleaned) {
279
+ const jsonCleaned = cleaned
280
+ .replace(/[\r\n]+\s*/g, '') // remove newlines and trailing padding (PTY indent)
281
+ .replace(/\s{2,}/g, ' '); // collapse remaining multi-space runs
282
+ try {
283
+ const parsed = JSON.parse(jsonCleaned);
284
+ if (!isValidNotifyPayload(parsed)) {
285
+ return null;
286
+ }
287
+ return parsed;
288
+ }
289
+ catch {
290
+ return null;
291
+ }
292
+ }
293
+ // =============================================================================
294
+ // Type Guards
295
+ // =============================================================================
296
+ /**
297
+ * Check if a value is a valid sender type
298
+ *
299
+ * @param value - Value to check
300
+ * @returns True if value is a valid ChatSenderType
301
+ */
302
+ export function isValidSenderType(value) {
303
+ return CHAT_SENDER_TYPES.includes(value);
304
+ }
305
+ /**
306
+ * Check if a value is a valid content type
307
+ *
308
+ * @param value - Value to check
309
+ * @returns True if value is a valid ChatContentType
310
+ */
311
+ export function isValidContentType(value) {
312
+ return CHAT_CONTENT_TYPES.includes(value);
313
+ }
314
+ /**
315
+ * Check if a value is a valid message status
316
+ *
317
+ * @param value - Value to check
318
+ * @returns True if value is a valid ChatMessageStatus
319
+ */
320
+ export function isValidMessageStatus(value) {
321
+ return CHAT_MESSAGE_STATUSES.includes(value);
322
+ }
323
+ /**
324
+ * Check if an object is a valid ChatSender
325
+ *
326
+ * @param value - Value to check
327
+ * @returns True if value is a valid ChatSender object
328
+ */
329
+ export function isValidChatSender(value) {
330
+ if (!value || typeof value !== 'object') {
331
+ return false;
332
+ }
333
+ const sender = value;
334
+ if (typeof sender.type !== 'string' || !isValidSenderType(sender.type)) {
335
+ return false;
336
+ }
337
+ if (sender.id !== undefined && typeof sender.id !== 'string') {
338
+ return false;
339
+ }
340
+ if (sender.name !== undefined && typeof sender.name !== 'string') {
341
+ return false;
342
+ }
343
+ if (sender.role !== undefined && typeof sender.role !== 'string') {
344
+ return false;
345
+ }
346
+ return true;
347
+ }
348
+ /**
349
+ * Check if an object is a valid ChatMessage
350
+ *
351
+ * @param value - Value to check
352
+ * @returns True if value is a valid ChatMessage object
353
+ */
354
+ export function isValidChatMessage(value) {
355
+ if (!value || typeof value !== 'object') {
356
+ return false;
357
+ }
358
+ const message = value;
359
+ if (typeof message.id !== 'string' || !message.id) {
360
+ return false;
361
+ }
362
+ if (typeof message.conversationId !== 'string' || !message.conversationId) {
363
+ return false;
364
+ }
365
+ if (!isValidChatSender(message.from)) {
366
+ return false;
367
+ }
368
+ if (typeof message.content !== 'string') {
369
+ return false;
370
+ }
371
+ if (typeof message.contentType !== 'string' || !isValidContentType(message.contentType)) {
372
+ return false;
373
+ }
374
+ if (typeof message.status !== 'string' || !isValidMessageStatus(message.status)) {
375
+ return false;
376
+ }
377
+ if (typeof message.timestamp !== 'string') {
378
+ return false;
379
+ }
380
+ return true;
381
+ }
382
+ /**
383
+ * Check if an object is a valid ChatConversation
384
+ *
385
+ * @param value - Value to check
386
+ * @returns True if value is a valid ChatConversation object
387
+ */
388
+ export function isValidChatConversation(value) {
389
+ if (!value || typeof value !== 'object') {
390
+ return false;
391
+ }
392
+ const conv = value;
393
+ if (typeof conv.id !== 'string' || !conv.id) {
394
+ return false;
395
+ }
396
+ if (!Array.isArray(conv.participantIds)) {
397
+ return false;
398
+ }
399
+ if (typeof conv.createdAt !== 'string') {
400
+ return false;
401
+ }
402
+ if (typeof conv.updatedAt !== 'string') {
403
+ return false;
404
+ }
405
+ if (typeof conv.isArchived !== 'boolean') {
406
+ return false;
407
+ }
408
+ if (typeof conv.messageCount !== 'number') {
409
+ return false;
410
+ }
411
+ return true;
412
+ }
413
+ // =============================================================================
414
+ // Utility Functions
415
+ // =============================================================================
416
+ /**
417
+ * Generate a unique ID for chat entities
418
+ *
419
+ * @returns A unique identifier string
420
+ */
421
+ export function generateChatId() {
422
+ return crypto.randomUUID();
423
+ }
424
+ /**
425
+ * Create a chat message with defaults
426
+ *
427
+ * @param input - Partial message input with required fields
428
+ * @returns A complete ChatMessage object
429
+ *
430
+ * @example
431
+ * ```typescript
432
+ * const message = createChatMessage({
433
+ * conversationId: 'conv-1',
434
+ * content: 'Hello!',
435
+ * from: { type: 'user' },
436
+ * });
437
+ * ```
438
+ */
439
+ export function createChatMessage(input) {
440
+ return {
441
+ id: generateChatId(),
442
+ conversationId: input.conversationId,
443
+ from: input.from,
444
+ content: input.content,
445
+ contentType: input.contentType ?? 'text',
446
+ status: input.status ?? 'sent',
447
+ timestamp: input.timestamp ?? new Date().toISOString(),
448
+ metadata: input.metadata,
449
+ parentId: input.parentId,
450
+ };
451
+ }
452
+ /**
453
+ * Create a conversation with defaults
454
+ *
455
+ * @param title - Optional title for the conversation
456
+ * @returns A new ChatConversation object
457
+ *
458
+ * @example
459
+ * ```typescript
460
+ * const conversation = createConversation('Project Discussion');
461
+ * ```
462
+ */
463
+ export function createConversation(title, idOverride) {
464
+ const now = new Date().toISOString();
465
+ return {
466
+ id: idOverride ?? generateChatId(),
467
+ title,
468
+ participantIds: [],
469
+ createdAt: now,
470
+ updatedAt: now,
471
+ isArchived: false,
472
+ messageCount: 0,
473
+ };
474
+ }
475
+ /**
476
+ * Format message content by cleaning terminal output
477
+ *
478
+ * Removes ANSI escape codes, control characters, carriage returns (which cause
479
+ * text to overwrite itself in terminals), and trims whitespace.
480
+ *
481
+ * @param content - Raw content to format
482
+ * @returns Cleaned content string
483
+ *
484
+ * @example
485
+ * ```typescript
486
+ * const clean = formatMessageContent('\x1b[32mGreen text\x1b[0m');
487
+ * // Returns: 'Green text'
488
+ * ```
489
+ */
490
+ export function formatMessageContent(content) {
491
+ let cleaned = content;
492
+ // IMPORTANT: Convert cursor movement sequences to spaces BEFORE stripping other ANSI codes
493
+ // Terminal uses \x1b[nC (cursor forward n positions) to create visual spacing
494
+ // We need to convert these to actual spaces to preserve word separation
495
+ // Uses TERMINAL_FORMATTING_CONSTANTS.MAX_CURSOR_REPEAT to cap repeat count
496
+ const maxRepeat = TERMINAL_FORMATTING_CONSTANTS.MAX_CURSOR_REPEAT;
497
+ cleaned = cleaned.replace(/\x1b\[(\d+)C/g, (_match, count) => {
498
+ const num = parseInt(count, 10);
499
+ if (Number.isNaN(num) || num < 0)
500
+ return '';
501
+ return ' '.repeat(Math.min(num, maxRepeat));
502
+ });
503
+ // Convert cursor down sequences to newlines
504
+ cleaned = cleaned.replace(/\x1b\[(\d+)B/g, (_match, count) => {
505
+ const num = parseInt(count, 10);
506
+ if (Number.isNaN(num) || num < 0)
507
+ return '';
508
+ return '\n'.repeat(Math.min(num, maxRepeat));
509
+ });
510
+ // Remove ANSI color/style codes (SGR sequences)
511
+ cleaned = cleaned.replace(/\x1b\[[0-9;]*m/g, '');
512
+ // Remove remaining ANSI escape sequences (cursor position, clear screen, etc.)
513
+ cleaned = cleaned.replace(/\x1b\[[0-9;]*[A-Za-z]/g, '');
514
+ // Remove OSC (Operating System Command) sequences (e.g., terminal title changes)
515
+ cleaned = cleaned.replace(/\x1b\][^\x07]*\x07/g, '');
516
+ // Remove CSI sequences that might not be caught above
517
+ cleaned = cleaned.replace(/\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g, '');
518
+ // Handle carriage returns - terminal uses \r to return cursor to start of line
519
+ // This can cause text overwriting. Split by \r and keep the last segment of each line
520
+ cleaned = cleaned
521
+ .split('\n')
522
+ .map((line) => {
523
+ // If line contains \r, split by it and keep the last non-empty segment
524
+ if (line.includes('\r')) {
525
+ const segments = line.split('\r');
526
+ // Find the last non-empty segment
527
+ for (let i = segments.length - 1; i >= 0; i--) {
528
+ if (segments[i].trim()) {
529
+ return segments[i];
530
+ }
531
+ }
532
+ return '';
533
+ }
534
+ return line;
535
+ })
536
+ .join('\n');
537
+ // Clean orphaned CSI fragments from PTY buffer boundary splits.
538
+ // When ESC char lands in one chunk and the CSI params in the next,
539
+ // artifacts like "[1C" or "[22m" appear mid-word.
540
+ // Note: \d+ (one or more digits) to avoid matching [C in [CHAT_RESPONSE]
541
+ // Multi-param CSI like [38;2;249;226;175m from Gemini CLI truecolor output
542
+ cleaned = cleaned.replace(/\[\d+C/g, ' ');
543
+ cleaned = cleaned.replace(/\[\d+(?:;\d+)*[A-BJKHfm]/g, '');
544
+ // Remove other control characters except newlines and tabs
545
+ cleaned = cleaned.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
546
+ // Normalize multiple consecutive spaces to single space (but preserve newlines)
547
+ cleaned = cleaned.replace(/ +/g, ' ');
548
+ // Clean up multiple blank lines (more than 2 consecutive newlines become 2)
549
+ cleaned = cleaned.replace(/\n{3,}/g, '\n\n');
550
+ // Trim whitespace from each line and remove leading/trailing whitespace
551
+ cleaned = cleaned
552
+ .split('\n')
553
+ .map((line) => line.trim())
554
+ .join('\n')
555
+ .trim();
556
+ return cleaned;
557
+ }
558
+ /**
559
+ * Default response extraction patterns
560
+ */
561
+ export const DEFAULT_RESPONSE_PATTERNS = [
562
+ {
563
+ name: CHAT_CONSTANTS.PATTERNS.EXPLICIT,
564
+ pattern: /\[RESPONSE\]([\s\S]*?)\[\/RESPONSE\]/i,
565
+ groupIndex: 1,
566
+ },
567
+ {
568
+ name: CHAT_CONSTANTS.PATTERNS.CHAT,
569
+ pattern: /\[CHAT_RESPONSE(?::[^\]]*)?\]([\s\S]*?)\[\/CHAT_RESPONSE\]/i,
570
+ groupIndex: 1,
571
+ },
572
+ {
573
+ name: CHAT_CONSTANTS.PATTERNS.CODEBLOCK,
574
+ pattern: /```response\n([\s\S]*?)```/i,
575
+ groupIndex: 1,
576
+ },
577
+ ];
578
+ /**
579
+ * Extract response from raw output using patterns
580
+ *
581
+ * Tries multiple patterns to extract the clean response from
582
+ * raw terminal output. Returns the original output if no pattern matches.
583
+ *
584
+ * @param rawOutput - Raw terminal output
585
+ * @param customPatterns - Optional custom patterns to use instead of defaults
586
+ * @returns Extracted response content
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * const response = extractResponseFromOutput(
591
+ * 'some text [RESPONSE]Hello World[/RESPONSE] more text'
592
+ * );
593
+ * // Returns: 'Hello World'
594
+ * ```
595
+ */
596
+ export function extractResponseFromOutput(rawOutput, customPatterns) {
597
+ const patterns = customPatterns ?? DEFAULT_RESPONSE_PATTERNS;
598
+ for (const { pattern, groupIndex = 1 } of patterns) {
599
+ const match = rawOutput.match(pattern);
600
+ // Check if match exists and has the capture group (even if empty string)
601
+ if (match && match[groupIndex] !== undefined) {
602
+ return match[groupIndex].trim();
603
+ }
604
+ }
605
+ // No pattern matched, return original output
606
+ return rawOutput;
607
+ }
608
+ /**
609
+ * Detect the content type of a message based on its content
610
+ *
611
+ * @param content - Message content to analyze
612
+ * @returns Detected content type
613
+ *
614
+ * @example
615
+ * ```typescript
616
+ * const type = detectContentType('## Heading\n- Item');
617
+ * // Returns: 'markdown'
618
+ * ```
619
+ */
620
+ export function detectContentType(content) {
621
+ // Check for markdown indicators
622
+ if (content.includes('```') ||
623
+ content.includes('##') ||
624
+ content.includes('**') ||
625
+ /^[-*] /.test(content) ||
626
+ /^\d+\. /.test(content)) {
627
+ return 'markdown';
628
+ }
629
+ // Check for code patterns
630
+ if (content.includes('function ') ||
631
+ content.includes('const ') ||
632
+ content.includes('import ') ||
633
+ content.includes('export ') ||
634
+ content.includes('class ') ||
635
+ /^(let|var)\s/.test(content)) {
636
+ return 'code';
637
+ }
638
+ // Check for error patterns
639
+ if (content.toLowerCase().includes('error:') ||
640
+ content.toLowerCase().includes('exception:') ||
641
+ content.includes('Error:') ||
642
+ content.includes('Failed:')) {
643
+ return 'error';
644
+ }
645
+ return 'text';
646
+ }
647
+ /**
648
+ * Create a last message preview from a chat message
649
+ *
650
+ * @param message - The chat message to create preview from
651
+ * @param maxLength - Maximum content length (default: CHAT_CONSTANTS.DEFAULTS.PREVIEW_LENGTH)
652
+ * @returns A LastMessagePreview object
653
+ */
654
+ export function createLastMessagePreview(message, maxLength = CHAT_CONSTANTS.DEFAULTS.PREVIEW_LENGTH) {
655
+ let previewContent = message.content;
656
+ if (previewContent.length > maxLength) {
657
+ previewContent = previewContent.slice(0, maxLength - 3) + '...';
658
+ }
659
+ return {
660
+ content: previewContent,
661
+ timestamp: message.timestamp,
662
+ from: message.from,
663
+ };
664
+ }
665
+ /**
666
+ * Validate SendMessageInput
667
+ *
668
+ * @param input - Input to validate
669
+ * @returns Object with valid flag and optional error message
670
+ */
671
+ export function validateSendMessageInput(input) {
672
+ if (!input || typeof input !== 'object') {
673
+ return { valid: false, error: 'Input must be an object' };
674
+ }
675
+ const data = input;
676
+ if (typeof data.content !== 'string') {
677
+ return { valid: false, error: 'Content must be a string' };
678
+ }
679
+ if (data.content.trim().length === 0) {
680
+ return { valid: false, error: 'Content cannot be empty' };
681
+ }
682
+ if (data.conversationId !== undefined && typeof data.conversationId !== 'string') {
683
+ return { valid: false, error: 'ConversationId must be a string' };
684
+ }
685
+ if (data.metadata !== undefined && (typeof data.metadata !== 'object' || data.metadata === null)) {
686
+ return { valid: false, error: 'Metadata must be an object' };
687
+ }
688
+ return { valid: true };
689
+ }
690
+ /**
691
+ * Validate ChatMessageFilter
692
+ *
693
+ * @param filter - Filter to validate
694
+ * @returns Object with valid flag and optional error message
695
+ */
696
+ export function validateChatMessageFilter(filter) {
697
+ if (!filter || typeof filter !== 'object') {
698
+ return { valid: false, error: 'Filter must be an object' };
699
+ }
700
+ const data = filter;
701
+ if (data.conversationId !== undefined && typeof data.conversationId !== 'string') {
702
+ return { valid: false, error: 'ConversationId must be a string' };
703
+ }
704
+ if (data.senderType !== undefined && !isValidSenderType(data.senderType)) {
705
+ return { valid: false, error: 'Invalid sender type' };
706
+ }
707
+ if (data.contentType !== undefined && !isValidContentType(data.contentType)) {
708
+ return { valid: false, error: 'Invalid content type' };
709
+ }
710
+ if (data.limit !== undefined && (typeof data.limit !== 'number' || data.limit < 1)) {
711
+ return { valid: false, error: 'Limit must be a positive number' };
712
+ }
713
+ if (data.offset !== undefined && (typeof data.offset !== 'number' || data.offset < 0)) {
714
+ return { valid: false, error: 'Offset must be a non-negative number' };
715
+ }
716
+ return { valid: true };
717
+ }
718
+ /**
719
+ * Validate ConversationFilter
720
+ *
721
+ * @param filter - Filter to validate
722
+ * @returns Object with valid flag and optional error message
723
+ */
724
+ export function validateConversationFilter(filter) {
725
+ if (!filter || typeof filter !== 'object') {
726
+ return { valid: false, error: 'Filter must be an object' };
727
+ }
728
+ const data = filter;
729
+ if (data.includeArchived !== undefined && typeof data.includeArchived !== 'boolean') {
730
+ return { valid: false, error: 'IncludeArchived must be a boolean' };
731
+ }
732
+ if (data.search !== undefined && typeof data.search !== 'string') {
733
+ return { valid: false, error: 'Search must be a string' };
734
+ }
735
+ if (data.limit !== undefined && (typeof data.limit !== 'number' || data.limit < 1)) {
736
+ return { valid: false, error: 'Limit must be a positive number' };
737
+ }
738
+ if (data.offset !== undefined && (typeof data.offset !== 'number' || data.offset < 0)) {
739
+ return { valid: false, error: 'Offset must be a non-negative number' };
740
+ }
741
+ return { valid: true };
742
+ }
743
+ //# sourceMappingURL=chat.types.js.map