@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
@@ -5,6 +5,7 @@ import { createSpecMessage, listSpecMessages } from '../lib/specMessages.js';
5
5
  import { beginSpecSessionThinkingRun, bindSpecSessionThinkingMessage } from '../lib/thinkingState.js';
6
6
  import { createSpecSnapshot, deriveSpecSessionTitle, getDefaultSpecSessionTitle, getSpecSession, getSpecSnapshot, resolveSpecModeValue, updateSpecSessionMode, updateSpecSessionRunConfig, updateSpecSessionStatus, updateSpecSessionTitle, updateSpecSessionUsageSnapshot, } from '../lib/specs.js';
7
7
  import { normalizeClaudeModelId, normalizeModelId } from '../lib/models.js';
8
+ import { HttpError } from '../lib/httpError.js';
8
9
  import { appendPlanModeQuestionPromptRules, PLAN_MODE_RUNTIME_PROMPT_RULES } from '../lib/planModeQuestions.js';
9
10
  import { getProjectMemoryPromptBlock } from '../lib/projectMemoryPrompt.js';
10
11
  import { buildPlanningSubagentGuidancePromptBlock } from '../lib/promptSkills.js';
@@ -15,12 +16,13 @@ import { getProjectById } from '../lib/projects.js';
15
16
  import { addExecutionRunLink, transitionExecutionRun } from '../lib/executionRuns.js';
16
17
  import { TurnStartError } from '../lib/turnExecutionErrors.js';
17
18
  import { buildLinkedResearchContext, prepareLinkedPlanningResearch } from './plan.js';
18
- import { extractGrillQuestionFromOutput, extractSpecArtifactFromOutput, projectPlannerOwnedLikelyFiles, resolveCarriedForwardArtifacts, resolveCarriedForwardStructuredFields, stripMermaidBlocks } from '../lib/specArtifact.js';
19
+ import { extractGrillQuestionFromOutput, extractSpecArtifactFromOutput, projectPlannerOwnedLikelyFiles, resolveCarriedForwardArtifacts, resolveCarriedForwardStructuredFields, stripFileRelationGraphBlocks, stripMermaidBlocks } from '../lib/specArtifact.js';
19
20
  import { createAskQuestionMetadata, extractAskQuestionFromOutput, formatAskQuestionMessage } from '../lib/planQuestions.js';
20
21
  import { collectSpecResourceUrls } from '../lib/specResources.js';
22
+ import { resolveImportedSpecBundleName } from '../lib/specBundleGroups.js';
21
23
  import { resolveSessionTargetForExecution } from '../lib/sessionTargets.js';
22
- import { captureSpecSnapshotRepositoryEvidenceFromAcquisition } from '../lib/specSnapshotEvidence.js';
23
- import { obtainExactCompletedScan, projectSpecRepositoryImpact, reconcileSpecLikelyFiles, selectSpecRepositoryImpactSeeds, serializeSpecRepositoryImpactForPrompt } from '../lib/specRepositoryImpact.js';
24
+ import { unavailableSpecSnapshotRepositoryEvidence } from '../lib/specSnapshotEvidenceSerialization.js';
25
+ import { SPEC_GRAPH_DISABLED_REASON } from '../lib/specGraphFeature.js';
24
26
  import { registerBundleSpecWork, registerRepoRootSpecWork } from '../lib/specWorkspaceActivity.js';
25
27
  import { IMPLEMENTATION_BODY_DEDUPLICATION_RULES, IMPLEMENTATION_DETAIL_RULES, IMPLEMENTATION_READY_DESCRIPTION_REQUIREMENTS, IMPLEMENTATION_READY_DESCRIPTION_SECTION_TEMPLATE, } from '../lib/ticketDescriptionContract.js';
