@straiffi/archon 1.8.14 → 1.8.16

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 (250) hide show
  1. package/dist/client/assets/ActivityView-p8gBUxYN.js +1 -0
  2. package/dist/client/assets/GitHubActionsDialog-BRxGcSyq.js +1 -0
  3. package/dist/client/assets/VerificationDialog-B6l5TYOS.js +4 -0
  4. package/dist/client/assets/{arc-C83vRtlz.js → arc-D2Nn9xIj.js} +1 -1
  5. package/dist/client/assets/architecture-7EHR7CIX-C-4Cp4ml.js +1 -0
  6. package/dist/client/assets/{architectureDiagram-3BPJPVTR-DFbki8mi.js → architectureDiagram-3BPJPVTR-DnuKO1RY.js} +1 -1
  7. package/dist/client/assets/{blockDiagram-GPEHLZMM-BZFehG8P.js → blockDiagram-GPEHLZMM-CnQ7FwEp.js} +1 -1
  8. package/dist/client/assets/{c4Diagram-AAUBKEIU-FVDXRu1t.js → c4Diagram-AAUBKEIU-BF1hFXwp.js} +1 -1
  9. package/dist/client/assets/channel-TJtf4cBJ.js +1 -0
  10. package/dist/client/assets/{chunk-2J33WTMH-4tuVZaT0.js → chunk-2J33WTMH-UvCFvkZO.js} +1 -1
  11. package/dist/client/assets/{chunk-3OPIFGDE-DSn14S35.js → chunk-3OPIFGDE-z1l5nBD0.js} +1 -1
  12. package/dist/client/assets/{chunk-4BX2VUAB-C5pU9ApX.js → chunk-4BX2VUAB-CtLS8D71.js} +1 -1
  13. package/dist/client/assets/{chunk-4EGX6M5U-CAjWPjND.js → chunk-4EGX6M5U-Btnm0QNe.js} +1 -1
  14. package/dist/client/assets/{chunk-55IACEB6-DhO4-AG4.js → chunk-55IACEB6-74CcJaub.js} +1 -1
  15. package/dist/client/assets/{chunk-5DO6E6H7-BDKA-zHS.js → chunk-5DO6E6H7-WLZ8L4ko.js} +1 -1
  16. package/dist/client/assets/{chunk-5ZQYHXKU-Cwx1KNjg.js → chunk-5ZQYHXKU-Bis0Pw2_.js} +1 -1
  17. package/dist/client/assets/{chunk-727SXJPM-Odza4hes.js → chunk-727SXJPM-B3gUO8rD.js} +1 -1
  18. package/dist/client/assets/{chunk-AQP2D5EJ-BmVoQT7M.js → chunk-AQP2D5EJ-hPBzrrh5.js} +1 -1
  19. package/dist/client/assets/{chunk-BR22UD5L-12D2GWh4.js → chunk-BR22UD5L-Cou5beGe.js} +1 -1
  20. package/dist/client/assets/{chunk-BSJP7CBP-DMi77e84.js → chunk-BSJP7CBP-DJ57XcV5.js} +1 -1
  21. package/dist/client/assets/{chunk-CSCIHK7Q-Bg7Ktx0B.js → chunk-CSCIHK7Q-BfOng_VY.js} +2 -2
  22. package/dist/client/assets/{chunk-FHYWG6QK-BhSajKiB.js → chunk-FHYWG6QK-Ba10e2kj.js} +1 -1
  23. package/dist/client/assets/{chunk-FMBD7UC4-Drmlc0wM.js → chunk-FMBD7UC4-CEo2wZMx.js} +1 -1
  24. package/dist/client/assets/{chunk-KSCS5N6A-2tnhar2x.js → chunk-KSCS5N6A-B2Jg7PW5.js} +1 -1
  25. package/dist/client/assets/{chunk-L5ZTLDWV-dAyg8qMJ.js → chunk-L5ZTLDWV-CUYujZxt.js} +1 -1
  26. package/dist/client/assets/{chunk-LZXEDZCA-0gElxrlR.js → chunk-LZXEDZCA-CH_eV8jH.js} +2 -2
  27. package/dist/client/assets/{chunk-MPE355IW-Cw8YmjTC.js → chunk-MPE355IW-MqEt-J8G.js} +1 -1
  28. package/dist/client/assets/{chunk-MZUSXYTE-jvxRCZ7x.js → chunk-MZUSXYTE-DdNi9lhx.js} +1 -1
  29. package/dist/client/assets/{chunk-N66VUXT2-00i4y0yD.js → chunk-N66VUXT2-CjemTW4E.js} +1 -1
  30. package/dist/client/assets/{chunk-ND2GUHAM-Bu-8Lz91.js → chunk-ND2GUHAM-BVF5evM9.js} +1 -1
  31. package/dist/client/assets/{chunk-NZK2D7GU-CInZFdzd.js → chunk-NZK2D7GU-WfG-2AOS.js} +1 -1
  32. package/dist/client/assets/{chunk-O5CBEL6O-rAzpvdNR.js → chunk-O5CBEL6O-CSF9ozqy.js} +1 -1
  33. package/dist/client/assets/{chunk-PUPMXCY4-DfWourL7.js → chunk-PUPMXCY4-ZvwTw0To.js} +1 -1
  34. package/dist/client/assets/chunk-QZHKN3VN-LI_RZca2.js +1 -0
  35. package/dist/client/assets/{chunk-UIBZB4QT-v-a5ZfN6.js → chunk-UIBZB4QT-BTY9be9s.js} +1 -1
  36. package/dist/client/assets/{chunk-WCWK7LTN-CtYzhvvb.js → chunk-WCWK7LTN-Db1n3n3-.js} +1 -1
  37. package/dist/client/assets/chunk-WU5MYG2G-DoVpb2oe.js +1 -0
  38. package/dist/client/assets/{chunk-XPW4576I-CvnAuXH2.js → chunk-XPW4576I-DObFPxjB.js} +1 -1
  39. package/dist/client/assets/classDiagram-4FO5ZUOK-CnKIRKWC.js +1 -0
  40. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-5ZgjUwTv.js +1 -0
  41. package/dist/client/assets/{cose-bilkent-S5V4N54A-fchD-dH2.js → cose-bilkent-S5V4N54A-MlOPiG6P.js} +1 -1
  42. package/dist/client/assets/{dagre-BM42HDAG-Dgua1iuh.js → dagre-BM42HDAG-rekDIYnC.js} +1 -1
  43. package/dist/client/assets/{dagre-DSrzm-Gq.js → dagre-BWNHuDdf.js} +1 -1
  44. package/dist/client/assets/{diagram-2AECGRRQ-odacwlwu.js → diagram-2AECGRRQ-Z4mXdhW0.js} +1 -1
  45. package/dist/client/assets/{diagram-5GNKFQAL-BiKjFmJ1.js → diagram-5GNKFQAL-DqeVe5Vc.js} +1 -1
  46. package/dist/client/assets/{diagram-KO2AKTUF-CmYcvFri.js → diagram-KO2AKTUF-ijppTuNc.js} +1 -1
  47. package/dist/client/assets/{diagram-LMA3HP47-ncx0RBuX.js → diagram-LMA3HP47-CDGLx0-N.js} +1 -1
  48. package/dist/client/assets/{diagram-OG6HWLK6-DbchKIzw.js → diagram-OG6HWLK6-DDlnjzF8.js} +1 -1
  49. package/dist/client/assets/{erDiagram-TEJ5UH35-CMnpvRyQ.js → erDiagram-TEJ5UH35-V_axe9oz.js} +1 -1
  50. package/dist/client/assets/eventmodeling-FCH6USID-Dqb6QKoI.js +1 -0
  51. package/dist/client/assets/{flowDiagram-I6XJVG4X-Bi02_PK5.js → flowDiagram-I6XJVG4X-GH5q79jg.js} +1 -1
  52. package/dist/client/assets/{ganttDiagram-6RSMTGT7-BiS992US.js → ganttDiagram-6RSMTGT7-BMWVdLeQ.js} +1 -1
  53. package/dist/client/assets/gitGraph-WXDBUCRP-DYEsqh93.js +1 -0
  54. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-Cc1hrTsT.js → gitGraphDiagram-PVQCEYII-VrV8jMUg.js} +1 -1
  55. package/dist/client/assets/index-B7J4DYDu.js +275 -0
  56. package/dist/client/assets/index-CsZfTdMO.css +2 -0
  57. package/dist/client/assets/info-J43DQDTF-CfjXFZai.js +1 -0
  58. package/dist/client/assets/{infoDiagram-5YYISTIA-BKVfqJCe.js → infoDiagram-5YYISTIA-EGiVbp17.js} +1 -1
  59. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-B-IbFOty.js → ishikawaDiagram-YF4QCWOH-Dw3CiXbm.js} +1 -1
  60. package/dist/client/assets/{journeyDiagram-JHISSGLW-DAZBgAQW.js → journeyDiagram-JHISSGLW-2S631RY5.js} +1 -1
  61. package/dist/client/assets/{kanban-definition-UN3LZRKU-Bkr_fXev.js → kanban-definition-UN3LZRKU-pc9vzUtB.js} +1 -1
  62. package/dist/client/assets/{line-CROuuXDO.js → line-BBMBmEjI.js} +1 -1
  63. package/dist/client/assets/{linear-BOwW57yX.js → linear-DT4rSZvy.js} +1 -1
  64. package/dist/client/assets/{mermaid-parser.core-DrBw_Rsc.js → mermaid-parser.core-ClNeolx0.js} +2 -2
  65. package/dist/client/assets/{mermaid.core-pPd6OYYj.js → mermaid.core-Q4IJbm5V.js} +3 -3
  66. package/dist/client/assets/{mindmap-definition-RKZ34NQL-BXSd3TZU.js → mindmap-definition-RKZ34NQL-DUTZxR8H.js} +1 -1
  67. package/dist/client/assets/{ordinal-CZ33lFpK.js → ordinal-k--hYEme.js} +1 -1
  68. package/dist/client/assets/packet-YPE3B663-Dv0HkRHU.js +1 -0
  69. package/dist/client/assets/pie-LRSECV5Y-S5zPzZFN.js +1 -0
  70. package/dist/client/assets/{pieDiagram-4H26LBE5-DoT7PIZC.js → pieDiagram-4H26LBE5-RW5hNtJq.js} +1 -1
  71. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-ycZkLowm.js → quadrantDiagram-W4KKPZXB-CK60c7X9.js} +1 -1
  72. package/dist/client/assets/radar-GUYGQ44K-B7psLv22.js +1 -0
  73. package/dist/client/assets/{requirementDiagram-4Y6WPE33-BPkO1yLu.js → requirementDiagram-4Y6WPE33-Dz35FvcC.js} +1 -1
  74. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-D7AvhhCw.js → sankeyDiagram-5OEKKPKP-ByyluoXu.js} +1 -1
  75. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-C982swnH.js → sequenceDiagram-3UESZ5HK-C-879UFe.js} +1 -1
  76. package/dist/client/assets/{stateDiagram-AJRCARHV-xvJ3u8lc.js → stateDiagram-AJRCARHV-B8neDlUu.js} +1 -1
  77. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-B4Mq8Abu.js +1 -0
  78. package/dist/client/assets/{timeline-definition-PNZ67QCA-D89qjzb5.js → timeline-definition-PNZ67QCA-iAwrltn1.js} +1 -1
  79. package/dist/client/assets/treeView-BLDUP644-B8H0kT67.js +1 -0
  80. package/dist/client/assets/treemap-LRROVOQU-DPLhFHnh.js +1 -0
  81. package/dist/client/assets/{vennDiagram-CIIHVFJN-CoKeC__u.js → vennDiagram-CIIHVFJN-DHN61m8d.js} +1 -1
  82. package/dist/client/assets/wardley-L42UT6IY-B5-Vb08V.js +1 -0
  83. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DKhjzvSE.js → wardleyDiagram-YWT4CUSO-XDVo7Jy1.js} +1 -1
  84. package/dist/client/assets/{xychartDiagram-2RQKCTM6-DFn9ass1.js → xychartDiagram-2RQKCTM6-Cb-HLpaN.js} +1 -1
  85. package/dist/client/index.html +2 -2
  86. package/dist/server/db.js +237 -0
  87. package/dist/server/db.js.map +1 -1
  88. package/dist/server/index.js +211 -87
  89. package/dist/server/index.js.map +1 -1
  90. package/dist/server/lib/agent.js +198 -100
  91. package/dist/server/lib/agent.js.map +1 -1
  92. package/dist/server/lib/agentProvider.js +14 -9
  93. package/dist/server/lib/agentProvider.js.map +1 -1
  94. package/dist/server/lib/agentRuns.js +20 -9
  95. package/dist/server/lib/agentRuns.js.map +1 -1
  96. package/dist/server/lib/buildExecutionEnvironment.js +517 -0
  97. package/dist/server/lib/buildExecutionEnvironment.js.map +1 -0
  98. package/dist/server/lib/buildOpenQuestionOperations.js +9 -3
  99. package/dist/server/lib/buildOpenQuestionOperations.js.map +1 -1
  100. package/dist/server/lib/chatOperations.js +30 -1
  101. package/dist/server/lib/chatOperations.js.map +1 -1
  102. package/dist/server/lib/checkAutoFix.js +1 -0
  103. package/dist/server/lib/checkAutoFix.js.map +1 -1
  104. package/dist/server/lib/checkRepairDispatch.js +3 -1
  105. package/dist/server/lib/checkRepairDispatch.js.map +1 -1
  106. package/dist/server/lib/dockerSandboxCredentials.js +62 -0
  107. package/dist/server/lib/dockerSandboxCredentials.js.map +1 -0
  108. package/dist/server/lib/dockerSandboxEnvironmentOperations.js +54 -0
  109. package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -0
  110. package/dist/server/lib/dockerSandboxExecutionEnvironment.js +631 -0
  111. package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -0
  112. package/dist/server/lib/dockerSandboxExecutionProvider.js +196 -0
  113. package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -0
  114. package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js +29 -0
  115. package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js.map +1 -0
  116. package/dist/server/lib/dockerSandboxRuntimeController.js +187 -0
  117. package/dist/server/lib/dockerSandboxRuntimeController.js.map +1 -0
  118. package/dist/server/lib/executionEnvironment.js +22 -0
  119. package/dist/server/lib/executionEnvironment.js.map +1 -1
  120. package/dist/server/lib/executionEnvironmentContexts.js +144 -0
  121. package/dist/server/lib/executionEnvironmentContexts.js.map +1 -0
  122. package/dist/server/lib/executionEnvironmentLifecycle.js +63 -0
  123. package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -0
  124. package/dist/server/lib/executionEnvironmentReconciliation.js +782 -0
  125. package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -0
  126. package/dist/server/lib/executionEnvironmentRoutes.js +354 -0
  127. package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -0
  128. package/dist/server/lib/executionEnvironmentValidation.js +486 -0
  129. package/dist/server/lib/executionEnvironmentValidation.js.map +1 -0
  130. package/dist/server/lib/executionEnvironmentValidationOperations.js +635 -0
  131. package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -0
  132. package/dist/server/lib/executionEnvironments.js +726 -0
  133. package/dist/server/lib/executionEnvironments.js.map +1 -0
  134. package/dist/server/lib/executionReconciliation.js +77 -0
  135. package/dist/server/lib/executionReconciliation.js.map +1 -1
  136. package/dist/server/lib/executionRetry.js +3 -0
  137. package/dist/server/lib/executionRetry.js.map +1 -1
  138. package/dist/server/lib/executionRuns.js +1 -0
  139. package/dist/server/lib/executionRuns.js.map +1 -1
  140. package/dist/server/lib/executionTargets.js +107 -0
  141. package/dist/server/lib/executionTargets.js.map +1 -0
  142. package/dist/server/lib/executionTimeline.js +3 -0
  143. package/dist/server/lib/executionTimeline.js.map +1 -1
  144. package/dist/server/lib/git.js +32 -1
  145. package/dist/server/lib/git.js.map +1 -1
  146. package/dist/server/lib/hostExecutionEnvironment.js +47 -1
  147. package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
  148. package/dist/server/lib/lightweightPrompt.js +1 -0
  149. package/dist/server/lib/lightweightPrompt.js.map +1 -1
  150. package/dist/server/lib/mobileAccess.js +2 -2
  151. package/dist/server/lib/mobileAccess.js.map +1 -1
  152. package/dist/server/lib/models.js +11 -0
  153. package/dist/server/lib/models.js.map +1 -1
  154. package/dist/server/lib/opencodeErrors.js +31 -3
  155. package/dist/server/lib/opencodeErrors.js.map +1 -1
  156. package/dist/server/lib/opencodeExecutionReliability.js +52 -0
  157. package/dist/server/lib/opencodeExecutionReliability.js.map +1 -0
  158. package/dist/server/lib/opencodeSessionOperations.js +210 -20
  159. package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
  160. package/dist/server/lib/opencodeTaskSessions.js +7 -12
  161. package/dist/server/lib/opencodeTaskSessions.js.map +1 -1
  162. package/dist/server/lib/postBuildChecks.js +2 -1
  163. package/dist/server/lib/postBuildChecks.js.map +1 -1
  164. package/dist/server/lib/projectAutoConfig.js +1 -0
  165. package/dist/server/lib/projectAutoConfig.js.map +1 -1
  166. package/dist/server/lib/projects.js +10 -0
  167. package/dist/server/lib/projects.js.map +1 -1
  168. package/dist/server/lib/specArtifact.js +20 -1
  169. package/dist/server/lib/specArtifact.js.map +1 -1
  170. package/dist/server/lib/specBundleGroups.js +151 -0
  171. package/dist/server/lib/specBundleGroups.js.map +1 -0
  172. package/dist/server/lib/specDraft.js +1 -5
  173. package/dist/server/lib/specDraft.js.map +1 -1
  174. package/dist/server/lib/specExport.js +2 -6
  175. package/dist/server/lib/specExport.js.map +1 -1
  176. package/dist/server/lib/specFormatting.js +13 -0
  177. package/dist/server/lib/specFormatting.js.map +1 -1
  178. package/dist/server/lib/specGraphFeature.js +3 -0
  179. package/dist/server/lib/specGraphFeature.js.map +1 -0
  180. package/dist/server/lib/specRepositoryEvidenceFormatting.js +2 -1
  181. package/dist/server/lib/specRepositoryEvidenceFormatting.js.map +1 -1
  182. package/dist/server/lib/specRepositoryImpact.js +4 -0
  183. package/dist/server/lib/specRepositoryImpact.js.map +1 -1
  184. package/dist/server/lib/specReviewContext.js +6 -20
  185. package/dist/server/lib/specReviewContext.js.map +1 -1
  186. package/dist/server/lib/specReviewValidation.js +22 -1
  187. package/dist/server/lib/specReviewValidation.js.map +1 -1
  188. package/dist/server/lib/specReviews.js +1 -1
  189. package/dist/server/lib/specSections.js +8 -1
  190. package/dist/server/lib/specSections.js.map +1 -1
  191. package/dist/server/lib/specSnapshotEvidence.js +4 -0
  192. package/dist/server/lib/specSnapshotEvidence.js.map +1 -1
  193. package/dist/server/lib/specTicketMaterialization.js +122 -0
  194. package/dist/server/lib/specTicketMaterialization.js.map +1 -0
  195. package/dist/server/lib/specs.js +27 -5
  196. package/dist/server/lib/specs.js.map +1 -1
  197. package/dist/server/lib/ticketFollowUpOperations.js +8 -1
  198. package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
  199. package/dist/server/lib/ticketRunOperations.js +0 -3
  200. package/dist/server/lib/ticketRunOperations.js.map +1 -1
  201. package/dist/server/lib/types.js +1 -0
  202. package/dist/server/lib/types.js.map +1 -1
  203. package/dist/server/lib/workspaceIdentity.js +3 -0
  204. package/dist/server/lib/workspaceIdentity.js.map +1 -1
  205. package/dist/server/workers/build.js +114 -8
  206. package/dist/server/workers/build.js.map +1 -1
  207. package/dist/server/workers/followUp.js +143 -7
  208. package/dist/server/workers/followUp.js.map +1 -1
  209. package/dist/server/workers/plan.js +57 -24
  210. package/dist/server/workers/plan.js.map +1 -1
  211. package/dist/server/workers/review.js +43 -23
  212. package/dist/server/workers/review.js.map +1 -1
  213. package/dist/server/workers/specReview.js +7 -2
  214. package/dist/server/workers/specReview.js.map +1 -1
  215. package/dist/server/workers/specSession.js +109 -153
  216. package/dist/server/workers/specSession.js.map +1 -1
  217. package/package.json +1 -1
  218. package/dist/client/assets/ActivityView-DYDYyqIN.js +0 -1
  219. package/dist/client/assets/GitHubActionsDialog-jhi4GOyV.js +0 -1
  220. package/dist/client/assets/RepositoryGraphDialog-BZV0vHu6.js +0 -1
  221. package/dist/client/assets/VerificationDialog-Sc6e8AKH.js +0 -4
  222. package/dist/client/assets/architecture-7EHR7CIX-Dm8H7N6Z.js +0 -1
  223. package/dist/client/assets/channel-D1kOpezG.js +0 -1
  224. package/dist/client/assets/chunk-QZHKN3VN-CtbsU1Bj.js +0 -1
  225. package/dist/client/assets/chunk-WU5MYG2G-DOOw2vq7.js +0 -1
  226. package/dist/client/assets/classDiagram-4FO5ZUOK-C253nwny.js +0 -1
  227. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DFgDA23g.js +0 -1
  228. package/dist/client/assets/eventmodeling-FCH6USID-BWhw0UJ8.js +0 -1
  229. package/dist/client/assets/gitGraph-WXDBUCRP-BSnxAa1J.js +0 -1
  230. package/dist/client/assets/index-B1gdJKwK.js +0 -275
  231. package/dist/client/assets/index-CCQwWUKF.css +0 -2
  232. package/dist/client/assets/info-J43DQDTF-DcFwF1-h.js +0 -1
  233. package/dist/client/assets/packet-YPE3B663-1VZiO_9r.js +0 -1
  234. package/dist/client/assets/pie-LRSECV5Y-BX1-tQCu.js +0 -1
  235. package/dist/client/assets/radar-GUYGQ44K-B2HRrCR4.js +0 -1
  236. package/dist/client/assets/stateDiagram-v2-BHNVJYJU-BKQG8NCn.js +0 -1
  237. package/dist/client/assets/treeView-BLDUP644-CDfUVbUi.js +0 -1
  238. package/dist/client/assets/treemap-LRROVOQU-DUWqu8sK.js +0 -1
  239. package/dist/client/assets/wardley-L42UT6IY-BEFuPUCy.js +0 -1
  240. /package/dist/client/assets/{array-B2f2amhX.js → array-BNor45A1.js} +0 -0
  241. /package/dist/client/assets/{chunk-NNHCCRGN-DgKrp8T-.js → chunk-NNHCCRGN-CZB-V-Gv.js} +0 -0
  242. /package/dist/client/assets/{cytoscape.esm-BInZCgaJ.js → cytoscape.esm-B2lJcMSI.js} +0 -0
  243. /package/dist/client/assets/{defaultLocale-sPXJ5urm.js → defaultLocale-DPzUsThw.js} +0 -0
  244. /package/dist/client/assets/{dist-DfHDMDTt.js → dist-CERhmQhR.js} +0 -0
  245. /package/dist/client/assets/{graphlib-DacNv4Jd.js → graphlib-BHOW-eWz.js} +0 -0
  246. /package/dist/client/assets/{init-BVCnG1lj.js → init-C0L3woqb.js} +0 -0
  247. /package/dist/client/assets/{katex-BlkrXOwm.js → katex-CpjQsUQe.js} +0 -0
  248. /package/dist/client/assets/{path-Bw5AvBNC.js → path-sMK4d_s9.js} +0 -0
  249. /package/dist/client/assets/{rough.esm-DeLgKbOI.js → rough.esm-BoTisKeL.js} +0 -0
  250. /package/dist/client/assets/{src-CFGsdLiG.js → src-BRjoYtUW.js} +0 -0
