@maycombhq/atticus 2.0.0-beta.2 → 2.0.0-beta.22

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 (284) hide show
  1. package/dist/bin.js +8 -4
  2. package/dist/chunk-23XVSEV5.js +49 -0
  3. package/dist/{chunk-ZDPAS56H.js → chunk-24OXGB3P.js} +8 -2
  4. package/dist/{chunk-7EOBHUMC.js → chunk-24XLDU72.js} +4 -3
  5. package/dist/{chunk-CR3MTH32.js → chunk-2F4CYZKJ.js} +86 -11
  6. package/dist/{chunk-6IU67AEK.js → chunk-2GF7OLF3.js} +23 -15
  7. package/dist/chunk-2IIMFOPM.js +41 -0
  8. package/dist/chunk-2LGRMVCA.js +617 -0
  9. package/dist/{chunk-XPCM366L.js → chunk-2MMCFP5C.js} +10 -8
  10. package/dist/{chunk-JBTK5OP2.js → chunk-2Q56PQPS.js} +6 -4
  11. package/dist/{chunk-Z6LF7HQN.js → chunk-2Q5EDGEO.js} +7 -5
  12. package/dist/{chunk-3USYZGRF.js → chunk-2RLKFUUL.js} +38 -27
  13. package/dist/chunk-2SKB4O2E.js +59 -0
  14. package/dist/{chunk-SP2I63OO.js → chunk-34S2WGOB.js} +87 -4
  15. package/dist/{chunk-GQ4N4WKF.js → chunk-3NFFJL5D.js} +33 -27
  16. package/dist/{chunk-SJRGMG6A.js → chunk-3NWDLGG6.js} +28 -25
  17. package/dist/{chunk-4WBVUHXN.js → chunk-3RM4UK6W.js} +20 -18
  18. package/dist/chunk-42SIDKEU.js +583 -0
  19. package/dist/{chunk-GLUX4EEP.js → chunk-4EURQWQD.js} +20 -15
  20. package/dist/chunk-4U276ICE.js +39 -0
  21. package/dist/{chunk-ZMFPW66A.js → chunk-53T4O55J.js} +4 -3
  22. package/dist/{chunk-6J5OKA4Y.js → chunk-57TDNMI3.js} +17 -15
  23. package/dist/chunk-5BD2KYLE.js +57 -0
  24. package/dist/{chunk-7EFILTCI.js → chunk-5F7GFN2F.js} +28 -0
  25. package/dist/chunk-5NMKONLP.js +95 -0
  26. package/dist/{chunk-7ZUIMTOU.js → chunk-5SJZW52K.js} +26 -24
  27. package/dist/{chunk-4RS5KZQD.js → chunk-63YRMR6J.js} +6 -5
  28. package/dist/chunk-66PPNOON.js +62 -0
  29. package/dist/chunk-6H3Z5JHH.js +64 -0
  30. package/dist/{chunk-CEXSU4S6.js → chunk-6MUGR4LS.js} +775 -89
  31. package/dist/{chunk-QSXK2RGH.js → chunk-6OJQOPUN.js} +5 -3
  32. package/dist/{chunk-MVZVGYXH.js → chunk-6PPOWY5E.js} +84 -14
  33. package/dist/{chunk-7EKXJZ2Y.js → chunk-6ZGLAACW.js} +299 -38
  34. package/dist/chunk-6ZJ5A7AF.js +222 -0
  35. package/dist/{chunk-L24C55VN.js → chunk-745DAZ4L.js} +142 -30
  36. package/dist/{chunk-Q4D5X7QB.js → chunk-7ASNL4Q4.js} +46 -24
  37. package/dist/chunk-7BR7IPOH.js +35 -0
  38. package/dist/{chunk-7WD63HU2.js → chunk-7DOR27HL.js} +6 -6
  39. package/dist/chunk-7FTTA3HD.js +341 -0
  40. package/dist/{chunk-OLQJTJJU.js → chunk-7GJS6DNX.js} +12 -3
  41. package/dist/{chunk-7JUKDRSZ.js → chunk-7IGKHZ4Z.js} +347 -226
  42. package/dist/{chunk-G2B4ZQGH.js → chunk-7IOWA5D5.js} +11 -6
  43. package/dist/{chunk-EBEW3XXQ.js → chunk-7JITZFJC.js} +7 -5
  44. package/dist/chunk-7MJSQTL5.js +174 -0
  45. package/dist/{chunk-I4JRCD6M.js → chunk-7UOMVMFG.js} +25 -17
  46. package/dist/{chunk-YY6ZQQBP.js → chunk-AFWUDXEM.js} +19 -7
  47. package/dist/chunk-AFZ3QA6W.js +47 -0
  48. package/dist/chunk-AJQ72EBM.js +420 -0
  49. package/dist/chunk-AJYXNTNZ.js +317 -0
  50. package/dist/chunk-AVTBS4OW.js +49 -0
  51. package/dist/{chunk-FHH4I4ZV.js → chunk-BDKC6H5P.js} +12 -6
  52. package/dist/{chunk-IPKHE5D6.js → chunk-BEVTIBRH.js} +1526 -875
  53. package/dist/chunk-BHT7QK4G.js +162 -0
  54. package/dist/{chunk-6JUBZBMW.js → chunk-BIGDQDHD.js} +6 -4
  55. package/dist/{chunk-2BFCZ3RK.js → chunk-BO4KX37X.js} +20 -18
  56. package/dist/chunk-BPK5P77O.js +115 -0
  57. package/dist/chunk-BQ4SQQC6.js +59 -0
  58. package/dist/chunk-BQGDB6ZL.js +7342 -0
  59. package/dist/{chunk-2ANOROX3.js → chunk-BTGPE6CR.js} +11 -9
  60. package/dist/chunk-BTY3HZBO.js +93 -0
  61. package/dist/{chunk-DPZHZQKE.js → chunk-BXYMYEJ4.js} +44 -10
  62. package/dist/{chunk-2RMYG36Q.js → chunk-C3RY6KU6.js} +309 -346
  63. package/dist/chunk-C4R4JLHE.js +40 -0
  64. package/dist/chunk-CADWLE2T.js +18 -0
  65. package/dist/chunk-CBGGOQWU.js +82 -0
  66. package/dist/chunk-CMDXGQTS.js +47 -0
  67. package/dist/{chunk-MC3H7736.js → chunk-CQDGOPGH.js} +58 -18
  68. package/dist/{chunk-HFQCFSJR.js → chunk-CX4RZ2KS.js} +4 -3
  69. package/dist/{chunk-PAMPPUR6.js → chunk-CXJ6FUKN.js} +1852 -207
  70. package/dist/{chunk-ABWHYWNI.js → chunk-D73UEXYW.js} +3 -3
  71. package/dist/chunk-DCZWQLYT.js +1205 -0
  72. package/dist/chunk-DLOBCJL6.js +48 -0
  73. package/dist/{chunk-4BN53TG3.js → chunk-DOBQKHIF.js} +31 -23
  74. package/dist/chunk-E3ISYXO3.js +423 -0
  75. package/dist/{chunk-7SW2QWLU.js → chunk-E6ZIEVOI.js} +16 -13
  76. package/dist/chunk-EBL2R3YG.js +43 -0
  77. package/dist/{chunk-AIOQPLA5.js → chunk-EGQRREQH.js} +41 -15
  78. package/dist/chunk-EHA7RMZ3.js +58 -0
  79. package/dist/{chunk-M766ZJ6W.js → chunk-EIPTLPFC.js} +38 -27
  80. package/dist/chunk-EMRIQUND.js +517 -0
  81. package/dist/{chunk-DFBCSHVT.js → chunk-EPCJQQWD.js} +6 -4
  82. package/dist/{chunk-RZPYKDWS.js → chunk-F3P7N7SF.js} +1 -1
  83. package/dist/{chunk-R77KLRB3.js → chunk-FFLNS6VP.js} +21 -18
  84. package/dist/chunk-FFTRTL6R.js +26 -0
  85. package/dist/{chunk-IHMLFRVV.js → chunk-FPJPLKDW.js} +62 -16
  86. package/dist/{chunk-JCZIKA4C.js → chunk-FSMSFDLD.js} +5 -4
  87. package/dist/{chunk-AVJDSJ2F.js → chunk-FUJM6RTF.js} +8 -7
  88. package/dist/chunk-FZOJFH7Q.js +132 -0
  89. package/dist/{chunk-QRAOANID.js → chunk-G6X77UJZ.js} +23 -21
  90. package/dist/{chunk-3ALD2W2A.js → chunk-GCWRWSU7.js} +10 -4
  91. package/dist/chunk-GIW4ZVDB.js +39 -0
  92. package/dist/{chunk-B2WLAWNJ.js → chunk-GUX3PTYM.js} +3 -3
  93. package/dist/{chunk-DPUYDDQG.js → chunk-GZY6RUZ6.js} +25 -3
  94. package/dist/chunk-H4VO6WG3.js +10 -0
  95. package/dist/{chunk-MMOSZPWJ.js → chunk-H5HBGNXU.js} +5 -4
  96. package/dist/chunk-H7KM7LZE.js +229 -0
  97. package/dist/{chunk-AA6YULYB.js → chunk-HNM2YQT2.js} +7 -7
  98. package/dist/{chunk-3C7EYRFZ.js → chunk-HYU5VLGA.js} +1 -1
  99. package/dist/{chunk-XY3P7JW7.js → chunk-IDKCWSM5.js} +1032 -172
  100. package/dist/chunk-IFKEI4SA.js +237 -0
  101. package/dist/{chunk-F7HYOUFF.js → chunk-IGOE6KPG.js} +67 -22
  102. package/dist/{chunk-TDD55CJH.js → chunk-IH2XURVQ.js} +6 -5
  103. package/dist/chunk-INQHESFB.js +38 -0
  104. package/dist/chunk-IP74LCOQ.js +57 -0
  105. package/dist/chunk-IPHHDDC6.js +45 -0
  106. package/dist/{chunk-T6AIP7H5.js → chunk-ISUAAMGS.js} +110 -153
  107. package/dist/{chunk-A7UPUQFY.js → chunk-IUPG3UKI.js} +624 -319
  108. package/dist/{chunk-L6SGQIR3.js → chunk-IVBOQAGB.js} +7 -3
  109. package/dist/{chunk-27NKUS3X.js → chunk-J2JAKCIW.js} +2205 -796
  110. package/dist/{chunk-V2YTAIQO.js → chunk-J3IOLXWM.js} +24 -7
  111. package/dist/chunk-JA5FI3QV.js +142 -0
  112. package/dist/chunk-JAVI7JSP.js +49 -0
  113. package/dist/{chunk-HLJAXMM4.js → chunk-JB5LINEM.js} +6 -2
  114. package/dist/{chunk-2VHF7OXM.js → chunk-JENSEMXF.js} +1 -1
  115. package/dist/{chunk-6BVONWJ7.js → chunk-JJF6HALY.js} +4 -3
  116. package/dist/chunk-JLUCKAEL.js +38 -0
  117. package/dist/chunk-JRBFANFE.js +221 -0
  118. package/dist/{chunk-R6XF6UR3.js → chunk-KDNTAPLX.js} +4 -4
  119. package/dist/chunk-KFAVQZSX.js +33 -0
  120. package/dist/chunk-KJXD4PNL.js +50 -0
  121. package/dist/chunk-KN5BXMWN.js +44 -0
  122. package/dist/{chunk-PCVDV3UZ.js → chunk-KQGURXFU.js} +9 -7
  123. package/dist/{chunk-WY6PP6AA.js → chunk-KXITGYLF.js} +40 -6
  124. package/dist/{chunk-66YVAGGM.js → chunk-L27SV425.js} +22 -20
  125. package/dist/{chunk-NE2W3OO7.js → chunk-LDLL7LB3.js} +24 -22
  126. package/dist/chunk-LFGTYX5U.js +379 -0
  127. package/dist/{chunk-EYWIDJFU.js → chunk-LGBMTVNT.js} +7 -5
  128. package/dist/{chunk-Q5AMFEWD.js → chunk-LGFL54FP.js} +3 -2
  129. package/dist/{chunk-6TACQN3N.js → chunk-LJXMYKZJ.js} +7 -5
  130. package/dist/{chunk-BKVWTZ6A.js → chunk-LKOR5UET.js} +29 -26
  131. package/dist/chunk-LNBQOP7D.js +294 -0
  132. package/dist/{chunk-O3WI5KWW.js → chunk-LO6P2VYG.js} +2 -2
  133. package/dist/chunk-LQJPN536.js +122 -0
  134. package/dist/{chunk-YEDDOYSC.js → chunk-LYBNHMVZ.js} +29 -5
  135. package/dist/{chunk-A3GY6SOA.js → chunk-LZ7NUC62.js} +20 -18
  136. package/dist/chunk-M32BLWDH.js +37 -0
  137. package/dist/{chunk-VYDBJ73M.js → chunk-M3NANSDZ.js} +17 -15
  138. package/dist/chunk-MFHL5URL.js +31 -0
  139. package/dist/chunk-MFR5OPBD.js +109 -0
  140. package/dist/{chunk-DE76JROX.js → chunk-MG4ZL5RW.js} +32 -20
  141. package/dist/{chunk-N7IXEHK3.js → chunk-MO6P2JZH.js} +10 -8
  142. package/dist/{chunk-65NYPGRC.js → chunk-MUWDB4R4.js} +1 -1
  143. package/dist/chunk-MZCGSXVR.js +34 -0
  144. package/dist/{chunk-MGYZM27B.js → chunk-N3XIYPU3.js} +51 -23
  145. package/dist/chunk-NDCF4R6S.js +172 -0
  146. package/dist/{chunk-DHPACDG7.js → chunk-NR2UJWOC.js} +10 -8
  147. package/dist/chunk-NXJ5URP6.js +51 -0
  148. package/dist/{chunk-UNM6ZOKP.js → chunk-NY2XSR5K.js} +147 -18
  149. package/dist/{chunk-5GDRCDQB.js → chunk-O45HFTFS.js} +3 -2
  150. package/dist/{chunk-ONLS5QA5.js → chunk-O4GXGGBX.js} +14 -12
  151. package/dist/chunk-O5PXQR67.js +249 -0
  152. package/dist/{chunk-PRPPGYZG.js → chunk-O66DM6DJ.js} +6 -4
  153. package/dist/{chunk-KEM4SDDP.js → chunk-O7FDLW7L.js} +11 -8
  154. package/dist/{chunk-T2UYZSCQ.js → chunk-O7XLYEFA.js} +169 -29
  155. package/dist/{chunk-FITWGOJ2.js → chunk-OHNCWBKF.js} +4 -4
  156. package/dist/{chunk-652QWTLZ.js → chunk-OHVTTOPS.js} +3 -3
  157. package/dist/chunk-OMI6FPPN.js +43 -0
  158. package/dist/chunk-ONUPY3H6.js +53 -0
  159. package/dist/chunk-OTLDSZDV.js +69 -0
  160. package/dist/chunk-OUBGGKDU.js +22 -0
  161. package/dist/chunk-OWNCM4ZN.js +330 -0
  162. package/dist/{chunk-YISXLPHN.js → chunk-P2V7QW4D.js} +235 -35
  163. package/dist/{chunk-CNUKCS2T.js → chunk-P32RUW3B.js} +1632 -93
  164. package/dist/{chunk-BWZ77RQT.js → chunk-PAQ2AS5E.js} +1 -1
  165. package/dist/{chunk-ZMAINWBW.js → chunk-PBPBMP2B.js} +4 -3
  166. package/dist/{chunk-ZVM6AKKM.js → chunk-PJSJPMJI.js} +3 -3
  167. package/dist/{chunk-EFHQ3TWP.js → chunk-PKBHS4AA.js} +233 -56
  168. package/dist/{chunk-GT4I4ZWM.js → chunk-PMUAJGLI.js} +20 -16
  169. package/dist/chunk-PPD7HTDP.js +152 -0
  170. package/dist/chunk-PSOFBQWB.js +42 -0
  171. package/dist/{chunk-S2A7YC3Q.js → chunk-Q2TECDIT.js} +10694 -8896
  172. package/dist/chunk-Q4K5WB2W.js +42 -0
  173. package/dist/{chunk-UGLN7QHV.js → chunk-Q6DFNVRJ.js} +14 -12
  174. package/dist/chunk-QA4O2GGC.js +265 -0
  175. package/dist/chunk-QAXW2N3B.js +1216 -0
  176. package/dist/chunk-QBNWF5ZU.js +19 -0
  177. package/dist/chunk-QFWA2DPH.js +224 -0
  178. package/dist/{chunk-23W7VWKR.js → chunk-QKUJMING.js} +1363 -114
  179. package/dist/{chunk-NXFPS2LR.js → chunk-R44CYFPV.js} +16 -13
  180. package/dist/{chunk-CKSITVS4.js → chunk-R7NYHMUU.js} +2687 -786
  181. package/dist/chunk-REWWDVQB.js +162 -0
  182. package/dist/{chunk-JMSCMUCA.js → chunk-RGERPOIV.js} +145 -21
  183. package/dist/{chunk-6JCPI55B.js → chunk-RLDGWLQ7.js} +49 -7
  184. package/dist/chunk-RUGXBPWI.js +384 -0
  185. package/dist/{chunk-CPA6HPVR.js → chunk-RXPJMEOW.js} +18 -12
  186. package/dist/{chunk-3HI6Z55Y.js → chunk-S4PMJU6H.js} +339 -43
  187. package/dist/chunk-S5LSDXV4.js +40 -0
  188. package/dist/chunk-S7FCV7S5.js +51 -0
  189. package/dist/{chunk-5GGOLAKC.js → chunk-SDKLKB6I.js} +28 -26
  190. package/dist/chunk-SFSPGFCV.js +62 -0
  191. package/dist/{chunk-ZNCEKR4J.js → chunk-SFUP7TTO.js} +12 -8
  192. package/dist/{chunk-64EQYWCA.js → chunk-SLXZOMA6.js} +69 -19
  193. package/dist/chunk-SQV37XO2.js +273 -0
  194. package/dist/{chunk-K65BJIMT.js → chunk-SU74NDMQ.js} +19 -17
  195. package/dist/chunk-SYV5LHML.js +165 -0
  196. package/dist/chunk-T4YPZIQN.js +36 -0
  197. package/dist/chunk-T6DQR5TV.js +323 -0
  198. package/dist/{chunk-JIITQXFB.js → chunk-THDMSZ3R.js} +3075 -802
  199. package/dist/{chunk-JGZCG5VM.js → chunk-TNR75OXT.js} +7 -7
  200. package/dist/{chunk-D3PO4DOZ.js → chunk-TUULXQRW.js} +174 -15
  201. package/dist/chunk-TYQBFTBR.js +516 -0
  202. package/dist/chunk-U76OWS3Q.js +49 -0
  203. package/dist/{chunk-YYQN46FY.js → chunk-UCROWG2D.js} +27 -24
  204. package/dist/{chunk-6M5NK3K3.js → chunk-UF4AZOZB.js} +50 -10
  205. package/dist/chunk-UF4GLFBX.js +345 -0
  206. package/dist/{chunk-OT2O76OS.js → chunk-UGUP3ZM6.js} +240 -39
  207. package/dist/chunk-UNAGJYET.js +45 -0
  208. package/dist/{chunk-5WG5YP4T.js → chunk-UOR2DTHH.js} +16 -14
  209. package/dist/{chunk-S3QNRWYR.js → chunk-UPOY4YSQ.js} +14 -12
  210. package/dist/{chunk-EPTBZ3GP.js → chunk-UPS2DGFC.js} +1 -1
  211. package/dist/{chunk-4AK7IBVP.js → chunk-UUU4CLJG.js} +4 -2
  212. package/dist/{chunk-W3BQAZ3Q.js → chunk-UWMJKX5U.js} +14 -12
  213. package/dist/{chunk-QZSX3F7C.js → chunk-UWOJLHFT.js} +27 -23
  214. package/dist/chunk-VBTP56CE.js +535 -0
  215. package/dist/chunk-VCTWPLAO.js +211 -0
  216. package/dist/chunk-VNU26RCO.js +1215 -0
  217. package/dist/{chunk-CSZ4C5N6.js → chunk-VTZMAJ3W.js} +93 -10
  218. package/dist/{chunk-TXLH6WHQ.js → chunk-VW62D6QE.js} +14 -12
  219. package/dist/{chunk-CAQZUNOH.js → chunk-VY72R2XZ.js} +610 -3
  220. package/dist/{chunk-2DIQQJCB.js → chunk-VZALIKIF.js} +18 -15
  221. package/dist/{chunk-TYAID7B7.js → chunk-W62H2XSO.js} +25 -23
  222. package/dist/{chunk-HVUPKCGJ.js → chunk-W7VWI2YH.js} +9 -6
  223. package/dist/{chunk-TANFV3MZ.js → chunk-WERM6KPJ.js} +7 -4
  224. package/dist/{chunk-BOHJZTEQ.js → chunk-WF7B67YE.js} +208 -87
  225. package/dist/{chunk-7FBGJFEE.js → chunk-WG5U3F5V.js} +14 -12
  226. package/dist/{chunk-4NDAAFQT.js → chunk-WJF2CS6M.js} +8 -5
  227. package/dist/{chunk-XAKWMCXI.js → chunk-WKUJ3KPV.js} +4 -4
  228. package/dist/chunk-WMTRHUI5.js +103 -0
  229. package/dist/chunk-WNKPRSGI.js +36 -0
  230. package/dist/chunk-WXFLMQSR.js +223 -0
  231. package/dist/{chunk-RRTKKSLQ.js → chunk-X3WY6MN3.js} +8 -6
  232. package/dist/{chunk-ZCJDOK2S.js → chunk-X4CXA2IL.js} +47 -23
  233. package/dist/{chunk-UBBC2XSG.js → chunk-X5F3Q5LV.js} +560 -105
  234. package/dist/{chunk-C6EKFH7J.js → chunk-XD75VZIH.js} +9 -7
  235. package/dist/chunk-XERYFDB5.js +297 -0
  236. package/dist/chunk-XI2LCCYQ.js +420 -0
  237. package/dist/chunk-Y2EQNWKV.js +933 -0
  238. package/dist/{chunk-LR3R6Z2A.js → chunk-YHCMZC2J.js} +7 -7
  239. package/dist/chunk-YYY3AZFE.js +122 -0
  240. package/dist/{chunk-GDLULHTC.js → chunk-Z5IA3WDR.js} +19 -31
  241. package/dist/{chunk-T6XQL73F.js → chunk-ZFFYNRIO.js} +63 -23
  242. package/dist/{chunk-EDS2L2LD.js → chunk-ZFL7NY4F.js} +56 -27
  243. package/dist/{chunk-YMZ3TNYB.js → chunk-ZGULQAPZ.js} +7 -4
  244. package/dist/{chunk-4SKZDI62.js → chunk-ZIUFM5HT.js} +3 -1
  245. package/dist/{chunk-DKJA76CJ.js → chunk-ZJFRMSJT.js} +15 -13
  246. package/dist/chunk-ZJXLNDH4.js +239 -0
  247. package/dist/chunk-ZQ3ON2VQ.js +252 -0
  248. package/dist/{chunk-HITVBIJS.js → chunk-ZQ7SKESZ.js} +150 -415
  249. package/dist/{chunk-6QSERWXH.js → chunk-ZQXZ2SES.js} +24 -21
  250. package/dist/chunk-ZX57KSEQ.js +39 -0
  251. package/dist/{chunk-I3E7CX4H.js → chunk-ZZK56BLP.js} +5 -3
  252. package/dist/files.json +664 -368
  253. package/dist/packages/naysayer/constitution/constitution.yaml +19 -0
  254. package/dist/packages/sdk/npm/index.js +6194 -2542
  255. package/dist/packages/ui/dist/assets/{elk-api-tma0MCuh.js → elk-api-CIf-0gz5.js} +2 -2
  256. package/dist/packages/ui/dist/assets/index-CoK_Dl0D.js +47 -0
  257. package/dist/packages/ui/dist/assets/index-Dw20IRhQ.css +1 -0
  258. package/dist/packages/ui/dist/index.html +3 -2
  259. package/package.json +5 -5
  260. package/dist/chunk-2BF2EYJV.js +0 -174
  261. package/dist/chunk-42EVSKME.js +0 -37
  262. package/dist/chunk-4BKGMUIK.js +0 -53
  263. package/dist/chunk-5KLGBXG5.js +0 -48
  264. package/dist/chunk-6BNC6EQ4.js +0 -41
  265. package/dist/chunk-6D2CQ5II.js +0 -41
  266. package/dist/chunk-7AVHLZGD.js +0 -45
  267. package/dist/chunk-D46WUV3T.js +0 -33
  268. package/dist/chunk-E36QOJMD.js +0 -47
  269. package/dist/chunk-FQXYPF7E.js +0 -147
  270. package/dist/chunk-GBRFVT63.js +0 -45
  271. package/dist/chunk-ICY36XCH.js +0 -34
  272. package/dist/chunk-J4K3KVLD.js +0 -131
  273. package/dist/chunk-JZU3H6UQ.js +0 -54
  274. package/dist/chunk-NN2ZQEB4.js +0 -38
  275. package/dist/chunk-PCOCACY3.js +0 -385
  276. package/dist/chunk-RTEYOSJY.js +0 -29
  277. package/dist/chunk-RUVFXE2L.js +0 -666
  278. package/dist/chunk-RVH5SUW5.js +0 -69
  279. package/dist/chunk-VN3DP4LQ.js +0 -43
  280. package/dist/chunk-W5BVQF44.js +0 -36
  281. package/dist/chunk-WVPJSRRJ.js +0 -52
  282. package/dist/chunk-XPTOBS2D.js +0 -48
  283. package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +0 -29
  284. package/dist/packages/ui/dist/assets/index-DD_hufQz.css +0 -1
