crewly 1.0.7 → 1.0.10

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 (468) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +50 -3
  3. package/config/constants.ts +59 -0
  4. package/config/index.ts +2 -0
  5. package/config/roles/architect/prompt.md +17 -5
  6. package/config/roles/backend-developer/prompt.md +35 -5
  7. package/config/roles/designer/prompt.md +17 -5
  8. package/config/roles/developer/prompt.md +43 -9
  9. package/config/roles/frontend-developer/prompt.md +35 -5
  10. package/config/roles/fullstack-dev/prompt.md +35 -5
  11. package/config/roles/generalist/prompt.md +18 -5
  12. package/config/roles/orchestrator/prompt.md +126 -3
  13. package/config/roles/product-manager/prompt.md +24 -9
  14. package/config/roles/qa/prompt.md +35 -5
  15. package/config/roles/qa-engineer/prompt.md +35 -5
  16. package/config/roles/sales/prompt.md +17 -5
  17. package/config/roles/support/prompt.md +17 -5
  18. package/config/roles/tpm/prompt.md +17 -5
  19. package/config/skills/agent/_common/lib.sh +4 -0
  20. package/config/skills/agent/core/accept-task/execute.sh +21 -0
  21. package/config/skills/agent/core/accept-task/instructions.md +20 -0
  22. package/config/skills/agent/core/accept-task/skill.json +20 -0
  23. package/config/skills/agent/core/block-task/execute.sh +26 -0
  24. package/config/skills/agent/core/block-task/instructions.md +22 -0
  25. package/config/skills/agent/core/block-task/skill.json +20 -0
  26. package/config/skills/agent/core/check-quality-gates/execute.sh +20 -0
  27. package/config/skills/agent/core/check-quality-gates/instructions.md +23 -0
  28. package/config/skills/agent/core/check-quality-gates/skill.json +20 -0
  29. package/config/skills/agent/core/complete-task/execute.sh +29 -0
  30. package/config/skills/agent/core/complete-task/instructions.md +53 -0
  31. package/config/skills/agent/core/complete-task/skill.json +20 -0
  32. package/config/skills/agent/core/get-my-context/execute.sh +23 -0
  33. package/config/skills/agent/core/get-my-context/instructions.md +21 -0
  34. package/config/skills/agent/core/get-my-context/skill.json +20 -0
  35. package/config/skills/agent/core/get-sops/execute.sh +24 -0
  36. package/config/skills/agent/core/get-sops/instructions.md +21 -0
  37. package/config/skills/agent/core/get-sops/skill.json +20 -0
  38. package/config/skills/agent/core/get-team-status/execute.sh +8 -0
  39. package/config/skills/agent/core/get-team-status/instructions.md +17 -0
  40. package/config/skills/agent/core/get-team-status/skill.json +20 -0
  41. package/config/skills/agent/core/heartbeat/execute.sh +22 -0
  42. package/config/skills/agent/core/heartbeat/instructions.md +23 -0
  43. package/config/skills/agent/core/heartbeat/skill.json +20 -0
  44. package/config/skills/agent/core/manage-knowledge/execute.sh +60 -0
  45. package/config/skills/agent/core/manage-knowledge/instructions.md +46 -0
  46. package/config/skills/agent/core/marketplace-search/execute.sh +77 -0
  47. package/config/skills/agent/core/marketplace-search/instructions.md +59 -0
  48. package/config/skills/agent/core/marketplace-search/skill.json +20 -0
  49. package/config/skills/agent/core/query-knowledge/execute.sh +30 -0
  50. package/config/skills/agent/core/query-knowledge/instructions.md +47 -0
  51. package/config/skills/agent/core/query-knowledge/skill.json +20 -0
  52. package/config/skills/agent/core/read-task/execute.sh +15 -0
  53. package/config/skills/agent/core/read-task/instructions.md +19 -0
  54. package/config/skills/agent/core/read-task/skill.json +20 -0
  55. package/config/skills/agent/core/recall/execute.sh +24 -0
  56. package/config/skills/agent/core/recall/instructions.md +23 -0
  57. package/config/skills/agent/core/recall/skill.json +20 -0
  58. package/config/skills/agent/core/record-learning/execute.sh +29 -0
  59. package/config/skills/agent/core/record-learning/instructions.md +24 -0
  60. package/config/skills/agent/core/record-learning/skill.json +20 -0
  61. package/config/skills/agent/core/register-self/execute.sh +28 -0
  62. package/config/skills/agent/core/register-self/instructions.md +18 -0
  63. package/config/skills/agent/core/register-self/skill.json +20 -0
  64. package/config/skills/agent/core/remember/execute.sh +29 -0
  65. package/config/skills/agent/core/remember/instructions.md +24 -0
  66. package/config/skills/agent/core/remember/skill.json +20 -0
  67. package/config/skills/agent/core/report-progress/execute.sh +28 -0
  68. package/config/skills/agent/core/report-progress/instructions.md +25 -0
  69. package/config/skills/agent/core/report-progress/skill.json +20 -0
  70. package/config/skills/agent/core/report-status/execute.sh +35 -0
  71. package/config/skills/agent/core/report-status/instructions.md +36 -0
  72. package/config/skills/agent/core/report-status/skill.json +20 -0
  73. package/config/skills/agent/core/send-chat-response/execute.sh +26 -0
  74. package/config/skills/agent/core/send-chat-response/instructions.md +22 -0
  75. package/config/skills/agent/core/send-chat-response/skill.json +20 -0
  76. package/config/skills/agent/core/send-message/execute.sh +17 -0
  77. package/config/skills/agent/core/send-message/instructions.md +20 -0
  78. package/config/skills/agent/core/send-message/skill.json +20 -0
  79. package/config/skills/orchestrator/complete-task/execute.sh +1 -0
  80. package/config/skills/orchestrator/delegate-task/execute.sh +1 -1
  81. package/config/skills/registry.json +850 -0
  82. package/config/templates/agent-claude-md.md +16 -0
  83. package/config/templates/research-team.json +22 -0
  84. package/config/templates/startup-team.json +22 -0
  85. package/config/templates/web-dev-team.json +22 -0
  86. package/dist/backend/backend/src/constants.d.ts +127 -1
  87. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  88. package/dist/backend/backend/src/constants.js +119 -8
  89. package/dist/backend/backend/src/constants.js.map +1 -1
  90. package/dist/backend/backend/src/controllers/marketplace/index.d.ts +1 -1
  91. package/dist/backend/backend/src/controllers/marketplace/index.d.ts.map +1 -1
  92. package/dist/backend/backend/src/controllers/marketplace/index.js +1 -1
  93. package/dist/backend/backend/src/controllers/marketplace/index.js.map +1 -1
  94. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts +64 -8
  95. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.d.ts.map +1 -1
  96. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js +194 -96
  97. package/dist/backend/backend/src/controllers/marketplace/marketplace.controller.js.map +1 -1
  98. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.d.ts.map +1 -1
  99. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js +7 -2
  100. package/dist/backend/backend/src/controllers/marketplace/marketplace.routes.js.map +1 -1
  101. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +7 -0
  102. package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
  103. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +174 -4
  104. package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
  105. package/dist/backend/backend/src/index.d.ts.map +1 -1
  106. package/dist/backend/backend/src/index.js +34 -0
  107. package/dist/backend/backend/src/index.js.map +1 -1
  108. package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
  109. package/dist/backend/backend/src/routes/modules/task-management.routes.js +2 -0
  110. package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
  111. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +8 -0
  112. package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
  113. package/dist/backend/backend/src/services/agent/agent-registration.service.js +89 -17
  114. package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
  115. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts +265 -0
  116. package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -0
  117. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +811 -0
  118. package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -0
  119. package/dist/backend/backend/src/services/agent/idle-detection.service.d.ts.map +1 -1
  120. package/dist/backend/backend/src/services/agent/idle-detection.service.js +11 -4
  121. package/dist/backend/backend/src/services/agent/idle-detection.service.js.map +1 -1
  122. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts +11 -0
  123. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.d.ts.map +1 -1
  124. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js +18 -0
  125. package/dist/backend/backend/src/services/agent/pty-activity-tracker.service.js.map +1 -1
  126. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts +12 -0
  127. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.d.ts.map +1 -1
  128. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js +51 -1
  129. package/dist/backend/backend/src/services/agent/runtime-exit-monitor.service.js.map +1 -1
  130. package/dist/backend/backend/src/services/continuation/patterns/waiting-patterns.d.ts +6 -0
  131. package/dist/backend/backend/src/services/continuation/patterns/waiting-patterns.d.ts.map +1 -1
  132. package/dist/backend/backend/src/services/continuation/patterns/waiting-patterns.js +10 -0
  133. package/dist/backend/backend/src/services/continuation/patterns/waiting-patterns.js.map +1 -1
  134. package/dist/backend/backend/src/services/index.d.ts +3 -0
  135. package/dist/backend/backend/src/services/index.d.ts.map +1 -1
  136. package/dist/backend/backend/src/services/index.js +5 -0
  137. package/dist/backend/backend/src/services/index.js.map +1 -1
  138. package/dist/backend/backend/src/services/marketplace/index.d.ts +1 -0
  139. package/dist/backend/backend/src/services/marketplace/index.d.ts.map +1 -1
  140. package/dist/backend/backend/src/services/marketplace/index.js +2 -0
  141. package/dist/backend/backend/src/services/marketplace/index.js.map +1 -1
  142. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts +10 -9
  143. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
  144. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +262 -73
  145. package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
  146. package/dist/backend/backend/src/services/marketplace/marketplace-submission.service.d.ts +71 -0
  147. package/dist/backend/backend/src/services/marketplace/marketplace-submission.service.d.ts.map +1 -0
  148. package/dist/backend/backend/src/services/marketplace/marketplace-submission.service.js +339 -0
  149. package/dist/backend/backend/src/services/marketplace/marketplace-submission.service.js.map +1 -0
  150. package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts +4 -15
  151. package/dist/backend/backend/src/services/marketplace/marketplace.service.d.ts.map +1 -1
  152. package/dist/backend/backend/src/services/marketplace/marketplace.service.js +172 -27
  153. package/dist/backend/backend/src/services/marketplace/marketplace.service.js.map +1 -1
  154. package/dist/backend/backend/src/services/mcp-client.d.ts +233 -0
  155. package/dist/backend/backend/src/services/mcp-client.d.ts.map +1 -0
  156. package/dist/backend/backend/src/services/mcp-client.js +297 -0
  157. package/dist/backend/backend/src/services/mcp-client.js.map +1 -0
  158. package/dist/backend/backend/src/services/mcp-server.d.ts +167 -0
  159. package/dist/backend/backend/src/services/mcp-server.d.ts.map +1 -0
  160. package/dist/backend/backend/src/services/mcp-server.js +586 -0
  161. package/dist/backend/backend/src/services/mcp-server.js.map +1 -0
  162. package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts +32 -2
  163. package/dist/backend/backend/src/services/messaging/message-queue.service.d.ts.map +1 -1
  164. package/dist/backend/backend/src/services/messaging/message-queue.service.js +85 -4
  165. package/dist/backend/backend/src/services/messaging/message-queue.service.js.map +1 -1
  166. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts +10 -0
  167. package/dist/backend/backend/src/services/messaging/queue-processor.service.d.ts.map +1 -1
  168. package/dist/backend/backend/src/services/messaging/queue-processor.service.js +129 -41
  169. package/dist/backend/backend/src/services/messaging/queue-processor.service.js.map +1 -1
  170. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.d.ts.map +1 -1
  171. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js +31 -0
  172. package/dist/backend/backend/src/services/orchestrator/orchestrator-status.service.js.map +1 -1
  173. package/dist/backend/backend/src/services/quality/index.d.ts +1 -0
  174. package/dist/backend/backend/src/services/quality/index.d.ts.map +1 -1
  175. package/dist/backend/backend/src/services/quality/index.js +1 -0
  176. package/dist/backend/backend/src/services/quality/index.js.map +1 -1
  177. package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts +84 -0
  178. package/dist/backend/backend/src/services/quality/task-output-validator.service.d.ts.map +1 -0
  179. package/dist/backend/backend/src/services/quality/task-output-validator.service.js +163 -0
  180. package/dist/backend/backend/src/services/quality/task-output-validator.service.js.map +1 -0
  181. package/dist/backend/backend/src/services/runtime-adapter.d.ts +254 -0
  182. package/dist/backend/backend/src/services/runtime-adapter.d.ts.map +1 -0
  183. package/dist/backend/backend/src/services/runtime-adapter.js +201 -0
  184. package/dist/backend/backend/src/services/runtime-adapter.js.map +1 -0
  185. package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts +19 -0
  186. package/dist/backend/backend/src/services/session/pty/pty-session-backend.d.ts.map +1 -1
  187. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js +31 -2
  188. package/dist/backend/backend/src/services/session/pty/pty-session-backend.js.map +1 -1
  189. package/dist/backend/backend/src/services/session/session-backend.interface.d.ts +14 -0
  190. package/dist/backend/backend/src/services/session/session-backend.interface.d.ts.map +1 -1
  191. package/dist/backend/backend/src/services/session/session-backend.interface.js.map +1 -1
  192. package/dist/backend/backend/src/services/session/session-command-helper.d.ts +9 -0
  193. package/dist/backend/backend/src/services/session/session-command-helper.d.ts.map +1 -1
  194. package/dist/backend/backend/src/services/session/session-command-helper.js +24 -1
  195. package/dist/backend/backend/src/services/session/session-command-helper.js.map +1 -1
  196. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts +7 -13
  197. package/dist/backend/backend/src/services/skill/skill-catalog.service.d.ts.map +1 -1
  198. package/dist/backend/backend/src/services/skill/skill-catalog.service.js +38 -47
  199. package/dist/backend/backend/src/services/skill/skill-catalog.service.js.map +1 -1
  200. package/dist/backend/backend/src/services/skill/skill.service.d.ts +3 -0
  201. package/dist/backend/backend/src/services/skill/skill.service.d.ts.map +1 -1
  202. package/dist/backend/backend/src/services/skill/skill.service.js +17 -0
  203. package/dist/backend/backend/src/services/skill/skill.service.js.map +1 -1
  204. package/dist/backend/backend/src/types/event-bus.types.d.ts +2 -2
  205. package/dist/backend/backend/src/types/event-bus.types.d.ts.map +1 -1
  206. package/dist/backend/backend/src/types/event-bus.types.js +2 -0
  207. package/dist/backend/backend/src/types/event-bus.types.js.map +1 -1
  208. package/dist/backend/backend/src/types/index.d.ts +1 -0
  209. package/dist/backend/backend/src/types/index.d.ts.map +1 -1
  210. package/dist/backend/backend/src/types/index.js +2 -0
  211. package/dist/backend/backend/src/types/index.js.map +1 -1
  212. package/dist/backend/backend/src/types/marketplace.types.d.ts +37 -0
  213. package/dist/backend/backend/src/types/marketplace.types.d.ts.map +1 -1
  214. package/dist/backend/backend/src/types/messaging.types.d.ts +9 -6
  215. package/dist/backend/backend/src/types/messaging.types.d.ts.map +1 -1
  216. package/dist/backend/backend/src/types/messaging.types.js +10 -3
  217. package/dist/backend/backend/src/types/messaging.types.js.map +1 -1
  218. package/dist/backend/backend/src/types/task-output.types.d.ts +78 -0
  219. package/dist/backend/backend/src/types/task-output.types.d.ts.map +1 -0
  220. package/dist/backend/backend/src/types/task-output.types.js +27 -0
  221. package/dist/backend/backend/src/types/task-output.types.js.map +1 -0
  222. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +13 -0
  223. package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
  224. package/dist/backend/backend/src/websocket/terminal.gateway.js +12 -0
  225. package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
  226. package/dist/backend/config/constants.d.ts +41 -0
  227. package/dist/backend/config/constants.d.ts.map +1 -1
  228. package/dist/backend/config/constants.js +57 -0
  229. package/dist/backend/config/constants.js.map +1 -1
  230. package/dist/backend/config/index.d.ts +2 -2
  231. package/dist/backend/config/index.d.ts.map +1 -1
  232. package/dist/backend/config/index.js +2 -2
  233. package/dist/backend/config/index.js.map +1 -1
  234. package/dist/cli/backend/src/constants.d.ts +817 -0
  235. package/dist/cli/backend/src/constants.d.ts.map +1 -0
  236. package/dist/cli/backend/src/constants.js +603 -0
  237. package/dist/cli/backend/src/constants.js.map +1 -0
  238. package/dist/cli/backend/src/models/Project.d.ts +18 -0
  239. package/dist/cli/backend/src/models/Project.d.ts.map +1 -0
  240. package/dist/cli/backend/src/models/Project.js +70 -0
  241. package/dist/cli/backend/src/models/Project.js.map +1 -0
  242. package/dist/cli/backend/src/models/ScheduledMessage.d.ts +27 -0
  243. package/dist/cli/backend/src/models/ScheduledMessage.d.ts.map +1 -0
  244. package/dist/cli/backend/src/models/ScheduledMessage.js +50 -0
  245. package/dist/cli/backend/src/models/ScheduledMessage.js.map +1 -0
  246. package/dist/cli/backend/src/models/Team.d.ts +20 -0
  247. package/dist/cli/backend/src/models/Team.d.ts.map +1 -0
  248. package/dist/cli/backend/src/models/Team.js +120 -0
  249. package/dist/cli/backend/src/models/Team.js.map +1 -0
  250. package/dist/cli/backend/src/models/Ticket.d.ts +24 -0
  251. package/dist/cli/backend/src/models/Ticket.d.ts.map +1 -0
  252. package/dist/cli/backend/src/models/Ticket.js +102 -0
  253. package/dist/cli/backend/src/models/Ticket.js.map +1 -0
  254. package/dist/cli/backend/src/models/index.d.ts +5 -0
  255. package/dist/cli/backend/src/models/index.d.ts.map +1 -0
  256. package/dist/cli/backend/src/models/index.js +5 -0
  257. package/dist/cli/backend/src/models/index.js.map +1 -0
  258. package/dist/cli/backend/src/services/continuation/patterns/waiting-patterns.d.ts +40 -0
  259. package/dist/cli/backend/src/services/continuation/patterns/waiting-patterns.d.ts.map +1 -0
  260. package/dist/cli/backend/src/services/continuation/patterns/waiting-patterns.js +74 -0
  261. package/dist/cli/backend/src/services/continuation/patterns/waiting-patterns.js.map +1 -0
  262. package/dist/cli/backend/src/services/core/config.service.d.ts +91 -0
  263. package/dist/cli/backend/src/services/core/config.service.d.ts.map +1 -0
  264. package/dist/cli/backend/src/services/core/config.service.js +246 -0
  265. package/dist/cli/backend/src/services/core/config.service.js.map +1 -0
  266. package/dist/cli/backend/src/services/core/logger.service.d.ts +70 -0
  267. package/dist/cli/backend/src/services/core/logger.service.d.ts.map +1 -0
  268. package/dist/cli/backend/src/services/core/logger.service.js +350 -0
  269. package/dist/cli/backend/src/services/core/logger.service.js.map +1 -0
  270. package/dist/cli/backend/src/services/core/storage.service.d.ts +269 -0
  271. package/dist/cli/backend/src/services/core/storage.service.d.ts.map +1 -0
  272. package/dist/cli/backend/src/services/core/storage.service.js +1406 -0
  273. package/dist/cli/backend/src/services/core/storage.service.js.map +1 -0
  274. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts +92 -0
  275. package/dist/cli/backend/src/services/core/teams-backup.service.d.ts.map +1 -0
  276. package/dist/cli/backend/src/services/core/teams-backup.service.js +120 -0
  277. package/dist/cli/backend/src/services/core/teams-backup.service.js.map +1 -0
  278. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts +125 -0
  279. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -0
  280. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +247 -0
  281. package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -0
  282. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts +153 -0
  283. package/dist/cli/backend/src/services/knowledge/knowledge.service.d.ts.map +1 -0
  284. package/dist/cli/backend/src/services/knowledge/knowledge.service.js +409 -0
  285. package/dist/cli/backend/src/services/knowledge/knowledge.service.js.map +1 -0
  286. package/dist/cli/backend/src/services/mcp-server.d.ts +167 -0
  287. package/dist/cli/backend/src/services/mcp-server.d.ts.map +1 -0
  288. package/dist/cli/backend/src/services/mcp-server.js +586 -0
  289. package/dist/cli/backend/src/services/mcp-server.js.map +1 -0
  290. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts +259 -0
  291. package/dist/cli/backend/src/services/memory/agent-memory.service.d.ts.map +1 -0
  292. package/dist/cli/backend/src/services/memory/agent-memory.service.js +539 -0
  293. package/dist/cli/backend/src/services/memory/agent-memory.service.js.map +1 -0
  294. package/dist/cli/backend/src/services/memory/memory.service.d.ts +306 -0
  295. package/dist/cli/backend/src/services/memory/memory.service.d.ts.map +1 -0
  296. package/dist/cli/backend/src/services/memory/memory.service.js +517 -0
  297. package/dist/cli/backend/src/services/memory/memory.service.js.map +1 -0
  298. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts +252 -0
  299. package/dist/cli/backend/src/services/memory/project-memory.service.d.ts.map +1 -0
  300. package/dist/cli/backend/src/services/memory/project-memory.service.js +600 -0
  301. package/dist/cli/backend/src/services/memory/project-memory.service.js.map +1 -0
  302. package/dist/cli/backend/src/types/auto-assign.types.d.ts +271 -0
  303. package/dist/cli/backend/src/types/auto-assign.types.d.ts.map +1 -0
  304. package/dist/cli/backend/src/types/auto-assign.types.js +136 -0
  305. package/dist/cli/backend/src/types/auto-assign.types.js.map +1 -0
  306. package/dist/cli/backend/src/types/budget.types.d.ts +217 -0
  307. package/dist/cli/backend/src/types/budget.types.d.ts.map +1 -0
  308. package/dist/cli/backend/src/types/budget.types.js +82 -0
  309. package/dist/cli/backend/src/types/budget.types.js.map +1 -0
  310. package/dist/cli/backend/src/types/chat.types.d.ts +550 -0
  311. package/dist/cli/backend/src/types/chat.types.d.ts.map +1 -0
  312. package/dist/cli/backend/src/types/chat.types.js +743 -0
  313. package/dist/cli/backend/src/types/chat.types.js.map +1 -0
  314. package/dist/cli/backend/src/types/continuation.types.d.ts +237 -0
  315. package/dist/cli/backend/src/types/continuation.types.d.ts.map +1 -0
  316. package/dist/cli/backend/src/types/continuation.types.js +10 -0
  317. package/dist/cli/backend/src/types/continuation.types.js.map +1 -0
  318. package/dist/cli/backend/src/types/index.d.ts +164 -0
  319. package/dist/cli/backend/src/types/index.d.ts.map +1 -0
  320. package/dist/cli/backend/src/types/index.js +25 -0
  321. package/dist/cli/backend/src/types/index.js.map +1 -0
  322. package/dist/cli/backend/src/types/knowledge.types.d.ts +195 -0
  323. package/dist/cli/backend/src/types/knowledge.types.d.ts.map +1 -0
  324. package/dist/cli/backend/src/types/knowledge.types.js +38 -0
  325. package/dist/cli/backend/src/types/knowledge.types.js.map +1 -0
  326. package/dist/cli/backend/src/types/memory.types.d.ts +587 -0
  327. package/dist/cli/backend/src/types/memory.types.d.ts.map +1 -0
  328. package/dist/cli/backend/src/types/memory.types.js +47 -0
  329. package/dist/cli/backend/src/types/memory.types.js.map +1 -0
  330. package/dist/cli/backend/src/types/quality-gate.types.d.ts +171 -0
  331. package/dist/cli/backend/src/types/quality-gate.types.d.ts.map +1 -0
  332. package/dist/cli/backend/src/types/quality-gate.types.js +42 -0
  333. package/dist/cli/backend/src/types/quality-gate.types.js.map +1 -0
  334. package/dist/cli/backend/src/types/role.types.d.ts +260 -0
  335. package/dist/cli/backend/src/types/role.types.d.ts.map +1 -0
  336. package/dist/cli/backend/src/types/role.types.js +238 -0
  337. package/dist/cli/backend/src/types/role.types.js.map +1 -0
  338. package/dist/cli/backend/src/types/scheduler.types.d.ts +254 -0
  339. package/dist/cli/backend/src/types/scheduler.types.d.ts.map +1 -0
  340. package/dist/cli/backend/src/types/scheduler.types.js +32 -0
  341. package/dist/cli/backend/src/types/scheduler.types.js.map +1 -0
  342. package/dist/cli/backend/src/types/settings.types.d.ts +178 -0
  343. package/dist/cli/backend/src/types/settings.types.d.ts.map +1 -0
  344. package/dist/cli/backend/src/types/settings.types.js +206 -0
  345. package/dist/cli/backend/src/types/settings.types.js.map +1 -0
  346. package/dist/cli/backend/src/types/skill.types.d.ts +515 -0
  347. package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -0
  348. package/dist/cli/backend/src/types/skill.types.js +481 -0
  349. package/dist/cli/backend/src/types/skill.types.js.map +1 -0
  350. package/dist/cli/backend/src/types/sop.types.d.ts +224 -0
  351. package/dist/cli/backend/src/types/sop.types.d.ts.map +1 -0
  352. package/dist/cli/backend/src/types/sop.types.js +85 -0
  353. package/dist/cli/backend/src/types/sop.types.js.map +1 -0
  354. package/dist/cli/backend/src/types/task-output.types.d.ts +78 -0
  355. package/dist/cli/backend/src/types/task-output.types.d.ts.map +1 -0
  356. package/dist/cli/backend/src/types/task-output.types.js +27 -0
  357. package/dist/cli/backend/src/types/task-output.types.js.map +1 -0
  358. package/dist/cli/backend/src/utils/file-io.utils.d.ts +102 -0
  359. package/dist/cli/backend/src/utils/file-io.utils.d.ts.map +1 -0
  360. package/dist/cli/backend/src/utils/file-io.utils.js +214 -0
  361. package/dist/cli/backend/src/utils/file-io.utils.js.map +1 -0
  362. package/dist/cli/backend/src/utils/terminal-output.utils.d.ts +54 -0
  363. package/dist/cli/backend/src/utils/terminal-output.utils.d.ts.map +1 -0
  364. package/dist/cli/backend/src/utils/terminal-output.utils.js +97 -0
  365. package/dist/cli/backend/src/utils/terminal-output.utils.js.map +1 -0
  366. package/dist/cli/cli/src/commands/mcp-server.d.ts +38 -0
  367. package/dist/cli/cli/src/commands/mcp-server.d.ts.map +1 -0
  368. package/dist/cli/cli/src/commands/mcp-server.js +49 -0
  369. package/dist/cli/cli/src/commands/mcp-server.js.map +1 -0
  370. package/dist/cli/cli/src/commands/onboard.d.ts +72 -8
  371. package/dist/cli/cli/src/commands/onboard.d.ts.map +1 -1
  372. package/dist/cli/cli/src/commands/onboard.js +306 -33
  373. package/dist/cli/cli/src/commands/onboard.js.map +1 -1
  374. package/dist/cli/cli/src/commands/publish.d.ts +35 -0
  375. package/dist/cli/cli/src/commands/publish.d.ts.map +1 -0
  376. package/dist/cli/cli/src/commands/publish.js +93 -0
  377. package/dist/cli/cli/src/commands/publish.js.map +1 -0
  378. package/dist/cli/cli/src/commands/seed-marketplace.d.ts +28 -0
  379. package/dist/cli/cli/src/commands/seed-marketplace.d.ts.map +1 -0
  380. package/dist/cli/cli/src/commands/seed-marketplace.js +148 -0
  381. package/dist/cli/cli/src/commands/seed-marketplace.js.map +1 -0
  382. package/dist/cli/cli/src/index.js +23 -0
  383. package/dist/cli/cli/src/index.js.map +1 -1
  384. package/dist/cli/cli/src/utils/archive-creator.d.ts +82 -0
  385. package/dist/cli/cli/src/utils/archive-creator.d.ts.map +1 -0
  386. package/dist/cli/cli/src/utils/archive-creator.js +105 -0
  387. package/dist/cli/cli/src/utils/archive-creator.js.map +1 -0
  388. package/dist/cli/cli/src/utils/marketplace.d.ts +17 -4
  389. package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
  390. package/dist/cli/cli/src/utils/marketplace.js +172 -58
  391. package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
  392. package/dist/cli/cli/src/utils/package-validator.d.ts +62 -0
  393. package/dist/cli/cli/src/utils/package-validator.d.ts.map +1 -0
  394. package/dist/cli/cli/src/utils/package-validator.js +122 -0
  395. package/dist/cli/cli/src/utils/package-validator.js.map +1 -0
  396. package/dist/cli/cli/src/utils/templates.d.ts +71 -0
  397. package/dist/cli/cli/src/utils/templates.d.ts.map +1 -0
  398. package/dist/cli/cli/src/utils/templates.js +91 -0
  399. package/dist/cli/cli/src/utils/templates.js.map +1 -0
  400. package/dist/cli/config/constants.d.ts +41 -0
  401. package/dist/cli/config/constants.d.ts.map +1 -1
  402. package/dist/cli/config/constants.js +57 -0
  403. package/dist/cli/config/constants.js.map +1 -1
  404. package/dist/cli/config/index.d.ts +2 -2
  405. package/dist/cli/config/index.d.ts.map +1 -1
  406. package/dist/cli/config/index.js +2 -2
  407. package/dist/cli/config/index.js.map +1 -1
  408. package/frontend/dist/assets/{index-523c7fce.js → index-0a245b0d.js} +247 -247
  409. package/frontend/dist/assets/{index-4c050f52.css → index-6972eeee.css} +1 -1
  410. package/frontend/dist/assets/nunito-cyrillic-400-normal-e44e669f.woff2 +0 -0
  411. package/frontend/dist/assets/nunito-cyrillic-400-normal-ff8e8bdd.woff +0 -0
  412. package/frontend/dist/assets/nunito-cyrillic-500-normal-2159679b.woff +0 -0
  413. package/frontend/dist/assets/nunito-cyrillic-500-normal-61a3b80e.woff2 +0 -0
  414. package/frontend/dist/assets/nunito-cyrillic-600-normal-ac046097.woff +0 -0
  415. package/frontend/dist/assets/nunito-cyrillic-600-normal-e61eb97b.woff2 +0 -0
  416. package/frontend/dist/assets/nunito-cyrillic-700-normal-8fcefcc9.woff2 +0 -0
  417. package/frontend/dist/assets/nunito-cyrillic-700-normal-b9684104.woff +0 -0
  418. package/frontend/dist/assets/nunito-cyrillic-800-normal-40253beb.woff +0 -0
  419. package/frontend/dist/assets/nunito-cyrillic-800-normal-d80292de.woff2 +0 -0
  420. package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-20d73ae7.woff2 +0 -0
  421. package/frontend/dist/assets/nunito-cyrillic-ext-400-normal-d48c37c9.woff +0 -0
  422. package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-16197abd.woff +0 -0
  423. package/frontend/dist/assets/nunito-cyrillic-ext-500-normal-9dcfe9b5.woff2 +0 -0
  424. package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-d53e9851.woff2 +0 -0
  425. package/frontend/dist/assets/nunito-cyrillic-ext-600-normal-e3d0201f.woff +0 -0
  426. package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-5936f6ac.woff2 +0 -0
  427. package/frontend/dist/assets/nunito-cyrillic-ext-700-normal-c8c02775.woff +0 -0
  428. package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-217b8f51.woff +0 -0
  429. package/frontend/dist/assets/nunito-cyrillic-ext-800-normal-796cf7bd.woff2 +0 -0
  430. package/frontend/dist/assets/nunito-latin-400-normal-a5906e15.woff2 +0 -0
  431. package/frontend/dist/assets/nunito-latin-400-normal-b51e7635.woff +0 -0
  432. package/frontend/dist/assets/nunito-latin-500-normal-23ae3083.woff2 +0 -0
  433. package/frontend/dist/assets/nunito-latin-500-normal-be14dbc6.woff +0 -0
  434. package/frontend/dist/assets/nunito-latin-600-normal-06a9c8b3.woff +0 -0
  435. package/frontend/dist/assets/nunito-latin-600-normal-45f437de.woff2 +0 -0
  436. package/frontend/dist/assets/nunito-latin-700-normal-ce9107dc.woff +0 -0
  437. package/frontend/dist/assets/nunito-latin-700-normal-fa89300b.woff2 +0 -0
  438. package/frontend/dist/assets/nunito-latin-800-normal-0ca02785.woff +0 -0
  439. package/frontend/dist/assets/nunito-latin-800-normal-2363d3ed.woff2 +0 -0
  440. package/frontend/dist/assets/nunito-latin-ext-400-normal-67250a41.woff2 +0 -0
  441. package/frontend/dist/assets/nunito-latin-ext-400-normal-d7e2415e.woff +0 -0
  442. package/frontend/dist/assets/nunito-latin-ext-500-normal-06f35d1c.woff +0 -0
  443. package/frontend/dist/assets/nunito-latin-ext-500-normal-343e7adc.woff2 +0 -0
  444. package/frontend/dist/assets/nunito-latin-ext-600-normal-5a8efd17.woff +0 -0
  445. package/frontend/dist/assets/nunito-latin-ext-600-normal-a7ba5f4f.woff2 +0 -0
  446. package/frontend/dist/assets/nunito-latin-ext-700-normal-0a4e4a02.woff2 +0 -0
  447. package/frontend/dist/assets/nunito-latin-ext-700-normal-0c607961.woff +0 -0
  448. package/frontend/dist/assets/nunito-latin-ext-800-normal-39f54b55.woff2 +0 -0
  449. package/frontend/dist/assets/nunito-latin-ext-800-normal-466d0211.woff +0 -0
  450. package/frontend/dist/assets/nunito-vietnamese-400-normal-2a755616.woff2 +0 -0
  451. package/frontend/dist/assets/nunito-vietnamese-400-normal-9c01ea9f.woff +0 -0
  452. package/frontend/dist/assets/nunito-vietnamese-500-normal-452e5e08.woff +0 -0
  453. package/frontend/dist/assets/nunito-vietnamese-500-normal-dc98d965.woff2 +0 -0
  454. package/frontend/dist/assets/nunito-vietnamese-600-normal-2ffbb85f.woff +0 -0
  455. package/frontend/dist/assets/nunito-vietnamese-600-normal-cf95b95d.woff2 +0 -0
  456. package/frontend/dist/assets/nunito-vietnamese-700-normal-0e29c28c.woff2 +0 -0
  457. package/frontend/dist/assets/nunito-vietnamese-700-normal-7793b75e.woff +0 -0
  458. package/frontend/dist/assets/nunito-vietnamese-800-normal-5baf507e.woff +0 -0
  459. package/frontend/dist/assets/nunito-vietnamese-800-normal-fac6740e.woff2 +0 -0
  460. package/frontend/dist/index.html +2 -2
  461. package/package.json +16 -6
  462. package/config/skills/chrome-browser/instructions.md +0 -42
  463. package/config/skills/chrome-browser/skill.json +0 -39
  464. package/config/skills/nano-banana-image/generate.sh +0 -73
  465. package/config/skills/nano-banana-image/instructions.md +0 -50
  466. package/config/skills/nano-banana-image/skill.json +0 -39
  467. package/config/skills/playwright-chrome-browser/instructions.md +0 -95
  468. package/config/skills/playwright-chrome-browser/skill.json +0 -44