@@ -8,13 +8,14 @@ import { normalizeClaudeModelId, normalizeModelId } from './models.js';
8
8
  import { createOpencodeTaskSessionReader, parseOpencodeTaskEnvelope } from './opencodeTaskSessions.js';
9
9
  import { hostOpencodeSessionOperations } from './opencodeSessionOperations.js';
10
10
  import { hostExecutionEnvironment } from './hostExecutionEnvironment.js';
11
+ import { markRetryableOpenCodeDatabaseLock, RetryableOpenCodeDatabaseLockError, retryOpenCodeDatabaseLocks } from './opencodeExecutionReliability.js';
11
12
  import { claudeAgentProvider } from './claudeAgentProvider.js';
12
13
  import { buildOpencodeSpecReviewInvocation, createOpencodeExitError, createOpencodeRecoveryTracker, interpretOpencodeRecoveryEvent, isSuccessfulOpencodeExit, opencodeAgentProvider, } from './opencodeAgentProvider.js';
13
14
  import { appendClaudeHeadlessPlanPrompt, buildClaudeHeadlessPlanArgs } from './planModeQuestions.js';
14
15
  import { formatGenericToolCall } from './genericToolCall.js';
15
16
  import { getSpecSession, updateSpecSessionResumeId, updateSpecSessionStatus, updateSpecSessionTitle, updateSpecSessionUsageSnapshot } from './specs.js';
