factory-factory 0.3.8 → 0.3.9

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 (377) hide show
  1. package/dist/client/assets/{_basePickBy-BzH_iru3.js → _basePickBy-CoLLbaiQ.js} +1 -1
  2. package/dist/client/assets/{_baseUniq-D6ny9r_u.js → _baseUniq-xRgxfXUW.js} +1 -1
  3. package/dist/client/assets/{arc-CRVgibiy.js → arc-De4Ny3V9.js} +1 -1
  4. package/dist/client/assets/{architectureDiagram-VXUJARFQ-1aDFSaTZ.js → architectureDiagram-VXUJARFQ-DM0j158z.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-VD42YOAC-m3mDHY-k.js → blockDiagram-VD42YOAC-DKBZN-sz.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-YG6GDRKO-B7ZlkfXz.js → c4Diagram-YG6GDRKO-CIA6AVRp.js} +1 -1
  7. package/dist/client/assets/channel-DW2o9xrZ.js +1 -0
  8. package/dist/client/assets/{chunk-4BX2VUAB-zLj9eiFf.js → chunk-4BX2VUAB-BrHsCtgI.js} +1 -1
  9. package/dist/client/assets/{chunk-55IACEB6-D6KQTgyD.js → chunk-55IACEB6-DLwlJB2L.js} +1 -1
  10. package/dist/client/assets/{chunk-B4BG7PRW-BQbzvx8l.js → chunk-B4BG7PRW-cqTY9ldj.js} +1 -1
  11. package/dist/client/assets/{chunk-DI55MBZ5-CPxKCw_e.js → chunk-DI55MBZ5-PAp7fYLU.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-nFaeGtHP.js → chunk-FMBD7UC4-CsvpScij.js} +1 -1
  13. package/dist/client/assets/{chunk-QN33PNHL-DhrGqSLY.js → chunk-QN33PNHL-DmkkCoc-.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-CZWrGmvf.js → chunk-QZHKN3VN-Ds5Tjlpo.js} +1 -1
  15. package/dist/client/assets/{chunk-TZMSLE5B-xhHdVO37.js → chunk-TZMSLE5B-4Gu0uKkR.js} +1 -1
  16. package/dist/client/assets/classDiagram-2ON5EDUG-CUeZuC6S.js +1 -0
  17. package/dist/client/assets/classDiagram-v2-WZHVMYZB-CUeZuC6S.js +1 -0
  18. package/dist/client/assets/clone-Df9JDgIw.js +1 -0
  19. package/dist/client/assets/{cose-bilkent-S5V4N54A-Cr0HX6ro.js → cose-bilkent-S5V4N54A-CQJ_MgcD.js} +1 -1
  20. package/dist/client/assets/{dagre-6UL2VRFP-s6RRMHqY.js → dagre-6UL2VRFP-CfyncTju.js} +1 -1
  21. package/dist/client/assets/{diagram-PSM6KHXK-BhdZNVs7.js → diagram-PSM6KHXK-BL2QA0bQ.js} +1 -1
  22. package/dist/client/assets/{diagram-QEK2KX5R-Dgwc4sx_.js → diagram-QEK2KX5R-BDcBrJO4.js} +1 -1
  23. package/dist/client/assets/{diagram-S2PKOQOG-BlcMpYrQ.js → diagram-S2PKOQOG-BxofoMik.js} +1 -1
  24. package/dist/client/assets/{erDiagram-Q2GNP2WA-BQQjswcC.js → erDiagram-Q2GNP2WA-CDGe-bUA.js} +1 -1
  25. package/dist/client/assets/{flowDiagram-NV44I4VS-_cBTH43Q.js → flowDiagram-NV44I4VS-CodDw20I.js} +1 -1
  26. package/dist/client/assets/{ganttDiagram-JELNMOA3-BxuyB7Oz.js → ganttDiagram-JELNMOA3-BHJlNcF5.js} +1 -1
  27. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-D0GjSYQi.js → gitGraphDiagram-V2S2FVAM-DsFPFnxn.js} +1 -1
  28. package/dist/client/assets/{graph-DNCXrik3.js → graph-DtyTGYVa.js} +1 -1
  29. package/dist/client/assets/index-BkwQogmx.css +1 -0
  30. package/dist/client/assets/{index-CCnMDzRJ.js → index-CSanKe06.js} +175 -175
  31. package/dist/client/assets/{infoDiagram-HS3SLOUP-BsUKtNMj.js → infoDiagram-HS3SLOUP-CczckdeY.js} +1 -1
  32. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-sScoNj-6.js → journeyDiagram-XKPGCS4Q-CIDlGmYi.js} +1 -1
  33. package/dist/client/assets/{kanban-definition-3W4ZIXB7-CycFvltk.js → kanban-definition-3W4ZIXB7-Dvuu9eqr.js} +1 -1
  34. package/dist/client/assets/{layout-LTiJ8avf.js → layout-Cth5sJm6.js} +1 -1
  35. package/dist/client/assets/{linear-CnQEAniJ.js → linear-DRv-Y17x.js} +1 -1
  36. package/dist/client/assets/{mindmap-definition-VGOIOE7T-Du5mb-g5.js → mindmap-definition-VGOIOE7T-AXsc24V4.js} +1 -1
  37. package/dist/client/assets/{mobile-baseline-necQV4Mu.js → mobile-baseline-DXBPdrir.js} +1 -1
  38. package/dist/client/assets/{pieDiagram-ADFJNKIX-CUAEo70K.js → pieDiagram-ADFJNKIX-oIn8Bgi4.js} +1 -1
  39. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-1MjtTI_Y.js → quadrantDiagram-AYHSOK5B-rGTqNh3q.js} +1 -1
  40. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-zgmi2Sjr.js → requirementDiagram-UZGBJVZJ-DgE2dYES.js} +1 -1
  41. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-Datw0Rj8.js → sankeyDiagram-TZEHDZUN-BWRLa217.js} +1 -1
  42. package/dist/client/assets/{sequenceDiagram-WL72ISMW-DopxoRon.js → sequenceDiagram-WL72ISMW-lYEkh9VX.js} +1 -1
  43. package/dist/client/assets/{stateDiagram-FKZM4ZOC-ZqoVSvsu.js → stateDiagram-FKZM4ZOC-CV9VCuVK.js} +1 -1
  44. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-DQ10FejB.js +1 -0
  45. package/dist/client/assets/{terminal-instance-gybkMDHu.js → terminal-instance-C3nwiweh.js} +1 -1
  46. package/dist/client/assets/{timeline-definition-IT6M3QCI-DQwpSE-n.js → timeline-definition-IT6M3QCI-Bzm_qoWF.js} +1 -1
  47. package/dist/client/assets/{treemap-GDKQZRPO-DK4UuMc6.js → treemap-GDKQZRPO-gouxKMUq.js} +1 -1
  48. package/dist/client/assets/{xychartDiagram-PRI3JC2R-CJP1ULwR.js → xychartDiagram-PRI3JC2R-DqSTMw-l.js} +1 -1
  49. package/dist/client/index.html +2 -2
  50. package/dist/prisma/generated/enums.d.ts +1 -0
  51. package/dist/prisma/generated/enums.d.ts.map +1 -1
  52. package/dist/prisma/generated/enums.js +1 -0
  53. package/dist/prisma/generated/enums.js.map +1 -1
  54. package/dist/prisma/generated/internal/class.js +1 -1
  55. package/dist/prisma/generated/internal/class.js.map +1 -1
  56. package/dist/src/backend/app-context.d.ts.map +1 -1
  57. package/dist/src/backend/app-context.js +3 -0
  58. package/dist/src/backend/app-context.js.map +1 -1
  59. package/dist/src/backend/domains/github/github-cli/mappers.d.ts +1 -1
  60. package/dist/src/backend/domains/github/github-cli/mappers.d.ts.map +1 -1
  61. package/dist/src/backend/domains/github/github-cli/mappers.js +2 -37
  62. package/dist/src/backend/domains/github/github-cli/mappers.js.map +1 -1
  63. package/dist/src/backend/domains/github/github-cli.service.test.js +20 -0
  64. package/dist/src/backend/domains/github/github-cli.service.test.js.map +1 -1
  65. package/dist/src/backend/domains/linear/linear-state-sync.service.d.ts.map +1 -1
  66. package/dist/src/backend/domains/linear/linear-state-sync.service.js.map +1 -1
  67. package/dist/src/backend/domains/ratchet/bridges.d.ts +4 -0
  68. package/dist/src/backend/domains/ratchet/bridges.d.ts.map +1 -1
  69. package/dist/src/backend/domains/ratchet/ratchet-active-session.helpers.d.ts +15 -0
  70. package/dist/src/backend/domains/ratchet/ratchet-active-session.helpers.d.ts.map +1 -0
  71. package/dist/src/backend/domains/ratchet/ratchet-active-session.helpers.js +126 -0
  72. package/dist/src/backend/domains/ratchet/ratchet-active-session.helpers.js.map +1 -0
  73. package/dist/src/backend/domains/ratchet/ratchet-fixer-dispatch.helpers.d.ts +14 -0
  74. package/dist/src/backend/domains/ratchet/ratchet-fixer-dispatch.helpers.d.ts.map +1 -0
  75. package/dist/src/backend/domains/ratchet/ratchet-fixer-dispatch.helpers.js +55 -0
  76. package/dist/src/backend/domains/ratchet/ratchet-fixer-dispatch.helpers.js.map +1 -0
  77. package/dist/src/backend/domains/ratchet/ratchet-pr-state.helpers.d.ts +107 -0
  78. package/dist/src/backend/domains/ratchet/ratchet-pr-state.helpers.d.ts.map +1 -0
  79. package/dist/src/backend/domains/ratchet/ratchet-pr-state.helpers.js +246 -0
  80. package/dist/src/backend/domains/ratchet/ratchet-pr-state.helpers.js.map +1 -0
  81. package/dist/src/backend/domains/ratchet/ratchet-review-poll.helpers.d.ts +16 -0
  82. package/dist/src/backend/domains/ratchet/ratchet-review-poll.helpers.d.ts.map +1 -0
  83. package/dist/src/backend/domains/ratchet/ratchet-review-poll.helpers.js +52 -0
  84. package/dist/src/backend/domains/ratchet/ratchet-review-poll.helpers.js.map +1 -0
  85. package/dist/src/backend/domains/ratchet/ratchet.service.d.ts +6 -40
  86. package/dist/src/backend/domains/ratchet/ratchet.service.d.ts.map +1 -1
  87. package/dist/src/backend/domains/ratchet/ratchet.service.js +99 -426
  88. package/dist/src/backend/domains/ratchet/ratchet.service.js.map +1 -1
  89. package/dist/src/backend/domains/ratchet/ratchet.types.d.ts +86 -0
  90. package/dist/src/backend/domains/ratchet/ratchet.types.d.ts.map +1 -0
  91. package/dist/src/backend/domains/ratchet/ratchet.types.js +2 -0
  92. package/dist/src/backend/domains/ratchet/ratchet.types.js.map +1 -0
  93. package/dist/src/backend/domains/ratchet/reconciliation.service.d.ts.map +1 -1
  94. package/dist/src/backend/domains/ratchet/reconciliation.service.js +1 -2
  95. package/dist/src/backend/domains/ratchet/reconciliation.service.js.map +1 -1
  96. package/dist/src/backend/domains/ratchet/reconciliation.service.test.js +8 -10
  97. package/dist/src/backend/domains/ratchet/reconciliation.service.test.js.map +1 -1
  98. package/dist/src/backend/domains/run-script/run-script.service.d.ts +1 -0
  99. package/dist/src/backend/domains/run-script/run-script.service.d.ts.map +1 -1
  100. package/dist/src/backend/domains/run-script/run-script.service.js +46 -19
  101. package/dist/src/backend/domains/run-script/run-script.service.js.map +1 -1
  102. package/dist/src/backend/domains/run-script/run-script.service.test.js +118 -0
  103. package/dist/src/backend/domains/run-script/run-script.service.test.js.map +1 -1
  104. package/dist/src/backend/domains/session/acp/acp-event-translator.d.ts +13 -1
  105. package/dist/src/backend/domains/session/acp/acp-event-translator.d.ts.map +1 -1
  106. package/dist/src/backend/domains/session/acp/acp-event-translator.js +86 -1
  107. package/dist/src/backend/domains/session/acp/acp-event-translator.js.map +1 -1
  108. package/dist/src/backend/domains/session/acp/acp-event-translator.test.js +39 -0
  109. package/dist/src/backend/domains/session/acp/acp-event-translator.test.js.map +1 -1
  110. package/dist/src/backend/domains/session/acp/acp-runtime-manager.d.ts +5 -0
  111. package/dist/src/backend/domains/session/acp/acp-runtime-manager.d.ts.map +1 -1
  112. package/dist/src/backend/domains/session/acp/acp-runtime-manager.js +12 -12
  113. package/dist/src/backend/domains/session/acp/acp-runtime-manager.js.map +1 -1
  114. package/dist/src/backend/domains/session/acp/acp-runtime-manager.test.js +3 -12
  115. package/dist/src/backend/domains/session/acp/acp-runtime-manager.test.js.map +1 -1
  116. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.d.ts +1 -0
  117. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.d.ts.map +1 -1
  118. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.js +3 -0
  119. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.js.map +1 -1
  120. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.d.ts +14 -15
  121. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.d.ts.map +1 -1
  122. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.js +74 -568
  123. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.js.map +1 -1
  124. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/retry-logic.d.ts +16 -0
  125. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/retry-logic.d.ts.map +1 -0
  126. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/retry-logic.js +53 -0
  127. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/retry-logic.js.map +1 -0
  128. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-config-resolver.d.ts +20 -0
  129. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-config-resolver.d.ts.map +1 -0
  130. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-config-resolver.js +341 -0
  131. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-config-resolver.js.map +1 -0
  132. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-negotiation.d.ts +41 -0
  133. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-negotiation.d.ts.map +1 -0
  134. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-negotiation.js +137 -0
  135. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-negotiation.js.map +1 -0
  136. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-state-container.d.ts +25 -0
  137. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-state-container.d.ts.map +1 -0
  138. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-state-container.js +47 -0
  139. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/session-state-container.js.map +1 -0
  140. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/shape-drift-reporter.d.ts +8 -0
  141. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/shape-drift-reporter.d.ts.map +1 -0
  142. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/shape-drift-reporter.js +37 -0
  143. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/shape-drift-reporter.js.map +1 -0
  144. package/dist/src/backend/domains/session/bridges.d.ts +5 -0
  145. package/dist/src/backend/domains/session/bridges.d.ts.map +1 -1
  146. package/dist/src/backend/domains/session/chat/chat-message-handlers/handlers/load-session.handler.d.ts.map +1 -1
  147. package/dist/src/backend/domains/session/chat/chat-message-handlers/handlers/load-session.handler.js +2 -2
  148. package/dist/src/backend/domains/session/chat/chat-message-handlers/handlers/load-session.handler.js.map +1 -1
  149. package/dist/src/backend/domains/session/chat/chat-message-handlers/handlers/load-session.handler.test.js +1 -1
  150. package/dist/src/backend/domains/session/chat/chat-message-handlers/handlers/load-session.handler.test.js.map +1 -1
  151. package/dist/src/backend/domains/session/chat/chat-message-handlers.service.js +2 -2
  152. package/dist/src/backend/domains/session/chat/chat-message-handlers.service.js.map +1 -1
  153. package/dist/src/backend/domains/session/data/{claude-session-history-loader.service.d.ts → session-history-loader.service.d.ts} +1 -1
  154. package/dist/src/backend/domains/session/data/session-history-loader.service.d.ts.map +1 -0
  155. package/dist/src/backend/domains/session/data/{claude-session-history-loader.service.js → session-history-loader.service.js} +4 -4
  156. package/dist/src/backend/domains/session/data/session-history-loader.service.js.map +1 -0
  157. package/dist/src/backend/domains/session/data/session-history-loader.service.test.d.ts +2 -0
  158. package/dist/src/backend/domains/session/data/session-history-loader.service.test.d.ts.map +1 -0
  159. package/dist/src/backend/domains/session/data/{claude-session-history-loader.service.test.js → session-history-loader.service.test.js} +6 -3
  160. package/dist/src/backend/domains/session/data/session-history-loader.service.test.js.map +1 -0
  161. package/dist/src/backend/domains/session/lifecycle/acp-event-processor.d.ts +71 -0
  162. package/dist/src/backend/domains/session/lifecycle/acp-event-processor.d.ts.map +1 -0
  163. package/dist/src/backend/domains/session/lifecycle/acp-event-processor.js +404 -0
  164. package/dist/src/backend/domains/session/lifecycle/acp-event-processor.js.map +1 -0
  165. package/dist/src/backend/domains/session/lifecycle/session.repository.d.ts +0 -2
  166. package/dist/src/backend/domains/session/lifecycle/session.repository.d.ts.map +1 -1
  167. package/dist/src/backend/domains/session/lifecycle/session.repository.js +0 -3
  168. package/dist/src/backend/domains/session/lifecycle/session.repository.js.map +1 -1
  169. package/dist/src/backend/domains/session/lifecycle/session.repository.test.js +0 -1
  170. package/dist/src/backend/domains/session/lifecycle/session.repository.test.js.map +1 -1
  171. package/dist/src/backend/domains/session/lifecycle/session.service.d.ts +8 -27
  172. package/dist/src/backend/domains/session/lifecycle/session.service.d.ts.map +1 -1
  173. package/dist/src/backend/domains/session/lifecycle/session.service.js +64 -376
  174. package/dist/src/backend/domains/session/lifecycle/session.service.js.map +1 -1
  175. package/dist/src/backend/domains/session/lifecycle/session.service.test.js +92 -21
  176. package/dist/src/backend/domains/session/lifecycle/session.service.test.js.map +1 -1
  177. package/dist/src/backend/domains/session/logging/acp-trace-logger.service.d.ts.map +1 -1
  178. package/dist/src/backend/domains/session/logging/acp-trace-logger.service.js +2 -13
  179. package/dist/src/backend/domains/session/logging/acp-trace-logger.service.js.map +1 -1
  180. package/dist/src/backend/domains/session/logging/acp-trace-logger.service.test.js +15 -3
  181. package/dist/src/backend/domains/session/logging/acp-trace-logger.service.test.js.map +1 -1
  182. package/dist/src/backend/domains/session/logging/session-file-logger.service.js +1 -1
  183. package/dist/src/backend/domains/session/logging/session-file-logger.service.js.map +1 -1
  184. package/dist/src/backend/domains/session/logging/session-file-logger.service.test.js +3 -0
  185. package/dist/src/backend/domains/session/logging/session-file-logger.service.test.js.map +1 -1
  186. package/dist/src/backend/domains/session/session-domain.service.d.ts.map +1 -1
  187. package/dist/src/backend/domains/session/session-domain.service.js +16 -0
  188. package/dist/src/backend/domains/session/session-domain.service.js.map +1 -1
  189. package/dist/src/backend/domains/session/session-domain.service.test.js +34 -0
  190. package/dist/src/backend/domains/session/session-domain.service.test.js.map +1 -1
  191. package/dist/src/backend/domains/session/store/file-lock.service.d.ts.map +1 -1
  192. package/dist/src/backend/domains/session/store/file-lock.service.js +2 -4
  193. package/dist/src/backend/domains/session/store/file-lock.service.js.map +1 -1
  194. package/dist/src/backend/domains/session/store/file-lock.service.test.js +3 -0
  195. package/dist/src/backend/domains/session/store/file-lock.service.test.js.map +1 -1
  196. package/dist/src/backend/domains/workspace/index.d.ts +0 -1
  197. package/dist/src/backend/domains/workspace/index.d.ts.map +1 -1
  198. package/dist/src/backend/domains/workspace/index.js +0 -1
  199. package/dist/src/backend/domains/workspace/index.js.map +1 -1
  200. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.d.ts +8 -0
  201. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.d.ts.map +1 -1
  202. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.js +47 -5
  203. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.js.map +1 -1
  204. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.test.js +117 -22
  205. package/dist/src/backend/domains/workspace/lifecycle/state-machine.service.test.js.map +1 -1
  206. package/dist/src/backend/domains/workspace/query/workspace-query.service.d.ts.map +1 -1
  207. package/dist/src/backend/domains/workspace/query/workspace-query.service.js +48 -44
  208. package/dist/src/backend/domains/workspace/query/workspace-query.service.js.map +1 -1
  209. package/dist/src/backend/domains/workspace/query/workspace-query.service.test.js +137 -97
  210. package/dist/src/backend/domains/workspace/query/workspace-query.service.test.js.map +1 -1
  211. package/dist/src/backend/domains/workspace/state/flow-state.d.ts +2 -2
  212. package/dist/src/backend/domains/workspace/state/flow-state.d.ts.map +1 -1
  213. package/dist/src/backend/domains/workspace/state/flow-state.js.map +1 -1
  214. package/dist/src/backend/domains/workspace/state/init-policy.js +1 -1
  215. package/dist/src/backend/domains/workspace/state/init-policy.js.map +1 -1
  216. package/dist/src/backend/domains/workspace/state/kanban-state.d.ts.map +1 -1
  217. package/dist/src/backend/domains/workspace/state/kanban-state.js +3 -2
  218. package/dist/src/backend/domains/workspace/state/kanban-state.js.map +1 -1
  219. package/dist/src/backend/interceptors/conversation-rename.interceptor.d.ts.map +1 -1
  220. package/dist/src/backend/interceptors/conversation-rename.interceptor.js +16 -2
  221. package/dist/src/backend/interceptors/conversation-rename.interceptor.js.map +1 -1
  222. package/dist/src/backend/interceptors/conversation-rename.interceptor.test.js +15 -3
  223. package/dist/src/backend/interceptors/conversation-rename.interceptor.test.js.map +1 -1
  224. package/dist/src/backend/interceptors/index.d.ts +2 -0
  225. package/dist/src/backend/interceptors/index.d.ts.map +1 -1
  226. package/dist/src/backend/interceptors/index.js +6 -0
  227. package/dist/src/backend/interceptors/index.js.map +1 -1
  228. package/dist/src/backend/interceptors/pre-pr-rename.interceptor.d.ts.map +1 -1
  229. package/dist/src/backend/interceptors/pre-pr-rename.interceptor.js +8 -0
  230. package/dist/src/backend/interceptors/pre-pr-rename.interceptor.js.map +1 -1
  231. package/dist/src/backend/interceptors/pre-pr-rename.interceptor.test.js +5 -1
  232. package/dist/src/backend/interceptors/pre-pr-rename.interceptor.test.js.map +1 -1
  233. package/dist/src/backend/interceptors/pre-push-rename.interceptor.d.ts.map +1 -1
  234. package/dist/src/backend/interceptors/pre-push-rename.interceptor.js +3 -0
  235. package/dist/src/backend/interceptors/pre-push-rename.interceptor.js.map +1 -1
  236. package/dist/src/backend/interceptors/registry.d.ts +5 -0
  237. package/dist/src/backend/interceptors/registry.d.ts.map +1 -1
  238. package/dist/src/backend/interceptors/registry.js +51 -0
  239. package/dist/src/backend/interceptors/registry.js.map +1 -1
  240. package/dist/src/backend/interceptors/types.d.ts +2 -0
  241. package/dist/src/backend/interceptors/types.d.ts.map +1 -1
  242. package/dist/src/backend/lib/workspace-derived-state.d.ts +47 -0
  243. package/dist/src/backend/lib/workspace-derived-state.d.ts.map +1 -0
  244. package/dist/src/backend/lib/workspace-derived-state.js +31 -0
  245. package/dist/src/backend/lib/workspace-derived-state.js.map +1 -0
  246. package/dist/src/backend/lib/workspace-derived-state.test.d.ts +2 -0
  247. package/dist/src/backend/lib/workspace-derived-state.test.d.ts.map +1 -0
  248. package/dist/src/backend/lib/workspace-derived-state.test.js +66 -0
  249. package/dist/src/backend/lib/workspace-derived-state.test.js.map +1 -0
  250. package/dist/src/backend/orchestration/domain-bridges.orchestrator.d.ts.map +1 -1
  251. package/dist/src/backend/orchestration/domain-bridges.orchestrator.js +3 -0
  252. package/dist/src/backend/orchestration/domain-bridges.orchestrator.js.map +1 -1
  253. package/dist/src/backend/orchestration/domain-bridges.orchestrator.test.js +19 -1
  254. package/dist/src/backend/orchestration/domain-bridges.orchestrator.test.js.map +1 -1
  255. package/dist/src/backend/orchestration/workspace-archive.orchestrator.d.ts.map +1 -1
  256. package/dist/src/backend/orchestration/workspace-archive.orchestrator.js +16 -6
  257. package/dist/src/backend/orchestration/workspace-archive.orchestrator.js.map +1 -1
  258. package/dist/src/backend/orchestration/workspace-archive.orchestrator.test.js +63 -30
  259. package/dist/src/backend/orchestration/workspace-archive.orchestrator.test.js.map +1 -1
  260. package/dist/src/backend/orchestration/workspace-init-script-pipeline.d.ts +18 -0
  261. package/dist/src/backend/orchestration/workspace-init-script-pipeline.d.ts.map +1 -0
  262. package/dist/src/backend/orchestration/workspace-init-script-pipeline.js +75 -0
  263. package/dist/src/backend/orchestration/workspace-init-script-pipeline.js.map +1 -0
  264. package/dist/src/backend/orchestration/workspace-init.orchestrator.d.ts.map +1 -1
  265. package/dist/src/backend/orchestration/workspace-init.orchestrator.js +22 -73
  266. package/dist/src/backend/orchestration/workspace-init.orchestrator.js.map +1 -1
  267. package/dist/src/backend/orchestration/workspace-init.orchestrator.test.js +75 -16
  268. package/dist/src/backend/orchestration/workspace-init.orchestrator.test.js.map +1 -1
  269. package/dist/src/backend/resource_accessors/project.accessor.js +1 -1
  270. package/dist/src/backend/resource_accessors/project.accessor.js.map +1 -1
  271. package/dist/src/backend/routers/websocket/snapshots.handler.d.ts.map +1 -1
  272. package/dist/src/backend/routers/websocket/snapshots.handler.js +17 -6
  273. package/dist/src/backend/routers/websocket/snapshots.handler.js.map +1 -1
  274. package/dist/src/backend/routers/websocket/snapshots.handler.test.js +40 -5
  275. package/dist/src/backend/routers/websocket/snapshots.handler.test.js.map +1 -1
  276. package/dist/src/backend/routers/websocket/websocket.integration.test.js +1 -0
  277. package/dist/src/backend/routers/websocket/websocket.integration.test.js.map +1 -1
  278. package/dist/src/backend/server.d.ts.map +1 -1
  279. package/dist/src/backend/server.js +6 -2
  280. package/dist/src/backend/server.js.map +1 -1
  281. package/dist/src/backend/server.upgrade.test.js +2 -0
  282. package/dist/src/backend/server.upgrade.test.js.map +1 -1
  283. package/dist/src/backend/services/check-single-writer.test.d.ts +2 -0
  284. package/dist/src/backend/services/check-single-writer.test.d.ts.map +1 -0
  285. package/dist/src/backend/services/check-single-writer.test.js +132 -0
  286. package/dist/src/backend/services/check-single-writer.test.js.map +1 -0
  287. package/dist/src/backend/services/config.service.d.ts +14 -6
  288. package/dist/src/backend/services/config.service.d.ts.map +1 -1
  289. package/dist/src/backend/services/config.service.js +31 -9
  290. package/dist/src/backend/services/config.service.js.map +1 -1
  291. package/dist/src/backend/services/env-schemas.d.ts +7 -3
  292. package/dist/src/backend/services/env-schemas.d.ts.map +1 -1
  293. package/dist/src/backend/services/env-schemas.js +19 -3
  294. package/dist/src/backend/services/env-schemas.js.map +1 -1
  295. package/dist/src/backend/services/run-script-config-persistence.service.d.ts +37 -0
  296. package/dist/src/backend/services/run-script-config-persistence.service.d.ts.map +1 -0
  297. package/dist/src/backend/services/run-script-config-persistence.service.js +73 -0
  298. package/dist/src/backend/services/run-script-config-persistence.service.js.map +1 -0
  299. package/dist/src/backend/services/run-script-config-persistence.service.test.d.ts +2 -0
  300. package/dist/src/backend/services/run-script-config-persistence.service.test.d.ts.map +1 -0
  301. package/dist/src/backend/services/run-script-config-persistence.service.test.js +111 -0
  302. package/dist/src/backend/services/run-script-config-persistence.service.test.js.map +1 -0
  303. package/dist/src/backend/services/run-script-proxy.service.d.ts.map +1 -1
  304. package/dist/src/backend/services/run-script-proxy.service.js +2 -1
  305. package/dist/src/backend/services/run-script-proxy.service.js.map +1 -1
  306. package/dist/src/backend/services/run-script-proxy.service.test.js +4 -0
  307. package/dist/src/backend/services/run-script-proxy.service.test.js.map +1 -1
  308. package/dist/src/backend/services/workspace-snapshot-store.service.d.ts +3 -3
  309. package/dist/src/backend/services/workspace-snapshot-store.service.d.ts.map +1 -1
  310. package/dist/src/backend/services/workspace-snapshot-store.service.js +13 -12
  311. package/dist/src/backend/services/workspace-snapshot-store.service.js.map +1 -1
  312. package/dist/src/backend/services/workspace-snapshot-store.service.test.js +3 -0
  313. package/dist/src/backend/services/workspace-snapshot-store.service.test.js.map +1 -1
  314. package/dist/src/backend/trpc/admin.router.test.js +0 -2
  315. package/dist/src/backend/trpc/admin.router.test.js.map +1 -1
  316. package/dist/src/backend/trpc/admin.trpc.d.ts +2 -7
  317. package/dist/src/backend/trpc/admin.trpc.d.ts.map +1 -1
  318. package/dist/src/backend/trpc/admin.trpc.js +0 -1
  319. package/dist/src/backend/trpc/admin.trpc.js.map +1 -1
  320. package/dist/src/backend/trpc/index.d.ts +8 -13
  321. package/dist/src/backend/trpc/index.d.ts.map +1 -1
  322. package/dist/src/backend/trpc/project.trpc.d.ts +3 -3
  323. package/dist/src/backend/trpc/workspace/run-script.router.test.js +31 -4
  324. package/dist/src/backend/trpc/workspace/run-script.router.test.js.map +1 -1
  325. package/dist/src/backend/trpc/workspace/run-script.trpc.d.ts.map +1 -1
  326. package/dist/src/backend/trpc/workspace/run-script.trpc.js +8 -8
  327. package/dist/src/backend/trpc/workspace/run-script.trpc.js.map +1 -1
  328. package/dist/src/backend/trpc/workspace.router.test.js +6 -1
  329. package/dist/src/backend/trpc/workspace.router.test.js.map +1 -1
  330. package/dist/src/backend/trpc/workspace.trpc.d.ts +3 -3
  331. package/dist/src/backend/trpc/workspace.trpc.d.ts.map +1 -1
  332. package/dist/src/backend/trpc/workspace.trpc.js +19 -13
  333. package/dist/src/backend/trpc/workspace.trpc.js.map +1 -1
  334. package/dist/src/cli/index.js +5 -2
  335. package/dist/src/cli/index.js.map +1 -1
  336. package/dist/src/shared/core/ci-status.d.ts +6 -4
  337. package/dist/src/shared/core/ci-status.d.ts.map +1 -1
  338. package/dist/src/shared/core/ci-status.js +47 -13
  339. package/dist/src/shared/core/ci-status.js.map +1 -1
  340. package/dist/src/shared/core/enums.d.ts +1 -0
  341. package/dist/src/shared/core/enums.d.ts.map +1 -1
  342. package/dist/src/shared/core/enums.js +1 -0
  343. package/dist/src/shared/core/enums.js.map +1 -1
  344. package/dist/src/shared/core/index.d.ts +1 -1
  345. package/dist/src/shared/core/index.d.ts.map +1 -1
  346. package/dist/src/shared/core/index.js +1 -1
  347. package/dist/src/shared/core/index.js.map +1 -1
  348. package/dist/src/shared/schemas/export-data.schema.d.ts +2 -0
  349. package/dist/src/shared/schemas/export-data.schema.d.ts.map +1 -1
  350. package/dist/src/shared/schemas/issue-tracker-config.schema.d.ts +2 -2
  351. package/dist/src/shared/workspace-flow-state.d.ts +3 -0
  352. package/dist/src/shared/workspace-flow-state.d.ts.map +1 -0
  353. package/dist/src/shared/workspace-flow-state.js +2 -0
  354. package/dist/src/shared/workspace-flow-state.js.map +1 -0
  355. package/dist/tsconfig.backend.tsbuildinfo +1 -1
  356. package/package.json +1 -1
  357. package/prisma/migrations/20260224150000_add_workspace_archiving_state/migration.sql +4 -0
  358. package/prisma/schema.prisma +1 -0
  359. package/dist/client/assets/channel-B_f9a3jD.js +0 -1
  360. package/dist/client/assets/classDiagram-2ON5EDUG-CgnrkUO8.js +0 -1
  361. package/dist/client/assets/classDiagram-v2-WZHVMYZB-CgnrkUO8.js +0 -1
  362. package/dist/client/assets/clone-BmilxOGI.js +0 -1
  363. package/dist/client/assets/index-DVprBuNv.css +0 -1
  364. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BRKf4wQr.js +0 -1
  365. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.d.ts.map +0 -1
  366. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.js.map +0 -1
  367. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.test.d.ts +0 -2
  368. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.test.d.ts.map +0 -1
  369. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.test.js.map +0 -1
  370. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.d.ts +0 -10
  371. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.d.ts.map +0 -1
  372. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.js +0 -24
  373. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.js.map +0 -1
  374. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.test.d.ts +0 -2
  375. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.test.d.ts.map +0 -1
  376. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.test.js +0 -17
  377. package/dist/src/backend/domains/workspace/lifecycle/archive-tracker.service.test.js.map +0 -1
