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

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 (475) 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-23W7VWKR.js +2609 -0
  6. package/dist/chunk-27NKUS3X.js +4330 -0
  7. package/dist/chunk-2ANOROX3.js +2522 -0
  8. package/dist/chunk-2BF2EYJV.js +174 -0
  9. package/dist/chunk-2BFCZ3RK.js +315 -0
  10. package/dist/chunk-2DIQQJCB.js +378 -0
  11. package/dist/chunk-2RMYG36Q.js +1227 -0
  12. package/dist/chunk-2VHF7OXM.js +55 -0
  13. package/dist/chunk-3ALD2W2A.js +95 -0
  14. package/dist/chunk-3C7EYRFZ.js +41 -0
  15. package/dist/chunk-3G4YI4ZU.js +16 -0
  16. package/dist/chunk-3HI6Z55Y.js +5949 -0
  17. package/dist/chunk-3USYZGRF.js +324 -0
  18. package/dist/chunk-42EVSKME.js +37 -0
  19. package/dist/chunk-4AK7IBVP.js +915 -0
  20. package/dist/chunk-4BKGMUIK.js +53 -0
  21. package/dist/chunk-4BN53TG3.js +343 -0
  22. package/dist/chunk-4NDAAFQT.js +103 -0
  23. package/dist/chunk-4Q3NN7VF.js +32 -0
  24. package/dist/chunk-4RS5KZQD.js +25 -0
  25. package/dist/chunk-4SKZDI62.js +22 -0
  26. package/dist/chunk-4WBVUHXN.js +69 -0
  27. package/dist/chunk-5GDRCDQB.js +32 -0
  28. package/dist/chunk-5GGOLAKC.js +856 -0
  29. package/dist/chunk-5KLGBXG5.js +48 -0
  30. package/dist/chunk-5WG5YP4T.js +34 -0
  31. package/dist/chunk-64EQYWCA.js +180 -0
  32. package/dist/chunk-652QWTLZ.js +242 -0
  33. package/dist/chunk-65NYPGRC.js +766 -0
  34. package/dist/chunk-66YVAGGM.js +46 -0
  35. package/dist/chunk-6BNC6EQ4.js +41 -0
  36. package/dist/chunk-6BVONWJ7.js +50 -0
  37. package/dist/chunk-6D2CQ5II.js +41 -0
  38. package/dist/chunk-6IU67AEK.js +325 -0
  39. package/dist/chunk-6J5OKA4Y.js +49 -0
  40. package/dist/chunk-6JCPI55B.js +92 -0
  41. package/dist/chunk-6JUBZBMW.js +56 -0
  42. package/dist/chunk-6M5NK3K3.js +415 -0
  43. package/dist/chunk-6QSERWXH.js +53 -0
  44. package/dist/chunk-6TACQN3N.js +41 -0
  45. package/dist/chunk-76WKMA4J.js +14 -0
  46. package/dist/chunk-7AVHLZGD.js +45 -0
  47. package/dist/chunk-7EFILTCI.js +67 -0
  48. package/dist/chunk-7EKXJZ2Y.js +2902 -0
  49. package/dist/chunk-7EOBHUMC.js +133 -0
  50. package/dist/chunk-7FBGJFEE.js +66 -0
  51. package/dist/chunk-7JUKDRSZ.js +1726 -0
  52. package/dist/chunk-7SW2QWLU.js +212 -0
  53. package/dist/chunk-7WD63HU2.js +143 -0
  54. package/dist/chunk-7ZUIMTOU.js +108 -0
  55. package/dist/chunk-A3GY6SOA.js +95 -0
  56. package/dist/chunk-A7UPUQFY.js +2356 -0
  57. package/dist/chunk-AA6YULYB.js +376 -0
  58. package/dist/chunk-ABWHYWNI.js +101 -0
  59. package/dist/chunk-AIOQPLA5.js +540 -0
  60. package/dist/chunk-AVJDSJ2F.js +18 -0
  61. package/dist/chunk-B2WLAWNJ.js +374 -0
  62. package/dist/chunk-BKVWTZ6A.js +211 -0
  63. package/dist/chunk-BOHJZTEQ.js +1991 -0
  64. package/dist/chunk-BWZ77RQT.js +25 -0
  65. package/dist/chunk-C6EKFH7J.js +169 -0
  66. package/dist/chunk-CAQZUNOH.js +1150 -0
  67. package/dist/chunk-CEXSU4S6.js +1217 -0
  68. package/dist/chunk-CKSITVS4.js +16101 -0
  69. package/dist/chunk-CNUKCS2T.js +2741 -0
  70. package/dist/chunk-CPA6HPVR.js +3206 -0
  71. package/dist/chunk-CR3MTH32.js +207 -0
  72. package/dist/chunk-CSZ4C5N6.js +307 -0
  73. package/dist/chunk-D3PO4DOZ.js +261 -0
  74. package/dist/chunk-D46WUV3T.js +33 -0
  75. package/dist/chunk-DE76JROX.js +80 -0
  76. package/dist/chunk-DFBCSHVT.js +69 -0
  77. package/dist/chunk-DHPACDG7.js +104 -0
  78. package/dist/chunk-DKJA76CJ.js +113 -0
  79. package/dist/chunk-DPUYDDQG.js +164 -0
  80. package/dist/chunk-DPZHZQKE.js +285 -0
  81. package/dist/chunk-E36QOJMD.js +47 -0
  82. package/dist/chunk-EADP3PEN.js +450 -0
  83. package/dist/chunk-EBEW3XXQ.js +166 -0
  84. package/dist/chunk-EDS2L2LD.js +106 -0
  85. package/dist/chunk-EFHQ3TWP.js +637 -0
  86. package/dist/chunk-EPTBZ3GP.js +101 -0
  87. package/dist/chunk-EYWIDJFU.js +130 -0
  88. package/dist/chunk-F7HYOUFF.js +287 -0
  89. package/dist/chunk-FHH4I4ZV.js +128 -0
  90. package/dist/chunk-FITWGOJ2.js +131 -0
  91. package/dist/chunk-FQXYPF7E.js +147 -0
  92. package/dist/chunk-G2B4ZQGH.js +240 -0
  93. package/dist/chunk-GBRFVT63.js +45 -0
  94. package/dist/chunk-GDLULHTC.js +2919 -0
  95. package/dist/chunk-GLUX4EEP.js +583 -0
  96. package/dist/chunk-GQ4N4WKF.js +1142 -0
  97. package/dist/chunk-GT4I4ZWM.js +38 -0
  98. package/dist/chunk-HFQCFSJR.js +60 -0
  99. package/dist/chunk-HITVBIJS.js +1247 -0
  100. package/dist/chunk-HLJAXMM4.js +233 -0
  101. package/dist/chunk-HVUPKCGJ.js +162 -0
  102. package/dist/chunk-I3E7CX4H.js +155 -0
  103. package/dist/chunk-I4JRCD6M.js +184 -0
  104. package/dist/chunk-ICY36XCH.js +34 -0
  105. package/dist/chunk-IHMLFRVV.js +228 -0
  106. package/dist/chunk-IPKHE5D6.js +1963 -0
  107. package/dist/chunk-J4K3KVLD.js +131 -0
  108. package/dist/chunk-JBTK5OP2.js +55 -0
  109. package/dist/chunk-JCZIKA4C.js +163 -0
  110. package/dist/chunk-JGZCG5VM.js +189 -0
  111. package/dist/chunk-JIITQXFB.js +4087 -0
  112. package/dist/chunk-JMSCMUCA.js +271 -0
  113. package/dist/chunk-JZU3H6UQ.js +54 -0
  114. package/dist/chunk-K65BJIMT.js +49 -0
  115. package/dist/chunk-KEM4SDDP.js +3898 -0
  116. package/dist/chunk-KQDZXGNR.js +14 -0
  117. package/dist/chunk-L24C55VN.js +7923 -0
  118. package/dist/chunk-L6SGQIR3.js +471 -0
  119. package/dist/chunk-LR3R6Z2A.js +400 -0
  120. package/dist/chunk-M766ZJ6W.js +119 -0
  121. package/dist/chunk-MC3H7736.js +19910 -0
  122. package/dist/chunk-MGYZM27B.js +205 -0
  123. package/dist/chunk-MMOSZPWJ.js +273 -0
  124. package/dist/chunk-MVZVGYXH.js +1611 -0
  125. package/dist/chunk-N7IXEHK3.js +549 -0
  126. package/dist/chunk-NE2W3OO7.js +230 -0
  127. package/dist/chunk-NN2ZQEB4.js +38 -0
  128. package/dist/chunk-NXFPS2LR.js +182 -0
  129. package/dist/chunk-O3WI5KWW.js +31 -0
  130. package/dist/chunk-OLQJTJJU.js +76 -0
  131. package/dist/chunk-ONLS5QA5.js +102 -0
  132. package/dist/chunk-OT2O76OS.js +1496 -0
  133. package/dist/chunk-PAMPPUR6.js +4500 -0
  134. package/dist/chunk-PCOCACY3.js +385 -0
  135. package/dist/chunk-PCVDV3UZ.js +430 -0
  136. package/dist/chunk-PRPPGYZG.js +104 -0
  137. package/dist/chunk-Q4D5X7QB.js +264 -0
  138. package/dist/chunk-Q5AMFEWD.js +119 -0
  139. package/dist/chunk-QRAOANID.js +214 -0
  140. package/dist/chunk-QSXK2RGH.js +688 -0
  141. package/dist/chunk-QZSX3F7C.js +389 -0
  142. package/dist/chunk-R6RY4Q5T.js +51 -0
  143. package/dist/chunk-R6XF6UR3.js +149 -0
  144. package/dist/chunk-R77KLRB3.js +166 -0
  145. package/dist/chunk-RRTKKSLQ.js +251 -0
  146. package/dist/chunk-RTEYOSJY.js +29 -0
  147. package/dist/chunk-RUVFXE2L.js +666 -0
  148. package/dist/chunk-RVH5SUW5.js +69 -0
  149. package/dist/chunk-RZPYKDWS.js +26 -0
  150. package/dist/chunk-S2A7YC3Q.js +41433 -0
  151. package/dist/chunk-S3QNRWYR.js +25 -0
  152. package/dist/chunk-SJRGMG6A.js +174 -0
  153. package/dist/chunk-SP2I63OO.js +252 -0
  154. package/dist/chunk-T2UYZSCQ.js +545 -0
  155. package/dist/chunk-T6AIP7H5.js +3851 -0
  156. package/dist/chunk-T6XQL73F.js +94 -0
  157. package/dist/chunk-TANFV3MZ.js +531 -0
  158. package/dist/chunk-TDD55CJH.js +119 -0
  159. package/dist/chunk-TV45EUGM.js +51 -0
  160. package/dist/chunk-TXLH6WHQ.js +2078 -0
  161. package/dist/chunk-TYAID7B7.js +408 -0
  162. package/dist/chunk-UBBC2XSG.js +873 -0
  163. package/dist/chunk-UGLN7QHV.js +27 -0
  164. package/dist/chunk-UNM6ZOKP.js +878 -0
  165. package/dist/chunk-V2YTAIQO.js +1075 -0
  166. package/dist/chunk-VN3DP4LQ.js +43 -0
  167. package/dist/chunk-VOGCSYOI.js +16 -0
  168. package/dist/chunk-VYDBJ73M.js +32 -0
  169. package/dist/chunk-W3BQAZ3Q.js +34 -0
  170. package/dist/chunk-W5BVQF44.js +36 -0
  171. package/dist/chunk-WVPJSRRJ.js +52 -0
  172. package/dist/chunk-WY6PP6AA.js +53 -0
  173. package/dist/chunk-XAKWMCXI.js +285 -0
  174. package/dist/chunk-XPCM366L.js +70 -0
  175. package/dist/chunk-XPTOBS2D.js +48 -0
  176. package/dist/chunk-XY3P7JW7.js +3479 -0
  177. package/dist/chunk-XZRON6IV.js +131 -0
  178. package/dist/chunk-YEDDOYSC.js +27809 -0
  179. package/dist/chunk-YISXLPHN.js +496 -0
  180. package/dist/chunk-YMZ3TNYB.js +18 -0
  181. package/dist/chunk-YY6ZQQBP.js +203 -0
  182. package/dist/chunk-YYQN46FY.js +334 -0
  183. package/dist/chunk-Z6LF7HQN.js +22 -0
  184. package/dist/chunk-ZCJDOK2S.js +116 -0
  185. package/dist/chunk-ZDPAS56H.js +76 -0
  186. package/dist/chunk-ZMAINWBW.js +18 -0
  187. package/dist/chunk-ZMFPW66A.js +22 -0
  188. package/dist/chunk-ZNCEKR4J.js +296 -0
  189. package/dist/chunk-ZVM6AKKM.js +47 -0
  190. package/dist/files.json +1888 -0
  191. package/dist/fixtures/forge/README.md +19 -0
  192. package/dist/fixtures/forge/expected/discrepancies.yaml +54 -0
  193. package/dist/fixtures/forge/expected/inputs.yaml +38 -0
  194. package/dist/fixtures/forge/expected/scan.yaml +342 -0
  195. package/dist/fixtures/forge/inputs/diagrams/forge-context.drawio +23 -0
  196. package/dist/fixtures/forge/inputs/partner-specs/northwind-pay-openapi.yaml +11 -0
  197. package/dist/fixtures/forge/inputs/tickets/ado-stories.json +4 -0
  198. package/dist/fixtures/forge/inputs/tickets/closed-service-requests.json +5 -0
  199. package/dist/fixtures/forge/inputs/wiki/integration-patterns.md +11 -0
  200. package/dist/fixtures/forge/inputs/wiki/ledger-solution-spec.md +9 -0
  201. package/dist/fixtures/forge/inputs/wiki/snow-firewall-request.md +4 -0
  202. package/dist/fixtures/forge/metarepo/judgments/reaches/84af5b6af24f7ca8c23013f3.yaml +17 -0
  203. package/dist/fixtures/forge/metarepo/judgments/reaches/c3917555edebddce8cecb647.yaml +17 -0
  204. package/dist/fixtures/forge/metarepo/judgments/reaches/c5fafd6601f8ca9e34e0bbd0.yaml +17 -0
  205. package/dist/fixtures/forge/metarepo/org-pack/agents/architecture-critic.yaml +9 -0
  206. package/dist/fixtures/forge/metarepo/org-pack/agents/story-writer.yaml +10 -0
  207. package/dist/fixtures/forge/metarepo/org-pack/checklists/architecture.yaml +115 -0
  208. package/dist/fixtures/forge/metarepo/org-pack/dialects/forge.yaml +111 -0
  209. package/dist/fixtures/forge/metarepo/org-pack/gates.yaml +22 -0
  210. package/dist/fixtures/forge/metarepo/org-pack/pack.yaml +11 -0
  211. package/dist/fixtures/forge/metarepo/org-pack/patterns/A.EB.PUB.yaml +12 -0
  212. package/dist/fixtures/forge/metarepo/org-pack/patterns/D.JDBC.yaml +12 -0
  213. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.DIR.BFF.yaml +12 -0
  214. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.SOR.yaml +13 -0
  215. package/dist/fixtures/forge/metarepo/org-pack/patterns/S.GW.VND.yaml +14 -0
  216. package/dist/fixtures/forge/metarepo/org-pack/process/change-templates/feature.md +37 -0
  217. package/dist/fixtures/forge/metarepo/org-pack/process/skills/add-forge-endpoint/SKILL.md +17 -0
  218. package/dist/fixtures/forge/metarepo/org-pack/process/snow/firewall-rule.yaml +14 -0
  219. package/dist/fixtures/forge/metarepo/org-pack/process/snow/gateway-route.yaml +13 -0
  220. package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/profile.yaml +12 -0
  221. package/dist/fixtures/forge/metarepo/org-pack/profiles/forge/repos.manifest.yaml +44 -0
  222. package/dist/fixtures/forge/metarepo/org-pack/roles.yaml +14 -0
  223. package/dist/fixtures/forge/metarepo/org-pack/runtime.yaml +14 -0
  224. package/dist/fixtures/forge/metarepo/org-pack/sources.yaml +3 -0
  225. package/dist/fixtures/forge/repos/forge-events/topics/payments.initiated.yaml +4 -0
  226. package/dist/fixtures/forge/repos/forge-events/topics/transfers.completed.yaml +4 -0
  227. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/ledger-v1.xml +3 -0
  228. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/SpikeArrest.xml +3 -0
  229. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/policies/VerifyOAuth.xml +4 -0
  230. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/proxies/default.xml +14 -0
  231. package/dist/fixtures/forge/repos/forge-gateway/proxies/ledger-v1/apiproxy/targets/ledger.xml +5 -0
  232. package/dist/fixtures/forge/repos/forge-infra/alerts/ledger-api.yaml +5 -0
  233. package/dist/fixtures/forge/repos/forge-infra/k8s/ledger-api.yaml +15 -0
  234. package/dist/fixtures/forge/repos/forge-infra/k8s/portal-bff.yaml +7 -0
  235. package/dist/fixtures/forge/repos/forge-infra/terraform/ledger-db.tf +9 -0
  236. package/dist/fixtures/forge/repos/forge-ledger/api/ledger-openapi.yaml +31 -0
  237. package/dist/fixtures/forge/repos/forge-ledger/forge.yaml +4 -0
  238. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEndpoints.java +13 -0
  239. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/LedgerEvents.java +11 -0
  240. package/dist/fixtures/forge/repos/forge-ledger/src/main/java/forge/ledger/NorthwindClient.java +10 -0
  241. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/application.yml +3 -0
  242. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V1__create_account.sql +5 -0
  243. package/dist/fixtures/forge/repos/forge-ledger/src/main/resources/db/migration/V2__create_entry.sql +7 -0
  244. package/dist/fixtures/forge/repos/forge-portal-bff/pom.xml +1 -0
  245. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/AuditPublisher.java +12 -0
  246. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/BalanceController.java +16 -0
  247. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/LedgerClient.java +13 -0
  248. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/java/forge/portal/PaymentEvents.java +13 -0
  249. package/dist/fixtures/forge/repos/forge-portal-bff/src/main/resources/application.yml +8 -0
  250. package/dist/fixtures/forge/repos/forge-portal-ui/package.json +1 -0
  251. package/dist/fixtures/forge/repos/forge-portal-ui/src/api/balance.ts +5 -0
  252. package/dist/fixtures/forge/repos/forge-reports-job/src/main/java/forge/reports/DailyEntriesJob.java +19 -0
  253. package/dist/fixtures/forge/repos/forge-reports-job/src/main/resources/application.yml +3 -0
  254. package/dist/fixtures/forge-change/README.md +41 -0
  255. package/dist/fixtures/forge-change/expected/findings.yaml +301 -0
  256. package/dist/fixtures/forge-change/expected/stories.yaml +101 -0
  257. package/dist/fixtures/forge-change/judgments/personal-data/0b5f3dbf5257a22275d8c74b.yaml +18 -0
  258. package/dist/fixtures/forge-change/judgments/personal-data/2759a66770134c417440bf2d.yaml +18 -0
  259. package/dist/fixtures/forge-change/judgments/personal-data/31b1ea2f14d0737f1aca79fd.yaml +18 -0
  260. package/dist/fixtures/forge-change/judgments/personal-data/49afd70c08228e65ad6ca1ed.yaml +18 -0
  261. package/dist/fixtures/forge-change/judgments/personal-data/761cabcb8a39f5e5866d2dd6.yaml +18 -0
  262. package/dist/fixtures/forge-change/judgments/personal-data/adae902b90cc8ffa0c765145.yaml +18 -0
  263. package/dist/fixtures/forge-change/judgments/personal-data/ba11bb933105ec9493e065dd.yaml +18 -0
  264. package/dist/fixtures/forge-change/judgments/personal-data/bdbcd1cdac3021c68063c3e7.yaml +18 -0
  265. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/brief.md +35 -0
  266. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/change.yaml +120 -0
  267. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/data.md +18 -0
  268. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/design.md +29 -0
  269. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/interfaces.md +17 -0
  270. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/mappings.md +26 -0
  271. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/proposal.md +35 -0
  272. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/snow.md +12 -0
  273. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/specs/transfer-limits/spec.md +19 -0
  274. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s1-refuse-over-limit.md +17 -0
  275. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s2-show-remaining.md +16 -0
  276. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s3-audit-refusals.md +18 -0
  277. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories/s4-velocity-check.md +16 -0
  278. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/stories.md +8 -0
  279. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/tasks.md +12 -0
  280. package/dist/fixtures/forge-change/openspec/changes/add-transfer-limit/ux.md +7 -0
  281. package/dist/fixtures/forge-change/org-pack/agents/code-and-test-critic.yaml +13 -0
  282. package/dist/fixtures/forge-change/org-pack/agents/complete-critic.yaml +12 -0
  283. package/dist/fixtures/forge-change/org-pack/agents/safe-critic.yaml +12 -0
  284. package/dist/fixtures/forge-change/org-pack/agents/ship-critic.yaml +11 -0
  285. package/dist/fixtures/forge-change/org-pack/agents/true-critic.yaml +11 -0
  286. package/dist/fixtures/forge-change/org-pack/checklists/review.yaml +54 -0
  287. package/dist/fixtures/forge-change/org-pack/gates.yaml +25 -0
  288. package/dist/fixtures/forge-change/org-pack/teams/team-ledger/checklists/ledger-team.yaml +227 -0
  289. package/dist/fixtures/forge-change/recordings/complete-critic/2ad84f84bf39c1d5412697e69fe23034d6983ec45a00314bf0975e627589a3c5.json +12 -0
  290. package/dist/fixtures/forge-change/recordings/complete-critic/417c98d8e54a4387d0fd93441c49f44c2868958739070d855c1dce0c41e24db3.json +12 -0
  291. package/dist/fixtures/forge-change/recordings/complete-critic/50203ee22e9cb3ef047295edb6538fe7d5695e1e4b139f3c929013dc6ce47021.json +12 -0
  292. package/dist/fixtures/forge-change/recordings/complete-critic/89f18d67f5d9c325bf35e2a9e020f9ddb6ee13b8523315037f0905cc57c040b1.json +12 -0
  293. package/dist/fixtures/forge-change/recordings/complete-critic/b4097867d26ae8eadc8b9efa8cdd86897013358035f0b40086c299a59c4ba121.json +12 -0
  294. package/dist/fixtures/forge-change/recordings/safe-critic/302d06f49664dd67ad2e21ab9cf74c1b0f7d3f750709c6ed8eff2b70983274e2.json +12 -0
  295. package/dist/fixtures/forge-change/recordings/safe-critic/32f1049c9a5ab4a759543290db4644ec6e221cc45fdfdcf06193837c6a8ce0b9.json +12 -0
  296. package/dist/fixtures/forge-change/recordings/safe-critic/4e4a84bfc04b9f26ca4250319a879901ff7a1c081c71e46a117675fee05026b0.json +12 -0
  297. package/dist/fixtures/forge-change/recordings/safe-critic/604af0fcdd6df6b76208fa88305fdc15c37606c2a4d1ae816477e46ac8c2dd04.json +12 -0
  298. package/dist/fixtures/forge-change/recordings/safe-critic/f0bf50af11f14c50d07904f0dffe1c8c20fb0cd89770645a8824c1d30a443955.json +12 -0
  299. package/dist/fixtures/forge-change/recordings/ship-critic/350954b58833b2c04880c67db45a1b328b7fd541d9f0d943b63905b8875488a6.json +12 -0
  300. package/dist/fixtures/forge-change/recordings/ship-critic/4af95c6c96a206777cec9de1f9c2d8c55a36ddc9b8db2f81d6eb83217b835efa.json +12 -0
  301. package/dist/fixtures/forge-change/recordings/ship-critic/76c34522a49cf7587a4e5689a5030d384603fa780b8aba97d27815cbc829683e.json +12 -0
  302. package/dist/fixtures/forge-change/recordings/ship-critic/a3b2cd1ace48587e5994333db03b34c3a0f9dec4f1932f1730ddfb687f6918c8.json +12 -0
  303. package/dist/fixtures/forge-change/recordings/ship-critic/de288a4fa64d0fc20890f9a787080ce6eac5203b7b9b72d884df11e8cf111835.json +12 -0
  304. package/dist/fixtures/forge-change/recordings/story-writer/1ddb00eac2aaf91a5ec5d9dfd220116be9f75aec6546a4a3a3b050ed89af2864.json +12 -0
  305. package/dist/packages/assistant-kit/frameworks-kit/README.md +86 -0
  306. package/dist/packages/assistant-kit/frameworks-kit/checklist.md +11 -0
  307. package/dist/packages/assistant-kit/frameworks-kit/examples/tide-lantern.yaml +56 -0
  308. package/dist/packages/assistant-kit/frameworks-kit/examples/tide-platform.yaml +43 -0
  309. package/dist/packages/assistant-kit/frameworks-kit/prompts/write-framework-model.md +12 -0
  310. package/dist/packages/assistant-kit/kit/README.md +98 -0
  311. package/dist/packages/assistant-kit/kit/c2-reference.md +334 -0
  312. package/dist/packages/assistant-kit/kit/checklist.md +39 -0
  313. package/dist/packages/assistant-kit/kit/examples/house-http-client.yaml +102 -0
  314. package/dist/packages/assistant-kit/kit/examples/tide-apigee.yaml +56 -0
  315. package/dist/packages/assistant-kit/kit/examples/tide-apim.yaml +32 -0
  316. package/dist/packages/assistant-kit/kit/examples/tide-kong.yaml +44 -0
  317. package/dist/packages/assistant-kit/kit/prompts/write-dialect.md +34 -0
  318. package/dist/packages/assistant-kit/kit/worked-example.md +198 -0
  319. package/dist/packages/conformance/sample/README.md +4 -0
  320. package/dist/packages/conformance/sample/inputs/notes.md +3 -0
  321. package/dist/packages/conformance/sample/inputs/systems.csv +3 -0
  322. package/dist/packages/conformance/sample/repo/api/greeter.proto +6 -0
  323. package/dist/packages/conformance/sample/repo/api/openapi.yaml +10 -0
  324. package/dist/packages/conformance/sample/repo/api/schema.graphql +3 -0
  325. package/dist/packages/conformance/sample/repo/db/V1__create_greeting.sql +4 -0
  326. package/dist/packages/conformance/sample/repo/package.json +7 -0
  327. package/dist/packages/conformance/sample/repo/src/main/java/sample/HelloController.java +10 -0
  328. package/dist/packages/conformance/sample/repo/web/app.ts +4 -0
  329. package/dist/packages/evals/datasets/critic-lenses.yaml +62 -0
  330. package/dist/packages/evals/datasets/dialect-writer.yaml +14 -0
  331. package/dist/packages/evals/datasets/feature-namer.yaml +34 -0
  332. package/dist/packages/evals/datasets/glossary-definer.yaml +25 -0
  333. package/dist/packages/evals/datasets/story-writer.yaml +13 -0
  334. package/dist/packages/evals/datasets/template-writer.yaml +16 -0
  335. package/dist/packages/evals/datasets/test-writer.yaml +18 -0
  336. package/dist/packages/executors/reference/reference-executor.mjs +233 -0
  337. package/dist/packages/extractors/dialects/argocd.yaml +45 -0
  338. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AccountResource.java +47 -0
  339. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/AuditClient.java +12 -0
  340. package/dist/packages/extractors/dialects/fixtures/jaxrs/accounts-service/src/main/java/forge/accounts/LedgerClient.java +17 -0
  341. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/LedgerClient.java +14 -0
  342. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/RatesClient.java +11 -0
  343. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/java/forge/statements/StatementController.java +36 -0
  344. package/dist/packages/extractors/dialects/fixtures/micronaut/statements-service/src/main/resources/application.yml +7 -0
  345. package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/java/forge/fraud/FraudScorer.java +27 -0
  346. package/dist/packages/extractors/dialects/fixtures/quarkus-reactive-messaging/fraud-service/src/main/resources/application.properties +4 -0
  347. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/api.tf +38 -0
  348. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/main.tf +95 -0
  349. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/terraform.tfvars +1 -0
  350. package/dist/packages/extractors/dialects/fixtures/terraform-aws/forge-aws-infra/envs/prod/variables.tf +4 -0
  351. package/dist/packages/extractors/dialects/fixtures/terraform-azure/forge-azure-infra/main.tf +102 -0
  352. package/dist/packages/extractors/dialects/fixtures/terraform-gcp/forge-gcp-infra/main.tf +51 -0
  353. package/dist/packages/extractors/dialects/harness.yaml +101 -0
  354. package/dist/packages/extractors/dialects/jaxrs.yaml +155 -0
  355. package/dist/packages/extractors/dialects/micronaut.yaml +207 -0
  356. package/dist/packages/extractors/dialects/quarkus-reactive-messaging.yaml +158 -0
  357. package/dist/packages/extractors/dialects/tekton.yaml +71 -0
  358. package/dist/packages/extractors/dialects/terraform-aws.yaml +267 -0
  359. package/dist/packages/extractors/dialects/terraform-azure.yaml +212 -0
  360. package/dist/packages/extractors/dialects/terraform-gcp.yaml +109 -0
  361. package/dist/packages/extractors/grammars/README.md +11 -0
  362. package/dist/packages/extractors/grammars/tree-sitter-groovy.LICENSE +21 -0
  363. package/dist/packages/extractors/grammars/tree-sitter-groovy.wasm +0 -0
  364. package/dist/packages/extractors/grammars/vendored.json +11 -0
  365. package/dist/packages/learn/lessons/architect-diagrams-and-code.yaml +69 -0
  366. package/dist/packages/learn/lessons/business-analyst-story-bar.yaml +94 -0
  367. package/dist/packages/learn/lessons/delivery-lead-release-readiness.yaml +44 -0
  368. package/dist/packages/learn/lessons/designer-features-in-user-words.yaml +57 -0
  369. package/dist/packages/learn/lessons/developer-find-your-way.yaml +60 -0
  370. package/dist/packages/learn/lessons/everyone-first-hour.yaml +74 -0
  371. package/dist/packages/learn/lessons/platform-lead-coverage-and-defences.yaml +58 -0
  372. package/dist/packages/learn/lessons/product-owner-first-change.yaml +167 -0
  373. package/dist/packages/learn/lessons/qa-tests-and-trace.yaml +53 -0
  374. package/dist/packages/learn/lessons/team-lead-initiative.yaml +146 -0
  375. package/dist/packages/naysayer/constitution/constitution.yaml +286 -0
  376. package/dist/packages/naysayer/starter/review.yaml +256 -0
  377. package/dist/packages/sdk/npm/index.js +8892 -0
  378. package/dist/packages/speckit/rules/drift.yaml +78 -0
  379. package/dist/packages/taskrun/rules/conform.yaml +38 -0
  380. package/dist/packages/testgen/rules/trace.yaml +49 -0
  381. package/dist/packages/ui/dist/assets/elk-api-tma0MCuh.js +2 -0
  382. package/dist/packages/ui/dist/assets/elk-worker.min--dAJroGl.js +6401 -0
  383. package/dist/packages/ui/dist/assets/elk-worker.min-DdYmS5kP.js +2 -0
  384. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-BTotfTJu.woff +0 -0
  385. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-400-normal-DZqxrq2p.woff2 +0 -0
  386. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-ByOcLdNv.woff +0 -0
  387. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-500-normal-CocWQlwt.woff2 +0 -0
  388. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-71GNu3SW.woff2 +0 -0
  389. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-600-normal-BGq0mW3O.woff +0 -0
  390. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-Dsrv2Tcn.woff +0 -0
  391. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-400-normal-g30qAdWV.woff2 +0 -0
  392. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-Cs5J6C77.woff2 +0 -0
  393. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-500-normal-DB5PtV2g.woff +0 -0
  394. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-Bz0x94Yp.woff +0 -0
  395. package/dist/packages/ui/dist/assets/ibm-plex-sans-cyrillic-ext-600-normal-DUMzJB7m.woff2 +0 -0
  396. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-D9ESIMu3.woff +0 -0
  397. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-400-normal-_efipK4i.woff2 +0 -0
  398. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-CuWXN6rf.woff +0 -0
  399. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-500-normal-JMMifIXV.woff2 +0 -0
  400. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-D-CqTdkO.woff +0 -0
  401. package/dist/packages/ui/dist/assets/ibm-plex-sans-greek-600-normal-DzTrcv_p.woff2 +0 -0
  402. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  403. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  404. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  405. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  406. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  407. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  408. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-C5H60-Va.woff2 +0 -0
  409. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-400-normal-RBey6euL.woff +0 -0
  410. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-D0aIdm-b.woff +0 -0
  411. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-500-normal-DakdToA3.woff2 +0 -0
  412. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DIrixKbi.woff +0 -0
  413. package/dist/packages/ui/dist/assets/ibm-plex-sans-latin-ext-600-normal-DOrvGEcy.woff2 +0 -0
  414. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-DG4YqDda.woff2 +0 -0
  415. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-400-normal-fK1oJ5dG.woff +0 -0
  416. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-BEb3_waV.woff +0 -0
  417. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-500-normal-e4dixQRQ.woff2 +0 -0
  418. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DgdngZtN.woff +0 -0
  419. package/dist/packages/ui/dist/assets/ibm-plex-sans-vietnamese-600-normal-DpPYBSTl.woff2 +0 -0
  420. package/dist/packages/ui/dist/assets/index-B54fm9FQ.js +29 -0
  421. package/dist/packages/ui/dist/assets/index-DD_hufQz.css +1 -0
  422. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  423. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  424. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  425. package/dist/packages/ui/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  426. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  427. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  428. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  429. package/dist/packages/ui/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  430. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  431. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  432. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  433. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  434. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  435. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  436. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  437. package/dist/packages/ui/dist/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  438. package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  439. package/dist/packages/ui/dist/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  440. package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-BtY48IV_.woff +0 -0
  441. package/dist/packages/ui/dist/assets/rajdhani-devanagari-600-normal-DhS7ScYx.woff2 +0 -0
  442. package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-BQQOj9BB.woff2 +0 -0
  443. package/dist/packages/ui/dist/assets/rajdhani-devanagari-700-normal-DBRwWuxA.woff +0 -0
  444. package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-CXCVEoA9.woff2 +0 -0
  445. package/dist/packages/ui/dist/assets/rajdhani-latin-600-normal-Dx02qI2_.woff +0 -0
  446. package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-BPDUZo87.woff2 +0 -0
  447. package/dist/packages/ui/dist/assets/rajdhani-latin-700-normal-e0Uj8ZlN.woff +0 -0
  448. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-BleIgkPp.woff +0 -0
  449. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-600-normal-C9ZjJQAt.woff2 +0 -0
  450. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-BPaQ7tlD.woff +0 -0
  451. package/dist/packages/ui/dist/assets/rajdhani-latin-ext-700-normal-S6aYESQK.woff2 +0 -0
  452. package/dist/packages/ui/dist/favicon.svg +1 -0
  453. package/dist/packages/ui/dist/index.html +15 -0
  454. package/dist/third-party.json +575 -0
  455. package/dist/vendor/@fission-ai/openspec/bin/openspec.js +85986 -0
  456. package/dist/vendor/@fission-ai/openspec/package.json +82 -0
  457. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/schema.yaml +248 -0
  458. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/design.md +21 -0
  459. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/proposal.md +34 -0
  460. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/spec.md +13 -0
  461. package/dist/vendor/@fission-ai/openspec/schemas/spec-driven/templates/tasks.md +11 -0
  462. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-c_sharp.wasm +0 -0
  463. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-go.wasm +0 -0
  464. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-java.wasm +0 -0
  465. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-javascript.wasm +0 -0
  466. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-kotlin.wasm +0 -0
  467. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-php.wasm +0 -0
  468. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-python.wasm +0 -0
  469. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-ruby.wasm +0 -0
  470. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-rust.wasm +0 -0
  471. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-scala.wasm +0 -0
  472. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-tsx.wasm +0 -0
  473. package/dist/vendor/tree-sitter-wasms/out/tree-sitter-typescript.wasm +0 -0
  474. package/dist/vendor/web-tree-sitter/tree-sitter.wasm +0 -0
  475. package/package.json +36 -3