16
17
  import { updateSpecReviewRunStatus, updateSpecReviewRunStreaming, updateSpecReviewRunUsage } from './specReviews.js';
17
- import { createAgentRun, emitAgentRunsUpdated, finalizeAgentRun, getNextAgentRunIndex, listAgentRunsForExecutionRun, listAgentRunsForParent, updateAgentRunLabel, updateAgentRunSessionId, updateAgentRunStatus } from './agentRuns.js';
18
+ import { createAgentRun, emitAgentRunsUpdated, emitExecutionAgentRunsUpdated, finalizeAgentRun, getNextAgentRunIndex, listAgentRunsForExecutionRun, listAgentRunsForParent, updateAgentRunLabel, updateAgentRunSessionId, updateAgentRunStatus } from './agentRuns.js';
18
19
  import { markTicketDescriptionVisibleInBundle } from './ticketMessages.js';
19
20
  import { getTicket } from './tickets.js';
20
21
  import { createTranscriptRunSnapshots } from './transcriptRuns.js';
@@ -49,6 +50,7 @@ export const getAgentErrorTranscriptRuns = (error) => {
49
50
  };
50
51
  const OPENCODE_SESSION_METADATA_LOOKUP_DELAY_MS = 1500;
51
52
  const AGENT_PROGRESS_UPDATE_INTERVAL_MS = 100;
