@maycombhq/atticus 0.0.0-stage → 2.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/LICENSE +177 -0
  2. package/README.md +17 -2
  3. package/THIRD-PARTY-LICENSES.txt +2607 -0
  4. package/dist/bin.js +47 -0
  5. package/dist/chunk-23M2LUYM.js +55 -0
  6. package/dist/chunk-26PLPSQW.js +48 -0
  7. package/dist/chunk-2G4DFUWJ.js +43 -0
  8. package/dist/chunk-2HMWX4T6.js +226 -0
  9. package/dist/chunk-2KDSXJFJ.js +294 -0
  10. package/dist/chunk-2M6WXO73.js +38 -0
  11. package/dist/chunk-2RX7PI2Y.js +166 -0
  12. package/dist/chunk-2XM6PYQQ.js +199 -0
  13. package/dist/chunk-3G4YI4ZU.js +16 -0
  14. package/dist/chunk-3GTZ2OON.js +362 -0
  15. package/dist/chunk-3QAKDIEU.js +108 -0
  16. package/dist/chunk-47QE246J.js +6115 -0
  17. package/dist/chunk-4GZXS6S2.js +5401 -0
  18. package/dist/chunk-4PJADZRR.js +545 -0
  19. package/dist/chunk-4Q3NN7VF.js +32 -0
  20. package/dist/chunk-4QUQEBFT.js +143 -0
  21. package/dist/chunk-4SKZDI62.js +22 -0
  22. package/dist/chunk-4SVJNVEE.js +80 -0
  23. package/dist/chunk-52R2YXP5.js +80 -0
  24. package/dist/chunk-577AJVRS.js +44694 -0
  25. package/dist/chunk-5F3RJCHB.js +45 -0
  26. package/dist/chunk-5IALSMZ2.js +34 -0
  27. package/dist/chunk-5KTOPOEP.js +174 -0
  28. package/dist/chunk-5MI2SEV5.js +242 -0
  29. package/dist/chunk-5XDNUJ4P.js +2743 -0
  30. package/dist/chunk-5XN76FTF.js +22 -0
  31. package/dist/chunk-5YIBJXGB.js +2007 -0
  32. package/dist/chunk-62YMDXY6.js +38 -0
  33. package/dist/chunk-65C57N7P.js +116 -0
  34. package/dist/chunk-67J3VZBA.js +120 -0
  35. package/dist/chunk-6EDQE7GO.js +27809 -0
  36. package/dist/chunk-6GNS32SI.js +285 -0
  37. package/dist/chunk-6GWHKMQR.js +405 -0
  38. package/dist/chunk-6JLPXDWN.js +7923 -0
  39. package/dist/chunk-6TJCUYC5.js +22 -0
  40. package/dist/chunk-6VBXAGJX.js +234 -0
  41. package/dist/chunk-73VPWF5R.js +415 -0
  42. package/dist/chunk-76WKMA4J.js +14 -0
  43. package/dist/chunk-7DUDLVFJ.js +52 -0
  44. package/dist/chunk-7EFILTCI.js +67 -0
  45. package/dist/chunk-7EKESFWV.js +130 -0
  46. package/dist/chunk-7F2RUWPU.js +101 -0
  47. package/dist/chunk-7GB4ZRE2.js +378 -0
  48. package/dist/chunk-7TGYNOXD.js +189 -0
  49. package/dist/chunk-7UKVYFQ2.js +2078 -0
  50. package/dist/chunk-7URGP4DD.js +102 -0
  51. package/dist/chunk-7YYEKTYF.js +2522 -0
  52. package/dist/chunk-AJJK7GLO.js +252 -0
  53. package/dist/chunk-AKJTKMXU.js +25 -0
  54. package/dist/chunk-APSVL2AI.js +344 -0
  55. package/dist/chunk-AWECWW5Y.js +3206 -0
  56. package/dist/chunk-AY2IUF4K.js +5071 -0
  57. package/dist/chunk-B2VSVN4P.js +34 -0
  58. package/dist/chunk-B3O52AUQ.js +275 -0
  59. package/dist/chunk-B7434AE2.js +104 -0
  60. package/dist/chunk-BDEKREZH.js +155 -0
  61. package/dist/chunk-BJPMKJTL.js +1428 -0
  62. package/dist/chunk-BMCKL3VQ.js +324 -0
  63. package/dist/chunk-BMHGA7WD.js +25 -0
  64. package/dist/chunk-BUYJL3GJ.js +287 -0
  65. package/dist/chunk-BXIX7S7O.js +32 -0
  66. package/dist/chunk-CHC5FKTU.js +26 -0
  67. package/dist/chunk-CITDNDIZ.js +53 -0
  68. package/dist/chunk-CIUHAHM6.js +70 -0
  69. package/dist/chunk-CNKGYDMG.js +334 -0
  70. package/dist/chunk-CRE4BJHM.js +408 -0
  71. package/dist/chunk-D3PO4DOZ.js +261 -0
  72. package/dist/chunk-DAQBIK5G.js +47 -0
  73. package/dist/chunk-DDAHCPGA.js +212 -0
  74. package/dist/chunk-DPHCFZ7W.js +374 -0
  75. package/dist/chunk-DZRQDNPT.js +34 -0
  76. package/dist/chunk-E3JYO547.js +46 -0
  77. package/dist/chunk-E3Z67HRK.js +104 -0
  78. package/dist/chunk-EADP3PEN.js +450 -0
  79. package/dist/chunk-EX6ZXS5K.js +169 -0
  80. package/dist/chunk-EZIUFEN6.js +27 -0
  81. package/dist/chunk-F2FOQLJ7.js +430 -0
  82. package/dist/chunk-F7UQR4ZX.js +149 -0
  83. package/dist/chunk-F7YL2RZ4.js +94 -0
  84. package/dist/chunk-FEZE6NIA.js +69 -0
  85. package/dist/chunk-FJCFYKVO.js +1014 -0
  86. package/dist/chunk-FLOEZA6K.js +29 -0
  87. package/dist/chunk-FMKKVWZD.js +133 -0
  88. package/dist/chunk-FNHSVBRA.js +48 -0
  89. package/dist/chunk-FOGG4AUR.js +114 -0
  90. package/dist/chunk-FPGVOSOG.js +41 -0
  91. package/dist/chunk-FQSRHTTC.js +49 -0
  92. package/dist/chunk-FR7JPYBD.js +182 -0
  93. package/dist/chunk-FTV6I76U.js +211 -0
  94. package/dist/chunk-FV5YFR6I.js +540 -0
  95. package/dist/chunk-FZ2E5LGK.js +54 -0
  96. package/dist/chunk-FZL2HNWP.js +531 -0
  97. package/dist/chunk-G2E5MNYP.js +549 -0
  98. package/dist/chunk-G5SFOH7P.js +256 -0
  99. package/dist/chunk-GFXLPJWY.js +53 -0
  100. package/dist/chunk-GR6YKM55.js +480 -0
  101. package/dist/chunk-GXJVY6WT.js +250 -0
  102. package/dist/chunk-GZ4TKR3Q.js +928 -0
  103. package/dist/chunk-HB6XSGI6.js +131 -0
  104. package/dist/chunk-HE4ZQXZM.js +396 -0
  105. package/dist/chunk-HHUFVJF7.js +1019 -0
  106. package/dist/chunk-HKTUIMH4.js +76 -0
  107. package/dist/chunk-HUZQDKQK.js +48 -0
  108. package/dist/chunk-I7IWQIEB.js +58 -0
  109. package/dist/chunk-IDGSU7JF.js +1496 -0
  110. package/dist/chunk-ILFKECGI.js +69 -0
  111. package/dist/chunk-ISNZYKAS.js +53 -0
  112. package/dist/chunk-IUD3ME4E.js +251 -0
  113. package/dist/chunk-IV7BCWWN.js +101 -0
  114. package/dist/chunk-IZNSAEBX.js +164 -0
  115. package/dist/chunk-J5LHDJU4.js +400 -0
  116. package/dist/chunk-JAA53T23.js +172 -0
  117. package/dist/chunk-JF2NSTFO.js +47 -0
  118. package/dist/chunk-JMSEEBN4.js +41 -0
  119. package/dist/chunk-JQ7XQPQS.js +273 -0
  120. package/dist/chunk-KC5DROFC.js +16667 -0
  121. package/dist/chunk-KIAI6PWL.js +36 -0
  122. package/dist/chunk-KIHOIVST.js +18 -0
  123. package/dist/chunk-KM2FBM3T.js +659 -0
  124. package/dist/chunk-KQDZXGNR.js +14 -0
  125. package/dist/chunk-L4VJ4ETL.js +41 -0
  126. package/dist/chunk-LDKUC2QJ.js +49 -0
  127. package/dist/chunk-LK44ULGI.js +2043 -0
  128. package/dist/chunk-LRS573EX.js +104 -0
  129. package/dist/chunk-LTQANUDH.js +119 -0
  130. package/dist/chunk-LVGBKKSM.js +282 -0
  131. package/dist/chunk-MF7QH4AX.js +162 -0
  132. package/dist/chunk-MGVYVW7Q.js +915 -0
  133. package/dist/chunk-MH5OCRUM.js +240 -0
  134. package/dist/chunk-MKFYQQ5Q.js +36 -0
  135. package/dist/chunk-MKRBG5EF.js +1142 -0
  136. package/dist/chunk-MTAUZW2Z.js +2504 -0
  137. package/dist/chunk-MTEBM4Y4.js +39 -0
  138. package/dist/chunk-N3NBWIYQ.js +48 -0
  139. package/dist/chunk-N4QZJJVB.js +3851 -0
  140. package/dist/chunk-NGPU2ARF.js +1726 -0
  141. package/dist/chunk-NIXVDQVO.js +2929 -0
  142. package/dist/chunk-NNUASOAA.js +34 -0
  143. package/dist/chunk-NPCD54I7.js +226 -0
  144. package/dist/chunk-OEI7LVRP.js +856 -0
  145. package/dist/chunk-OGRWQ562.js +18 -0
  146. package/dist/chunk-OIU657QQ.js +95 -0
  147. package/dist/chunk-OJLRFGBP.js +128 -0
  148. package/dist/chunk-OS7PQ35Z.js +391 -0
  149. package/dist/chunk-OSGQW2Z6.js +104 -0
  150. package/dist/chunk-P3TKKBAH.js +131 -0
  151. package/dist/chunk-PEF5OEMB.js +163 -0
  152. package/dist/chunk-PGKHJYOB.js +706 -0
  153. package/dist/chunk-PIVKU64W.js +688 -0
  154. package/dist/chunk-PKCMRPPB.js +109 -0
  155. package/dist/chunk-QICFHVRW.js +15 -0
  156. package/dist/chunk-QKEFZRHS.js +166 -0
  157. package/dist/chunk-QWVBEK4P.js +113 -0
  158. package/dist/chunk-R4TBNKKC.js +3217 -0
  159. package/dist/chunk-R64GLVBO.js +2919 -0
  160. package/dist/chunk-R6B6XAKK.js +56 -0
  161. package/dist/chunk-R6RY4Q5T.js +51 -0
  162. package/dist/chunk-RK6MKKKP.js +471 -0
  163. package/dist/chunk-ROTY5J2L.js +25 -0
  164. package/dist/chunk-RRVT4MPS.js +150 -0
  165. package/dist/chunk-SS66Q4VE.js +231 -0
  166. package/dist/chunk-T4RTWMJD.js +310 -0
  167. package/dist/chunk-T6USVBEJ.js +105 -0
  168. package/dist/chunk-TM7LC37P.js +4044 -0
  169. package/dist/chunk-TV45EUGM.js +51 -0
  170. package/dist/chunk-TZDSDDSV.js +233 -0
  171. package/dist/chunk-UBWCUP3G.js +55 -0
  172. package/dist/chunk-UF7TAFJM.js +906 -0
  173. package/dist/chunk-UR7RMZ3R.js +19943 -0
  174. package/dist/chunk-UYYN2IUZ.js +1611 -0
  175. package/dist/chunk-V2TH46ZY.js +66 -0
  176. package/dist/chunk-VKMTFIWS.js +315 -0
  177. package/dist/chunk-VOGCSYOI.js +16 -0
  178. package/dist/chunk-W5OYJMBT.js +41 -0
  179. package/dist/chunk-WARBF2KY.js +296 -0
  180. package/dist/chunk-WGZWR4RF.js +130 -0
  181. package/dist/chunk-WLIIQ2A4.js +18 -0
  182. package/dist/chunk-X4W4XXWP.js +134 -0
  183. package/dist/chunk-XB5RFZHH.js +1217 -0
  184. package/dist/chunk-XEG3FE2R.js +766 -0
  185. package/dist/chunk-XIWYUQZQ.js +583 -0
  186. package/dist/chunk-XKS6THI5.js +31 -0
  187. package/dist/chunk-XKZHAD6Y.js +184 -0
  188. package/dist/chunk-XNYNEEBR.js +214 -0
  189. package/dist/chunk-XPCWQXTY.js +37 -0
  190. package/dist/chunk-XPEEICAO.js +325 -0
  191. package/dist/chunk-XQ3YIV5R.js +3507 -0
  192. package/dist/chunk-XRO65C7V.js +1079 -0
  193. package/dist/chunk-XTVDAHH2.js +203 -0
  194. package/dist/chunk-XZRON6IV.js +131 -0
  195. package/dist/chunk-Y4BRGOJR.js +523 -0
  196. package/dist/chunk-Y5PZHS4K.js +3898 -0
  197. package/dist/chunk-Y7KBQ4BD.js +230 -0
  198. package/dist/chunk-YFSSNGLR.js +277 -0
  199. package/dist/chunk-YGKYFMSL.js +60 -0
  200. package/dist/chunk-YGR6OCHQ.js +345 -0
  201. package/dist/chunk-YIEOFHOL.js +30 -0
  202. package/dist/chunk-YLAJAI2W.js +180 -0
  203. package/dist/chunk-YMOJD5BO.js +50 -0
  204. package/dist/chunk-YPBQNJHA.js +33 -0
  205. package/dist/chunk-YPIEYQF4.js +307 -0
  206. package/dist/chunk-YVLMBAYE.js +221 -0
  207. package/dist/chunk-YXJ4XOHF.js +376 -0
  208. package/dist/chunk-ZE3P35DA.js +1247 -0
  209. package/dist/chunk-ZONE6E3Z.js +32 -0
  210. package/dist/chunk-ZP4FJHR4.js +95 -0
  211. package/dist/chunk-ZZXF6OOJ.js +119 -0
  212. package/dist/files.json +1976 -0
  213. package/dist/fixtures/forge/README.md +19 -0
  214. package/dist/fixtures/forge/expected/discrepancies.yaml +54 -0
  215. package/dist/fixtures/forge/expected/inputs.yaml +38 -0
  216. package/dist/fixtures/forge/expected/scan.yaml +342 -0
  217. package/dist/fixtures/forge/inputs/diagrams/forge-context.drawio +23 -0
  218. package/dist/fixtures/forge/inputs/partner-specs/northwind-pay-openapi.yaml +11 -0
  219. package/dist/fixtures/forge/inputs/tickets/ado-stories.json +4 -0
  220. package/dist/fixtures/forge/inputs/tickets/closed-service-requests.json +5 -0
  221. package/dist/fixtures/forge/inputs/wiki/integration-patterns.md +11 -0
  222. package/dist/fixtures/forge/inputs/wiki/ledger-solution-spec.md +9 -0
  223. package/dist/fixtures/forge/inputs/wiki/snow-firewall-request.md +4 -0
  224. package/dist/fixtures/forge/metarepo/judgments/reaches/84af5b6af24f7ca8c23013f3.yaml +17 -0
  225. package/dist/fixtures/forge/metarepo/judgments/reaches/c3917555edebddce8cecb647.yaml +17 -0
  226. package/dist/fixtures/forge/metarepo/judgments/reaches/c5fafd6601f8ca9e34e0bbd0.yaml +17 -0
  227. package/dist/fixtures/forge/metarepo/org-pack/agents/architecture-critic.yaml +9 -0
  228. package/dist/fixtures/forge/metarepo/org-pack/agents/story-writer.yaml +10 -0
  229. package/dist/fixtures/forge/metarepo/org-pack/checklists/architecture.yaml +115 -0
  230. package/dist/fixtures/forge/metarepo/org-pack/dialects/forge.yaml +111 -0
  231. package/dist/fixtures/forge/metarepo/org-pack/gates.yaml +22 -0
  232. package/dist/fixtures/forge/metarepo/org-pack/pack.yaml +11 -0
  233. package/dist/fixtures/forge/metarepo/org-pack/patterns/A.EB.PUB.yaml +12 -0
  234. package/dist/fixtures/forge/metarepo/org-pack/patterns/D.JDBC.yaml +12 -0
  235. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.DIR.BFF.yaml +12 -0
  236. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.SOR.yaml +13 -0
  237. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.VND.yaml +14 -0
  238. package/dist/fixtures/forge/metarepo/org-pack/process/change-templates/feature.md +37 -0
  239. package/dist/fixtures/forge/metarepo/org-pack/process/skills/add-forge-endpoint/SKILL.md +17 -0
  240. package/dist/fixtures/forge/metarepo/org-pack/process/snow/firewall-rule.yaml +14 -0
  241. package/dist/fixtures/forge/metarepo/org-pack/process/snow/gateway-route.yaml +13 -0
  242. package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/profile.yaml +12 -0
  243. package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/repos.manifest.yaml +44 -0
  244. package/dist/fixtures/forge/metarepo/org-pack/roles.yaml +14 -0
  245. package/dist/fixtures/forge/metarepo/org-pack/runtime.yaml +14 -0
  246. package/dist/fixtures/forge/metarepo/org-pack/sources.yaml +3 -0
  247. package/dist/fixtures/forge/repos/forge-events/topics/payments.initiated.yaml +4 -0
  248. package/dist/fixtures/forge/repos/forge-events/topics/transfers.completed.yaml +4 -0
  249. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/ledger-v1.xml +3 -0
  250. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/SpikeArrest.xml +3 -0
  251. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/VerifyOAuth.xml +4 -0
  252. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/proxies/default.xml +14 -0
  253. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/targets/ledger.xml +5 -0
  254. package/dist/fixtures/forge/repos/forge-infra/alerts/ledger-api.yaml +5 -0
  255. package/dist/fixtures/forge/repos/forge-infra/k8s/ledger-api.yaml +15 -0
  256. package/dist/fixtures/forge/repos/forge-infra/k8s/portal-bff.yaml +7 -0
  257. package/dist/fixtures/forge/repos/forge-infra/terraform/ledger-db.tf +9 -0
  258. package/dist/fixtures/forge/repos/forge-ledger/api/ledger-openapi.yaml +31 -0
  259. package/dist/fixtures/forge/repos/forge-ledger/forge.yaml +4 -0
  260. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEndpoints.java +13 -0
  261. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEvents.java +11 -0
  262. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/NorthwindClient.java +10 -0
  263. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/application.yml +3 -0
  264. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V1__create_account.sql +5 -0
  265. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V2__create_entry.sql +7 -0
  266. package/dist/fixtures/forge/repos/forge-portal-bff/pom.xml +1 -0
  267. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/AuditPublisher.java +12 -0
  268. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/BalanceController.java +16 -0
  269. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/LedgerClient.java +13 -0
  270. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/PaymentEvents.java +13 -0
  271. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/resources/application.yml +8 -0
  272. package/dist/fixtures/forge/repos/forge-portal-ui/package.json +1 -0
  273. package/dist/fixtures/forge/repos/forge-portal-ui/src/api/balance.ts +5 -0
  274. package/dist/fixtures/forge/repos/forge-reports-job/src/main/java/forge/reports/DailyEntriesJob.java +19 -0
  275. package/dist/fixtures/forge/repos/forge-reports-job/src/main/resources/application.yml +3 -0
  276. package/dist/fixtures/forge-change/README.md +41 -0
  277. package/dist/fixtures/forge-change/expected/findings.yaml +301 -0
  278. package/dist/fixtures/forge-change/expected/stories.yaml +101 -0
  279. package/dist/fixtures/forge-change/judgments/personal-data/0b5f3dbf5257a22275d8c74b.yaml +18 -0
  280. package/dist/fixtures/forge-change/judgments/personal-data/2759a66770134c417440bf2d.yaml +18 -0
  281. package/dist/fixtures/forge-change/judgments/personal-data/31b1ea2f14d0737f1aca79fd.yaml +18 -0
  282. package/dist/fixtures/forge-change/judgments/personal-data/49afd70c08228e65ad6ca1ed.yaml +18 -0
  283. package/dist/fixtures/forge-change/judgments/personal-data/761cabcb8a39f5e5866d2dd6.yaml +18 -0
  284. package/dist/fixtures/forge-change/judgments/personal-data/adae902b90cc8ffa0c765145.yaml +18 -0
  285. package/dist/fixtures/forge-change/judgments/personal-data/ba11bb933105ec9493e065dd.yaml +18 -0
  286. package/dist/fixtures/forge-change/judgments/personal-data/bdbcd1cdac3021c68063c3e7.yaml +18 -0
  287. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/brief.md +35 -0
  288. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/change.yaml +120 -0
  289. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/data.md +18 -0
  290. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/design.md +29 -0
  291. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/interfaces.md +17 -0
  292. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/mappings.md +26 -0
  293. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/proposal.md +35 -0
  294. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/snow.md +12 -0
  295. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/specs/transfer-limits/spec.md +19 -0
  296. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s1-refuse-over-limit.md +17 -0
  297. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s2-show-remaining.md +16 -0
  298. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s3-audit-refusals.md +18 -0
  299. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s4-velocity-check.md +16 -0
  300. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories.md +8 -0
  301. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/tasks.md +12 -0
  302. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/ux.md +7 -0
  303. package/dist/fixtures/forge-change/org-pack/agents/code-and-test-critic.yaml +13 -0
  304. package/dist/fixtures/forge-change/org-pack/agents/complete-critic.yaml +12 -0
  305. package/dist/fixtures/forge-change/org-pack/agents/safe-critic.yaml +12 -0
  306. package/dist/fixtures/forge-change/org-pack/agents/ship-critic.yaml +11 -0
  307. package/dist/fixtures/forge-change/org-pack/agents/true-critic.yaml +11 -0
  308. package/dist/fixtures/forge-change/org-pack/checklists/review.yaml +54 -0
  309. package/dist/fixtures/forge-change/org-pack/gates.yaml +25 -0
  310. package/dist/fixtures/forge-change/org-pack/teams/team-ledger/checklists/ledger-team.yaml +227 -0
  311. package/dist/fixtures/forge-change/recordings/complete-critic/2ad84f84bf39c1d5412697e69fe23034d6983ec45a00314bf0975e627589a3c5.json +12 -0
  312. package/dist/fixtures/forge-change/recordings/complete-critic/417c98d8e54a4387d0fd93441c49f44c2868958739070d855c1dce0c41e24db3.json +12 -0
  313. package/dist/fixtures/forge-change/recordings/complete-critic/50203ee22e9cb3ef047295edb6538fe7d5695e1e4b139f3c929013dc6ce47021.json +12 -0
  314. package/dist/fixtures/forge-change/recordings/complete-critic/89f18d67f5d9c325bf35e2a9e020f9ddb6ee13b8523315037f0905cc57c040b1.json +12 -0
  315. package/dist/fixtures/forge-change/recordings/complete-critic/b4097867d26ae8eadc8b9efa8cdd86897013358035f0b40086c299a59c4ba121.json +12 -0
  316. package/dist/fixtures/forge-change/recordings/safe-critic/302d06f49664dd67ad2e21ab9cf74c1b0f7d3f750709c6ed8eff2b70983274e2.json +12 -0
  317. package/dist/fixtures/forge-change/recordings/safe-critic/32f1049c9a5ab4a759543290db4644ec6e221cc45fdfdcf06193837c6a8ce0b9.json +12 -0
  318. package/dist/fixtures/forge-change/recordings/safe-critic/4e4a84bfc04b9f26ca4250319a879901ff7a1c081c71e46a117675fee05026b0.json +12 -0
  319. package/dist/fixtures/forge-change/recordings/safe-critic/604af0fcdd6df6b76208fa88305fdc15c37606c2a4d1ae816477e46ac8c2dd04.json +12 -0
  320. package/dist/fixtures/forge-change/recordings/safe-critic/f0bf50af11f14c50d07904f0dffe1c8c20fb0cd89770645a8824c1d30a443955.json +12 -0
  321. package/dist/fixtures/forge-change/recordings/ship-critic/350954b58833b2c04880c67db45a1b328b7fd541d9f0d943b63905b8875488a6.json +12 -0
  322. package/dist/fixtures/forge-change/recordings/ship-critic/4af95c6c96a206777cec9de1f9c2d8c55a36ddc9b8db2f81d6eb83217b835efa.json +12 -0
  323. package/dist/fixtures/forge-change/recordings/ship-critic/76c34522a49cf7587a4e5689a5030d384603fa780b8aba97d27815cbc829683e.json +12 -0
  324. package/dist/fixtures/forge-change/recordings/ship-critic/a3b2cd1ace48587e5994333db03b34c3a0f9dec4f1932f1730ddfb687f6918c8.json +12 -0
  325. package/dist/fixtures/forge-change/recordings/ship-critic/de288a4fa64d0fc20890f9a787080ce6eac5203b7b9b72d884df11e8cf111835.json +12 -0
  326. package/dist/fixtures/forge-change/recordings/story-writer/1ddb00eac2aaf91a5ec5d9dfd220116be9f75aec6546a4a3a3b050ed89af2864.json +12 -0
  327. package/dist/packages/assistant-kit/frameworks-kit/README.md +86 -0
  328. package/dist/packages/assistant-kit/frameworks-kit/checklist.md +11 -0
  329. package/dist/packages/assistant-kit/frameworks-kit/examples/tide-lantern.yaml +56 -0
  330. package/dist/packages/assistant-kit/frameworks-kit/examples/tide-platform.yaml +43 -0
  331. package/dist/packages/assistant-kit/frameworks-kit/prompts/write-framework-model.md +12 -0
  332. package/dist/packages/assistant-kit/kit/README.md +98 -0
  333. package/dist/packages/assistant-kit/kit/c2-reference.md +334 -0
  334. package/dist/packages/assistant-kit/kit/checklist.md +39 -0
  335. package/dist/packages/assistant-kit/kit/examples/house-http-client.yaml +102 -0
  336. package/dist/packages/assistant-kit/kit/examples/tide-apigee.yaml +56 -0
  337. package/dist/packages/assistant-kit/kit/examples/tide-apim.yaml +32 -0
  338. package/dist/packages/assistant-kit/kit/examples/tide-kong.yaml +44 -0
  339. package/dist/packages/assistant-kit/kit/prompts/write-dialect.md +34 -0
  340. package/dist/packages/assistant-kit/kit/worked-example.md +198 -0
  341. package/dist/packages/conformance/sample/README.md +4 -0
  342. package/dist/packages/conformance/sample/inputs/notes.md +3 -0
  343. package/dist/packages/conformance/sample/inputs/systems.csv +3 -0
  344. package/dist/packages/conformance/sample/repo/api/greeter.proto +6 -0
  345. package/dist/packages/conformance/sample/repo/api/openapi.yaml +10 -0
  346. package/dist/packages/conformance/sample/repo/api/schema.graphql +3 -0
  347. package/dist/packages/conformance/sample/repo/db/V1__create_greeting.sql +4 -0
  348. package/dist/packages/conformance/sample/repo/package.json +7 -0
  349. package/dist/packages/conformance/sample/repo/src/main/java/sample/HelloController.java +10 -0
  350. package/dist/packages/conformance/sample/repo/web/app.ts +4 -0
  351. package/dist/packages/evals/datasets/critic-lenses.yaml +62 -0
  352. package/dist/packages/evals/datasets/dialect-writer.yaml +14 -0
  353. package/dist/packages/evals/datasets/feature-namer.yaml +34 -0
  354. package/dist/packages/evals/datasets/glossary-definer.yaml +25 -0
  355. package/dist/packages/evals/datasets/story-writer.yaml +13 -0
  356. package/dist/packages/evals/datasets/template-writer.yaml +16 -0
  357. package/dist/packages/evals/datasets/test-writer.yaml +18 -0
  358. package/dist/packages/executors/reference/reference-executor.mjs +233 -0
  359. package/dist/packages/extractors/dialects/argocd.yaml +45 -0
  360. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AccountResource.java +47 -0
  361. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AuditClient.java +12 -0
  362. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/LedgerClient.java +17 -0
  363. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/LedgerClient.java +14 -0
  364. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/RatesClient.java +11 -0
  365. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/StatementController.java +36 -0
  366. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/resources/application.yml +7 -0
  367. package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/java/forge/fraud/FraudScorer.java +27 -0
  368. package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/resources/application.properties +4 -0
  369. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/api.tf +38 -0
  370. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/main.tf +95 -0
  371. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/terraform.tfvars +1 -0
  372. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/variables.tf +4 -0
  373. package/dist/packages/extractors/dialects/fixtures/terraform-azure/forge-azure-infra/main.tf +102 -0
  374. package/dist/packages/extractors/dialects/fixtures/terraform-gcp/forge-gcp-infra/main.tf +51 -0
  375. package/dist/packages/extractors/dialects/harness.yaml +101 -0
  376. package/dist/packages/extractors/dialects/jaxrs.yaml +155 -0
  377. package/dist/packages/extractors/dialects/micronaut.yaml +207 -0
  378. package/dist/packages/extractors/dialects/quarkus-reactive-messaging.yaml +158 -0
  379. package/dist/packages/extractors/dialects/tekton.yaml +71 -0
  380. package/dist/packages/extractors/dialects/terraform-aws.yaml +267 -0
  381. package/dist/packages/extractors/dialects/terraform-azure.yaml +212 -0
  382. package/dist/packages/extractors/dialects/terraform-gcp.yaml +109 -0
  383. package/dist/packages/extractors/grammars/README.md +11 -0
  384. package/dist/packages/extractors/grammars/tree-sitter-groovy.LICENSE +21 -0
  385. package/dist/packages/extractors/grammars/tree-sitter-groovy.wasm +0 -0
  386. package/dist/packages/extractors/grammars/vendored.json +11 -0
  387. package/dist/packages/learn/lessons/architect-diagrams-and-code.yaml +69 -0
  388. package/dist/packages/learn/lessons/business-analyst-story-bar.yaml +94 -0
  389. package/dist/packages/learn/lessons/delivery-lead-release-readiness.yaml +44 -0
  390. package/dist/packages/learn/lessons/designer-features-in-user-words.yaml +57 -0
  391. package/dist/packages/learn/lessons/developer-find-your-way.yaml +60 -0
  392. package/dist/packages/learn/lessons/everyone-first-hour.yaml +74 -0
  393. package/dist/packages/learn/lessons/platform-lead-coverage-and-defences.yaml +58 -0
  394. package/dist/packages/learn/lessons/product-owner-first-change.yaml +167 -0
  395. package/dist/packages/learn/lessons/qa-tests-and-trace.yaml +53 -0
  396. package/dist/packages/learn/lessons/team-lead-initiative.yaml +146 -0
  397. package/dist/packages/naysayer/constitution/constitution.yaml +305 -0
  398. package/dist/packages/naysayer/starter/review.yaml +256 -0
  399. package/dist/packages/sdk/npm/index.js +9780 -0
  400. package/dist/packages/speckit/rules/drift.yaml +78 -0
  401. package/dist/packages/taskrun/rules/conform.yaml +38 -0
  402. package/dist/packages/testgen/rules/trace.yaml +49 -0
  403. package/dist/packages/ui/dist/assets/elk-api-Mo5w5xCa.js +2 -0
  404. package/dist/packages/ui/dist/assets/elk-worker.min--dAJroGl.js +6401 -0
  405. package/dist/packages/ui/dist/assets/elk-worker.min-DdYmS5kP.js +2 -0
  406. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  407. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  408. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
  409. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
  410. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  411. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  412. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  413. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  414. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
  415. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
  416. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  417. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  418. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  419. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  420. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
  421. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
  422. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  423. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  424. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  425. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  426. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  427. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  428. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  429. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  430. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  431. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  432. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
  433. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
  434. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  435. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  436. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  437. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  438. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
  439. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
  440. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  441. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  442. package/dist/packages/ui/dist/assets/index-Bp3XhPHX.css +1 -0
  443. package/dist/packages/ui/dist/assets/index-DM212ZbV.js +29 -0
  444. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  445. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  446. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  447. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  448. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  449. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  450. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  451. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  452. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  453. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  454. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  455. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  456. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  457. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  458. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  459. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  460. package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  461. package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  462. package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-BtY48IV_.woff +0 -0
  463. package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-DhS7ScYx.woff2 +0 -0
  464. package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-BQQOj9BB.woff2 +0 -0
  465. package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-DBRwWuxA.woff +0 -0
  466. package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-CXCVEoA9.woff2 +0 -0
  467. package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-Dx02qI2_.woff +0 -0
  468. package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-BPDUZo87.woff2 +0 -0
  469. package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-e0Uj8ZlN.woff +0 -0
  470. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-BleIgkPp.woff +0 -0
  471. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-C9ZjJQAt.woff2 +0 -0
  472. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-BPaQ7tlD.woff +0 -0
  473. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-S6aYESQK.woff2 +0 -0
  474. package/dist/packages/ui/dist/favicon.svg +1 -0
  475. package/dist/packages/ui/dist/index.html +15 -0
  476. package/dist/third-party.json +575 -0
  477. package/dist/vendor/@fission-ai/openspec/bin/openspec.js +85986 -0
  478. package/dist/vendor/@fission-ai/openspec/package.json +82 -0
  479. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/schema.yaml +248 -0
  480. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/design.md +21 -0
  481. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/proposal.md +34 -0
  482. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/spec.md +13 -0
  483. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/tasks.md +11 -0
  484. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-c_sharp.wasm +0 -0
  485. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-go.wasm +0 -0
  486. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-java.wasm +0 -0
  487. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-javascript.wasm +0 -0
  488. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-kotlin.wasm +0 -0
  489. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-php.wasm +0 -0
  490. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-python.wasm +0 -0
  491. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-ruby.wasm +0 -0
  492. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-rust.wasm +0 -0
  493. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-scala.wasm +0 -0
  494. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-tsx.wasm +0 -0
  495. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-typescript.wasm +0 -0
  496. package/dist/vendor/web-tree-sitter/tree-sitter.wasm +0 -0
  497. package/package.json +36 -3
