factory-factory 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/dist/client/assets/{_basePickBy-BsuMuaCZ.js → _basePickBy-BzH_iru3.js} +1 -1
  2. package/dist/client/assets/{_baseUniq-BDd8f52s.js → _baseUniq-D6ny9r_u.js} +1 -1
  3. package/dist/client/assets/{arc-BWbaJQoA.js → arc-CRVgibiy.js} +1 -1
  4. package/dist/client/assets/{architectureDiagram-VXUJARFQ-C_FQG3JS.js → architectureDiagram-VXUJARFQ-1aDFSaTZ.js} +1 -1
  5. package/dist/client/assets/{blockDiagram-VD42YOAC-CLwvH-wA.js → blockDiagram-VD42YOAC-m3mDHY-k.js} +1 -1
  6. package/dist/client/assets/{c4Diagram-YG6GDRKO-Ba80_haP.js → c4Diagram-YG6GDRKO-B7ZlkfXz.js} +1 -1
  7. package/dist/client/assets/channel-B_f9a3jD.js +1 -0
  8. package/dist/client/assets/{chunk-4BX2VUAB-CSlDSMiy.js → chunk-4BX2VUAB-zLj9eiFf.js} +1 -1
  9. package/dist/client/assets/{chunk-55IACEB6-Dm3keBAf.js → chunk-55IACEB6-D6KQTgyD.js} +1 -1
  10. package/dist/client/assets/{chunk-B4BG7PRW-BSrvNYuP.js → chunk-B4BG7PRW-BQbzvx8l.js} +1 -1
  11. package/dist/client/assets/{chunk-DI55MBZ5-DFQPoLQZ.js → chunk-DI55MBZ5-CPxKCw_e.js} +1 -1
  12. package/dist/client/assets/{chunk-FMBD7UC4-C1KS438H.js → chunk-FMBD7UC4-nFaeGtHP.js} +1 -1
  13. package/dist/client/assets/{chunk-QN33PNHL-4rPPxHo4.js → chunk-QN33PNHL-DhrGqSLY.js} +1 -1
  14. package/dist/client/assets/{chunk-QZHKN3VN-B_sF5IzV.js → chunk-QZHKN3VN-CZWrGmvf.js} +1 -1
  15. package/dist/client/assets/{chunk-TZMSLE5B-L-qbjoBp.js → chunk-TZMSLE5B-xhHdVO37.js} +1 -1
  16. package/dist/client/assets/classDiagram-2ON5EDUG-CgnrkUO8.js +1 -0
  17. package/dist/client/assets/classDiagram-v2-WZHVMYZB-CgnrkUO8.js +1 -0
  18. package/dist/client/assets/clone-BmilxOGI.js +1 -0
  19. package/dist/client/assets/{cose-bilkent-S5V4N54A-DB7lwAnl.js → cose-bilkent-S5V4N54A-Cr0HX6ro.js} +1 -1
  20. package/dist/client/assets/{dagre-6UL2VRFP-z2fl_1iD.js → dagre-6UL2VRFP-s6RRMHqY.js} +1 -1
  21. package/dist/client/assets/{diagram-PSM6KHXK-BL2iv8II.js → diagram-PSM6KHXK-BhdZNVs7.js} +1 -1
  22. package/dist/client/assets/{diagram-QEK2KX5R-DgMZW0D1.js → diagram-QEK2KX5R-Dgwc4sx_.js} +1 -1
  23. package/dist/client/assets/{diagram-S2PKOQOG-Ct2QBl2c.js → diagram-S2PKOQOG-BlcMpYrQ.js} +1 -1
  24. package/dist/client/assets/{erDiagram-Q2GNP2WA-DII-pqkb.js → erDiagram-Q2GNP2WA-BQQjswcC.js} +1 -1
  25. package/dist/client/assets/{flowDiagram-NV44I4VS-BV4CMZAZ.js → flowDiagram-NV44I4VS-_cBTH43Q.js} +1 -1
  26. package/dist/client/assets/{ganttDiagram-JELNMOA3-Dfj064tE.js → ganttDiagram-JELNMOA3-BxuyB7Oz.js} +1 -1
  27. package/dist/client/assets/{gitGraphDiagram-V2S2FVAM-Cg2b-j3t.js → gitGraphDiagram-V2S2FVAM-D0GjSYQi.js} +1 -1
  28. package/dist/client/assets/{graph-wzICjOO_.js → graph-DNCXrik3.js} +1 -1
  29. package/dist/client/assets/{index-EVrp_NXm.js → index-CCnMDzRJ.js} +165 -158
  30. package/dist/client/assets/index-DVprBuNv.css +1 -0
  31. package/dist/client/assets/{infoDiagram-HS3SLOUP-D09mbfgG.js → infoDiagram-HS3SLOUP-BsUKtNMj.js} +1 -1
  32. package/dist/client/assets/{journeyDiagram-XKPGCS4Q-BebsQbuf.js → journeyDiagram-XKPGCS4Q-sScoNj-6.js} +1 -1
  33. package/dist/client/assets/{kanban-definition-3W4ZIXB7-DOuawTNU.js → kanban-definition-3W4ZIXB7-CycFvltk.js} +1 -1
  34. package/dist/client/assets/{layout-Bj6cMfF5.js → layout-LTiJ8avf.js} +1 -1
  35. package/dist/client/assets/{linear-B58HS9F4.js → linear-CnQEAniJ.js} +1 -1
  36. package/dist/client/assets/{mindmap-definition-VGOIOE7T-hSFgcTL2.js → mindmap-definition-VGOIOE7T-Du5mb-g5.js} +1 -1
  37. package/dist/client/assets/{mobile-baseline-CmdjqYSm.js → mobile-baseline-necQV4Mu.js} +1 -1
  38. package/dist/client/assets/{pieDiagram-ADFJNKIX-D1vkoKs3.js → pieDiagram-ADFJNKIX-CUAEo70K.js} +1 -1
  39. package/dist/client/assets/{quadrantDiagram-AYHSOK5B-pMQj9xcS.js → quadrantDiagram-AYHSOK5B-1MjtTI_Y.js} +1 -1
  40. package/dist/client/assets/{requirementDiagram-UZGBJVZJ-DvRtxnIi.js → requirementDiagram-UZGBJVZJ-zgmi2Sjr.js} +1 -1
  41. package/dist/client/assets/{sankeyDiagram-TZEHDZUN-BWoDxXkR.js → sankeyDiagram-TZEHDZUN-Datw0Rj8.js} +1 -1
  42. package/dist/client/assets/{sequenceDiagram-WL72ISMW-Dz5i1ly3.js → sequenceDiagram-WL72ISMW-DopxoRon.js} +1 -1
  43. package/dist/client/assets/{stateDiagram-FKZM4ZOC-BFd_gXUo.js → stateDiagram-FKZM4ZOC-ZqoVSvsu.js} +1 -1
  44. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-BRKf4wQr.js +1 -0
  45. package/dist/client/assets/{terminal-instance-BTIzq32H.js → terminal-instance-gybkMDHu.js} +1 -1
  46. package/dist/client/assets/{timeline-definition-IT6M3QCI-BFEIWW6m.js → timeline-definition-IT6M3QCI-DQwpSE-n.js} +1 -1
  47. package/dist/client/assets/{treemap-GDKQZRPO-CC2Fh6RQ.js → treemap-GDKQZRPO-DK4UuMc6.js} +1 -1
  48. package/dist/client/assets/{xychartDiagram-PRI3JC2R-DFygXQrm.js → xychartDiagram-PRI3JC2R-CJP1ULwR.js} +1 -1
  49. package/dist/client/index.html +2 -2
  50. package/dist/prisma/generated/internal/class.js +4 -4
  51. package/dist/prisma/generated/internal/class.js.map +1 -1
  52. package/dist/prisma/generated/internal/prismaNamespace.d.ts +1 -0
  53. package/dist/prisma/generated/internal/prismaNamespace.d.ts.map +1 -1
  54. package/dist/prisma/generated/internal/prismaNamespace.js +1 -0
  55. package/dist/prisma/generated/internal/prismaNamespace.js.map +1 -1
  56. package/dist/prisma/generated/internal/prismaNamespaceBrowser.d.ts +1 -0
  57. package/dist/prisma/generated/internal/prismaNamespaceBrowser.d.ts.map +1 -1
  58. package/dist/prisma/generated/internal/prismaNamespaceBrowser.js +1 -0
  59. package/dist/prisma/generated/internal/prismaNamespaceBrowser.js.map +1 -1
  60. package/dist/prisma/generated/models/Workspace.d.ts +44 -1
  61. package/dist/prisma/generated/models/Workspace.d.ts.map +1 -1
  62. package/dist/src/backend/app-context.d.ts +2 -1
  63. package/dist/src/backend/app-context.d.ts.map +1 -1
  64. package/dist/src/backend/app-context.js +19 -5
  65. package/dist/src/backend/app-context.js.map +1 -1
  66. package/dist/src/backend/domains/run-script/index.d.ts +1 -1
  67. package/dist/src/backend/domains/run-script/index.d.ts.map +1 -1
  68. package/dist/src/backend/domains/run-script/index.js +1 -1
  69. package/dist/src/backend/domains/run-script/index.js.map +1 -1
  70. package/dist/src/backend/domains/run-script/run-script-domain-exports.test.js +5 -4
  71. package/dist/src/backend/domains/run-script/run-script-domain-exports.test.js.map +1 -1
  72. package/dist/src/backend/domains/run-script/run-script.service.d.ts +12 -1
  73. package/dist/src/backend/domains/run-script/run-script.service.d.ts.map +1 -1
  74. package/dist/src/backend/domains/run-script/run-script.service.js +140 -2
  75. package/dist/src/backend/domains/run-script/run-script.service.js.map +1 -1
  76. package/dist/src/backend/domains/run-script/run-script.service.test.js +86 -0
  77. package/dist/src/backend/domains/run-script/run-script.service.test.js.map +1 -1
  78. package/dist/src/backend/domains/session/acp/acp-runtime-manager.d.ts.map +1 -1
  79. package/dist/src/backend/domains/session/acp/acp-runtime-manager.js +4 -1
  80. package/dist/src/backend/domains/session/acp/acp-runtime-manager.js.map +1 -1
  81. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.d.ts +23 -0
  82. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.d.ts.map +1 -0
  83. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.js +76 -0
  84. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/acp-adapter-utils.js.map +1 -0
  85. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/adapter-state.d.ts +97 -0
  86. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/adapter-state.d.ts.map +1 -0
  87. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/adapter-state.js +2 -0
  88. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/adapter-state.js.map +1 -0
  89. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.d.ts +3 -24
  90. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.d.ts.map +1 -1
  91. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.js +36 -1127
  92. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.js.map +1 -1
  93. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.test.js +0 -191
  94. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-app-server-acp-adapter.test.js.map +1 -1
  95. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/codex-zod.d.ts +3 -3
  96. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.d.ts +16 -0
  97. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.d.ts.map +1 -0
  98. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.js +292 -0
  99. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.js.map +1 -0
  100. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.test.d.ts +2 -0
  101. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.test.d.ts.map +1 -0
  102. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.test.js +56 -0
  103. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/command-metadata.test.js.map +1 -0
  104. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.d.ts +19 -0
  105. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.d.ts.map +1 -0
  106. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.js +369 -0
  107. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.js.map +1 -0
  108. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.test.d.ts +2 -0
  109. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.test.d.ts.map +1 -0
  110. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.test.js +91 -0
  111. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/protocol-permission-handler.test.js.map +1 -0
  112. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.d.ts +53 -0
  113. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.d.ts.map +1 -0
  114. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.js +419 -0
  115. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.js.map +1 -0
  116. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.test.d.ts +2 -0
  117. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.test.d.ts.map +1 -0
  118. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.test.js +95 -0
  119. package/dist/src/backend/domains/session/acp/codex-app-server-adapter/stream-event-handler.test.js.map +1 -0
  120. package/dist/src/backend/domains/session/acp/index.d.ts +1 -1
  121. package/dist/src/backend/domains/session/acp/index.d.ts.map +1 -1
  122. package/dist/src/backend/domains/session/acp/index.js +1 -1
  123. package/dist/src/backend/domains/session/acp/index.js.map +1 -1
  124. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.d.ts.map +1 -1
  125. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.js +19 -5
  126. package/dist/src/backend/domains/session/data/claude-session-history-loader.service.js.map +1 -1
  127. package/dist/src/backend/domains/session/data/codex-session-history-loader.service.d.ts.map +1 -1
  128. package/dist/src/backend/domains/session/data/codex-session-history-loader.service.js +77 -24
  129. package/dist/src/backend/domains/session/data/codex-session-history-loader.service.js.map +1 -1
  130. package/dist/src/backend/domains/session/data/session-data.service.d.ts +2 -0
  131. package/dist/src/backend/domains/session/data/session-data.service.d.ts.map +1 -1
  132. package/dist/src/backend/domains/session/index.d.ts +3 -1
  133. package/dist/src/backend/domains/session/index.d.ts.map +1 -1
  134. package/dist/src/backend/domains/session/index.js +2 -1
  135. package/dist/src/backend/domains/session/index.js.map +1 -1
  136. package/dist/src/backend/domains/session/interceptor.bridge.d.ts +8 -0
  137. package/dist/src/backend/domains/session/interceptor.bridge.d.ts.map +1 -0
  138. package/dist/src/backend/domains/session/interceptor.bridge.js +7 -0
  139. package/dist/src/backend/domains/session/interceptor.bridge.js.map +1 -0
  140. package/dist/src/backend/domains/session/lifecycle/session.config.service.d.ts +59 -0
  141. package/dist/src/backend/domains/session/lifecycle/session.config.service.d.ts.map +1 -0
  142. package/dist/src/backend/domains/session/lifecycle/session.config.service.js +635 -0
  143. package/dist/src/backend/domains/session/lifecycle/session.config.service.js.map +1 -0
  144. package/dist/src/backend/domains/session/lifecycle/session.config.service.test.d.ts +2 -0
  145. package/dist/src/backend/domains/session/lifecycle/session.config.service.test.d.ts.map +1 -0
  146. package/dist/src/backend/domains/session/lifecycle/session.config.service.test.js +552 -0
  147. package/dist/src/backend/domains/session/lifecycle/session.config.service.test.js.map +1 -0
  148. package/dist/src/backend/domains/session/lifecycle/session.permission.service.d.ts +17 -0
  149. package/dist/src/backend/domains/session/lifecycle/session.permission.service.d.ts.map +1 -0
  150. package/dist/src/backend/domains/session/lifecycle/session.permission.service.js +86 -0
  151. package/dist/src/backend/domains/session/lifecycle/session.permission.service.js.map +1 -0
  152. package/dist/src/backend/domains/session/lifecycle/session.permission.service.test.d.ts +2 -0
  153. package/dist/src/backend/domains/session/lifecycle/session.permission.service.test.d.ts.map +1 -0
  154. package/dist/src/backend/domains/session/lifecycle/session.permission.service.test.js +137 -0
  155. package/dist/src/backend/domains/session/lifecycle/session.permission.service.test.js.map +1 -0
  156. package/dist/src/backend/domains/session/lifecycle/session.service.d.ts +16 -29
  157. package/dist/src/backend/domains/session/lifecycle/session.service.d.ts.map +1 -1
  158. package/dist/src/backend/domains/session/lifecycle/session.service.js +92 -723
  159. package/dist/src/backend/domains/session/lifecycle/session.service.js.map +1 -1
  160. package/dist/src/backend/domains/session/lifecycle/session.service.test.js +0 -698
  161. package/dist/src/backend/domains/session/lifecycle/session.service.test.js.map +1 -1
  162. package/dist/src/backend/domains/session/session-domain.service.d.ts +1 -2
  163. package/dist/src/backend/domains/session/session-domain.service.d.ts.map +1 -1
  164. package/dist/src/backend/domains/session/session-domain.service.js +5 -2
  165. package/dist/src/backend/domains/session/session-domain.service.js.map +1 -1
  166. package/dist/src/backend/domains/session/store/file-lock.service.d.ts.map +1 -1
  167. package/dist/src/backend/domains/session/store/file-lock.service.js +23 -2
  168. package/dist/src/backend/domains/session/store/file-lock.service.js.map +1 -1
  169. package/dist/src/backend/domains/session/zod-issue-summary.d.ts +3 -0
  170. package/dist/src/backend/domains/session/zod-issue-summary.d.ts.map +1 -0
  171. package/dist/src/backend/domains/session/zod-issue-summary.js +7 -0
  172. package/dist/src/backend/domains/session/zod-issue-summary.js.map +1 -0
  173. package/dist/src/backend/domains/workspace/lifecycle/creation.service.d.ts +7 -0
  174. package/dist/src/backend/domains/workspace/lifecycle/creation.service.d.ts.map +1 -1
  175. package/dist/src/backend/domains/workspace/lifecycle/creation.service.js +98 -85
  176. package/dist/src/backend/domains/workspace/lifecycle/creation.service.js.map +1 -1
  177. package/dist/src/backend/domains/workspace/lifecycle/creation.service.test.js +41 -1
  178. package/dist/src/backend/domains/workspace/lifecycle/creation.service.test.js.map +1 -1
  179. package/dist/src/backend/domains/workspace/lifecycle/data.service.d.ts +9 -1
  180. package/dist/src/backend/domains/workspace/lifecycle/data.service.d.ts.map +1 -1
  181. package/dist/src/backend/domains/workspace/lifecycle/data.service.js +2 -1
  182. package/dist/src/backend/domains/workspace/lifecycle/data.service.js.map +1 -1
  183. package/dist/src/backend/domains/workspace/query/project-management.service.d.ts +2 -0
  184. package/dist/src/backend/domains/workspace/query/project-management.service.d.ts.map +1 -1
  185. package/dist/src/backend/domains/workspace/query/workspace-query.service.d.ts +4 -1
  186. package/dist/src/backend/domains/workspace/query/workspace-query.service.d.ts.map +1 -1
  187. package/dist/src/backend/domains/workspace/query/workspace-query.service.js +18 -7
  188. package/dist/src/backend/domains/workspace/query/workspace-query.service.js.map +1 -1
  189. package/dist/src/backend/domains/workspace/query/workspace-query.service.test.js +57 -0
  190. package/dist/src/backend/domains/workspace/query/workspace-query.service.test.js.map +1 -1
  191. package/dist/src/backend/domains/workspace/state/kanban-state.d.ts +2 -1
  192. package/dist/src/backend/domains/workspace/state/kanban-state.d.ts.map +1 -1
  193. package/dist/src/backend/domains/workspace/state/kanban-state.js +6 -3
  194. package/dist/src/backend/domains/workspace/state/kanban-state.js.map +1 -1
  195. package/dist/src/backend/domains/workspace/state/kanban-state.test.js +23 -0
  196. package/dist/src/backend/domains/workspace/state/kanban-state.test.js.map +1 -1
  197. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.d.ts +3 -6
  198. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.d.ts.map +1 -1
  199. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.js +7 -116
  200. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.js.map +1 -1
  201. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.test.js +38 -65
  202. package/dist/src/backend/domains/workspace/worktree/worktree-lifecycle.service.test.js.map +1 -1
  203. package/dist/src/backend/interceptors/conversation-rename.interceptor.d.ts.map +1 -1
  204. package/dist/src/backend/interceptors/conversation-rename.interceptor.js +6 -4
  205. package/dist/src/backend/interceptors/conversation-rename.interceptor.js.map +1 -1
  206. package/dist/src/backend/interceptors/conversation-rename.interceptor.test.js +10 -10
  207. package/dist/src/backend/interceptors/conversation-rename.interceptor.test.js.map +1 -1
  208. package/dist/src/backend/lib/file-helpers.d.ts +2 -0
  209. package/dist/src/backend/lib/file-helpers.d.ts.map +1 -1
  210. package/dist/src/backend/lib/file-helpers.js +64 -1
  211. package/dist/src/backend/lib/file-helpers.js.map +1 -1
  212. package/dist/src/backend/middleware/cors.middleware.d.ts +1 -2
  213. package/dist/src/backend/middleware/cors.middleware.d.ts.map +1 -1
  214. package/dist/src/backend/middleware/cors.middleware.js +0 -2
  215. package/dist/src/backend/middleware/cors.middleware.js.map +1 -1
  216. package/dist/src/backend/middleware/index.d.ts +1 -1
  217. package/dist/src/backend/middleware/index.d.ts.map +1 -1
  218. package/dist/src/backend/middleware/index.js +1 -1
  219. package/dist/src/backend/middleware/index.js.map +1 -1
  220. package/dist/src/backend/orchestration/data-backup.service.test.js +1 -0
  221. package/dist/src/backend/orchestration/data-backup.service.test.js.map +1 -1
  222. package/dist/src/backend/orchestration/domain-bridges.orchestrator.d.ts +26 -1
  223. package/dist/src/backend/orchestration/domain-bridges.orchestrator.d.ts.map +1 -1
  224. package/dist/src/backend/orchestration/domain-bridges.orchestrator.js +21 -1
  225. package/dist/src/backend/orchestration/domain-bridges.orchestrator.js.map +1 -1
  226. package/dist/src/backend/orchestration/event-collector.orchestrator.d.ts +8 -1
  227. package/dist/src/backend/orchestration/event-collector.orchestrator.d.ts.map +1 -1
  228. package/dist/src/backend/orchestration/event-collector.orchestrator.js +41 -21
  229. package/dist/src/backend/orchestration/event-collector.orchestrator.js.map +1 -1
  230. package/dist/src/backend/orchestration/event-collector.orchestrator.test.js +19 -4
  231. package/dist/src/backend/orchestration/event-collector.orchestrator.test.js.map +1 -1
  232. package/dist/src/backend/orchestration/snapshot-reconciliation.orchestrator.d.ts +6 -2
  233. package/dist/src/backend/orchestration/snapshot-reconciliation.orchestrator.d.ts.map +1 -1
  234. package/dist/src/backend/orchestration/snapshot-reconciliation.orchestrator.js +8 -3
  235. package/dist/src/backend/orchestration/snapshot-reconciliation.orchestrator.js.map +1 -1
  236. package/dist/src/backend/orchestration/workspace-archive.orchestrator.d.ts +19 -1
  237. package/dist/src/backend/orchestration/workspace-archive.orchestrator.d.ts.map +1 -1
  238. package/dist/src/backend/orchestration/workspace-archive.orchestrator.js +5 -7
  239. package/dist/src/backend/orchestration/workspace-archive.orchestrator.js.map +1 -1
  240. package/dist/src/backend/orchestration/workspace-archive.orchestrator.test.js +40 -47
  241. package/dist/src/backend/orchestration/workspace-archive.orchestrator.test.js.map +1 -1
  242. package/dist/src/backend/orchestration/workspace-init.orchestrator.d.ts.map +1 -1
  243. package/dist/src/backend/orchestration/workspace-init.orchestrator.js +86 -36
  244. package/dist/src/backend/orchestration/workspace-init.orchestrator.js.map +1 -1
  245. package/dist/src/backend/orchestration/workspace-init.orchestrator.test.js +62 -2
  246. package/dist/src/backend/orchestration/workspace-init.orchestrator.test.js.map +1 -1
  247. package/dist/src/backend/resource_accessors/workspace.accessor.d.ts +1 -0
  248. package/dist/src/backend/resource_accessors/workspace.accessor.d.ts.map +1 -1
  249. package/dist/src/backend/resource_accessors/workspace.accessor.js.map +1 -1
  250. package/dist/src/backend/routers/websocket/index.d.ts +1 -0
  251. package/dist/src/backend/routers/websocket/index.d.ts.map +1 -1
  252. package/dist/src/backend/routers/websocket/index.js +1 -0
  253. package/dist/src/backend/routers/websocket/index.js.map +1 -1
  254. package/dist/src/backend/routers/websocket/post-run-logs.handler.d.ts +9 -0
  255. package/dist/src/backend/routers/websocket/post-run-logs.handler.d.ts.map +1 -0
  256. package/dist/src/backend/routers/websocket/post-run-logs.handler.js +52 -0
  257. package/dist/src/backend/routers/websocket/post-run-logs.handler.js.map +1 -0
  258. package/dist/src/backend/server.d.ts.map +1 -1
  259. package/dist/src/backend/server.js +10 -4
  260. package/dist/src/backend/server.js.map +1 -1
  261. package/dist/src/backend/server.upgrade.test.js +2 -0
  262. package/dist/src/backend/server.upgrade.test.js.map +1 -1
  263. package/dist/src/backend/services/workspace-snapshot-store.service.d.ts +2 -0
  264. package/dist/src/backend/services/workspace-snapshot-store.service.d.ts.map +1 -1
  265. package/dist/src/backend/services/workspace-snapshot-store.service.js +8 -4
  266. package/dist/src/backend/services/workspace-snapshot-store.service.js.map +1 -1
  267. package/dist/src/backend/trpc/admin.trpc.js +2 -2
  268. package/dist/src/backend/trpc/admin.trpc.js.map +1 -1
  269. package/dist/src/backend/trpc/index.d.ts +41 -1
  270. package/dist/src/backend/trpc/index.d.ts.map +1 -1
  271. package/dist/src/backend/trpc/project.trpc.d.ts +14 -0
  272. package/dist/src/backend/trpc/project.trpc.d.ts.map +1 -1
  273. package/dist/src/backend/trpc/project.trpc.js +22 -0
  274. package/dist/src/backend/trpc/project.trpc.js.map +1 -1
  275. package/dist/src/backend/trpc/session.router.test.js +1 -0
  276. package/dist/src/backend/trpc/session.router.test.js.map +1 -1
  277. package/dist/src/backend/trpc/session.trpc.d.ts +4 -0
  278. package/dist/src/backend/trpc/session.trpc.d.ts.map +1 -1
  279. package/dist/src/backend/trpc/session.trpc.js +2 -2
  280. package/dist/src/backend/trpc/session.trpc.js.map +1 -1
  281. package/dist/src/backend/trpc/workspace/files.trpc.d.ts.map +1 -1
  282. package/dist/src/backend/trpc/workspace/files.trpc.js +1 -64
  283. package/dist/src/backend/trpc/workspace/files.trpc.js.map +1 -1
  284. package/dist/src/backend/trpc/workspace/init.router.test.js +1 -1
  285. package/dist/src/backend/trpc/workspace/init.router.test.js.map +1 -1
  286. package/dist/src/backend/trpc/workspace/init.trpc.d.ts +1 -0
  287. package/dist/src/backend/trpc/workspace/init.trpc.d.ts.map +1 -1
  288. package/dist/src/backend/trpc/workspace/init.trpc.js +2 -3
  289. package/dist/src/backend/trpc/workspace/init.trpc.js.map +1 -1
  290. package/dist/src/backend/trpc/workspace/run-script.router.test.js +1 -1
  291. package/dist/src/backend/trpc/workspace/run-script.router.test.js.map +1 -1
  292. package/dist/src/backend/trpc/workspace/run-script.trpc.d.ts +2 -0
  293. package/dist/src/backend/trpc/workspace/run-script.trpc.d.ts.map +1 -1
  294. package/dist/src/backend/trpc/workspace/run-script.trpc.js +1 -1
  295. package/dist/src/backend/trpc/workspace/run-script.trpc.js.map +1 -1
  296. package/dist/src/backend/trpc/workspace/workspace-helpers.d.ts +2 -0
  297. package/dist/src/backend/trpc/workspace/workspace-helpers.d.ts.map +1 -1
  298. package/dist/src/backend/trpc/workspace.router.test.js +39 -0
  299. package/dist/src/backend/trpc/workspace.router.test.js.map +1 -1
  300. package/dist/src/backend/trpc/workspace.trpc.d.ts +23 -1
  301. package/dist/src/backend/trpc/workspace.trpc.d.ts.map +1 -1
  302. package/dist/src/backend/trpc/workspace.trpc.js +6 -3
  303. package/dist/src/backend/trpc/workspace.trpc.js.map +1 -1
  304. package/dist/src/cli/index.js +12 -3
  305. package/dist/src/cli/index.js.map +1 -1
  306. package/dist/src/shared/schemas/factory-config.schema.d.ts +1 -0
  307. package/dist/src/shared/schemas/factory-config.schema.d.ts.map +1 -1
  308. package/dist/src/shared/schemas/factory-config.schema.js +1 -0
  309. package/dist/src/shared/schemas/factory-config.schema.js.map +1 -1
  310. package/dist/src/shared/schemas/persisted-stores.schema.d.ts +0 -2
  311. package/dist/src/shared/schemas/persisted-stores.schema.d.ts.map +1 -1
  312. package/dist/src/shared/schemas/persisted-stores.schema.js +0 -1
  313. package/dist/src/shared/schemas/persisted-stores.schema.js.map +1 -1
  314. package/dist/tsconfig.backend.tsbuildinfo +1 -1
  315. package/package.json +1 -1
  316. package/prisma/migrations/20260222120000_add_post_run_command/migration.sql +1 -0
  317. package/prisma/schema.prisma +1 -0
  318. package/dist/client/assets/channel-B2z94T-9.js +0 -1
  319. package/dist/client/assets/classDiagram-2ON5EDUG-B2LoFG_o.js +0 -1
  320. package/dist/client/assets/classDiagram-v2-WZHVMYZB-B2LoFG_o.js +0 -1
  321. package/dist/client/assets/clone-C8LA0zQQ.js +0 -1
  322. package/dist/client/assets/index-DvtmO7DV.css +0 -1
  323. package/dist/client/assets/stateDiagram-v2-4FDKWEC3-CO6XGRkL.js +0 -1