@@ -1,17 +1,15 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import pLimit from 'p-limit';
3
- import { buildRatchetDispatchPrompt } from '../../../backend/prompts/ratchet-dispatch.js';
4
- import { agentSessionAccessor } from '../../../backend/resource_accessors/agent-session.accessor.js';
5
3
  import { workspaceAccessor } from '../../../backend/resource_accessors/workspace.accessor.js';
6
- import { SERVICE_CACHE_TTL_MS, SERVICE_CONCURRENCY, SERVICE_INTERVAL_MS, SERVICE_THRESHOLDS, SERVICE_TIMEOUT_MS, } from '../../../backend/services/constants.js';
4
+ import { SERVICE_CONCURRENCY, SERVICE_INTERVAL_MS, SERVICE_TIMEOUT_MS, } from '../../../backend/services/constants.js';
7
5
  import { createLogger } from '../../../backend/services/logger.service.js';
8
6
  import { RateLimitBackoff } from '../../../backend/services/rate-limit-backoff.js';
9
- import { CIStatus, RatchetState, SessionStatus } from '../../../shared/core/index.js';
10
- import { fixerSessionService } from './fixer-session.service.js';
11
- import { ratchetProviderResolverService } from './ratchet-provider-resolver.service.js';
7
+ import { CIStatus, RatchetState } from '../../../shared/core/index.js';
8
+ import { getActiveRatchetSession as getActiveRatchetSessionHelper, hasActiveSession as hasActiveSessionHelper, } from './ratchet-active-session.helpers.js';
9
+ import { triggerRatchetFixer } from './ratchet-fixer-dispatch.helpers.js';
10
+ import { buildFailedCheckDiagnostics as buildFailedCheckDiagnosticsHelper, buildReviewTimestampDiagnostics as buildReviewTimestampDiagnosticsHelper, buildSnapshotDiagnostics as buildSnapshotDiagnosticsHelper, computeDispatchSnapshotKey as computeDispatchSnapshotKeyHelper, computeLatestReviewActivityAtMs as computeLatestReviewActivityAtMsHelper, determineRatchetState as determineRatchetStateHelper, fetchPRState as fetchPRStateHelper, getAuthenticatedUsernameCached as getAuthenticatedUsernameCachedHelper, hasNewReviewActivitySinceLastDispatch as hasNewReviewActivitySinceLastDispatchHelper, shouldSkipCleanPR as shouldSkipCleanPRHelper, } from './ratchet-pr-state.helpers.js';
11
+ import { handleReviewCommentPoll as handleReviewCommentPollHelper } from './ratchet-review-poll.helpers.js';
12
12
  const logger = createLogger('ratchet');
