@joshuafolkken/kit 1.872.0

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 (1108) hide show
  1. package/.claude/.claude-plugin/plugin.json +11 -0
  2. package/.claude/settings.json +110 -0
  3. package/.claude/skills/dependency-update/SKILL.md +76 -0
  4. package/.claude/skills/epic-commands/SKILL.md +463 -0
  5. package/.claude/skills/verify-ui/SKILL.md +96 -0
  6. package/.claude/skills/workflow-commands/SKILL.md +265 -0
  7. package/.claude/skills/workflow-commands/background-commands.md +130 -0
  8. package/.claude/skills/workflow-commands/backlogrun-child.md +364 -0
  9. package/.claude/skills/workflow-commands/backlogrun-lanes.md +345 -0
  10. package/.claude/skills/workflow-commands/backlogrun-park.md +179 -0
  11. package/.claude/skills/workflow-commands/backlogrun-progress.md +600 -0
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +604 -0
  13. package/.claude/skills/workflow-commands/backlogrun.md +109 -0
  14. package/.claude/skills/workflow-commands/chain-rule.md +98 -0
  15. package/.claude/skills/workflow-commands/delegation.md +52 -0
  16. package/.claude/skills/workflow-commands/followup-reference.md +118 -0
  17. package/.claude/skills/workflow-commands/followup.md +222 -0
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +93 -0
  19. package/.claude/skills/workflow-commands/fullrun.md +82 -0
  20. package/.claude/skills/workflow-commands/halfrun.md +73 -0
  21. package/.claude/skills/workflow-commands/into-target.md +48 -0
  22. package/.claude/skills/workflow-commands/issue-comments.md +109 -0
  23. package/.claude/skills/workflow-commands/issue-fold-existing.md +27 -0
  24. package/.claude/skills/workflow-commands/issue-scout.md +45 -0
  25. package/.claude/skills/workflow-commands/kickoff.md +82 -0
  26. package/.claude/skills/workflow-commands/latest-gate.md +85 -0
  27. package/.claude/skills/workflow-commands/needs-human-review.md +64 -0
  28. package/.claude/skills/workflow-commands/observation-filing.md +349 -0
  29. package/.claude/skills/workflow-commands/pre-gate-cut.md +340 -0
  30. package/.claude/skills/workflow-commands/prerequisite.md +62 -0
  31. package/.claude/skills/workflow-commands/retrospective.md +81 -0
  32. package/.claude/skills/workflow-commands/rule-residency.md +267 -0
  33. package/.claude/skills/workflow-commands/split-assessment.md +130 -0
  34. package/.claude/skills/workflow-commands/target-repository.md +58 -0
  35. package/.claude/skills/workflow-commands/working-tree-hold.md +66 -0
  36. package/.claude-plugin/marketplace.json +15 -0
  37. package/.coderabbit.yaml +50 -0
  38. package/.codex/config.toml +8 -0
  39. package/.codex/hooks.json +71 -0
  40. package/.cursorrules +45 -0
  41. package/.gitattributes +7 -0
  42. package/.github/dependabot.yml +19 -0
  43. package/.github/pull_request_template.md +1 -0
  44. package/.github/release.yml +18 -0
  45. package/.github/workflows/auto-tag.yml +111 -0
  46. package/.github/workflows/ci.yml +681 -0
  47. package/.github/workflows/dependabot-auto-merge.yml +55 -0
  48. package/.github/workflows/production.yml +47 -0
  49. package/.github/workflows/publish.yml +39 -0
  50. package/.github/workflows/sonar-qube.yml +34 -0
  51. package/.mcp.json +8 -0
  52. package/.ncurc.json +3 -0
  53. package/.prettierignore +20 -0
  54. package/.vscode/extensions.json +21 -0
  55. package/.vscode/settings.json +41 -0
  56. package/AGENTS.md +29 -0
  57. package/CLAUDE.md +207 -0
  58. package/CODE_OF_CONDUCT.md +132 -0
  59. package/GEMINI.md +30 -0
  60. package/LICENSE +21 -0
  61. package/README.md +41 -0
  62. package/SECURITY.md +34 -0
  63. package/cspell/index.yaml +177 -0
  64. package/dist/CLAUDE.md +207 -0
  65. package/dist/config-merge/index.d.ts +29 -0
  66. package/dist/config-merge/index.js +459 -0
  67. package/dist/hooks/batch-guard.js +28 -0
  68. package/dist/hooks/chunk-25JL6FMS.js +4970 -0
  69. package/dist/hooks/chunk-2ANGT3XM.js +375 -0
  70. package/dist/hooks/chunk-2EI5GBSW.js +42 -0
  71. package/dist/hooks/chunk-2OT5XE2N.js +5014 -0
  72. package/dist/hooks/chunk-2RUPMGGV.js +137 -0
  73. package/dist/hooks/chunk-2XIGZQMQ.js +3299 -0
  74. package/dist/hooks/chunk-33ELOKEV.js +910 -0
  75. package/dist/hooks/chunk-33YRTKM7.js +230 -0
  76. package/dist/hooks/chunk-36JQU5NN.js +77 -0
  77. package/dist/hooks/chunk-3EJBTWVS.js +1769 -0
  78. package/dist/hooks/chunk-3FK5SFAC.js +432 -0
  79. package/dist/hooks/chunk-3PWPYDD2.js +240 -0
  80. package/dist/hooks/chunk-3TQU7TDH.js +375 -0
  81. package/dist/hooks/chunk-3TVLSFZ6.js +432 -0
  82. package/dist/hooks/chunk-3VXYCB4E.js +77 -0
  83. package/dist/hooks/chunk-44M6JXGV.js +3398 -0
  84. package/dist/hooks/chunk-46EEEHC3.js +240 -0
  85. package/dist/hooks/chunk-4A7UVP2P.js +364 -0
  86. package/dist/hooks/chunk-4LFQEZS4.js +137 -0
  87. package/dist/hooks/chunk-4OCX3V2T.js +469 -0
  88. package/dist/hooks/chunk-4OHA5DE7.js +49 -0
  89. package/dist/hooks/chunk-4PMDW3YD.js +68 -0
  90. package/dist/hooks/chunk-4QHBNAI4.js +68 -0
  91. package/dist/hooks/chunk-4SSB3FEE.js +3273 -0
  92. package/dist/hooks/chunk-5A2WQ2CQ.js +5390 -0
  93. package/dist/hooks/chunk-5EVA2JQB.js +5390 -0
  94. package/dist/hooks/chunk-5P7VF5VE.js +3230 -0
  95. package/dist/hooks/chunk-5QWJGGZP.js +49 -0
  96. package/dist/hooks/chunk-5U5EZYG6.js +77 -0
  97. package/dist/hooks/chunk-5VUUF3ZV.js +240 -0
  98. package/dist/hooks/chunk-5WA7UBT3.js +374 -0
  99. package/dist/hooks/chunk-6EBGRQ3Q.js +301 -0
  100. package/dist/hooks/chunk-6TVHWMD3.js +432 -0
  101. package/dist/hooks/chunk-6V5OPIUU.js +13 -0
  102. package/dist/hooks/chunk-6VAGLEMB.js +68 -0
  103. package/dist/hooks/chunk-75BTXKFJ.js +3424 -0
  104. package/dist/hooks/chunk-75RHN67S.js +137 -0
  105. package/dist/hooks/chunk-76KC3BDD.js +3414 -0
  106. package/dist/hooks/chunk-76SLS7CZ.js +898 -0
  107. package/dist/hooks/chunk-7DHZ4DWT.js +5015 -0
  108. package/dist/hooks/chunk-7INSJDGE.js +458 -0
  109. package/dist/hooks/chunk-7VJ4FTDX.js +268 -0
  110. package/dist/hooks/chunk-7XCYNHQK.js +77 -0
  111. package/dist/hooks/chunk-A5YJ3H7E.js +375 -0
  112. package/dist/hooks/chunk-AAEXXUUL.js +268 -0
  113. package/dist/hooks/chunk-ABVEVV2M.js +432 -0
  114. package/dist/hooks/chunk-ACN3YXFL.js +68 -0
  115. package/dist/hooks/chunk-AD3XE3QZ.js +397 -0
  116. package/dist/hooks/chunk-AENFZPZH.js +230 -0
  117. package/dist/hooks/chunk-AFKRFQ6W.js +68 -0
  118. package/dist/hooks/chunk-AHD5IPWI.js +375 -0
  119. package/dist/hooks/chunk-AMK5JGV7.js +77 -0
  120. package/dist/hooks/chunk-ARN7NCQI.js +425 -0
  121. package/dist/hooks/chunk-AUFY653N.js +3425 -0
  122. package/dist/hooks/chunk-AXQBNFEF.js +375 -0
  123. package/dist/hooks/chunk-AYC7R6U4.js +3316 -0
  124. package/dist/hooks/chunk-AYEA2FJ7.js +5015 -0
  125. package/dist/hooks/chunk-B2LIXYFL.js +77 -0
  126. package/dist/hooks/chunk-B4HPNY2I.js +375 -0
  127. package/dist/hooks/chunk-B4YNCUGB.js +469 -0
  128. package/dist/hooks/chunk-B57S3VWT.js +922 -0
  129. package/dist/hooks/chunk-BINZ3PLI.js +364 -0
  130. package/dist/hooks/chunk-BIWLABFK.js +432 -0
  131. package/dist/hooks/chunk-BODUSXKK.js +410 -0
  132. package/dist/hooks/chunk-BQBAT2YK.js +375 -0
  133. package/dist/hooks/chunk-BUJEBW75.js +391 -0
  134. package/dist/hooks/chunk-BVNWORKA.js +72 -0
  135. package/dist/hooks/chunk-BWI47LQS.js +5205 -0
  136. package/dist/hooks/chunk-C25HRMJX.js +137 -0
  137. package/dist/hooks/chunk-CBFZNC74.js +375 -0
  138. package/dist/hooks/chunk-CECYXS4Y.js +3424 -0
  139. package/dist/hooks/chunk-CELGUP5F.js +49 -0
  140. package/dist/hooks/chunk-CMHANU3F.js +3442 -0
  141. package/dist/hooks/chunk-CMN372LI.js +68 -0
  142. package/dist/hooks/chunk-CPGZLMMK.js +3299 -0
  143. package/dist/hooks/chunk-CTQKXDC7.js +268 -0
  144. package/dist/hooks/chunk-CYAT4RIT.js +68 -0
  145. package/dist/hooks/chunk-CYTWYCH2.js +5014 -0
  146. package/dist/hooks/chunk-CZSOLRBA.js +77 -0
  147. package/dist/hooks/chunk-D2PIDYJR.js +3438 -0
  148. package/dist/hooks/chunk-DE57HI6T.js +137 -0
  149. package/dist/hooks/chunk-DGXDGAPG.js +5306 -0
  150. package/dist/hooks/chunk-DNYRSYQG.js +5014 -0
  151. package/dist/hooks/chunk-DTAXH2A2.js +240 -0
  152. package/dist/hooks/chunk-E2IZUWI5.js +375 -0
  153. package/dist/hooks/chunk-E4L2K2BL.js +397 -0
  154. package/dist/hooks/chunk-E55NKX5F.js +68 -0
  155. package/dist/hooks/chunk-ECXVCCVD.js +3079 -0
  156. package/dist/hooks/chunk-EPHO443D.js +68 -0
  157. package/dist/hooks/chunk-EUFK2BI2.js +375 -0
  158. package/dist/hooks/chunk-EYCD5ZAV.js +137 -0
  159. package/dist/hooks/chunk-F2SDYJU4.js +240 -0
  160. package/dist/hooks/chunk-F4B5D5TF.js +68 -0
  161. package/dist/hooks/chunk-FGEO3NDX.js +432 -0
  162. package/dist/hooks/chunk-FJYI52RE.js +137 -0
  163. package/dist/hooks/chunk-FXAKJKTB.js +18 -0
  164. package/dist/hooks/chunk-FYTZHIY4.js +3085 -0
  165. package/dist/hooks/chunk-G7JL2A5K.js +375 -0
  166. package/dist/hooks/chunk-GA3ITDBW.js +42 -0
  167. package/dist/hooks/chunk-GDR4H4SV.js +469 -0
  168. package/dist/hooks/chunk-GFKDXPSM.js +2855 -0
  169. package/dist/hooks/chunk-GIMRTKFU.js +566 -0
  170. package/dist/hooks/chunk-GOPHRLGO.js +240 -0
  171. package/dist/hooks/chunk-GX4HO7SJ.js +230 -0
  172. package/dist/hooks/chunk-GXKKK23T.js +240 -0
  173. package/dist/hooks/chunk-GZ6FUVIK.js +566 -0
  174. package/dist/hooks/chunk-H5HPY5M5.js +2869 -0
  175. package/dist/hooks/chunk-HCF3OGEE.js +1829 -0
  176. package/dist/hooks/chunk-HDEXAOUM.js +469 -0
  177. package/dist/hooks/chunk-HM2TY3TN.js +469 -0
  178. package/dist/hooks/chunk-HOA7NXA2.js +55 -0
  179. package/dist/hooks/chunk-HOFEWH6H.js +240 -0
  180. package/dist/hooks/chunk-HUUI6S5J.js +2669 -0
  181. package/dist/hooks/chunk-I4D3NVUD.js +469 -0
  182. package/dist/hooks/chunk-I4Q6WAJE.js +68 -0
  183. package/dist/hooks/chunk-IB6N4CR2.js +432 -0
  184. package/dist/hooks/chunk-IFLDYJMD.js +469 -0
  185. package/dist/hooks/chunk-IGU466YD.js +77 -0
  186. package/dist/hooks/chunk-IJCQUHKY.js +375 -0
  187. package/dist/hooks/chunk-IKUMBDJB.js +230 -0
  188. package/dist/hooks/chunk-IM3BDIBJ.js +5005 -0
  189. package/dist/hooks/chunk-IMYMAODK.js +3431 -0
  190. package/dist/hooks/chunk-IN2ZVGXA.js +5005 -0
  191. package/dist/hooks/chunk-ITVJ2MKQ.js +18 -0
  192. package/dist/hooks/chunk-J5RIJYTM.js +2669 -0
  193. package/dist/hooks/chunk-JFLMH4K5.js +3460 -0
  194. package/dist/hooks/chunk-JR25IFML.js +77 -0
  195. package/dist/hooks/chunk-JT5AUXFI.js +432 -0
  196. package/dist/hooks/chunk-JY5YVN6N.js +3234 -0
  197. package/dist/hooks/chunk-K5Q4ETVI.js +391 -0
  198. package/dist/hooks/chunk-K67V2F24.js +137 -0
  199. package/dist/hooks/chunk-KABG6AEW.js +3460 -0
  200. package/dist/hooks/chunk-KATZESEC.js +3273 -0
  201. package/dist/hooks/chunk-KFH4H7W7.js +469 -0
  202. package/dist/hooks/chunk-KMUEI6RX.js +910 -0
  203. package/dist/hooks/chunk-KMV4OY77.js +3438 -0
  204. package/dist/hooks/chunk-KQAZNWEY.js +137 -0
  205. package/dist/hooks/chunk-KZZR6JER.js +5015 -0
  206. package/dist/hooks/chunk-LAR6DREP.js +77 -0
  207. package/dist/hooks/chunk-LNCJWEZD.js +5015 -0
  208. package/dist/hooks/chunk-LRYD2GLM.js +6 -0
  209. package/dist/hooks/chunk-LXBKYHDV.js +77 -0
  210. package/dist/hooks/chunk-LYLKIUNE.js +5024 -0
  211. package/dist/hooks/chunk-LZKCFOVC.js +432 -0
  212. package/dist/hooks/chunk-M4FCIYRI.js +77 -0
  213. package/dist/hooks/chunk-M5M7327Q.js +3425 -0
  214. package/dist/hooks/chunk-MF72MHSX.js +3455 -0
  215. package/dist/hooks/chunk-MK56LKDO.js +397 -0
  216. package/dist/hooks/chunk-N3MJADY7.js +240 -0
  217. package/dist/hooks/chunk-NFQSUDBN.js +458 -0
  218. package/dist/hooks/chunk-NHREKY45.js +137 -0
  219. package/dist/hooks/chunk-NP5TTAAW.js +375 -0
  220. package/dist/hooks/chunk-NQTLTKTJ.js +2993 -0
  221. package/dist/hooks/chunk-NVRCZPBZ.js +391 -0
  222. package/dist/hooks/chunk-O46HMMLJ.js +469 -0
  223. package/dist/hooks/chunk-OFJGH2L4.js +240 -0
  224. package/dist/hooks/chunk-OLFMCZH5.js +240 -0
  225. package/dist/hooks/chunk-OMCZS46I.js +49 -0
  226. package/dist/hooks/chunk-OQZEZW5G.js +469 -0
  227. package/dist/hooks/chunk-P2MDAT2Y.js +1897 -0
  228. package/dist/hooks/chunk-P3M2JJIF.js +68 -0
  229. package/dist/hooks/chunk-PDVHQITQ.js +3453 -0
  230. package/dist/hooks/chunk-PNT2AMDH.js +391 -0
  231. package/dist/hooks/chunk-PR2LVSY6.js +3445 -0
  232. package/dist/hooks/chunk-PRR5R4JK.js +137 -0
  233. package/dist/hooks/chunk-PXT44QVN.js +566 -0
  234. package/dist/hooks/chunk-PZLWJLAP.js +469 -0
  235. package/dist/hooks/chunk-Q2FEAZJ2.js +77 -0
  236. package/dist/hooks/chunk-Q32WETDO.js +3265 -0
  237. package/dist/hooks/chunk-Q45DUBLE.js +3600 -0
  238. package/dist/hooks/chunk-Q7NZSWQ5.js +240 -0
  239. package/dist/hooks/chunk-QH2JNAMK.js +3085 -0
  240. package/dist/hooks/chunk-QNNWYQ2R.js +375 -0
  241. package/dist/hooks/chunk-QPU5H2OS.js +68 -0
  242. package/dist/hooks/chunk-QRAHZ5TO.js +1829 -0
  243. package/dist/hooks/chunk-QUZ5HPIE.js +469 -0
  244. package/dist/hooks/chunk-QVCRG34O.js +2893 -0
  245. package/dist/hooks/chunk-R3MY4E3S.js +1675 -0
  246. package/dist/hooks/chunk-R6TXJJXP.js +77 -0
  247. package/dist/hooks/chunk-REJU6VT7.js +1829 -0
  248. package/dist/hooks/chunk-REQAQLRC.js +2993 -0
  249. package/dist/hooks/chunk-RFCXPAHH.js +391 -0
  250. package/dist/hooks/chunk-RHI6Y22X.js +137 -0
  251. package/dist/hooks/chunk-RKZVOBBS.js +469 -0
  252. package/dist/hooks/chunk-RL57TT2Y.js +566 -0
  253. package/dist/hooks/chunk-RORDOD4S.js +3321 -0
  254. package/dist/hooks/chunk-RZKYW5P2.js +77 -0
  255. package/dist/hooks/chunk-SJPJ6VSI.js +391 -0
  256. package/dist/hooks/chunk-SKSIJQQQ.js +432 -0
  257. package/dist/hooks/chunk-SSQDZKXG.js +268 -0
  258. package/dist/hooks/chunk-SSX23SJ2.js +89 -0
  259. package/dist/hooks/chunk-SYHFKE4C.js +77 -0
  260. package/dist/hooks/chunk-TCGNI2ZY.js +42 -0
  261. package/dist/hooks/chunk-TG3WXJF5.js +137 -0
  262. package/dist/hooks/chunk-TH7IJAY5.js +77 -0
  263. package/dist/hooks/chunk-TLZ27PCY.js +240 -0
  264. package/dist/hooks/chunk-U652FXTN.js +566 -0
  265. package/dist/hooks/chunk-UEK47YUF.js +268 -0
  266. package/dist/hooks/chunk-UIO45H3O.js +432 -0
  267. package/dist/hooks/chunk-UNLZEEVH.js +5005 -0
  268. package/dist/hooks/chunk-UNRVF3SZ.js +432 -0
  269. package/dist/hooks/chunk-USLFAFOI.js +3453 -0
  270. package/dist/hooks/chunk-VAEELMLL.js +442 -0
  271. package/dist/hooks/chunk-VALSWLDQ.js +3453 -0
  272. package/dist/hooks/chunk-VC5JEPNY.js +3398 -0
  273. package/dist/hooks/chunk-VEZVK6C7.js +230 -0
  274. package/dist/hooks/chunk-VK5JKFAR.js +49 -0
  275. package/dist/hooks/chunk-VNF2KP7Z.js +469 -0
  276. package/dist/hooks/chunk-VWWCUMW6.js +2669 -0
  277. package/dist/hooks/chunk-W4JARUQV.js +137 -0
  278. package/dist/hooks/chunk-WCYPBPJC.js +5014 -0
  279. package/dist/hooks/chunk-WEOBMNJG.js +2993 -0
  280. package/dist/hooks/chunk-WKJU3J5Y.js +5390 -0
  281. package/dist/hooks/chunk-WMN4TSVF.js +3299 -0
  282. package/dist/hooks/chunk-WNON54PT.js +3469 -0
  283. package/dist/hooks/chunk-WOVKBPPX.js +137 -0
  284. package/dist/hooks/chunk-WRVFORYJ.js +432 -0
  285. package/dist/hooks/chunk-WUBVYGQZ.js +240 -0
  286. package/dist/hooks/chunk-WWULTUOM.js +68 -0
  287. package/dist/hooks/chunk-WXHKKB45.js +4962 -0
  288. package/dist/hooks/chunk-XAI3YTHJ.js +469 -0
  289. package/dist/hooks/chunk-XFZH6JZJ.js +77 -0
  290. package/dist/hooks/chunk-XGPWX6IA.js +137 -0
  291. package/dist/hooks/chunk-XIXXIVGY.js +566 -0
  292. package/dist/hooks/chunk-XKDOYJGA.js +922 -0
  293. package/dist/hooks/chunk-YALTVBHM.js +432 -0
  294. package/dist/hooks/chunk-YEBEPBFK.js +5014 -0
  295. package/dist/hooks/chunk-YI2BQ3DK.js +3441 -0
  296. package/dist/hooks/chunk-YVNBCFGG.js +1829 -0
  297. package/dist/hooks/chunk-YXBN3RGG.js +432 -0
  298. package/dist/hooks/chunk-Z2OOJSW3.js +3163 -0
  299. package/dist/hooks/chunk-ZA3HVBOY.js +2644 -0
  300. package/dist/hooks/chunk-ZKID46U3.js +137 -0
  301. package/dist/hooks/chunk-ZPMU2JV6.js +49 -0
  302. package/dist/hooks/chunk-ZRKY4W7O.js +432 -0
  303. package/dist/hooks/chunk-ZTMRB7LJ.js +268 -0
  304. package/dist/hooks/chunk-ZVPPBQ3L.js +3413 -0
  305. package/dist/hooks/codex-hook-adapter.js +164 -0
  306. package/dist/hooks/duplicate-read-guard.js +29 -0
  307. package/dist/hooks/format-edited.js +37 -0
  308. package/dist/hooks/investigation-guard.js +31 -0
  309. package/dist/hooks/pretool-guard.js +21 -0
  310. package/dist/hooks/session-lang.js +34 -0
  311. package/dist/hooks/stop-guard.js +1597 -0
  312. package/dist/josh.js +1795 -0
  313. package/dist/managed-marker/index.d.ts +10 -0
  314. package/dist/managed-marker/index.js +32 -0
  315. package/dist/self-sync-guard/index.d.ts +10 -0
  316. package/dist/self-sync-guard/index.js +49 -0
  317. package/dist/version/index.d.ts +93 -0
  318. package/dist/version/index.js +1024 -0
  319. package/env/index.d.ts +7 -0
  320. package/env/index.js +62 -0
  321. package/eslint/base.js +233 -0
  322. package/eslint/checkout-rooted-parser.js +34 -0
  323. package/eslint/config-fingerprint.js +103 -0
  324. package/eslint/rules/code-quality.js +292 -0
  325. package/eslint/rules/english-only-prose.js +135 -0
  326. package/eslint/rules/formatting.js +44 -0
  327. package/eslint/rules/import.js +83 -0
  328. package/eslint/rules/namespace-object-export.js +107 -0
  329. package/eslint/rules/naming-convention.js +109 -0
  330. package/eslint/rules/promise.js +17 -0
  331. package/eslint/rules/sonarjs.js +45 -0
  332. package/eslint/rules/test-filename.js +91 -0
  333. package/eslint/rules/typescript.js +186 -0
  334. package/eslint/rules/unicorn.js +191 -0
  335. package/eslint/vanilla.js +1 -0
  336. package/evals/scenarios/consult-not-execute.json +20 -0
  337. package/evals/scenarios/no-implicit-workflow.json +26 -0
  338. package/evals/scenarios/overrides-both-locations.json +29 -0
  339. package/evals/scenarios/upstream-interrupt.json +23 -0
  340. package/evals/scenarios/workflow-skill-loaded.json +16 -0
  341. package/lefthook/base.yml +131 -0
  342. package/lefthook/vanilla.yml +7 -0
  343. package/package.json +169 -0
  344. package/playwright.config.ts +160 -0
  345. package/pnpm-workspace.yaml +41 -0
  346. package/ports/index.d.ts +17 -0
  347. package/ports/index.js +256 -0
  348. package/prettier/index.d.ts +3 -0
  349. package/prettier/index.js +31 -0
  350. package/prompts/agent-lint-protocol.json +79 -0
  351. package/prompts/agent-rules.md +63 -0
  352. package/prompts/coding-standards.md +382 -0
  353. package/prompts/collaboration-workflow/consultation-vs-execution.md +8 -0
  354. package/prompts/collaboration-workflow/cross-repo-epic.md +54 -0
  355. package/prompts/collaboration-workflow/distributed-docs.md +7 -0
  356. package/prompts/collaboration-workflow/durable-rules.md +24 -0
  357. package/prompts/collaboration-workflow/epic-audit.md +56 -0
  358. package/prompts/collaboration-workflow/epic-bundle.md +109 -0
  359. package/prompts/collaboration-workflow/file-edits.md +124 -0
  360. package/prompts/collaboration-workflow/gh-rest.md +57 -0
  361. package/prompts/collaboration-workflow/issue-citation.md +38 -0
  362. package/prompts/collaboration-workflow/issue-template.md +190 -0
  363. package/prompts/collaboration-workflow/latest-first.md +14 -0
  364. package/prompts/collaboration-workflow/no-clones.md +11 -0
  365. package/prompts/collaboration-workflow/operating-rules.md +123 -0
  366. package/prompts/collaboration-workflow/output-bounds.md +107 -0
  367. package/prompts/collaboration-workflow/overview.md +35 -0
  368. package/prompts/collaboration-workflow/plan-comment.md +85 -0
  369. package/prompts/collaboration-workflow/proposal-request.md +23 -0
  370. package/prompts/collaboration-workflow/report-format.md +206 -0
  371. package/prompts/collaboration-workflow/residency.md +94 -0
  372. package/prompts/collaboration-workflow/rule-delivery.md +146 -0
  373. package/prompts/collaboration-workflow/shell-body.md +82 -0
  374. package/prompts/collaboration-workflow/simplicity-first.md +9 -0
  375. package/prompts/collaboration-workflow/single-source-rules.md +13 -0
  376. package/prompts/collaboration-workflow/turn-batching.md +137 -0
  377. package/prompts/collaboration-workflow/upstream-interrupt.md +51 -0
  378. package/prompts/collaboration-workflow/wip-cap.md +118 -0
  379. package/prompts/collaboration-workflow.md +52 -0
  380. package/prompts/refactoring.md +103 -0
  381. package/prompts/review-rubric.md +338 -0
  382. package/prompts/review.md +217 -0
  383. package/prompts/sonar-hotspot-handling.md +77 -0
  384. package/prompts/testing-guide.md +277 -0
  385. package/scripts/adopt/adopt-logic.ts +107 -0
  386. package/scripts/adopt/adopt-toolkits.ts +181 -0
  387. package/scripts/adopt/adopt.ts +171 -0
  388. package/scripts/agent/agent-argv.ts +140 -0
  389. package/scripts/agent/agent-diagnostics.ts +120 -0
  390. package/scripts/agent/agent-event.ts +173 -0
  391. package/scripts/agent/agent-exit-record.ts +32 -0
  392. package/scripts/agent/agent-launch-environment.ts +71 -0
  393. package/scripts/agent/agent-role-profile.ts +329 -0
  394. package/scripts/agent/api-outage.ts +51 -0
  395. package/scripts/agent/claude-agent-argv.ts +151 -0
  396. package/scripts/agent/claude-result-event.ts +98 -0
  397. package/scripts/agent/codex-agent-argv.ts +94 -0
  398. package/scripts/agent/codex-home-source.ts +11 -0
  399. package/scripts/agent/interactive-ask.ts +91 -0
  400. package/scripts/auto-ok/auto-ok-cli.ts +516 -0
  401. package/scripts/backlog/backlog-arrival.ts +147 -0
  402. package/scripts/backlog/backlog-budget-cli.ts +220 -0
  403. package/scripts/backlog/backlog-budget.ts +284 -0
  404. package/scripts/backlog/backlog-defect-priority.ts +77 -0
  405. package/scripts/backlog/backlog-drive-cli.ts +377 -0
  406. package/scripts/backlog/backlog-drive-finish.ts +23 -0
  407. package/scripts/backlog/backlog-drive-named-offer.ts +81 -0
  408. package/scripts/backlog/backlog-drive-named.ts +101 -0
  409. package/scripts/backlog/backlog-drive-offer-argv.ts +29 -0
  410. package/scripts/backlog/backlog-drive-owner.ts +22 -0
  411. package/scripts/backlog/backlog-drive-restore.ts +67 -0
  412. package/scripts/backlog/backlog-drive.ts +322 -0
  413. package/scripts/backlog/backlog-named.ts +164 -0
  414. package/scripts/backlog/backlog-next.ts +376 -0
  415. package/scripts/backlog/backlog-offer-cli.ts +279 -0
  416. package/scripts/backlog/backlog-offer.ts +93 -0
  417. package/scripts/backlog/backlog-plan-cli.ts +235 -0
  418. package/scripts/backlog/backlog-plan.ts +231 -0
  419. package/scripts/backlog/backlog-pool.ts +322 -0
  420. package/scripts/backlog/backlog-ready.ts +146 -0
  421. package/scripts/backlog/backlog-scope.ts +144 -0
  422. package/scripts/backlog/backlog-stalled-cli.ts +30 -0
  423. package/scripts/backlog/backlog-stalled-detect.ts +143 -0
  424. package/scripts/backlog/backlog-stalled.ts +118 -0
  425. package/scripts/behavior/behavior-assertion.ts +87 -0
  426. package/scripts/behavior/behavior-cli.ts +88 -0
  427. package/scripts/behavior/behavior-rules.ts +128 -0
  428. package/scripts/build/build-bin.ts +36 -0
  429. package/scripts/build/build-claude-md.ts +42 -0
  430. package/scripts/build/build-config-merge.ts +26 -0
  431. package/scripts/build/build-hooks.ts +79 -0
  432. package/scripts/build/build-library.ts +83 -0
  433. package/scripts/build/build-managed-marker.ts +26 -0
  434. package/scripts/build/build-self-sync-guard.ts +26 -0
  435. package/scripts/build/build-version.ts +25 -0
  436. package/scripts/build/local-bin.ts +97 -0
  437. package/scripts/build/shim-shell.ts +25 -0
  438. package/scripts/bytes/bytes-command.ts +181 -0
  439. package/scripts/cases/cases-cli.ts +48 -0
  440. package/scripts/cases/cases-logic.ts +100 -0
  441. package/scripts/claude/skill-meta.ts +37 -0
  442. package/scripts/claude/workflow-destination.ts +13 -0
  443. package/scripts/clone/clone-aggregate.ts +76 -0
  444. package/scripts/clone/clone-fingerprint.ts +96 -0
  445. package/scripts/clone/clone-scan-cli.ts +39 -0
  446. package/scripts/clone/clone-scan.ts +158 -0
  447. package/scripts/config-merge/index.ts +19 -0
  448. package/scripts/config-merge/json-format.ts +128 -0
  449. package/scripts/config-merge/list-patch.ts +61 -0
  450. package/scripts/config-merge/parse-jsonc.ts +14 -0
  451. package/scripts/config-merge/patch-json-key.ts +439 -0
  452. package/scripts/config-merge/patch-json-list.ts +38 -0
  453. package/scripts/config-merge/patch-yaml-list.ts +107 -0
  454. package/scripts/cost-runtime/codex-usage.ts +119 -0
  455. package/scripts/cost-runtime/context-cut-payback.ts +77 -0
  456. package/scripts/cost-runtime/context-cut-threshold.ts +21 -0
  457. package/scripts/cost-runtime/cost-attribute.ts +168 -0
  458. package/scripts/cost-runtime/cost-blocks.ts +149 -0
  459. package/scripts/cost-runtime/cost-cli.ts +318 -0
  460. package/scripts/cost-runtime/cost-corpus.ts +278 -0
  461. package/scripts/cost-runtime/cost-format.ts +32 -0
  462. package/scripts/cost-runtime/cost-pricing.ts +176 -0
  463. package/scripts/cost-runtime/cost-tokens.ts +84 -0
  464. package/scripts/cost-runtime/cost-transcript.ts +531 -0
  465. package/scripts/cost-runtime/cost-usage.ts +287 -0
  466. package/scripts/cost-runtime/cost-verdict.ts +89 -0
  467. package/scripts/cost-runtime/own-session.ts +58 -0
  468. package/scripts/cost-runtime/transcript-cwd.ts +14 -0
  469. package/scripts/delegation/delegation-cli.ts +91 -0
  470. package/scripts/delegation/delegation-policy.ts +178 -0
  471. package/scripts/delegation/duplicate-read-guard.ts +244 -0
  472. package/scripts/delegation/fanout-cli.ts +61 -0
  473. package/scripts/delegation/fanout.ts +95 -0
  474. package/scripts/delegation/investigation-guard.ts +131 -0
  475. package/scripts/delegation/investigation-reads.ts +637 -0
  476. package/scripts/discovery/repo-discovery.ts +166 -0
  477. package/scripts/discovery/repo-map-logic.ts +102 -0
  478. package/scripts/discovery/repo-origin.ts +153 -0
  479. package/scripts/discovery/repo-party-cli.ts +69 -0
  480. package/scripts/discovery/repo-party.ts +46 -0
  481. package/scripts/doctor/doctor-consumer.ts +181 -0
  482. package/scripts/doctor/doctor-io.ts +210 -0
  483. package/scripts/doctor/doctor-logic.ts +122 -0
  484. package/scripts/doctor/doctor-ports.ts +117 -0
  485. package/scripts/doctor/doctor.ts +232 -0
  486. package/scripts/document/backlogrun-parent-read-set.ts +48 -0
  487. package/scripts/document/bash-output-cap.ts +45 -0
  488. package/scripts/document/document-byte-budget.ts +183 -0
  489. package/scripts/document/document-byte-check.ts +131 -0
  490. package/scripts/document/document-reachability.ts +131 -0
  491. package/scripts/document/document-read-cli.ts +82 -0
  492. package/scripts/document/document-scan.ts +108 -0
  493. package/scripts/document/document-section-cli.ts +101 -0
  494. package/scripts/document/document-section.ts +156 -0
  495. package/scripts/document/edit-files-cli.ts +280 -0
  496. package/scripts/document/entry-read-budget.ts +154 -0
  497. package/scripts/document/entry-read-set.ts +471 -0
  498. package/scripts/document/generate-catalog.ts +69 -0
  499. package/scripts/document/lane-child-read-set.ts +88 -0
  500. package/scripts/document/read-files-cli.ts +135 -0
  501. package/scripts/document/read-set-cli.ts +295 -0
  502. package/scripts/document/read-set-point-of-use.ts +89 -0
  503. package/scripts/document/read-set-pricing.ts +52 -0
  504. package/scripts/document/read-set-trim.ts +78 -0
  505. package/scripts/document/retired-phrases.ts +143 -0
  506. package/scripts/document/review-agent-type.ts +46 -0
  507. package/scripts/document/single-source.ts +73 -0
  508. package/scripts/epic/epic-audit-checks.ts +452 -0
  509. package/scripts/epic/epic-audit-cli.ts +374 -0
  510. package/scripts/epic/epic-audit-orphans.ts +142 -0
  511. package/scripts/epic/epic-audit-rationale.ts +191 -0
  512. package/scripts/epic/epic-audit-report.ts +101 -0
  513. package/scripts/epic/epic-audit.ts +240 -0
  514. package/scripts/epic/epic-bundle-cli.ts +472 -0
  515. package/scripts/epic/epic-bundle-evidence.ts +147 -0
  516. package/scripts/epic/epic-bundle-gaps.ts +86 -0
  517. package/scripts/epic/epic-bundle-referenced.ts +195 -0
  518. package/scripts/epic/epic-bundle.ts +309 -0
  519. package/scripts/epic/epic-busy.ts +204 -0
  520. package/scripts/epic/epic-candidate-confirm.ts +279 -0
  521. package/scripts/epic/epic-classify.ts +294 -0
  522. package/scripts/epic/epic-cross-repo.ts +366 -0
  523. package/scripts/epic/epic-fetch.ts +370 -0
  524. package/scripts/epic/epic-graph.ts +279 -0
  525. package/scripts/epic/epic-index.ts +209 -0
  526. package/scripts/epic/epic-issue.ts +172 -0
  527. package/scripts/epic/epic-lane-offer.ts +207 -0
  528. package/scripts/epic/epic-nested.ts +37 -0
  529. package/scripts/epic/epic-next-read.ts +141 -0
  530. package/scripts/epic/epic-next-views.ts +144 -0
  531. package/scripts/epic/epic-next.ts +477 -0
  532. package/scripts/epic/epic-outside-blocker.ts +113 -0
  533. package/scripts/epic/epic-relation-recheck.ts +108 -0
  534. package/scripts/epic/epic-report.ts +200 -0
  535. package/scripts/gate/core-budget.ts +292 -0
  536. package/scripts/gate/gate-log.ts +95 -0
  537. package/scripts/gate/gate-plan.ts +356 -0
  538. package/scripts/gate/gate-report.ts +207 -0
  539. package/scripts/gate/gate-skip.ts +123 -0
  540. package/scripts/gate/gate-tree.ts +49 -0
  541. package/scripts/gate/hook-gate-reuse.ts +130 -0
  542. package/scripts/gate/pre-commit-type-check.ts +187 -0
  543. package/scripts/gate/scoped-green.ts +260 -0
  544. package/scripts/gate/type-check-step.ts +90 -0
  545. package/scripts/gate/verification-gate.ts +531 -0
  546. package/scripts/gh/fix-gh-packages-logic.ts +232 -0
  547. package/scripts/gh/fix-gh-packages.ts +129 -0
  548. package/scripts/gh/gh-cli-token.ts +18 -0
  549. package/scripts/gh/gh-spawn.ts +44 -0
  550. package/scripts/git/animation-helpers.ts +81 -0
  551. package/scripts/git/change-base.ts +26 -0
  552. package/scripts/git/changed-file-scope.ts +209 -0
  553. package/scripts/git/changed-paths.ts +30 -0
  554. package/scripts/git/constants.ts +41 -0
  555. package/scripts/git/git-ai-review-scan.ts +154 -0
  556. package/scripts/git/git-animation.ts +41 -0
  557. package/scripts/git/git-branch.ts +127 -0
  558. package/scripts/git/git-command.ts +587 -0
  559. package/scripts/git/git-commit.ts +27 -0
  560. package/scripts/git/git-common-directory.ts +38 -0
  561. package/scripts/git/git-epic-add-body.ts +365 -0
  562. package/scripts/git/git-epic-add-plan.ts +421 -0
  563. package/scripts/git/git-epic-add.ts +249 -0
  564. package/scripts/git/git-epic-body.ts +150 -0
  565. package/scripts/git/git-epic-chains.ts +411 -0
  566. package/scripts/git/git-epic-close-comment.ts +199 -0
  567. package/scripts/git/git-epic-close.ts +393 -0
  568. package/scripts/git/git-epic-decision.ts +171 -0
  569. package/scripts/git/git-epic-parse.ts +351 -0
  570. package/scripts/git/git-epic-promote.ts +102 -0
  571. package/scripts/git/git-epic-read.ts +73 -0
  572. package/scripts/git/git-epic-reconcile.ts +246 -0
  573. package/scripts/git/git-epic-reference.ts +98 -0
  574. package/scripts/git/git-epic-relations.ts +78 -0
  575. package/scripts/git/git-epic-remove-plan.ts +152 -0
  576. package/scripts/git/git-epic-remove.ts +101 -0
  577. package/scripts/git/git-epic-run.ts +223 -0
  578. package/scripts/git/git-epic-sections.ts +98 -0
  579. package/scripts/git/git-epic-shape.ts +81 -0
  580. package/scripts/git/git-epic-validate.ts +155 -0
  581. package/scripts/git/git-error.ts +78 -0
  582. package/scripts/git/git-execa-error.ts +35 -0
  583. package/scripts/git/git-fixture-workspace.ts +88 -0
  584. package/scripts/git/git-followup-cleanup.ts +88 -0
  585. package/scripts/git/git-followup-flush.ts +63 -0
  586. package/scripts/git/git-followup-label.ts +67 -0
  587. package/scripts/git/git-followup-pending.ts +95 -0
  588. package/scripts/git/git-followup-stages.ts +149 -0
  589. package/scripts/git/git-gh-api-path.ts +118 -0
  590. package/scripts/git/git-gh-check.ts +21 -0
  591. package/scripts/git/git-gh-command.ts +17 -0
  592. package/scripts/git/git-gh-exec.ts +344 -0
  593. package/scripts/git/git-gh-failure.ts +103 -0
  594. package/scripts/git/git-gh-helpers.ts +44 -0
  595. package/scripts/git/git-gh-issue-list.ts +257 -0
  596. package/scripts/git/git-gh-issue-read.ts +457 -0
  597. package/scripts/git/git-gh-issue-rest.ts +238 -0
  598. package/scripts/git/git-gh-issue-write.ts +285 -0
  599. package/scripts/git/git-gh-issue.ts +161 -0
  600. package/scripts/git/git-gh-pr-auto-merge.ts +85 -0
  601. package/scripts/git/git-gh-pr-read.ts +322 -0
  602. package/scripts/git/git-gh-pr-rest.ts +172 -0
  603. package/scripts/git/git-gh-pr-review.ts +103 -0
  604. package/scripts/git/git-gh-pr-rollup.ts +91 -0
  605. package/scripts/git/git-gh-pr-snapshot.ts +138 -0
  606. package/scripts/git/git-gh-pr.ts +219 -0
  607. package/scripts/git/git-gh-reachability.ts +56 -0
  608. package/scripts/git/git-gh-repo.ts +37 -0
  609. package/scripts/git/git-gh-rest-state.ts +14 -0
  610. package/scripts/git/git-issue.ts +168 -0
  611. package/scripts/git/git-location-environment.ts +62 -0
  612. package/scripts/git/git-ls-remote.ts +28 -0
  613. package/scripts/git/git-next-issues.ts +98 -0
  614. package/scripts/git/git-notify.ts +104 -0
  615. package/scripts/git/git-pr-ai-review.ts +180 -0
  616. package/scripts/git/git-pr-checks-eval.ts +265 -0
  617. package/scripts/git/git-pr-checks-parse.ts +153 -0
  618. package/scripts/git/git-pr-checks-watch.ts +184 -0
  619. package/scripts/git/git-pr-checks.ts +387 -0
  620. package/scripts/git/git-pr-coderabbit.ts +129 -0
  621. package/scripts/git/git-pr-confirmation.ts +64 -0
  622. package/scripts/git/git-pr-error.ts +25 -0
  623. package/scripts/git/git-pr-followup-wrapup.ts +225 -0
  624. package/scripts/git/git-pr-followup.ts +436 -0
  625. package/scripts/git/git-pr-managed-config.ts +69 -0
  626. package/scripts/git/git-pr-messages.ts +37 -0
  627. package/scripts/git/git-pr.ts +181 -0
  628. package/scripts/git/git-prompt-display.ts +22 -0
  629. package/scripts/git/git-prompt.ts +207 -0
  630. package/scripts/git/git-push-transport.ts +173 -0
  631. package/scripts/git/git-push.ts +27 -0
  632. package/scripts/git/git-remote-branch.ts +40 -0
  633. package/scripts/git/git-spawn.ts +47 -0
  634. package/scripts/git/git-staging.ts +128 -0
  635. package/scripts/git/git-stash.ts +124 -0
  636. package/scripts/git/git-status.ts +198 -0
  637. package/scripts/git/git-worktree.ts +110 -0
  638. package/scripts/git/github-issue-url.ts +105 -0
  639. package/scripts/git/gone-branch.ts +113 -0
  640. package/scripts/git/issue-labels.ts +279 -0
  641. package/scripts/git/listing-cutoff.ts +51 -0
  642. package/scripts/git/main-merge-guard.ts +134 -0
  643. package/scripts/git/main-merge.ts +120 -0
  644. package/scripts/git/main-sync.ts +121 -0
  645. package/scripts/git/parse-json-array.ts +102 -0
  646. package/scripts/git/schemas.ts +166 -0
  647. package/scripts/git/stash-orphans.ts +91 -0
  648. package/scripts/git/stash-pop-args.ts +59 -0
  649. package/scripts/git/stash-pop-cli.ts +105 -0
  650. package/scripts/git/telegram-notify.ts +404 -0
  651. package/scripts/hooks/batch-guard.ts +144 -0
  652. package/scripts/hooks/check-commit-message.ts +134 -0
  653. package/scripts/hooks/codex-hook-adapter.ts +155 -0
  654. package/scripts/hooks/edited-cspell.ts +128 -0
  655. package/scripts/hooks/format-edited-file-fixtures.ts +109 -0
  656. package/scripts/hooks/format-edited-file.ts +510 -0
  657. package/scripts/hooks/format-rewrite-notice.ts +99 -0
  658. package/scripts/hooks/pre-push-unit.ts +146 -0
  659. package/scripts/hooks/pretool-guard.ts +96 -0
  660. package/scripts/hooks/prevent-main-commit.ts +38 -0
  661. package/scripts/hooks/prompt-hooks.ts +38 -0
  662. package/scripts/hooks/reserved-run.ts +90 -0
  663. package/scripts/hooks/stop-guard.ts +135 -0
  664. package/scripts/init/claude-plugin-config.ts +51 -0
  665. package/scripts/init/distributed-paths.ts +100 -0
  666. package/scripts/init/hook-command-rewrite.ts +85 -0
  667. package/scripts/init/hook-launch.ts +31 -0
  668. package/scripts/init/init-actions.ts +147 -0
  669. package/scripts/init/init-ai-copy.ts +235 -0
  670. package/scripts/init/init-copy-content.ts +50 -0
  671. package/scripts/init/init-logic-deploy-vps.ts +43 -0
  672. package/scripts/init/init-logic-json-merge.ts +340 -0
  673. package/scripts/init/init-logic-migrate.ts +62 -0
  674. package/scripts/init/init-logic-package-key-order.ts +50 -0
  675. package/scripts/init/init-logic-secretlint.ts +36 -0
  676. package/scripts/init/init-logic-sonar.ts +197 -0
  677. package/scripts/init/init-logic-templates.ts +142 -0
  678. package/scripts/init/init-logic-workspace.ts +59 -0
  679. package/scripts/init/init-logic-yaml-merge.ts +57 -0
  680. package/scripts/init/init-logic.ts +474 -0
  681. package/scripts/init/init-paths.ts +11 -0
  682. package/scripts/init/init-sonar.ts +32 -0
  683. package/scripts/init/init.ts +219 -0
  684. package/scripts/init/kit-base-preset.ts +60 -0
  685. package/scripts/init/plugin-install-hint.ts +47 -0
  686. package/scripts/init/tsconfig-preset-migration.ts +67 -0
  687. package/scripts/issue/baseline-measure.ts +105 -0
  688. package/scripts/issue/behavior-change-lint.ts +122 -0
  689. package/scripts/issue/defect-rate-cli.ts +167 -0
  690. package/scripts/issue/defect-rate.ts +145 -0
  691. package/scripts/issue/issue-backlinks-cli.ts +97 -0
  692. package/scripts/issue/issue-backlinks.ts +164 -0
  693. package/scripts/issue/issue-cite-cli.ts +158 -0
  694. package/scripts/issue/issue-cite.ts +102 -0
  695. package/scripts/issue/issue-comment-cli.ts +95 -0
  696. package/scripts/issue/issue-fold-cli.ts +104 -0
  697. package/scripts/issue/issue-fold-existing-cli.ts +81 -0
  698. package/scripts/issue/issue-fold-existing.ts +73 -0
  699. package/scripts/issue/issue-fold.ts +42 -0
  700. package/scripts/issue/issue-lint-cli.ts +60 -0
  701. package/scripts/issue/issue-lint.ts +26 -0
  702. package/scripts/issue/issue-logic.ts +50 -0
  703. package/scripts/issue/issue-read-cli.ts +190 -0
  704. package/scripts/issue/issue-read.ts +145 -0
  705. package/scripts/issue/issue-scout-cli.ts +482 -0
  706. package/scripts/issue/issue-scout.ts +244 -0
  707. package/scripts/issue/issue-state-cli.ts +260 -0
  708. package/scripts/issue/issue-state.ts +109 -0
  709. package/scripts/issue/markdown-section.ts +39 -0
  710. package/scripts/issue/measure-rerun-cli.ts +98 -0
  711. package/scripts/issue/reproduction-measure.ts +59 -0
  712. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +1171 -0
  713. package/scripts/josh/agent-session-environment.ts +188 -0
  714. package/scripts/josh/cli-body.ts +96 -0
  715. package/scripts/josh/command-suggest.ts +57 -0
  716. package/scripts/josh/file-map-stamp.ts +264 -0
  717. package/scripts/josh/hook-decision.ts +479 -0
  718. package/scripts/josh/josh-command-map.ts +196 -0
  719. package/scripts/josh/josh-command-types.ts +226 -0
  720. package/scripts/josh/josh-commands-ai.ts +327 -0
  721. package/scripts/josh/josh-commands-backlog.ts +54 -0
  722. package/scripts/josh/josh-commands-clone.ts +18 -0
  723. package/scripts/josh/josh-commands-development.ts +206 -0
  724. package/scripts/josh/josh-commands-document.ts +45 -0
  725. package/scripts/josh/josh-commands-guard.ts +38 -0
  726. package/scripts/josh/josh-commands-hooks.ts +42 -0
  727. package/scripts/josh/josh-commands-issue.ts +69 -0
  728. package/scripts/josh/josh-commands-lane.ts +75 -0
  729. package/scripts/josh/josh-commands-lint.ts +37 -0
  730. package/scripts/josh/josh-commands-maintenance.ts +80 -0
  731. package/scripts/josh/josh-commands-project.ts +53 -0
  732. package/scripts/josh/josh-commands-split.ts +20 -0
  733. package/scripts/josh/josh-commands-versioning.ts +48 -0
  734. package/scripts/josh/josh-commands-workflow.ts +116 -0
  735. package/scripts/josh/josh-composite-arguments.ts +55 -0
  736. package/scripts/josh/josh-environment-file.ts +31 -0
  737. package/scripts/josh/josh-in-process.ts +80 -0
  738. package/scripts/josh/josh-logic.ts +308 -0
  739. package/scripts/josh/josh-run.ts +53 -0
  740. package/scripts/josh/josh-script-reader.ts +11 -0
  741. package/scripts/josh/josh-verdict.ts +111 -0
  742. package/scripts/josh/josh.ts +60 -0
  743. package/scripts/josh/kit-only.ts +33 -0
  744. package/scripts/josh/path-decision.ts +104 -0
  745. package/scripts/josh/platform-temporary.ts +66 -0
  746. package/scripts/josh/process-identity.ts +335 -0
  747. package/scripts/josh/session-language-cli.ts +51 -0
  748. package/scripts/josh/session-language.ts +30 -0
  749. package/scripts/josh/stamp-file.ts +194 -0
  750. package/scripts/lane/lane-await.ts +165 -0
  751. package/scripts/lane/lane-cache-run.ts +39 -0
  752. package/scripts/lane/lane-cache.ts +135 -0
  753. package/scripts/lane/lane-capacity.ts +69 -0
  754. package/scripts/lane/lane-child-invocation.ts +73 -0
  755. package/scripts/lane/lane-child-marker.ts +58 -0
  756. package/scripts/lane/lane-cli.ts +410 -0
  757. package/scripts/lane/lane-close.ts +197 -0
  758. package/scripts/lane/lane-dispatch-log.ts +13 -0
  759. package/scripts/lane/lane-dispatch.ts +458 -0
  760. package/scripts/lane/lane-environment.ts +253 -0
  761. package/scripts/lane/lane-guard-policy.ts +136 -0
  762. package/scripts/lane/lane-install.ts +94 -0
  763. package/scripts/lane/lane-launch-cli.ts +133 -0
  764. package/scripts/lane/lane-occupancy.ts +112 -0
  765. package/scripts/lane/lane-open.ts +275 -0
  766. package/scripts/lane/lane-output.ts +124 -0
  767. package/scripts/lane/lane-paths.ts +96 -0
  768. package/scripts/lane/lane-reap.ts +137 -0
  769. package/scripts/lane/lane-registry.ts +261 -0
  770. package/scripts/lane/lane-relaunch.ts +68 -0
  771. package/scripts/lane/lane-report.ts +95 -0
  772. package/scripts/lane/lane-resume.ts +61 -0
  773. package/scripts/lane/lane-seed.ts +44 -0
  774. package/scripts/lane/lane-start-point.ts +175 -0
  775. package/scripts/lane/openai-lane-supervisor-cli.ts +32 -0
  776. package/scripts/lane/openai-lane-supervisor-decision.ts +63 -0
  777. package/scripts/lane/openai-lane-supervisor.ts +337 -0
  778. package/scripts/lib/bounded-pool.ts +109 -0
  779. package/scripts/lib/buffered-process.ts +82 -0
  780. package/scripts/lib/caddy-logs.sh +45 -0
  781. package/scripts/lib/cli-flags.ts +19 -0
  782. package/scripts/lib/json-value.ts +24 -0
  783. package/scripts/lib/poll.ts +57 -0
  784. package/scripts/lib/read-file.ts +16 -0
  785. package/scripts/lib/schemas.ts +67 -0
  786. package/scripts/lib/spawn-exit.ts +45 -0
  787. package/scripts/lib/status-icons.ts +24 -0
  788. package/scripts/lines/effective-limit.ts +156 -0
  789. package/scripts/lines/line-budget.ts +404 -0
  790. package/scripts/lines/line-targets.ts +80 -0
  791. package/scripts/lines/lines-command.ts +174 -0
  792. package/scripts/lint/cspell-cached.ts +41 -0
  793. package/scripts/lint/lint-parallel.ts +72 -0
  794. package/scripts/lint/lint-related-scope.ts +128 -0
  795. package/scripts/lint/lint-related.ts +104 -0
  796. package/scripts/managed-marker/index.ts +5 -0
  797. package/scripts/managed-marker/managed-marker-logic.ts +67 -0
  798. package/scripts/observations/observation-ledger-home.ts +32 -0
  799. package/scripts/observations/observation-ledger-line.ts +93 -0
  800. package/scripts/observations/observation-ledger.ts +35 -0
  801. package/scripts/observations/observations-flush-cli.ts +42 -0
  802. package/scripts/observations/observations-flush-landing.ts +97 -0
  803. package/scripts/observations/observations-flush.ts +420 -0
  804. package/scripts/overrides/lockfile-overrides.ts +105 -0
  805. package/scripts/overrides/overrides-check.ts +84 -0
  806. package/scripts/overrides/overrides-files.ts +19 -0
  807. package/scripts/overrides/overrides-logic.ts +211 -0
  808. package/scripts/overrides/schemas.ts +49 -0
  809. package/scripts/package/package-scout-cli.ts +195 -0
  810. package/scripts/package/package-scout-format.ts +151 -0
  811. package/scripts/package/package-scout.ts +121 -0
  812. package/scripts/ports/port-command.ts +87 -0
  813. package/scripts/propagate/propagate-git-failure.ts +191 -0
  814. package/scripts/propagate/propagate-git.ts +224 -0
  815. package/scripts/propagate/propagate-publish.ts +181 -0
  816. package/scripts/propagate/propagate-run.ts +201 -0
  817. package/scripts/propagate/propagate-steps.ts +421 -0
  818. package/scripts/propagate/propagate-targets.ts +160 -0
  819. package/scripts/propagate/propagate.ts +216 -0
  820. package/scripts/refactor/import-graph.ts +187 -0
  821. package/scripts/refactor/refactor-lint.ts +250 -0
  822. package/scripts/refactor/refactor-scan-cli.ts +10 -0
  823. package/scripts/refactor/refactor-scan.ts +124 -0
  824. package/scripts/refactor/refactor-targets.ts +103 -0
  825. package/scripts/release/release-cli.ts +88 -0
  826. package/scripts/release/release-history.ts +132 -0
  827. package/scripts/release/release-plan.ts +130 -0
  828. package/scripts/release/release-publish.ts +152 -0
  829. package/scripts/release/release-scope-cli.ts +103 -0
  830. package/scripts/release/release-tag.ts +93 -0
  831. package/scripts/release/release-worktree.ts +71 -0
  832. package/scripts/repo/auto-merge-setting-logic.ts +100 -0
  833. package/scripts/repo/auto-merge-setting.ts +37 -0
  834. package/scripts/repo/repo-setting.ts +112 -0
  835. package/scripts/report/report-lint-cli.ts +49 -0
  836. package/scripts/report/report-lint.ts +250 -0
  837. package/scripts/retrospective/retrospective-cli.ts +97 -0
  838. package/scripts/retrospective/retrospective.ts +127 -0
  839. package/scripts/review/disposition-cli.ts +44 -0
  840. package/scripts/review/disposition-logic.ts +45 -0
  841. package/scripts/review/live-evidence.ts +62 -0
  842. package/scripts/review/review-attest-cli.ts +115 -0
  843. package/scripts/review/review-attest.ts +319 -0
  844. package/scripts/review/review-brief-cli.ts +290 -0
  845. package/scripts/review/review-brief.ts +440 -0
  846. package/scripts/review/review-checkout.ts +56 -0
  847. package/scripts/review/review-finding-ledger.ts +167 -0
  848. package/scripts/review/review-findings-cli.ts +57 -0
  849. package/scripts/review/review-level.ts +86 -0
  850. package/scripts/review/review-record-cli.ts +196 -0
  851. package/scripts/review/review-record.ts +74 -0
  852. package/scripts/review/review-round2-cli.ts +84 -0
  853. package/scripts/review/review-round2.ts +139 -0
  854. package/scripts/review/review-stamps.ts +113 -0
  855. package/scripts/review/review-tree.ts +58 -0
  856. package/scripts/rules/bash-triggers.ts +44 -0
  857. package/scripts/rules/decision-oracle.ts +342 -0
  858. package/scripts/rules/delivered-rules-harness.ts +72 -0
  859. package/scripts/rules/delivered-rules.ts +793 -0
  860. package/scripts/rules/early-heartbeat.ts +241 -0
  861. package/scripts/rules/file-body.ts +150 -0
  862. package/scripts/rules/filing-cap.ts +133 -0
  863. package/scripts/rules/filing-offer.ts +81 -0
  864. package/scripts/rules/firing-point.ts +63 -0
  865. package/scripts/rules/gh-api.ts +65 -0
  866. package/scripts/rules/git-argv.ts +129 -0
  867. package/scripts/rules/git-force.ts +104 -0
  868. package/scripts/rules/implementation-cut-verdict.ts +84 -0
  869. package/scripts/rules/implementation-cut.ts +202 -0
  870. package/scripts/rules/issue-citation.ts +242 -0
  871. package/scripts/rules/issue-fold.ts +73 -0
  872. package/scripts/rules/issue-scout.ts +64 -0
  873. package/scripts/rules/josh-git-bare.ts +80 -0
  874. package/scripts/rules/lane-carry-conflict.ts +96 -0
  875. package/scripts/rules/lane-interactive-ask.ts +71 -0
  876. package/scripts/rules/lane-park.ts +122 -0
  877. package/scripts/rules/lane-switch-main.ts +139 -0
  878. package/scripts/rules/oracle-consulted.ts +81 -0
  879. package/scripts/rules/oracle-firing.ts +151 -0
  880. package/scripts/rules/oracle-list-cli.ts +81 -0
  881. package/scripts/rules/piped-verification.ts +126 -0
  882. package/scripts/rules/poll-loop.ts +125 -0
  883. package/scripts/rules/pre-gate-cut.ts +207 -0
  884. package/scripts/rules/prior-comment-read.ts +106 -0
  885. package/scripts/rules/raw-field-body.ts +56 -0
  886. package/scripts/rules/reply-language.ts +116 -0
  887. package/scripts/rules/rule-body-guard.ts +206 -0
  888. package/scripts/rules/rule-guard.ts +23 -0
  889. package/scripts/rules/rule-value-cli.ts +129 -0
  890. package/scripts/rules/rule-value.ts +397 -0
  891. package/scripts/rules/run-tail.ts +178 -0
  892. package/scripts/rules/shell-body-trigger.ts +204 -0
  893. package/scripts/rules/shell-segments.ts +45 -0
  894. package/scripts/rules/stop-rules.ts +329 -0
  895. package/scripts/rules/tail-commands.ts +35 -0
  896. package/scripts/rules/test-declared-commit.ts +51 -0
  897. package/scripts/rules/third-party-write.ts +90 -0
  898. package/scripts/rules/top-level-scripts-guard.ts +47 -0
  899. package/scripts/rules/worktree-guard.ts +130 -0
  900. package/scripts/run/detached-launch.ts +360 -0
  901. package/scripts/run/run-carry-args.ts +264 -0
  902. package/scripts/run/run-carry-change.ts +69 -0
  903. package/scripts/run/run-carry-cli.ts +441 -0
  904. package/scripts/run/run-carry-flush.ts +63 -0
  905. package/scripts/run/run-carry-stash.ts +71 -0
  906. package/scripts/run/run-carry-streak.ts +113 -0
  907. package/scripts/run/run-carry.ts +550 -0
  908. package/scripts/run/run-cut-args.ts +132 -0
  909. package/scripts/run/run-cut-cli.ts +461 -0
  910. package/scripts/run/run-cut-handoff.ts +126 -0
  911. package/scripts/run/run-cut.ts +531 -0
  912. package/scripts/run/run-ending-cli.ts +111 -0
  913. package/scripts/run/run-ending.ts +239 -0
  914. package/scripts/run/run-entry-cli.ts +135 -0
  915. package/scripts/run/run-entry.ts +95 -0
  916. package/scripts/run/run-event-cli.ts +210 -0
  917. package/scripts/run/run-event-follow.ts +65 -0
  918. package/scripts/run/run-event-render.ts +75 -0
  919. package/scripts/run/run-event-scope.ts +127 -0
  920. package/scripts/run/run-event-stream-emit.ts +140 -0
  921. package/scripts/run/run-event-stream.ts +258 -0
  922. package/scripts/run/run-event-watch.ts +37 -0
  923. package/scripts/run/run-headless.ts +105 -0
  924. package/scripts/run/run-hold-cli.ts +310 -0
  925. package/scripts/run/run-hold.ts +264 -0
  926. package/scripts/run/run-invocation.ts +237 -0
  927. package/scripts/run/run-issue-number.ts +19 -0
  928. package/scripts/run/run-liveness-cli.ts +169 -0
  929. package/scripts/run/run-liveness.ts +424 -0
  930. package/scripts/run/run-merge-cli.ts +385 -0
  931. package/scripts/run/run-merge-steps.ts +326 -0
  932. package/scripts/run/run-merge.ts +158 -0
  933. package/scripts/run/run-next-cli.ts +48 -0
  934. package/scripts/run/run-next.ts +80 -0
  935. package/scripts/run/run-preflight.ts +337 -0
  936. package/scripts/run/run-prep-cli.ts +151 -0
  937. package/scripts/run/run-prep.ts +84 -0
  938. package/scripts/run/run-progress-args.ts +65 -0
  939. package/scripts/run/run-progress-cli.ts +508 -0
  940. package/scripts/run/run-progress-clock.ts +320 -0
  941. package/scripts/run/run-progress-config.ts +119 -0
  942. package/scripts/run/run-progress-read.ts +199 -0
  943. package/scripts/run/run-progress.ts +366 -0
  944. package/scripts/run/run-report-cli.ts +71 -0
  945. package/scripts/run/run-report.ts +78 -0
  946. package/scripts/run/run-review-cli.ts +130 -0
  947. package/scripts/run/run-review-steps.ts +161 -0
  948. package/scripts/run/run-review.ts +121 -0
  949. package/scripts/run/run-ship-cli.ts +431 -0
  950. package/scripts/run/run-ship-detach.ts +200 -0
  951. package/scripts/run/run-ship-probe.ts +103 -0
  952. package/scripts/run/run-ship-return.ts +75 -0
  953. package/scripts/run/run-ship-review-steps.ts +227 -0
  954. package/scripts/run/run-ship-review.ts +177 -0
  955. package/scripts/run/run-ship-stage.ts +150 -0
  956. package/scripts/run/run-ship.ts +78 -0
  957. package/scripts/run/run-status-cli.ts +175 -0
  958. package/scripts/run/run-status.ts +77 -0
  959. package/scripts/run/run-step-cli.ts +111 -0
  960. package/scripts/run/run-step.ts +292 -0
  961. package/scripts/run/run-stop-notify.ts +52 -0
  962. package/scripts/run/run-stranded-cli.ts +31 -0
  963. package/scripts/run/run-stranded-detect.ts +134 -0
  964. package/scripts/run/run-stranded.ts +120 -0
  965. package/scripts/run/run-tail-cli.ts +105 -0
  966. package/scripts/run/run-tail.ts +61 -0
  967. package/scripts/run/run-transcript.golden.txt +57 -0
  968. package/scripts/run/run-wake-cli.ts +428 -0
  969. package/scripts/run/run-wake-describe.ts +97 -0
  970. package/scripts/run/run-wake-driver.ts +80 -0
  971. package/scripts/run/run-wake-handoff.ts +29 -0
  972. package/scripts/run/run-wake-loop.ts +223 -0
  973. package/scripts/run/run-wake-session.ts +150 -0
  974. package/scripts/run/run-wake-work.ts +104 -0
  975. package/scripts/run/run-wake.ts +607 -0
  976. package/scripts/run/run-watcher-guard-cli.ts +37 -0
  977. package/scripts/run/run-watcher-guard.ts +59 -0
  978. package/scripts/run/run-watcher-hook.ts +86 -0
  979. package/scripts/security/secretlint-scan.ts +86 -0
  980. package/scripts/security/security-audit-logic.ts +51 -0
  981. package/scripts/security/security-audit-provision-logic.ts +217 -0
  982. package/scripts/security/security-audit-provision.ts +186 -0
  983. package/scripts/security/security-audit.ts +132 -0
  984. package/scripts/security/security-updates-logic.ts +131 -0
  985. package/scripts/security/security-updates.ts +38 -0
  986. package/scripts/security/sonar-file.ts +44 -0
  987. package/scripts/self-sync-guard/index.ts +5 -0
  988. package/scripts/self-sync-guard/self-sync-guard-logic.ts +98 -0
  989. package/scripts/self-sync-guard/self-sync-refusal.ts +22 -0
  990. package/scripts/sonar/sonar-hotspots-cli.ts +149 -0
  991. package/scripts/sonar/sonar-hotspots.ts +111 -0
  992. package/scripts/split/split-assess-cli.ts +52 -0
  993. package/scripts/split/split-assess.ts +124 -0
  994. package/scripts/sync/dependabot-pin-logic.ts +135 -0
  995. package/scripts/sync/directory-copy-guard.ts +187 -0
  996. package/scripts/sync/file-content.ts +49 -0
  997. package/scripts/sync/managed-config-scope-cli.ts +64 -0
  998. package/scripts/sync/managed-config-scope.ts +123 -0
  999. package/scripts/sync/plugin-skill-directories.ts +15 -0
  1000. package/scripts/sync/reconcile-templates.ts +53 -0
  1001. package/scripts/sync/removed-skill-manifest.ts +27 -0
  1002. package/scripts/sync/skill-migration.ts +192 -0
  1003. package/scripts/sync/sync-configs.ts +156 -0
  1004. package/scripts/sync/sync-hook-safety.ts +82 -0
  1005. package/scripts/sync/sync.ts +417 -0
  1006. package/scripts/sync/synced-paths.ts +52 -0
  1007. package/scripts/sync/template-source-logic.ts +122 -0
  1008. package/scripts/sync/workflow-pin-logic.ts +240 -0
  1009. package/scripts/test/classify-isolation.ts +149 -0
  1010. package/scripts/test/e2e-retry-check.ts +150 -0
  1011. package/scripts/test/http-fault-injection.ts +79 -0
  1012. package/scripts/test/josh-harness-environment.ts +260 -0
  1013. package/scripts/test/josh-harness.ts +96 -0
  1014. package/scripts/test/pilot-files.ts +457 -0
  1015. package/scripts/test/pilot-measure.ts +78 -0
  1016. package/scripts/test/test-declared-changed.ts +99 -0
  1017. package/scripts/test/test-declared-logic.ts +91 -0
  1018. package/scripts/test/test-declared-match.ts +106 -0
  1019. package/scripts/test/test-declared.ts +180 -0
  1020. package/scripts/test/test-e2e-guard.ts +86 -0
  1021. package/scripts/test/test-network-guard.ts +453 -0
  1022. package/scripts/test/test-red-commit.ts +51 -0
  1023. package/scripts/test/test-red-logic.ts +76 -0
  1024. package/scripts/test/test-red.ts +154 -0
  1025. package/scripts/test/test-related-scope.ts +115 -0
  1026. package/scripts/test/test-related.ts +73 -0
  1027. package/scripts/test/test-repository-guard.ts +317 -0
  1028. package/scripts/test/test-state-guard.ts +85 -0
  1029. package/scripts/test/test-stdout-guard.ts +54 -0
  1030. package/scripts/test/test-telegram-guard.ts +90 -0
  1031. package/scripts/test/test-type-logic.ts +31 -0
  1032. package/scripts/test/test-unit-guard.ts +185 -0
  1033. package/scripts/test/unit-guard-environment.ts +12 -0
  1034. package/scripts/test/unit-projects.ts +139 -0
  1035. package/scripts/test/unit-worker-share.ts +251 -0
  1036. package/scripts/test/vitest-include-globs.ts +12 -0
  1037. package/scripts/time-runtime/time-agent-bundles.ts +128 -0
  1038. package/scripts/time-runtime/time-background.ts +300 -0
  1039. package/scripts/time-runtime/time-batch-guard-fixtures.ts +66 -0
  1040. package/scripts/time-runtime/time-batch-guard.ts +529 -0
  1041. package/scripts/time-runtime/time-bundle-call.ts +575 -0
  1042. package/scripts/time-runtime/time-bundles.ts +536 -0
  1043. package/scripts/time-runtime/time-call-identity.ts +37 -0
  1044. package/scripts/time-runtime/time-command-key.ts +35 -0
  1045. package/scripts/time-runtime/time-density-hook.ts +166 -0
  1046. package/scripts/time-runtime/time-density.ts +147 -0
  1047. package/scripts/time-runtime/time-followup-stage.ts +107 -0
  1048. package/scripts/time-runtime/time-format.ts +186 -0
  1049. package/scripts/time-runtime/time-hook-transcript.ts +82 -0
  1050. package/scripts/time-runtime/time-instant.ts +20 -0
  1051. package/scripts/time-runtime/time-markers.ts +228 -0
  1052. package/scripts/time-runtime/time-phase-names.ts +123 -0
  1053. package/scripts/time-runtime/time-reported-failure.ts +227 -0
  1054. package/scripts/time-runtime/time-round-trips.ts +279 -0
  1055. package/scripts/time-runtime/time-shell.ts +286 -0
  1056. package/scripts/time-runtime/time-single-check.ts +65 -0
  1057. package/scripts/time-runtime/time-spans.ts +545 -0
  1058. package/scripts/time-runtime/time-transcript-line.ts +253 -0
  1059. package/scripts/time-runtime/time-writes.ts +71 -0
  1060. package/scripts/ui/ui-routes-cli.ts +122 -0
  1061. package/scripts/ui/ui-routes.ts +102 -0
  1062. package/scripts/version/bump-version.ts +71 -0
  1063. package/scripts/version/effective-upstream.ts +93 -0
  1064. package/scripts/version/index.ts +25 -0
  1065. package/scripts/version/kit-descriptor.ts +10 -0
  1066. package/scripts/version/kit-version-config.ts +30 -0
  1067. package/scripts/version/latest-corepack.ts +404 -0
  1068. package/scripts/version/latest-lane-guard.ts +49 -0
  1069. package/scripts/version/latest-regression.ts +93 -0
  1070. package/scripts/version/latest-scope-cli.ts +147 -0
  1071. package/scripts/version/latest-stamp.ts +107 -0
  1072. package/scripts/version/latest-update.ts +198 -0
  1073. package/scripts/version/package-manager-version.ts +95 -0
  1074. package/scripts/version/parse-json.ts +13 -0
  1075. package/scripts/version/preinstall-version-update.ts +84 -0
  1076. package/scripts/version/publishable-range-check.ts +74 -0
  1077. package/scripts/version/publishable-range.ts +123 -0
  1078. package/scripts/version/release-age.ts +146 -0
  1079. package/scripts/version/release-hold.ts +142 -0
  1080. package/scripts/version/running-binary.ts +42 -0
  1081. package/scripts/version/upgrade-command-guard.ts +49 -0
  1082. package/scripts/version/upgrade-shell-command.ts +30 -0
  1083. package/scripts/version/version-check-logic.ts +333 -0
  1084. package/scripts/version/version-check.ts +14 -0
  1085. package/scripts/version/version-command-config.ts +177 -0
  1086. package/scripts/version/version-commands.ts +296 -0
  1087. package/scripts/version/version-remote.ts +86 -0
  1088. package/scripts/version/version-targets.ts +81 -0
  1089. package/scripts/yaml/yaml-document.ts +46 -0
  1090. package/scripts-ai/completion-gate.ts +13 -0
  1091. package/scripts-ai/environment-loader.ts +9 -0
  1092. package/scripts-ai/epic-check.ts +34 -0
  1093. package/scripts-ai/epic-cli-argv.ts +77 -0
  1094. package/scripts-ai/epic-cli-remove.ts +71 -0
  1095. package/scripts-ai/epic-cli.ts +413 -0
  1096. package/scripts-ai/epic.ts +192 -0
  1097. package/scripts-ai/followup-issue-number.ts +31 -0
  1098. package/scripts-ai/git-followup-finish.ts +217 -0
  1099. package/scripts-ai/git-followup-workflow.ts +252 -0
  1100. package/scripts-ai/git-workflow.ts +246 -0
  1101. package/scripts-ai/telegram-test-logic.ts +88 -0
  1102. package/scripts-ai/telegram-test.ts +130 -0
  1103. package/templates/gitignore +76 -0
  1104. package/templates/sonar-project.properties +52 -0
  1105. package/templates/workflows/ci.yml +639 -0
  1106. package/templates/workflows/dependabot-auto-merge.yml +428 -0
  1107. package/tsconfig/base.json +50 -0
  1108. package/tsconfig.sonar.json +34 -0