@@ -0,0 +1,1216 @@
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
+ onboardingView
8
+ } from "./chunk-7JITZFJC.js";
9
+ import {
10
+ onboardingQueue,
11
+ queueWhy,
12
+ reasonOf
13
+ } from "./chunk-LQJPN536.js";
14
+ import {
15
+ repoIdKey
16
+ } from "./chunk-4U276ICE.js";
17
+ import {
18
+ houseUntaughtOf,
19
+ houseUntaughtWords
20
+ } from "./chunk-EHA7RMZ3.js";
21
+ import {
22
+ catalogSources
23
+ } from "./chunk-OWNCM4ZN.js";
24
+ import {
25
+ rulesLackingAll
26
+ } from "./chunk-WXFLMQSR.js";
27
+ import {
28
+ loadReadPlan,
29
+ partOfWords,
30
+ readCostOf,
31
+ readCostWords,
32
+ readPlanProgress,
33
+ readPlanRelOf,
34
+ tokensWords
35
+ } from "./chunk-TYQBFTBR.js";
36
+ import {
37
+ checkoutOf,
38
+ conventionsAt
39
+ } from "./chunk-2F4CYZKJ.js";
40
+ import {
41
+ isMetarepo,
42
+ notMetarepo
43
+ } from "./chunk-3G4YI4ZU.js";
44
+ import {
45
+ readTaskRun
46
+ } from "./chunk-6MUGR4LS.js";
47
+ import {
48
+ readChangeTasks
49
+ } from "./chunk-UGUP3ZM6.js";
50
+ import {
51
+ readNeeds,
52
+ seedCollisions
53
+ } from "./chunk-R7NYHMUU.js";
54
+ import {
55
+ ASSISTANT_FORMATS,
56
+ probedAssistant,
57
+ readProbes,
58
+ whatRunsWhere
59
+ } from "./chunk-BEVTIBRH.js";
60
+ import {
61
+ readChangeFiles
62
+ } from "./chunk-S4PMJU6H.js";
63
+ import {
64
+ assess,
65
+ changeStore,
66
+ isManualPrUrl,
67
+ liveHandoff,
68
+ loadChangeContext,
69
+ loadChangePolicy,
70
+ releasePrReasons,
71
+ stageCompletion
72
+ } from "./chunk-IDKCWSM5.js";
73
+ import {
74
+ fileStepStore
75
+ } from "./chunk-7IGKHZ4Z.js";
76
+ import {
77
+ readCatalog
78
+ } from "./chunk-J2JAKCIW.js";
79
+ import {
80
+ readKnowledge,
81
+ snapshotDates,
82
+ workingDays
83
+ } from "./chunk-745DAZ4L.js";
84
+ import {
85
+ baseClonePath
86
+ } from "./chunk-PKBHS4AA.js";
87
+ import {
88
+ stepClassOfNextStep
89
+ } from "./chunk-P32RUW3B.js";
90
+ import {
91
+ ScanVerifyProposal,
92
+ catalogDirOf,
93
+ changesDirOf,
94
+ changesRelOf,
95
+ factsDirOf,
96
+ factsFileOf,
97
+ factsRelOf,
98
+ fastPathOf,
99
+ headFromFiles,
100
+ isAdopted,
101
+ listQuestions,
102
+ loadOrgPack,
103
+ orderQuestions,
104
+ orgPackDirOf,
105
+ proposalsDirOf,
106
+ questionWeights,
107
+ readRepoSpec,
108
+ readSpecFindings,
109
+ stepModelsOf
110
+ } from "./chunk-Q2TECDIT.js";
111
+ import {
112
+ require_dist
113
+ } from "./chunk-BQGDB6ZL.js";
114
+ import {
115
+ __toESM
116
+ } from "./chunk-TV45EUGM.js";
117
+
118
+ // packages/cli/dist/next-commands.js
119
+ var import_yaml = __toESM(require_dist(), 1);
120
+ import { existsSync } from "node:fs";
121
+ import { readdir, readFile } from "node:fs/promises";
122
+ import { join } from "node:path";
123
+ var METAREPO = "metarepo";
124
+ var DRAFTING = ["feature", "architecture", "stories"];
125
+ var draftingAt = (s) => DRAFTING.indexOf(s);
126
+ var STALE_DAYS = 14;
127
+ var plural = (n, one, many = `${one}s`) => `${n} ${n === 1 ? one : many}`;
128
+ async function verifyState(root, repo) {
129
+ const text = await readFile(join(proposalsDirOf(root), "scan", `${repo}.yaml`), "utf8").catch(() => void 0);
130
+ if (text === void 0)
131
+ return "none";
132
+ const p = ScanVerifyProposal.safeParse((0, import_yaml.parse)(text));
133
+ if (!p.success)
134
+ return "none";
135
+ const s = p.data.settings;
136
+ const entries = s.exclude.length + s.prefixes.length + s.clients.length;
137
+ if (entries > 0 && (!p.data.accepted || p.data.accepted.at < p.data.at))
138
+ return "accept";
139
+ return "done";
140
+ }
141
+ async function staleOf(root, repo) {
142
+ const text = await readFile(join(factsDirOf(root), `${repo}.verify.yaml`), "utf8").catch(() => void 0);
143
+ let facts;
144
+ try {
145
+ const c = (0, import_yaml.parse)(text ?? "")?.commit;
146
+ if (typeof c === "string" && /^[0-9a-f]{7,64}$/.test(c))
147
+ facts = c;
148
+ } catch {
149
+ return void 0;
150
+ }
151
+ if (!facts)
152
+ return void 0;
153
+ let dir;
154
+ try {
155
+ dir = isAdopted(root) ? root : baseClonePath(root, repo);
156
+ } catch {
157
+ return void 0;
158
+ }
159
+ const head = await headFromFiles(dir);
160
+ if (!head || head.startsWith(facts) || facts.startsWith(head))
161
+ return void 0;
162
+ return { facts, head };
163
+ }
164
+ async function readNextState(root) {
165
+ const view = await onboardingView(root);
166
+ const problems = [...view.problems];
167
+ const repos = [];
168
+ const factIds = (await readdir(factsDirOf(root)).catch(() => [])).map((n) => factsFileOf(n)).flatMap((f) => f?.facts ? [f.repo] : []);
169
+ const fromFacts = catalogSources((await readCatalog(join(catalogDirOf(root), "generated"), { cacheRoot: root })).records);
170
+ for (const r of view.repos) {
171
+ const hasFacts = existsSync(join(factsDirOf(root), `${r.id}.jsonl`));
172
+ const near = hasFacts ? [] : factIds.filter((x) => x !== r.id && repoIdKey(x) === repoIdKey(r.id)).sort().map((x) => ({ id: x, file: `${factsRelOf(root)}/${x}.jsonl` }));
173
+ const spec = await readRepoSpec(root, r.id, { cacheRoot: root });
174
+ problems.push(...spec.problems);
175
+ const findings = await readSpecFindings(root, r.id);
176
+ const plan = await readPlanProgress(root, r.id);
177
+ const planFile = await loadReadPlan(root, r.id);
178
+ const mapped = !!spec.header?.template.startsWith("facts@") || (fromFacts.get(r.id)?.facts ?? 0) > 0;
179
+ const stale = mapped && hasFacts ? await staleOf(root, r.id) : void 0;
180
+ const rules = hasFacts && r.cloned && !await staleOf(root, r.id) ? await rulesLackingAll(root, r.id, planFile?.rules) : [];
181
+ repos.push({
182
+ id: r.id,
183
+ cloned: r.cloned,
184
+ settings: r.scanSettings.present,
185
+ scanned: r.lastScan !== null,
186
+ verify: await verifyState(root, r.id),
187
+ flows: spec.flows.length,
188
+ checked: !!findings && findings.draftedAt === spec.header?.drafted?.at,
189
+ findings: findings?.findings.filter((f) => !f.question).length ?? 0,
190
+ described: !r.description ? "none" : r.description.trust === "suggested" ? "draft" : "said",
191
+ ...mapped ? { facts: true } : {},
192
+ ...stale ? { stale } : {},
193
+ ...rules.length ? { rules } : {},
194
+ ...planFile ? { cost: readCostOf(planFile) } : {},
195
+ ...hasFacts ? { read: true } : {},
196
+ ...near.length ? { nearFacts: near } : {},
197
+ ...plan ? {
198
+ readPlan: {
199
+ total: plan.total,
200
+ done: plan.done,
201
+ ...plan.next ? { next: { part: plan.next.part, paths: plan.next.paths } } : {},
202
+ file: readPlanRelOf(root, r.id)
203
+ }
204
+ } : {}
205
+ });
206
+ }
207
+ const waiting = repos.filter((r) => r.cloned && !r.facts && !r.scanned);
208
+ if (waiting.length) {
209
+ const q = await onboardingQueue(root, waiting.map((r) => ({
210
+ repo: r.id,
211
+ ...r.read || (r.readPlan?.done ?? 0) > 0 ? { started: true } : {}
212
+ })));
213
+ problems.push(...q.problems);
214
+ q.queue.forEach((x, order) => {
215
+ const r = repos.find((y) => y.id === x.repo);
216
+ r.queue = { order, reason: reasonOf(x), why: queueWhy(x) };
217
+ });
218
+ const first = waiting.filter((r) => !r.read).sort((a, b) => (a.queue?.order ?? Infinity) - (b.queue?.order ?? Infinity))[0];
219
+ const dir = first ? await checkoutOf(root, first.id) : void 0;
220
+ if (first && dir && (await conventionsAt(root)).housePrefixes.length) {
221
+ const found = await houseUntaughtOf(root, first.id, { dir }).catch(() => []);
222
+ if (found.length)
223
+ first.houseUntaught = found;
224
+ }
225
+ }
226
+ const open = await listQuestions(root, { state: "open" });
227
+ problems.push(...open.problems);
228
+ const changeIds = new Set(await changeStore(root).list().then((cs) => cs.map((c) => c.id), () => []));
229
+ const changeQuestions = {};
230
+ const openIds = new Set(open.questions.map((q) => q.id));
231
+ for (const q of open.questions)
232
+ if (changeIds.has(q.repo))
233
+ (changeQuestions[q.repo] ??= []).push(q.id);
234
+ const knowledge = await readKnowledge(root, { cacheRoot: root });
235
+ const sources = [];
236
+ for (const w of view.sources.wikis) {
237
+ const newest = (await snapshotDates(root, w.id))[0];
238
+ sources.push({
239
+ id: w.id,
240
+ snapshot: !!newest,
241
+ scanned: !!newest && !!knowledge.report?.snapshots.some((s) => s.source === w.id && s.date === newest),
242
+ ...newest ? { age: Math.floor((Date.now() - Date.parse(`${newest}T00:00:00Z`)) / 864e5) } : {}
243
+ });
244
+ }
245
+ const orgPack = await loadOrgPack(orgPackDirOf(root)).catch((e) => e);
246
+ let orgpack;
247
+ try {
248
+ if (orgPack instanceof Error)
249
+ throw orgPack;
250
+ const op = orgPack;
251
+ const names = new Set(op.profiles.flatMap((p) => (p.profile?.systems ?? []).flatMap((x) => [x.name, ...x.aliases])).map((n) => n.toLowerCase()));
252
+ const missing = knowledge.items.filter((i) => (i.kind === "Product" && i.productKind === "product" || i.kind === "Party" && i.partyKind === "vendor" && !!i.quote) && ![i.name, ...i.aliases].some((n) => names.has(n.toLowerCase()))).length;
253
+ let draft;
254
+ for (const f of await readdir(join(proposalsDirOf(root), "orgpack")).catch(() => []))
255
+ if (f.endsWith(".yaml")) {
256
+ const d = (0, import_yaml.parse)(await readFile(join(proposalsDirOf(root), "orgpack", f), "utf8"));
257
+ if (d?.platform && d.proposals?.length)
258
+ draft = { platform: d.platform, proposals: d.proposals.length };
259
+ }
260
+ if (missing || draft)
261
+ orgpack = { missing, ...draft ? { draft } : {} };
262
+ } catch (e) {
263
+ problems.push({ file: "org-pack", message: e.message.split("\n")[0] });
264
+ }
265
+ const changes = [];
266
+ let unverifiedNeeds = 0;
267
+ let active;
268
+ const types = orgPack instanceof Error ? [] : orgPack.changeTypes.types;
269
+ const { policy } = await loadChangePolicy(orgPackDirOf(root));
270
+ const clashes = await seedCollisions(root).catch(() => []);
271
+ let ctxP;
272
+ const changeContext = () => ctxP ??= loadChangeContext(root);
273
+ try {
274
+ for (const c of await changeStore(root).list()) {
275
+ const clash = clashes.filter((x) => x.change === c.id).map(({ seed, repo, capability, flow }) => ({ seed, repo, capability, flow }));
276
+ const files = await readChangeFiles(join(changesDirOf(root), c.id)).catch(() => void 0);
277
+ const stagesDone = (await stageCompletion({ root, policy }, c)).filter((s) => s.state === "done").map((s) => s.stage);
278
+ const needs = await readNeeds(root, c.id);
279
+ const open2 = needs?.needs.filter((n) => n.status === "open") ?? [];
280
+ unverifiedNeeds += open2.filter((n) => {
281
+ const r = knowledge.reviews[n.item];
282
+ return r?.state !== "verified" && r?.state !== "corrected";
283
+ }).length;
284
+ const longest = open2.map((n) => ({
285
+ n,
286
+ // The lead time as the knowledge scan read it (ADR 0117); a need with none sorts last.
287
+ days: n.leadTimeDays ? workingDays(n.leadTimeDays) : 0
288
+ })).sort((a, b) => b.days - a.days)[0];
289
+ const own = stageOf(c.state);
290
+ const loop = draftingAt(own) >= 0 ? await loopState(root, c.id, own) : void 0;
291
+ const live = c.state === "returned" ? void 0 : liveHandoff(c);
292
+ const busy = await stageInProgress(root, c.id);
293
+ const asked = await stageQuestions(root, c.id, openIds);
294
+ const questions = [.../* @__PURE__ */ new Set([...changeQuestions[c.id] ?? [], ...asked])];
295
+ const missing = c.state === "define" || c.state === "returned" ? await draftMissing(changeContext, c).catch(() => ({ draft: false, brief: false })) : { draft: false, brief: false };
296
+ const blocking = stageOf(c.state) === "tasks" ? await blockingOf(changeContext, c).catch(() => 0) : 0;
297
+ const gate = draftingAt(own) >= 0 && !live && (stagesDone.includes(own) || c.state === "returned") ? await gateFindingsOf(changeContext, c).catch(() => []) : [];
298
+ if (busy && stageOf(c.state) !== "done" && (!active || busy > active.at))
299
+ active = { id: c.id, at: busy };
300
+ changes.push({
301
+ id: c.id,
302
+ state: c.state,
303
+ tasks: files ? await Promise.all(readChangeTasks(files).map(async (t) => {
304
+ const run = t.done ? void 0 : (await readTaskRun(root, c.id, t.id).catch(() => void 0))?.state;
305
+ return { id: t.id, repo: t.repo, done: t.done, ...run ? { run } : {} };
306
+ })) : [],
307
+ feature: existsSync(join(changesDirOf(root), c.id, "feature.yaml")),
308
+ ...missing.draft ? { undrafted: true } : {},
309
+ ...blocking ? { blocking } : {},
310
+ ...gate.length ? { gate } : {},
311
+ ...c.state === "released" ? await releasedOf(root, c.id) : {},
312
+ ...stageOf(c.state) === "release" ? await releasePrsOf(root, c.id) : {},
313
+ ...missing.brief ? { brief: `${changesRelOf(root)}/${c.id}/brief.md` } : {},
314
+ ...questions.length ? { questions } : {},
315
+ ...knowledge.items.length ? { knowledge: true } : {},
316
+ ...stagesDone.length ? { stagesDone } : {},
317
+ ...loop ? { loop } : {},
318
+ ...live ? {
319
+ handoff: {
320
+ phase: live.phase,
321
+ number: live.pr.number,
322
+ url: live.pr.url,
323
+ state: live.state,
324
+ ...isManualPrUrl(live.pr.url) ? await manualPrRecorded(root, c.id, live.branch, orgPack) : {}
325
+ }
326
+ } : {},
327
+ ...clash.length ? { seedCollisions: clash } : {},
328
+ ...await isFast(root, c, types) ? {
329
+ fast: true,
330
+ .../^state: done$/m.test(await readFile(join(changesDirOf(root), c.id, "stage", "small.yaml"), "utf8").catch(() => "")) ? { fastDone: true } : {}
331
+ } : {},
332
+ ...needs ? {
333
+ needs: {
334
+ open: open2.length,
335
+ ...longest?.days ? { longest: `${longest.n.title}, ${longest.n.leadTime}` } : {}
336
+ }
337
+ } : {}
338
+ });
339
+ }
340
+ } catch (e) {
341
+ problems.push({ file: "openspec/changes", message: e.message.split("\n")[0] });
342
+ }
343
+ return {
344
+ repos,
345
+ catalogRecords: view.catalog.records,
346
+ // ADR 0140 (Q3): in the order to ask them, what a change in flight rests on first.
347
+ openQuestions: orderQuestions(open.questions, await questionWeights(root, open.questions).catch(() => /* @__PURE__ */ new Map())).map((q) => q.id),
348
+ ...Object.keys(changeQuestions).length ? { changeQuestions } : {},
349
+ ...active ? { active: active.id } : {},
350
+ sources,
351
+ changes,
352
+ problems,
353
+ ...orgpack ? { orgpack } : {},
354
+ ...unverifiedNeeds ? { unverifiedNeeds } : {}
355
+ };
356
+ }
357
+ var UNDER_WAY = /* @__PURE__ */ new Set(["drafting", "waiting", "questions", "stopped"]);
358
+ async function stageInProgress(root, change) {
359
+ const dir = join(changesDirOf(root), change, "stage");
360
+ let newest;
361
+ for (const f of (await readdir(dir).catch(() => [])).filter((x) => x.endsWith(".yaml"))) {
362
+ const loop = await readFile(join(dir, f), "utf8").then((t) => {
363
+ try {
364
+ return (0, import_yaml.parse)(t);
365
+ } catch {
366
+ return null;
367
+ }
368
+ }, () => null);
369
+ const at = typeof loop?.updatedAt === "string" ? loop.updatedAt : "";
370
+ if (typeof loop?.state === "string" && UNDER_WAY.has(loop.state) && (!newest || at > newest))
371
+ newest = at || "0";
372
+ }
373
+ return newest;
374
+ }
375
+ async function loopState(root, change, stage) {
376
+ const t = await readFile(join(changesDirOf(root), change, "stage", `${stage}.yaml`), "utf8").catch(() => void 0);
377
+ if (t === void 0)
378
+ return void 0;
379
+ try {
380
+ const s = (0, import_yaml.parse)(t)?.state;
381
+ return typeof s === "string" ? s : void 0;
382
+ } catch {
383
+ return void 0;
384
+ }
385
+ }
386
+ async function stageQuestions(root, change, open) {
387
+ const out = [];
388
+ for (const s of DRAFTING) {
389
+ const t = await readFile(join(changesDirOf(root), change, "stage", `${s}.yaml`), "utf8").catch(() => "");
390
+ let y;
391
+ try {
392
+ y = (0, import_yaml.parse)(t);
393
+ } catch {
394
+ continue;
395
+ }
396
+ if (Array.isArray(y?.questions)) {
397
+ for (const q of y.questions)
398
+ if (typeof q === "string" && open.has(q))
399
+ out.push(q);
400
+ }
401
+ }
402
+ return out;
403
+ }
404
+ async function isFast(root, c, types) {
405
+ const type = types.find((t) => t.id === c.type);
406
+ if (!type || type.size !== "small" && !type.smallWhenBriefSays)
407
+ return false;
408
+ const brief = await readFile(join(changesDirOf(root), c.id, "brief.md"), "utf8").catch(() => "");
409
+ return fastPathOf(type, brief).fast;
410
+ }
411
+ async function draftMissing(ctx, c) {
412
+ const a = await assess(await ctx(), c);
413
+ return {
414
+ draft: a.blockers.some((b) => b.code === "missing-artifact" && (b.artifact === "proposal" || b.artifact === "specs")),
415
+ brief: a.blockers.some((b) => (b.code === "missing-artifact" || b.code === "unfilled-artifact") && b.artifact === "brief")
416
+ };
417
+ }
418
+ async function blockingOf(ctx, c) {
419
+ const a = await assess(await ctx(), c);
420
+ return a.blockers.filter((b) => b.code === "blocking-finding" || b.code === "open-gap").length;
421
+ }
422
+ async function gateFindingsOf(ctx, c) {
423
+ const a = await assess(await ctx(), c);
424
+ return a.blockers.flatMap((b) => b.code === "blocking-finding" || b.code === "open-gap" ? [{ code: b.code, ...b.finding ? { finding: b.finding } : {}, message: b.message }] : []);
425
+ }
426
+ function gateBlockedStep(c, stage, gate) {
427
+ const first = c.gate?.[0];
428
+ if (!first)
429
+ return void 0;
430
+ const id = c.id;
431
+ const more = c.gate.length - 1;
432
+ const head = `${id}'s ${stage} stage is done, but the ${gate} gate is blocked, so its hand-off would be refused: ${first.message.replace(/\.?$/, ".")}`;
433
+ const tail = more ? `; ${more} more after it.` : ".";
434
+ const asked = /\(owner question (q-[0-9a-f]+)[,)]/.exec(first.message)?.[1];
435
+ if (asked)
436
+ return {
437
+ step: "answer",
438
+ command: `atticus questions answer ${asked}`,
439
+ where: METAREPO,
440
+ why: `${head} Its owner answers ${asked} (Questions, Owner questions), and the answer closes the gap${tail}`,
441
+ person: true,
442
+ change: id
443
+ };
444
+ const f = first.finding ?? "<id>";
445
+ if (first.code === "open-gap")
446
+ return {
447
+ step: "finding",
448
+ command: `atticus finding ${id} ${f} ask`,
449
+ where: METAREPO,
450
+ why: `${head} Ask its owner (atticus finding ${id} ${f} ask --asked-of <who>), or fill it in (atticus finding ${id} ${f} edit-and-apply)${tail}`,
451
+ person: true,
452
+ change: id
453
+ };
454
+ return {
455
+ step: "finding",
456
+ command: `atticus finding ${id} ${f} edit-and-apply`,
457
+ where: METAREPO,
458
+ why: `${head} Fix it (atticus finding ${id} ${f} edit-and-apply), or record why it doesn't apply (not-relevant --reason, or waive)${tail}`,
459
+ person: true,
460
+ change: id
461
+ };
462
+ }
463
+ async function releasedOf(root, id) {
464
+ try {
465
+ const { archiveGate } = await import("./chunk-5BD2KYLE.js");
466
+ const g = await archiveGate(root, id);
467
+ return {
468
+ released: { blockers: g.blockers.map((b) => ({ code: b.code, message: b.message })) }
469
+ };
470
+ } catch {
471
+ return { released: { blockers: [] } };
472
+ }
473
+ }
474
+ function releasedSteps(c) {
475
+ const id = c.id;
476
+ const blockers = c.released?.blockers ?? [];
477
+ const repoOf = (m) => /^([A-Za-z0-9][\w.-]*): /.exec(m)?.[1];
478
+ const reads = [];
479
+ for (const b of blockers) {
480
+ const repo = repoOf(b.message);
481
+ if (!repo)
482
+ continue;
483
+ if (b.code === "needs-reading")
484
+ reads.push({
485
+ step: "reread",
486
+ command: `atticus map ${repo}`,
487
+ slash: `/atticus-map ${repo}`,
488
+ where: METAREPO,
489
+ why: `${id} is released, and the archive gate needs what shipped read: ${b.message}`,
490
+ repo,
491
+ change: id
492
+ });
493
+ else if (b.code === "catalog-stale")
494
+ reads.push({
495
+ step: "verify",
496
+ command: `atticus verify ${repo} --write`,
497
+ where: METAREPO,
498
+ why: `${id} is released, and the archive gate needs the catalog written from what shipped: ${b.message}`,
499
+ repo,
500
+ change: id
501
+ });
502
+ else if (b.code === "not-synced")
503
+ reads.push({
504
+ step: "sync",
505
+ command: `atticus workspace sync --repos ${repo}`,
506
+ where: METAREPO,
507
+ why: `${id} is released, and the archive gate needs ${repo}'s clone at what merged: ${b.message}`,
508
+ repo,
509
+ change: id
510
+ });
511
+ }
512
+ const others = blockers.filter((b) => !repoOf(b.message) || !["needs-reading", "catalog-stale", "not-synced"].includes(b.code));
513
+ if (others.length)
514
+ return [
515
+ ...reads,
516
+ {
517
+ step: "archive-gate",
518
+ command: `atticus ci archive-gate ${id}`,
519
+ where: METAREPO,
520
+ why: `${id} is released, but the archive gate doesn't pass yet: ${others.map((b) => b.message).join(" ")}`,
521
+ change: id,
522
+ person: true
523
+ }
524
+ ];
525
+ return [
526
+ ...reads,
527
+ {
528
+ step: "archive",
529
+ command: `atticus change archive ${id}`,
530
+ where: METAREPO,
531
+ why: reads.length ? `Then a person archives ${id} (its spec deltas merge into openspec/specs/ and the estate is scanned again).` : `${id} is released and the archive gate passes: a person archives it (its spec deltas merge into openspec/specs/ and the estate is scanned again, so the catalog says what shipped).`,
532
+ change: id,
533
+ person: true
534
+ }
535
+ ];
536
+ }
537
+ async function releasePrsOf(root, id) {
538
+ const reasons = await releasePrReasons(root, id).catch(() => []);
539
+ if (reasons.some((r) => r.code === "release-pr-missing" || r.code === "release-pr-stale"))
540
+ return { releasePrs: "raise" };
541
+ if (reasons.some((r) => r.code === "release-pr-not-merged"))
542
+ return { releasePrs: "merge" };
543
+ return {};
544
+ }
545
+ function stageOf(state) {
546
+ switch (state) {
547
+ case "draft":
548
+ case "define":
549
+ case "returned":
550
+ return "feature";
551
+ case "design":
552
+ return "architecture";
553
+ case "plan":
554
+ return "stories";
555
+ case "build":
556
+ case "qa":
557
+ return "tasks";
558
+ case "released":
559
+ case "archived":
560
+ return "done";
561
+ default:
562
+ return "release";
563
+ }
564
+ }
565
+ function changeSteps(c) {
566
+ if (c.state === "released")
567
+ return releasedSteps(c);
568
+ const stage = stageSteps(c);
569
+ const id = c.id;
570
+ const done = stageOf(c.state) === "done";
571
+ const find = c.feature && c.knowledge && !c.needs && !done ? [
572
+ {
573
+ step: "needs",
574
+ command: `atticus change needs ${id}`,
575
+ slash: `/atticus-needs ${id}`,
576
+ where: METAREPO,
577
+ why: `${id} is placed on the estate: your assistant says what it needs from the organisation (requests and processes to raise, standards to follow, teams to involve), and Atticus checks each against the change's own words (ADR 0101).`,
578
+ change: id
579
+ }
580
+ ] : [];
581
+ const raise = c.needs?.open && !done ? [
582
+ {
583
+ step: "raise-needs",
584
+ command: `atticus needs --change ${id}`,
585
+ where: METAREPO,
586
+ why: `${plural(c.needs.open, "need")} of ${id} ${c.needs.open === 1 ? "is" : "are"} open${c.needs.longest ? ` (the longest: ${c.needs.longest})` : ""}. Raise each, then record it with atticus needs done ${id} <item>.`,
587
+ change: id,
588
+ person: true
589
+ }
590
+ ] : [];
591
+ const seeds = done ? [] : [...new Set((c.seedCollisions ?? []).map((x) => x.repo))].sort().map((repo) => {
592
+ const xs = c.seedCollisions.filter((x) => x.repo === repo);
593
+ return {
594
+ step: "accept-seed",
595
+ command: `atticus spec accept ${repo}`,
596
+ where: METAREPO,
597
+ why: `${id} adds ${xs.map((x) => x.flow).join(", ")} as new, and ${repo}'s starting spec (${xs[0].seed}), not accepted yet, adds ${xs.length === 1 ? "it" : "them"} too: archiving both would fail on a requirement added twice. A person reads and accepts the seed. Then run the change's stories stage again (atticus plan stories ${id}) so it modifies the seeded requirement (ADR 0156).`,
598
+ person: true,
599
+ change: id,
600
+ repo
601
+ };
602
+ });
603
+ const gate = done ? [] : handoffWait(c);
604
+ if (gate.length)
605
+ return [...gate, ...find, ...raise];
606
+ const asked = done ? [] : questionStep(c);
607
+ const ownDone = (c.stagesDone ?? []).includes(stageOf(c.state));
608
+ return ownDone ? [...seeds, ...stage, ...asked, ...find, ...raise] : [...asked, ...seeds, ...stage, ...find, ...raise];
609
+ }
610
+ async function manualPrRecorded(root, change, branch, orgPack) {
611
+ const steps = await fileStepStore(root).list({ change, system: "git-host" }).catch(() => []);
612
+ const open = steps.find((x) => x.action === "open-pull-request" && x.inputs.head === branch && x.state !== "open");
613
+ if (!open)
614
+ return {};
615
+ const named = orgPack instanceof Error ? void 0 : orgPack.runtime.adapters.gitHost?.settings.metarepo;
616
+ const repo = typeof open.inputs.repo === "string" ? open.inputs.repo : void 0;
617
+ return { recorded: typeof named === "string" || !repo ? {} : { repo } };
618
+ }
619
+ function handoffWait(c) {
620
+ const h = c.handoff;
621
+ if (!h)
622
+ return [];
623
+ const id = c.id;
624
+ if (h.state === "changes-requested")
625
+ return [
626
+ {
627
+ step: "handoff",
628
+ command: `atticus change handoff ${id} --approve`,
629
+ where: METAREPO,
630
+ why: `Changes were requested on PR #${h.number} (${id}'s ${h.phase} hand-off): update the work, then a person hands it off again.`,
631
+ change: id,
632
+ person: true,
633
+ ...isManualPrUrl(h.url) ? {} : { pr: h.url }
634
+ }
635
+ ];
636
+ if (isManualPrUrl(h.url) && h.recorded)
637
+ return [
638
+ {
639
+ step: "merge",
640
+ command: `atticus change sync ${id}${h.recorded.repo ? ` --repo ${h.recorded.repo}` : ""}`,
641
+ where: METAREPO,
642
+ why: `${id}'s ${h.phase} hand-off PR is recorded on its manual steps: syncing reads what was recorded and moves the change on; once its merge is recorded, that approves the ${h.phase} gate.`,
643
+ change: id,
644
+ person: true
645
+ }
646
+ ];
647
+ if (isManualPrUrl(h.url))
648
+ return [
649
+ {
650
+ step: "merge",
651
+ command: `atticus todo --change ${id}`,
652
+ where: METAREPO,
653
+ why: `${id}'s ${h.phase} hand-off PR isn't open yet: your Git host is manual, so opening it is a step waiting on you (atticus todo, or Home \u203A Manual steps in the app). Open it on the Git host as its step says, record its link, then sync; merging it approves the ${h.phase} gate.`,
654
+ change: id,
655
+ person: true,
656
+ pr: h.url
657
+ }
658
+ ];
659
+ return [
660
+ {
661
+ step: "merge",
662
+ command: `atticus change sync ${id}`,
663
+ where: METAREPO,
664
+ why: `${id}'s ${h.phase} hand-off PR #${h.number} is raised (${h.url}): a person approves and merges it on the Git host, then syncing moves the change on (ADR 0073).`,
665
+ change: id,
666
+ person: true,
667
+ pr: h.url
668
+ }
669
+ ];
670
+ }
671
+ function questionStep(c) {
672
+ const ids = c.questions ?? [];
673
+ if (!ids.length)
674
+ return [];
675
+ const stage = stageOf(c.state);
676
+ const again = draftingAt(stage) >= 0 ? `Answer ${plural(ids.length, "question")} on Questions (or atticus questions answer <id>), then run the ${c.fast ? "fast path's one step" : `${stage} stage`} again.` : `Its stage goes on once ${ids.length === 1 ? "it is" : "they are"} answered.`;
677
+ return [
678
+ {
679
+ step: "answer",
680
+ command: "atticus questions list --state open",
681
+ slash: "/atticus-answer",
682
+ where: METAREPO,
683
+ why: `${plural(ids.length, "question")} of ${c.id} ${ids.length === 1 ? "is" : "are"} waiting for a person: ${ids.join(", ")}. ${again}`,
684
+ person: true,
685
+ change: c.id
686
+ }
687
+ ];
688
+ }
689
+ function againWhy(c, stage) {
690
+ return c.loop === "questions" && !c.questions?.length ? `The questions the ${stage} stage of ${c.id} asked are answered: run the stage again so it reads the answers (ADR 0087).` : void 0;
691
+ }
692
+ function stageSteps(c) {
693
+ const id = c.id;
694
+ const stage = stageOf(c.state);
695
+ if (c.brief && stage === "feature" && !c.stagesDone?.includes("feature"))
696
+ return [
697
+ {
698
+ step: "brief",
699
+ command: c.brief,
700
+ where: METAREPO,
701
+ why: `Write the brief of ${id} (${c.brief}): it still holds only the template. The feature stage places the change on the estate from it.`,
702
+ change: id,
703
+ person: true
704
+ }
705
+ ];
706
+ if (c.fast && (stage === "feature" || stage === "architecture" || stage === "stories"))
707
+ return c.fastDone ? [
708
+ {
709
+ step: "small-handoff",
710
+ command: `atticus change handoff ${id} --approve`,
711
+ where: METAREPO,
712
+ why: `${id}'s one step is done and nothing blocks it: a person opens its pull request, and merging it approves the plan (ADR 0113).`,
713
+ change: id,
714
+ person: true
715
+ }
716
+ ] : [
717
+ {
718
+ step: "small",
719
+ command: `atticus change small ${id}`,
720
+ slash: `/atticus-small ${id}`,
721
+ where: METAREPO,
722
+ why: `${id} is a small change: your assistant places it, writes its target flows and words its stories in one step, and Atticus runs every stage's checks and the critic at its gate (ADR 0113). Then a person approves its one pull request.`,
723
+ change: id
724
+ }
725
+ ];
726
+ if ((stage === "feature" || stage === "architecture" || stage === "stories") && c.stagesDone?.includes(stage)) {
727
+ const later = c.stagesDone.slice(c.stagesDone.indexOf(stage) + 1);
728
+ const gate = c.state === "returned" ? "define" : c.state;
729
+ if (stage === "feature" && c.undrafted)
730
+ return [
731
+ {
732
+ step: "draft",
733
+ command: `atticus change draft ${id}`,
734
+ slash: `/atticus-draft ${id}`,
735
+ where: METAREPO,
736
+ why: `${id} is placed on the estate, but its proposal or specs aren't written yet: your assistant drafts them, and Atticus checks the draft. Then a person raises the define hand-off.`,
737
+ change: id
738
+ }
739
+ ];
740
+ const blocked = gateBlockedStep(c, stage, gate);
741
+ if (blocked)
742
+ return [blocked];
743
+ return [
744
+ {
745
+ step: "handoff",
746
+ command: `atticus change handoff ${id} --approve`,
747
+ where: METAREPO,
748
+ why: `${id}'s ${stage} stage is done${later.length ? ` (and ${later.join(" and ")} ran ahead)` : ""}, but the change is still in ${c.state}: a person raises its ${gate} hand-off PR, and merging it approves the ${gate} gate and moves it on (ADR 0073).`,
749
+ change: id,
750
+ person: true
751
+ }
752
+ ];
753
+ }
754
+ switch (stage) {
755
+ case "feature":
756
+ return [
757
+ {
758
+ step: "feature",
759
+ command: `atticus change feature ${id}`,
760
+ slash: `/atticus-feature ${id}`,
761
+ where: METAREPO,
762
+ why: againWhy(c, "feature") ?? `${id} is at the feature stage: your assistant places it on the estate's flows and features, and Atticus checks and criticises every draft until nothing blocks (ADR 0087).`,
763
+ change: id
764
+ }
765
+ ];
766
+ case "architecture":
767
+ return [
768
+ // Fifth UX walk: the architecture stage reads the placed feature; without one it refuses.
769
+ ...c.feature === false ? [
770
+ {
771
+ step: "feature",
772
+ command: `atticus change feature ${id}`,
773
+ slash: `/atticus-feature ${id}`,
774
+ where: METAREPO,
775
+ why: `${id} isn't placed on the estate yet: your assistant places it on the flows and features first, then writes its target flows.`,
776
+ change: id
777
+ }
778
+ ] : [],
779
+ {
780
+ step: "architecture",
781
+ command: `atticus change architecture ${id}`,
782
+ slash: `/atticus-architecture ${id}`,
783
+ where: METAREPO,
784
+ why: againWhy(c, "architecture") ?? `${id} is at the architecture stage: your assistant writes its target flows, and Atticus checks and criticises every draft until nothing blocks (ADR 0087).`,
785
+ change: id
786
+ }
787
+ ];
788
+ case "stories":
789
+ return [
790
+ {
791
+ step: "stories",
792
+ command: `atticus plan stories ${id}`,
793
+ slash: `/atticus-stories ${id}`,
794
+ where: METAREPO,
795
+ why: againWhy(c, "stories") ?? `${id} has an approved design: write its stories and tasks.`,
796
+ change: id
797
+ }
798
+ ];
799
+ case "tasks": {
800
+ const underWay = (x) => x.run === "built" || x.run === "unverified" || x.run === "pr-open" || x.run === "waiting";
801
+ const open = c.tasks.filter((x) => !x.done);
802
+ const t = open.find((x) => !underWay(x));
803
+ const drafted = open.filter(underWay).map((x) => x.id);
804
+ const draftedNote = drafted.length ? ` ${drafted.length === 1 ? "Task" : "Tasks"} ${drafted.join(", ")} ${drafted.length === 1 ? "is" : "are"} under way: raise or merge ${drafted.length === 1 ? "its" : "their"} PR on the Task board.` : "";
805
+ if (!t && drafted.length)
806
+ return [
807
+ {
808
+ step: "tasks",
809
+ command: `atticus change status ${id}`,
810
+ where: METAREPO,
811
+ why: `Every task of ${id} not ticked is under way.${draftedNote}`,
812
+ change: id
813
+ }
814
+ ];
815
+ const handoffStep = {
816
+ step: "handoff",
817
+ command: `atticus change handoff ${id} --approve`,
818
+ where: METAREPO,
819
+ why: `Every task of ${id} is ticked: a person raises its ${c.state} hand-off PR, and merging it approves the ${c.state} gate and moves it on (ADR 0073).`,
820
+ change: id,
821
+ person: true
822
+ };
823
+ if (!t && c.blocking)
824
+ return [
825
+ {
826
+ step: "findings",
827
+ command: `atticus change status ${id}`,
828
+ where: METAREPO,
829
+ why: `Every task of ${id} is ticked, but ${plural(c.blocking, "blocking finding")} hold${c.blocking === 1 ? "s" : ""} its ${c.state} hand-off: a person resolves each (Apply fix, Not relevant or Waive, on the change's page), then raises the hand-off PR.`,
830
+ change: id,
831
+ person: true
832
+ },
833
+ handoffStep
834
+ ];
835
+ if (!t)
836
+ return [handoffStep];
837
+ return [
838
+ {
839
+ step: "task",
840
+ command: `atticus task run ${id} ${t.id}`,
841
+ slash: `/atticus-task ${id} ${t.id}`,
842
+ where: METAREPO,
843
+ why: `Task ${t.id} of ${id} in ${t.repo} is the first one not done. /atticus-task gives your assistant its context (atticus task context ${id} ${t.id}): the story, the criteria, the step with today's code and the files to change (ADR 0113).${draftedNote}`,
844
+ repo: t.repo,
845
+ change: id
846
+ }
847
+ ];
848
+ }
849
+ case "release":
850
+ if (c.releasePrs === "raise")
851
+ return [
852
+ {
853
+ step: "release-prs",
854
+ command: `atticus change release-prs ${id} --approve`,
855
+ where: METAREPO,
856
+ why: `${id}'s code reaches each repo's default branch through its release PRs: raise them (Release \u203A Raise the release PRs), then a person merges each on the Git host.`,
857
+ person: true,
858
+ change: id
859
+ }
860
+ ];
861
+ if (c.releasePrs === "merge")
862
+ return [
863
+ {
864
+ step: "release-prs-merge",
865
+ command: `atticus change sync ${id}`,
866
+ where: METAREPO,
867
+ why: `${id}'s release PRs wait on a person on the Git host: merge each, then Sync records it (Release).`,
868
+ person: true,
869
+ change: id
870
+ }
871
+ ];
872
+ return [
873
+ {
874
+ step: "release",
875
+ command: `atticus change status ${id}`,
876
+ slash: `/atticus-release ${id}`,
877
+ where: METAREPO,
878
+ why: `${id} is on its way to release: check what still blocks it.`,
879
+ change: id
880
+ }
881
+ ];
882
+ default:
883
+ return [];
884
+ }
885
+ }
886
+ function changeAnswer(c, filed) {
887
+ const id = c.id;
888
+ const ids = filed.filter((q) => !c.questions?.includes(q));
889
+ if (!ids.length)
890
+ return [];
891
+ return [
892
+ {
893
+ step: "answer",
894
+ command: "atticus questions list --state open",
895
+ slash: "/atticus-answer",
896
+ where: METAREPO,
897
+ why: `${plural(ids.length, "question")} of ${id} ${ids.length === 1 ? "is" : "are"} waiting for a person: ${ids.join(", ")}. Its stage goes on once ${ids.length === 1 ? "it is" : "they are"} answered.`,
898
+ person: true,
899
+ change: id
900
+ }
901
+ ];
902
+ }
903
+ function nearFactsWords(r) {
904
+ return (r.nearFacts ?? []).map((n) => ` No facts are filed under ${r.id}, but ${n.id} has some (${n.file}) and its id is near this one: if they are one repo, keep one id with atticus repo rename ${r.id} ${n.id} (or rename the facts to ${r.id}).`).join("");
905
+ }
906
+ function costWords(r) {
907
+ const e = r.cost?.estimated;
908
+ if (!e)
909
+ return "";
910
+ return ` Estimated about ${tokensWords(e.tokens)} tokens in ${e.sessions} session${e.sessions === 1 ? "" : "s"} (atticus map ${r.id} --estimate; an estimate, not a meter).`;
911
+ }
912
+ function nextSteps(s) {
913
+ const out = [];
914
+ const byChange = s.changeQuestions ?? {};
915
+ const inHand = s.active ? s.changes.find((c) => c.id === s.active) : void 0;
916
+ if (inHand && stageOf(inHand.state) !== "done")
917
+ out.push(...changeAnswer(inHand, byChange[inHand.id] ?? []), ...changeSteps(inHand));
918
+ const ofChanges = /* @__PURE__ */ new Set([
919
+ ...Object.values(byChange).flat(),
920
+ ...s.changes.filter((c) => stageOf(c.state) !== "done").flatMap((c) => c.questions ?? [])
921
+ ]);
922
+ const repoQuestions = s.openQuestions.filter((id) => !ofChanges.has(id));
923
+ if (s.repos.length === 0 && !inHand) {
924
+ out.push({
925
+ step: "discover",
926
+ command: "atticus repos discover <folder>",
927
+ why: "No repo is listed yet. Propose the manifest from a folder of clones or your Git host's organisation (--org)."
928
+ });
929
+ return out;
930
+ }
931
+ const notCloned = s.repos.filter((r) => !r.cloned);
932
+ if (notCloned.length)
933
+ out.push({
934
+ step: "sync",
935
+ command: "atticus workspace sync",
936
+ why: `${plural(notCloned.length, "repo")} ${notCloned.length === 1 ? "isn't" : "aren't"} cloned yet: ${notCloned.map((r) => r.id).join(", ")}.`
937
+ });
938
+ const unread = s.repos.filter((r) => r.cloned && !r.facts && !r.scanned).sort((a, b) => (a.queue?.order ?? Infinity) - (b.queue?.order ?? Infinity));
939
+ for (const r of unread)
940
+ out.push(r.read ? {
941
+ step: "write",
942
+ command: `atticus verify ${r.id} --write`,
943
+ why: `${r.id} is read: atticus verify ${r.id} --write checks its facts against the code, then puts them in the catalog and renders its map.`,
944
+ repo: r.id
945
+ } : {
946
+ step: "map",
947
+ command: `atticus map ${r.id}`,
948
+ slash: `/atticus-map ${r.id}`,
949
+ where: METAREPO,
950
+ // A-ledger: a repo read in parts says which part comes next, so nobody keeps the list.
951
+ why: (r.readPlan?.next ? `${r.id} is read in ${r.readPlan.total} parts (${r.readPlan.file}): ${partOfWords({ part: r.readPlan.next.part, total: r.readPlan.total })} is next, ${r.readPlan.done === 0 ? "none" : r.readPlan.done} ${r.readPlan.done === 1 ? "is" : "are"} read (${r.readPlan.next.paths.join(", ")}). Your assistant reads the part and writes its facts, each citing its line.` : `${r.id} isn't read yet: your assistant reads it and writes its facts, each citing its line, and atticus verify ${r.id} checks them.`) + // Only a reason that moved it up the queue is worth a sentence here; --queue says all.
952
+ (r.queue && (r.queue.reason === "called" || r.queue.reason === "gateway" || r.queue.reason === "places") ? ` ${r.queue.why}` : "") + costWords(r) + houseUntaughtWords(r.id, r.houseUntaught ?? []) + nearFactsWords(r),
953
+ repo: r.id
954
+ });
955
+ for (const r of s.repos.filter((x) => x.cloned && x.facts && x.stale))
956
+ out.push({
957
+ step: "reread",
958
+ command: `atticus map ${r.id}`,
959
+ slash: `/atticus-map ${r.id}`,
960
+ where: METAREPO,
961
+ why: `${r.id}'s clone moved past its facts' commit (facts ${r.stale.facts.slice(0, 12)}, clone ${r.stale.head.slice(0, 12)}): atticus estate fresh says how many facts to read again; your assistant reads only the files that changed.`,
962
+ repo: r.id
963
+ });
964
+ for (const r of s.repos.filter((x) => x.cloned && x.read && x.rules?.length))
965
+ out.push({
966
+ step: "rules",
967
+ command: `atticus map ${r.id} --rules`,
968
+ slash: `/atticus-map ${r.id} --rules`,
969
+ where: METAREPO,
970
+ why: `${r.id} was read before reading rules added since (${r.rules.join(", ")}): your assistant reads only the files they apply to, for what they ask, and atticus verify ${r.id} records the rules. atticus map --all --stale tops up every such repo.`,
971
+ repo: r.id
972
+ });
973
+ const cloned = s.repos.filter((r) => r.cloned && !r.facts && r.scanned);
974
+ for (const r of cloned.filter((x) => !x.settings))
975
+ out.push({
976
+ step: "survey",
977
+ command: `atticus scan survey ${r.id}`,
978
+ slash: `/atticus-survey ${r.id}`,
979
+ where: METAREPO,
980
+ why: `${r.id} has no scan settings yet: your assistant reads it and drafts them, and Atticus checks each entry against the code.`,
981
+ repo: r.id
982
+ });
983
+ if (cloned.length && s.catalogRecords === 0)
984
+ out.push({
985
+ step: "scan",
986
+ command: "atticus scan",
987
+ why: "The catalog is empty: scan the repos into it."
988
+ });
989
+ const scanned = cloned;
990
+ for (const r of scanned)
991
+ if (r.verify === "none")
992
+ out.push({
993
+ step: "verify",
994
+ command: `atticus scan verify ${r.id}`,
995
+ slash: `/atticus-verify ${r.id}`,
996
+ where: METAREPO,
997
+ why: `The last scan of ${r.id} hasn't been verified: your assistant compares the code with what the scan recorded.`,
998
+ repo: r.id
999
+ });
1000
+ else if (r.verify === "accept")
1001
+ out.push({
1002
+ step: "accept",
1003
+ command: `atticus scan verify ${r.id} --accept`,
1004
+ why: `The verify of ${r.id} proposes scan settings entries. A person reads the proposal and accepts it.`,
1005
+ person: true,
1006
+ repo: r.id
1007
+ });
1008
+ const undescribed = s.repos.filter((r) => r.described === "none");
1009
+ if (undescribed.length)
1010
+ out.push({
1011
+ step: "describe",
1012
+ command: `atticus repo describe ${undescribed[0].id} --description "what it is"`,
1013
+ why: `${plural(undescribed.length, "repo")} ${undescribed.length === 1 ? "doesn't say" : "don't say"} what ${undescribed.length === 1 ? "it is" : "they are"}: ${undescribed.map((r) => r.id).join(", ")}. One line each is carried into every reading prompt, the join's questions and the views, so an opaque id can be read and placed.`,
1014
+ person: true,
1015
+ ...undescribed.length === 1 ? { repo: undescribed[0].id } : {}
1016
+ });
1017
+ const drafted = s.repos.filter((r) => r.described === "draft");
1018
+ if (drafted.length)
1019
+ out.push({
1020
+ step: "describe-accept",
1021
+ command: `atticus repo describe ${drafted[0].id} --accept`,
1022
+ why: `Your assistant drafted what ${drafted.length === 1 ? "this repo is" : "these repos are"} and nobody has confirmed ${drafted.length === 1 ? "it" : "them"}: ${drafted.map((r) => r.id).join(", ")}. Until a person does, each is shown as unconfirmed everywhere it is used.`,
1023
+ person: true,
1024
+ ...drafted.length === 1 ? { repo: drafted[0].id } : {}
1025
+ });
1026
+ if (repoQuestions.length)
1027
+ out.push({
1028
+ step: "answer",
1029
+ command: "atticus questions list --state open",
1030
+ slash: "/atticus-answer",
1031
+ where: METAREPO,
1032
+ why: `${plural(repoQuestions.length, "question")} ${repoQuestions.length === 1 ? "is" : "are"} waiting for a person: ${repoQuestions.join(", ")}. The steps that asked go on once they are answered.`,
1033
+ person: true
1034
+ });
1035
+ for (const r of scanned) {
1036
+ const slash = { slash: `/atticus-spec ${r.id}`, where: METAREPO, repo: r.id };
1037
+ if (r.flows === 0)
1038
+ out.push({
1039
+ step: "spec",
1040
+ command: `atticus spec draft ${r.id}`,
1041
+ ...slash,
1042
+ why: `${r.id} has no spec yet: your assistant writes its flows, one per trigger, each step cited.`
1043
+ });
1044
+ else if (!r.checked)
1045
+ out.push({
1046
+ step: "spec-check",
1047
+ command: `atticus spec check ${r.id}`,
1048
+ ...slash,
1049
+ why: `The spec of ${r.id} hasn't been checked since its last draft.`
1050
+ });
1051
+ else if (r.findings > 0)
1052
+ out.push({
1053
+ step: "spec",
1054
+ command: `atticus spec draft ${r.id}`,
1055
+ ...slash,
1056
+ why: `The last spec check of ${r.id} found ${plural(r.findings, "problem")}: draft the flagged flows again, then check.`
1057
+ });
1058
+ }
1059
+ for (const k of s.sources)
1060
+ if (!k.snapshot)
1061
+ out.push({
1062
+ step: "sync-source",
1063
+ command: `atticus sources sync --source ${k.id}`,
1064
+ slash: `/atticus-knowledge ${k.id}`,
1065
+ where: METAREPO,
1066
+ why: `The knowledge source ${k.id} has no snapshot yet: copy its pages, then read them into knowledge items.`,
1067
+ source: k.id
1068
+ });
1069
+ else if (!k.scanned)
1070
+ out.push({
1071
+ step: "knowledge",
1072
+ command: `atticus knowledge scan --source ${k.id}`,
1073
+ slash: `/atticus-knowledge ${k.id}`,
1074
+ where: METAREPO,
1075
+ why: `The newest snapshot of ${k.id} hasn't been read into knowledge items yet.`,
1076
+ source: k.id
1077
+ });
1078
+ else if ((k.age ?? 0) > STALE_DAYS)
1079
+ out.push({
1080
+ step: "sync-source",
1081
+ command: `atticus sources sync --source ${k.id}`,
1082
+ slash: `/atticus-knowledge ${k.id}`,
1083
+ where: METAREPO,
1084
+ why: `The newest snapshot of ${k.id} is ${k.age} days old: sync it again, and a rescan reads only the pages that changed (ADR 0101).`,
1085
+ source: k.id
1086
+ });
1087
+ if (s.orgpack?.draft)
1088
+ out.push({
1089
+ step: "accept-orgpack",
1090
+ command: `atticus orgpack accept ${s.orgpack.draft.platform}`,
1091
+ why: `A draft of the ${s.orgpack.draft.platform} profile has ${plural(s.orgpack.draft.proposals, "system")} from the wikis waiting: read it (proposals/orgpack/${s.orgpack.draft.platform}.md) and accept what is right, with --only or --verified-only.`,
1092
+ person: true
1093
+ });
1094
+ else if (s.orgpack?.missing)
1095
+ out.push({
1096
+ step: "orgpack-draft",
1097
+ command: "atticus orgpack draft",
1098
+ why: `The wikis name ${plural(s.orgpack.missing, "product or vendor", "products and vendors")} that no profile has yet: draft them into the org pack, with their aliases and owners.`
1099
+ });
1100
+ if (s.unverifiedNeeds)
1101
+ out.push({
1102
+ step: "verify-knowledge",
1103
+ command: "atticus knowledge list --unverified",
1104
+ why: `${plural(s.unverifiedNeeds, "open need")} of changes ${s.unverifiedNeeds === 1 ? "comes" : "come"} from knowledge items no person has verified: check each against its page (atticus knowledge verify, correct or reject).`,
1105
+ person: true
1106
+ });
1107
+ const inFlight = s.changes.filter((c) => stageOf(c.state) !== "done" || c.state === "released");
1108
+ for (const c of inFlight)
1109
+ if (c !== inHand)
1110
+ out.push(...changeAnswer(c, byChange[c.id] ?? []), ...changeSteps(c));
1111
+ if (!inFlight.length)
1112
+ out.push({
1113
+ step: "new-change",
1114
+ command: 'atticus change new "<title>" --type <type>',
1115
+ why: out.length ? "Then start a change: no change is in flight." : "Everything is onboarded, checked and answered, and no change is in flight. Start one."
1116
+ });
1117
+ return out;
1118
+ }
1119
+ async function nextCommand(root, o, io) {
1120
+ if (!isMetarepo(root)) {
1121
+ io.err(notMetarepo(root));
1122
+ return 2;
1123
+ }
1124
+ const state = await readNextState(root);
1125
+ if (o.queue)
1126
+ return queueOut(state, o, io);
1127
+ const steps = nextSteps(state);
1128
+ const runtime = await loadOrgPack(orgPackDirOf(root)).then((op) => op.runtime).catch(() => void 0);
1129
+ const probes = (await readProbes(root)).results;
1130
+ const probed = runtime ? probedAssistant(runtime, probes) : [...probes].sort((a, b) => b.measured.localeCompare(a.measured))[0]?.assistant;
1131
+ const assistant = probed ?? runtime?.assistants.default ?? "copilot";
1132
+ if (o.json) {
1133
+ const runs = runtime ? whatRunsWhere(runtime, { probes }) : void 0;
1134
+ const modelMode = !!runtime && runtime.ai !== "off" && runtime.modes.allowed.includes("model") && !!runtime.adapters.model && runtime.adapters.model.type !== "mock";
1135
+ const classed = steps.map((x) => {
1136
+ const c = x.person ? void 0 : stepClassOfNextStep(x.step);
1137
+ return c ? { ...x, stepClass: c } : x;
1138
+ });
1139
+ const orgModels = stepModelsOf(runtime);
1140
+ io.out(JSON.stringify({
1141
+ next: classed[0],
1142
+ steps: classed,
1143
+ problems: state.problems,
1144
+ ...runs ? { runs } : {},
1145
+ modelMode,
1146
+ assistant,
1147
+ ...Object.keys(orgModels).length ? { orgModels } : {}
1148
+ }, null, 2));
1149
+ return 0;
1150
+ }
1151
+ for (const p of state.problems)
1152
+ io.err(`Couldn't read ${p.file}: ${p.message}`);
1153
+ const typeIn = ASSISTANT_FORMATS[assistant].typeIn;
1154
+ const slashLine = (x) => x.slash ? `In ${typeIn}${x.where && x.where !== METAREPO ? ` in ${x.where}` : ""}: ${x.slash}` : void 0;
1155
+ if (!o.all) {
1156
+ const n = steps[0];
1157
+ io.out(`Next: ${n.command}`);
1158
+ const sl = slashLine(n);
1159
+ if (sl)
1160
+ io.out(sl);
1161
+ io.out(`Why: ${n.why}`);
1162
+ if (steps.length > 1)
1163
+ io.out(`${plural(steps.length - 1, "more step")} after this one: atticus next --all`);
1164
+ return 0;
1165
+ }
1166
+ steps.forEach((x, i) => {
1167
+ io.out(`${i + 1}. ${x.command}`);
1168
+ const sl = slashLine(x);
1169
+ if (sl)
1170
+ io.out(` ${sl}`);
1171
+ io.out(` ${x.why}`);
1172
+ });
1173
+ return 0;
1174
+ }
1175
+ function queueOut(s, o, io) {
1176
+ const waiting = s.repos.filter((r) => r.queue).sort((a, b) => a.queue.order - b.queue.order);
1177
+ const read = s.repos.filter((r) => r.facts);
1178
+ if (o.json) {
1179
+ io.out(JSON.stringify({
1180
+ queue: waiting.map((r) => ({
1181
+ repo: r.id,
1182
+ order: r.queue.order + 1,
1183
+ reason: r.queue.reason,
1184
+ why: r.queue.why,
1185
+ command: `atticus map ${r.id}`,
1186
+ slash: `/atticus-map ${r.id}`,
1187
+ ...r.cost ? { cost: r.cost } : {}
1188
+ })),
1189
+ read: read.map((r) => ({
1190
+ repo: r.id,
1191
+ ...r.cost ? { cost: r.cost } : {},
1192
+ ...r.stale ? { stale: r.stale } : {}
1193
+ })),
1194
+ problems: s.problems
1195
+ }, null, 2));
1196
+ return 0;
1197
+ }
1198
+ for (const p of s.problems)
1199
+ io.err(`Couldn't read ${p.file}: ${p.message}`);
1200
+ io.out(waiting.length ? `${plural(waiting.length, "repo")} to read, in the order that lands links early (callees and gateways first):` : "No repo is waiting to be read.");
1201
+ waiting.forEach((r, i) => io.out(` ${i + 1}. ${r.id}: ${r.queue.why} ${r.cost?.estimated ? `Cost: ${readCostWords(r.cost)}.` : `Cost: not estimated yet (atticus map ${r.id} --estimate).`}`));
1202
+ if (read.length) {
1203
+ io.out(`${plural(read.length, "repo")} read:`);
1204
+ for (const r of read)
1205
+ io.out(` ${r.id}: ${r.cost ? readCostWords(r.cost) || "no cost on file" : "no cost on file (read before Atticus recorded one)"}${r.stale ? `; its clone moved past its facts' commit: atticus estate fresh` : ""}`);
1206
+ }
1207
+ io.out("Tokens estimated are counted from the source; reported ones are your assistant's word (atticus map <repo> --spent); Atticus meters neither.");
1208
+ return 0;
1209
+ }
1210
+
1211
+ export {
1212
+ readNextState,
1213
+ changeSteps,
1214
+ nextSteps,
1215
+ nextCommand
1216
+ };