@@ -0,0 +1,873 @@
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
+ loadReadPlan,
8
+ partOfWords,
9
+ readPlanProgress,
10
+ readPlanRelOf,
11
+ writeReadPlan
12
+ } from "./chunk-FQXYPF7E.js";
13
+ import {
14
+ carryOf,
15
+ checkoutOf,
16
+ excludesOf,
17
+ headOf,
18
+ raiseReadQuestions,
19
+ readCorrections,
20
+ readReviewed,
21
+ reviewedProblemsOf,
22
+ writeVerifyFiles
23
+ } from "./chunk-CR3MTH32.js";
24
+ import "./chunk-O3WI5KWW.js";
25
+ import {
26
+ ABOUT_RULE,
27
+ assistantTier,
28
+ mapBatchInstructions,
29
+ readProbes,
30
+ tierSource,
31
+ tierWords
32
+ } from "./chunk-IPKHE5D6.js";
33
+ import {
34
+ FILE_KINDS,
35
+ SESSION_TOKENS,
36
+ SHOWN_PROPOSALS,
37
+ dirSource,
38
+ exclusionYaml,
39
+ frameworkTopics,
40
+ frameworkTopicsOfType,
41
+ kindsOf,
42
+ numberedSlice,
43
+ onlyFiles,
44
+ planBatches,
45
+ planParts,
46
+ proposeExclusions,
47
+ rereadPlan,
48
+ sameCommit,
49
+ sliceText,
50
+ staleMessage,
51
+ verifyFacts
52
+ } from "./chunk-PAMPPUR6.js";
53
+ import {
54
+ loadRepos
55
+ } from "./chunk-EFHQ3TWP.js";
56
+ import "./chunk-GQ4N4WKF.js";
57
+ import {
58
+ DATA_RULE,
59
+ HandoffRuntime,
60
+ PromptTooLong,
61
+ buildContextPack,
62
+ currentPromptLimit,
63
+ estimateTokens,
64
+ promptBudget,
65
+ wrapData
66
+ } from "./chunk-CNUKCS2T.js";
67
+ import {
68
+ AgentDefinition,
69
+ Fact,
70
+ REPO_DESCRIPTION_MAX,
71
+ citedFiles,
72
+ descriptionNote,
73
+ descriptionTrust,
74
+ factsDirOf,
75
+ factsRelOf,
76
+ listQuestions,
77
+ loadOrgPack,
78
+ orgPackDirOf,
79
+ parseFacts,
80
+ runsDirOf,
81
+ saysNotProduct
82
+ } from "./chunk-S2A7YC3Q.js";
83
+ import {
84
+ writeFileAtomic
85
+ } from "./chunk-D3PO4DOZ.js";
86
+ import "./chunk-TV45EUGM.js";
87
+
88
+ // packages/cli/dist/map-commands.js
89
+ import { existsSync } from "node:fs";
90
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
91
+ import { dirname, join, relative } from "node:path";
92
+ var REPO_READER = "repo-reader";
93
+ var OUTPUT = "facts.jsonl";
94
+ var KEPT_RESERVE = 1500;
95
+ var MIN_KEPT_RESERVE = 1200;
96
+ var MIN_ROOM = 300;
97
+ var EXAMPLE_LIMIT = 12078;
98
+ var AROUND = 12;
99
+ function repoReaderAgent(op) {
100
+ const own = op?.agents.find((a) => a.id === REPO_READER);
101
+ if (own)
102
+ return own;
103
+ return AgentDefinition.parse({
104
+ schemaVersion: 1,
105
+ id: REPO_READER,
106
+ role: "architect",
107
+ description: "Reads a repo's code into facts (ADR 0124): what it answers to, calls, stores, the fields that cross those boundaries, its deployment and config, each citing its file and line.",
108
+ inputs: ["repo-code"],
109
+ outputArtifact: "data",
110
+ tokenBudget: op?.runtime.budgets.defaultTokens ?? 15e4,
111
+ allowedRuntimes: ["hand-off", "model", "headless-claude-code", "mock", "replay"]
112
+ });
113
+ }
114
+ var plural = (n, w) => `${n} ${w}${n === 1 ? "" : "s"}`;
115
+ var batches = (n) => `${n} ${n === 1 ? "batch" : "batches"}`;
116
+ var changeOf = (repo) => `map-${repo}`;
117
+ var stateFile = (root, repo) => join(runsDirOf(root), changeOf(repo), "state.json");
118
+ async function readState(root, repo) {
119
+ const text = await readFile(stateFile(root, repo), "utf8").catch(() => void 0);
120
+ return text ? JSON.parse(text) : void 0;
121
+ }
122
+ async function saveState(root, s) {
123
+ await mkdir(dirname(stateFile(root, s.repo)), { recursive: true });
124
+ await writeFileAtomic(stateFile(root, s.repo), JSON.stringify(s, null, 2) + "\n");
125
+ }
126
+ var LEVELS = ["public", "internal", "confidential", "restricted"];
127
+ function instructionTokens(repo, commit, kinds = [], frameworks) {
128
+ return (
129
+ // The rule asking what the repo is (ADR 0128) isn't counted here: it is paid for out of the
130
+ // reserve below (`reserveFor`), so the room planned for files is what it always was.
131
+ estimateTokens(mapBatchInstructions({ repo, commit, batch: 999, of: 999, kinds, frameworks })) + estimateTokens(DATA_RULE) + // the <atticus-data> wrapper around the batch's files
132
+ 60
133
+ );
134
+ }
135
+ async function aboutOf(root, repo) {
136
+ return (await loadRepos(root).catch(() => [])).find((r) => r.id === repo)?.description;
137
+ }
138
+ function aboutSource(repo, d) {
139
+ return {
140
+ id: "6-about",
141
+ kind: "document",
142
+ origin: "repos.manifest.yaml",
143
+ text: descriptionNote(repo, d),
144
+ classification: "internal",
145
+ priority: 9
146
+ };
147
+ }
148
+ var aboutTokens = (repo, d) => d ? estimateTokens(wrapData({ id: "6-about", origin: "repos.manifest.yaml", kind: "document" }, descriptionNote(repo, d))) : 0;
149
+ var overheadOf = (repo, commit, frameworks) => {
150
+ const core = instructionTokens(repo, commit, [], frameworks);
151
+ return (kinds) => instructionTokens(repo, commit, kinds, frameworks) - core;
152
+ };
153
+ async function frameworksFor(root, repo, facts) {
154
+ const fromFacts = frameworkTopics(facts);
155
+ if (fromFacts)
156
+ return fromFacts;
157
+ const type = (await loadRepos(root).catch(() => [])).find((r) => r.id === repo)?.type;
158
+ return frameworkTopicsOfType(type);
159
+ }
160
+ var joinKinds = (a, b) => FILE_KINDS.filter((k) => a.includes(k) || b.includes(k));
161
+ function claimOf(f) {
162
+ switch (f.kind) {
163
+ case "entry":
164
+ case "call":
165
+ return `${f.method ? `${f.method} ` : ""}${f.path}`;
166
+ case "store":
167
+ return `${f.op} ${f.store} ${f.name}`;
168
+ case "field":
169
+ return `${f.owner}.${f.name}`;
170
+ case "deploy":
171
+ return `${f.platform}${f.resourceName ? ` ${f.resourceName}` : ""}`;
172
+ case "config":
173
+ return f.key;
174
+ case "framework":
175
+ return `${f.name}${f.version ? ` ${f.version}` : ""}`;
176
+ case "flow":
177
+ return f.name;
178
+ }
179
+ }
180
+ function readAnswer(text, repo, commit) {
181
+ const facts = /* @__PURE__ */ new Map();
182
+ const questions = [];
183
+ const problems = [];
184
+ let about;
185
+ text.split(/\r?\n/).forEach((raw, i) => {
186
+ const line = raw.trim();
187
+ if (!line || line.startsWith("```"))
188
+ return;
189
+ let json;
190
+ try {
191
+ json = JSON.parse(line);
192
+ } catch {
193
+ problems.push(`line ${i + 1} is not one JSON object: ${line.slice(0, 80)}`);
194
+ return;
195
+ }
196
+ if (!json || typeof json !== "object" || Array.isArray(json)) {
197
+ problems.push(`line ${i + 1} is not one JSON object`);
198
+ return;
199
+ }
200
+ const o = json;
201
+ if ("question" in o && !("kind" in o)) {
202
+ questions.push(o);
203
+ return;
204
+ }
205
+ if ("about" in o && !("kind" in o)) {
206
+ const text2 = typeof o.about === "string" ? o.about.trim() : "";
207
+ if (!text2) {
208
+ problems.push(`line ${i + 1}: "about" needs one line saying what the repo is`);
209
+ return;
210
+ }
211
+ const cites = (Array.isArray(o.cites) ? o.cites : []).flatMap((c) => {
212
+ const x = c;
213
+ return typeof x.file === "string" && Number.isInteger(x.line) && Number(x.line) > 0 ? [{ file: x.file, line: Number(x.line) }] : [];
214
+ }).slice(0, 6);
215
+ if (!cites.length) {
216
+ problems.push(`line ${i + 1}: "about" needs "cites": the file and line it was read from, as a fact cites its line`);
217
+ return;
218
+ }
219
+ about ??= { text: text2.slice(0, REPO_DESCRIPTION_MAX), cites };
220
+ return;
221
+ }
222
+ const r = Fact.safeParse({ repo, commit, ...o, verified: "none", by: "assistant" });
223
+ if (r.success)
224
+ facts.set(r.data.id, r.data);
225
+ else
226
+ problems.push(`line ${i + 1}${typeof o.id === "string" ? ` (${o.id})` : ""}: ${r.error.issues.map((x) => `${x.path.join(".") || "(fact)"}: ${x.message}`).join("; ")}`);
227
+ });
228
+ return { facts: [...facts.values()], questions, problems, ...about ? { about } : {} };
229
+ }
230
+ function rejectedText(r, source) {
231
+ const text = source.read(r.fact.cite.file);
232
+ const lines = text?.split(/\r?\n/).length ?? 0;
233
+ const from = Math.max(1, r.fact.cite.line - AROUND);
234
+ const to = Math.min(lines, r.fact.cite.line + AROUND);
235
+ return [
236
+ `${r.fact.id} was rejected (${r.code}): ${r.message}`,
237
+ `The fact: ${JSON.stringify(r.fact)}`,
238
+ ...text !== void 0 && from <= to ? [
239
+ `${r.fact.cite.file} lines ${from}-${to} (numbered as in the file):`,
240
+ numberedSlice(text, { from, to })
241
+ ] : []
242
+ ].join("\n");
243
+ }
244
+ function questionsText(qs) {
245
+ return [
246
+ "Questions already on file for this repo. Don't ask them again; follow each answer a person gave.",
247
+ ...qs.map((q) => `- ${q.question} (${q.evidence.join(", ")}): ${q.state === "answered" ? `answered: ${q.answer?.text ?? q.options[(q.answer?.option ?? 1) - 1]?.label ?? ""}` : "waiting for a person"}`)
248
+ ].join("\n");
249
+ }
250
+ function keptText(facts, budgetTokens) {
251
+ const head = "Facts already kept (id, kind, claim, where). Name them by id; don't write them again.";
252
+ const order = ["entry", "call", "store", "flow", "deploy", "config", "field"];
253
+ const sorted = [...facts].sort((a, b) => order.indexOf(a.kind) - order.indexOf(b.kind) || a.id.localeCompare(b.id));
254
+ const out = [head];
255
+ let used = estimateTokens(head);
256
+ for (const [i, f] of sorted.entries()) {
257
+ const l = `- ${f.id} (${f.kind}): ${claimOf(f)} [${f.cite.file}:${f.cite.line}]`;
258
+ if (used + estimateTokens(l) > budgetTokens - 20) {
259
+ out.push(`... and ${sorted.length - i} more`);
260
+ break;
261
+ }
262
+ out.push(l);
263
+ used += estimateTokens(l);
264
+ }
265
+ return out.join("\n");
266
+ }
267
+ async function readFactsFile(root, repo) {
268
+ const file = join(factsDirOf(root), `${repo}.jsonl`);
269
+ if (!existsSync(file))
270
+ return [];
271
+ const parsed = parseFacts(await readFile(file, "utf8"));
272
+ if (parsed.ok)
273
+ return parsed.facts;
274
+ return `${factsRelOf(root)}/${repo}.jsonl does not read as facts (${parsed.issues[0]?.message ?? "?"}); fix it, or start again with --force after moving it aside.`;
275
+ }
276
+ function rereadInstructions(s) {
277
+ const r = s.reread;
278
+ return [
279
+ `This is a re-read: the facts were read at ${r.from.map((c) => c.slice(0, 12)).join(", ")}, and the checkout moved to ${s.commit}. Only the files changed since are in these batches.`,
280
+ `The ${plural(r.facts, "fact")} that cite a changed file are listed below as rejected (cite-changed): read the file again (a renamed file under its new path) and write each again at this commit under the same id, with its line as it is now, or leave it out if the code no longer says it.`,
281
+ `The other ${plural(r.carried, "fact")} cite files that didn't change: they are kept and carried to this commit. Don't write them again; name them by id.`,
282
+ "Write a fact for anything new in the changed files, as in a first read."
283
+ ].join("\n");
284
+ }
285
+ async function rereadOf(dir, facts, commit, source, exclude, git) {
286
+ if (!facts.some((f) => !sameCommit(f.commit, commit)))
287
+ return { missing: [] };
288
+ const { carry, missing } = await carryOf(dir, facts, commit, git);
289
+ if (!Object.keys(carry).length)
290
+ return { missing };
291
+ return { plan: rereadPlan({ facts, commit, carry, source, exclude }), missing };
292
+ }
293
+ async function packFor(root, s, batch, source, op, now) {
294
+ const agent = repoReaderAgent(op);
295
+ const budget = op.runtime.budgets.perAgent[agent.id] ?? agent.tokenBudget;
296
+ const fix = batch >= s.batches.length;
297
+ const about = await aboutOf(root, s.repo);
298
+ const reserve = reserveFor(s.repo, about);
299
+ const kept = await readFactsFile(root, s.repo);
300
+ const facts = typeof kept === "string" ? [] : kept;
301
+ const onFile = (await listQuestions(root, { repo: s.repo })).questions.filter((q) => q.state !== "retired");
302
+ const slices = fix ? [] : s.batches[batch];
303
+ const rejected = s.rejected.map((r) => rejectedText(r, source));
304
+ const own = kindsOf(slices.map((x) => x.path));
305
+ const theirs = kindsOf(s.rejected.flatMap((r) => citedFiles(r.fact)));
306
+ const both = joinKinds(own, theirs);
307
+ const extra = instructionTokens(s.repo, s.commit, both) - instructionTokens(s.repo, s.commit, own);
308
+ const kinds = fix ? theirs : extra + rejected.reduce((n, t) => n + estimateTokens(t), 0) <= reserve ? both : own;
309
+ const sources = [
310
+ {
311
+ id: "0-instructions",
312
+ kind: "instruction",
313
+ origin: "atticus/map",
314
+ text: mapBatchInstructions({
315
+ repo: s.repo,
316
+ commit: s.commit,
317
+ batch: batch + 1,
318
+ of: s.batches.length,
319
+ ...fix ? { fix: true } : {},
320
+ kinds,
321
+ // A-framework: the frameworks the repo's own facts declare, else its type's hint. The
322
+ // build files are read first, so from the second batch on this is what the code says.
323
+ frameworks: await frameworksFor(root, s.repo, facts),
324
+ // Nothing says what this repo is: ask for one line, cited, for a person to confirm.
325
+ ...about ? {} : { askAbout: true }
326
+ }),
327
+ classification: "public",
328
+ trusted: true
329
+ },
330
+ ...s.reread ? [
331
+ {
332
+ id: "0-reread",
333
+ kind: "instruction",
334
+ origin: "atticus/map",
335
+ text: rereadInstructions(s),
336
+ classification: "public",
337
+ trusted: true
338
+ }
339
+ ] : [],
340
+ ...slices.length ? [
341
+ {
342
+ id: "1-files",
343
+ kind: "code",
344
+ origin: slices.map((x) => `${x.path}#L${x.from}-${x.to}`).join(", "),
345
+ text: slices.map((x) => sliceText(source, x)).join("\n\n"),
346
+ classification: "internal",
347
+ priority: 10
348
+ }
349
+ ] : [],
350
+ ...s.rejected.map((r, i) => ({
351
+ id: `2-rejected-${String(i + 1).padStart(3, "0")}`,
352
+ kind: "document",
353
+ origin: `${factsRelOf(root)}/${s.repo}.rejected.jsonl`,
354
+ text: rejected[i],
355
+ classification: "internal",
356
+ priority: 6
357
+ })),
358
+ ...s.problems.length ? [
359
+ {
360
+ id: "3-problems",
361
+ kind: "document",
362
+ origin: "the last answer",
363
+ text: `Lines of your last answer that weren't kept:
364
+ ${s.problems.map((p) => `- ${p}`).join("\n")}`,
365
+ classification: "internal",
366
+ priority: 5
367
+ }
368
+ ] : [],
369
+ ...onFile.length ? [
370
+ {
371
+ id: "4-questions",
372
+ kind: "document",
373
+ origin: "questions/",
374
+ text: questionsText(onFile),
375
+ classification: "internal",
376
+ priority: 4
377
+ }
378
+ ] : [],
379
+ // What a person says the repo is (ADR 0128), as data: it orients the read, never leads it.
380
+ ...about ? [aboutSource(s.repo, about)] : [],
381
+ ...facts.length ? [
382
+ {
383
+ id: "5-kept",
384
+ kind: "document",
385
+ origin: `${factsRelOf(root)}/${s.repo}.jsonl`,
386
+ text: keptText(facts, reserve),
387
+ classification: "internal",
388
+ priority: 3
389
+ }
390
+ ] : []
391
+ ];
392
+ const levels = op.pack?.classification ?? LEVELS;
393
+ return {
394
+ agent,
395
+ pack: buildContextPack({
396
+ change: changeOf(s.repo),
397
+ agent: agent.id,
398
+ budget,
399
+ sources,
400
+ levels,
401
+ maxClassification: levels.includes("internal") ? "internal" : levels.at(-1),
402
+ now,
403
+ ...s.maxTokens ? { maxTokens: s.maxTokens } : {},
404
+ required: slices.length ? ["1-files"] : [],
405
+ step: `map ${s.repo}`
406
+ })
407
+ };
408
+ }
409
+ var COPY_START = "----- copy from here -----";
410
+ var COPY_END = "----- to here -----";
411
+ function limitOf(o, op, tier) {
412
+ const given = o.maxTokens ?? currentPromptLimit();
413
+ if (given !== void 0)
414
+ return { limit: given, from: "flag" };
415
+ if (tier?.maxTokensFrom === "probe" && tier.maxTokens !== void 0)
416
+ return { limit: tier.maxTokens, from: "probe" };
417
+ const maxInput = op.runtime.adapters.model?.settings.maxInput;
418
+ return typeof maxInput === "number" ? { limit: maxInput, from: "runtime.yaml" } : {};
419
+ }
420
+ async function tierHere(root, op) {
421
+ return assistantTier(op.runtime, { probes: (await readProbes(root)).results });
422
+ }
423
+ function roomFor(limit, op, repo, commit) {
424
+ const agent = repoReaderAgent(op);
425
+ const budget = op.runtime.budgets.perAgent[agent.id] ?? agent.tokenBudget;
426
+ const fitted = limit === void 0 ? budget : Math.min(budget, promptBudget(limit));
427
+ return fitted - instructionTokens(repo, commit) - KEPT_RESERVE;
428
+ }
429
+ function reserveFor(repo, about) {
430
+ const cost = about ? aboutTokens(repo, about) : estimateTokens(ABOUT_RULE);
431
+ return Math.max(MIN_KEPT_RESERVE, KEPT_RESERVE - cost);
432
+ }
433
+ async function mapCommand(root, repo, o, io, deps = {}) {
434
+ const now = deps.now ?? (() => /* @__PURE__ */ new Date());
435
+ const dir = await checkoutOf(root, repo, o.dir);
436
+ if (!dir || !existsSync(dir)) {
437
+ io.err(`No checkout of ${repo}: clone it (atticus workspace sync) or give its folder with --dir.`);
438
+ return 2;
439
+ }
440
+ const commit = o.commit ?? await headOf(dir);
441
+ if (!commit || !/^[0-9a-f]{7,64}$/.test(commit)) {
442
+ io.err(`${dir} has no Git commit to read at; give one with --commit <sha> (every fact names the commit it was read at).`);
443
+ return 2;
444
+ }
445
+ const op = await loadOrgPack(orgPackDirOf(root));
446
+ const source = dirSource(dir);
447
+ const exclude = await excludesOf(root, repo);
448
+ const factsFile = `${factsRelOf(root)}/${repo}.jsonl`;
449
+ if (o.estimate)
450
+ return estimate(root, repo, { o, op, dir, commit, source, exclude, factsFile, ...deps.git ? { git: deps.git } : {} }, io);
451
+ const runtime = deps.runtime;
452
+ if (!runtime) {
453
+ io.err("atticus map needs an AI runtime: run it with --handoff, --copy or --mode <mode>.");
454
+ return 2;
455
+ }
456
+ let s = await readState(root, repo);
457
+ const continuing = o.next || o.resume !== void 0 || o.copy && o.answer !== void 0;
458
+ if (continuing) {
459
+ if (!s || s.done || !s.waiting && o.answer !== void 0) {
460
+ io.err(`No read of ${repo} is waiting for an answer. Start one with atticus map ${repo}${o.copy ? " --copy" : " --handoff"}.`);
461
+ return 2;
462
+ }
463
+ if (o.resume && o.resume !== s.waiting?.runId) {
464
+ io.err(`${o.resume} isn't the run the read of ${repo} waits for${s.waiting ? ` (it waits for ${s.waiting.runId})` : ""}.`);
465
+ return 2;
466
+ }
467
+ }
468
+ if (continuing && s?.waiting) {
469
+ const runId = s.waiting.runId;
470
+ if (o.copy && o.answer !== void 0) {
471
+ const text = o.answer === "-" ? await (deps.stdin ?? readStdin)() : await readFile(o.answer, "utf8").catch(() => void 0);
472
+ if (text === void 0) {
473
+ io.err(`Can't read ${o.answer}: save the assistant's answer to that file first.`);
474
+ return 2;
475
+ }
476
+ const out = join(runsDirOf(root), changeOf(repo), runId, OUTPUT);
477
+ await mkdir(dirname(out), { recursive: true });
478
+ await writeFile(out, text, "utf8");
479
+ }
480
+ let run = await runtime.result(runId);
481
+ const resultFile = join(runsDirOf(root), changeOf(repo), runId, OUTPUT);
482
+ if (run.state === "waiting" && runtime instanceof HandoffRuntime && existsSync(resultFile))
483
+ run = await runtime.done(runId);
484
+ if (run.state === "waiting" || run.state === "prepared") {
485
+ io.out(`Run ${runId} is still waiting for its result file: write it, then atticus map ${repo} --next.`);
486
+ io.report?.({ handoff: { runId } });
487
+ return 0;
488
+ }
489
+ const r = await takeAnswer(root, s, run, s.waiting.batch, source, exclude, now, io, {
490
+ dir,
491
+ ...deps.git ? { git: deps.git } : {}
492
+ });
493
+ if (typeof r === "number")
494
+ return r;
495
+ s = r;
496
+ } else if (!continuing) {
497
+ if (s && !s.done && !o.force) {
498
+ io.out(`A read of ${repo} is under way (batch ${(s.waiting?.batch ?? s.next) + 1} of ${s.batches.length}${s.waiting ? `, waiting for run ${s.waiting.runId}` : ""}). Continue it with atticus map ${repo} --next${o.copy ? " (--copy --answer <file> to paste the answer)" : ""}; start again with --force.`);
499
+ if (s.waiting) {
500
+ if (o.copy)
501
+ return printCopy(s, runtime, io);
502
+ io.report?.({ handoff: { runId: s.waiting.runId } });
503
+ }
504
+ return 0;
505
+ }
506
+ const existing = await readFactsFile(root, repo);
507
+ if (typeof existing === "string") {
508
+ io.err(existing);
509
+ return 2;
510
+ }
511
+ const { limit } = limitOf(o, op, runtime.kind === "hand-off" ? await tierHere(root, op) : void 0);
512
+ const room = roomFor(limit, op, repo, commit);
513
+ const tooSmall = (more) => {
514
+ const fitted = limit === void 0 ? room : promptBudget(limit);
515
+ io.err(new PromptTooLong(`map ${repo}`, instructionTokens(repo, commit) + more + KEPT_RESERVE + MIN_ROOM, fitted, limit ?? fitted, []).message);
516
+ return 2;
517
+ };
518
+ if (room < MIN_ROOM)
519
+ return tooSmall(0);
520
+ const frameworks = await frameworksFor(root, repo, existing);
521
+ const re = await rereadOf(dir, existing, commit, source, exclude, deps.git);
522
+ const reread = re.plan && !re.plan.unknown.length ? re.plan : void 0;
523
+ const since = reread?.from.map((x) => x.commit.slice(0, 12)).join(", ");
524
+ if (reread && !reread.files.length && !reread.reread.length) {
525
+ io.out(`Nothing ${repo}'s facts cite changed since ${since}, and no source file did: atticus verify ${repo} carries its ${plural(reread.carried, "fact")} to ${commit.slice(0, 12)}.`);
526
+ return 0;
527
+ }
528
+ const plan = planBatches(reread ? onlyFiles(source, reread.files.map((f) => f.path)) : source, { room, exclude, overhead: overheadOf(repo, commit, frameworks) });
529
+ if (plan.leastRoom < MIN_ROOM)
530
+ return tooSmall(room - plan.leastRoom);
531
+ if (!plan.batches.length && !reread) {
532
+ io.out(`${repo} has no source files to read${plan.excluded.length ? ` (${plural(plan.excluded.length, "file")} excluded)` : ""}.`);
533
+ return 0;
534
+ }
535
+ const byId = new Map(existing.map((f) => [f.id, f]));
536
+ s = {
537
+ schemaVersion: 1,
538
+ repo,
539
+ commit,
540
+ ...limit ? { maxTokens: limit } : {},
541
+ room,
542
+ batches: plan.batches,
543
+ next: 0,
544
+ rejected: (reread?.reread ?? []).map((r) => {
545
+ const fact = byId.get(r.id);
546
+ return { id: r.id, code: "cite-changed", message: staleMessage(fact, r, commit), fact };
547
+ }),
548
+ problems: [],
549
+ ...reread ? {
550
+ reread: {
551
+ from: reread.from.map((x) => x.commit),
552
+ carried: reread.carried,
553
+ facts: reread.reread.length
554
+ }
555
+ } : {}
556
+ };
557
+ await saveState(root, s);
558
+ io.out(reread ? `Re-reading ${repo} at ${commit.slice(0, 12)}: ${plural(plan.files, "source file")} changed since ${since}, in ${batches(plan.batches.length)}${plan.batches.length ? ` (about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""})` : ""}; ${plural(reread.reread.length, "fact")} to rewrite, ${reread.carried} carried as they are; facts go to ${factsFile}.` : `Reading ${repo} at ${commit.slice(0, 12)} in ${batches(plan.batches.length)} (${plural(plan.files, "source file")}, about ${plan.tokens} tokens${limit ? `, each prompt within ${limit} tokens` : ""}); facts go to ${factsFile}.`);
559
+ }
560
+ if (!s)
561
+ return 2;
562
+ for (; ; ) {
563
+ const fixRound = s.next >= s.batches.length;
564
+ if (fixRound && (s.fixRound || !s.rejected.length))
565
+ break;
566
+ if (fixRound)
567
+ s.fixRound = true;
568
+ const { agent, pack } = await packFor(root, s, s.next, source, op, now());
569
+ const prepared = await runtime.prepare({
570
+ change: changeOf(repo),
571
+ agent,
572
+ pack,
573
+ outputPath: OUTPUT,
574
+ outputIn: "run"
575
+ });
576
+ const run = await runtime.run(prepared.runId);
577
+ if (run.state === "waiting" || run.state === "prepared") {
578
+ s.waiting = { runId: run.runId, batch: s.next };
579
+ await saveState(root, s);
580
+ if (o.copy)
581
+ return printCopy(s, runtime, io);
582
+ const label = fixRound ? "the fix round for the rejected facts" : `batch ${s.next + 1} of ${s.batches.length}`;
583
+ io.out(`Handed ${label} to your assistant (run ${run.runId}). When it is done: atticus handoff done ${run.runId}, then atticus map ${repo} --next`);
584
+ io.report?.({ handoff: { runId: run.runId } });
585
+ return 0;
586
+ }
587
+ const r = await takeAnswer(root, s, run, s.next, source, exclude, now, io, {
588
+ dir,
589
+ ...deps.git ? { git: deps.git } : {}
590
+ });
591
+ if (typeof r === "number")
592
+ return r;
593
+ s = r;
594
+ }
595
+ return finish(root, s, io, o);
596
+ }
597
+ async function readStdin() {
598
+ const chunks = [];
599
+ for await (const c of process.stdin)
600
+ chunks.push(c);
601
+ return Buffer.concat(chunks).toString("utf8");
602
+ }
603
+ async function printCopy(s, runtime, io) {
604
+ const run = await runtime.result(s.waiting.runId);
605
+ io.out(COPY_START);
606
+ io.out(run.request.pack.prompt.trimEnd());
607
+ io.out(COPY_END);
608
+ io.out(`Paste it into your assistant's chat (${s.waiting.batch < s.batches.length ? `batch ${s.waiting.batch + 1} of ${s.batches.length}` : "the fix round"}). Save its answer to a file, then run: atticus map ${s.repo} --copy --answer <file> (or --answer - to paste it on stdin).`);
609
+ io.report?.({ handoff: { runId: run.runId } });
610
+ return 0;
611
+ }
612
+ async function takeAnswer(root, s, run, batch, source, exclude, now, io, at) {
613
+ const label = batch < s.batches.length ? `Batch ${batch + 1} of ${s.batches.length}` : "The fix round";
614
+ if (run.state !== "validated" && run.state !== "produced") {
615
+ io.err(`${label} got no answer to read (${run.errors.join("; ") || `the run ended ${run.state}`}). Run atticus map ${s.repo} --next to hand it again.`);
616
+ const { waiting: _w2, ...rest2 } = s;
617
+ await saveState(root, { ...rest2, next: batch });
618
+ return 1;
619
+ }
620
+ const answer = readAnswer(run.output ?? "", s.repo, s.commit);
621
+ const existing = await readFactsFile(root, s.repo);
622
+ if (typeof existing === "string") {
623
+ io.err(existing);
624
+ return 2;
625
+ }
626
+ const merged = new Map(existing.map((f) => [f.id, f]));
627
+ for (const f of answer.facts)
628
+ merged.set(f.id, f);
629
+ const { carry } = await carryOf(at.dir, [...merged.values()], s.commit, at.git);
630
+ const reviewed = await readReviewed(root, s.repo);
631
+ const report = await verifyFacts({
632
+ facts: [...merged.values()],
633
+ source,
634
+ commit: s.commit,
635
+ carry,
636
+ exclude,
637
+ // ADR 0124 addendum D-app: a person's corrections hold through every batch of a read.
638
+ corrections: (await readCorrections(root, s.repo)).corrections,
639
+ // ADR 0124 addendum A-read: files the reader read and found nothing in, if it wrote any.
640
+ reviewed: reviewed.entries
641
+ });
642
+ const q = await raiseReadQuestions(root, s.repo, answer.questions, source, {
643
+ command: `atticus map ${s.repo}`,
644
+ run: run.runId,
645
+ at: now().toISOString()
646
+ });
647
+ const summary = await writeVerifyFiles(root, s.repo, report, s.commit, q.problems, [], reviewedProblemsOf(reviewed.bad, report));
648
+ if (answer.about) {
649
+ const { keepDraftedDescription } = await import("./chunk-DPZHZQKE.js");
650
+ const d = await keepDraftedDescription(root, s.repo, answer.about, now());
651
+ if (d.kept)
652
+ io.out(`Your assistant says ${s.repo} is: "${answer.about.text}" \u2014 written to the manifest as a draft, unconfirmed. Confirm it (atticus repo describe ${s.repo} --accept), change it (--description "...") or drop it (--reject).`);
653
+ else if (d.why)
654
+ io.out(`The description your assistant drafted wasn't kept: ${d.why}.`);
655
+ }
656
+ const fresh = new Set(answer.facts.map((f) => f.id));
657
+ const kept = report.accepted.filter((f) => fresh.has(f.id)).length;
658
+ io.out(`${label}: ${plural(kept, "fact")} kept (${report.accepted.length} in all${report.carried.length ? `, ${report.carried.length} carried from an earlier commit` : ""}), ${report.rejected.length} rejected${q.raised.length ? `, ${plural(q.raised.length, "question")} raised for a person` : ""}${answer.problems.length ? `, ${plural(answer.problems.length, "line")} not read` : ""}.`);
659
+ const { waiting: _w, ...rest } = s;
660
+ const rejected = report.rejected.map((r) => ({
661
+ id: r.fact.id,
662
+ code: r.code,
663
+ message: r.message,
664
+ fact: r.fact
665
+ }));
666
+ const settled = /* @__PURE__ */ new Set([...report.accepted.map((f) => f.id), ...rejected.map((r) => r.id)]);
667
+ const pending = s.rejected.filter((r) => r.code === "cite-changed" && !settled.has(r.id));
668
+ return {
669
+ ...rest,
670
+ next: batch + 1,
671
+ rejected: [...rejected, ...pending],
672
+ problems: [...answer.problems, ...q.problems.map((p) => `${p.message}: ${p.line}`)],
673
+ last: summary
674
+ };
675
+ }
676
+ async function finish(root, s, io, o) {
677
+ s.done = true;
678
+ await saveState(root, s);
679
+ const last = s.last;
680
+ const rel = factsRelOf(root);
681
+ if (o.json) {
682
+ io.out(JSON.stringify({ state: "done", repo: s.repo, batches: s.batches.length, ...last }, null, 2));
683
+ return last && last.rejected ? 1 : 0;
684
+ }
685
+ if (!last) {
686
+ io.out(`Read ${s.repo}: nothing was kept.`);
687
+ return 0;
688
+ }
689
+ io.out(`Read ${s.repo} in ${batches(s.batches.length)}: ${plural(last.accepted, "fact")} kept in ${rel}/${s.repo}.jsonl, ${last.rejected} still rejected; coverage ${Math.round(last.coverage.ratio * 100)}% (${last.coverage.read} read, ${last.coverage.reviewed ? `${last.coverage.reviewed} reviewed with nothing to record, ` : ""}${last.coverage.unknown.length} unknown).`);
690
+ if (last.rejected)
691
+ io.out(`The rejected facts are in ${rel}/${s.repo}.rejected.jsonl; fix them by hand or with your assistant, then atticus verify ${s.repo}.`);
692
+ if (last.coverage.unknown.length)
693
+ io.out(`Files no fact cites yet are listed in ${rel}/${s.repo}.verify.yaml; generated code can be excluded in org-pack/scan/${s.repo}.yaml.`);
694
+ return last.rejected ? 1 : 0;
695
+ }
696
+ function rereadLines(repo, r) {
697
+ const head = r.commit.slice(0, 12);
698
+ const since = r.from.map((x) => x.commit.slice(0, 12)).join(", ");
699
+ const changed = r.from.reduce((n, x) => n + x.changed, 0);
700
+ const out = [
701
+ `A re-read: the facts are of ${since} and the checkout is at ${head}; ${plural(changed, "file")} changed since. Read only what is listed here, not the whole repo.`,
702
+ `${plural(r.carried, "fact")} still ${r.carried === 1 ? "holds" : "hold"} (every file they cite is unchanged): keep them as they are; atticus verify ${repo} carries them to ${head}, checking each line again.`
703
+ ];
704
+ if (r.current)
705
+ out.push(`${plural(r.current, "fact")} ${r.current === 1 ? "is" : "are"} already of ${head}.`);
706
+ if (r.reread.length) {
707
+ out.push(`${plural(r.reread.length, "fact")} ${r.reread.length === 1 ? "cites" : "cite"} a file that changed: read it again, then write each at ${head} under the same id with its line as it is now, or drop it if the code no longer says it:`);
708
+ for (const f of r.reread)
709
+ out.push(` ${f.id} (${f.kind}): ${f.file} was ${f.how === "renamed" ? `renamed to ${f.to}` : f.how}`);
710
+ }
711
+ if (r.files.length) {
712
+ out.push(`${plural(r.files.length, "file")} to read whole (changed since ${since}):`);
713
+ for (const f of r.files)
714
+ out.push(` ${f.path} (${f.facts ? `${plural(f.facts, "fact")} to rewrite` : `${f.status === "added" ? "new" : f.status}; no fact cites it yet`})`);
715
+ } else if (!r.reread.length)
716
+ out.push(`Nothing a fact cites changed and no source file did: run atticus verify ${repo} to carry the facts to ${head}.`);
717
+ return out;
718
+ }
719
+ async function estimate(root, repo, c, io) {
720
+ const tier = await tierHere(root, c.op);
721
+ const { limit: given, from } = limitOf(c.o, c.op, tier);
722
+ const limit = given ?? EXAMPLE_LIMIT;
723
+ const about = await aboutOf(root, repo);
724
+ const room = roomFor(limit, c.op, repo, c.commit);
725
+ const existing = await readFactsFile(root, repo);
726
+ const re = typeof existing === "string" ? { missing: [] } : await rereadOf(c.dir, existing, c.commit, c.source, c.exclude, c.git);
727
+ const reread = re.plan && !re.plan.unknown.length ? re.plan : void 0;
728
+ const readSource = reread ? onlyFiles(c.source, reread.files.map((f) => f.path)) : c.source;
729
+ const repoWhole = reread ? planBatches(c.source, { room: Number.MAX_SAFE_INTEGER, exclude: c.exclude }) : void 0;
730
+ const whole = planBatches(readSource, { room: Number.MAX_SAFE_INTEGER, exclude: c.exclude });
731
+ const planned = room >= MIN_ROOM ? planBatches(readSource, {
732
+ room,
733
+ exclude: c.exclude,
734
+ overhead: overheadOf(repo, c.commit, await frameworksFor(root, repo, typeof existing === "string" ? [] : existing))
735
+ }) : void 0;
736
+ const plan = planned && planned.leastRoom >= MIN_ROOM ? planned : void 0;
737
+ const files = whole.batches.flat().map((s) => ({ path: s.path, tokens: s.tokens }));
738
+ const proposed = reread ? { proposals: [], before: whole.tokens, after: whole.tokens } : proposeExclusions(files, c.source.list(), (p) => c.source.read(p), {
739
+ // What the person's description plainly says this repo holds (ADR 0128).
740
+ saysNotProduct: saysNotProduct(about)
741
+ });
742
+ const left = proposed.proposals.map((p) => p.path.slice(0, -2));
743
+ const session = Math.max(SESSION_TOKENS, Math.floor(0.75 * (given ?? 0)));
744
+ const product = files.filter((f) => !left.some((d) => f.path.startsWith(d)));
745
+ const parts = planParts(product, session);
746
+ const plan0 = await loadReadPlan(root, repo);
747
+ const same = plan0 !== void 0 && plan0.commit === c.commit && plan0.session === session && plan0.parts.length === parts.length && plan0.parts.every((p, i) => p.paths.length === parts[i].paths.length && p.paths.every((x, j) => x === parts[i].paths[j]));
748
+ if (parts.length && !same)
749
+ await writeReadPlan(root, repo, { commit: c.commit, session, parts });
750
+ const progress = parts.length ? await readPlanProgress(root, repo, { commit: c.commit }) : void 0;
751
+ const questions = (await listQuestions(root, { repo })).questions.filter((q) => q.state !== "retired");
752
+ if (c.o.json) {
753
+ io.out(JSON.stringify({
754
+ repo,
755
+ dir: c.dir,
756
+ commit: c.commit,
757
+ factsFile: c.factsFile,
758
+ files: whole.files,
759
+ lines: whole.lines,
760
+ tokens: whole.tokens,
761
+ excluded: whole.excluded,
762
+ maxTokens: limit,
763
+ maxTokensGiven: given !== void 0,
764
+ maxTokensFrom: from ?? "example",
765
+ batches: plan?.batches.length ?? null,
766
+ order: whole.batches.flat().map((x) => x.path),
767
+ // ADR 0128: what a person says the repo is, and whether that eased the proposals.
768
+ about: about ? { text: about.text, trust: about.trust, eased: saysNotProduct(about) } : null,
769
+ proposals: {
770
+ before: proposed.before,
771
+ after: proposed.after,
772
+ exclude: proposed.proposals
773
+ },
774
+ parts: {
775
+ session,
776
+ parts,
777
+ // A-ledger: the read plan on file and what the facts say each part has covered.
778
+ ...progress ? {
779
+ plan: {
780
+ file: readPlanRelOf(root, repo),
781
+ total: progress.total,
782
+ done: progress.done,
783
+ ...progress.next ? { next: progress.next.part } : {},
784
+ stale: progress.stale,
785
+ parts: progress.parts
786
+ }
787
+ } : {}
788
+ },
789
+ tier,
790
+ questions: questions.map((q) => ({
791
+ id: q.id,
792
+ question: q.question,
793
+ state: q.state,
794
+ ...q.answer ? { answer: q.answer } : {}
795
+ })),
796
+ // A re-read: what the files and batches above are, and the facts to revisit.
797
+ reread: reread ? {
798
+ ...reread,
799
+ repo: {
800
+ files: repoWhole.files,
801
+ lines: repoWhole.lines,
802
+ tokens: repoWhole.tokens
803
+ }
804
+ } : null,
805
+ ...re.missing.length ? { notComparable: re.missing } : {}
806
+ }, null, 2));
807
+ return 0;
808
+ }
809
+ io.out(`${repo} at ${c.commit} in ${c.dir}`);
810
+ io.out(about ? `What it is (${descriptionTrust(about)}${about.by ? `, ${about.by}` : ""}): ${about.text} \u2014 a person's note from the manifest, not read from the code: where the code says otherwise, the code is right.` : `What it is: nothing says yet. A person writes one line (atticus repo describe ${repo} --description "..."); if the files say plainly, hand yours over with atticus repo describe ${repo} --drafted "..." --cites <file>:<line>, and it waits for a person.`);
811
+ io.out(`Facts file: ${c.factsFile}`);
812
+ if (reread)
813
+ for (const l of rereadLines(repo, reread))
814
+ io.out(l);
815
+ for (const m of re.missing)
816
+ io.out(`Some facts are of commit ${m.slice(0, 12)}, which this clone can't compare with ${c.commit.slice(0, 12)} (fetch it, or read the repo again whole): the read below is the whole repo.`);
817
+ io.out(`${plural(whole.files, "source file")}${reread ? " to read" : ""}, ${plural(whole.lines, "line")}, about ${whole.tokens} tokens${whole.excluded.length ? `; ${whole.excluded.length} excluded` : ""}${reread ? ` (the repo has ${plural(repoWhole.files, "source file")}, about ${repoWhole.tokens} tokens)` : ""}.`);
818
+ if (proposed.proposals.length) {
819
+ const scan = relative(root, join(orgPackDirOf(root), "scan", `${repo}.yaml`)).replace(/\\/g, "/");
820
+ io.out(`Folders that look like data, documentation or vendored code, not the product (${proposed.proposals.length}):`);
821
+ if (saysNotProduct(about))
822
+ io.out(` (${repo}'s description says it is mostly not product code, so a smaller folder is proposed than would be otherwise. Each is still a proposal a person accepts.)`);
823
+ for (const p of proposed.proposals.slice(0, SHOWN_PROPOSALS))
824
+ io.out(` ${p.path} (about ${p.tokens} tokens, ${plural(p.files, "file")}): ${p.why}`);
825
+ if (proposed.proposals.length > SHOWN_PROPOSALS)
826
+ io.out(` ... and ${proposed.proposals.length - SHOWN_PROPOSALS} more (all in the exclude: block below)`);
827
+ const fresh = !existsSync(join(root, scan));
828
+ io.out(fresh ? `To leave them out, a person saves this as ${scan} in a pull request (Atticus never writes it):` : `To leave them out, a person adds these entries to the exclude: list of ${scan} in a pull request (Atticus never writes it):`);
829
+ if (fresh)
830
+ io.out(`schemaVersion: 1
831
+ repo: ${repo}`);
832
+ io.out(exclusionYaml(proposed.proposals).trimEnd());
833
+ io.out(`With them left out: about ${proposed.after} tokens (now ${proposed.before}).`);
834
+ }
835
+ if (parts.length) {
836
+ if (proposed.proposals.length)
837
+ io.out(`The parts below are planned over what is left with the ${plural(proposed.proposals.length, "proposed folder")} left out (${plural(product.length, "source file")}, about ${proposed.after} tokens); no part reads a proposed folder.`);
838
+ io.out(`About ${parts.reduce((n, p) => n + p.tokens, 0)} tokens${proposed.proposals.length ? " with those left out" : ""} is more than one session reads (${session} tokens): read it in ${parts.length} parts, one per session or sub-agent, as /atticus-map says:`);
839
+ const stateOf = (i) => progress?.parts[i]?.state;
840
+ const words = (s) => s === "done" ? "done" : s === "in-progress" ? "part-read" : "to read";
841
+ parts.forEach((p, i) => io.out(` part ${i + 1} (${words(stateOf(i))}, about ${p.tokens} tokens, ${plural(p.files, "file")}): ${p.paths.join(", ")}`));
842
+ if (progress) {
843
+ io.out(`Read plan: ${readPlanRelOf(root, repo)}. ${progress.next ? `${partOfWords({ part: progress.next.part, total: progress.total })} is next (${progress.done ? `${progress.done} of ${progress.total} read` : `none of ${progress.total} read yet`}): ${progress.next.paths.join(", ")}.` : `All ${progress.total} parts are read.`} A part counts as read when every folder it covers is in the facts (a fact citing a file, or a line of ${factsRelOf(root)}/${repo}.reviewed.jsonl); atticus next says which comes next.`);
844
+ for (const p of progress.parts)
845
+ if (p.state === "in-progress")
846
+ io.out(` part ${p.part} is part-read: nothing in the facts yet for ${p.left.join(", ")}.`);
847
+ }
848
+ }
849
+ io.out(`Your assistant: ${tierWords(tier)}, ${tierSource(tier)}. ${tier.how}`);
850
+ io.out(`Another agentic assistant (Claude Code, Cursor, Gemini CLI) reads it the same way: /atticus-map ${repo}; one without file tools gets batches with atticus map ${repo} --handoff --max-tokens <its limit>.`);
851
+ if (tier.fallback)
852
+ io.out(tier.fallback);
853
+ if (tier.note)
854
+ io.out(tier.note);
855
+ if (tier.model)
856
+ io.out(tier.model);
857
+ if (tier.measured?.stale)
858
+ io.out(`That was ${tier.measured.days} days ago: atticus probe measures it again.`);
859
+ else if (tier.source === "runtime.yaml" && tier.tier !== "off")
860
+ io.out("atticus probe measures your assistant's tier and limit instead.");
861
+ io.out(plan ? `In batches at ${limit} tokens a prompt${given === void 0 ? " (GPT-4o mini through Copilot; --max-tokens n for your model's limit)" : from === "probe" ? ` (the limit stated when your assistant was measured on ${tier.measured?.at})` : ""}: ${plural(plan.batches.length, "prompt")}, one more if facts are rejected in the last.` : `A model of ${limit} tokens leaves too little room for the files beside the instructions: use a model with a bigger limit.`);
862
+ for (const q of questions)
863
+ io.out(`Question ${q.id}: ${q.question} (${q.state === "answered" ? `answered: ${q.answer?.text ?? q.options[(q.answer?.option ?? 1) - 1]?.label ?? ""}` : "open"})`);
864
+ if (questions.length)
865
+ io.out("Follow each answer; don't ask these again.");
866
+ return 0;
867
+ }
868
+ export {
869
+ REPO_READER,
870
+ mapCommand,
871
+ readAnswer,
872
+ repoReaderAgent
873
+ };