26
28
  const raceAgainstSpecCancellation = async (promise, cancellationState) => {
@@ -68,6 +70,7 @@ const getTranscriptContentFallback = (runs) => {
68
70
  || runs?.find(run => run.thinking_log?.trim())?.thinking_log?.trim()
69
71
  || '';
70
72
  };
73
+ const stripSpecFileGraph = (value) => stripFileRelationGraphBlocks(value).trim();
71
74
  const resolveSpecWorkerKey = (specSessionId) => `spec-session:${specSessionId}`;
72
75
  /**
73
76
  * Render the prior snapshot's structured fields as a compact text block the
@@ -108,9 +111,15 @@ const formatPreviousSpecStateBlock = (snapshot) => {
108
111
  lines.push(`- ${dep.blocker_key} -> ${dep.dependent_key}`);
109
112
  }
110
113
  }
114
+ if ((snapshot.bundle_groups ?? []).length > 0) {
115
+ lines.push('Bundle groups:');
116
+ for (const group of snapshot.bundle_groups ?? []) {
117
+ lines.push(`- ${group.key} (${group.name}): ${group.ticket_keys.join(', ')}`);
118
+ }
119
+ }
111
120
  return lines.join('\n');
112
121
  };
113
- const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRelationGraph, }) => {
122
+ const buildStandardModeTail = ({ existingMermaid, existingMockup, bundleGroupingInstruction, }) => {
114
123
  return [
115
124
  [
116
125
  'Turn handling:',
@@ -124,25 +133,12 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
124
133
  ' (carry-forward status, prior-turn JSON bugs, re-emission rationale, or notes about what the',
125
134
  ' artifact "still contains"). The reader never needs to know that information was carried forward.',
126
135
  '',
127
- '2. Diagrams. Emit TWO mermaid diagrams as separate fenced blocks — they serve different purposes and',
128
- ' the UI renders them in different panels (Visualization vs Likely Files), so do not merge them into',
129
- ' one block. Both are normally expected on a plan update that touches code; skip one only when its',
130
- ' subject matter is genuinely absent.',
131
- ' a. A `mermaid` block — the ARCHITECTURE/data-flow diagram (components, request lifecycle, module',
132
- ' boundaries, data flow). Use `flowchart TD` for hierarchical/architectural layouts, `flowchart LR`',
133
- ' for timelines or sequential flows. Nodes here are abstract roles ("API server", "DB", "client"),',
134
- ' NOT individual source files. Skip only for trivial single-step plans with no architecture to depict.',
135
- ' b. An `archon-file-graph` block — the FILE-RELATION diagram: literal edges between the entries in',
136
- ' `likely_files` (A imports B, A calls B, A extends B, etc.). Use `flowchart LR` and reference the',
137
- ' SAME file paths used in `likely_files` so the reader can cross-reference. Emit this block whenever',
138
- ' `likely_files` contains 3 or more files that import, call, or otherwise depend on each other;',
139
- ' omit it only when the files are genuinely independent (a flat list with no cross-file edges).',
140
- ' Do NOT duplicate the architecture diagram here — if a node is "the API server" it belongs in (a),',
141
- ' if it is "src/server/api.ts" it belongs in (b).',
142
- ' The fence language tag determines where the diagram renders: a plain `mermaid` block renders in the',
143
- ' Visualization slot, an `archon-file-graph` block renders under Likely Files. Putting file-relation',
144
- ' content in a plain `mermaid` block lands it in the wrong slot.',
145
- ' Mermaid syntax rules apply to BOTH diagrams (a single bad label fails the whole diagram):',
136
+ '2. When the plan has architecture or data flow to show, emit one `mermaid` block for the',
137
+ ' ARCHITECTURE/data-flow diagram (components, request lifecycle, module boundaries, data flow). Use',
138
+ ' `flowchart TD` for hierarchical/architectural layouts or `flowchart LR` for timelines and sequential',
139
+ ' flows. Nodes here are abstract roles ("API server", "DB", "client"), NOT individual source files.',
140
+ ' Skip it for trivial plans with no architecture to depict.',
141
+ ' Mermaid syntax rules apply to this diagram:',
146
142
  ' - Quote EVERY node label that contains anything other than letters, digits, spaces, or hyphens, using',
147
143
  ' the bracket-quoted form `ID["label text"]`. File paths, function signatures, and any text with `.`,',
148
144
  ' `/`, `(`, `)`, `[`, `]`, `"`, `&`, `<`, `>`, or `|` MUST be quoted.',
@@ -153,8 +149,6 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
153
149
  ' Example:',
154
150
  ' Good: MA["MobileApp.tsx"] --> API["mobileApi.ts"]',
155
151
  ' Bad: MA[MobileApp.tsx] --> API[mobileApi.ts] %% tolerated, but any `)` or `]` in a bare label is a hard parse failure',
156
- ' The `archon-file-graph` block is for human review only and is never forwarded to the build agent or',
157
- ' included in any ticket description.',
158
152
  '',
159
153
  '3. When (and only when) the plan involves a UI surface, optionally include a low-fidelity UI mockup as a',
160
154
  ' self-contained, generic, unstyled HTML wireframe inside a fenced `archon-mockup` block. Use plain',
@@ -165,7 +159,7 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
165
159
  '',
166
160
  '4. A machine-readable artifact block with the spec structured data, using exactly these markers:',
167
161
  ' <archon-spec-artifact>',
168
- ' {"summary":"short plan summary","likely_files":[{"path":"src/foo.ts","reason":"Add bar helper","is_new":false},{"path":"src/newHelper.ts","reason":"Provide the new shared helper","is_new":true}],"tickets":[{"key":"add-foo-bar","title":"Add bar helper to foo module","description":"## Problem Statement\\nThe foo module is missing the `bar` helper, blocking downstream consumers from validating inputs consistently.\\n\\n## Acceptance Criteria\\n- [ ] A `bar(input)` function is exported from `src/foo.ts`.\\n- [ ] Invalid inputs throw a typed error with a clear message.\\n- [ ] All existing callers of foo continue to work unchanged.\\n\\n## Implementation Approach\\n1. Add `bar` to `src/foo.ts` following the existing `baz` helper signature pattern.\\n2. Reuse the project existing validation utilities instead of inlining checks.\\n3. Export `bar` from the module barrel file.\\n\\n## Edge Cases and Error Handling\\n- Empty string inputs should throw the same typed error as other invalid inputs.\\n- Preserve current behavior for `undefined`/`null` (do not coerce).\\n\\n## Constraints and Things to Avoid\\n- Do not introduce a new dependency.\\n- Do not change the public signature of existing exports."},{"key":"use-bar-in-consumer","title":"Call bar from consumer module","description":"## Problem Statement\\nThe consumer module duplicates input validation that `bar` now provides.\\n\\n## Acceptance Criteria\\n- [ ] Consumer calls `bar` instead of its own inline validation.\\n- [ ] Existing consumer tests still pass.\\n\\n## Implementation Approach\\n1. Replace the inline check in consumer with a call to `bar`.\\n2. Remove the now-unused validation helper from consumer.\\n\\n## Edge Cases and Error Handling\\n- Consumer must handle the typed errors thrown by `bar`.\\n\\n## Constraints and Things to Avoid\\n- Do not change the consumer public API."}],"dependencies":[{"blocker_key":"add-foo-bar","dependent_key":"use-bar-in-consumer"}]}',
162
+ ' {"summary":"short plan summary","likely_files":[{"path":"src/foo.ts","reason":"Add bar helper","is_new":false},{"path":"src/newHelper.ts","reason":"Provide the new shared helper","is_new":true}],"tickets":[{"key":"add-foo-bar","title":"Add bar helper to foo module","description":"## Problem Statement\\nThe foo module is missing the `bar` helper, blocking downstream consumers from validating inputs consistently.\\n\\n## Acceptance Criteria\\n- [ ] A `bar(input)` function is exported from `src/foo.ts`.\\n- [ ] Invalid inputs throw a typed error with a clear message.\\n- [ ] All existing callers of foo continue to work unchanged.\\n\\n## Implementation Approach\\n1. Add `bar` to `src/foo.ts` following the existing `baz` helper signature pattern.\\n2. Reuse the project existing validation utilities instead of inlining checks.\\n3. Export `bar` from the module barrel file.\\n\\n## Edge Cases and Error Handling\\n- Empty string inputs should throw the same typed error as other invalid inputs.\\n- Preserve current behavior for `undefined`/`null` (do not coerce).\\n\\n## Constraints and Things to Avoid\\n- Do not introduce a new dependency.\\n- Do not change the public signature of existing exports."},{"key":"use-bar-in-consumer","title":"Call bar from consumer module","description":"## Problem Statement\\nThe consumer module duplicates input validation that `bar` now provides.\\n\\n## Acceptance Criteria\\n- [ ] Consumer calls `bar` instead of its own inline validation.\\n- [ ] Existing consumer tests still pass.\\n\\n## Implementation Approach\\n1. Replace the inline check in consumer with a call to `bar`.\\n2. Remove the now-unused validation helper from consumer.\\n\\n## Edge Cases and Error Handling\\n- Consumer must handle the typed errors thrown by `bar`.\\n\\n## Constraints and Things to Avoid\\n- Do not change the consumer public API."}],"dependencies":[{"blocker_key":"add-foo-bar","dependent_key":"use-bar-in-consumer"}],"bundle_groups":[{"key":"core-change","name":"foo-validation","ticket_keys":["add-foo-bar","use-bar-in-consumer"]}]}',
169
163
  ' </archon-spec-artifact>',
170
164
  '',
171
165
  'The artifact represents the complete current state of the spec. On follow-up turns, re-emit every field',
@@ -207,8 +201,10 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
207
201
  ' work). Omit the field or emit `[]` for tickets that need neither (e.g. pure backend work). The system',
208
202
  ' appends the tagged blocks as text; never embed the diagram or mockup source in the description yourself.',
209
203
  '- `dependencies` — array of objects with `blocker_key` (the ticket key that must be done first) and `dependent_key` (the ticket key that depends on the blocker). Only include direct blockers, not transitive dependencies. Every key must reference one of the generated ticket keys.',
204
+ '- `bundle_groups` (required for a new spec) — ordered array of {"key":"stable-kebab-key","name":"short-branch-safe-name","ticket_keys":["ticket-key"]}. Every ticket must appear exactly once, groups and effective names must be unique, groups cannot be empty, and dependencies cannot cross groups.',
205
+ bundleGroupingInstruction,
210
206
  '',
211
- 'For the optional array fields (assumptions, open_questions, likely_files, dependencies):',
207
+ 'For the optional array fields (assumptions, open_questions, likely_files, dependencies, bundle_groups):',
212
208
  '- OMIT a field to leave it unchanged from the prior snapshot — it is carried forward automatically.',
213
209
  '- Emit an array to set the field to that exact value this turn. Emit `[]` ONLY to intentionally clear it.',
214
210
  '- When the plan changes a field, re-emit it with the updated contents. Do not silently drop entries that',
@@ -218,8 +214,6 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
218
214
  'automatically from the fenced code block above.',
219
215
  'Do NOT include the UI mockup in the artifact JSON — the `archon-mockup` block is extracted',
220
216
  'automatically from its fenced code block above when present.',
221
- 'Do NOT include the file-relation graph in the artifact JSON — the `archon-file-graph` block is extracted',
222
- 'automatically from its fenced code block above when present, and is for human review only.',
223
217
  'A per-ticket `relevant_visualizations` tag array IS allowed — it references the blocks by key and does',
224
218
  'not duplicate their content.',
225
219
  '',
@@ -234,19 +228,19 @@ const buildStandardModeTail = ({ existingMermaid, existingMockup, existingFileRe
234
228
  '- If no dependencies are needed, return an empty dependencies array.',
235
229
  '- If the artifact block is missing or malformed, no specification snapshot will be saved.',
236
230
  ].join('\n'),
237
- (existingMermaid || existingMockup || existingFileRelationGraph)
231
+ (existingMermaid || existingMockup)
238
232
  ? [
239
- 'A `mermaid` diagram, `archon-mockup` UI wireframe, and/or `archon-file-graph` file-relation diagram',
233
+ 'A `mermaid` diagram and/or `archon-mockup` UI wireframe',
240
234
  'has already been established for this spec in a prior turn and is preserved automatically across',
241
235
  'turns. Do NOT regenerate any of these fenced blocks unless this turn materially changes the',
242
- 'architecture, UI, or file relationships it depicts — re-emitting unchanged content wastes tokens.',
243
- 'Omit the `mermaid`, `archon-mockup`, and/or `archon-file-graph` blocks on this turn when they would',
236
+ 'architecture or UI it depicts — re-emitting unchanged content wastes tokens.',
237
+ 'Omit the `mermaid` and/or `archon-mockup` blocks on this turn when they would',
244
238
  'be unchanged; they will be carried forward from the previous snapshot automatically.',
245
239
  ].join('\n')
246
240
  : '',
247
241
  ].filter(Boolean).join('\n\n');
248
242
  };
249
- const buildGrillModeTail = () => {
243
+ const buildGrillModeTail = (bundleGroupingInstruction) => {
250
244
  return [
251
245
  [
252
246
  'GRILL MODE: You are pressure-testing this spec before it is written. Do NOT emit the full plan or the',
@@ -294,11 +288,11 @@ const buildGrillModeTail = () => {
294
288
  [
295
289
  'Standard spec artifact emission rules (use ONLY on the turn you finalize the plan):',
296
290
  '',
297
- buildStandardModeTail({ existingMermaid: false, existingMockup: false, existingFileRelationGraph: false }),
291
+ buildStandardModeTail({ existingMermaid: false, existingMockup: false, bundleGroupingInstruction }),
298
292
  ].join('\n'),
299
293
  ].join('\n\n');
300
294
  };
301
- const buildSpecPrompt = ({ projectName, projectPath, instruction, hasAttachments, projectMemory, memoryEnabled, previousSnapshot, linkedResearchContext, repositoryImpactContext, mode, }) => {
295
+ const buildSpecPrompt = ({ projectName, projectPath, instruction, hasAttachments, projectMemory, memoryEnabled, previousSnapshot, linkedResearchContext, mode, targetKind, targetBundleName, externalKey, }) => {
302
296
  const trimmedInstruction = instruction.trim();
303
297
  const attachmentPrompt = hasAttachments
304
298
  ? 'One or more user-attached images are included with this turn. Inspect them for requirements, visual constraints, and implementation context.'
@@ -313,7 +307,11 @@ const buildSpecPrompt = ({ projectName, projectPath, instruction, hasAttachments
313
307
  : '';
314
308
  const existingMermaid = Boolean(previousSnapshot?.mermaid);
315
309
  const existingMockup = Boolean(previousSnapshot?.mockup);
316
- const existingFileRelationGraph = Boolean(previousSnapshot?.file_relation_graph);
310
+ const bundleGroupingInstruction = targetKind === 'bundle'
311
+ ? `This spec targets the existing bundle "${targetBundleName ?? 'captured bundle'}". Emit exactly one group containing every ticket; multi-bundle output is invalid and the captured bundle will be used.`
312
+ : externalKey
313
+ ? `This is an imported spec. Group tickets independently as justified, but bundle names are ignored and persisted deterministically as ${resolveImportedSpecBundleName(externalKey, 0)}, ${resolveImportedSpecBundleName(externalKey, 1)}, and onward in group order.`
314
+ : 'Choose one or more independently buildable PR-oriented groups with short branch-safe names. If the user requests an exact count, use it only when that exact number of non-empty independent groups is justified; otherwise ask the user to reconsider and do not emit an artifact.';
317
315
  const previousSpecBaseline = previousSnapshot
318
316
  ? [
319
317
  'This spec already exists from prior turns. Treat the spec as accumulating: the artifact you emit this',
@@ -338,15 +336,14 @@ const buildSpecPrompt = ({ projectName, projectPath, instruction, hasAttachments
338
336
  `Project: ${projectName}\nWorking directory: ${projectPath}`,
339
337
  projectMemory,
340
338
  linkedResearchContext,
341
- repositoryImpactContext,
342
339
  previousSpecBaseline,
343
340
  attachmentPrompt,
344
341
  attachmentResponseInstruction,
345
342
  userRequest,
346
343
  ];
347
344
  const modeTail = mode === 'grill'
348
- ? buildGrillModeTail()
349
- : buildStandardModeTail({ existingMermaid, existingMockup, existingFileRelationGraph });
345
+ ? buildGrillModeTail(bundleGroupingInstruction)
346
+ : buildStandardModeTail({ existingMermaid, existingMockup, bundleGroupingInstruction });
350
347
  const prompt = [
351
348
  ...sharedBlocks,
352
349
  modeTail,
@@ -545,15 +542,6 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
545
542
  ? { kind: 'bundle', bundle_id: runnableTarget.target.target_bundle_id }
546
543
  : { kind: 'repo_root', bundle_id: null };
547
544
  const requestedMode = turnMode ?? resolveSpecModeValue(latestSession.mode);
548
- let consultedScan = {
549
- state: 'fallback',
550
- reason: 'acquisition_failed',
551
- message: 'Repository graph evidence was not acquired for this turn mode.',
552
- };
553
- let repositoryImpactContext = '';
554
- const scanAcquisition = requestedMode === 'standard'
555
- ? obtainExactCompletedScan(latestProject, targetDescriptor)
556
- : Promise.resolve(consultedScan);
557
545
  const promptContext = latestSession.title === getDefaultSpecSessionTitle()
558
546
  ? null
559
547
  : latestSession.title;
@@ -565,39 +553,20 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
565
553
  currentInstruction: trimmedInstruction,
566
554
  invocation: { parentType: 'spec', parentId: specSessionId, agentRunId: mainRunId },
567
555
  });
568
- const preResponseContext = await raceAgainstSpecCancellation(Promise.all([
569
- trimmedInstruction
570
- ? prepareLinkedPlanningResearch(trimmedInstruction, {
571
- projectId: latestProject.id,
572
- cwd,
573
- tool: resolvedTool,
574
- model: resolvedModel,
575
- variant: resolvedVariant,
576
- skills: resolvedSkills,
577
- executionContext,
578
- cancellationState: specCancellation,
579
- agentRunParent: { parentType: 'spec', parentId: specSessionId, io },
580
- })
581
- : Promise.resolve([]),
582
- scanAcquisition,
583
- ]), specCancellation);
584
- const [linkedResearch, acquiredScan] = preResponseContext.cancelled
585
- ? [[], consultedScan]
586
- : preResponseContext.value;
587
- consultedScan = acquiredScan;
588
- if (consultedScan.state === 'ready') {
589
- const promptSeeds = selectSpecRepositoryImpactSeeds({
590
- plannerLikelyFiles: projectPlannerOwnedLikelyFiles(previousSnapshot?.likely_files ?? []),
591
- instruction: trimmedInstruction,
592
- });
593
- if (promptSeeds.length > 0) {
594
- repositoryImpactContext = serializeSpecRepositoryImpactForPrompt(projectSpecRepositoryImpact({
595
- projectId: latestProject.id,
596
- scanId: consultedScan.scan.id,
597
- seeds: promptSeeds,
598
- }));
599
- }
600
- }
556
+ const preResponseContext = await raceAgainstSpecCancellation(trimmedInstruction
557
+ ? prepareLinkedPlanningResearch(trimmedInstruction, {
558
+ projectId: latestProject.id,
559
+ cwd,
560
+ tool: resolvedTool,
561
+ model: resolvedModel,
562
+ variant: resolvedVariant,
563
+ skills: resolvedSkills,
564
+ executionContext,
565
+ cancellationState: specCancellation,
566
+ agentRunParent: { parentType: 'spec', parentId: specSessionId, io },
567
+ })
568
+ : Promise.resolve([]), specCancellation);
569
+ const linkedResearch = preResponseContext.cancelled ? [] : preResponseContext.value;
601
570
  // Honor an interrupt that arrived during the pre-response window. There
602
571
  // is no child to kill and no partial response to save; transition straight
603
572
  // to 'stopped' (worker-owned, mirroring how Chat finalizes after a stop).
@@ -636,8 +605,10 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
636
605
  memoryEnabled: Boolean(latestProject.memory_enabled),
637
606
  previousSnapshot,
638
607
  linkedResearchContext,
639
- repositoryImpactContext,
640
608
  mode: requestedMode,
609
+ targetKind: runnableTarget.target.target_kind,
610
+ targetBundleName: latestSession.target_branch_snapshot,
611
+ externalKey: latestSession.external_source?.external_key ?? null,
641
612
  });
642
613
  const specRunResult = await runSpecAgent({
643
614
  specSessionId,
@@ -658,9 +629,9 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
658
629
  });
659
630
  if (specRunResult.completionStatus === 'stopped') {
660
631
  const interruptedSession = getSpecSession(specSessionId);
661
- const interruptedResponse = interruptedSession?.streaming_response?.trim()
662
- || specRunResult.finalResponse?.trim()
663
- || getTranscriptContentFallback(specRunResult.transcriptRuns)
632
+ const interruptedResponse = stripSpecFileGraph(interruptedSession?.streaming_response ?? '')
633
+ || stripSpecFileGraph(specRunResult.finalResponse ?? '')
634
+ || stripSpecFileGraph(getTranscriptContentFallback(specRunResult.transcriptRuns))
664
635
  || '';
665
636
  if (resolvedTool === 'opencode' && interruptedSession?.title === getDefaultSpecSessionTitle()) {
666
637
  updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
@@ -725,9 +696,9 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
725
696
  throw new Error(`Invalid Grill question envelope: ${grillResult.error}`);
726
697
  }
727
698
  if (grillResult.grillQuestion) {
728
- const cleanedGrillText = grillResult.cleanedOutput.trim()
699
+ const cleanedGrillText = stripSpecFileGraph(grillResult.cleanedOutput)
729
700
  || grillResult.grillQuestion.question
730
- || streamedAssistantMessage.trim();
701
+ || stripSpecFileGraph(streamedAssistantMessage);
731
702
  const grillMessageId = createSpecMessage({
732
703
  specSessionId,
733
704
  role: 'assistant',
@@ -775,7 +746,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
775
746
  throw new Error(`Invalid question envelope: ${askQuestionResult.error}`);
776
747
  }
777
748
  if (askQuestionResult.questionSet) {
778
- const questionMessage = askQuestionResult.cleanedOutput.trim() || formatAskQuestionMessage(askQuestionResult.questionSet);
749
+ const questionMessage = stripSpecFileGraph(askQuestionResult.cleanedOutput) || formatAskQuestionMessage(askQuestionResult.questionSet);
779
750
  const messageId = createSpecMessage({
780
751
  specSessionId,
781
752
  role: 'assistant',
@@ -820,29 +791,23 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
820
791
  if (latestProject.memory_enabled && parsedResponse.suggestions && parsedResponse.suggestions.length > 0) {
821
792
  persistSpecSessionProjectMemorySuggestions(latestProject.id, specSessionId, parsedResponse.suggestions);
822
793
  }
823
- const cleanedPlanText = stripMermaidBlocks(parsedResponse.cleanedOutput).trim()
824
- || stripMermaidBlocks(streamedAssistantMessage).trim();
794
+ const cleanPlannerResponse = (value) => stripSpecFileGraph(stripMermaidBlocks(value));
795
+ const cleanedPlanText = cleanPlannerResponse(parsedResponse.cleanedOutput)
796
+ || cleanPlannerResponse(streamedAssistantMessage);
825
797
  let assistantMessage = cleanedPlanText
826
- || getTranscriptContentFallback(specRunResult.transcriptRuns)
798
+ || stripSpecFileGraph(getTranscriptContentFallback(specRunResult.transcriptRuns))
827
799
  || (attachments.length > 0 ? ATTACHMENT_ONLY_EMPTY_RESPONSE_FALLBACK : '');
800
+ let artifactValidationError = artifactResult.error;
828
801
  // Create snapshot from artifact if present. Presence is populated
829
802
  // alongside artifact by the extractor, so the two are non-null together.
830
803
  if (artifactResult.artifact && artifactResult.presence) {
831
- if (sessionMode === 'grill') {
832
- const acquisition = await raceAgainstSpecCancellation(obtainExactCompletedScan(latestProject, targetDescriptor), specCancellation);
833
- if (acquisition.cancelled) {
834
- throw new Error('Spec repository evidence acquisition was cancelled');
835
- }
836
- consultedScan = acquisition.value;
837
- }
838
804
  // A block re-emitted this turn overrides the previous snapshot's value;
839
805
  // an omitted block is carried forward so established artifacts don't
840
806
  // disappear when a follow-up turn omits the diagram/mockup.
841
- const { mermaid: mermaidBlock, mockup: mockupBlock, fileRelationGraph: fileRelationGraphBlock } = resolveCarriedForwardArtifacts({
807
+ const { mermaid: mermaidBlock, mockup: mockupBlock } = resolveCarriedForwardArtifacts({
842
808
  rawResponse,
843
809
  previousMermaid: previousSnapshot?.mermaid ?? null,
844
810
  previousMockup: previousSnapshot?.mockup ?? null,
845
- previousFileRelationGraph: previousSnapshot?.file_relation_graph ?? null,
846
811
  });
847
812
  // Optional structured array fields use the same carry-forward contract:
848
813
  // a field the LLM emitted this turn (including an explicit empty array)
@@ -857,75 +822,66 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
857
822
  openQuestions: previousSnapshot.open_questions,
858
823
  likelyFiles: previousSnapshot.likely_files,
859
824
  dependencies: previousSnapshot.dependencies,
825
+ bundleGroups: previousSnapshot.bundle_groups ?? [],
860
826
  }
861
827
  : null,
862
828
  });
863
829
  const resourceUrls = collectSpecResourceUrls(listSpecMessages(specSessionId, latestProject.id)
864
830
  .filter(message => message.role === 'user')
865
831
  .map(message => message.content));
866
- const plannerSeedPaths = selectSpecRepositoryImpactSeeds({
867
- plannerLikelyFiles: carriedFields.likelyFiles,
868
- instruction: trimmedInstruction,
869
- });
870
- const postResponseProjection = consultedScan.state === 'ready' && plannerSeedPaths.length > 0
871
- ? projectSpecRepositoryImpact({
872
- projectId: latestProject.id,
873
- scanId: consultedScan.scan.id,
874
- seeds: plannerSeedPaths,
875
- })
876
- : {
877
- state: 'fallback',
878
- reason: 'unknown_seeds',
879
- message: 'No existing planner-authored likely files were available as repository graph seeds.',
880
- };
881
- const repositoryEvidence = await captureSpecSnapshotRepositoryEvidenceFromAcquisition({
882
- project: latestProject,
883
- target: targetDescriptor,
884
- seedPaths: plannerSeedPaths,
885
- acquisition: consultedScan,
886
- });
887
- const likelyFiles = repositoryEvidence.capture_state === 'complete'
888
- ? reconcileSpecLikelyFiles({ plannerLikelyFiles: carriedFields.likelyFiles, projection: postResponseProjection })
889
- : projectPlannerOwnedLikelyFiles(carriedFields.likelyFiles);
890
- const snapshotId = createSpecSnapshot({
891
- specSessionId,
892
- summary: artifactResult.artifact.summary,
893
- assumptions: carriedFields.assumptions,
894
- openQuestions: carriedFields.openQuestions,
895
- likelyFiles,
896
- tickets: artifactResult.artifact.tickets,
897
- dependencies: carriedFields.dependencies,
898
- resourceUrls,
899
- mermaid: mermaidBlock,
900
- mockup: mockupBlock,
901
- fileRelationGraph: fileRelationGraphBlock,
902
- planText: cleanedPlanText,
903
- repositoryEvidence,
904
- });
905
- addExecutionRunLink({
906
- projectId: executionContext.projectId,
907
- runId: executionContext.runId,
908
- link: {
909
- entityType: 'spec_snapshot',
910
- entityId: snapshotId,
911
- relationship: 'result',
912
- expectedParent: { entityType: 'spec_session', entityId: specSessionId },
913
- },
914
- });
832
+ const repositoryEvidence = unavailableSpecSnapshotRepositoryEvidence(SPEC_GRAPH_DISABLED_REASON, targetDescriptor);
833
+ const likelyFiles = projectPlannerOwnedLikelyFiles(carriedFields.likelyFiles);
834
+ let snapshotId = null;
835
+ try {
836
+ snapshotId = createSpecSnapshot({
837
+ specSessionId,
838
+ summary: artifactResult.artifact.summary,
839
+ assumptions: carriedFields.assumptions,
840
+ openQuestions: carriedFields.openQuestions,
841
+ likelyFiles,
842
+ tickets: artifactResult.artifact.tickets,
843
+ dependencies: carriedFields.dependencies,
844
+ bundleGroups: carriedFields.bundleGroups,
845
+ resourceUrls,
846
+ mermaid: mermaidBlock,
847
+ mockup: mockupBlock,
848
+ fileRelationGraph: null,
849
+ planText: cleanedPlanText,
850
+ repositoryEvidence,
851
+ });
852
+ }
853
+ catch (error) {
854
+ if (!(error instanceof HttpError) || error.status !== 422) {
855
+ throw error;
856
+ }
857
+ artifactValidationError = error.message;
858
+ }
859
+ if (snapshotId) {
860
+ addExecutionRunLink({
861
+ projectId: executionContext.projectId,
862
+ runId: executionContext.runId,
863
+ link: {
864
+ entityType: 'spec_snapshot',
865
+ entityId: snapshotId,
866
+ relationship: 'result',
867
+ expectedParent: { entityType: 'spec_session', entityId: specSessionId },
868
+ },
869
+ });
870
+ }
915
871
  // Auto-finalize: when an artifact is emitted during grill mode, the
916
872
  // agent has signaled that it has no remaining questions. Flip the
917
873
  // session mode back to 'standard' so subsequent turns run the standard
918
874
  // prompt. This runs inside the same queued job that wrote the snapshot,
919
875
  // so it cannot race with a concurrent user-initiated mode change.
920
- if (sessionMode === 'grill') {
876
+ if (snapshotId && sessionMode === 'grill') {
921
877
  updateSpecSessionMode(specSessionId, 'standard');
922
878
  }
923
879
  }
924
880
  // Append artifact error note to the visible message if extraction failed.
925
881
  // Suppress the "no block found" note — it is normal for Q&A turns where the
926
882
  // agent intentionally omitted the artifact because the specification did not change.
927
- if (artifactResult.error && assistantMessage && artifactResult.error !== 'No spec artifact block found in planner response') {
928
- assistantMessage += `\n\n[Note: ${artifactResult.error}. No specification snapshot was saved. You can try refining the spec or asking the planner to regenerate the artifact.]`;
883
+ if (artifactValidationError && assistantMessage && artifactValidationError !== 'No spec artifact block found in planner response') {
884
+ assistantMessage += `\n\n[Note: ${artifactValidationError}. No specification snapshot was saved. You can try refining the spec or asking the planner to regenerate the artifact.]`;
929
885
  }
930
886
  if (assistantMessage) {
931
887
  const messageId = createSpecMessage({