@@ -0,0 +1,1217 @@
1
+ import { createRequire as __atticusCreateRequire } from "node:module";
2
+ import { fileURLToPath as __atticusFileURLToPath } from "node:url";
3
+ var require = __atticusCreateRequire(import.meta.url);
4
+ var __atticusUrl = (p) => new URL("./" + p, import.meta.url).href;
5
+ var __atticusPath = (p) => __atticusFileURLToPath(__atticusUrl(p));
6
+ import {
7
+ changeWorktree,
8
+ handDown,
9
+ loadTask,
10
+ openTaskWorktree,
11
+ readChangeTasks
12
+ } from "./chunk-IDGSU7JF.js";
13
+ import {
14
+ buildEngineFor
15
+ } from "./chunk-LK44ULGI.js";
16
+ import {
17
+ slug,
18
+ writeGateRound
19
+ } from "./chunk-7YYEKTYF.js";
20
+ import {
21
+ conform,
22
+ readConformDeltas,
23
+ readTaskSteps,
24
+ renderTaskContext,
25
+ taskContext
26
+ } from "./chunk-KC5DROFC.js";
27
+ import {
28
+ readChangeFiles,
29
+ readRound,
30
+ roundsOf,
31
+ writeQuarantineItems
32
+ } from "./chunk-47QE246J.js";
33
+ import {
34
+ changeFolder,
35
+ changeStore
36
+ } from "./chunk-XQ3YIV5R.js";
37
+ import {
38
+ AdapterError,
39
+ createAdapters,
40
+ fileStepStore,
41
+ requireApproval
42
+ } from "./chunk-NGPU2ARF.js";
43
+ import {
44
+ scanEstate
45
+ } from "./chunk-AY2IUF4K.js";
46
+ import {
47
+ baseClonePath,
48
+ createGit,
49
+ toRepoRelative
50
+ } from "./chunk-PGKHJYOB.js";
51
+ import {
52
+ HandoffRuntime,
53
+ buildContextPack,
54
+ createRuntime,
55
+ quarantineItems,
56
+ toRunSummary
57
+ } from "./chunk-5XDNUJ4P.js";
58
+ import {
59
+ AgentDefinition,
60
+ ChecklistPack,
61
+ Finding,
62
+ RecordId,
63
+ RunSummary,
64
+ RuntimeKind,
65
+ api_exports,
66
+ changeBranch,
67
+ changesDirOf,
68
+ changesRelOf,
69
+ external_exports,
70
+ readRepoSpec,
71
+ require_dist,
72
+ runsDirOf,
73
+ runsRelOf,
74
+ stateDirOf,
75
+ taskBranch,
76
+ toCanonicalYaml
77
+ } from "./chunk-577AJVRS.js";
78
+ import {
79
+ writeFileAtomic
80
+ } from "./chunk-D3PO4DOZ.js";
81
+ import {
82
+ __toESM
83
+ } from "./chunk-TV45EUGM.js";
84
+
85
+ // packages/taskrun/dist/apply.js
86
+ import { mkdir, rm, writeFile } from "node:fs/promises";
87
+ import { dirname, join } from "node:path";
88
+ var FILE_FORMAT = `Give every file you change whole, in this form, and nothing else for code:
89
+
90
+ === file: <path from the repo root>
91
+ <the whole new content>
92
+ === end file
93
+
94
+ Delete a file with a line "=== delete: <path>". Write a short report of what you changed, and why, outside the blocks.`;
95
+ function refusedPath(path) {
96
+ if (!path || path.startsWith("/") || /^[A-Za-z]:/.test(path) || path.includes("\\"))
97
+ return `${path || "(empty)"} is not a relative path inside the repo`;
98
+ const parts = path.split("/");
99
+ if (parts.includes("..") || parts.includes("."))
100
+ return `${path} leaves the repo`;
101
+ if (parts[0] === ".git")
102
+ return `${path} is Git's own data`;
103
+ if (path === ".specify/memory/constitution.md")
104
+ return `${path} is generated from the org pack`;
105
+ return void 0;
106
+ }
107
+ function parseAnswer(output) {
108
+ const lines = output.replace(/\r\n/g, "\n").split("\n");
109
+ const changes = [];
110
+ const report = [];
111
+ const problems = [];
112
+ for (let i = 0; i < lines.length; i++) {
113
+ const del = /^=== delete:\s*(.+?)\s*$/.exec(lines[i]);
114
+ if (del) {
115
+ changes.push({ path: del[1] });
116
+ continue;
117
+ }
118
+ const open = /^=== file:\s*(.+?)\s*$/.exec(lines[i]);
119
+ if (!open) {
120
+ report.push(lines[i]);
121
+ continue;
122
+ }
123
+ const body = [];
124
+ let j = i + 1;
125
+ for (; j < lines.length && lines[j] !== "=== end file"; j++)
126
+ body.push(lines[j]);
127
+ if (j >= lines.length)
128
+ problems.push(`the block for ${open[1]} has no "=== end file" line`);
129
+ changes.push({ path: open[1], content: body.join("\n") + "\n" });
130
+ i = j;
131
+ }
132
+ for (const c of changes) {
133
+ const why = refusedPath(c.path);
134
+ if (why)
135
+ problems.push(why);
136
+ }
137
+ return { changes, report: report.join("\n").trim(), problems };
138
+ }
139
+ async function applyChanges(worktree, changes) {
140
+ for (const c of changes) {
141
+ const why = refusedPath(c.path);
142
+ if (why)
143
+ throw new Error(why);
144
+ }
145
+ for (const c of changes) {
146
+ const full = join(worktree, c.path);
147
+ if (c.content === void 0)
148
+ await rm(full, { force: true });
149
+ else {
150
+ await mkdir(dirname(full), { recursive: true });
151
+ await writeFile(full, c.content, "utf8");
152
+ }
153
+ }
154
+ return changes.map((c) => c.path);
155
+ }
156
+
157
+ // packages/taskrun/dist/commands.js
158
+ import { spawn } from "node:child_process";
159
+ function shellCommandRunner() {
160
+ return (command, cwd, o = {}) => new Promise((resolve) => {
161
+ const child = spawn(command, {
162
+ cwd,
163
+ shell: true,
164
+ env: { ...process.env, ...o.env },
165
+ windowsHide: true
166
+ });
167
+ let stdout = "";
168
+ let stderr = "";
169
+ const timer = setTimeout(() => child.kill(), o.timeoutMs ?? 30 * 6e4);
170
+ child.stdout.setEncoding("utf8").on("data", (d) => stdout += d);
171
+ child.stderr.setEncoding("utf8").on("data", (d) => stderr += d);
172
+ child.on("error", (e) => {
173
+ clearTimeout(timer);
174
+ resolve({ exitCode: null, stdout, stderr: stderr + e.message });
175
+ });
176
+ child.on("close", (code) => {
177
+ clearTimeout(timer);
178
+ resolve({ exitCode: code, stdout, stderr });
179
+ });
180
+ });
181
+ }
182
+
183
+ // packages/taskrun/dist/store.js
184
+ var import_yaml = __toESM(require_dist(), 1);
185
+ import { readdir, readFile } from "node:fs/promises";
186
+ import { join as join2 } from "node:path";
187
+ var TaskRunState = external_exports.enum([
188
+ /** Plan-only finished: tasks/<task>/plan.md is written. */
189
+ "planned",
190
+ /** Hand-off mode: the person's assistant is doing the step. */
191
+ "waiting",
192
+ /** Draft finished with a passing build, committed on the task branch. */
193
+ "built",
194
+ /** Draft finished but the repo has no build command, so nothing was checked. */
195
+ "unverified",
196
+ /** The PR from the task branch to the change branch is open. */
197
+ "pr-open",
198
+ /** The build still fails after the allowed fix rounds, or a PR can't be opened: a person takes over. */
199
+ "needs-person",
200
+ /** The AI run itself failed. */
201
+ "failed"
202
+ ]);
203
+ var RunLevel = external_exports.enum(["plan", "draft", "pr"]);
204
+ var BuildAttempt = external_exports.strictObject({
205
+ n: external_exports.number().int().positive(),
206
+ /** The AI fix run that came before this build, if any. */
207
+ fixRun: external_exports.string().optional(),
208
+ command: external_exports.string(),
209
+ exitCode: external_exports.number().int().nullable(),
210
+ passed: external_exports.boolean(),
211
+ /** Log path relative to the metarepo (.runs/...). */
212
+ log: external_exports.string(),
213
+ at: external_exports.string()
214
+ });
215
+ var TaskRunRecord = external_exports.strictObject({
216
+ schemaVersion: external_exports.literal(1),
217
+ change: RecordId,
218
+ task: RecordId,
219
+ repo: RecordId,
220
+ level: RunLevel,
221
+ runtime: RuntimeKind,
222
+ engine: external_exports.enum(["speckit", "atticus"]),
223
+ by: external_exports.string().min(1),
224
+ branch: external_exports.string(),
225
+ /** Task worktree, relative to the metarepo. */
226
+ worktree: external_exports.string(),
227
+ state: TaskRunState,
228
+ /** Every AI run, in order (the first is the main run, then fix runs). */
229
+ runs: external_exports.array(external_exports.string()).default([]),
230
+ /** The hand-off run Atticus waits on. */
231
+ waiting: external_exports.string().optional(),
232
+ attempts: external_exports.array(BuildAttempt).default([]),
233
+ /** Files the run changed in the worktree. */
234
+ changed: external_exports.array(external_exports.string()).default([]),
235
+ commit: external_exports.string().optional(),
236
+ pr: external_exports.strictObject({ number: external_exports.number().int().positive(), url: external_exports.string() }).optional(),
237
+ startedAt: external_exports.string(),
238
+ finishedAt: external_exports.string().optional(),
239
+ notes: external_exports.array(external_exports.string()).default([])
240
+ });
241
+ var LEADING = [
242
+ "schemaVersion",
243
+ "change",
244
+ "task",
245
+ "repo",
246
+ "level",
247
+ "runtime",
248
+ "engine",
249
+ "by",
250
+ "branch",
251
+ "worktree",
252
+ "state"
253
+ ];
254
+ var taskDir = (root, change, task) => join2(changeFolder(root, change), "tasks", task);
255
+ async function saveTaskRun(root, r) {
256
+ const v = TaskRunRecord.parse(r);
257
+ await writeFileAtomic(join2(taskDir(root, v.change, v.task), "task-run.yaml"), toCanonicalYaml(v, LEADING));
258
+ return v;
259
+ }
260
+ async function readTaskRun(root, change, task) {
261
+ const text = await readFile(join2(taskDir(root, change, task), "task-run.yaml"), "utf8").catch(() => void 0);
262
+ return text === void 0 ? void 0 : TaskRunRecord.parse((0, import_yaml.parse)(text));
263
+ }
264
+ async function saveRunSummary(root, change, task, s) {
265
+ const rel = `tasks/${task}/runs/${s.runId}.yaml`;
266
+ await writeFileAtomic(join2(changeFolder(root, change), rel), toCanonicalYaml(RunSummary.parse(s), ["schemaVersion", "runId"]));
267
+ return rel;
268
+ }
269
+ async function findWaitingTaskRun(root, runId) {
270
+ const changes = changesDirOf(root);
271
+ for (const c of (await readdir(changes, { withFileTypes: true }).catch(() => [])).filter((d) => d.isDirectory())) {
272
+ for (const t of (await readdir(join2(changes, c.name, "tasks"), { withFileTypes: true }).catch(() => [])).filter((d) => d.isDirectory())) {
273
+ const r = await readTaskRun(root, c.name, t.name).catch(() => void 0);
274
+ if (r?.waiting === runId)
275
+ return r;
276
+ }
277
+ }
278
+ return void 0;
279
+ }
280
+
281
+ // packages/taskrun/dist/prompt.js
282
+ import { readFile as readFile2 } from "node:fs/promises";
283
+ import { join as join3 } from "node:path";
284
+ var TASK_RUNNER = "task-runner";
285
+ function taskRunnerAgent(t) {
286
+ const own = t.ctx.orgPack.agents.find((a) => a.id === TASK_RUNNER);
287
+ if (own)
288
+ return own;
289
+ return AgentDefinition.parse({
290
+ schemaVersion: 1,
291
+ id: TASK_RUNNER,
292
+ role: "developer",
293
+ description: "Implements one task of a change in its repo, with tests, within the approved design.",
294
+ inputs: ["stories", "design", "interfaces", "data", "mappings", "skills", "repo-code"],
295
+ outputArtifact: "code",
296
+ tokenBudget: t.ctx.orgPack.runtime.budgets.defaultTokens,
297
+ allowedRuntimes: ["hand-off", "model", "headless-claude-code", "mock", "replay"]
298
+ });
299
+ }
300
+ function instructions(p) {
301
+ const { t } = p;
302
+ const branch = taskBranch(t.change.id, t.task.id);
303
+ const feature = p.engine === "speckit" ? `The task's Spec Kit feature is \`specs/${t.task.id}/\` (spec.md, plan.md, data-model.md, contracts/, tasks.md): follow it, and keep tasks.md's boxes up to date.` : `The task file is \`.atticus/tasks/${t.task.id}.md\`.`;
304
+ const common = [
305
+ `# Run with AI: task ${t.task.id} of change ${t.change.id}`,
306
+ "",
307
+ `Task: ${t.task.title}. Repo: ${t.repo.id} (component ${t.component}), branch \`${branch}\`.`,
308
+ feature,
309
+ "",
310
+ "Rules that always hold:",
311
+ "- Stay inside the approved design. If the work needs an interface, table or system the design doesn't list, don't add it: say so in your report as a question for the architect.",
312
+ "- Never push, merge, deploy or touch a protected branch; Atticus raises the pull request with a person's approval.",
313
+ "- Don't edit `.specify/memory/constitution.md`: it is generated from the org pack.",
314
+ "- needs.md (when the change has one) is what the organisation needs of this change: follow its standards and patterns for this task, its story and the whole change. Its requests and processes are a person's to raise, never yours. An item marked not yet verified was read from a wiki and no person has checked it: follow it, and say in your report if it looks wrong for this code."
315
+ ];
316
+ if (p.buildLog)
317
+ return [
318
+ ...common,
319
+ "",
320
+ `## Fix the build (attempt ${p.buildLog.attempt})`,
321
+ "",
322
+ `\`${p.buildLog.command}\` failed after your last change. Its log is in the data below. Fix the cause in the code or tests; don't weaken or delete a test to make it pass.`,
323
+ "",
324
+ p.oneShot ? FILE_FORMAT : "Edit the files in the worktree, then stop."
325
+ ].join("\n");
326
+ if (p.level === "plan")
327
+ return [
328
+ ...common,
329
+ "",
330
+ "## Plan only",
331
+ "",
332
+ "Change no code. Write the plan for this task in Markdown: the files to add or change with what changes in each, the tests to write for each acceptance criterion, the order of the work, risks, and open questions for the architect. Write only the plan."
333
+ ].join("\n");
334
+ return [
335
+ ...common,
336
+ "",
337
+ "## Draft the change",
338
+ "",
339
+ "Make the code and test changes the task needs, tested against every acceptance criterion. Atticus runs the build afterwards and sends failures back to you.",
340
+ "",
341
+ p.oneShot ? FILE_FORMAT : `Work in \`${p.worktreeRel}\` only. When you are done, write a short report of what you changed and why.`
342
+ ].join("\n");
343
+ }
344
+ async function readIf(path) {
345
+ return readFile2(path, "utf8").then((t) => t.replace(/\r\n/g, "\n"), () => void 0);
346
+ }
347
+ async function taskPack(p) {
348
+ const { t } = p;
349
+ const agent = taskRunnerAgent(t);
350
+ const levels = t.ctx.orgPack.pack?.classification ?? [
351
+ "public",
352
+ "internal",
353
+ "confidential",
354
+ "restricted"
355
+ ];
356
+ const skills = t.ctx.orgPack.skills.filter((s) => s.status === "active" && (s.appliesTo.repoTypes.length === 0 || s.appliesTo.repoTypes.includes(t.repo.type)));
357
+ const sources = [
358
+ {
359
+ id: "0-instructions",
360
+ kind: "instruction",
361
+ origin: "atticus/taskrun",
362
+ text: instructions(p),
363
+ classification: "public",
364
+ trusted: true
365
+ },
366
+ ...skills.map((s) => ({
367
+ id: `skill-${s.id}`,
368
+ kind: "skill",
369
+ origin: `org-pack/process/skills/${s.id}/SKILL.md`,
370
+ text: `## Skill: ${s.name}
371
+
372
+ ${s.body.trim()}`,
373
+ classification: "public",
374
+ trusted: true
375
+ }))
376
+ ];
377
+ const artifact = (rel, priority) => {
378
+ const d = t.files.docs.get(rel);
379
+ if (d)
380
+ sources.push({
381
+ id: rel,
382
+ kind: "artifact",
383
+ origin: `${changesRelOf(t.root)}/${t.change.id}/${rel}`,
384
+ text: d.raw,
385
+ classification: "internal",
386
+ priority
387
+ });
388
+ };
389
+ const context = await taskContext(t.root, t.change.id, t.task.id).catch(() => void 0);
390
+ if (context)
391
+ sources.push({
392
+ id: "task-context",
393
+ kind: "artifact",
394
+ origin: `atticus task context ${t.change.id} ${t.task.id}`,
395
+ text: renderTaskContext(context).replace(/\r\n/g, "\n"),
396
+ classification: "internal",
397
+ priority: 35
398
+ });
399
+ for (const s of t.task.stories)
400
+ artifact(`stories/${s}.md`, 30);
401
+ for (const a of ["design.md", "interfaces.md", "mappings.md", "data.md"])
402
+ artifact(a, 20);
403
+ const needs = await readIf(join3(t.root, ...changesRelOf(t.root).split("/"), t.change.id, "needs.md"));
404
+ if (needs !== void 0)
405
+ sources.push({
406
+ id: "needs.md",
407
+ kind: "artifact",
408
+ origin: `${changesRelOf(t.root)}/${t.change.id}/needs.md`,
409
+ text: needs,
410
+ classification: "internal",
411
+ priority: 25
412
+ });
413
+ const featureFiles = p.engine === "speckit" ? ["spec.md", "plan.md", "data-model.md", "tasks.md", "research.md", "quickstart.md"].map((f) => `specs/${t.task.id}/${f}`) : [`.atticus/tasks/${t.task.id}.md`];
414
+ for (const f of featureFiles) {
415
+ const text = await readIf(join3(p.worktree, f));
416
+ if (text !== void 0)
417
+ sources.push({
418
+ id: `repo:${f}`,
419
+ kind: "code",
420
+ origin: `${t.repo.id}:${f}`,
421
+ text,
422
+ classification: "internal",
423
+ priority: 40
424
+ });
425
+ }
426
+ const listed = await p.git(["ls-files"], p.worktree).then((r) => r.stdout.trim().split("\n").filter(Boolean), () => []);
427
+ if (listed.length)
428
+ sources.push({
429
+ id: "repo:files",
430
+ kind: "code",
431
+ origin: `${t.repo.id}:git ls-files`,
432
+ text: `Files in ${t.repo.id}:
433
+ ${listed.slice(0, 400).join("\n")}${listed.length > 400 ? `
434
+ (and ${listed.length - 400} more)` : ""}`,
435
+ classification: "internal",
436
+ priority: 10
437
+ });
438
+ if (p.buildLog)
439
+ sources.push({
440
+ id: `build-log-${p.buildLog.attempt}`,
441
+ kind: "document",
442
+ origin: `build: ${p.buildLog.command}`,
443
+ text: p.buildLog.text.split("\n").slice(-200).join("\n"),
444
+ classification: "internal",
445
+ priority: 50
446
+ });
447
+ return buildContextPack({
448
+ change: t.change.id,
449
+ agent: agent.id,
450
+ budget: t.ctx.orgPack.runtime.budgets.perAgent[agent.id] ?? agent.tokenBudget,
451
+ sources,
452
+ levels,
453
+ maxClassification: levels.includes("confidential") ? "confidential" : levels.at(-1),
454
+ now: p.now
455
+ });
456
+ }
457
+
458
+ // packages/taskrun/dist/run.js
459
+ import { existsSync as existsSync2 } from "node:fs";
460
+ import { mkdir as mkdir3, writeFile as writeFile2 } from "node:fs/promises";
461
+ import { join as join5 } from "node:path";
462
+
463
+ // packages/taskrun/dist/conform.js
464
+ var import_yaml2 = __toESM(require_dist(), 1);
465
+ import { createHash, randomBytes } from "node:crypto";
466
+ import { existsSync } from "node:fs";
467
+ import { mkdir as mkdir2, readdir as readdir2, readFile as readFile3, rm as rm2 } from "node:fs/promises";
468
+ import { join as join4 } from "node:path";
469
+ import { fileURLToPath } from "node:url";
470
+ var __atticus_import_meta_url = __atticusUrl("packages/taskrun/dist/conform.js");
471
+ var CONFORM_GATE = "conform";
472
+ var CONFORM_DIR = "conform";
473
+ var ConformError = class extends Error {
474
+ code;
475
+ constructor(code, message) {
476
+ super(message);
477
+ this.code = code;
478
+ this.name = "ConformError";
479
+ }
480
+ };
481
+ var stamp = () => (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
482
+ function conformScanDir(root, repo, commit2) {
483
+ const own = `${process.pid}-${randomBytes(4).toString("hex")}`;
484
+ return join4(stateDirOf(root), ".index", "conform", `${repo}-${commit2.slice(0, 12)}-${own}`);
485
+ }
486
+ function gitScanAt(root, git) {
487
+ return async (repo, commit2) => {
488
+ const base = baseClonePath(root, repo);
489
+ const dir = conformScanDir(root, repo, commit2);
490
+ await rm2(dir, { recursive: true, force: true });
491
+ await mkdir2(join4(dir, ".."), { recursive: true });
492
+ await git(["worktree", "add", "--detach", "--force", "--", dir, commit2], base);
493
+ try {
494
+ const s = await scanEstate({
495
+ root,
496
+ repos: [repo],
497
+ repoDir: () => dir,
498
+ repoState: async () => ({ commit: commit2, dirty: false })
499
+ });
500
+ const files = (await git(["ls-tree", "-r", "--name-only", commit2], base)).stdout.split("\n").map((l) => l.trim()).filter(Boolean);
501
+ return {
502
+ records: s.records,
503
+ files,
504
+ problems: s.problems.filter((p) => !p.repo || p.repo === repo).map((p) => `${p.repo ? `${p.repo}: ` : ""}${p.source}: ${p.message}`)
505
+ };
506
+ } finally {
507
+ await git(["worktree", "remove", "--force", "--", dir], base).catch(() => void 0);
508
+ await rm2(dir, { recursive: true, force: true }).catch(() => void 0);
509
+ await git(["worktree", "prune"], base).catch(() => void 0);
510
+ }
511
+ };
512
+ }
513
+ var RULES_FILE = fileURLToPath(new URL("../rules/conform.yaml", __atticus_import_meta_url));
514
+ async function loadConformRules() {
515
+ const pack = ChecklistPack.parse((0, import_yaml2.parse)(await readFile3(RULES_FILE, "utf8")));
516
+ return new Map(pack.rules.map((r) => [r.id, r]));
517
+ }
518
+ var FIX = {
519
+ missing: "Build what the step says on the branch, or change the target flow (atticus change architecture) if the design was wrong.",
520
+ "still-there": "Take the call out on the branch, or keep the step in the target flow if it should stay.",
521
+ unexpected: "Add a step that names it to the target flow if the change needs it, or take it out of the branch. Dismiss it as not relevant if it belongs elsewhere."
522
+ };
523
+ function conformFindingId(i) {
524
+ const column = i.check !== "column" ? "" : i.record ? `-${slug(i.record.split(".").pop())}` : `-${createHash("sha256").update(i.what).digest("hex").slice(0, 8)}`;
525
+ const subject = i.status === "unexpected" ? slug(i.record ?? i.what) : `${slug(i.flow ?? "")}-${i.item ?? "trigger"}${column}`;
526
+ return `conform-${i.status}-${i.check}-${subject}`.slice(0, 120).replace(/-+$/, "");
527
+ }
528
+ async function conformFindings(change, results, lines, now) {
529
+ const rules = await loadConformRules();
530
+ const out = [];
531
+ for (const r of results)
532
+ for (const i of r.items) {
533
+ if (i.status === "found")
534
+ continue;
535
+ const rule = rules.get(`conform.${i.status}`);
536
+ const artifact = i.flow ? `target-flows/${i.flow}.yaml` : "code";
537
+ const line = i.flow ? lines.get(`${i.flow}#${i.item ?? 0}`) : void 0;
538
+ const summary = i.what.length <= 200 ? i.what : `${i.what.slice(0, 197)}...`;
539
+ out.push(Finding.parse({
540
+ schemaVersion: 1,
541
+ id: conformFindingId(i),
542
+ kind: "issue",
543
+ change,
544
+ gate: CONFORM_GATE,
545
+ round: 1,
546
+ rule: rule.id,
547
+ layer: rule.layer,
548
+ lens: rule.lens,
549
+ severity: rule.severity,
550
+ artifact,
551
+ locator: i.flow ? line ? { line } : { heading: i.item ? `item ${i.item}` : "trigger" } : { record: i.record ?? r.repo },
552
+ summary,
553
+ why: rule.description ?? rule.title,
554
+ fix: { text: FIX[i.status] },
555
+ evidence: i.at.map((c) => c.source === "artifact" ? { source: "artifact", path: c.path, ...c.line ? { line: c.line } : {} } : {
556
+ source: "code",
557
+ repo: c.repo ?? r.repo,
558
+ path: c.path,
559
+ ...c.line ? { line: c.line } : {}
560
+ }),
561
+ waivable: rule.waivable,
562
+ state: "open",
563
+ createdAt: now
564
+ }));
565
+ }
566
+ return out;
567
+ }
568
+ async function readConformResults(root, change) {
569
+ const dir = join4(changeFolder(root, change), CONFORM_DIR);
570
+ const results = [];
571
+ const problems = [];
572
+ for (const f of (await readdir2(dir).catch(() => [])).sort()) {
573
+ if (!f.endsWith(".yaml"))
574
+ continue;
575
+ try {
576
+ const r = api_exports.ConformRepoResult.safeParse((0, import_yaml2.parse)(await readFile3(join4(dir, f), "utf8")));
577
+ if (r.success)
578
+ results.push(r.data);
579
+ else
580
+ problems.push(`${CONFORM_DIR}/${f}: ${r.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`);
581
+ } catch (e) {
582
+ problems.push(`${CONFORM_DIR}/${f}: ${e.message.split("\n")[0]}`);
583
+ }
584
+ }
585
+ return { results, problems };
586
+ }
587
+ async function deltasOf(root, change) {
588
+ const { deltas, problems } = await readConformDeltas(changeFolder(root, change));
589
+ const specs = /* @__PURE__ */ new Map();
590
+ const out = [];
591
+ for (const d of deltas) {
592
+ if (!specs.has(d.delta.repo))
593
+ specs.set(d.delta.repo, (await readRepoSpec(root, d.delta.repo, { cacheRoot: root })).flows);
594
+ const today = specs.get(d.delta.repo).find((f) => f.id === d.delta.flow);
595
+ if (d.delta.change !== "new" && !today)
596
+ problems.push(`${d.file}: ${d.delta.flow} isn't in ${d.delta.repo}'s spec, so the steps it ${d.delta.change === "remove" ? "removes" : "changes"} are checked without today's flow.`);
597
+ out.push(today ? { ...d, today } : d);
598
+ }
599
+ return { deltas: out, problems };
600
+ }
601
+ function linesOf(deltas) {
602
+ const m = /* @__PURE__ */ new Map();
603
+ for (const d of deltas) {
604
+ m.set(`${d.delta.flow}#0`, d.triggerLine);
605
+ d.stepLines.forEach((l, i) => m.set(`${d.delta.flow}#${i + 1}`, l));
606
+ }
607
+ return m;
608
+ }
609
+ async function conformChange(root, change, o = {}) {
610
+ await changeStore(root).read(change).catch(() => {
611
+ throw new ConformError("not-found", `There is no change ${change}.`);
612
+ });
613
+ const git = o.git ?? createGit();
614
+ const now = o.now ?? stamp();
615
+ const { deltas, problems } = await deltasOf(root, change);
616
+ if (!deltas.length)
617
+ return { results: [], problems, flows: 0 };
618
+ const tasks = await readTaskSteps(changeFolder(root, change));
619
+ let taskRepo;
620
+ if (o.task) {
621
+ const t = o.task.toLowerCase();
622
+ const listed = readChangeTasks(await readChangeFiles(changeFolder(root, change))).find((x) => x.id === t);
623
+ const flow = [...tasks].find(([, v]) => v === t)?.[0].split("#")[0];
624
+ taskRepo = listed?.repo ?? deltas.find((d) => d.delta.flow === flow)?.delta.repo;
625
+ if (!taskRepo)
626
+ throw new ConformError("not-found", `There is no task ${o.task} in ${change}'s tasks.md or stories.`);
627
+ }
628
+ const repos = o.repo ? [o.repo] : taskRepo ? [taskRepo] : [...new Set(deltas.map((d) => d.delta.repo))].sort();
629
+ if (o.repo && !deltas.some((d) => d.delta.repo === o.repo))
630
+ problems.push(`No target flow of ${change} is in ${o.repo}; only what it adds is checked.`);
631
+ const scanAt = o.scanAt ?? gitScanAt(root, git);
632
+ const results = [];
633
+ for (const repo of repos) {
634
+ const ref = o.ref ?? (o.task ? taskBranch(change, o.task.toLowerCase()) : changeBranch(change));
635
+ const base = baseClonePath(root, repo);
636
+ if (!existsSync(base))
637
+ throw new ConformError("refused", `There is no base clone of ${repo}; run atticus workspace sync first.`);
638
+ const commit2 = await git(["rev-parse", "--verify", "--quiet", `${ref}^{commit}`], base).then((x) => x.stdout.trim(), () => "");
639
+ if (!commit2) {
640
+ problems.push(`${repo} has no ${ref} yet, so there is no code to check: open the change (atticus workspace open ${change} --repos ${repo}) or name the branch with --ref.`);
641
+ continue;
642
+ }
643
+ const from = await git(["merge-base", commit2, "HEAD"], base).then((x) => x.stdout.trim() || commit2, () => commit2);
644
+ const after = await scanAt(repo, commit2);
645
+ const before = from === commit2 ? after : await scanAt(repo, from);
646
+ const scope = o.task ? [...tasks].filter(([, v]) => v === o.task.toLowerCase()).map(([k]) => ({ flow: k.split("#")[0], item: Number(k.split("#")[1]) })) : void 0;
647
+ const repoProblems = [.../* @__PURE__ */ new Set([...before.problems, ...after.problems])];
648
+ if (o.task && !scope?.length)
649
+ repoProblems.push(`The stories don't say which target-flow steps task ${o.task} builds, so every step of ${repo}'s target flows is checked.`);
650
+ const r = conform({
651
+ repo,
652
+ deltas,
653
+ ...scope?.length ? { scope } : {},
654
+ tasks,
655
+ before: before.records,
656
+ after: after.records,
657
+ files: after.files
658
+ });
659
+ const count = (s) => r.items.filter((i) => i.status === s).length;
660
+ const result = {
661
+ schemaVersion: 1,
662
+ change,
663
+ repo,
664
+ ref,
665
+ commit: commit2,
666
+ base: from,
667
+ ...o.task ? { task: o.task.toLowerCase() } : {},
668
+ checkedAt: now,
669
+ counts: {
670
+ found: count("found"),
671
+ missing: count("missing"),
672
+ stillThere: count("still-there"),
673
+ unexpected: count("unexpected")
674
+ },
675
+ items: r.items,
676
+ unchecked: r.unchecked,
677
+ problems: repoProblems
678
+ };
679
+ await writeFileAtomic(join4(changeFolder(root, change), CONFORM_DIR, `${repo}.yaml`), toCanonicalYaml(result, [
680
+ "schemaVersion",
681
+ "change",
682
+ "repo",
683
+ "ref",
684
+ "commit",
685
+ "base",
686
+ "task",
687
+ "checkedAt",
688
+ "counts",
689
+ "status",
690
+ "check",
691
+ "flow",
692
+ "item"
693
+ ]));
694
+ results.push(result);
695
+ }
696
+ const stored = await readConformResults(root, change);
697
+ problems.push(...stored.problems);
698
+ const round = await writeGateRound(root, change, CONFORM_GATE, await conformFindings(change, stored.results, linesOf(deltas), now), now);
699
+ return {
700
+ results,
701
+ ...round.round ? { round: round.round } : {},
702
+ problems,
703
+ flows: deltas.length
704
+ };
705
+ }
706
+ async function conformanceOf(root, change) {
707
+ const c = await changeStore(root).read(change).catch(() => void 0);
708
+ if (!c)
709
+ return void 0;
710
+ const { deltas, problems } = await readConformDeltas(changeFolder(root, change));
711
+ const stored = await readConformResults(root, change);
712
+ const rounds = await roundsOf(root, change, CONFORM_GATE).catch(() => []);
713
+ const round = rounds.at(-1);
714
+ const states = /* @__PURE__ */ new Map();
715
+ if (round)
716
+ for (const f of (await readRound(root, change, CONFORM_GATE, round)).findings)
717
+ states.set(f.finding.id, f.finding.state);
718
+ return {
719
+ change,
720
+ title: c.title,
721
+ flows: deltas.length,
722
+ results: stored.results.map((r) => ({
723
+ ...r,
724
+ items: r.items.map((i) => {
725
+ if (i.status === "found")
726
+ return i;
727
+ const id = conformFindingId(i);
728
+ return { ...i, finding: { id, state: states.get(id) ?? "open" } };
729
+ })
730
+ })),
731
+ gate: CONFORM_GATE,
732
+ ...round ? { round } : {},
733
+ problems: [...problems, ...stored.problems]
734
+ };
735
+ }
736
+ async function conformAfterBuild(c) {
737
+ if (c.record.state !== "built" || !c.record.commit)
738
+ return;
739
+ const change = c.t.change.id;
740
+ const task = c.t.task.id;
741
+ try {
742
+ const r = await conformChange(c.root, change, {
743
+ task,
744
+ ref: c.record.branch,
745
+ git: c.git,
746
+ now: c.now().toISOString().replace(/\.\d{3}Z$/, "Z")
747
+ });
748
+ if (!r.flows)
749
+ return;
750
+ const x = r.results[0];
751
+ const cmd = `atticus change conform ${change} --task ${task}`;
752
+ if (!x) {
753
+ c.record.notes.push(`The code wasn't checked against the design: ${r.problems[0] ?? "nothing to check"} (${cmd}).`);
754
+ return;
755
+ }
756
+ const n = x.counts;
757
+ const parts = [
758
+ n.missing ? `${n.missing} missing` : "",
759
+ n.stillThere ? `${n.stillThere} still there` : "",
760
+ n.unexpected ? `${n.unexpected} not in the design` : ""
761
+ ].filter(Boolean);
762
+ c.record.notes.push(parts.length ? `Checked against the design: ${parts.join(", ")}; the findings are on the conform gate (${cmd}).` : `Checked against the design: ${n.found} found, nothing missing or unexpected (${cmd}).`);
763
+ } catch (e) {
764
+ c.record.notes.push(`The code couldn't be checked against the design: ${e.message.split("\n")[0]}`);
765
+ }
766
+ }
767
+
768
+ // packages/taskrun/dist/run.js
769
+ var TaskRunError = class extends Error {
770
+ code;
771
+ constructor(code, message) {
772
+ super(message);
773
+ this.code = code;
774
+ this.name = "TaskRunError";
775
+ }
776
+ };
777
+ var LEVEL_RANK = { plan: 0, draft: 1, pr: 2 };
778
+ var AUTONOMY = {
779
+ "plan-only": "plan",
780
+ draft: "draft",
781
+ "draft-and-pr": "pr"
782
+ };
783
+ var stamp2 = (d) => d.toISOString().replace(/\.\d{3}Z$/, "Z");
784
+ function gitHostOf(root, t) {
785
+ return createAdapters(t.ctx.orgPack.runtime, {}, { store: fileStepStore(root), root, procedures: t.ctx.orgPack.procedures }).gitHost;
786
+ }
787
+ async function summarise(c, run) {
788
+ await saveRunSummary(c.root, c.t.change.id, c.t.task.id, toRunSummary(run));
789
+ if (!c.record.runs.includes(run.runId))
790
+ c.record.runs.push(run.runId);
791
+ }
792
+ async function aiStep(c, buildLog) {
793
+ const level = c.record.level;
794
+ const oneShot = c.runtime.kind !== "hand-off" && c.runtime.kind !== "headless-claude-code";
795
+ const pack = await taskPack({
796
+ t: c.t,
797
+ level,
798
+ engine: c.record.engine,
799
+ worktree: c.worktree,
800
+ worktreeRel: c.record.worktree,
801
+ oneShot,
802
+ git: c.git,
803
+ ...buildLog ? { buildLog } : {},
804
+ now: c.now()
805
+ });
806
+ const request = {
807
+ change: c.t.change.id,
808
+ agent: taskRunnerAgent(c.t),
809
+ pack,
810
+ outputPath: `tasks/${c.t.task.id}/${level === "plan" ? "plan.md" : "report.md"}`
811
+ };
812
+ const prepared = await c.runtime.prepare(request);
813
+ await writeQuarantineItems(c.root, c.t.change.id, prepared.runId, quarantineItems(pack.defences ?? []));
814
+ if (c.runtime instanceof HandoffRuntime) {
815
+ await writeFile2(join5(runsDirOf(c.root), request.change, prepared.runId, "prompt.md"), handoffPrompt(c, prepared), "utf8");
816
+ }
817
+ const run = await c.runtime.run(prepared.runId);
818
+ await summarise(c, run);
819
+ return run;
820
+ }
821
+ function handoffPrompt(c, run) {
822
+ const out = `${changesRelOf(c.root)}/${c.t.change.id}/${run.request.outputPath}`;
823
+ return [
824
+ `# ${run.request.agent.id}: task ${c.t.task.id} of change ${c.t.change.id}`,
825
+ "",
826
+ c.record.level === "plan" ? `Write the plan to ${out}. Change no code.` : `Make the changes in ${c.record.worktree} (branch ${c.record.branch}) only, then write a short report of what you changed to ${out}.`,
827
+ "",
828
+ run.request.pack.prompt.trimEnd(),
829
+ "",
830
+ `When you are done, run: atticus handoff done ${run.runId}`,
831
+ ""
832
+ ].join("\n");
833
+ }
834
+ async function build(c, runId, fixRun) {
835
+ const command = c.t.repo.build;
836
+ if (!command)
837
+ return void 0;
838
+ const n = c.record.attempts.length + 1;
839
+ const res = await c.commands(command, c.worktree);
840
+ const logRel = `${runsRelOf(c.root)}/${c.t.change.id}/${runId}/build-${n}.log`;
841
+ await mkdir3(join5(runsDirOf(c.root), c.t.change.id, runId), { recursive: true });
842
+ await writeFile2(join5(c.root, logRel), `$ ${command}
843
+ ${res.stdout}${res.stderr ? `
844
+ ${res.stderr}` : ""}
845
+ (exit ${res.exitCode ?? "none"})
846
+ `, "utf8");
847
+ const a = {
848
+ n,
849
+ ...fixRun ? { fixRun } : {},
850
+ command,
851
+ exitCode: res.exitCode,
852
+ passed: res.exitCode === 0,
853
+ log: logRel,
854
+ at: stamp2(c.now())
855
+ };
856
+ c.record.attempts.push(a);
857
+ return a;
858
+ }
859
+ async function applyAnswer(c, run) {
860
+ if (c.runtime.kind === "headless-claude-code") {
861
+ const changed = await c.git(["status", "--porcelain"], c.worktree);
862
+ for (const l of changed.stdout.split("\n").filter(Boolean)) {
863
+ const p = l.slice(3).trim();
864
+ if (!c.record.changed.includes(p))
865
+ c.record.changed.push(p);
866
+ }
867
+ await writeReport(c, run.output ?? "");
868
+ return [];
869
+ }
870
+ const a = parseAnswer(run.output ?? "");
871
+ if (a.problems.length)
872
+ return a.problems;
873
+ if (a.changes.length === 0)
874
+ return ["the answer changes no files"];
875
+ for (const p of await applyChanges(c.worktree, a.changes))
876
+ if (!c.record.changed.includes(p))
877
+ c.record.changed.push(p);
878
+ await writeReport(c, a.report);
879
+ return [];
880
+ }
881
+ async function writeReport(c, text) {
882
+ await writeFileAtomic(join5(changeFolder(c.root, c.t.change.id), `tasks/${c.t.task.id}/report.md`), `# Task ${c.t.task.id}: ${c.t.task.title}
883
+
884
+ ${text.trim() || "No report was given."}
885
+ `);
886
+ }
887
+ async function buildAndFix(c, runId) {
888
+ let a = await build(c, runId);
889
+ if (!a) {
890
+ c.record.notes.push(`${c.t.repo.id} has no build command in repos.manifest.yaml, so the change wasn't built or tested.`);
891
+ c.record.state = "unverified";
892
+ return;
893
+ }
894
+ let fixes = 0;
895
+ while (!a.passed && fixes < c.maxFix && c.runtime.kind !== "hand-off") {
896
+ fixes++;
897
+ const log = await import("node:fs/promises").then((fs) => fs.readFile(join5(c.root, a.log), "utf8"));
898
+ const fix = await aiStep(c, { command: a.command, text: log, attempt: fixes });
899
+ if (fix.state !== "validated") {
900
+ c.record.notes.push(`Fix round ${fixes} failed: ${fix.errors.join("; ") || fix.state}.`);
901
+ break;
902
+ }
903
+ const problems = await applyAnswer(c, fix);
904
+ if (problems.length) {
905
+ c.record.notes.push(`Fix round ${fixes} was not applied: ${problems.join("; ")}.`);
906
+ break;
907
+ }
908
+ a = await build(c, runId, fix.runId);
909
+ }
910
+ if (!a.passed) {
911
+ c.record.state = "needs-person";
912
+ c.record.notes.push(`The build still fails after ${fixes} fix round${fixes === 1 ? "" : "s"}; a person takes over in ${c.record.worktree}. See ${a.log}.`);
913
+ return;
914
+ }
915
+ c.record.state = "built";
916
+ }
917
+ async function commit(c, runId) {
918
+ await c.git(["add", "-A", "--", "."], c.worktree);
919
+ const staged = (await c.git(["diff", "--cached", "--name-only"], c.worktree)).stdout.trim();
920
+ if (!staged) {
921
+ c.record.notes.push("Nothing to commit.");
922
+ return;
923
+ }
924
+ await c.git([
925
+ "commit",
926
+ "-q",
927
+ "-m",
928
+ `${c.t.task.title} (task ${c.t.task.id} of ${c.t.change.id})`,
929
+ "-m",
930
+ `Atticus-Change: ${c.t.change.id}
931
+ Atticus-Task: ${c.t.task.id}
932
+ Atticus-Run: ${runId}
933
+ Requested-By: ${c.record.by}`
934
+ ], c.worktree);
935
+ c.record.commit = (await c.git(["rev-parse", "HEAD"], c.worktree)).stdout.trim();
936
+ }
937
+ async function openPr(c) {
938
+ if (c.record.state !== "built") {
939
+ c.record.notes.push(c.record.state === "unverified" ? "No PR: a pull request needs a passing build, and this repo has no build command." : "No PR: the build doesn't pass.");
940
+ if (c.record.state === "unverified")
941
+ c.record.state = "needs-person";
942
+ return;
943
+ }
944
+ const approval = requireApproval("git-host", c.approval);
945
+ if (!c.gitHost) {
946
+ c.record.state = "needs-person";
947
+ c.record.notes.push(`No Git host is connected (runtime.yaml adapters.gitHost): push ${c.record.branch} and open the PR into ${changeBranch(c.t.change.id)} by hand, then record it.`);
948
+ return;
949
+ }
950
+ const base = changeBranch(c.t.change.id);
951
+ const info = await c.gitHost.getRepo(c.t.repo.id);
952
+ for (const b of [c.record.branch, base])
953
+ if (info.protectedBranches.includes(b))
954
+ throw new TaskRunError("refused", `${b} is protected in ${c.t.repo.id}; Run with AI never pushes to or opens a PR into a protected branch.`);
955
+ if (base === info.defaultBranch)
956
+ throw new TaskRunError("refused", `${base} is ${c.t.repo.id}'s default branch; task PRs go into the change branch.`);
957
+ await c.git([
958
+ "push",
959
+ "-q",
960
+ "origin",
961
+ `refs/heads/${base}:refs/heads/${base}`,
962
+ `refs/heads/${c.record.branch}:refs/heads/${c.record.branch}`
963
+ ], c.worktree);
964
+ try {
965
+ const pr = await c.gitHost.createPullRequest({
966
+ repo: c.t.repo.id,
967
+ head: c.record.branch,
968
+ base,
969
+ title: `${c.t.task.title} (task ${c.t.task.id} of ${c.t.change.id})`,
970
+ body: [
971
+ `Task ${c.t.task.id} of change ${c.t.change.id}, drafted with Run with AI (${c.record.runtime}) and requested by ${c.record.by}.`,
972
+ "",
973
+ `Build: ${c.record.attempts.at(-1)?.command ?? "none"} passed after ${c.record.attempts.length} attempt${c.record.attempts.length === 1 ? "" : "s"}.`,
974
+ `Files: ${c.record.changed.join(", ") || "none"}.`,
975
+ "",
976
+ "A person reviews and merges this PR; Atticus never merges or deploys."
977
+ ].join("\n")
978
+ }, approval);
979
+ c.record.pr = { number: pr.number, url: pr.url };
980
+ c.record.state = "pr-open";
981
+ } catch (e) {
982
+ if (e instanceof AdapterError) {
983
+ c.record.state = "needs-person";
984
+ c.record.notes.push(`The PR couldn't be opened: ${e.message}`);
985
+ return;
986
+ }
987
+ throw e;
988
+ }
989
+ }
990
+ async function finish(c, run) {
991
+ if (c.record.level === "plan") {
992
+ if (c.runtime.kind !== "hand-off")
993
+ await writeFileAtomic(join5(changeFolder(c.root, c.t.change.id), run.request.outputPath), `${(run.output ?? "").trim()}
994
+ `);
995
+ c.record.state = "planned";
996
+ } else {
997
+ if (c.runtime.kind !== "hand-off") {
998
+ const problems = await applyAnswer(c, run);
999
+ if (problems.length) {
1000
+ c.record.state = "failed";
1001
+ c.record.notes.push(`The answer was not applied: ${problems.join("; ")}.`);
1002
+ return done(c);
1003
+ }
1004
+ }
1005
+ await buildAndFix(c, run.runId);
1006
+ if (c.record.state === "built" || c.record.state === "unverified")
1007
+ await commit(c, run.runId);
1008
+ await conformAfterBuild(c);
1009
+ if (c.record.level === "pr")
1010
+ await openPr(c);
1011
+ }
1012
+ return done(c);
1013
+ }
1014
+ async function done(c) {
1015
+ delete c.record.waiting;
1016
+ c.record.finishedAt = stamp2(c.now());
1017
+ return saveTaskRun(c.root, c.record);
1018
+ }
1019
+ async function runTask(root, changeId, taskId, o) {
1020
+ const now = o.now ?? (() => /* @__PURE__ */ new Date());
1021
+ const git = o.git ?? createGit();
1022
+ let t = await loadTask(root, changeId, taskId);
1023
+ const rt = t.ctx.orgPack.runtime;
1024
+ const level = o.level ?? AUTONOMY[rt.autonomy.default];
1025
+ const cap = rt.autonomy.capPerRepo[t.repo.id];
1026
+ if (cap && LEVEL_RANK[level] > LEVEL_RANK[AUTONOMY[cap]])
1027
+ throw new TaskRunError("refused", `${t.repo.id} allows Run with AI up to ${cap} (runtime.yaml autonomy.capPerRepo); ask for a lower level.`);
1028
+ if (level === "pr") {
1029
+ try {
1030
+ requireApproval("git-host", o.approval);
1031
+ } catch {
1032
+ throw new TaskRunError("refused", "The pr level pushes the task branch and opens a PR, which needs your approval: run it again with --approve.");
1033
+ }
1034
+ }
1035
+ const engine = buildEngineFor(t.ctx.orgPack, t.repo.id);
1036
+ const changeDir = await changeWorktree(root, t.change.id, t.repo.id);
1037
+ const handed = engine === "speckit" ? `specs/${t.task.id}/plan.md` : `.atticus/tasks/${t.task.id}.md`;
1038
+ const notes = [];
1039
+ if (!existsSync2(join5(changeDir, handed))) {
1040
+ const h = await handDown(root, t.change.id, t.task.id, { git });
1041
+ notes.push(`Handed the task down first (${h.feature} in ${h.repo}${h.commit ? `, commit ${h.commit.slice(0, 12)}` : ""}).`);
1042
+ t = await loadTask(root, changeId, taskId);
1043
+ }
1044
+ const wt = await openTaskWorktree(root, t.change.id, t.task.id, t.repo.id, git);
1045
+ const runtime = o.runtime ?? await createRuntime(t.ctx.orgPack, {
1046
+ root,
1047
+ ...o.mode ? { mode: o.mode } : {},
1048
+ ...o.replayDir ? { replayDir: o.replayDir } : {},
1049
+ now,
1050
+ ...o.runtimeOptions,
1051
+ headless: {
1052
+ ...o.runtimeOptions?.headless,
1053
+ invocation: () => ({
1054
+ cwd: wt.path,
1055
+ permissionMode: level === "plan" ? "plan" : "acceptEdits",
1056
+ ...engine === "speckit" ? { env: { SPECIFY_FEATURE_DIRECTORY: `specs/${t.task.id}` } } : {}
1057
+ })
1058
+ }
1059
+ });
1060
+ let gitHost = o.gitHost;
1061
+ if (!gitHost && level === "pr")
1062
+ gitHost = gitHostOf(root, t);
1063
+ const record = {
1064
+ schemaVersion: 1,
1065
+ change: t.change.id,
1066
+ task: t.task.id,
1067
+ repo: t.repo.id,
1068
+ level,
1069
+ runtime: runtime.kind,
1070
+ engine,
1071
+ by: o.by,
1072
+ branch: wt.branch,
1073
+ worktree: toRepoRelative(root, wt.path),
1074
+ state: "failed",
1075
+ runs: [],
1076
+ attempts: [],
1077
+ changed: [],
1078
+ startedAt: stamp2(now()),
1079
+ notes
1080
+ };
1081
+ const c = {
1082
+ root,
1083
+ t,
1084
+ record,
1085
+ worktree: wt.path,
1086
+ runtime,
1087
+ commands: o.commands ?? shellCommandRunner(),
1088
+ git,
1089
+ ...gitHost ? { gitHost } : {},
1090
+ ...o.approval ? { approval: o.approval } : {},
1091
+ now,
1092
+ maxFix: rt.autonomy.maxFixRounds
1093
+ };
1094
+ const run = await aiStep(c);
1095
+ if (run.state === "waiting") {
1096
+ record.state = "waiting";
1097
+ record.waiting = run.runId;
1098
+ return saveTaskRun(root, record);
1099
+ }
1100
+ if (run.state !== "validated") {
1101
+ record.notes.push(`The AI run ended ${run.state}: ${run.errors.join("; ") || "no reason given"}.`);
1102
+ return done(c);
1103
+ }
1104
+ return finish(c, run);
1105
+ }
1106
+ async function completeTaskHandoff(root, runId, o = {}) {
1107
+ const record = await findWaitingTaskRun(root, runId);
1108
+ if (!record)
1109
+ throw new TaskRunError("not-found", `No task run is waiting on ${runId}.`);
1110
+ const now = o.now ?? (() => /* @__PURE__ */ new Date());
1111
+ const git = o.git ?? createGit();
1112
+ const t = await loadTask(root, record.change, record.task);
1113
+ const rt = t.ctx.orgPack.runtime;
1114
+ const commands = o.commands ?? shellCommandRunner();
1115
+ let gitHost = o.gitHost;
1116
+ if (!gitHost && record.level === "pr")
1117
+ gitHost = gitHostOf(root, t);
1118
+ const c = {
1119
+ root,
1120
+ t,
1121
+ record,
1122
+ worktree: join5(root, record.worktree),
1123
+ runtime: void 0,
1124
+ commands,
1125
+ git,
1126
+ ...gitHost ? { gitHost } : {},
1127
+ ...o.approval ? { approval: o.approval } : {},
1128
+ now,
1129
+ maxFix: rt.autonomy.maxFixRounds
1130
+ };
1131
+ let attempt;
1132
+ const handoff = new HandoffRuntime({
1133
+ root,
1134
+ now,
1135
+ validate: async (file) => {
1136
+ const text = await import("node:fs/promises").then((fs) => fs.readFile(file, "utf8"));
1137
+ if (!text.trim())
1138
+ return [`${file.slice(root.length + 1)} is empty`];
1139
+ if (record.level === "plan")
1140
+ return [];
1141
+ attempt = await build(c, runId);
1142
+ if (!attempt)
1143
+ return [];
1144
+ return attempt.passed ? [] : [`${attempt.command} failed; see ${attempt.log}`];
1145
+ }
1146
+ });
1147
+ c.runtime = handoff;
1148
+ const run = await handoff.done(runId);
1149
+ await summarise(c, run);
1150
+ if (run.state === "validated") {
1151
+ if (record.level === "plan")
1152
+ record.state = "planned";
1153
+ else {
1154
+ record.state = attempt ? "built" : "unverified";
1155
+ if (!attempt)
1156
+ record.notes.push(`${t.repo.id} has no build command in repos.manifest.yaml, so the change wasn't built or tested.`);
1157
+ const changed = await git(["status", "--porcelain"], c.worktree);
1158
+ for (const l of changed.stdout.split("\n").filter(Boolean)) {
1159
+ const p = l.slice(3).trim();
1160
+ if (!record.changed.includes(p))
1161
+ record.changed.push(p);
1162
+ }
1163
+ await commit(c, runId);
1164
+ await conformAfterBuild(c);
1165
+ if (record.level === "pr")
1166
+ await openPr(c);
1167
+ }
1168
+ return done(c);
1169
+ }
1170
+ const builds = record.attempts.length;
1171
+ if (attempt && !attempt.passed && builds <= c.maxFix) {
1172
+ await handoff.retry(runId);
1173
+ await handoff.run(runId);
1174
+ record.notes.push(`Build attempt ${builds} failed; the run is waiting for a fix (${run.errors.join("; ")}).`);
1175
+ return saveTaskRun(root, record);
1176
+ }
1177
+ record.state = attempt && !attempt.passed ? "needs-person" : "failed";
1178
+ record.notes.push(attempt && !attempt.passed ? `The build still fails after ${builds} attempts; a person takes over in ${record.worktree}.` : `The hand-off failed: ${run.errors.join("; ")}.`);
1179
+ return done(c);
1180
+ }
1181
+ async function isTaskRun(root, runId) {
1182
+ return await findWaitingTaskRun(root, runId) !== void 0;
1183
+ }
1184
+
1185
+ export {
1186
+ FILE_FORMAT,
1187
+ refusedPath,
1188
+ parseAnswer,
1189
+ applyChanges,
1190
+ shellCommandRunner,
1191
+ TaskRunState,
1192
+ RunLevel,
1193
+ BuildAttempt,
1194
+ TaskRunRecord,
1195
+ taskDir,
1196
+ saveTaskRun,
1197
+ readTaskRun,
1198
+ saveRunSummary,
1199
+ findWaitingTaskRun,
1200
+ TASK_RUNNER,
1201
+ taskRunnerAgent,
1202
+ taskPack,
1203
+ CONFORM_GATE,
1204
+ CONFORM_DIR,
1205
+ ConformError,
1206
+ conformScanDir,
1207
+ conformFindingId,
1208
+ conformFindings,
1209
+ readConformResults,
1210
+ conformChange,
1211
+ conformanceOf,
1212
+ conformAfterBuild,
1213
+ TaskRunError,
1214
+ runTask,
1215
+ completeTaskHandoff,
1216
+ isTaskRun
1217
+ };