@@ -1,15 +1,13 @@
1
- import { AcpEventTranslator, AcpPermissionBridge, acpRuntimeManager, } from '../../../../backend/domains/session/acp/index.js';
1
+ import { AcpEventTranslator, acpRuntimeManager, } from '../../../../backend/domains/session/acp/index.js';
2
2
  import { acpTraceLogger } from '../../../../backend/domains/session/logging/acp-trace-logger.service.js';
3
3
  import { sessionFileLogger } from '../../../../backend/domains/session/logging/session-file-logger.service.js';
4
- import { sessionDomainService } from '../../../../backend/domains/session/session-domain.service.js';
4
+ import { sessionDomainService, } from '../../../../backend/domains/session/session-domain.service.js';
5
5
  import { interceptorRegistry } from '../../../../backend/interceptors/registry.js';
6
- import { userSettingsAccessor } from '../../../../backend/resource_accessors/user-settings.accessor.js';
7
6
  import { createLogger } from '../../../../backend/services/logger.service.js';
8
- import { extractPlanText } from '../../../../shared/acp-protocol/plan-content.js';
9
- import { EMPTY_CHAT_BAR_CAPABILITIES } from '../../../../shared/chat-capabilities.js';
10
7
  import { SessionStatus } from '../../../../shared/core/index.js';