@@ -0,0 +1,637 @@
1
+ import path from 'node:path'
2
+ import { cost_blocks } from '#scripts/cost-runtime/cost-blocks'
3
+ import { cost_transcript } from '#scripts/cost-runtime/cost-transcript'
4
+ import { hook_decision, type GuardRun } from '#scripts/josh/hook-decision'
5
+ import { time_batch_guard, type GuardedCall } from '#scripts/time-runtime/time-batch-guard'
6
+ import { time_bundle_call } from '#scripts/time-runtime/time-bundle-call'
7
+ import { time_shell } from '#scripts/time-runtime/time-shell'
8
+ import { time_spans, type Span } from '#scripts/time-runtime/time-spans'
9
+ import { delegation_policy } from './delegation-policy'
10
+
11
+ // How many files a run has read and not edited **since its last delegated unit**
12
+ // (joshuafolkken/kit#1460).
13
+ //
14
+ // **joshuafolkken/kit#1426 made the threshold a count rather than a forecast, and left the counting
15
+ // to the agent.** Measured on run #1441, that is a one-shot judgement: `josh delegate investigation`
16
+ // was called once at t+4.0 min, the unit returned at t+7.2, and the main line then read **8 more
17
+ // files it did not edit** — more than twice the threshold — without the question being asked a second
18
+ // time. The count is a memory, and after a delegation the run remembers the *step* as done rather
19
+ // than the *counter* as reset.
20
+ //
21
+ // **So the counting happens here, off the transcript, and not in the agent's head.** A delegation
22
+ // clears the set; a read adds to it; an edit takes its file back out of it. Nothing has to be
23
+ // remembered, which is why the threshold necessarily fires again — a second accumulation is
24
+ // indistinguishable from the first.
25
+ //
26
+ // **Why a mechanism and not wording.** joshuafolkken/kit#1344 measured three consecutive runs after
27
+ // the batching norm was distributed as prose and as a live notice: 1.10–1.12 calls per round trip
28
+ // against a 1.50 floor, unchanged. joshuafolkken/kit#1390 read that as the answer — intervene in the
29
+ // decision instead of describing it — and this is the same conclusion applied to the same class of
30
+ // rule. The wording is corrected too, but it is not what is expected to move the number.
31
+
32
+ const READ_TOOLS: ReadonlySet<string> = new Set(['Read'])
33
+ // The label a subagent call carries is the verbatim tool name (`time-spans.ts` → `to_tool_call`), and
34
+ // both spellings are in use: `Task` in the published tool set, `Agent` in this harness's transcripts.
35
+ // Neither has a constant anywhere, so the pair is named here rather than matched loosely.
36
+ const DELEGATION_TOOLS: ReadonlySet<string> = new Set(['Agent', 'Task'])
37
+
38
+ // **Narrower than `time-bundle-call.ts`'s `READ_COMMANDS`, deliberately.** That list answers which
39
+ // calls are bundleable, and it holds `grep`, `ls` and `wc` — commands that report *about* a file
40
+ // without carrying its text. What this rule counts is text arriving in the prompt, so only the
41
+ // commands that print a file belong here.
42
+ const CONTENT_READ_COMMANDS: ReadonlyArray<string> = [
43
+ 'bat',
44
+ 'cat',
45
+ 'head',
46
+ 'less',
47
+ 'more',
48
+ 'nl',
49
+ 'sed',
50
+ 'tail',
51
+ ]
52
+ // Built through `bash_label` so the `Bash: ` prefix is spelled in one place — the labels on a span
53
+ // come from that same function.
54
+ const CONTENT_READ_LABELS: ReadonlySet<string> = new Set(
55
+ CONTENT_READ_COMMANDS.map((command) => time_shell.bash_label(command)),
56
+ )
57
+
58
+ // What the refusal tells the model. It has to name the count, the command and the return shape,
59
+ // because the deny reason is the only text that reaches the model — a run that is refused and told
60
+ // nothing reads it as a broken tool.
61
+ const REASON = `⛔ investigation: ${String(delegation_policy.INVESTIGATION_FILE_THRESHOLD)} files read and not edited since the last delegated unit, so the reading from here goes to a unit of its own. Ask \`pnpm josh delegate investigation\`, then brief a unit with what the main line has already concluded and what is left to find out; it returns the conclusion plus its \`file:line\` citations, never the file text. Keep a read in the main line only where this run will edit that file — an \`Edit\` cannot be issued against text you do not hold. This run's own instructions and the harness's own session files — a backgrounded call's output, a persisted tool result, this session's scratchpad — are never counted, so they are not what took the count here. The rule is \`.claude/skills/workflow-commands/SKILL.md\` → §2b, "The pre-implementation reading".`
62
+
63
+ interface ReadTally {
64
+ // The files read and not since edited, resolved so the two ways a target reaches here compare.
65
+ pending: ReadonlyArray<string>
66
+ // How many of those entered the set **after** the instant the caller asked about — the refusal's,
67
+ // in the one call that matters (joshuafolkken/kit#1764). It is the second way a refusal re-arms:
68
+ // a run that ignores the one refusal it gets goes on accumulating, and a threshold's worth of new
69
+ // unedited files is a second accumulation whatever the run did about the first.
70
+ pending_since: number
71
+ // When the last delegated unit closed, or `NEVER_MS` where the window holds none. This is what
72
+ // re-arms a refusal: a delegation after the recorded one is a new accumulation.
73
+ reset_ms: number
74
+ // The first instant the window covers. A refusal recorded before it cannot be checked against a
75
+ // delegation any more, because the delegation that would re-arm it has scrolled out.
76
+ window_start_ms: number
77
+ // The files this run has successfully edited within the window, resolved (joshuafolkken/kit#1840).
78
+ // A re-read of one of them is a read of a file the run edited, which §2b keeps in the main line — so
79
+ // it is excluded from the count and from a call's projected growth rather than counted as fresh
80
+ // investigation.
81
+ edited: ReadonlySet<string>
82
+ }
83
+
84
+ // **The run's own instructions are not the Issue's subject, so reading them is not what §2b delegates.**
85
+ // #1426's rule is about reading to find out how the subject works; `CLAUDE.md`, a `prompts/` topic and
86
+ // a skill file are read to find out what to *do*, they are read by nearly every run, and a unit cannot
87
+ // be sent to read them on the main line's behalf. #1441's own measurement excluded 5 of them by hand
88
+ // for exactly this reason, and a count that includes them trips on a run that has investigated nothing.
89
+ //
90
+ // **Matched against the path relative to the repository root, so `prompts` means *this* repository's**:
91
+ // `includes('prompts/')` also exempted `scripts/eval/prompts/x.ts`, which is subject code, and
92
+ // `endsWith('CLAUDE.md')` also exempted `MY_CLAUDE.md`. A file outside the checkout is subject
93
+ // material like any other — only these paths inside it are the run's own instructions.
94
+ const INSTRUCTION_PATHS: ReadonlyArray<string> = ['prompts', '.claude/skills']
95
+ const INSTRUCTION_FILES: ReadonlySet<string> = new Set(['CLAUDE.md', 'AGENTS.md', 'GEMINI.md'])
96
+ const REPOSITORY_ROOT = process.cwd()
97
+
98
+ // **The two ways a target reaches this file spell the same path differently.** A tool call carries
99
+ // `file_path`, which Claude Code requires to be absolute; a shell line carries the word as it was
100
+ // typed, normalized only for a leading `./`. Left as they are, `cat scripts/x.ts` followed by an
101
+ // `Edit` of `/…/scripts/x.ts` never cancels — the file stays pending for the rest of the run — and
102
+ // reading the same file once each way counts twice.
103
+ function resolved(target: string): string {
104
+ return path.resolve(REPOSITORY_ROOT, target)
105
+ }
106
+
107
+ // **Anchored at the repository root, not matched anywhere in the absolute path.** Testing the
108
+ // absolute string made every file in the repository an instruction document for anyone whose checkout
109
+ // sits under a directory called `prompts` — which disarmed the guard entirely, in silence.
110
+ // Both path predicates below ask the same question of the repository root, so the expression is named
111
+ // once rather than written twice — they differ only in what they do with the answer.
112
+ function repository_relative(absolute: string): string {
113
+ return path.relative(REPOSITORY_ROOT, absolute)
114
+ }
115
+
116
+ function is_instruction_document(target: string): boolean {
117
+ const relative = repository_relative(resolved(target))
118
+ const segments = relative.split(path.sep)
119
+
120
+ return (
121
+ INSTRUCTION_FILES.has(segments.at(-1) ?? '') ||
122
+ INSTRUCTION_PATHS.some((prefix) => relative.startsWith(`${prefix}${path.sep}`))
123
+ )
124
+ }
125
+
126
+ // **The harness's own session files are not the subject either, and it is the same test that excludes
127
+ // them** (joshuafolkken/kit#1771): no unit can be sent to read one on the main line's behalf. A
128
+ // backgrounded call's result reaches its run *only* as `tasks/<id>.output` under this session's temp
129
+ // tree, and a tool result too large for the transcript reaches it *only* as a file the harness wrote
130
+ // under `.claude/projects/`. Refusing either refuses a run the answer to an instruction it issued
131
+ // itself — and the remedy the refusal names does not exist for a file that belongs to this session
132
+ // alone, so the round trip buys nothing and the read is simply reissued.
133
+ //
134
+ // **Anchored on a directory the harness *writes*, never on the session tree as a whole.** Exempting
135
+ // the whole tree would have disarmed the guard in silence for anything a run unpacks or clones into
136
+ // its scratchpad to investigate — real subject material, read to find out how something works, that
137
+ // would never have reached the count. That is the failure the instruction-document half's own anchor
138
+ // note describes, and it is why the scratchpad is deliberately **not** exempt: what stays exempt is
139
+ // what the harness itself wrote.
140
+ const SESSION_TEMP_SEGMENT = /^claude-\d+$/u
141
+ // **Single-sourced from `cost-transcript.ts`**, which already owns where the harness keeps a session's
142
+ // state and builds the transcript directory out of it — spelling `.claude/projects` a second time here
143
+ // is the clone `CLAUDE.md` prohibits. That module joins the value onto a home directory and this one
144
+ // matches it as a run of segments, so what the two share is the fact rather than the use.
145
+ //
146
+ // **The `tasks/<id>.output` spelling is deliberately *not* borrowed from `time-background.ts`.** This
147
+ // rule matches the session *tree*, which covers that file, the scratchpad and the transcript in one
148
+ // test; matching the file name would need a second rule for each of the others.
149
+ const SESSION_STATE_SEGMENTS = cost_transcript.TRANSCRIPT_ROOT.split(path.sep)
150
+ // What the harness writes into a session's temp tree has a fixed shape — `tasks/<id>.output`, a
151
+ // backgrounded call's result — and **both halves are required**. The directory name alone is not
152
+ // enough: `tasks/` is one of the commonest directory names a repository has, and a run may unpack or
153
+ // clone one into its scratchpad, where matching the name would re-open the silent false negative one
154
+ // level down. Persisted tool results and the transcript need no entry here at all — they live under
155
+ // the state root above, which is exempt whole.
156
+ const HARNESS_OUTPUT_DIRECTORY = 'tasks'
157
+ const HARNESS_OUTPUT_EXTENSION = '.output'
158
+ // `at()` counts from the end, so the file itself is -1 and the directory holding it is -2.
159
+ const FILE_SEGMENT_INDEX = -1
160
+ const PARENT_SEGMENT_INDEX = -2
161
+
162
+ // The state root holds transcripts and persisted results and no subject code, so it is exempt whole.
163
+ // It is not anchored to the home directory: `cost-transcript.ts` is this package's only file allowed
164
+ // to look that up at all (`scripts/hooks/no-global-shim-write.test.ts`), and two adjacent segments outside
165
+ // the checkout are specific enough without it.
166
+ function has_state_root(segments: ReadonlyArray<string>, index: number): boolean {
167
+ return SESSION_STATE_SEGMENTS.every((segment, offset) => segments[index + offset] === segment)
168
+ }
169
+
170
+ // The file's **own parent** is tested rather than any directory above it, and the name has to match
171
+ // as well — see the shape note above for why one without the other is not enough.
172
+ function is_harness_output(segments: ReadonlyArray<string>): boolean {
173
+ return (
174
+ segments.some((segment) => SESSION_TEMP_SEGMENT.test(segment)) &&
175
+ segments.at(PARENT_SEGMENT_INDEX) === HARNESS_OUTPUT_DIRECTORY &&
176
+ (segments.at(FILE_SEGMENT_INDEX) ?? '').endsWith(HARNESS_OUTPUT_EXTENSION)
177
+ )
178
+ }
179
+
180
+ // **A path inside the checkout is never one of these, whatever its directories are called.** The
181
+ // instruction-document test above is anchored at the repository root because matching the absolute
182
+ // string made every file an instruction document for a checkout sitting under a directory called
183
+ // `prompts`; this test cannot borrow that anchor, since the files it names live outside the checkout by
184
+ // construction. So the anchor is inverted — leaving the repository is a precondition — and a
185
+ // repository file can therefore never be exempted here, whatever it is named.
186
+ function is_outside_repository(absolute: string): boolean {
187
+ return repository_relative(absolute).startsWith('..')
188
+ }
189
+
190
+ function is_session_artifact(target: string): boolean {
191
+ const absolute = resolved(target)
192
+ const segments = absolute.split(path.sep)
193
+
194
+ if (!is_outside_repository(absolute)) return false
195
+
196
+ return (
197
+ segments.some((_segment, index) => has_state_root(segments, index)) ||
198
+ is_harness_output(segments)
199
+ )
200
+ }
201
+
202
+ // The two exclusions answer one question — could a unit be sent to read this instead? — so a target
203
+ // failing either is not the Issue's subject and never reaches the count.
204
+ function is_subject_file(target: string): boolean {
205
+ return !is_instruction_document(target) && !is_session_artifact(target)
206
+ }
207
+
208
+ // A shell glob resolves to a literal path with a `*` in it, which no edit can ever name — so left in,
209
+ // it stays pending until the next delegation and keeps contributing to a count it does not belong in.
210
+ function is_nameable_file(target: string): boolean {
211
+ return !target.includes('*') && !target.includes('?')
212
+ }
213
+
214
+ function is_content_read(label: string): boolean {
215
+ return READ_TOOLS.has(label) || CONTENT_READ_LABELS.has(label)
216
+ }
217
+
218
+ function subject_targets(targets: ReadonlyArray<string>): ReadonlyArray<string> {
219
+ return targets
220
+ .filter((target) => is_nameable_file(target) && is_subject_file(target))
221
+ .map((target) => resolved(target))
222
+ }
223
+
224
+ function call_targets(call: GuardedCall): ReadonlyArray<string> {
225
+ return subject_targets(time_bundle_call.call_facts(call.name, call.input).targets)
226
+ }
227
+
228
+ // **The instant a delegation closed, not the one it opened.** The refusal this re-arms was recorded
229
+ // before the unit was ever briefed, so either end of that span is after it — and the closing instant
230
+ // needs no duration arithmetic to derive, which keeps the one number this rule compares free of
231
+ // `to_spans`' own bookkeeping.
232
+ function delegation_instant(span: Span | undefined): number {
233
+ return span === undefined ? hook_decision.NEVER_MS : span.ended_ms
234
+ }
235
+
236
+ // **A span whose outcome was failure changed nothing, so it is not what this rule acts on**
237
+ // (joshuafolkken/kit#1764, joshuafolkken/kit#1840). A failed **read** carried no text into the
238
+ // prompt — the case that matters is the guard's own refusal: Claude Code writes a denied call to the
239
+ // transcript as a `tool_use` block with an errored `tool_result`, and the stamp is written *before*
240
+ // the reason is returned, so counting the denied read's targets would pre-load `pending_since` with
241
+ // the very read the refusal stopped. A failed **edit** wrote nothing, so it does not exempt a later
242
+ // read of its target either — `edited_files` below asks the same question for that reason. An
243
+ // **unknown** outcome still counts, because a result nobody recorded is not a failure.
244
+ function is_failed_outcome(span: Span): boolean {
245
+ return span.outcome === time_spans.FAILED_OUTCOME
246
+ }
247
+
248
+ // **Every file the run successfully wrote within the window, resolved** (joshuafolkken/kit#1840). It
249
+ // is the one source of "this run edited that file", shared by the live tally and the replay: a read of
250
+ // a file the run edits is reading §2b keeps in the main line, so it is never counted — whether the read
251
+ // came before the edit or after it. A failed edit wrote nothing and so exempts nothing, and a file
252
+ // edited outside the window is unknown rather than assumed: the set is only ever as wide as the tail
253
+ // the hook read, which is the bound joshuafolkken/kit#1764 already holds the accumulation to.
254
+ function edited_files(spans: ReadonlyArray<Span>): Set<string> {
255
+ const written = spans
256
+ .filter((span) => !is_failed_outcome(span))
257
+ .flatMap((span) => subject_targets(span.writes))
258
+
259
+ return new Set(written)
260
+ }
261
+
262
+ // **The set records *when* each file entered it, which is the whole of the second re-arm**
263
+ // (joshuafolkken/kit#1764). A plain set could say how many files were pending and never how many of
264
+ // them arrived after the refusal, so a run that ignored its one refusal was indistinguishable from
265
+ // one that had read nothing since. The first entry stands: a re-read of a file already pending is
266
+ // not a new accumulation, exactly as it is not a new count.
267
+ function add_all(
268
+ pending: Map<string, number>,
269
+ targets: ReadonlyArray<string>,
270
+ at_ms: number,
271
+ ): void {
272
+ for (const target of targets) if (!pending.has(target)) pending.set(target, at_ms)
273
+ }
274
+
275
+ // **A file the run edited is never added to the set in the first place** (joshuafolkken/kit#1840).
276
+ // `edited_files` has already gathered every successful write in the window, so a read of one of them —
277
+ // before the edit or after it — is filtered here rather than added and then subtracted. This closes
278
+ // the re-read-after-edit gap the old subtract-on-the-edit-span could not: a subtraction runs only on
279
+ // the edit's own span, so a read issued *after* the edit was added and stayed. `sed -i`, `MultiEdit`
280
+ // and `NotebookEdit` need no special case any more — each is a write, so its target is in `edited` and
281
+ // never enters the read count.
282
+ function apply_span(pending: Map<string, number>, span: Span, edited: ReadonlySet<string>): void {
283
+ if (DELEGATION_TOOLS.has(span.label)) {
284
+ pending.clear()
285
+
286
+ return
287
+ }
288
+
289
+ if (!is_content_read(span.label) || is_failed_outcome(span)) return
290
+
291
+ const fresh = subject_targets(span.targets).filter((target) => !edited.has(target))
292
+
293
+ add_all(pending, fresh, span.ended_ms)
294
+ }
295
+
296
+ function last_delegation_ms(spans: ReadonlyArray<Span>): number {
297
+ return delegation_instant(spans.findLast((span) => DELEGATION_TOOLS.has(span.label)))
298
+ }
299
+
300
+ // **The window is the tail the hook read, not the whole run.** That is the same bound the batching
301
+ // guard works under, and it costs nothing here: the set is cleared at every delegation anyway, so a
302
+ // tail that reaches back past the last one already holds the whole accumulation.
303
+ function pending_after(pending: ReadonlyMap<string, number>, since_ms: number): number {
304
+ return [...pending.values()].filter((at_ms) => at_ms > since_ms).length
305
+ }
306
+
307
+ function tally_of(text: string, since_ms: number = hook_decision.NEVER_MS): ReadTally {
308
+ const { spans, started_ms } = time_spans.parse_timeline(text)
309
+ const edited = edited_files(spans)
310
+ const pending = new Map<string, number>()
311
+
312
+ for (const span of spans) apply_span(pending, span, edited)
313
+
314
+ return {
315
+ pending: [...pending.keys()],
316
+ pending_since: pending_after(pending, since_ms),
317
+ reset_ms: last_delegation_ms(spans),
318
+ window_start_ms: started_ms,
319
+ edited,
320
+ }
321
+ }
322
+
323
+ // **The call has to actually add a file the count does not already hold.** Its targets are filtered
324
+ // against `edited` first, so a re-read of a file the run edited is not the `+ 1` that trips the
325
+ // threshold — the same exclusion `apply_span` makes for the pending set this is compared against
326
+ // (joshuafolkken/kit#1840). The `Set` union still absorbs a re-read of something already pending — a
327
+ // second `sed -n` window of the same file, or a `Read` with a new `offset` — which would not have
328
+ // grown the count either. The default empty set is for the exported callers that ask about
329
+ // accumulation alone — a test, or any reader with no edited set in hand.
330
+ function projected_count(
331
+ pending: ReadonlyArray<string>,
332
+ call: GuardedCall,
333
+ edited: ReadonlySet<string> = new Set<string>(),
334
+ ): number {
335
+ return new Set([...pending, ...call_targets(call).filter((target) => !edited.has(target))]).size
336
+ }
337
+
338
+ // **The read that takes the count *up to* the threshold is the boundary.** The ones below it stay in
339
+ // the main line, which is what keeps a small investigation from paying the two turns a brief and a
340
+ // result cost.
341
+ //
342
+ // **It is the *accumulated* count that has to reach the boundary, never the projected one.** Counting
343
+ // the call's own targets toward it let one bundled multi-file read — `cat a.ts b.ts c.ts`, exactly the
344
+ // batching `CLAUDE.md` mandates — be refused as the first call of a run, with a reason claiming three
345
+ // files had already been read. The boundary is crossed by a call, not jumped over by one.
346
+ function is_at_threshold(pending_count: number): boolean {
347
+ return pending_count + 1 >= delegation_policy.INVESTIGATION_FILE_THRESHOLD
348
+ }
349
+
350
+ // **One refusal per accumulation, re-armed by a delegation and by nothing else.** A run that reads on
351
+ // regardless is not refused again, so a false positive — three files the run was about to edit — costs
352
+ // one round trip rather than wedging the run. And a run that *does* delegate is refused again as soon
353
+ // as three more unedited files pile up, which is the whole of joshuafolkken/kit#1460.
354
+ //
355
+ // **A refusal older than the window re-arms too**, and without that arm the guard fell permanently
356
+ // silent on exactly the run lengths the Issue was filed about: once the last delegation scrolls out of
357
+ // the 256 KB tail there is no `reset_ms` left to beat, and one stale stamp disarmed the rest of the
358
+ // session. This is the bound `batch-guard.ts` already documents for its own window — one extra
359
+ // refusal per window rather than silence — and it errs toward delegating, which is the goal.
360
+ //
361
+ // **And a further accumulation re-arms it, which is what "one refusal per accumulation" had always
362
+ // meant and never done** (joshuafolkken/kit#1764). A delegation was the only thing that could clear
363
+ // the disarm, so a run that *ignored* the refusal — read on without delegating — was never spoken to
364
+ // again however many unedited files it went on to open: the one case the threshold exists for was the
365
+ // one case it stopped covering. `docs/josh-commands.md` had already published the corrected
366
+ // behavior — "one per accumulation and re-arms after the next three unedited reads" — against code
367
+ // that did nothing of the kind, which is the shipped-mechanism-not-working defect
368
+ // joshuafolkken/kit#1262 declared highest priority.
369
+ //
370
+ // **It is not a refusal on the next call.** The count has to climb a whole threshold again, so a
371
+ // false positive still costs one round trip; what it cannot do any more is buy silence for the rest
372
+ // of the run.
373
+ //
374
+ // **A delegated unit is not re-armed here because it is not refused at all** (joshuafolkken/kit#1840).
375
+ // The hook counts a unit's reading against the unit (joshuafolkken/kit#1424), and the refusal asks for
376
+ // a dispatch — but a unit is already where §2b sends the reading, and a read-only one (`Explore`,
377
+ // `Plan`) has no `Agent` tool to dispatch with. It was formerly degraded to a single first refusal,
378
+ // which still asked for an action the unit could not take; now the unit short circuit in `should_block`
379
+ // turns it off entirely, so this function is the parent's alone and needs no delegation condition.
380
+ function has_cleared_the_disarm(tally: ReadTally, refused_at_ms: number): boolean {
381
+ return tally.reset_ms > refused_at_ms || refused_at_ms < tally.window_start_ms
382
+ }
383
+
384
+ function is_rearmed(tally: ReadTally, refused_at_ms: number): boolean {
385
+ if (refused_at_ms === hook_decision.NEVER_MS || has_cleared_the_disarm(tally, refused_at_ms)) {
386
+ return true
387
+ }
388
+
389
+ return is_at_threshold(tally.pending_since)
390
+ }
391
+
392
+ // A transcript under a session's `subagents/` directory is a delegated unit's. The segment is
393
+ // `cost-transcript.ts`'s, which owns the layout — spelling it a second time here is the clone
394
+ // `CLAUDE.md` prohibits, and the hook is handed the derived fork path rather than the parent's
395
+ // (`hook-decision.ts` → `guard_reason_for_payload`).
396
+ function is_unit_transcript(transcript: string): boolean {
397
+ return transcript.split(path.sep).includes(cost_transcript.UNIT_DIRECTORY)
398
+ }
399
+
400
+ // The run-level question `should_block` asks of the payload: is this a delegated unit's transcript?
401
+ // `run` is absent in the pure-tally tests, which are the parent's context by construction.
402
+ function is_unit_run(run: GuardRun | undefined): boolean {
403
+ return run !== undefined && is_unit_transcript(run.transcript)
404
+ }
405
+
406
+ function is_refusable_command(call: GuardedCall): boolean {
407
+ const label = time_shell.bash_label(time_shell.bash_command(call.input))
408
+
409
+ return CONTENT_READ_LABELS.has(label) && time_batch_guard.is_read_only_call(call)
410
+ }
411
+
412
+ // **A `Read` is always safe to refuse; a `Bash` line is refused only where it writes nothing.** This
413
+ // guard counts *reading*, so a line that also writes is one it has no business stopping — a `sed -i`
414
+ // is work rather than investigation, and refusing one would leave the siblings of its turn applied and
415
+ // itself not for no gain in what this guard measures.
416
+ //
417
+ // **It asks `is_read_only_call`, which is what `is_guarded_call` used to mean**
418
+ // (joshuafolkken/kit#1762). The batching guard can now refuse a write, and the two guards ask
419
+ // different questions of the same call: that one asks whether the call could have gone out beside
420
+ // another, this one whether the call is reading. A single shared predicate would have moved this one
421
+ // silently when that one widened, so the read-only test kept its semantics under a name that states
422
+ // them. A `sed -n` read is therefore still **counted and never refused**; the refusal lands on the
423
+ // next call that is unambiguously a read.
424
+ //
425
+ // **A call naming no subject file is never refused either**, which covers two cases in one rule: a
426
+ // call that names only instruction documents — refusing `CLAUDE.md` would stop a run reading the very
427
+ // rule being enforced — and a call whose targets could not be read at all, which cannot move the count
428
+ // and so has nothing to be refused for.
429
+ function is_refusable_call(call: GuardedCall): boolean {
430
+ if (call_targets(call).length === 0) return false
431
+ if (READ_TOOLS.has(call.name)) return true
432
+
433
+ return call.name === cost_blocks.BASH_TOOL && is_refusable_command(call)
434
+ }
435
+
436
+ function should_block(
437
+ text: string,
438
+ call: GuardedCall,
439
+ refused_at_ms: number,
440
+ run?: GuardRun,
441
+ ): boolean {
442
+ // A delegated unit is never refused (joshuafolkken/kit#1840): the remedy the refusal names — send
443
+ // the reading to a unit — does not exist inside one. Asked before the tail is parsed, since the
444
+ // answer needs none of it.
445
+ if (!is_refusable_call(call) || is_unit_run(run)) return false
446
+
447
+ const tally = tally_of(text, refused_at_ms)
448
+
449
+ if (!is_at_threshold(tally.pending.length)) return false
450
+
451
+ return (
452
+ projected_count(tally.pending, call, tally.edited) > tally.pending.length &&
453
+ is_rearmed(tally, refused_at_ms)
454
+ )
455
+ }
456
+
457
+ // What a read this rule saw was, in the four answers the rule itself can give
458
+ // (joshuafolkken/kit#1764). `pnpm josh time` prints them as a block, and the ids are here rather than
459
+ // there because each one is a fact about the guard: the two above the line are the reading §2b leaves
460
+ // in the main line on purpose, and the two below it are the reading it sends to a unit.
461
+ //
462
+ // **The last is the gap, and naming it is the point.** A read that reached the threshold and was not
463
+ // refused is neither by design nor caught, and nothing could see it — so the 35.9% of a run's turns
464
+ // that `investigation` accounts for could not be told apart from the reading that belongs there. Two
465
+ // things put a read in it, and the row deliberately covers both: a refusal already standing that the
466
+ // arm above had not re-armed, and a spelling the guard never refuses at all (`sed -n`, below).
467
+ const EDIT_TARGET_CLASS = 'edit targets'
468
+ const UNDER_THRESHOLD_CLASS = 'under the threshold'
469
+ const REFUSED_CLASS = 'refused'
470
+ // Kept inside `time-format.ts`'s 24-character label column, which the fuller phrasing overflowed —
471
+ // the prose beside the block is where the two reasons are named.
472
+ const LET_THROUGH_CLASS = 'let through'
473
+ const READ_CLASSES: ReadonlyArray<string> = [
474
+ EDIT_TARGET_CLASS,
475
+ UNDER_THRESHOLD_CLASS,
476
+ REFUSED_CLASS,
477
+ LET_THROUGH_CLASS,
478
+ ]
479
+
480
+ // **The live guard refuses a `Read` always and a shell read only where the line cannot also write**,
481
+ // which is why `Bash: sed` is counted and never refused: `sed -n` prints and `sed -i` rewrites, and
482
+ // `time-batch-guard.ts` → `is_read_only_call` answers conservatively for both. A span carries the
483
+ // label but not the command, so the replay asks the question the span *can* answer — and of the eight
484
+ // printing commands, `sed` is the only one on `time-bundle-call.ts`'s writing list. **The residual is
485
+ // named rather than hidden**: a redirection inside a `cat` line also stops the live call being refusable
486
+ // and is invisible here, so a handful of such reads land in `refused` that the guard would have let
487
+ // through. It is the same direction as the row below and far smaller.
488
+ const NEVER_REFUSED_LABELS: ReadonlySet<string> = new Set([time_shell.bash_label('sed')])
489
+
490
+ // The guard's state as a replay walks a recorded run, which is `ReadTally` plus the one thing a live
491
+ // hook keeps on disk instead — the instant it last refused.
492
+ interface Replay {
493
+ pending: Map<string, number>
494
+ reset_ms: number
495
+ window_start_ms: number
496
+ refused_at_ms: number
497
+ // The whole run's successful writes, gathered once by `classified_reads` and carried so `tally_now`
498
+ // can hand them to the same exclusion the live guard makes (joshuafolkken/kit#1840).
499
+ edited: ReadonlySet<string>
500
+ }
501
+
502
+ // The tally the live guard would have held at this instant, so the re-arm is asked of the one
503
+ // function that answers it rather than of a second copy of the rule.
504
+ function tally_now(replay: Replay): ReadTally {
505
+ return {
506
+ pending: [...replay.pending.keys()],
507
+ pending_since: pending_after(replay.pending, replay.refused_at_ms),
508
+ reset_ms: replay.reset_ms,
509
+ window_start_ms: replay.window_start_ms,
510
+ edited: replay.edited,
511
+ }
512
+ }
513
+
514
+ // The same two conditions `should_block` asks: the accumulated count is at the boundary, and this
515
+ // read actually adds a file to it.
516
+ function reaches_threshold(replay: Replay, targets: ReadonlyArray<string>): boolean {
517
+ const added = targets.filter((target) => !replay.pending.has(target))
518
+
519
+ return added.length > 0 && is_at_threshold(replay.pending.size)
520
+ }
521
+
522
+ // Whether the guard would have refused this read had it been armed — the same two conditions
523
+ // `is_refusable_call` puts in front of every refusal, asked of a span.
524
+ function would_refuse(replay: Replay, span: Span): boolean {
525
+ if (NEVER_REFUSED_LABELS.has(span.label)) return false
526
+
527
+ return is_rearmed(tally_now(replay), replay.refused_at_ms)
528
+ }
529
+
530
+ function class_of(replay: Replay, span: Span, edited: ReadonlySet<string>): string {
531
+ // Exclude the edited files first, so the threshold is judged on the same set `should_block` judges
532
+ // it on: an all-edited read is an edit target, and a mixed read reaches the threshold only on its
533
+ // genuinely new files, never on a file the run edited (joshuafolkken/kit#1840).
534
+ const fresh = subject_targets(span.targets).filter((target) => !edited.has(target))
535
+
536
+ if (fresh.length === 0) return EDIT_TARGET_CLASS
537
+ if (!reaches_threshold(replay, fresh)) return UNDER_THRESHOLD_CLASS
538
+
539
+ return would_refuse(replay, span) ? REFUSED_CLASS : LET_THROUGH_CLASS
540
+ }
541
+
542
+ // A span that is not a read, or whose every target was an instruction document or a session file,
543
+ // classifies as nothing at all — it never reached the count, so putting it in a row would report the
544
+ // guard as having an opinion about it.
545
+ function read_class(replay: Replay, span: Span, edited: ReadonlySet<string>): string | undefined {
546
+ if (!is_content_read(span.label)) return undefined
547
+ if (subject_targets(span.targets).length === 0) return undefined
548
+
549
+ return class_of(replay, span, edited)
550
+ }
551
+
552
+ function step(replay: Replay, span: Span, edited: ReadonlySet<string>): string | undefined {
553
+ if (DELEGATION_TOOLS.has(span.label)) {
554
+ replay.reset_ms = span.ended_ms
555
+ apply_span(replay.pending, span, edited)
556
+
557
+ return undefined
558
+ }
559
+
560
+ const found = read_class(replay, span, edited)
561
+
562
+ // A refusal moves the disarm forward, exactly as the hook's own stamp does.
563
+ if (found === REFUSED_CLASS) replay.refused_at_ms = span.ended_ms
564
+
565
+ apply_span(replay.pending, span, edited)
566
+
567
+ return found
568
+ }
569
+
570
+ // **A read paired with where it fell in the run** (joshuafolkken/kit#1868). `index` is the read span's
571
+ // position in the array handed to `classified_reads`; `time-investigation.ts` classifies that same
572
+ // array's phases and pairs the two by index, so it can say which phase — setup above all — each read
573
+ // landed in.
574
+ interface ClassifiedRead {
575
+ found: string
576
+ index: number
577
+ }
578
+
579
+ const FIRST_SPAN = 0
580
+
581
+ function fresh_replay(spans: ReadonlyArray<Span>, edited: ReadonlySet<string>): Replay {
582
+ return {
583
+ pending: new Map<string, number>(),
584
+ reset_ms: hook_decision.NEVER_MS,
585
+ window_start_ms: spans[FIRST_SPAN]?.ended_ms ?? hook_decision.NEVER_MS,
586
+ refused_at_ms: hook_decision.NEVER_MS,
587
+ edited,
588
+ }
589
+ }
590
+
591
+ // **What each of a run's reads was, replayed through this rule's own predicates**
592
+ // (joshuafolkken/kit#1764). It is the measurement half of the guard and shares every decision with
593
+ // it — the subject test, the threshold, the delegation reset and the re-arm — because a second walk
594
+ // that merely resembled the guard would answer about a rule nobody ships. Each read carries its span's
595
+ // index, so `time-investigation.ts` can place it in a phase (joshuafolkken/kit#1868).
596
+ function classified_reads(spans: ReadonlyArray<Span>): Array<ClassifiedRead> {
597
+ const edited = edited_files(spans)
598
+ const replay = fresh_replay(spans, edited)
599
+ const reads: Array<ClassifiedRead> = []
600
+
601
+ for (const [index, span] of spans.entries()) {
602
+ const found = step(replay, span, edited)
603
+
604
+ if (found !== undefined) reads.push({ found, index })
605
+ }
606
+
607
+ return reads
608
+ }
609
+
610
+ const investigation_reads = {
611
+ CONTENT_READ_COMMANDS,
612
+ EDIT_TARGET_CLASS,
613
+ LET_THROUGH_CLASS,
614
+ READ_CLASSES,
615
+ REFUSED_CLASS,
616
+ UNDER_THRESHOLD_CLASS,
617
+ classified_reads,
618
+ subject_targets,
619
+ DELEGATION_TOOLS,
620
+ READ_TOOLS,
621
+ REASON,
622
+ is_at_threshold,
623
+ is_content_read,
624
+ is_instruction_document,
625
+ is_rearmed,
626
+ is_refusable_call,
627
+ is_session_artifact,
628
+ is_subject_file,
629
+ projected_count,
630
+ repository_relative,
631
+ resolved,
632
+ should_block,
633
+ tally_of,
634
+ }
635
+
636
+ export type { ClassifiedRead, ReadTally }
637
+ export { investigation_reads }