@@ -0,0 +1,811 @@
1
+ /**
2
+ * Context Window Monitor Service
3
+ *
4
+ * Monitors PTY session output for context window usage percentages and triggers
5
+ * proactive warnings and runtime-native compaction when thresholds are exceeded.
6
+ *
7
+ * When an agent's session reports context usage (e.g., "85% context"),
8
+ * this service detects the percentage, evaluates it against configured thresholds,
9
+ * and takes action:
10
+ * - Yellow (70%): Publishes a warning event
11
+ * - Red (85%): Publishes a warning + triggers runtime compact (/compact or /compress)
12
+ * - Critical (95%): Retries compact with cooldown; auto-recovery disabled by default
13
+ *
14
+ * Strategy: prefer runtime-native compact/compress commands which preserve session
15
+ * state over session kill + restart which loses all context. Auto-recovery is
16
+ * available as a last resort via AUTO_RECOVERY_ENABLED constant.
17
+ *
18
+ * Follows the PTY subscription pattern from RuntimeExitMonitorService and the
19
+ * lifecycle/restart pattern from AgentHeartbeatMonitorService.
20
+ *
21
+ * @module services/agent/context-window-monitor
22
+ */
23
+ import * as fs from 'fs/promises';
24
+ import { v4 as uuidv4 } from 'uuid';
25
+ import { LoggerService } from '../core/logger.service.js';
26
+ import { getSessionBackendSync, } from '../session/index.js';
27
+ import { getSessionStatePersistence } from '../session/session-state-persistence.js';
28
+ import { getTerminalGateway } from '../../websocket/terminal.gateway.js';
29
+ import { PtyActivityTrackerService } from './pty-activity-tracker.service.js';
30
+ import { RuntimeExitMonitorService } from './runtime-exit-monitor.service.js';
31
+ import { stripAnsiCodes } from '../../utils/terminal-output.utils.js';
32
+ import { CONTEXT_WINDOW_MONITOR_CONSTANTS, RUNTIME_COMPACT_COMMANDS, RUNTIME_TYPES, AGENT_SUSPEND_CONSTANTS, SESSION_COMMAND_DELAYS, } from '../../constants.js';
33
+ // =============================================================================
34
+ // Regex patterns for detecting context usage percentages in PTY output
35
+ // =============================================================================
36
+ /**
37
+ * Patterns to match context window usage percentages from Claude Code output.
38
+ * Each pattern captures the percentage as group 1.
39
+ */
40
+ const CONTEXT_PERCENT_PATTERNS = [
41
+ /(\d{1,3})%\s*(?:of\s+)?context/i,
42
+ /context[:\s]+(\d{1,3})%/i,
43
+ /(\d{1,3})%\s*ctx/i,
44
+ ];
45
+ // =============================================================================
46
+ // Service
47
+ // =============================================================================
48
+ /**
49
+ * Monitors agent PTY sessions for context window usage and triggers
50
+ * threshold-based warnings and auto-recovery.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * const monitor = ContextWindowMonitorService.getInstance();
55
+ * monitor.setDependencies(backend, regService, storageService, taskService, eventBus);
56
+ * monitor.start();
57
+ * monitor.startSessionMonitoring('agent-dev', 'member-1', 'team-1', 'developer');
58
+ * ```
59
+ */
60
+ export class ContextWindowMonitorService {
61
+ static instance = null;
62
+ logger;
63
+ /** Per-session context window state */
64
+ contextStates = new Map();
65
+ /** Per-session PTY data subscriptions + rolling buffers */
66
+ sessionSubscriptions = new Map();
67
+ /** Periodic check interval timer */
68
+ checkTimer = null;
69
+ /** Dependencies (injected via setDependencies) */
70
+ sessionBackend = null;
71
+ agentRegistrationService = null;
72
+ storageService = null;
73
+ taskTrackingService = null;
74
+ eventBusService = null;
75
+ constructor() {
76
+ this.logger = LoggerService.getInstance().createComponentLogger('ContextWindowMonitor');
77
+ }
78
+ /**
79
+ * Get the singleton instance.
80
+ *
81
+ * @returns The ContextWindowMonitorService singleton
82
+ */
83
+ static getInstance() {
84
+ if (!ContextWindowMonitorService.instance) {
85
+ ContextWindowMonitorService.instance = new ContextWindowMonitorService();
86
+ }
87
+ return ContextWindowMonitorService.instance;
88
+ }
89
+ /**
90
+ * Reset the singleton (for testing).
91
+ */
92
+ static resetInstance() {
93
+ if (ContextWindowMonitorService.instance) {
94
+ ContextWindowMonitorService.instance.stop();
95
+ ContextWindowMonitorService.instance.destroyAllSubscriptions();
96
+ }
97
+ ContextWindowMonitorService.instance = null;
98
+ }
99
+ /**
100
+ * Inject required dependencies.
101
+ *
102
+ * @param sessionBackend - Session backend for PTY access
103
+ * @param agentRegistrationService - For recreating agent sessions on recovery
104
+ * @param storageService - For querying agent status
105
+ * @param taskTrackingService - For querying in-progress tasks for re-delivery
106
+ * @param eventBusService - For publishing context warning/critical events
107
+ */
108
+ setDependencies(sessionBackend, agentRegistrationService, storageService, taskTrackingService, eventBusService) {
109
+ this.sessionBackend = sessionBackend;
110
+ this.agentRegistrationService = agentRegistrationService;
111
+ this.storageService = storageService;
112
+ this.taskTrackingService = taskTrackingService;
113
+ this.eventBusService = eventBusService;
114
+ }
115
+ /**
116
+ * Start the periodic check loop for stale detection and cleanup.
117
+ */
118
+ start() {
119
+ if (this.checkTimer) {
120
+ this.logger.warn('Context window monitor already running');
121
+ return;
122
+ }
123
+ this.logger.info('Starting context window monitor', {
124
+ checkIntervalMs: CONTEXT_WINDOW_MONITOR_CONSTANTS.CHECK_INTERVAL_MS,
125
+ yellowThreshold: CONTEXT_WINDOW_MONITOR_CONSTANTS.YELLOW_THRESHOLD_PERCENT,
126
+ redThreshold: CONTEXT_WINDOW_MONITOR_CONSTANTS.RED_THRESHOLD_PERCENT,
127
+ criticalThreshold: CONTEXT_WINDOW_MONITOR_CONSTANTS.CRITICAL_THRESHOLD_PERCENT,
128
+ });
129
+ this.checkTimer = setInterval(() => {
130
+ this.performCheck();
131
+ }, CONTEXT_WINDOW_MONITOR_CONSTANTS.CHECK_INTERVAL_MS);
132
+ }
133
+ /**
134
+ * Stop the periodic check loop.
135
+ */
136
+ stop() {
137
+ if (this.checkTimer) {
138
+ clearInterval(this.checkTimer);
139
+ this.checkTimer = null;
140
+ this.logger.info('Context window monitor stopped');
141
+ }
142
+ }
143
+ /**
144
+ * Check if the monitor is currently running.
145
+ *
146
+ * @returns True if the periodic check loop is active
147
+ */
148
+ isRunning() {
149
+ return this.checkTimer !== null;
150
+ }
151
+ /**
152
+ * Start monitoring a specific session for context window usage.
153
+ *
154
+ * Subscribes to the session's PTY onData events and parses output
155
+ * for context usage percentages.
156
+ *
157
+ * @param sessionName - PTY session name
158
+ * @param memberId - Team member ID
159
+ * @param teamId - Team ID
160
+ * @param role - Agent role
161
+ * @param runtimeType - Runtime type (defaults to 'claude-code')
162
+ */
163
+ startSessionMonitoring(sessionName, memberId, teamId, role, runtimeType = RUNTIME_TYPES.CLAUDE_CODE) {
164
+ // Stop any existing monitoring for this session
165
+ if (this.sessionSubscriptions.has(sessionName)) {
166
+ this.stopSessionMonitoring(sessionName);
167
+ }
168
+ const backend = this.sessionBackend || getSessionBackendSync();
169
+ if (!backend) {
170
+ this.logger.warn('Cannot start context monitoring: session backend not available', { sessionName });
171
+ return;
172
+ }
173
+ const session = backend.getSession(sessionName);
174
+ if (!session) {
175
+ this.logger.warn('Cannot start context monitoring: session not found', { sessionName });
176
+ return;
177
+ }
178
+ // Initialize state
179
+ const state = {
180
+ sessionName,
181
+ memberId,
182
+ teamId,
183
+ role,
184
+ runtimeType,
185
+ contextPercent: 0,
186
+ level: 'normal',
187
+ lastDetectedAt: Date.now(),
188
+ recoveryTriggered: false,
189
+ recoveryCount: 0,
190
+ recoveryTimestamps: [],
191
+ compactAttempts: 0,
192
+ compactInProgress: false,
193
+ lastCompactAt: 0,
194
+ };
195
+ this.contextStates.set(sessionName, state);
196
+ // Subscribe to PTY data
197
+ const unsubscribe = session.onData((data) => {
198
+ this.handleData(sessionName, data);
199
+ });
200
+ this.sessionSubscriptions.set(sessionName, {
201
+ unsubscribe,
202
+ buffer: '',
203
+ });
204
+ this.logger.info('Started context window monitoring', {
205
+ sessionName,
206
+ memberId,
207
+ teamId,
208
+ role,
209
+ });
210
+ }
211
+ /**
212
+ * Stop monitoring a specific session.
213
+ *
214
+ * @param sessionName - PTY session name
215
+ */
216
+ stopSessionMonitoring(sessionName) {
217
+ const sub = this.sessionSubscriptions.get(sessionName);
218
+ if (sub) {
219
+ sub.unsubscribe();
220
+ this.sessionSubscriptions.delete(sessionName);
221
+ }
222
+ this.contextStates.delete(sessionName);
223
+ this.proactiveCompactLastTriggered.delete(sessionName);
224
+ this.logger.debug('Stopped context window monitoring', { sessionName });
225
+ }
226
+ /**
227
+ * Get the context window state for a specific session.
228
+ *
229
+ * @param sessionName - PTY session name
230
+ * @returns The context window state or undefined if not monitored
231
+ */
232
+ getContextState(sessionName) {
233
+ return this.contextStates.get(sessionName);
234
+ }
235
+ /**
236
+ * Get all monitored context window states.
237
+ *
238
+ * @returns Map of session name to context window state
239
+ */
240
+ getAllContextStates() {
241
+ return new Map(this.contextStates);
242
+ }
243
+ /**
244
+ * Handle incoming PTY data for a monitored session.
245
+ * Strips ANSI codes, appends to rolling buffer, and checks for context % patterns.
246
+ *
247
+ * @param sessionName - PTY session name
248
+ * @param data - Raw PTY output data
249
+ */
250
+ handleData(sessionName, data) {
251
+ const sub = this.sessionSubscriptions.get(sessionName);
252
+ const state = this.contextStates.get(sessionName);
253
+ if (!sub || !state) {
254
+ return;
255
+ }
256
+ // Strip ANSI and append to rolling buffer
257
+ const clean = stripAnsiCodes(data);
258
+ sub.buffer += clean;
259
+ // Cap buffer size
260
+ if (sub.buffer.length > CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_BUFFER_SIZE) {
261
+ sub.buffer = sub.buffer.slice(-CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_BUFFER_SIZE);
262
+ }
263
+ // Try to extract context percentage from buffer
264
+ const percent = this.extractContextPercent(sub.buffer);
265
+ if (percent !== null) {
266
+ this.updateContextUsage(sessionName, percent);
267
+ // Clear buffer after successful extraction to avoid re-matching
268
+ sub.buffer = '';
269
+ }
270
+ }
271
+ /**
272
+ * Extract context usage percentage from terminal output.
273
+ *
274
+ * @param text - Cleaned terminal output text
275
+ * @returns The extracted percentage (0-100) or null if not found
276
+ */
277
+ extractContextPercent(text) {
278
+ for (const pattern of CONTEXT_PERCENT_PATTERNS) {
279
+ const match = pattern.exec(text);
280
+ if (match) {
281
+ const percent = parseInt(match[1], 10);
282
+ if (percent >= 0 && percent <= 100) {
283
+ return percent;
284
+ }
285
+ }
286
+ }
287
+ return null;
288
+ }
289
+ /**
290
+ * Update context usage for a session and evaluate thresholds.
291
+ *
292
+ * @param sessionName - PTY session name
293
+ * @param percent - New context usage percentage
294
+ */
295
+ updateContextUsage(sessionName, percent) {
296
+ const state = this.contextStates.get(sessionName);
297
+ if (!state) {
298
+ return;
299
+ }
300
+ const previousLevel = state.level;
301
+ state.contextPercent = percent;
302
+ state.lastDetectedAt = Date.now();
303
+ // Determine new level
304
+ if (percent >= CONTEXT_WINDOW_MONITOR_CONSTANTS.CRITICAL_THRESHOLD_PERCENT) {
305
+ state.level = 'critical';
306
+ }
307
+ else if (percent >= CONTEXT_WINDOW_MONITOR_CONSTANTS.RED_THRESHOLD_PERCENT) {
308
+ state.level = 'red';
309
+ }
310
+ else if (percent >= CONTEXT_WINDOW_MONITOR_CONSTANTS.YELLOW_THRESHOLD_PERCENT) {
311
+ state.level = 'yellow';
312
+ }
313
+ else {
314
+ state.level = 'normal';
315
+ // Reset compact tracking when context drops back to normal
316
+ if (previousLevel !== 'normal') {
317
+ state.compactAttempts = 0;
318
+ state.compactInProgress = false;
319
+ }
320
+ }
321
+ // Only fire events on level transitions (not repeated at same level)
322
+ if (state.level !== previousLevel && state.level !== 'normal') {
323
+ this.evaluateThresholds(state, previousLevel);
324
+ }
325
+ }
326
+ /**
327
+ * Evaluate threshold transitions and take appropriate actions.
328
+ *
329
+ * Strategy (compact-first):
330
+ * 1. Yellow (70%): Publish warning event only
331
+ * 2. Red (85%): Publish warning + trigger runtime-native compact/compress
332
+ * 3. Critical (95%): Retry compact; periodic checks will continue retrying
333
+ * with cooldown. Auto-recovery (kill + restart) only if enabled.
334
+ *
335
+ * @param state - Current context window state
336
+ * @param previousLevel - The level before this update
337
+ */
338
+ evaluateThresholds(state, previousLevel) {
339
+ this.logger.warn('Context window threshold crossed', {
340
+ sessionName: state.sessionName,
341
+ previousLevel,
342
+ newLevel: state.level,
343
+ contextPercent: state.contextPercent,
344
+ });
345
+ // Publish event for warning levels
346
+ if (state.level === 'yellow' || state.level === 'red') {
347
+ this.publishContextEvent(state, 'agent:context_warning');
348
+ }
349
+ // At red level: try compact before things get critical
350
+ if (state.level === 'red' && !state.compactInProgress) {
351
+ if (state.compactAttempts < CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_COMPACT_ATTEMPTS) {
352
+ this.triggerCompact(state).catch((err) => {
353
+ this.logger.error('Compact failed', {
354
+ sessionName: state.sessionName,
355
+ error: err instanceof Error ? err.message : String(err),
356
+ });
357
+ });
358
+ }
359
+ }
360
+ // Critical level: try compact, or fall back to recovery if enabled
361
+ if (state.level === 'critical') {
362
+ this.publishContextEvent(state, 'agent:context_critical');
363
+ // Try compact if we haven't hit the limit yet
364
+ if (!state.compactInProgress &&
365
+ state.compactAttempts < CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_COMPACT_ATTEMPTS) {
366
+ this.triggerCompact(state).catch((err) => {
367
+ this.logger.error('Compact at critical failed', {
368
+ sessionName: state.sessionName,
369
+ error: err instanceof Error ? err.message : String(err),
370
+ });
371
+ });
372
+ }
373
+ else if (CONTEXT_WINDOW_MONITOR_CONSTANTS.AUTO_RECOVERY_ENABLED &&
374
+ !state.recoveryTriggered) {
375
+ // Auto-recovery enabled and compact exhausted — kill + restart
376
+ state.recoveryTriggered = true;
377
+ this.triggerAutoRecovery(state).catch((err) => {
378
+ this.logger.error('Auto-recovery failed', {
379
+ sessionName: state.sessionName,
380
+ error: err instanceof Error ? err.message : String(err),
381
+ });
382
+ });
383
+ }
384
+ else if (!CONTEXT_WINDOW_MONITOR_CONSTANTS.AUTO_RECOVERY_ENABLED) {
385
+ // Auto-recovery disabled — periodic checks will retry compact
386
+ // after COMPACT_RETRY_COOLDOWN_MS via performCheck()
387
+ this.logger.warn('Context critical, compact exhausted, auto-recovery disabled. Periodic retry will continue.', {
388
+ sessionName: state.sessionName,
389
+ contextPercent: state.contextPercent,
390
+ compactAttempts: state.compactAttempts,
391
+ });
392
+ }
393
+ }
394
+ // Broadcast to frontend
395
+ this.broadcastContextWarning(state);
396
+ }
397
+ /**
398
+ * Publish a context event via the event bus.
399
+ *
400
+ * @param state - Context window state
401
+ * @param eventType - Event type to publish
402
+ */
403
+ publishContextEvent(state, eventType) {
404
+ if (!this.eventBusService) {
405
+ return;
406
+ }
407
+ const event = {
408
+ id: uuidv4(),
409
+ type: eventType,
410
+ timestamp: new Date().toISOString(),
411
+ teamId: state.teamId,
412
+ teamName: '',
413
+ memberId: state.memberId,
414
+ memberName: '',
415
+ sessionName: state.sessionName,
416
+ previousValue: String(state.contextPercent),
417
+ newValue: state.level,
418
+ changedField: 'contextUsage',
419
+ };
420
+ this.eventBusService.publish(event);
421
+ this.logger.info('Published context event', {
422
+ eventType,
423
+ sessionName: state.sessionName,
424
+ contextPercent: state.contextPercent,
425
+ level: state.level,
426
+ });
427
+ }
428
+ /**
429
+ * Broadcast context window status to frontend via WebSocket.
430
+ *
431
+ * @param state - Context window state to broadcast
432
+ */
433
+ broadcastContextWarning(state) {
434
+ const terminalGateway = getTerminalGateway();
435
+ if (!terminalGateway) {
436
+ return;
437
+ }
438
+ terminalGateway.broadcastContextWindowStatus({
439
+ sessionName: state.sessionName,
440
+ memberId: state.memberId,
441
+ teamId: state.teamId,
442
+ contextPercent: state.contextPercent,
443
+ level: state.level,
444
+ timestamp: new Date().toISOString(),
445
+ });
446
+ }
447
+ /**
448
+ * Trigger context compaction by sending the runtime's native compact command.
449
+ *
450
+ * Writes the appropriate slash command (e.g., `/compact` for Claude Code,
451
+ * `/compress` for Gemini CLI) to the PTY session stdin. The runtime handles
452
+ * the actual compression — typically via LLM-based summarization.
453
+ *
454
+ * @param state - Context window state for the session to compact
455
+ */
456
+ async triggerCompact(state) {
457
+ const backend = this.sessionBackend || getSessionBackendSync();
458
+ if (!backend) {
459
+ this.logger.warn('Cannot trigger compact: session backend not available', {
460
+ sessionName: state.sessionName,
461
+ });
462
+ return;
463
+ }
464
+ const session = backend.getSession(state.sessionName);
465
+ if (!session) {
466
+ this.logger.warn('Cannot trigger compact: session not found', {
467
+ sessionName: state.sessionName,
468
+ });
469
+ return;
470
+ }
471
+ const command = RUNTIME_COMPACT_COMMANDS[state.runtimeType];
472
+ if (!command) {
473
+ this.logger.warn('No compact command for runtime type', {
474
+ sessionName: state.sessionName,
475
+ runtimeType: state.runtimeType,
476
+ });
477
+ return;
478
+ }
479
+ state.compactInProgress = true;
480
+ state.compactAttempts++;
481
+ state.lastCompactAt = Date.now();
482
+ this.logger.info('Triggering context compaction', {
483
+ sessionName: state.sessionName,
484
+ runtimeType: state.runtimeType,
485
+ command,
486
+ attempt: state.compactAttempts,
487
+ contextPercent: state.contextPercent,
488
+ });
489
+ // Send Escape first to clear any in-progress input, then the compact command
490
+ session.write('\x1b');
491
+ await new Promise(resolve => setTimeout(resolve, 200));
492
+ session.write(command + '\r');
493
+ // After COMPACT_WAIT_MS, mark compact as no longer in progress
494
+ // so further threshold evaluations can proceed
495
+ setTimeout(() => {
496
+ state.compactInProgress = false;
497
+ }, CONTEXT_WINDOW_MONITOR_CONSTANTS.COMPACT_WAIT_MS);
498
+ // Broadcast compact status to frontend
499
+ const terminalGateway = getTerminalGateway();
500
+ if (terminalGateway) {
501
+ terminalGateway.broadcastContextWindowStatus({
502
+ sessionName: state.sessionName,
503
+ memberId: state.memberId,
504
+ teamId: state.teamId,
505
+ contextPercent: state.contextPercent,
506
+ level: state.level,
507
+ timestamp: new Date().toISOString(),
508
+ });
509
+ }
510
+ }
511
+ /**
512
+ * Trigger auto-recovery for a session at critical context usage.
513
+ *
514
+ * Mirrors the restart pattern from AgentHeartbeatMonitorService:
515
+ * 1. Check cooldown
516
+ * 2. Save Claude session ID
517
+ * 3. Stop exit monitoring
518
+ * 4. Kill PTY session
519
+ * 5. Clear activity tracker
520
+ * 6. Pre-set session ID for resume
521
+ * 7. Recreate agent session
522
+ * 8. Broadcast status
523
+ * 9. Re-deliver tasks
524
+ *
525
+ * @param state - Context window state for the session to recover
526
+ */
527
+ async triggerAutoRecovery(state) {
528
+ const backend = this.sessionBackend || getSessionBackendSync();
529
+ if (!backend || !this.agentRegistrationService) {
530
+ this.logger.warn('Cannot trigger auto-recovery: missing dependencies', {
531
+ sessionName: state.sessionName,
532
+ });
533
+ return;
534
+ }
535
+ // Check cooldown
536
+ const now = Date.now();
537
+ const windowStart = now - CONTEXT_WINDOW_MONITOR_CONSTANTS.COOLDOWN_WINDOW_MS;
538
+ state.recoveryTimestamps = state.recoveryTimestamps.filter(ts => ts > windowStart);
539
+ if (state.recoveryTimestamps.length >= CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_RECOVERIES_PER_WINDOW) {
540
+ this.logger.warn('Context recovery cooldown active, skipping', {
541
+ sessionName: state.sessionName,
542
+ recoveriesInWindow: state.recoveryTimestamps.length,
543
+ maxPerWindow: CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_RECOVERIES_PER_WINDOW,
544
+ });
545
+ return;
546
+ }
547
+ this.logger.info('Triggering context window auto-recovery', {
548
+ sessionName: state.sessionName,
549
+ contextPercent: state.contextPercent,
550
+ recoveryCount: state.recoveryCount,
551
+ });
552
+ try {
553
+ // Save Claude session ID before killing
554
+ let claudeSessionId;
555
+ try {
556
+ const persistence = getSessionStatePersistence();
557
+ claudeSessionId = persistence.getSessionId(state.sessionName);
558
+ }
559
+ catch {
560
+ this.logger.warn('Could not retrieve Claude session ID for recovery', {
561
+ sessionName: state.sessionName,
562
+ });
563
+ }
564
+ // Stop exit monitoring to avoid triggering exit callbacks
565
+ RuntimeExitMonitorService.getInstance().stopMonitoring(state.sessionName);
566
+ // Stop our own monitoring (will be re-started after session creation)
567
+ this.stopSessionMonitoring(state.sessionName);
568
+ // Kill old PTY session
569
+ if (backend.sessionExists(state.sessionName)) {
570
+ await backend.killSession(state.sessionName);
571
+ }
572
+ // Clear PTY activity tracker
573
+ PtyActivityTrackerService.getInstance().clearSession(state.sessionName);
574
+ // Pre-set session ID for resume
575
+ if (claudeSessionId) {
576
+ try {
577
+ const persistence = getSessionStatePersistence();
578
+ const metadata = persistence.getSessionMetadata(state.sessionName);
579
+ if (metadata) {
580
+ persistence.updateSessionId(state.sessionName, claudeSessionId);
581
+ }
582
+ }
583
+ catch {
584
+ this.logger.warn('Could not pre-set session ID for resume', {
585
+ sessionName: state.sessionName,
586
+ });
587
+ }
588
+ }
589
+ // Recreate agent session
590
+ const result = await this.agentRegistrationService.createAgentSession({
591
+ sessionName: state.sessionName,
592
+ role: state.role,
593
+ teamId: state.teamId,
594
+ memberId: state.memberId,
595
+ });
596
+ if (!result.success) {
597
+ this.logger.error('Context recovery createAgentSession failed', {
598
+ sessionName: state.sessionName,
599
+ error: result.error,
600
+ });
601
+ return;
602
+ }
603
+ // Track recovery
604
+ state.recoveryTimestamps.push(now);
605
+ state.recoveryCount++;
606
+ // Broadcast agent recovered status
607
+ const terminalGateway = getTerminalGateway();
608
+ if (terminalGateway) {
609
+ terminalGateway.broadcastTeamMemberStatus({
610
+ teamId: state.teamId,
611
+ memberId: state.memberId,
612
+ sessionName: state.sessionName,
613
+ agentStatus: 'active',
614
+ });
615
+ }
616
+ this.logger.info('Context window auto-recovery successful', {
617
+ sessionName: state.sessionName,
618
+ recoveryCount: state.recoveryCount,
619
+ claudeSessionId: claudeSessionId ? '(resumed)' : '(fresh)',
620
+ });
621
+ // Re-deliver in-progress tasks (async, non-blocking)
622
+ this.redeliverTasks(state).catch((err) => {
623
+ this.logger.error('Task re-delivery failed after context recovery', {
624
+ sessionName: state.sessionName,
625
+ error: err instanceof Error ? err.message : String(err),
626
+ });
627
+ });
628
+ }
629
+ catch (err) {
630
+ this.logger.error('Failed to perform context window auto-recovery', {
631
+ sessionName: state.sessionName,
632
+ error: err instanceof Error ? err.message : String(err),
633
+ });
634
+ }
635
+ }
636
+ /**
637
+ * Re-deliver in-progress tasks to a recovered agent.
638
+ *
639
+ * @param state - Context window state for the recovered session
640
+ */
641
+ async redeliverTasks(state) {
642
+ if (!this.taskTrackingService) {
643
+ return;
644
+ }
645
+ const backend = this.sessionBackend || getSessionBackendSync();
646
+ if (!backend) {
647
+ return;
648
+ }
649
+ // Wait for agent initialization
650
+ await new Promise(resolve => setTimeout(resolve, AGENT_SUSPEND_CONSTANTS.REHYDRATION_TIMEOUT_MS));
651
+ if (!backend.sessionExists(state.sessionName)) {
652
+ this.logger.warn('Agent session not found after recovery, skipping task re-delivery', {
653
+ sessionName: state.sessionName,
654
+ });
655
+ return;
656
+ }
657
+ const session = backend.getSession(state.sessionName);
658
+ if (!session) {
659
+ return;
660
+ }
661
+ const tasks = await this.taskTrackingService.getTasksForTeamMember(state.memberId);
662
+ const activeTasks = tasks.filter(t => t.status === 'assigned' || t.status === 'active');
663
+ if (activeTasks.length === 0) {
664
+ this.logger.debug('No active tasks to re-deliver after context recovery', {
665
+ sessionName: state.sessionName,
666
+ });
667
+ return;
668
+ }
669
+ this.logger.info('Re-delivering tasks after context recovery', {
670
+ sessionName: state.sessionName,
671
+ taskCount: activeTasks.length,
672
+ });
673
+ for (const task of activeTasks) {
674
+ let taskContent = '';
675
+ try {
676
+ taskContent = await fs.readFile(task.taskFilePath, 'utf-8');
677
+ if (taskContent.length > 2000) {
678
+ taskContent = taskContent.slice(0, 2000) + '\n... (truncated)';
679
+ }
680
+ }
681
+ catch {
682
+ taskContent = '(task file not found)';
683
+ }
684
+ const message = [
685
+ '[TASK RE-DELIVERY] Your previous session ran out of context window.',
686
+ 'You were working on this task before your session was recovered:',
687
+ `Task: ${task.taskName}`,
688
+ `File: ${task.taskFilePath}`,
689
+ '---',
690
+ taskContent,
691
+ '---',
692
+ 'Please continue working on this task.',
693
+ ].join('\n');
694
+ session.write(message);
695
+ const pasteDelay = Math.min(SESSION_COMMAND_DELAYS.MESSAGE_DELAY + Math.ceil(message.length / 10), 5000);
696
+ await new Promise(resolve => setTimeout(resolve, pasteDelay));
697
+ session.write('\r');
698
+ await new Promise(resolve => setTimeout(resolve, 2000));
699
+ }
700
+ this.logger.info('Task re-delivery after context recovery complete', {
701
+ sessionName: state.sessionName,
702
+ tasksDelivered: activeTasks.length,
703
+ });
704
+ }
705
+ /**
706
+ * Periodic check for stale states, cleanup, compact retries, and proactive compaction.
707
+ *
708
+ * For stale sessions (no context % detected recently), resets to normal.
709
+ * For critical sessions with exhausted compacts, retries compact after
710
+ * COMPACT_RETRY_COOLDOWN_MS has elapsed since the last attempt.
711
+ * For all monitored sessions, checks cumulative output bytes and triggers
712
+ * proactive compact when threshold is exceeded.
713
+ */
714
+ performCheck() {
715
+ const now = Date.now();
716
+ const staleThreshold = CONTEXT_WINDOW_MONITOR_CONSTANTS.STALE_DETECTION_THRESHOLD_MS;
717
+ // Proactive compact based on cumulative output volume
718
+ this.checkProactiveCompact(now);
719
+ for (const [sessionName, state] of this.contextStates) {
720
+ const timeSinceLastDetection = now - state.lastDetectedAt;
721
+ // Clean up stale states (no context % detected for a while)
722
+ if (timeSinceLastDetection > staleThreshold && state.level !== 'normal') {
723
+ this.logger.debug('Context state stale, resetting to normal', {
724
+ sessionName,
725
+ timeSinceLastDetectionMs: timeSinceLastDetection,
726
+ });
727
+ state.level = 'normal';
728
+ state.recoveryTriggered = false;
729
+ state.compactAttempts = 0;
730
+ state.compactInProgress = false;
731
+ continue;
732
+ }
733
+ // Retry compact for critical sessions after cooldown
734
+ if (state.level === 'critical' &&
735
+ !state.compactInProgress &&
736
+ !state.recoveryTriggered &&
737
+ state.compactAttempts >= CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_COMPACT_ATTEMPTS) {
738
+ const timeSinceLastCompact = now - state.lastCompactAt;
739
+ if (timeSinceLastCompact >= CONTEXT_WINDOW_MONITOR_CONSTANTS.COMPACT_RETRY_COOLDOWN_MS) {
740
+ this.logger.info('Retrying compact after cooldown for critical session', {
741
+ sessionName,
742
+ contextPercent: state.contextPercent,
743
+ compactAttempts: state.compactAttempts,
744
+ timeSinceLastCompactMs: timeSinceLastCompact,
745
+ });
746
+ // Reset attempts to allow one more try
747
+ state.compactAttempts = CONTEXT_WINDOW_MONITOR_CONSTANTS.MAX_COMPACT_ATTEMPTS - 1;
748
+ this.triggerCompact(state).catch((err) => {
749
+ this.logger.error('Compact retry failed', {
750
+ sessionName: state.sessionName,
751
+ error: err instanceof Error ? err.message : String(err),
752
+ });
753
+ });
754
+ }
755
+ }
756
+ }
757
+ }
758
+ /** Timestamp of last proactive compact per session for cooldown tracking */
759
+ proactiveCompactLastTriggered = new Map();
760
+ /**
761
+ * Check all monitored sessions for cumulative output volume and trigger
762
+ * proactive compact when the threshold is exceeded.
763
+ *
764
+ * @param now - Current timestamp in epoch ms
765
+ */
766
+ checkProactiveCompact(now) {
767
+ const backend = this.sessionBackend || getSessionBackendSync();
768
+ if (!backend || !backend.getCumulativeOutputBytes || !backend.resetCumulativeOutput) {
769
+ return;
770
+ }
771
+ for (const [sessionName, state] of this.contextStates) {
772
+ if (state.compactInProgress) {
773
+ continue;
774
+ }
775
+ const cumulativeBytes = backend.getCumulativeOutputBytes(sessionName);
776
+ if (cumulativeBytes < CONTEXT_WINDOW_MONITOR_CONSTANTS.PROACTIVE_COMPACT_THRESHOLD_BYTES) {
777
+ continue;
778
+ }
779
+ // Check cooldown
780
+ const lastTriggered = this.proactiveCompactLastTriggered.get(sessionName) ?? 0;
781
+ if (now - lastTriggered < CONTEXT_WINDOW_MONITOR_CONSTANTS.PROACTIVE_COMPACT_COOLDOWN_MS) {
782
+ continue;
783
+ }
784
+ this.logger.info('Proactive compact triggered by cumulative output volume', {
785
+ sessionName,
786
+ cumulativeBytes,
787
+ thresholdBytes: CONTEXT_WINDOW_MONITOR_CONSTANTS.PROACTIVE_COMPACT_THRESHOLD_BYTES,
788
+ });
789
+ this.proactiveCompactLastTriggered.set(sessionName, now);
790
+ backend.resetCumulativeOutput(sessionName);
791
+ this.triggerCompact(state).catch((err) => {
792
+ this.logger.error('Proactive compact failed', {
793
+ sessionName,
794
+ error: err instanceof Error ? err.message : String(err),
795
+ });
796
+ });
797
+ }
798
+ }
799
+ /**
800
+ * Destroy all PTY subscriptions. Used during resetInstance.
801
+ */
802
+ destroyAllSubscriptions() {
803
+ for (const [sessionName, sub] of this.sessionSubscriptions) {
804
+ sub.unsubscribe();
805
+ }
806
+ this.sessionSubscriptions.clear();
807
+ this.contextStates.clear();
808
+ this.proactiveCompactLastTriggered.clear();
809
+ }
810
+ }
811
+ //# sourceMappingURL=context-window-monitor.service.js.map