11
- import { isUserQuestionRequest } from '../../../../shared/pending-request-types.js';
12
8
  import { createInitialSessionRuntimeState, } from '../../../../shared/session-runtime.js';
9
+ import { SessionConfigService, } from './session.config.service.js';
10
+ import { SessionPermissionService } from './session.permission.service.js';
13
11
  import { sessionPromptBuilder } from './session.prompt-builder.js';
14
12
  import { sessionRepository } from './session.repository.js';
15
13
  const logger = createLogger('session');
@@ -23,11 +21,14 @@ function toErrorMessage(error) {
23
21
  }
24
22
  return String(error);
25
23
  }
26
- class SessionService {
24
+ export class SessionService {
27
25
  repository;
28
26
  promptBuilder;
27
+ runtimeManager;
28
+ sessionDomainService;
29
29
  acpEventTranslator = new AcpEventTranslator(logger);
30
- acpPermissionBridges = new Map();
30
+ sessionPermissionService;
31
+ sessionConfigService;
31
32
  acpStreamState = new Map();
32
33
  pendingAcpToolCalls = new Map();
33
34
  suppressAcpReplayForSession = new Set();
@@ -52,10 +53,9 @@ class SessionService {
52
53
  return Date.now() - updatedAtMs > STALE_LOADING_RUNTIME_MAX_AGE_MS;
53
54
  }
54
55
  setupAcpEventHandler(sessionId) {
55
- const bridge = new AcpPermissionBridge();
56
- this.acpPermissionBridges.set(sessionId, bridge);
56
+ const permissionBridge = this.sessionPermissionService.createPermissionBridge(sessionId);
57
57
  return {
58
- permissionBridge: bridge,
58
+ permissionBridge,
59
59
  onAcpEvent: (sid, event) => {
60
60
  const typed = event;
61
61
  if (typed.type === 'acp_session_update') {
@@ -82,7 +82,7 @@ class SessionService {
82
82
  return;
83
83
  }
84
84
  if (typed.type === 'acp_permission_request') {
85
- this.handleAcpPermissionRequest(sid, event);
85
+ this.sessionPermissionService.handlePermissionRequest(sid, event);
86
86
  return;
87
87
  }
88
88
  },
@@ -112,14 +112,10 @@ class SessionService {
112
112
  this.suppressAcpReplayForSession.delete(sid);
113
113
  this.sessionToWorkspace.delete(sid);
114
114
  this.sessionToWorkingDir.delete(sid);
115
- const b = this.acpPermissionBridges.get(sid);
116
- if (b) {
117
- b.cancelAll();
118
- this.acpPermissionBridges.delete(sid);
119
- }
115
+ this.sessionPermissionService.cancelPendingRequests(sid);
120
116
  acpTraceLogger.log(sid, 'runtime_exit', { exitCode });
121
117
  try {
122
- sessionDomainService.markProcessExit(sid, exitCode);
118
+ this.sessionDomainService.markProcessExit(sid, exitCode);
123
119
  const session = await this.repository.updateSession(sid, {
124
120
  status: SessionStatus.COMPLETED,
125
121
  });
@@ -145,7 +141,7 @@ class SessionService {
145
141
  message: error.message,
146
142
  stack: error.stack,
147
143
  });
148
- sessionDomainService.markError(sid, error.message);
144
+ this.sessionDomainService.markError(sid, error.message);
149
145
  logger.error('ACP client error', {
150
146
  sessionId: sid,
151
147
  error: error.message,
@@ -167,25 +163,15 @@ class SessionService {
167
163
  }
168
164
  this.trackPendingAcpToolCalls(sid, delta);
169
165
  if (delta.type === 'config_options_update') {
170
- const acpHandle = acpRuntimeManager.getClient(sid);
166
+ const acpHandle = this.runtimeManager.getClient(sid);
171
167
  if (acpHandle) {
172
168
  const { configOptions } = delta;
173
- acpHandle.configOptions = configOptions;
174
- void this.persistAcpConfigSnapshot(sid, {
175
- provider: acpHandle.provider,
176
- providerSessionId: acpHandle.providerSessionId,
177
- configOptions: acpHandle.configOptions,
178
- });
179
- sessionDomainService.emitDelta(sid, delta);
180
- sessionDomainService.emitDelta(sid, {
181
- type: 'chat_capabilities',
182
- capabilities: this.buildAcpChatBarCapabilities(acpHandle),
183
- });
169
+ this.sessionConfigService.applyConfigOptionsUpdateDelta(sid, acpHandle, configOptions);
184
170
  return;
185
171
  }
186
172
  }
187
173
  if (delta.type !== 'agent_message') {
188
- sessionDomainService.emitDelta(sid, delta);
174
+ this.sessionDomainService.emitDelta(sid, delta);
189
175
  return;
190
176
  }
191
177
  const data = delta.data;
@@ -194,8 +180,8 @@ class SessionService {
194
180
  return;
195
181
  }
196
182
  this.acpStreamState.delete(sid);
197
- const order = sessionDomainService.appendClaudeEvent(sid, data);
198
- sessionDomainService.emitDelta(sid, { ...delta, order });
183
+ const order = this.sessionDomainService.appendClaudeEvent(sid, data);
184
+ this.sessionDomainService.emitDelta(sid, { ...delta, order });
199
185
  }
200
186
  trackPendingAcpToolCalls(sid, delta) {
201
187
  if (delta.type === 'agent_message') {
@@ -429,14 +415,14 @@ class SessionService {
429
415
  if (this.suppressAcpReplayForSession.has(sid)) {
430
416
  return;
431
417
  }
432
- if (acpRuntimeManager.isSessionWorking(sid)) {
418
+ if (this.runtimeManager.isSessionWorking(sid)) {
433
419
  return;
434
420
  }
435
421
  const normalized = text.trim();
436
422
  if (normalized.length === 0) {
437
423
  return;
438
424
  }
439
- sessionDomainService.injectCommittedUserMessage(sid, normalized);
425
+ this.sessionDomainService.injectCommittedUserMessage(sid, normalized);
440
426
  }
441
427
  accumulateAcpText(sid, data) {
442
428
  const content = data.message?.content;
@@ -445,7 +431,7 @@ class SessionService {
445
431
  : '';
446
432
  let ss = this.acpStreamState.get(sid);
447
433
  if (!ss) {
448
- ss = { textOrder: sessionDomainService.allocateOrder(sid), accText: '' };
434
+ ss = { textOrder: this.sessionDomainService.allocateOrder(sid), accText: '' };
449
435
  this.acpStreamState.set(sid, ss);
450
436
  }
451
437
  ss.accText += chunkText;
@@ -453,67 +439,13 @@ class SessionService {
453
439
  type: 'assistant',
454
440
  message: { role: 'assistant', content: [{ type: 'text', text: ss.accText }] },
455
441
  };
456
- sessionDomainService.upsertClaudeEvent(sid, accMsg, ss.textOrder);
457
- sessionDomainService.emitDelta(sid, {
442
+ this.sessionDomainService.upsertClaudeEvent(sid, accMsg, ss.textOrder);
443
+ this.sessionDomainService.emitDelta(sid, {
458
444
  type: 'agent_message',
459
445
  data: accMsg,
460
446
  order: ss.textOrder,
461
447
  });
462
448
  }
463
- handleAcpPermissionRequest(sid, event) {
464
- const { requestId, params } = event;
465
- const toolName = params.toolCall.title ?? 'ACP Tool';
466
- const toolInput = params.toolCall.rawInput ?? {};
467
- const acpOptions = params.options.map((o) => ({
468
- optionId: o.optionId,
469
- name: o.name,
470
- kind: o.kind,
471
- }));
472
- const planContent = this.extractPlanContent(toolName, toolInput);
473
- if (isUserQuestionRequest({ toolName, input: toolInput })) {
474
- const questions = this.extractAskUserQuestions(toolInput);
475
- sessionDomainService.emitDelta(sid, {
476
- type: 'user_question',
477
- requestId,
478
- toolName,
479
- questions,
480
- acpOptions,
481
- });
482
- }
483
- else {
484
- sessionDomainService.emitDelta(sid, {
485
- type: 'permission_request',
486
- requestId,
487
- toolName,
488
- toolUseId: params.toolCall.toolCallId,
489
- toolInput,
490
- planContent,
491
- acpOptions,
492
- });
493
- }
494
- sessionDomainService.setPendingInteractiveRequest(sid, {
495
- requestId,
496
- toolName,
497
- toolUseId: params.toolCall.toolCallId,
498
- input: toolInput,
499
- planContent,
500
- acpOptions,
501
- timestamp: new Date().toISOString(),
502
- });
503
- }
504
- extractAskUserQuestions(input) {
505
- const questions = input.questions;
506
- if (!Array.isArray(questions)) {
507
- return [];
508
- }
509
- return questions;
510
- }
511
- extractPlanContent(toolName, input) {
512
- if (toolName !== 'ExitPlanMode') {
513
- return null;
514
- }
515
- return extractPlanText(input.plan);
516
- }
517
449
  async createAcpClient(sessionId, options, session) {
518
450
  const sessionContext = await this.loadSessionContext(sessionId, session);
519
451
  if (!sessionContext) {
@@ -541,7 +473,7 @@ class SessionService {
541
473
  };
542
474
  let handle;
543
475
  try {
544
- handle = await acpRuntimeManager.getOrCreateClient(sessionId, clientOptions, handlers, {
476
+ handle = await this.runtimeManager.getOrCreateClient(sessionId, clientOptions, handlers, {
545
477
  workspaceId: sessionContext.workspaceId,
546
478
  workingDir: sessionContext.workingDir,
547
479
  });
@@ -559,12 +491,12 @@ class SessionService {
559
491
  existingMetadata: session?.providerMetadata ?? undefined,
560
492
  });
561
493
  if (handle.configOptions.length > 0) {
562
- sessionDomainService.emitDelta(sessionId, {
494
+ this.sessionDomainService.emitDelta(sessionId, {
563
495
  type: 'config_options_update',
564
496
  configOptions: handle.configOptions,
565
497
  });
566
498
  }
567
- sessionDomainService.emitDelta(sessionId, {
499
+ this.sessionDomainService.emitDelta(sessionId, {
568
500
  type: 'chat_capabilities',
569
501
  capabilities: this.buildAcpChatBarCapabilities(handle),
570
502
  });
@@ -574,16 +506,16 @@ class SessionService {
574
506
  if (!session?.providerSessionId) {
575
507
  return false;
576
508
  }
577
- if (!sessionDomainService.isHistoryHydrated(sessionId)) {
509
+ if (!this.sessionDomainService.isHistoryHydrated(sessionId)) {
578
510
  return false;
579
511
  }
580
- return sessionDomainService.getTranscriptSnapshot(sessionId).length > 0;
512
+ return this.sessionDomainService.getTranscriptSnapshot(sessionId).length > 0;
581
513
  }
582
514
  maybeLiftReplaySuppression(sessionId) {
583
515
  if (!this.suppressAcpReplayForSession.has(sessionId)) {
584
516
  return;
585
517
  }
586
- if (!acpRuntimeManager.isSessionWorking(sessionId)) {
518
+ if (!this.runtimeManager.isSessionWorking(sessionId)) {
587
519
  return;
588
520
  }
589
521
  this.suppressAcpReplayForSession.delete(sessionId);
@@ -591,16 +523,26 @@ class SessionService {
591
523
  constructor(options) {
592
524
  this.repository = options?.repository ?? sessionRepository;
593
525
  this.promptBuilder = options?.promptBuilder ?? sessionPromptBuilder;
526
+ this.runtimeManager = options?.runtimeManager ?? acpRuntimeManager;
527
+ this.sessionDomainService = options?.sessionDomainService ?? sessionDomainService;
528
+ this.sessionPermissionService = new SessionPermissionService({
529
+ sessionDomainService: this.sessionDomainService,
530
+ });
531
+ this.sessionConfigService = new SessionConfigService({
532
+ repository: this.repository,
533
+ runtimeManager: this.runtimeManager,
534
+ sessionDomainService: this.sessionDomainService,
535
+ });
594
536
  }
595
537
  async startSession(sessionId, options) {
596
538
  const session = await this.repository.getSessionById(sessionId);
597
539
  if (!session) {
598
540
  throw new Error(`Session not found: ${sessionId}`);
599
541
  }
600
- if (acpRuntimeManager.isStopInProgress(sessionId)) {
542
+ if (this.runtimeManager.isStopInProgress(sessionId)) {
601
543
  throw new Error('Session is currently being stopped');
602
544
  }
603
- const existingClient = acpRuntimeManager.getClient(sessionId);
545
+ const existingClient = this.runtimeManager.getClient(sessionId);
604
546
  if (existingClient) {
605
547
  throw new Error('Session is already running');
606
548
  }
@@ -618,279 +560,22 @@ class SessionService {
618
560
  logger.info('Session started', { sessionId, provider: session.provider });
619
561
  }
620
562
  async applyStartupModePreset(sessionId, handle, startupModePreset, workflow) {
621
- if (!startupModePreset) {
622
- return;
623
- }
624
- const modeResult = await this.applyStartupCollaborationModePreset({
625
- sessionId,
626
- handle,
627
- startupModePreset,
628
- workflow,
629
- configOptions: handle.configOptions,
563
+ await this.sessionConfigService.applyStartupModePreset(sessionId, handle, startupModePreset, workflow, {
564
+ persistSnapshot: this.persistAcpConfigSnapshot.bind(this),
630
565
  });
631
- const executionResult = await this.applyStartupExecutionModePreset({
632
- sessionId,
633
- handle,
634
- startupModePreset,
635
- workflow,
636
- configOptions: modeResult.configOptions,
637
- });
638
- const didUpdate = modeResult.didUpdate || executionResult.didUpdate;
639
- if (!didUpdate) {
640
- return;
641
- }
642
- handle.configOptions = executionResult.configOptions;
643
- try {
644
- await this.persistAcpConfigSnapshot(sessionId, {
645
- provider: handle.provider,
646
- providerSessionId: handle.providerSessionId,
647
- configOptions: executionResult.configOptions,
648
- });
649
- sessionDomainService.emitDelta(sessionId, {
650
- type: 'config_options_update',
651
- configOptions: executionResult.configOptions,
652
- });
653
- sessionDomainService.emitDelta(sessionId, {
654
- type: 'chat_capabilities',
655
- capabilities: this.buildAcpChatBarCapabilities(handle),
656
- });
657
- }
658
- catch (error) {
659
- logger.warn('Failed persisting startup mode preset configuration snapshot', {
660
- sessionId,
661
- provider: handle.provider,
662
- workflow,
663
- startupModePreset,
664
- error: error instanceof Error ? error.message : String(error),
665
- });
666
- }
667
- }
668
- async applyStartupCollaborationModePreset(params) {
669
- const modeOption = params.configOptions.find((option) => option.category === 'mode');
670
- if (!modeOption) {
671
- return { configOptions: params.configOptions, didUpdate: false };
672
- }
673
- const availableModeValues = this.getConfigOptionValues(modeOption);
674
- const targetMode = this.resolveStartupModeTarget(params.handle.provider, params.startupModePreset, availableModeValues);
675
- if (!targetMode) {
676
- logger.debug('Startup mode preset not available in ACP mode options', {
677
- sessionId: params.sessionId,
678
- provider: params.handle.provider,
679
- workflow: params.workflow,
680
- startupModePreset: params.startupModePreset,
681
- availableModeValues,
682
- });
683
- return { configOptions: params.configOptions, didUpdate: false };
684
- }
685
- const currentMode = modeOption.currentValue ? String(modeOption.currentValue) : null;
686
- if (currentMode === targetMode) {
687
- return { configOptions: params.configOptions, didUpdate: false };
688
- }
689
- try {
690
- const configOptions = await acpRuntimeManager.setSessionMode(params.sessionId, targetMode);
691
- return { configOptions, didUpdate: true };
692
- }
693
- catch (error) {
694
- logger.warn('Failed applying startup mode preset', {
695
- sessionId: params.sessionId,
696
- provider: params.handle.provider,
697
- workflow: params.workflow,
698
- startupModePreset: params.startupModePreset,
699
- targetMode,
700
- error: error instanceof Error ? error.message : String(error),
701
- });
702
- return { configOptions: params.configOptions, didUpdate: false };
703
- }
704
- }
705
- async applyStartupExecutionModePreset(params) {
706
- const executionModeOption = params.configOptions.find((option) => option.id === 'execution_mode' || option.category === 'permission');
707
- const targetExecutionMode = this.resolveStartupExecutionModeTarget(params.handle.provider, params.workflow, params.startupModePreset, executionModeOption);
708
- if (!(executionModeOption && targetExecutionMode)) {
709
- return { configOptions: params.configOptions, didUpdate: false };
710
- }
711
- const currentExecutionMode = executionModeOption.currentValue
712
- ? String(executionModeOption.currentValue)
713
- : null;
714
- if (currentExecutionMode === targetExecutionMode) {
715
- return { configOptions: params.configOptions, didUpdate: false };
716
- }
717
- try {
718
- const configOptions = await acpRuntimeManager.setConfigOption(params.sessionId, executionModeOption.id, targetExecutionMode);
719
- return { configOptions, didUpdate: true };
720
- }
721
- catch (error) {
722
- logger.warn('Failed applying startup execution-mode preset', {
723
- sessionId: params.sessionId,
724
- provider: params.handle.provider,
725
- workflow: params.workflow,
726
- startupModePreset: params.startupModePreset,
727
- targetExecutionMode,
728
- error: error instanceof Error ? error.message : String(error),
729
- });
730
- return { configOptions: params.configOptions, didUpdate: false };
731
- }
732
- }
733
- resolveStartupModeTarget(provider, startupModePreset, availableModeValues) {
734
- if (availableModeValues.length === 0) {
735
- return null;
736
- }
737
- if (startupModePreset === 'plan') {
738
- return this.findModeValue(availableModeValues, ['plan']);
739
- }
740
- if (provider === 'CLAUDE') {
741
- return this.findModeValue(availableModeValues, [
742
- 'bypassPermissions',
743
- 'dangerouslySkipPermissions',
744
- 'dangerousSkipPermissions',
745
- 'acceptEdits',
746
- ]);
747
- }
748
- return this.findModeValue(availableModeValues, [
749
- 'fullAccess',
750
- 'full_access',
751
- 'full-access',
752
- 'code',
753
- ]);
754
- }
755
- resolveStartupExecutionModeTarget(provider, workflow, startupModePreset, executionModeOption) {
756
- if (provider !== 'CODEX' ||
757
- workflow !== 'ratchet' ||
758
- startupModePreset !== 'non_interactive' ||
759
- !executionModeOption) {
760
- return null;
761
- }
762
- const availableValues = this.getConfigOptionValues(executionModeOption);
763
- const yoloByValue = this.findModeValue(availableValues, ['["never","danger-full-access"]']);
764
- if (yoloByValue) {
765
- return yoloByValue;
766
- }
767
- const yoloByName = this.getSelectOptions(executionModeOption).find((option) => /yolo/i.test(option.name ?? ''));
768
- return yoloByName?.value ?? null;
769
566
  }
770
567
  async applyConfiguredPermissionPreset(sessionId, session, handle) {
771
- if (handle.provider !== 'CODEX') {
772
- return;
773
- }
774
- const executionModeOption = handle.configOptions.find((option) => option.id === 'execution_mode' || option.category === 'permission');
775
- if (!executionModeOption) {
776
- return;
777
- }
778
- let permissionPreset = session.workflow === 'ratchet' ? 'YOLO' : 'STRICT';
779
- try {
780
- const settings = await userSettingsAccessor.get();
781
- permissionPreset =
782
- session.workflow === 'ratchet'
783
- ? settings.ratchetPermissions
784
- : settings.defaultWorkspacePermissions;
785
- }
786
- catch (error) {
787
- logger.warn('Failed loading user permission presets; using defaults', {
788
- sessionId,
789
- workflow: session.workflow,
790
- error: error instanceof Error ? error.message : String(error),
791
- });
792
- }
793
- const targetExecutionMode = this.resolveConfiguredExecutionModeTarget(executionModeOption, permissionPreset);
794
- if (!targetExecutionMode) {
795
- return;
796
- }
797
- const currentExecutionMode = executionModeOption.currentValue
798
- ? String(executionModeOption.currentValue)
799
- : null;
800
- if (currentExecutionMode === targetExecutionMode) {
801
- return;
802
- }
803
- try {
804
- const configOptions = await acpRuntimeManager.setConfigOption(sessionId, executionModeOption.id, targetExecutionMode);
805
- handle.configOptions = configOptions;
806
- await this.persistAcpConfigSnapshot(sessionId, {
807
- provider: handle.provider,
808
- providerSessionId: handle.providerSessionId,
809
- configOptions,
810
- });
811
- sessionDomainService.emitDelta(sessionId, {
812
- type: 'config_options_update',
813
- configOptions,
814
- });
815
- sessionDomainService.emitDelta(sessionId, {
816
- type: 'chat_capabilities',
817
- capabilities: this.buildAcpChatBarCapabilities(handle),
818
- });
819
- }
820
- catch (error) {
821
- logger.warn('Failed applying configured session permission preset', {
822
- sessionId,
823
- workflow: session.workflow,
824
- permissionPreset,
825
- targetExecutionMode,
826
- error: error instanceof Error ? error.message : String(error),
827
- });
828
- }
829
- }
830
- resolveConfiguredExecutionModeTarget(executionModeOption, permissionPreset) {
831
- const availableValues = this.getConfigOptionValues(executionModeOption);
832
- const preferredValuesByPreset = {
833
- STRICT: [
834
- '["on-request","workspace-write"]',
835
- '["on-request","read-only"]',
836
- '["on-request","danger-full-access"]',
837
- ],
838
- RELAXED: [
839
- '["on-failure","workspace-write"]',
840
- '["on-failure","read-only"]',
841
- '["on-failure","danger-full-access"]',
842
- ],
843
- YOLO: [
844
- '["never","danger-full-access"]',
845
- '["never","workspace-write"]',
846
- '["never","read-only"]',
847
- ],
848
- };
849
- const preferredValues = preferredValuesByPreset[permissionPreset];
850
- const byValue = this.findModeValue(availableValues, preferredValues);
851
- if (byValue) {
852
- return byValue;
853
- }
854
- const byName = this.getSelectOptions(executionModeOption).find((option) => {
855
- const name = option.name ?? '';
856
- if (permissionPreset === 'STRICT') {
857
- return /on request/i.test(name);
858
- }
859
- if (permissionPreset === 'RELAXED') {
860
- return /on failure/i.test(name);
861
- }
862
- return /yolo|never ask/i.test(name);
863
- });
864
- return byName?.value ?? null;
865
- }
866
- findModeValue(availableModeValues, preferredModeValues) {
867
- if (availableModeValues.length === 0 || preferredModeValues.length === 0) {
868
- return null;
869
- }
870
- const availableByNormalized = new Map();
871
- for (const value of availableModeValues) {
872
- availableByNormalized.set(this.normalizeModeValue(value), value);
873
- }
874
- for (const preferredValue of preferredModeValues) {
875
- const match = availableByNormalized.get(this.normalizeModeValue(preferredValue));
876
- if (match) {
877
- return match;
878
- }
879
- }
880
- return null;
881
- }
882
- normalizeModeValue(value) {
883
- return value.replace(/[^a-z0-9]/gi, '').toLowerCase();
568
+ await this.sessionConfigService.applyConfiguredPermissionPreset(sessionId, session, handle);
884
569
  }
885
570
  async stopSession(sessionId, options) {
886
571
  const session = await this.loadSessionForStop(sessionId);
887
572
  const workspaceId = session?.workspaceId ?? this.sessionToWorkspace.get(sessionId);
888
- if (acpRuntimeManager.isStopInProgress(sessionId)) {
573
+ if (this.runtimeManager.isStopInProgress(sessionId)) {
889
574
  logger.debug('Session stop already in progress', { sessionId });
890
575
  return;
891
576
  }
892
577
  const current = this.getRuntimeSnapshot(sessionId);
893
- sessionDomainService.setRuntimeSnapshot(sessionId, {
578
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
894
579
  ...current,
895
580
  phase: 'stopping',
896
581
  activity: 'IDLE',
@@ -898,15 +583,11 @@ class SessionService {
898
583
  });
899
584
  this.acpStreamState.delete(sessionId);
900
585
  this.suppressAcpReplayForSession.delete(sessionId);
901
- const acpBridge = this.acpPermissionBridges.get(sessionId);
902
- if (acpBridge) {
903
- acpBridge.cancelAll();
904
- this.acpPermissionBridges.delete(sessionId);
905
- }
586
+ this.sessionPermissionService.cancelPendingRequests(sessionId);
906
587
  let stopClientFailed = false;
907
588
  try {
908
- if (!acpRuntimeManager.isStopInProgress(sessionId)) {
909
- await acpRuntimeManager.stopClient(sessionId);
589
+ if (!this.runtimeManager.isStopInProgress(sessionId)) {
590
+ await this.runtimeManager.stopClient(sessionId);
910
591
  }
911
592
  }
912
593
  catch (error) {
@@ -919,8 +600,8 @@ class SessionService {
919
600
  finally {
920
601
  this.finalizeOrphanedToolCallsOnStop(sessionId);
921
602
  await this.updateStoppedSessionState(sessionId);
922
- sessionDomainService.clearQueuedWork(sessionId, { emitSnapshot: true });
923
- sessionDomainService.setRuntimeSnapshot(sessionId, {
603
+ this.sessionDomainService.clearQueuedWork(sessionId, { emitSnapshot: true });
604
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
924
605
  phase: 'idle',
925
606
  processState: 'stopped',
926
607
  activity: 'IDLE',
@@ -1024,7 +705,7 @@ class SessionService {
1024
705
  const sessions = await this.repository.getSessionsByWorkspaceId(workspaceId);
1025
706
  for (const session of sessions) {
1026
707
  if (session.status === SessionStatus.RUNNING ||
1027
- acpRuntimeManager.isSessionRunning(session.id)) {
708
+ this.runtimeManager.isSessionRunning(session.id)) {
1028
709
  try {
1029
710
  await this.stopSession(session.id);
1030
711
  }
@@ -1044,7 +725,7 @@ class SessionService {
1044
725
  if (!session) {
1045
726
  throw new Error(`Session not found: ${sessionId}`);
1046
727
  }
1047
- const hadClient = !!acpRuntimeManager.getClient(sessionId);
728
+ const hadClient = !!this.runtimeManager.getClient(sessionId);
1048
729
  const handle = await this.getOrCreateAcpSessionClient(sessionId, options ?? {}, session);
1049
730
  if (!(hadClient || session.providerSessionId)) {
1050
731
  await this.applyConfiguredPermissionPreset(sessionId, session, handle);
@@ -1052,7 +733,7 @@ class SessionService {
1052
733
  return handle;
1053
734
  }
1054
735
  async getOrCreateSessionClientFromRecord(session, options) {
1055
- const hadClient = !!acpRuntimeManager.getClient(session.id);
736
+ const hadClient = !!this.runtimeManager.getClient(session.id);
1056
737
  const handle = await this.getOrCreateAcpSessionClient(session.id, options ?? {}, session);
1057
738
  if (!(hadClient || session.providerSessionId)) {
1058
739
  await this.applyConfiguredPermissionPreset(session.id, session, handle);
@@ -1060,135 +741,28 @@ class SessionService {
1060
741
  return handle;
1061
742
  }
1062
743
  getSessionClient(sessionId) {
1063
- return acpRuntimeManager.getClient(sessionId);
744
+ return this.runtimeManager.getClient(sessionId);
1064
745
  }
1065
746
  getSessionConfigOptions(sessionId) {
1066
- const acpHandle = acpRuntimeManager.getClient(sessionId);
1067
- return acpHandle ? [...acpHandle.configOptions] : [];
747
+ return this.sessionConfigService.getSessionConfigOptions(sessionId);
1068
748
  }
1069
- async getSessionConfigOptionsWithFallback(sessionId) {
1070
- const liveConfigOptions = this.getSessionConfigOptions(sessionId);
1071
- if (liveConfigOptions.length > 0) {
1072
- return liveConfigOptions;
1073
- }
1074
- const session = await this.repository.getSessionById(sessionId);
1075
- if (!session) {
1076
- return [];
1077
- }
1078
- const cachedSnapshot = this.extractAcpConfigSnapshot(session.providerMetadata);
1079
- if (cachedSnapshot && cachedSnapshot.provider === session.provider) {
1080
- return [...cachedSnapshot.configOptions];
1081
- }
1082
- return [];
749
+ getSessionConfigOptionsWithFallback(sessionId) {
750
+ return this.sessionConfigService.getSessionConfigOptionsWithFallback(sessionId);
1083
751
  }
1084
752
  async setSessionModel(sessionId, model) {
1085
- const acpHandle = acpRuntimeManager.getClient(sessionId);
1086
- if (acpHandle) {
1087
- const modelOption = acpHandle.configOptions.find((o) => o.category === 'model');
1088
- if (modelOption && model) {
1089
- const availableValues = this.getConfigOptionValues(modelOption);
1090
- if (availableValues.length > 0 && !availableValues.includes(model)) {
1091
- logger.debug('Skipping unsupported model for ACP session', {
1092
- sessionId,
1093
- provider: acpHandle.provider,
1094
- model,
1095
- availableValues,
1096
- });
1097
- return;
1098
- }
1099
- await this.setSessionConfigOption(sessionId, modelOption.id, model);
1100
- }
1101
- return;
1102
- }
1103
- logger.debug('No ACP handle for setSessionModel', { sessionId, model });
753
+ await this.sessionConfigService.setSessionModel(sessionId, model);
1104
754
  }
1105
755
  setSessionReasoningEffort(sessionId, _effort) {
1106
756
  logger.debug('setSessionReasoningEffort is a no-op for ACP sessions', { sessionId });
1107
757
  }
1108
758
  async setSessionThinkingBudget(sessionId, maxTokens) {
1109
- const acpHandle = acpRuntimeManager.getClient(sessionId);
1110
- if (acpHandle) {
1111
- const thoughtOption = acpHandle.configOptions.find((o) => o.category === 'thought_level');
1112
- if (thoughtOption && maxTokens != null) {
1113
- await this.setSessionConfigOption(sessionId, thoughtOption.id, String(maxTokens));
1114
- }
1115
- return;
1116
- }
1117
- logger.debug('No ACP handle for setSessionThinkingBudget', { sessionId, maxTokens });
759
+ await this.sessionConfigService.setSessionThinkingBudget(sessionId, maxTokens);
1118
760
  }
1119
761
  async setSessionConfigOption(sessionId, configId, value) {
1120
- const acpHandle = acpRuntimeManager.getClient(sessionId);
1121
- if (!acpHandle) {
1122
- const configOptions = await this.setCachedSessionConfigOption(sessionId, configId, value);
1123
- sessionDomainService.emitDelta(sessionId, {
1124
- type: 'config_options_update',
1125
- configOptions,
1126
- });
1127
- return;
1128
- }
1129
- const selectedOption = acpHandle.configOptions.find((option) => option.id === configId);
1130
- const isModeOption = configId === 'mode' || selectedOption?.category === 'mode';
1131
- const isModelOption = configId === 'model' || selectedOption?.category === 'model';
1132
- const configOptions = isModeOption
1133
- ? await acpRuntimeManager.setSessionMode(sessionId, value)
1134
- : isModelOption
1135
- ? await acpRuntimeManager.setSessionModel(sessionId, value)
1136
- : await acpRuntimeManager.setConfigOption(sessionId, configId, value);
1137
- sessionDomainService.emitDelta(sessionId, {
1138
- type: 'config_options_update',
1139
- configOptions,
1140
- });
1141
- const acpHandleAfterUpdate = acpRuntimeManager.getClient(sessionId);
1142
- if (acpHandleAfterUpdate) {
1143
- await this.persistAcpConfigSnapshot(sessionId, {
1144
- provider: acpHandleAfterUpdate.provider,
1145
- providerSessionId: acpHandleAfterUpdate.providerSessionId,
1146
- configOptions: configOptions,
1147
- });
1148
- }
1149
- }
1150
- async setCachedSessionConfigOption(sessionId, configId, value) {
1151
- const session = await this.repository.getSessionById(sessionId);
1152
- if (!session) {
1153
- throw new Error(`Session not found: ${sessionId}`);
1154
- }
1155
- const snapshot = this.extractAcpConfigSnapshot(session.providerMetadata);
1156
- if (!snapshot || snapshot.provider !== session.provider) {
1157
- throw new Error(`Cannot set config option for inactive session ${sessionId}: no cached ACP config available`);
1158
- }
1159
- const configOptions = this.updateCachedConfigOptions(snapshot.configOptions, configId, value);
1160
- await this.persistAcpConfigSnapshot(sessionId, {
1161
- provider: snapshot.provider,
1162
- providerSessionId: snapshot.providerSessionId,
1163
- configOptions,
1164
- existingMetadata: session.providerMetadata,
1165
- });
1166
- return configOptions;
1167
- }
1168
- updateCachedConfigOptions(configOptions, configId, value) {
1169
- let didUpdate = false;
1170
- const nextConfigOptions = configOptions.map((option) => {
1171
- if (option.id !== configId) {
1172
- return option;
1173
- }
1174
- const allowedValues = this.getConfigOptionValues(option);
1175
- if (allowedValues.length > 0 && !allowedValues.includes(value)) {
1176
- throw new Error(`Unsupported value "${value}" for config option "${configId}"` +
1177
- ` (allowed: ${allowedValues.join(', ')})`);
1178
- }
1179
- didUpdate = true;
1180
- return {
1181
- ...option,
1182
- currentValue: value,
1183
- };
1184
- });
1185
- if (!didUpdate) {
1186
- throw new Error(`Unknown config option: ${configId}`);
1187
- }
1188
- return nextConfigOptions;
762
+ await this.sessionConfigService.setSessionConfigOption(sessionId, configId, value);
1189
763
  }
1190
764
  sendSessionMessage(sessionId, content) {
1191
- const acpClient = acpRuntimeManager.getClient(sessionId);
765
+ const acpClient = this.runtimeManager.getClient(sessionId);
1192
766
  if (acpClient) {
1193
767
  const normalizedText = typeof content === 'string' ? content : this.normalizeContentToText(content);
1194
768
  return this.sendAcpMessage(sessionId, normalizedText).then(() => {
@@ -1232,7 +806,7 @@ class SessionService {
1232
806
  async sendAcpMessage(sessionId, content) {
1233
807
  const workspaceId = this.sessionToWorkspace.get(sessionId);
1234
808
  this.pendingAcpToolCalls.set(sessionId, new Map());
1235
- sessionDomainService.setRuntimeSnapshot(sessionId, {
809
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1236
810
  phase: 'running',
1237
811
  processState: 'alive',
1238
812
  activity: 'WORKING',
@@ -1242,9 +816,9 @@ class SessionService {
1242
816
  this.workspaceBridge.markSessionRunning(workspaceId, sessionId);
1243
817
  }
1244
818
  try {
1245
- const result = await acpRuntimeManager.sendPrompt(sessionId, content);
819
+ const result = await this.runtimeManager.sendPrompt(sessionId, content);
1246
820
  this.finalizeOrphanedToolCalls(sessionId, `stop_reason:${result.stopReason}`);
1247
- sessionDomainService.setRuntimeSnapshot(sessionId, {
821
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1248
822
  phase: 'idle',
1249
823
  processState: 'alive',
1250
824
  activity: 'IDLE',
@@ -1254,7 +828,7 @@ class SessionService {
1254
828
  }
1255
829
  catch (error) {
1256
830
  this.finalizeOrphanedToolCalls(sessionId, 'prompt_error');
1257
- sessionDomainService.setRuntimeSnapshot(sessionId, {
831
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1258
832
  phase: 'error',
1259
833
  processState: 'alive',
1260
834
  activity: 'IDLE',
@@ -1293,10 +867,10 @@ class SessionService {
1293
867
  }
1294
868
  }
1295
869
  async cancelAcpPrompt(sessionId) {
1296
- await acpRuntimeManager.cancelPrompt(sessionId);
870
+ await this.runtimeManager.cancelPrompt(sessionId);
1297
871
  }
1298
872
  getSessionConversationHistory(sessionId, _workingDir) {
1299
- const transcript = sessionDomainService.getTranscriptSnapshot(sessionId);
873
+ const transcript = this.sessionDomainService.getTranscriptSnapshot(sessionId);
1300
874
  return transcript.flatMap((entry) => this.mapTranscriptEntryToHistory(entry));
1301
875
  }
1302
876
  mapTranscriptEntryToHistory(entry) {
@@ -1342,19 +916,15 @@ class SessionService {
1342
916
  .trim();
1343
917
  }
1344
918
  respondToAcpPermission(sessionId, requestId, optionId, answers) {
1345
- const bridge = this.acpPermissionBridges.get(sessionId);
1346
- if (!bridge) {
1347
- return false;
1348
- }
1349
- return bridge.resolvePermission(requestId, optionId, answers);
919
+ return this.sessionPermissionService.respondToPermission(sessionId, requestId, optionId, answers);
1350
920
  }
1351
921
  getRuntimeSnapshot(sessionId) {
1352
922
  const fallback = createInitialSessionRuntimeState();
1353
- const persisted = sessionDomainService.getRuntimeSnapshot(sessionId);
923
+ const persisted = this.sessionDomainService.getRuntimeSnapshot(sessionId);
1354
924
  const base = persisted ?? fallback;
1355
- const acpClient = acpRuntimeManager.getClient(sessionId);
925
+ const acpClient = this.runtimeManager.getClient(sessionId);
1356
926
  if (acpClient) {
1357
- const isWorking = acpRuntimeManager.isSessionWorking(sessionId);
927
+ const isWorking = this.runtimeManager.isSessionWorking(sessionId);
1358
928
  return {
1359
929
  phase: isWorking ? 'running' : 'idle',
1360
930
  processState: 'alive',
@@ -1362,7 +932,7 @@ class SessionService {
1362
932
  updatedAt: base.updatedAt,
1363
933
  };
1364
934
  }
1365
- if (acpRuntimeManager.isStopInProgress(sessionId)) {
935
+ if (this.runtimeManager.isStopInProgress(sessionId)) {
1366
936
  return {
1367
937
  ...base,
1368
938
  phase: 'stopping',
@@ -1381,9 +951,9 @@ class SessionService {
1381
951
  return base;
1382
952
  }
1383
953
  async getOrCreateAcpSessionClient(sessionId, options, session) {
1384
- const existingAcp = acpRuntimeManager.getClient(sessionId);
954
+ const existingAcp = this.runtimeManager.getClient(sessionId);
1385
955
  if (existingAcp) {
1386
- sessionDomainService.setRuntimeSnapshot(sessionId, {
956
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1387
957
  phase: existingAcp.isPromptInFlight ? 'running' : 'idle',
1388
958
  processState: 'alive',
1389
959
  activity: existingAcp.isPromptInFlight ? 'WORKING' : 'IDLE',
@@ -1391,7 +961,7 @@ class SessionService {
1391
961
  });
1392
962
  return existingAcp;
1393
963
  }
1394
- sessionDomainService.setRuntimeSnapshot(sessionId, {
964
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1395
965
  phase: 'starting',
1396
966
  processState: 'alive',
1397
967
  activity: 'IDLE',
@@ -1402,7 +972,7 @@ class SessionService {
1402
972
  handle = await this.createAcpClient(sessionId, options, session);
1403
973
  }
1404
974
  catch (error) {
1405
- sessionDomainService.setRuntimeSnapshot(sessionId, {
975
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1406
976
  phase: 'error',
1407
977
  processState: 'stopped',
1408
978
  activity: 'IDLE',
@@ -1414,7 +984,7 @@ class SessionService {
1414
984
  await this.repository.updateSession(sessionId, {
1415
985
  status: SessionStatus.RUNNING,
1416
986
  });
1417
- sessionDomainService.setRuntimeSnapshot(sessionId, {
987
+ this.sessionDomainService.setRuntimeSnapshot(sessionId, {
1418
988
  phase: handle.isPromptInFlight ? 'running' : 'idle',
1419
989
  processState: 'alive',
1420
990
  activity: handle.isPromptInFlight ? 'WORKING' : 'IDLE',
@@ -1423,13 +993,13 @@ class SessionService {
1423
993
  return handle;
1424
994
  }
1425
995
  isSessionRunning(sessionId) {
1426
- return acpRuntimeManager.isSessionRunning(sessionId);
996
+ return this.runtimeManager.isSessionRunning(sessionId);
1427
997
  }
1428
998
  isSessionWorking(sessionId) {
1429
- return acpRuntimeManager.isSessionWorking(sessionId);
999
+ return this.runtimeManager.isSessionWorking(sessionId);
1430
1000
  }
1431
1001
  isAnySessionWorking(sessionIds) {
1432
- return acpRuntimeManager.isAnySessionWorking(sessionIds);
1002
+ return this.runtimeManager.isAnySessionWorking(sessionIds);
1433
1003
  }
1434
1004
  async getSessionOptions(sessionId) {
1435
1005
  const sessionContext = await this.loadSessionContext(sessionId);
@@ -1443,121 +1013,15 @@ class SessionService {
1443
1013
  model: sessionContext.model,
1444
1014
  };
1445
1015
  }
1446
- async getChatBarCapabilities(sessionId) {
1447
- const acpHandle = acpRuntimeManager.getClient(sessionId);
1448
- if (acpHandle) {
1449
- return this.buildAcpChatBarCapabilities(acpHandle);
1450
- }
1451
- const session = await this.repository.getSessionById(sessionId);
1452
- if (!session) {
1453
- return EMPTY_CHAT_BAR_CAPABILITIES;
1454
- }
1455
- const cachedSnapshot = this.extractAcpConfigSnapshot(session.providerMetadata);
1456
- if (cachedSnapshot && cachedSnapshot.provider === session.provider) {
1457
- return this.buildCapabilitiesFromConfigOptions(session.provider, cachedSnapshot.configOptions, cachedSnapshot.observedModelId);
1458
- }
1459
- if (session.provider === 'CODEX') {
1460
- return {
1461
- ...EMPTY_CHAT_BAR_CAPABILITIES,
1462
- provider: 'CODEX',
1463
- };
1464
- }
1465
- return EMPTY_CHAT_BAR_CAPABILITIES;
1016
+ getChatBarCapabilities(sessionId) {
1017
+ return this.sessionConfigService.getChatBarCapabilities(sessionId);
1466
1018
  }
1467
1019
  buildAcpChatBarCapabilities(handle) {
1468
- return this.buildCapabilitiesFromConfigOptions(handle.provider, handle.configOptions);
1469
- }
1470
- buildCapabilitiesFromConfigOptions(provider, configOptions, fallbackModel) {
1471
- const modelOption = configOptions.find((o) => o.category === 'model');
1472
- const modeOption = configOptions.find((o) => o.category === 'mode');
1473
- const thoughtOption = configOptions.find((o) => o.category === 'thought_level' || o.id === 'reasoning_effort' || o.category === 'reasoning');
1474
- const selectedModel = modelOption?.currentValue
1475
- ? String(modelOption.currentValue)
1476
- : (fallbackModel ?? undefined);
1477
- const modelOptions = this.buildModelOptions(modelOption, selectedModel);
1478
- const isCodexProvider = provider === 'CODEX';
1479
- const reasoningOptions = isCodexProvider && thoughtOption
1480
- ? this.getSelectOptions(thoughtOption).map((option) => ({
1481
- value: option.value,
1482
- label: option.name ?? option.value,
1483
- ...(option.description ? { description: option.description } : {}),
1484
- }))
1485
- : [];
1486
- const reasoningValues = new Set(reasoningOptions.map((option) => option.value));
1487
- const selectedReasoning = isCodexProvider &&
1488
- thoughtOption?.currentValue &&
1489
- typeof thoughtOption.currentValue === 'string' &&
1490
- reasoningValues.has(thoughtOption.currentValue)
1491
- ? thoughtOption.currentValue
1492
- : undefined;
1493
- const modeDescriptors = modeOption
1494
- ? [
1495
- ...this.getConfigOptionValues(modeOption),
1496
- ...this.getSelectOptions(modeOption)
1497
- .map((entry) => entry.name ?? '')
1498
- .filter((value) => value.trim().length > 0),
1499
- ]
1500
- : [];
1501
- const planModeEnabled = modeDescriptors.some((entry) => /plan/i.test(entry));
1502
- return {
1503
- provider,
1504
- model: {
1505
- enabled: modelOptions.length > 0,
1506
- options: modelOptions,
1507
- ...(selectedModel ? { selected: selectedModel } : {}),
1508
- },
1509
- reasoning: {
1510
- enabled: reasoningOptions.length > 0,
1511
- options: reasoningOptions,
1512
- ...(selectedReasoning ? { selected: selectedReasoning } : {}),
1513
- },
1514
- thinking: {
1515
- enabled: !isCodexProvider && !!thoughtOption,
1516
- },
1517
- planMode: { enabled: planModeEnabled },
1518
- attachments: isCodexProvider
1519
- ? { enabled: false, kinds: [] }
1520
- : { enabled: true, kinds: ['image', 'text'] },
1521
- slashCommands: { enabled: false },
1522
- usageStats: { enabled: false, contextWindow: false },
1523
- rewind: { enabled: false },
1524
- };
1525
- }
1526
- buildModelOptions(modelOption, selectedModel) {
1527
- if (!modelOption) {
1528
- return selectedModel ? [{ value: selectedModel, label: selectedModel }] : [];
1529
- }
1530
- const byValue = new Map();
1531
- for (const option of this.getSelectOptions(modelOption)) {
1532
- if (!byValue.has(option.value)) {
1533
- byValue.set(option.value, option.name ?? option.value);
1534
- }
1535
- }
1536
- if (selectedModel && !byValue.has(selectedModel)) {
1537
- byValue.set(selectedModel, selectedModel);
1538
- }
1539
- return Array.from(byValue.entries()).map(([value, label]) => ({ value, label }));
1540
- }
1541
- getSelectOptions(option) {
1542
- return option.options.flatMap((entry) => {
1543
- if (typeof entry !== 'object' || entry === null) {
1544
- return [];
1545
- }
1546
- if ('value' in entry && typeof entry.value === 'string') {
1547
- return [entry];
1548
- }
1549
- if ('options' in entry && Array.isArray(entry.options)) {
1550
- return entry.options.filter((grouped) => typeof grouped === 'object' && grouped !== null && typeof grouped.value === 'string');
1551
- }
1552
- return [];
1553
- });
1554
- }
1555
- getConfigOptionValues(option) {
1556
- return this.getSelectOptions(option).map((entry) => entry.value);
1020
+ return this.sessionConfigService.buildAcpChatBarCapabilities(handle);
1557
1021
  }
1558
1022
  async stopAllClients(_timeoutMs = 5000) {
1559
1023
  try {
1560
- await acpRuntimeManager.stopAllClients();
1024
+ await this.runtimeManager.stopAllClients();
1561
1025
  }
1562
1026
  catch (error) {
1563
1027
  logger.error('Failed to stop ACP clients during shutdown', {
@@ -1567,105 +1031,7 @@ class SessionService {
1567
1031
  }
1568
1032
  }
1569
1033
  async persistAcpConfigSnapshot(sessionId, params) {
1570
- if (params.configOptions.length === 0) {
1571
- return;
1572
- }
1573
- const configOptionsForStorage = this.cloneConfigOptionsForStorage(params.configOptions);
1574
- const observedModelId = this.resolveObservedModel(configOptionsForStorage);
1575
- const metadataSource = params.existingMetadata ??
1576
- (await this.repository.getSessionById(sessionId))?.providerMetadata ??
1577
- null;
1578
- const snapshot = {
1579
- provider: params.provider,
1580
- providerSessionId: params.providerSessionId,
1581
- capturedAt: new Date().toISOString(),
1582
- configOptions: configOptionsForStorage,
1583
- ...(observedModelId ? { observedModelId } : {}),
1584
- };
1585
- const persistedUpdate = this.buildSnapshotPersistUpdate(metadataSource, snapshot, observedModelId);
1586
- try {
1587
- await this.repository.updateSession(sessionId, persistedUpdate);
1588
- }
1589
- catch (error) {
1590
- logger.warn('Failed persisting ACP config snapshot to session metadata; retrying once', {
1591
- sessionId,
1592
- error: error instanceof Error ? error.message : String(error),
1593
- });
1594
- await this.retryPersistAcpConfigSnapshot(sessionId, snapshot, observedModelId);
1595
- }
1596
- }
1597
- buildSnapshotPersistUpdate(metadataSource, snapshot, observedModelId) {
1598
- const nextMetadata = {
1599
- ...this.toMetadataRecord(metadataSource),
1600
- acpConfigSnapshot: snapshot,
1601
- };
1602
- if (observedModelId) {
1603
- nextMetadata.observedModelId = observedModelId;
1604
- }
1605
- return {
1606
- providerMetadata: nextMetadata,
1607
- ...(observedModelId ? { model: observedModelId } : {}),
1608
- };
1609
- }
1610
- async retryPersistAcpConfigSnapshot(sessionId, snapshot, observedModelId) {
1611
- try {
1612
- const latestMetadataSource = (await this.repository.getSessionById(sessionId))
1613
- ?.providerMetadata;
1614
- await this.repository.updateSession(sessionId, this.buildSnapshotPersistUpdate(latestMetadataSource, snapshot, observedModelId));
1615
- }
1616
- catch (retryError) {
1617
- logger.warn('Retry failed persisting ACP config snapshot to session metadata', {
1618
- sessionId,
1619
- error: retryError instanceof Error ? retryError.message : String(retryError),
1620
- });
1621
- }
1622
- }
1623
- cloneConfigOptionsForStorage(configOptions) {
1624
- try {
1625
- return structuredClone(configOptions);
1626
- }
1627
- catch {
1628
- return configOptions;
1629
- }
1630
- }
1631
- toMetadataRecord(metadata) {
1632
- if (typeof metadata !== 'object' || metadata === null || Array.isArray(metadata)) {
1633
- return {};
1634
- }
1635
- return { ...metadata };
1636
- }
1637
- extractAcpConfigSnapshot(metadata) {
1638
- const record = this.toMetadataRecord(metadata);
1639
- const snapshot = record.acpConfigSnapshot;
1640
- if (typeof snapshot !== 'object' || snapshot === null || Array.isArray(snapshot)) {
1641
- return null;
1642
- }
1643
- const candidate = snapshot;
1644
- const provider = candidate.provider;
1645
- const providerSessionId = candidate.providerSessionId;
1646
- const configOptions = candidate.configOptions;
1647
- const observedModelId = candidate.observedModelId;
1648
- if (provider !== 'CLAUDE' && provider !== 'CODEX') {
1649
- return null;
1650
- }
1651
- if (typeof providerSessionId !== 'string' || providerSessionId.length === 0) {
1652
- return null;
1653
- }
1654
- if (!Array.isArray(configOptions)) {
1655
- return null;
1656
- }
1657
- return {
1658
- provider,
1659
- providerSessionId,
1660
- capturedAt: typeof candidate.capturedAt === 'string' ? candidate.capturedAt : new Date(0).toISOString(),
1661
- configOptions: configOptions,
1662
- ...(typeof observedModelId === 'string' ? { observedModelId } : {}),
1663
- };
1664
- }
1665
- resolveObservedModel(configOptions) {
1666
- const modelOption = configOptions.find((option) => option.category === 'model');
1667
- const currentValue = modelOption?.currentValue;
1668
- return currentValue ? String(currentValue) : undefined;
1034
+ await this.sessionConfigService.persistAcpConfigSnapshot(sessionId, params);
1669
1035
  }
1670
1036
  async loadSessionContext(sessionId, preloadedSession) {
1671
1037
  const session = preloadedSession ?? (await this.repository.getSessionById(sessionId));
@@ -1728,5 +1094,8 @@ class SessionService {
1728
1094
  };
1729
1095
  }
1730
1096
  }
1731
- export const sessionService = new SessionService();
1097
+ export function createSessionService(options) {
1098
+ return new SessionService(options);
1099
+ }
1100
+ export const sessionService = createSessionService();
1732
1101
  //# sourceMappingURL=session.service.js.map