53
+ const OPENCODE_SUBAGENT_POLL_INTERVAL_MS = 750;
52
54
  const resolveAgentModel = (tool, model) => {
53
55
  if (tool === 'claude') {
54
56
  return normalizeClaudeModelId(model) || null;
@@ -445,29 +447,29 @@ const createThrottledProgressUpdater = (flushUpdate) => {
445
447
  },
446
448
  };
447
449
  };
448
- export const readOpencodeUsageSnapshot = ({ sessionId, spawnTimestamp = null, }) => {
449
- const snapshot = hostOpencodeSessionOperations.readUsageSnapshot(sessionId, spawnTimestamp);
450
+ export const readOpencodeUsageSnapshot = async ({ sessionId, spawnTimestamp = null, sessionOperations = hostOpencodeSessionOperations, }) => {
451
+ const snapshot = await sessionOperations.readUsageSnapshot(sessionId, spawnTimestamp);
450
452
  if (!snapshot) {
451
453
  throw new Error('OpenCode usage snapshot read failed');
452
454
  }
453
455
  return snapshot;
454
456
  };
455
- const resolveOpencodeUsageSnapshot = ({ current, sessionId, spawnTimestamp = null, }) => {
457
+ const resolveOpencodeUsageSnapshot = async ({ current, sessionId, spawnTimestamp = null, }) => {
456
458
  try {
457
- return mergeChatUsageSnapshot(current, readOpencodeUsageSnapshot({ sessionId, spawnTimestamp }));
459
+ return mergeChatUsageSnapshot(current, await readOpencodeUsageSnapshot({ sessionId, spawnTimestamp }));
458
460
  }
459
461
  catch {
460
462
  return current;
461
463
  }
462
464
  };
463
- export const refreshChatSessionUsageSnapshot = (chatSessionId, options = {}) => {
465
+ export const refreshChatSessionUsageSnapshot = async (chatSessionId, options = {}) => {
464
466
  const chatSession = getChatSession(chatSessionId, { includeMessages: options.includeMessages });
465
467
  if (!chatSession || chatSession.tool !== 'opencode' || !chatSession.opencode_session_id) {
466
468
  return chatSession;
467
469
  }
468
470
  let nextUsageSnapshot;
469
471
  try {
470
- nextUsageSnapshot = readOpencodeUsageSnapshot({
472
+ nextUsageSnapshot = await readOpencodeUsageSnapshot({
471
473
  sessionId: chatSession.opencode_session_id,
472
474
  });
473
475
  }
@@ -480,14 +482,14 @@ export const refreshChatSessionUsageSnapshot = (chatSessionId, options = {}) =>
480
482
  updateChatSessionUsageSnapshot(chatSessionId, nextUsageSnapshot);
481
483
  return getChatSession(chatSessionId, { includeMessages: options.includeMessages });
482
484
  };
483
- export const refreshSpecSessionUsageSnapshot = (specSessionId, options = {}) => {
485
+ export const refreshSpecSessionUsageSnapshot = async (specSessionId, options = {}) => {
484
486
  const specSession = getSpecSession(specSessionId, { includeMessages: options.includeMessages });
485
487
  if (!specSession || specSession.tool !== 'opencode' || !specSession.opencode_session_id) {
486
488
  return specSession;
487
489
  }
488
490
  let nextUsageSnapshot;
489
491
  try {
490
- nextUsageSnapshot = readOpencodeUsageSnapshot({
492
+ nextUsageSnapshot = await readOpencodeUsageSnapshot({
491
493
  sessionId: specSession.opencode_session_id,
492
494
  });
493
495
  }
@@ -500,9 +502,9 @@ export const refreshSpecSessionUsageSnapshot = (specSessionId, options = {}) =>
500
502
  updateSpecSessionUsageSnapshot(specSessionId, nextUsageSnapshot);
501
503
  return getSpecSession(specSessionId, { includeMessages: options.includeMessages });
502
504
  };
503
- export const storeTicketUsageSnapshot = (ticketId, opencodeSessionId) => {
505
+ export const storeTicketUsageSnapshot = async (ticketId, opencodeSessionId, sessionOperations = hostOpencodeSessionOperations) => {
504
506
  try {
505
- const snapshot = readOpencodeUsageSnapshot({ sessionId: opencodeSessionId });
507
+ const snapshot = await readOpencodeUsageSnapshot({ sessionId: opencodeSessionId, sessionOperations });
506
508
  if (snapshot.usage_snapshot_total_tokens === null) {
507
509
  return;
508
510
  }
@@ -543,7 +545,7 @@ const createOpencodeMetadataRefresher = ({ chatSessionId, io, spawnTimestamp, in
543
545
  clearTimeout(lookupTimer);
544
546
  lookupTimer = null;
545
547
  };
546
- const readCurrentSession = () => {
548
+ const readCurrentSession = async () => {
547
549
  if (knownSessionId) {
548
550
  return hostOpencodeSessionOperations.findSessionById(knownSessionId);
549
551
  }
@@ -552,12 +554,12 @@ const createOpencodeMetadataRefresher = ({ chatSessionId, io, spawnTimestamp, in
552
554
  }
553
555
  return hostOpencodeSessionOperations.findLatestSessionAfter(spawnTimestamp);
554
556
  };
555
- const refresh = () => {
557
+ const refresh = async () => {
556
558
  if (stopped) {
557
559
  return { hasSession: false, hasResolvedTitle: false, sessionId: knownSessionId };
558
560
  }
559
561
  try {
560
- const session = readCurrentSession();
562
+ const session = await readCurrentSession();
561
563
  if (!session) {
562
564
  return { hasSession: false, hasResolvedTitle: false, sessionId: knownSessionId };
563
565
  }
@@ -583,10 +585,11 @@ const createOpencodeMetadataRefresher = ({ chatSessionId, io, spawnTimestamp, in
583
585
  }
584
586
  clearLookupTimer();
585
587
  lookupTimer = setTimeout(() => {
586
- const result = refresh();
587
- if (!result.hasResolvedTitle) {
588
- scheduleRetry();
589
- }
588
+ void refresh().then(result => {
589
+ if (!result.hasResolvedTitle) {
590
+ scheduleRetry();
591
+ }
592
+ });
590
593
  }, OPENCODE_SESSION_METADATA_LOOKUP_DELAY_MS);
591
594
  };
592
595
  return {
@@ -611,7 +614,7 @@ const createSpecOpencodeMetadataRefresher = ({ specSessionId, io, spawnTimestamp
611
614
  clearTimeout(lookupTimer);
612
615
  lookupTimer = null;
613
616
  };
614
- const readCurrentSession = () => {
617
+ const readCurrentSession = async () => {
615
618
  if (knownSessionId) {
616
619
  return hostOpencodeSessionOperations.findSessionById(knownSessionId);
617
620
  }
@@ -620,12 +623,12 @@ const createSpecOpencodeMetadataRefresher = ({ specSessionId, io, spawnTimestamp
620
623
  }
621
624
  return hostOpencodeSessionOperations.findLatestSessionAfter(spawnTimestamp);
622
625
  };
623
- const refresh = () => {
626
+ const refresh = async () => {
624
627
  if (stopped) {
625
628
  return { hasSession: false, hasResolvedTitle: false, sessionId: knownSessionId };
626
629
  }
627
630
  try {
628
- const session = readCurrentSession();
631
+ const session = await readCurrentSession();
629
632
  if (!session) {
630
633
  return { hasSession: false, hasResolvedTitle: false, sessionId: knownSessionId };
631
634
  }
@@ -651,10 +654,11 @@ const createSpecOpencodeMetadataRefresher = ({ specSessionId, io, spawnTimestamp
651
654
  }
652
655
  clearLookupTimer();
653
656
  lookupTimer = setTimeout(() => {
654
- const result = refresh();
655
- if (!result.hasResolvedTitle) {
656
- scheduleRetry();
657
- }
657
+ void refresh().then(result => {
658
+ if (!result.hasResolvedTitle) {
659
+ scheduleRetry();
660
+ }
661
+ });
658
662
  }, OPENCODE_SESSION_METADATA_LOOKUP_DELAY_MS);
659
663
  };
660
664
  return {
@@ -1192,6 +1196,10 @@ export const createSubagentRunTracker = ({ parentType, parentId, io, mainRun, ex
1192
1196
  const trackedRuns = [];
1193
1197
  let nextRunIndex = Math.max(executionContext ? getNextAgentRunIndex(executionContext.runId) : getNextAgentRunIndex(parentType, parentId), mainRun ? mainRun.runIndex + 1 : 1);
1194
1198
  const emitUpdate = () => {
1199
+ if (executionContext) {
1200
+ emitExecutionAgentRunsUpdated(io, parentType, parentId, executionContext.runId);
1201
+ return;
1202
+ }
1195
1203
  emitAgentRunsUpdated(io, parentType, parentId);
1196
1204
  };
1197
1205
  const updateMain = (log, response) => {
@@ -1471,13 +1479,13 @@ export const reconstructOpencodeSubagentTranscript = (parts, cwd) => {
1471
1479
  }
1472
1480
  return { log: log || null, response: response || null };
1473
1481
  };
1474
- export const readOpencodeSessionTranscript = ({ sessionId, since, cwd, }) => {
1482
+ export const readOpencodeSessionTranscript = async ({ sessionId, since, cwd, }) => {
1475
1483
  const reader = createOpencodeTaskSessionReader();
1476
1484
  if (!reader) {
1477
1485
  return null;
1478
1486
  }
1479
1487
  try {
1480
- return reconstructOpencodeSubagentTranscript(reader.listSessionParts(sessionId, since), cwd);
1488
+ return reconstructOpencodeSubagentTranscript(await reader.listSessionParts(sessionId, since), cwd);
1481
1489
  }
1482
1490
  catch {
1483
1491
  return null;
@@ -1486,7 +1494,7 @@ export const readOpencodeSessionTranscript = ({ sessionId, since, cwd, }) => {
1486
1494
  reader.close();
1487
1495
  }
1488
1496
  };
1489
- export const createOpencodeSubagentMonitor = ({ initialParentSessionId, spawnTimestamp, cwd, tracker, onParentSessionId, taskSessionReader, discoverParentSession = true, }) => {
1497
+ export const createOpencodeSubagentMonitor = ({ initialParentSessionId, spawnTimestamp, cwd, tracker, onParentSessionId, taskSessionReader, discoverParentSession = true, parentDiscoveryDelayMs = 0, }) => {
1490
1498
  const reader = taskSessionReader === undefined ? createOpencodeTaskSessionReader() : taskSessionReader;
1491
1499
  let parentSessionId = initialParentSessionId;
1492
1500
  let timer = null;
@@ -1524,24 +1532,27 @@ export const createOpencodeSubagentMonitor = ({ initialParentSessionId, spawnTim
1524
1532
  childSessionByCallId.set(stillUnmatchedInvocations[0].callId, stillUnmatchedChildren[0].id);
1525
1533
  }
1526
1534
  };
1527
- const refresh = () => {
1535
+ let refreshInFlight = null;
1536
+ const performRefresh = async () => {
1528
1537
  if (!reader) {
1529
1538
  return;
1530
1539
  }
1531
1540
  try {
1532
- if (!parentSessionId && discoverParentSession) {
1533
- setParentSessionId(reader.findParentSessionSince(spawnTimestamp));
1541
+ if (!parentSessionId && discoverParentSession && Date.now() >= spawnTimestamp + parentDiscoveryDelayMs) {
1542
+ setParentSessionId(await reader.findParentSessionSince(spawnTimestamp));
1534
1543
  }
1535
1544
  if (!parentSessionId) {
1536
1545
  return;
1537
1546
  }
1538
- const invocations = reader.listTaskInvocations(parentSessionId, spawnTimestamp);
1539
- const children = reader.listChildSessions(parentSessionId, spawnTimestamp);
1547
+ const [invocations, children] = await Promise.all([
1548
+ reader.listTaskInvocations(parentSessionId, spawnTimestamp),
1549
+ reader.listChildSessions(parentSessionId, spawnTimestamp),
1550
+ ]);
1540
1551
  resolveChildSessions(invocations, children);
1541
1552
  for (const invocation of invocations) {
1542
1553
  const childSessionId = childSessionByCallId.get(invocation.callId) ?? invocation.childSessionId;
1543
1554
  const transcript = childSessionId
1544
- ? reconstructOpencodeSubagentTranscript(reader.listSessionParts(childSessionId), cwd)
1555
+ ? reconstructOpencodeSubagentTranscript(await reader.listSessionParts(childSessionId), cwd)
1545
1556
  : { log: null, response: null };
1546
1557
  tracker.applySnapshot({
1547
1558
  callId: invocation.callId,
@@ -1557,12 +1568,20 @@ export const createOpencodeSubagentMonitor = ({ initialParentSessionId, spawnTim
1557
1568
  // OpenCode persistence is a progressive enhancement; stdout remains the fallback.
1558
1569
  }
1559
1570
  };
1571
+ const refresh = () => {
1572
+ if (!refreshInFlight) {
1573
+ refreshInFlight = performRefresh().finally(() => {
1574
+ refreshInFlight = null;
1575
+ });
1576
+ }
1577
+ return refreshInFlight;
1578
+ };
1560
1579
  const start = () => {
1561
1580
  if (!reader || timer) {
1562
1581
  return;
1563
1582
  }
1564
- refresh();
1565
- timer = setInterval(refresh, 150);
1583
+ void refresh();
1584
+ timer = setInterval(() => void refresh(), OPENCODE_SUBAGENT_POLL_INTERVAL_MS);
1566
1585
  timer.unref?.();
1567
1586
  };
1568
1587
  const stop = () => {
@@ -1619,7 +1638,9 @@ const interruptProcess = (state, signal) => {
1619
1638
  return;
1620
1639
  }
1621
1640
  if (state.interrupt) {
1622
- state.interrupt(signal);
1641
+ void Promise.resolve(state.interrupt(signal)).catch(() => {
1642
+ // Durable sandbox execution records typed interruption failures through its lifecycle owner.
1643
+ });
1623
1644
  return;
1624
1645
  }
1625
1646
  killProcess(state.child, signal);
@@ -1666,7 +1687,13 @@ export const registerChatProcessPlaceholder = (chatSessionId) => {
1666
1687
  return state;
1667
1688
  };
1668
1689
  export const registerBuildProcessPlaceholder = (ticketId) => {
1669
- const state = { child: null, interrupt: null, stopRequested: false, sessionLookupTimer: null };
1690
+ const state = {
1691
+ child: null,
1692
+ interrupt: null,
1693
+ abortController: new AbortController(),
1694
+ stopRequested: false,
1695
+ sessionLookupTimer: null,
1696
+ };
1670
1697
  activeBuildProcesses.set(ticketId, state);
1671
1698
  return state;
1672
1699
  };
@@ -1764,11 +1791,12 @@ export const stopBuildAgent = async (ticketId) => {
1764
1791
  return false;
1765
1792
  }
1766
1793
  state.stopRequested = true;
1794
+ state.abortController.abort(new Error('Build stop requested'));
1767
1795
  if (!state.child) {
1768
1796
  return true;
1769
1797
  }
1770
1798
  if (state.interrupt) {
1771
- state.interrupt('SIGTERM');
1799
+ await state.interrupt('SIGTERM');
1772
1800
  }
1773
1801
  else {
1774
1802
  killProcess(state.child, 'SIGTERM');
@@ -1776,7 +1804,7 @@ export const stopBuildAgent = async (ticketId) => {
1776
1804
  await waitForProcessExit(state.child, 5000);
1777
1805
  if (isProcessAlive(state.child)) {
1778
1806
  if (state.interrupt) {
1779
- state.interrupt('SIGKILL');
1807
+ await state.interrupt('SIGKILL');
1780
1808
  }
1781
1809
  else {
1782
1810
  killProcess(state.child, 'SIGKILL');
@@ -1864,8 +1892,9 @@ export const stopSpecReviewAgent = async (specReviewRunId) => {
1864
1892
  }
1865
1893
  return true;
1866
1894
  };
1867
- export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = null, resumeSessionId = null, sessionField = 'session_id', trackBuildProcess = false, reviewProcessState, emitSuccessUpdate = true, opencodeAgentMode, runStream, executionContext, persistSessionIdToTicket = false, spawnPermitId, executionProvider = hostExecutionEnvironment, }) => {
1895
+ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null, resumeSessionId = null, sessionField = 'session_id', trackBuildProcess = false, reviewProcessState, emitSuccessUpdate = true, opencodeAgentMode, runStream, executionContext, persistSessionIdToTicket = false, spawnPermitId, executionProvider = hostExecutionEnvironment, executionTarget, }) => {
1868
1896
  const resolvedModel = resolveAgentModel(tool, model);
1897
+ const opencodeSessionOperations = executionProvider.sessionOperations?.opencode ?? null;
1869
1898
  const subagentTracker = createSubagentRunTracker({
1870
1899
  parentType: 'ticket',
1871
1900
  parentId: ticketId,
@@ -1882,10 +1911,18 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
1882
1911
  : {}),
1883
1912
  executionContext,
1884
1913
  });
1914
+ const emitRunUpdate = () => {
1915
+ const emitter = io;
1916
+ if (executionContext) {
1917
+ emitExecutionAgentRunsUpdated(emitter, 'ticket', ticketId, executionContext.runId);
1918
+ return;
1919
+ }
1920
+ emitAgentRunsUpdated(emitter, 'ticket', ticketId);
1921
+ };
1885
1922
  const writeRunStatus = (status, log, streamingResponse = null, options = {}) => {
1886
1923
  if (runStream) {
1887
1924
  updateAgentRunStatus(runStream.runId, status, log, streamingResponse);
1888
- emitAgentRunsUpdated(io, 'ticket', ticketId);
1925
+ emitRunUpdate();
1889
1926
  return;
1890
1927
  }
1891
1928
  updateStatus(ticketId, status, log, io, streamingResponse, options);
@@ -1893,7 +1930,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
1893
1930
  const writeRunSessionId = (sessionId) => {
1894
1931
  if (runStream) {
1895
1932
  updateAgentRunSessionId(runStream.runId, sessionId);
1896
- emitAgentRunsUpdated(io, 'ticket', ticketId);
1933
+ emitRunUpdate();
1897
1934
  if (persistSessionIdToTicket) {
1898
1935
  updateSessionId(ticketId, sessionId, sessionField, io);
1899
1936
  }
@@ -1904,7 +1941,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
1904
1941
  const finalizeRun = (status, log, responseText, options = {}) => {
1905
1942
  if (runStream) {
1906
1943
  finalizeAgentRun(runStream.runId, status, responseText);
1907
- emitAgentRunsUpdated(io, 'ticket', ticketId);
1944
+ emitRunUpdate();
1908
1945
  return subagentTracker.finalize(status, log, responseText);
1909
1946
  }
1910
1947
  updateStatus(ticketId, status, log, io, responseText, options);
@@ -1957,13 +1994,13 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
1957
1994
  writeRunSessionId(normalized);
1958
1995
  }
1959
1996
  };
1960
- const attemptOpencodeSessionLookup = () => {
1997
+ const attemptOpencodeSessionLookup = async () => {
1961
1998
  if (tool !== 'opencode' || hasResolvedOpencodeSessionId || spawnTimestamp === null) {
1962
1999
  return hasResolvedOpencodeSessionId;
1963
2000
  }
1964
2001
  try {
1965
- const session = hostOpencodeSessionOperations.findLatestSessionAfter(spawnTimestamp);
1966
- if (session?.id) {
2002
+ const session = await opencodeSessionOperations?.findLatestSessionAfter(spawnTimestamp, cwd);
2003
+ if (!hasResolvedOpencodeSessionId && session?.id) {
1967
2004
  bindResolvedOpencodeSession(session.id);
1968
2005
  }
1969
2006
  }
@@ -1995,6 +2032,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
1995
2032
  let child;
1996
2033
  let interrupt;
1997
2034
  let placementFailure;
2035
+ let placementCompletion = Promise.resolve(null);
1998
2036
  try {
1999
2037
  if (buildState?.stopRequested) {
2000
2038
  throw new AgentSpawnPermitRevokedError();
@@ -2003,12 +2041,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2003
2041
  assertAgentSpawnPermit(spawnPermitId, executionContext.runId);
2004
2042
  }
2005
2043
  const handle = executionProvider.execute({
2006
- target: {
2007
- kind: 'worktree',
2008
- id: ticketId,
2009
- workspacePath: cwd,
2010
- revision: 'working-tree',
2011
- },
2044
+ target: executionTarget ?? null,
2012
2045
  command: invocation.command,
2013
2046
  args: invocation.args,
2014
2047
  cwd,
@@ -2019,6 +2052,9 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2019
2052
  child = handle.child;
2020
2053
  interrupt = handle.interrupt;
2021
2054
  placementFailure = handle.placementFailure;
2055
+ if (handle.placementIdentity) {
2056
+ placementCompletion = placementFailure;
2057
+ }
2022
2058
  }
2023
2059
  catch (error) {
2024
2060
  const resolvedError = agentProvider.classifyExecutionFailure(error);
@@ -2051,11 +2087,15 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2051
2087
  });
2052
2088
  startTime = Date.now();
2053
2089
  if (tool === 'opencode' && spawnTimestamp !== null) {
2090
+ const taskSessionReader = opencodeSessionOperations
2091
+ ? createOpencodeTaskSessionReader(opencodeSessionOperations)
2092
+ : null;
2054
2093
  opencodeSubagentMonitor = createOpencodeSubagentMonitor({
2055
2094
  initialParentSessionId: resumeSessionId,
2056
2095
  spawnTimestamp,
2057
2096
  cwd,
2058
2097
  tracker: subagentTracker,
2098
+ taskSessionReader,
2059
2099
  discoverParentSession: false,
2060
2100
  onParentSessionId: discoveredSessionId => {
2061
2101
  bindResolvedOpencodeSession(discoveredSessionId);
@@ -2097,8 +2137,12 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2097
2137
  }
2098
2138
  });
2099
2139
  child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
2100
- child.on('close', code => {
2140
+ child.on('close', async (code) => {
2101
2141
  progressUpdater.cancel();
2142
+ const finalPlacementFailure = await placementCompletion;
2143
+ if (finalPlacementFailure || settled) {
2144
+ return;
2145
+ }
2102
2146
  if (remainder.trim()) {
2103
2147
  usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, remainder);
2104
2148
  const parsed = parseClaudeStreamJsonLine(remainder, cwd);
@@ -2152,6 +2196,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2152
2196
  const logLines = [];
2153
2197
  const responseLines = [];
2154
2198
  const recoveryTracker = createOpencodeRecoveryTracker();
2199
+ let usageSnapshot = EMPTY_CHAT_USAGE_SNAPSHOT;
2155
2200
  let remainder = '';
2156
2201
  const stderrChunks = [];
2157
2202
  const progressUpdater = createThrottledProgressUpdater(() => {
@@ -2162,6 +2207,7 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2162
2207
  const lines = text.split('\n');
2163
2208
  remainder = lines.pop() ?? '';
2164
2209
  for (const line of lines) {
2210
+ usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, line);
2165
2211
  if (firstFinalAnswerTime === null && startTime !== null) {
2166
2212
  const trimmedLine = line.trim();
2167
2213
  if (trimmedLine.startsWith('{')) {
@@ -2195,21 +2241,22 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2195
2241
  child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
2196
2242
  if (tool === 'opencode' && !resumeSessionId) {
2197
2243
  sessionLookupTimer = setTimeout(() => {
2198
- attemptOpencodeSessionLookup();
2199
- sessionLookupTimer = null;
2244
+ void attemptOpencodeSessionLookup().finally(() => {
2245
+ sessionLookupTimer = null;
2246
+ });
2200
2247
  }, 1500);
2201
2248
  if (trackBuildProcess && buildState) {
2202
2249
  buildState.sessionLookupTimer = sessionLookupTimer;
2203
2250
  }
2204
2251
  }
2205
- child.on('close', code => {
2252
+ child.on('close', async (code) => {
2206
2253
  progressUpdater.cancel();
2207
- const resolvedSessionOnClose = attemptOpencodeSessionLookup();
2208
- if (sessionLookupTimer && (resolvedSessionOnClose || hasResolvedOpencodeSessionId)) {
2209
- clearTimeout(sessionLookupTimer);
2210
- sessionLookupTimer = null;
2254
+ const finalPlacementFailure = await placementCompletion;
2255
+ if (finalPlacementFailure || settled) {
2256
+ return;
2211
2257
  }
2212
2258
  if (remainder.trim()) {
2259
+ usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, remainder);
2213
2260
  const parsed = parseOpencodeJsonLine(remainder);
2214
2261
  const { subagentEvents, providerSessionId } = parsed;
2215
2262
  if (isExecutionCapableParsedStreamLine(parsed)) {
@@ -2221,8 +2268,13 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2221
2268
  firstFinalAnswerTime = null;
2222
2269
  }
2223
2270
  }
2271
+ const resolvedSessionOnClose = await attemptOpencodeSessionLookup();
2272
+ if (sessionLookupTimer && (resolvedSessionOnClose || hasResolvedOpencodeSessionId)) {
2273
+ clearTimeout(sessionLookupTimer);
2274
+ sessionLookupTimer = null;
2275
+ }
2224
2276
  const stderrOutput = Buffer.concat(stderrChunks).toString();
2225
- opencodeSubagentMonitor?.refresh();
2277
+ await opencodeSubagentMonitor?.refresh();
2226
2278
  const log = logLines.join('\n\n') || stderrOutput;
2227
2279
  const recoveredResponse = recoveryTracker.getRecoveredResponse();
2228
2280
  const finalResponse = recoveryTracker.hasRecoveredFinalAnswer()
@@ -2232,18 +2284,25 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2232
2284
  const timing = buildResponseTiming({ startTime, firstFinalAnswerTime, isStopped: Boolean(buildState?.stopRequested || reviewProcessState?.stopRequested) });
2233
2285
  if (buildState?.stopRequested || reviewProcessState?.stopRequested) {
2234
2286
  const transcriptRuns = finalizeRun('stopped', log, finalResponse);
2235
- resolveOnce(withTranscriptRuns({ response: finalResponse, responseTiming: timing }, transcriptRuns));
2287
+ resolveOnce(withTranscriptRuns({ response: finalResponse, responseTiming: timing, usageSnapshot }, transcriptRuns));
2236
2288
  return;
2237
2289
  }
2238
2290
  if (isSuccessfulOpencodeExit(code, stderrModelError, recoveryTracker)) {
2239
2291
  const transcriptRuns = finalizeRun('done', log, finalResponse, { emit: emitSuccessUpdate });
2240
- resolveOnce(withTranscriptRuns({ response: finalResponse, responseTiming: timing }, transcriptRuns));
2292
+ resolveOnce(withTranscriptRuns({ response: finalResponse, responseTiming: timing, usageSnapshot }, transcriptRuns));
2241
2293
  return;
2242
2294
  }
2243
2295
  const failureMessage = `Agent exited with code ${code ?? 'null'}\n${log}${stderrOutput !== log && stderrOutput ? '\n\n' + stderrOutput : ''}`;
2244
2296
  const error = resumeSessionId && !executionCapableEventObserved && isTypedPreExecutionContinuationRejection(failureMessage)
2245
2297
  ? new AgentContinuationRejectedError(failureMessage)
2246
2298
  : createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker);
2299
+ const retryableError = !executionCapableEventObserved && !sessionId
2300
+ ? markRetryableOpenCodeDatabaseLock(error)
2301
+ : error;
2302
+ if (retryableError instanceof RetryableOpenCodeDatabaseLockError) {
2303
+ rejectOnce(retryableError);
2304
+ return;
2305
+ }
2247
2306
  const transcriptRuns = finalizeRun('error', log, finalResponse);
2248
2307
  rejectOnce(attachTranscriptRunsToError(error, transcriptRuns));
2249
2308
  });
@@ -2264,7 +2323,11 @@ export const runAgent = ({ ticketId, tool, prompt, cwd, io, model, variant = nul
2264
2323
  });
2265
2324
  });
2266
2325
  };
2267
- export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, opencodeAgentMode = 'build', executionContext, mainRun, spawnPermitId, }) => {
2326
+ export const runAgent = (options) => {
2327
+ const run = () => runAgentOnce(options);
2328
+ return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
2329
+ };
2330
+ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, opencodeAgentMode = 'build', executionContext, mainRun, spawnPermitId, }) => {
2268
2331
  const resolvedModel = resolveAgentModel(tool, model);
2269
2332
  const subagentTracker = createSubagentRunTracker({
2270
2333
  parentType: 'chat',
@@ -2332,10 +2395,12 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2332
2395
  });
2333
2396
  chatState.metadataRefresher = opencodeMetadataRefresher;
2334
2397
  if (resumeSessionId) {
2335
- const result = opencodeMetadataRefresher.refresh();
2336
- if (!result.hasResolvedTitle) {
2337
- opencodeMetadataRefresher.scheduleRetry();
2338
- }
2398
+ const metadataRefresher = opencodeMetadataRefresher;
2399
+ void metadataRefresher.refresh().then(result => {
2400
+ if (!result.hasResolvedTitle) {
2401
+ metadataRefresher.scheduleRetry();
2402
+ }
2403
+ });
2339
2404
  }
2340
2405
  }
2341
2406
  let child;
@@ -2555,7 +2620,7 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2555
2620
  if (!resumeSessionId) {
2556
2621
  opencodeMetadataRefresher?.scheduleRetry();
2557
2622
  }
2558
- child.on('close', code => {
2623
+ child.on('close', async (code) => {
2559
2624
  progressUpdater.cancel();
2560
2625
  if (remainder.trim()) {
2561
2626
  usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, remainder);
@@ -2583,15 +2648,15 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2583
2648
  response: finalResponse,
2584
2649
  })
2585
2650
  : null;
2586
- const metadataResult = opencodeMetadataRefresher?.refresh();
2651
+ const metadataResult = await opencodeMetadataRefresher?.refresh();
2587
2652
  const resolvedOpencodeSessionId = metadataResult?.sessionId
2588
2653
  ?? preservedOutput?.opencodeSessionId
2589
2654
  ?? getChatSession(chatSessionId)?.opencode_session_id
2590
2655
  ?? resumeSessionId;
2591
- opencodeSubagentMonitor?.refresh();
2656
+ await opencodeSubagentMonitor?.refresh();
2592
2657
  if (chatState.stopRequested) {
2593
2658
  if (resolvedOpencodeSessionId) {
2594
- usageSnapshot = resolveOpencodeUsageSnapshot({
2659
+ usageSnapshot = await resolveOpencodeUsageSnapshot({
2595
2660
  current: usageSnapshot,
2596
2661
  sessionId: resolvedOpencodeSessionId,
2597
2662
  spawnTimestamp,
@@ -2615,7 +2680,7 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2615
2680
  response: finalResponse,
2616
2681
  });
2617
2682
  if (resolvedOpencodeSessionId && spawnTimestamp !== null) {
2618
- usageSnapshot = resolveOpencodeUsageSnapshot({
2683
+ usageSnapshot = await resolveOpencodeUsageSnapshot({
2619
2684
  current: usageSnapshot,
2620
2685
  sessionId: resolvedOpencodeSessionId,
2621
2686
  spawnTimestamp,
@@ -2631,11 +2696,18 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2631
2696
  }, transcriptRuns));
2632
2697
  return;
2633
2698
  }
2634
- updateChatSessionStatus(chatSessionId, 'error', log, io, finalResponse);
2635
2699
  const failureMessage = `Agent exited with code ${code ?? 'null'}\n${log}${stderrOutput !== log && stderrOutput ? '\n\n' + stderrOutput : ''}`;
2636
2700
  const error = resumeSessionId && !executionCapableEventObserved && isTypedPreExecutionContinuationRejection(failureMessage)
2637
2701
  ? new AgentContinuationRejectedError(failureMessage)
2638
2702
  : createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker);
2703
+ const retryableError = !executionCapableEventObserved
2704
+ ? markRetryableOpenCodeDatabaseLock(error)
2705
+ : error;
2706
+ if (retryableError instanceof RetryableOpenCodeDatabaseLockError) {
2707
+ rejectOnce(retryableError);
2708
+ return;
2709
+ }
2710
+ updateChatSessionStatus(chatSessionId, 'error', log, io, finalResponse);
2639
2711
  const transcriptRuns = subagentTracker.finalize('error', log, finalResponse);
2640
2712
  rejectOnce(attachTranscriptRunsToError(error, transcriptRuns));
2641
2713
  });
@@ -2665,7 +2737,11 @@ export const runChatAgent = ({ chatSessionId, tool, prompt, files = [], cwd, io,
2665
2737
  });
2666
2738
  });
2667
2739
  };
2668
- export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, executionContext, mainRun, }) => {
2740
+ export const runChatAgent = (options) => {
2741
+ const run = () => runChatAgentOnce(options);
2742
+ return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
2743
+ };
2744
+ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, executionContext, mainRun, }) => {
2669
2745
  const resolvedModel = resolveAgentModel(tool, model);
2670
2746
  const subagentTracker = createSubagentRunTracker({
2671
2747
  parentType: 'spec',
@@ -2732,10 +2808,12 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
2732
2808
  });
2733
2809
  specState.metadataRefresher = opencodeMetadataRefresher;
2734
2810
  if (resumeSessionId) {
2735
- const result = opencodeMetadataRefresher.refresh();
2736
- if (!result.hasResolvedTitle) {
2737
- opencodeMetadataRefresher.scheduleRetry();
2738
- }
2811
+ const metadataRefresher = opencodeMetadataRefresher;
2812
+ void metadataRefresher.refresh().then(result => {
2813
+ if (!result.hasResolvedTitle) {
2814
+ metadataRefresher.scheduleRetry();
2815
+ }
2816
+ });
2739
2817
  }
2740
2818
  }
2741
2819
  let child;
@@ -2931,9 +3009,9 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
2931
3009
  if (!resumeSessionId) {
2932
3010
  opencodeMetadataRefresher?.scheduleRetry();
2933
3011
  }
2934
- child.on('close', code => {
3012
+ child.on('close', async (code) => {
2935
3013
  progressUpdater.cancel();
2936
- opencodeSubagentMonitor?.refresh();
3014
+ await opencodeSubagentMonitor?.refresh();
2937
3015
  if (remainder.trim()) {
2938
3016
  usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, remainder);
2939
3017
  const parsed = parseOpencodeJsonLine(remainder, cwd);
@@ -2957,15 +3035,15 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
2957
3035
  response: finalResponse,
2958
3036
  })
2959
3037
  : null;
2960
- const metadataResult = opencodeMetadataRefresher?.refresh();
3038
+ const metadataResult = await opencodeMetadataRefresher?.refresh();
2961
3039
  const resolvedOpencodeSessionId = metadataResult?.sessionId
2962
3040
  ?? preservedOutput?.opencodeSessionId
2963
3041
  ?? getSpecSession(specSessionId)?.opencode_session_id
2964
3042
  ?? resumeSessionId;
2965
- opencodeSubagentMonitor?.refresh();
3043
+ await opencodeSubagentMonitor?.refresh();
2966
3044
  if (specState.stopRequested) {
2967
3045
  if (resolvedOpencodeSessionId) {
2968
- usageSnapshot = resolveOpencodeUsageSnapshot({
3046
+ usageSnapshot = await resolveOpencodeUsageSnapshot({
2969
3047
  current: usageSnapshot,
2970
3048
  sessionId: resolvedOpencodeSessionId,
2971
3049
  spawnTimestamp,
@@ -2989,7 +3067,7 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
2989
3067
  response: finalResponse,
2990
3068
  });
2991
3069
  if (resolvedOpencodeSessionId && spawnTimestamp !== null) {
2992
- usageSnapshot = resolveOpencodeUsageSnapshot({
3070
+ usageSnapshot = await resolveOpencodeUsageSnapshot({
2993
3071
  current: usageSnapshot,
2994
3072
  sessionId: resolvedOpencodeSessionId,
2995
3073
  spawnTimestamp,
@@ -3005,10 +3083,18 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
3005
3083
  }, transcriptRuns));
3006
3084
  return;
3007
3085
  }
3086
+ const failureMessage = `Agent exited with code ${code ?? 'null'}\n${log}${stderrOutput !== log && stderrOutput ? '\n\n' + stderrOutput : ''}`;
3087
+ const error = createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker);
3088
+ const retryableError = logLines.length === 0 && responseLines.length === 0
3089
+ ? markRetryableOpenCodeDatabaseLock(error)
3090
+ : error;
3091
+ if (retryableError instanceof RetryableOpenCodeDatabaseLockError) {
3092
+ rejectOnce(retryableError);
3093
+ return;
3094
+ }
3008
3095
  updateSpecSessionStatusLocal(specSessionId, 'error', log, io, finalResponse);
3009
3096
  const transcriptRuns = subagentTracker.finalize('error', log, finalResponse);
3010
- const failureMessage = `Agent exited with code ${code ?? 'null'}\n${log}${stderrOutput !== log && stderrOutput ? '\n\n' + stderrOutput : ''}`;
3011
- rejectOnce(attachTranscriptRunsToError(createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker), transcriptRuns));
3097
+ rejectOnce(attachTranscriptRunsToError(error, transcriptRuns));
3012
3098
  });
3013
3099
  child.on('error', err => {
3014
3100
  progressUpdater.cancel();
@@ -3036,6 +3122,10 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
3036
3122
  });
3037
3123
  });
3038
3124
  };
3125
+ export const runSpecAgent = (options) => {
3126
+ const run = () => runSpecAgentOnce(options);
3127
+ return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
3128
+ };
3039
3129
  /**
3040
3130
  * Focused, decoupled runner for a one-shot Spec Review.
3041
3131
  *
@@ -3046,7 +3136,7 @@ export const runSpecAgent = ({ specSessionId, tool, prompt, files = [], cwd, io,
3046
3136
  * updateSpecReviewRunStatus / updateSpecReviewRunStreaming / updateSpecReviewRunUsage —
3047
3137
  * the spec_sessions row is never touched by this path.
3048
3138
  */
3049
- export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, executionContext, }) => {
3139
+ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, executionContext, }) => {
3050
3140
  const registeredState = activeSpecReviewProcesses.get(specReviewRunId);
3051
3141
  if (registeredState?.stopRequested) {
3052
3142
  return Promise.resolve({
@@ -3100,12 +3190,7 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3100
3190
  const invocation = buildOpencodeSpecReviewInvocation({ prompt, files, model: resolvedModel, variant });
3101
3191
  try {
3102
3192
  const handle = hostExecutionEnvironment.execute({
3103
- target: {
3104
- kind: 'repository',
3105
- id: cwd,
3106
- workspacePath: cwd,
3107
- revision: 'working-tree',
3108
- },
3193
+ target: null,
3109
3194
  command: invocation.command,
3110
3195
  args: invocation.args,
3111
3196
  cwd,
@@ -3150,6 +3235,7 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3150
3235
  spawnTimestamp,
3151
3236
  cwd,
3152
3237
  tracker: subagentTracker,
3238
+ parentDiscoveryDelayMs: OPENCODE_SESSION_METADATA_LOOKUP_DELAY_MS,
3153
3239
  });
3154
3240
  opencodeSubagentMonitor.start();
3155
3241
  }
@@ -3273,9 +3359,9 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3273
3359
  }
3274
3360
  });
3275
3361
  child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
3276
- child.on('close', code => {
3362
+ child.on('close', async (code) => {
3277
3363
  progressUpdater.cancel();
3278
- opencodeSubagentMonitor?.refresh();
3364
+ await opencodeSubagentMonitor?.refresh();
3279
3365
  if (remainder.trim()) {
3280
3366
  usageSnapshot = mergeUsageFromJsonLine(usageSnapshot, remainder);
3281
3367
  const parsed = parseOpencodeJsonLine(remainder, cwd);
@@ -3293,7 +3379,7 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3293
3379
  ? recoveredResponse
3294
3380
  : responseLines.join('\n\n') || stderrOutput;
3295
3381
  if (opencodeSessionId && spawnTimestamp !== null) {
3296
- usageSnapshot = resolveOpencodeUsageSnapshot({
3382
+ usageSnapshot = await resolveOpencodeUsageSnapshot({
3297
3383
  current: usageSnapshot,
3298
3384
  sessionId: opencodeSessionId,
3299
3385
  spawnTimestamp,
@@ -3322,9 +3408,17 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3322
3408
  });
3323
3409
  return;
3324
3410
  }
3325
- subagentTracker.finalize('error', log || null, finalResponse || null);
3326
3411
  const failureMessage = `Agent exited with code ${code ?? 'null'}\n${log}${stderrOutput !== log && stderrOutput ? '\n\n' + stderrOutput : ''}`;
3327
- rejectOnce(createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker));
3412
+ const error = createOpencodeExitError(failureMessage, stderrModelError, recoveryTracker);
3413
+ const retryableError = logLines.length === 0 && responseLines.length === 0 && !opencodeSessionId
3414
+ ? markRetryableOpenCodeDatabaseLock(error)
3415
+ : error;
3416
+ if (retryableError instanceof RetryableOpenCodeDatabaseLockError) {
3417
+ rejectOnce(retryableError);
3418
+ return;
3419
+ }
3420
+ subagentTracker.finalize('error', log || null, finalResponse || null);
3421
+ rejectOnce(error);
3328
3422
  });
3329
3423
  child.on('error', err => {
3330
3424
  progressUpdater.cancel();
@@ -3350,4 +3444,8 @@ export const runSpecReviewAgent = ({ specReviewRunId, specSessionId, tool, promp
3350
3444
  });
3351
3445
  });
3352
3446
  };
3447
+ export const runSpecReviewAgent = (options) => {
3448
+ const run = () => runSpecReviewAgentOnce(options);
3449
+ return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
3450
+ };
3353
3451
  //# sourceMappingURL=agent.js.map