13
- const RATCHET_WORKFLOW = 'ratchet';
14
- const REVIEW_POLL_INTERVAL_MS = 2 * 60_000;
15
13
  export const RATCHET_STATE_CHANGED = 'ratchet_state_changed';
16
14
  export const RATCHET_TOGGLED = 'ratchet_toggled';
17
15
  class RatchetService extends EventEmitter {
@@ -152,6 +150,9 @@ class RatchetService extends EventEmitter {
152
150
  }
153
151
  return this.runWorkspaceCheckSafely(workspace);
154
152
  }
153
+ async clearRatchetActiveSessionIfMatching(workspaceId, sessionId) {
154
+ await workspaceAccessor.clearRatchetActiveSession(workspaceId, sessionId);
155
+ }
155
156
  async runWorkspaceCheckSafely(workspace) {
156
157
  const checkPromise = this.runWorkspaceCheck(workspace.id, () => this.processWorkspace(workspace));
157
158
  try {
@@ -159,9 +160,10 @@ class RatchetService extends EventEmitter {
159
160
  }
160
161
  catch (error) {
161
162
  const errorMessage = error instanceof Error ? error.message : String(error);
162
- logger.error('Ratchet workspace check failed', error, {
163
+ logger.warn('Ratchet workspace check failed', {
163
164
  workspaceId: workspace.id,
164
165
  prUrl: workspace.prUrl,
166
+ error: errorMessage,
165
167
  });
166
168
  return {
167
169
  workspaceId: workspace.id,
@@ -216,10 +218,16 @@ class RatchetService extends EventEmitter {
216
218
  }
217
219
  const activeSessionId = workspace.ratchetActiveSessionId;
218
220
  if (activeSessionId && this.session.isSessionRunning(activeSessionId)) {
219
- await this.safeStopSession(activeSessionId, 'Failed to stop active ratchet session while disabling ratchet', {
220
- workspaceId,
221
- sessionId: activeSessionId,
222
- });
221
+ try {
222
+ await this.session.stopSession(activeSessionId);
223
+ }
224
+ catch (error) {
225
+ logger.warn('Failed to stop active ratchet session while disabling ratchet', {
226
+ workspaceId,
227
+ sessionId: activeSessionId,
228
+ error: error instanceof Error ? error.message : String(error),
229
+ });
230
+ }
223
231
  }
224
232
  await workspaceAccessor.update(workspaceId, {
225
233
  ratchetEnabled: false,
@@ -376,70 +384,13 @@ class RatchetService extends EventEmitter {
376
384
  };
377
385
  }
378
386
  buildSnapshotDiagnostics(workspace, prStateInfo, decisionContext) {
379
- if (!prStateInfo) {
380
- return {
381
- ciSnapshotKey: null,
382
- snapshotComparison: null,
383
- };
384
- }
385
- return {
386
- ciSnapshotKey: this.computeCiSnapshotKey(prStateInfo.ciStatus, prStateInfo.statusCheckRollup),
387
- snapshotComparison: {
388
- previousDispatchSnapshotKey: workspace.ratchetLastCiRunId,
389
- currentSnapshotKey: prStateInfo.snapshotKey,
390
- changedSinceLastDispatch: decisionContext?.hasStateChangedSinceLastDispatch ??
391
- this.hasStateChangedSinceLastDispatch(workspace, prStateInfo),
392
- },
393
- };
387
+ return buildSnapshotDiagnosticsHelper(workspace, prStateInfo, decisionContext);
394
388
  }
395
389
  buildReviewTimestampDiagnostics(workspace, prStateInfo, decisionContext) {
396
- const latestReviewActivityAtMs = prStateInfo?.latestReviewActivityAtMs ?? null;
397
- const prReviewLastCheckedAtMs = workspace.prReviewLastCheckedAt?.getTime() ?? null;
398
- const deltaMs = latestReviewActivityAtMs !== null && prReviewLastCheckedAtMs !== null
399
- ? latestReviewActivityAtMs - prReviewLastCheckedAtMs
400
- : null;
401
- if (!prStateInfo) {
402
- return {
403
- latestReviewActivityAtMs,
404
- reviewTimestampComparison: null,
405
- };
406
- }
407
- return {
408
- latestReviewActivityAtMs,
409
- reviewTimestampComparison: {
410
- prReviewLastCheckedAt: workspace.prReviewLastCheckedAt?.toISOString() ?? null,
411
- latestReviewActivityAt: latestReviewActivityAtMs !== null
412
- ? new Date(latestReviewActivityAtMs).toISOString()
413
- : null,
414
- prReviewLastCheckedAtMs,
415
- latestReviewActivityAtMs,
416
- deltaMs,
417
- hasNewReviewActivitySinceLastDispatch: decisionContext?.hasNewReviewActivitySinceLastDispatch !== undefined
418
- ? decisionContext.hasNewReviewActivitySinceLastDispatch
419
- : this.hasNewReviewActivitySinceLastDispatch(workspace, prStateInfo),
420
- },
421
- };
390
+ return buildReviewTimestampDiagnosticsHelper(workspace, prStateInfo, decisionContext, logger);
422
391
  }
423
392
  buildFailedCheckDiagnostics(prStateInfo) {
424
- return (prStateInfo?.statusCheckRollup
425
- ?.filter((check) => {
426
- const conclusion = check.conclusion?.toUpperCase();
427
- return (conclusion === 'FAILURE' ||
428
- conclusion === 'TIMED_OUT' ||
429
- conclusion === 'CANCELLED' ||
430
- conclusion === 'ERROR' ||
431
- conclusion === 'ACTION_REQUIRED');
432
- })
433
- .map((check) => {
434
- const runIdMatch = check.detailsUrl?.match(/\/actions\/runs\/(\d+)/);
435
- return {
436
- name: check.name ?? 'unknown',
437
- status: check.status ?? null,
438
- conclusion: check.conclusion ?? null,
439
- runId: runIdMatch?.[1] ?? null,
440
- detailsUrl: check.detailsUrl ?? null,
441
- };
442
- }) ?? []);
393
+ return buildFailedCheckDiagnosticsHelper(prStateInfo);
443
394
  }
444
395
  describeNonRatchetingReason(action) {
445
396
  switch (action.type) {
@@ -574,105 +525,46 @@ class RatchetService extends EventEmitter {
574
525
  return (prStateInfo.reviewComments?.length ?? 0) > 0;
575
526
  }
576
527
  shouldSkipCleanPR(workspace, prStateInfo) {
577
- if (prStateInfo.ciStatus !== CIStatus.SUCCESS || prStateInfo.hasChangesRequested) {
578
- return false;
579
- }
580
- return !this.hasNewReviewActivitySinceLastDispatch(workspace, prStateInfo);
528
+ return shouldSkipCleanPRHelper(workspace, prStateInfo, logger);
581
529
  }
582
530
  hasNewReviewActivitySinceLastDispatch(workspace, prStateInfo) {
583
- if (prStateInfo.latestReviewActivityAtMs === null) {
584
- return false;
585
- }
586
- if (!workspace.prReviewLastCheckedAt) {
587
- return true;
588
- }
589
- if (prStateInfo.latestReviewActivityAtMs > workspace.prReviewLastCheckedAt.getTime()) {
590
- return true;
591
- }
592
- if (!workspace.ratchetActiveSessionId) {
593
- const age = Date.now() - workspace.prReviewLastCheckedAt.getTime();
594
- if (age > SERVICE_THRESHOLDS.ratchetReviewCheckStaleMs) {
595
- logger.info('Review check timestamp is stale with no active session, treating as new activity', {
596
- workspaceId: workspace.id,
597
- checkedAtAge: Math.round(age / 1000),
598
- });
599
- return true;
600
- }
601
- }
602
- return false;
531
+ return hasNewReviewActivitySinceLastDispatchHelper(workspace, prStateInfo, logger);
603
532
  }
604
533
  async processReviewCommentPoll(workspace, prStateInfo, authenticatedUsername) {
605
534
  const pollResult = await this.handleReviewCommentPoll(workspace, prStateInfo, authenticatedUsername);
606
- if (pollResult.action === 'comments-found') {
607
- const freshContext = await this.buildRatchetDecisionContext(workspace, pollResult.freshPrState);
608
- const freshDecision = this.decideRatchetAction(freshContext);
609
- const freshAction = await this.applyRatchetDecision(freshContext, freshDecision);
610
- await this.updateWorkspaceAfterCheck(workspace, pollResult.freshPrState, freshAction, freshContext.finalState);
611
- if (freshContext.previousState !== freshContext.finalState) {
612
- this.emit(RATCHET_STATE_CHANGED, {
613
- workspaceId: workspace.id,
614
- fromState: freshContext.previousState,
615
- toState: freshContext.finalState,
616
- });
617
- }
618
- this.logWorkspaceRatchetingDecision(workspace, freshContext.previousState, freshContext.finalState, freshAction, pollResult.freshPrState, freshContext);
619
- return {
620
- workspaceId: workspace.id,
621
- previousState: freshContext.previousState,
622
- newState: freshContext.finalState,
623
- action: freshAction,
624
- };
625
- }
626
- return null;
627
- }
628
- async handleReviewCommentPoll(workspace, prStateInfo, authenticatedUsername) {
629
- const existing = this.reviewPollTrackers.get(workspace.id);
630
- if (!existing) {
631
- this.reviewPollTrackers.set(workspace.id, {
632
- snapshotKey: prStateInfo.snapshotKey,
633
- lastPolledAt: Date.now(),
634
- pollCount: 0,
635
- });
636
- logger.info('Started review comment polling', {
637
- workspaceId: workspace.id,
638
- snapshotKey: prStateInfo.snapshotKey,
639
- });
640
- return { action: 'waiting' };
641
- }
642
- if (existing.snapshotKey !== prStateInfo.snapshotKey) {
643
- this.reviewPollTrackers.set(workspace.id, {
644
- snapshotKey: prStateInfo.snapshotKey,
645
- lastPolledAt: Date.now(),
646
- pollCount: 0,
647
- });
648
- logger.info('Reset review comment polling (new snapshot)', {
649
- workspaceId: workspace.id,
650
- snapshotKey: prStateInfo.snapshotKey,
651
- });
652
- return { action: 'waiting' };
653
- }
654
- if (Date.now() - existing.lastPolledAt < REVIEW_POLL_INTERVAL_MS) {
655
- return { action: 'waiting' };
656
- }
657
- if (this.isShuttingDown) {
658
- return { action: 'waiting' };
659
- }
660
- const freshPrState = await this.fetchPRState(workspace, authenticatedUsername);
661
- if (!freshPrState) {
662
- return { action: 'waiting' };
535
+ if (pollResult.action !== 'comments-found') {
536
+ return null;
663
537
  }
664
- existing.pollCount++;
665
- existing.lastPolledAt = Date.now();
666
- if (!this.shouldSkipCleanPR(workspace, freshPrState)) {
667
- this.reviewPollTrackers.delete(workspace.id);
668
- logger.info('Review comments detected during poll', {
538
+ const freshContext = await this.buildRatchetDecisionContext(workspace, pollResult.freshPrState);
539
+ const freshDecision = this.decideRatchetAction(freshContext);
540
+ const freshAction = await this.applyRatchetDecision(freshContext, freshDecision);
541
+ await this.updateWorkspaceAfterCheck(workspace, pollResult.freshPrState, freshAction, freshContext.finalState);
542
+ if (freshContext.previousState !== freshContext.finalState) {
543
+ this.emit(RATCHET_STATE_CHANGED, {
669
544
  workspaceId: workspace.id,
670
- pollNumber: existing.pollCount,
671
- latestReviewActivityAtMs: freshPrState.latestReviewActivityAtMs,
545
+ fromState: freshContext.previousState,
546
+ toState: freshContext.finalState,
672
547
  });
673
- return { action: 'comments-found', freshPrState };
674
548
  }
675
- return { action: 'waiting' };
549
+ this.logWorkspaceRatchetingDecision(workspace, freshContext.previousState, freshContext.finalState, freshAction, pollResult.freshPrState, freshContext);
550
+ return {
551
+ workspaceId: workspace.id,
552
+ previousState: freshContext.previousState,
553
+ newState: freshContext.finalState,
554
+ action: freshAction,
555
+ };
556
+ }
557
+ async handleReviewCommentPoll(workspace, prStateInfo, authenticatedUsername) {
558
+ return await handleReviewCommentPollHelper({
559
+ workspace,
560
+ prStateInfo,
561
+ authenticatedUsername,
562
+ reviewPollTrackers: this.reviewPollTrackers,
563
+ isShuttingDown: this.isShuttingDown,
564
+ fetchPRState: (workspaceArg, authenticatedUsernameArg) => this.fetchPRState(workspaceArg, authenticatedUsernameArg),
565
+ shouldSkipCleanPR: (workspaceArg, prStateInfoArg) => this.shouldSkipCleanPR(workspaceArg, prStateInfoArg),
566
+ logger,
567
+ });
676
568
  }
677
569
  hasStateChangedSinceLastDispatch(workspace, prStateInfo) {
678
570
  return workspace.ratchetLastCiRunId !== prStateInfo.snapshotKey;
@@ -694,286 +586,67 @@ class RatchetService extends EventEmitter {
694
586
  }
695
587
  }
696
588
  async getActiveRatchetSession(workspace) {
697
- if (!workspace.ratchetActiveSessionId) {
698
- return null;
699
- }
700
- const resolvedRatchetProvider = await ratchetProviderResolverService.resolveRatchetProvider({
701
- workspaceId: workspace.id,
589
+ return await getActiveRatchetSessionHelper({
702
590
  workspace,
591
+ sessionBridge: this.session,
592
+ snapshotBridge: this.snapshot,
593
+ resetDispatchState: (workspaceId) => this.resetDispatchState(workspaceId),
594
+ clearActiveSession: (workspaceId) => this.clearActiveSession(workspaceId),
595
+ logger,
703
596
  });
704
- const session = await agentSessionAccessor.findById(workspace.ratchetActiveSessionId);
705
- if (!session) {
706
- await this.clearFailedRatchetDispatch(workspace, 'session not found in database');
707
- return null;
708
- }
709
- if (session.provider !== resolvedRatchetProvider) {
710
- await this.clearFailedRatchetDispatch(workspace, `provider mismatch: expected ${resolvedRatchetProvider}, got ${session.provider}`);
711
- await this.stopSessionForProviderMismatch(workspace.id, session.id, resolvedRatchetProvider, session.provider);
712
- return null;
713
- }
714
- if (session.status !== SessionStatus.RUNNING) {
715
- await this.clearFailedRatchetDispatch(workspace, `session status is ${session.status}`);
716
- return null;
717
- }
718
- if (!this.session.isSessionRunning(session.id)) {
719
- await this.clearFailedRatchetDispatch(workspace, 'session process is not running');
720
- return null;
721
- }
722
- if (!this.session.isSessionWorking(session.id)) {
723
- await this.clearActiveRatchetSession(workspace.id);
724
- await this.stopCompletedRatchetSession(workspace.id, session.id);
725
- return null;
726
- }
727
- return { type: 'FIXER_ACTIVE', sessionId: workspace.ratchetActiveSessionId };
728
- }
729
- async clearFailedRatchetDispatch(workspace, reason) {
730
- logger.info('Clearing failed ratchet dispatch, resetting state for retry', {
731
- workspaceId: workspace.id,
732
- sessionId: workspace.ratchetActiveSessionId,
733
- reason,
734
- });
735
- await workspaceAccessor.update(workspace.id, {
736
- ratchetActiveSessionId: null,
737
- ratchetLastCiRunId: null,
738
- });
739
- await this.snapshot.recordReviewCheck(workspace.id, null);
740
597
  }
741
598
  async hasActiveSession(workspaceId) {
742
- const sessions = await agentSessionAccessor.findByWorkspaceId(workspaceId);
743
- return sessions.some((session) => this.session.isSessionWorking(session.id));
744
- }
745
- async clearActiveRatchetSession(workspaceId) {
746
- await workspaceAccessor.update(workspaceId, { ratchetActiveSessionId: null });
747
- }
748
- async safeStopSession(sessionId, warningMessage, warningContext) {
749
- try {
750
- await this.session.stopSession(sessionId);
751
- }
752
- catch (error) {
753
- logger.warn(warningMessage, {
754
- ...warningContext,
755
- error: error instanceof Error ? error.message : String(error),
756
- });
757
- }
758
- }
759
- async stopCompletedRatchetSession(workspaceId, sessionId) {
760
- await this.safeStopSession(sessionId, 'Failed to stop completed ratchet session', {
761
- workspaceId,
762
- sessionId,
763
- });
764
- }
765
- async stopSessionForProviderMismatch(workspaceId, sessionId, expectedProvider, actualProvider) {
766
- await this.safeStopSession(sessionId, 'Failed to stop mismatched ratchet provider session', {
767
- workspaceId,
768
- sessionId,
769
- expectedProvider,
770
- actualProvider,
771
- });
772
- }
773
- resolveRatchetPrContext(workspace) {
774
- const prInfo = this.github.extractPRInfo(workspace.prUrl);
775
- if (!prInfo) {
776
- logger.warn('Could not parse PR URL', { prUrl: workspace.prUrl });
777
- return null;
778
- }
779
- const prNumber = workspace.prNumber ?? prInfo.number;
780
- if (!prNumber) {
781
- logger.warn('Could not determine PR number for ratchet check', {
782
- workspaceId: workspace.id,
783
- prUrl: workspace.prUrl,
784
- });
785
- return null;
786
- }
787
- return {
788
- repo: `${prInfo.owner}/${prInfo.repo}`,
789
- prNumber,
790
- };
599
+ return await hasActiveSessionHelper(workspaceId, this.session);
791
600
  }
792
601
  async fetchPRState(workspace, authenticatedUsername) {
793
- const prContext = this.resolveRatchetPrContext(workspace);
794
- if (!prContext) {
795
- return null;
796
- }
797
- try {
798
- const [prDetails, reviewComments] = await Promise.all([
799
- this.github.getPRFullDetails(prContext.repo, prContext.prNumber),
800
- this.github.getReviewComments(prContext.repo, prContext.prNumber),
801
- ]);
802
- const statusCheckRollup = prDetails.statusCheckRollup?.map((check) => ({
803
- name: check.name,
804
- status: check.status,
805
- conclusion: check.conclusion ?? undefined,
806
- detailsUrl: check.detailsUrl,
807
- })) ?? null;
808
- const ciStatus = this.github.computeCIStatus(statusCheckRollup);
809
- const hasChangesRequested = prDetails.reviewDecision === 'CHANGES_REQUESTED';
810
- const latestReviewActivityAtMs = this.computeLatestReviewActivityAtMs(prDetails, reviewComments, authenticatedUsername);
811
- const snapshotKey = this.computeDispatchSnapshotKey(ciStatus, hasChangesRequested, latestReviewActivityAtMs, statusCheckRollup);
812
- const filteredReviewComments = reviewComments
813
- .filter((c) => !this.isIgnoredReviewAuthor(c.author.login, authenticatedUsername))
814
- .map((c) => ({
815
- author: c.author.login,
816
- body: c.body,
817
- path: c.path,
818
- line: c.line,
819
- url: c.url,
820
- }));
821
- return {
822
- ciStatus,
823
- snapshotKey,
824
- hasChangesRequested,
825
- latestReviewActivityAtMs,
826
- statusCheckRollup,
827
- prState: prDetails.state,
828
- prNumber: prDetails.number,
829
- reviewComments: filteredReviewComments,
830
- };
831
- }
832
- catch (error) {
833
- this.backoff.handleError(error, logger, 'Ratchet', { workspaceId: workspace.id, prUrl: workspace.prUrl }, SERVICE_INTERVAL_MS.ratchetPoll);
834
- return null;
835
- }
602
+ return await fetchPRStateHelper({
603
+ workspace,
604
+ authenticatedUsername,
605
+ github: this.github,
606
+ backoff: this.backoff,
607
+ logger,
608
+ computeLatestReviewActivityAtMs: (prDetails, reviewComments, authenticatedUsernameArg) => this.computeLatestReviewActivityAtMs(prDetails, reviewComments, authenticatedUsernameArg),
609
+ computeDispatchSnapshotKey: (ciStatus, hasChangesRequested, latestReviewActivityAtMs, statusChecks) => this.computeDispatchSnapshotKey(ciStatus, hasChangesRequested, latestReviewActivityAtMs, statusChecks),
610
+ });
836
611
  }
837
612
  computeDispatchSnapshotKey(ciStatus, hasChangesRequested, latestReviewActivityAtMs, statusChecks) {
838
- const ciKey = this.computeCiSnapshotKey(ciStatus, statusChecks);
839
- const reviewKey = `${hasChangesRequested ? 'changes-requested' : 'no-changes-requested'}:${latestReviewActivityAtMs ?? 'none'}`;
840
- return `${ciKey}|${reviewKey}`;
841
- }
842
- computeCiSnapshotKey(ciStatus, statusChecks) {
843
- if (ciStatus !== CIStatus.FAILURE) {
844
- return `ci:${ciStatus}`;
845
- }
846
- const failedChecks = statusChecks?.filter((check) => {
847
- const conclusion = check.conclusion?.toUpperCase();
848
- return (conclusion === 'FAILURE' ||
849
- conclusion === 'TIMED_OUT' ||
850
- conclusion === 'CANCELLED' ||
851
- conclusion === 'ERROR' ||
852
- conclusion === 'ACTION_REQUIRED');
853
- }) ?? [];
854
- if (failedChecks.length === 0) {
855
- return 'ci:FAILURE:unknown';
856
- }
857
- const signature = failedChecks
858
- .map((check) => {
859
- const runIdMatch = check.detailsUrl?.match(/\/actions\/runs\/(\d+)/);
860
- const runId = runIdMatch?.[1];
861
- const stableCheckIdentity = runId ?? check.detailsUrl ?? 'no-run-id-or-details-url';
862
- return `${check.name ?? 'unknown'}:${check.conclusion ?? 'UNKNOWN'}:${stableCheckIdentity}`;
863
- })
864
- .sort()
865
- .join('|');
866
- return `ci:FAILURE:${signature}`;
613
+ return computeDispatchSnapshotKeyHelper(ciStatus, hasChangesRequested, latestReviewActivityAtMs, statusChecks);
867
614
  }
868
615
  computeLatestReviewActivityAtMs(prDetails, reviewComments, authenticatedUsername) {
869
- const entries = [
870
- ...prDetails.reviews.map((review) => ({
871
- authorLogin: review.author.login,
872
- timestamp: review.submittedAt,
873
- })),
874
- ...prDetails.comments.map((comment) => ({
875
- authorLogin: comment.author.login,
876
- timestamp: comment.updatedAt,
877
- })),
878
- ...reviewComments.map((reviewComment) => ({
879
- authorLogin: reviewComment.author.login,
880
- timestamp: reviewComment.updatedAt,
881
- })),
882
- ];
883
- const timestamps = entries
884
- .filter((entry) => entry.timestamp !== null &&
885
- !this.isIgnoredReviewAuthor(entry.authorLogin, authenticatedUsername))
886
- .map((entry) => Date.parse(entry.timestamp))
887
- .filter((timestamp) => Number.isFinite(timestamp));
888
- return timestamps.length > 0 ? Math.max(...timestamps) : null;
889
- }
890
- isIgnoredReviewAuthor(authorLogin, authenticatedUsername) {
891
- if (!authenticatedUsername) {
892
- return false;
893
- }
894
- return authorLogin === authenticatedUsername;
616
+ return computeLatestReviewActivityAtMsHelper(prDetails, reviewComments, authenticatedUsername);
895
617
  }
896
618
  async getAuthenticatedUsernameCached() {
897
- const nowMs = Date.now();
898
- if (this.cachedAuthenticatedUsername && this.cachedAuthenticatedUsername.expiresAtMs > nowMs) {
899
- return this.cachedAuthenticatedUsername.value;
900
- }
901
- const username = await this.github.getAuthenticatedUsername();
902
- this.cachedAuthenticatedUsername = {
903
- value: username,
904
- expiresAtMs: nowMs + SERVICE_CACHE_TTL_MS.ratchetAuthenticatedUsername,
905
- };
619
+ const { username, cache } = await getAuthenticatedUsernameCachedHelper({
620
+ cachedValue: this.cachedAuthenticatedUsername,
621
+ github: this.github,
622
+ });
623
+ this.cachedAuthenticatedUsername = cache;
906
624
  return username;
907
625
  }
908
626
  determineRatchetState(pr) {
909
- if (pr.prState === 'MERGED') {
910
- return RatchetState.MERGED;
911
- }
912
- if (pr.prState !== 'OPEN') {
913
- return RatchetState.IDLE;
914
- }
915
- if (pr.ciStatus === CIStatus.PENDING || pr.ciStatus === CIStatus.UNKNOWN) {
916
- return RatchetState.CI_RUNNING;
917
- }
918
- if (pr.ciStatus === CIStatus.FAILURE) {
919
- return RatchetState.CI_FAILED;
920
- }
921
- if (pr.hasChangesRequested) {
922
- return RatchetState.REVIEW_PENDING;
923
- }
924
- return RatchetState.READY;
627
+ return determineRatchetStateHelper(pr);
925
628
  }
926
629
  async triggerFixer(workspace, prStateInfo) {
927
- try {
928
- const result = await fixerSessionService.acquireAndDispatch({
929
- workspaceId: workspace.id,
930
- workflow: RATCHET_WORKFLOW,
931
- sessionName: 'Ratchet',
932
- runningIdleAction: 'restart',
933
- dispatchMode: 'start_empty_and_send',
934
- buildPrompt: () => buildRatchetDispatchPrompt(workspace.prUrl, prStateInfo.prNumber, prStateInfo.reviewComments),
935
- beforeStart: ({ sessionId, prompt }) => {
936
- this.session.injectCommittedUserMessage(sessionId, prompt);
937
- },
938
- });
939
- if (result.status === 'started') {
940
- const promptSent = result.promptSent ?? true;
941
- if (!promptSent) {
942
- logger.warn('Ratchet session started but prompt delivery failed', {
943
- workspaceId: workspace.id,
944
- sessionId: result.sessionId,
945
- });
946
- await workspaceAccessor.update(workspace.id, { ratchetActiveSessionId: null });
947
- if (this.session.isSessionRunning(result.sessionId)) {
948
- await this.session.stopSession(result.sessionId);
949
- }
950
- return { type: 'ERROR', error: 'Failed to deliver initial ratchet prompt' };
951
- }
952
- await workspaceAccessor.update(workspace.id, {
953
- ratchetActiveSessionId: result.sessionId,
954
- });
955
- return {
956
- type: 'TRIGGERED_FIXER',
957
- sessionId: result.sessionId,
958
- promptSent,
959
- };
960
- }
961
- if (result.status === 'already_active') {
962
- await workspaceAccessor.update(workspace.id, { ratchetActiveSessionId: result.sessionId });
963
- return { type: 'FIXER_ACTIVE', sessionId: result.sessionId };
964
- }
965
- if (result.status === 'skipped') {
966
- return { type: 'ERROR', error: result.reason };
967
- }
968
- return { type: 'ERROR', error: result.error };
969
- }
970
- catch (error) {
971
- const errorMessage = error instanceof Error ? error.message : String(error);
972
- logger.error('Failed to trigger ratchet fixer', error, {
973
- workspaceId: workspace.id,
974
- });
975
- return { type: 'ERROR', error: errorMessage };
976
- }
630
+ return await triggerRatchetFixer({
631
+ workspace,
632
+ prStateInfo,
633
+ sessionBridge: this.session,
634
+ setActiveSession: (workspaceId, sessionId) => this.setActiveSession(workspaceId, sessionId),
635
+ clearActiveSession: (workspaceId) => this.clearActiveSession(workspaceId),
636
+ logger,
637
+ });
638
+ }
639
+ async setActiveSession(workspaceId, sessionId) {
640
+ await workspaceAccessor.update(workspaceId, { ratchetActiveSessionId: sessionId });
641
+ }
642
+ async clearActiveSession(workspaceId) {
643
+ await workspaceAccessor.update(workspaceId, { ratchetActiveSessionId: null });
644
+ }
645
+ async resetDispatchState(workspaceId) {
646
+ await workspaceAccessor.update(workspaceId, {
647
+ ratchetActiveSessionId: null,
648
+ ratchetLastCiRunId: null,
649
+ });
977
650
  }
978
651
  }
979
652
  export const ratchetService = new RatchetService();