@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,204 @@
1
+ // The `shell-body` row's trigger, in a module of its own rather than inside the enumeration
2
+ // (joshuafolkken/kit#1198). Every other row's trigger is already shaped that way — `time_batch_guard`
3
+ // and `cost_blocks` each hold their own reading of a call — and this one needs a small model of what
4
+ // zsh does inside double quotes, which is more than an enumeration row should carry. The split also
5
+ // gives that model a suite of its own, so a regex change is read beside the cases it has to keep.
6
+
7
+ // A body handed to a command as an inline double-quoted argument, in the spellings a run reaches for:
8
+ // `gh`'s field flags (`-f` / `-F` / `--field` / `--raw-field` with `body=`), `gh`'s own `--body`, and
9
+ // `josh`'s `--body` and `--notify-message`. The value is captured so the decision can be made on what
10
+ // the body actually contains rather than on the flag alone.
11
+ //
12
+ // **`-b` is deliberately absent.** It is `gh`'s short `--body`, but it is also `git checkout -b`, and
13
+ // a branch name is not a body — covering it would refuse calls where nothing is wrong. The `*-file`
14
+ // spellings end in `-` where this pattern needs whitespace or `=`, so `--body-file <path>` and
15
+ // `--notify-message-file <path>` cannot match it.
16
+ const FIELD_FLAGS = '(?:-f|-F|--field|--raw-field)'
17
+ const MESSAGE_FLAGS = '(?:--body|--notify-message)'
18
+
19
+ // **The opening quote sits on either side of `body=`, and both spellings are the same command.** zsh
20
+ // strips the quotes before `gh` is started, so `-f body="… \`pnpm josh ms\` …"` and
21
+ // `-f "body=… \`pnpm josh ms\` …"` hand `gh` one identical argument and execute one identical
22
+ // backtick. A pattern that knew only the first fired on half of the calls it was written for.
23
+ //
24
+ // **They are two alternatives rather than one optional quote on each side.** An optional quote after
25
+ // `body=` would also match `--field body=@$HOME/b.md`, capture the unquoted path up to some later
26
+ // quote, find the `$` in it and refuse the very file form this rule asks callers to use.
27
+ //
28
+ // **The separator is `=` as readily as whitespace**, because `gh` accepts `--field=body="…"` for the
29
+ // same reason `--body=…` works — which `MESSAGE_OPENING` below has always allowed. A pattern that
30
+ // only knew the space stayed silent on a call that executes the backtick.
31
+ const FIELD_OPENING = String.raw`${FIELD_FLAGS}[\s=]*(?:'?body="|"body=)`
32
+ const MESSAGE_OPENING = String.raw`${MESSAGE_FLAGS}[\s=]+"`
33
+
34
+ // One command substitution nested inside another — the `$(pwd)` of `$(cat "$(pwd)/x.md")`. One level
35
+ // is every spelling a run composes; deeper nesting stops matching and is read as ordinary text.
36
+ const NESTED_SUBSTITUTION = String.raw`\$\([^()]*\)`
37
+
38
+ // A whole command substitution, the quotes inside it included. **It belongs to the value pattern and
39
+ // not only to the exemption below**: `"` is legal inside `$( … )`, so a value that stopped at the
40
+ // first one truncated `$(cat "$(pwd)/x.md")` to `$(cat `, found the `$` and refused a caller who was
41
+ // already passing the body by path — spending the run's one delivery on a call that kept the rule.
42
+ //
43
+ // The branches are kept disjoint — `[^()$]` excludes the `$` the other two start with — so the match
44
+ // is linear rather than a nested quantifier that backtracks.
45
+ const SUBSTITUTION = String.raw`\$\((?:[^()$]|\$(?!\()|${NESTED_SUBSTITUTION})*\)`
46
+
47
+ // The text between the opening quote and the closing one: ordinary characters, a backslash escape, a
48
+ // lone `$`, or a whole substitution consumed in one piece so its inner quotes do not end the value.
49
+ const QUOTED_VALUE = String.raw`(?:[^"\\$]|\\.|\$(?!\()|${SUBSTITUTION})*`
50
+
51
+ const INLINE_BODY_VALUE = new RegExp(
52
+ `(?:${FIELD_OPENING}|${MESSAGE_OPENING})(${QUOTED_VALUE})"`,
53
+ 'gu',
54
+ )
55
+
56
+ // **What zsh evaluates inside double quotes, measured in this harness rather than assumed**
57
+ // (joshuafolkken/kit#1198): a backtick runs as command substitution and a `$` expands. `!` does
58
+ // **not** — history expansion is off in a non-interactive zsh, and `"hello!world"` survives intact —
59
+ // so it is deliberately absent: a rule that fired on every exclamation mark would be firing on turns
60
+ // where nothing is wrong, which `prompts/collaboration-workflow/rule-delivery.md` names as worse than
61
+ // no hook at all.
62
+ const SHELL_EVALUATED = /[`$]/u
63
+
64
+ // **The one exemption: a body that is *entirely* one command substitution.** `body="$(cat <path>)"`
65
+ // is the rule already being kept — the substitution's output is not re-scanned by the shell, so a
66
+ // body full of backticks reaches the command byte for byte, and refusing it would spend the run's one
67
+ // delivery on a caller who had already moved the body into a file.
68
+ //
69
+ // **It is anchored to the whole value, not to the `$(` alone.** Excusing `$(` anywhere would let
70
+ // `body="Result: run $(git log -1) to confirm"` through, and that one really is evaluated: the
71
+ // substitution replaces the text and the command runs.
72
+ const WHOLE_VALUE_SUBSTITUTION = new RegExp(`^${SUBSTITUTION}$`, 'u')
73
+
74
+ // **A backtick inside the substitution voids the exemption.** The exemption's reason is that the
75
+ // *output* is not re-scanned — but the substitution's own command is shell text, and a backtick in it
76
+ // runs exactly as an inline one does. `body="$(echo \`date\`)"` executes `date`, which is the damage
77
+ // joshuafolkken/kit#1198 was filed over, merely written one level in. A nested `$( … )` is the safe
78
+ // spelling of the same composition and stays exempt.
79
+ const BACKTICK = '`'
80
+
81
+ // **The other spelling of "already in a file": `body=@<path>`.** The unquoted `--field body=@<path>`
82
+ // never reaches the pattern at all, and `--field "body=@$HOME/body.md"` is that same call with the
83
+ // quote moved one character left — so it is excused for the same reason, and by the same shape of
84
+ // test as the substitution above: the *whole* value is the reference. A body that merely opens with
85
+ // an `@mention` is not one, so it carries a space and still fires.
86
+ const WHOLE_VALUE_FILE_REFERENCE = /^@\S+$/u
87
+
88
+ // A backslash escape makes the next character literal inside double quotes, so `\$` and `` \` `` are
89
+ // safe. They are dropped before the test rather than excluded from it, which is the same thing in one
90
+ // pass and keeps `SHELL_EVALUATED` readable.
91
+ const ESCAPED_PAIR = /\\./gu
92
+
93
+ function is_whole_value_substitution(literal: string): boolean {
94
+ return WHOLE_VALUE_SUBSTITUTION.test(literal) && !literal.includes(BACKTICK)
95
+ }
96
+
97
+ function is_body_already_in_a_file(literal: string): boolean {
98
+ return WHOLE_VALUE_FILE_REFERENCE.test(literal) || is_whole_value_substitution(literal)
99
+ }
100
+
101
+ function is_evaluated_value(raw_value: string): boolean {
102
+ const literal = raw_value.replaceAll(ESCAPED_PAIR, '')
103
+
104
+ if (is_body_already_in_a_file(literal)) return false
105
+
106
+ return SHELL_EVALUATED.test(literal)
107
+ }
108
+
109
+ // **The trigger is the body's content, not the flag.** Every worked example in this repository's
110
+ // prompts passes a placeholder (`-f body="<plan>"`), which is inert; the moment a real body carrying
111
+ // a backtick is substituted in, the call becomes the one that executes text. Keying on the flag would
112
+ // refuse the inert examples too — firing on turns where the rule is already being kept.
113
+ function is_shell_evaluated_body(command: string): boolean {
114
+ for (const match of command.matchAll(INLINE_BODY_VALUE)) {
115
+ if (is_evaluated_value(match[1] ?? '')) return true
116
+ }
117
+
118
+ return false
119
+ }
120
+
121
+ // **The safe spellings, which is what keeping this rule looks like** (joshuafolkken/kit#1643). They
122
+ // are the ones the refusal hands back: the `*-file` flags, a field whose value is a file reference,
123
+ // and `$'…'` quoting. The `*-file` flags cannot reach `INLINE_BODY_VALUE` at all — the note at the top
124
+ // of this file records why — so they are read straight off the command rather than out of a value.
125
+ const FILE_FLAG = /(?:--body-file|--notify-message-file)(?:[\s=]|$)/u
126
+ const FIELD_FILE_REFERENCE = new RegExp(String.raw`${FIELD_FLAGS}[\s=]*body=@\S`, 'u')
127
+ // **`$'…'` is the other form the refusal sanctions**, because zsh expands neither a backtick nor a `$`
128
+ // inside it. Only the **double**-quoted spans are blanked before it is read: blanking the single-quoted
129
+ // span is exactly what would hide the form itself, while leaving the double-quoted ones would credit
130
+ // `grep -rn "--body=$'" scripts/rules` — a run reading this repository — as one that passed a body.
131
+ const ANSI_C_BODY = /(?:(?:--body|--notify-message)[\s=]+|body=)\$'/u
132
+ const DOUBLE_QUOTED_SPAN = /"[^"]*"/gu
133
+
134
+ // **Any spelling that hands a command a body, whatever the quoting.** The trigger above reads double
135
+ // quotes alone, because those are the ones the shell evaluates; the occasion the rule governs is
136
+ // wider, and leaving a `$'…'` or single-quoted body out of it would drop from the denominator exactly
137
+ // the compliant runs this predicate was added to keep in it.
138
+ const BODY_FLAG = new RegExp(
139
+ String.raw`${FIELD_FLAGS}[\s=]*'?"?body=|${MESSAGE_FLAGS}[\s=]|--body-file[\s=]|--notify-message-file[\s=]`,
140
+ 'u',
141
+ )
142
+
143
+ // **A flag is only a flag outside the quotes**, the same reading `run-tail.ts` takes of a pull-request
144
+ // title. This repository's own refusal text names `--body-file <path>`, so a `grep` or an `echo`
145
+ // quoting it would otherwise be scored as a run that passed a body by path. The quoted spellings of
146
+ // the same thing are not lost by blanking: `--field "body=@<path>"` is a whole-value file reference,
147
+ // which the literal branch below reads.
148
+ const QUOTED_SPAN = /"[^"]*"|'[^']*'/gu
149
+
150
+ function inline_body_literals(command: string): Array<string> {
151
+ return Array.from(command.matchAll(INLINE_BODY_VALUE), (match) =>
152
+ (match[1] ?? '').replaceAll(ESCAPED_PAIR, ''),
153
+ )
154
+ }
155
+
156
+ function is_safe_body_form(command: string): boolean {
157
+ if (ANSI_C_BODY.test(command.replaceAll(DOUBLE_QUOTED_SPAN, ' '))) return true
158
+
159
+ const flags = command.replaceAll(QUOTED_SPAN, ' ')
160
+
161
+ if (FILE_FLAG.test(flags) || FIELD_FILE_REFERENCE.test(flags)) return true
162
+
163
+ return inline_body_literals(command).some((literal) => is_body_already_in_a_file(literal))
164
+ }
165
+
166
+ // **A call that passes its body safely and executes none inline.** The measurement asks a call whether
167
+ // it kept the rule before it asks whether it broke it, so a call doing both would be credited for the
168
+ // half it got right; requiring the absence of an evaluated body is what stops that.
169
+ function keeps_body_safe(command: string): boolean {
170
+ return is_safe_body_form(command) && !is_shell_evaluated_body(command)
171
+ }
172
+
173
+ // **The occasion this rule governs: a body handed to a command at all**, in every spelling. It is the
174
+ // denominator `rule-value.ts` reads, and it exists because this rule's trigger fires only on the
175
+ // violation — a run that passed every body safely would otherwise never appear in the reading.
176
+ function carries_a_body(command: string): boolean {
177
+ if (BODY_FLAG.test(command.replaceAll(QUOTED_SPAN, ' '))) return true
178
+
179
+ return inline_body_literals(command).length > 0
180
+ }
181
+
182
+ // The instruction in the shape a refusal can carry: what the shell is about to do, the safe
183
+ // spellings, and the reissue sentence every delivery needs. The damage is named because it is the
184
+ // half that reads as unbelievable — the substituted text is *executed*, not discarded. It lives here
185
+ // beside its trigger rather than inline in the enumeration, the shape every newer row's reason takes
186
+ // (`git-force.ts`, `lane-carry-conflict.ts`).
187
+ const SHELL_BODY_REASON =
188
+ '⛔ shell-evaluated body: this command carries a body inline in double quotes, and that body ' +
189
+ 'contains a backtick or a `$`, so the shell runs it — the text is executed rather than merely ' +
190
+ 'mangled (joshuafolkken/kit#1198). Write the body to a file and pass it by path: `pnpm josh ' +
191
+ 'issue:comment <N> --body-file <path>`, `pnpm josh followup --notify-message-file <path>`, or ' +
192
+ "`--body-file <path>` wherever offered. `$'…'` quoting is the other safe form; the rule and the " +
193
+ "trigger's blind spots are in `prompts/collaboration-workflow/shell-body.md`. Reissue this call " +
194
+ 'once the body is in a file — it fires once per run and cannot repeat on the call in hand.'
195
+
196
+ const shell_body_trigger = {
197
+ SHELL_BODY_REASON,
198
+ carries_a_body,
199
+ is_safe_body_form,
200
+ is_shell_evaluated_body,
201
+ keeps_body_safe,
202
+ }
203
+
204
+ export { shell_body_trigger }
@@ -0,0 +1,45 @@
1
+ import { time_shell } from '#scripts/time-runtime/time-shell'
2
+
3
+ // **A shell line carries several commands, and each has to be judged on its own.** Every trigger in
4
+ // this directory that reads a command string needs the same cut, so the cut lives here rather than
5
+ // beside whichever trigger needed it first — the clone `CLAUDE.md` prohibits is two copies of a
6
+ // pattern that would then have to be corrected twice.
7
+ //
8
+ // **A bare `|` is deliberately not a separator.** It appears inside a `--jq` filter far more often
9
+ // than between two commands, and cutting there would split one call into fragments neither of which
10
+ // is command-shaped. The rule that *is* about a pipe reads the whole line instead
11
+ // (`piped-verification.ts`).
12
+ //
13
+ // **`early-heartbeat.ts` keeps its own separator on purpose** and is not a caller here: it adds `&`,
14
+ // because `sleep 1200 &` is an armed timer sent to the background and has to be seen as one. That is
15
+ // a different question about a different character, not a second copy of this answer.
16
+ const SEGMENT_SEPARATOR = /&&|\|\||;|\n/u
17
+
18
+ /** The line's commands, trimmed. Empty segments are kept: a caller anchoring at `^` rejects them. */
19
+ function segments_of(command: string): Array<string> {
20
+ return command.split(SEGMENT_SEPARATOR).map((segment) => segment.trim())
21
+ }
22
+
23
+ // **Both spellings still match, and the expansion is no longer this file's** (joshuafolkken/kit#1643
24
+ // for the reading, joshuafolkken/kit#1789 for where it now happens). A `josh_names` here used to widen
25
+ // each caller's set with every alias standing for one of its names; `josh_command_of` expands the
26
+ // alias in the command it reads, so `pnpm josh ga` arrives as `josh gate` and a caller's canonical set
27
+ // matches it as it is. Widening as well would be a second copy of one rule, and the caller that
28
+ // forgot it would be the one that stops seeing `pnpm josh ga` at all — which is why each caller's own
29
+ // suite names a call in its alias spelling.
30
+ /** Whether this segment invokes one of the named josh subcommands, in either spelling. */
31
+ function is_josh_command(segment: string, names: ReadonlySet<string>): boolean {
32
+ const named = time_shell.josh_command_of(segment)
33
+
34
+ if (!named.startsWith(time_shell.JOSH_PREFIX)) return false
35
+
36
+ return names.has(named.slice(time_shell.JOSH_PREFIX.length))
37
+ }
38
+
39
+ const shell_segments = {
40
+ SEGMENT_SEPARATOR,
41
+ is_josh_command,
42
+ segments_of,
43
+ }
44
+
45
+ export { shell_segments }
@@ -0,0 +1,329 @@
1
+ import { hook_decision } from '#scripts/josh/hook-decision'
2
+ import { z } from 'zod'
3
+ import { filing_offer } from './filing-offer'
4
+ import { issue_citation } from './issue-citation'
5
+ import { reply_language } from './reply-language'
6
+
7
+ // The stop-time rules, delivered on the `Stop` hook (joshuafolkken/kit#2121, joshuafolkken/kit#2422,
8
+ // joshuafolkken/kit#2445).
9
+ //
10
+ // **It exists because `.claude/settings.json` wired no `Stop` event.** The four events it did wire
11
+ // (`SessionStart` / `UserPromptSubmit` / `PreToolUse` / `PostToolUse`) can catch the moment a call is
12
+ // about to run, but not the moment a run *stops* or *reports* — so three rules whose inputs are all
13
+ // mechanically readable could not be enforced structurally (`prompts/collaboration-workflow/rule-delivery.md`).
14
+ //
15
+ // **No second decision engine.** This loads on the same `hook_decision` foundation the PreToolUse
16
+ // guards share — the `.env` load and the switch — and reuses `lane-park`'s stop-notification judgement
17
+ // and `run:hold`'s record read rather than re-deriving either. What differs is only the event: a
18
+ // `Stop` payload has no tool call, and it blocks with `{"decision":"block"}` rather than a PreToolUse
19
+ // permission envelope. The stop guard is a second *entry* on the one foundation, exactly as
20
+ // `pretool-guard` is one — not a second copy of the plumbing.
21
+ //
22
+ // **Every rule refuses** (joshuafolkken/kit#2247). Missing the stop notification or leaving a hold
23
+ // on a clean tree costs a person a silent wait or a trampled tree; a bare `#N` in the reply reaches
24
+ // the person watching but not the model that could fix it, so it too blocks — `{"decision":"block"}`
25
+ // is the one channel a `Stop` hook has to the model, and `stop_hook_active` caps a false positive at a
26
+ // single wasted turn. The detection is tightened to match (`issue-citation.ts`, `filing-offer.ts`).
27
+
28
+ const SWITCH_ENV_KEY = 'JOSH_STOP_GUARD'
29
+ const BLOCK_DECISION = 'block'
30
+
31
+ // Only the fields the stop rules read. `last_assistant_message` is the turn's session-facing text —
32
+ // Claude Code hands it directly so the transcript's async lag is never in the citation path.
33
+ const stop_payload_schema = z.object({
34
+ transcript_path: z.string().min(1),
35
+ stop_hook_active: z.boolean().nullish(),
36
+ last_assistant_message: z.string().nullish(),
37
+ })
38
+
39
+ type StopPayload = z.infer<typeof stop_payload_schema>
40
+
41
+ // What one stop looks like to the rules, computed once by the CLI from the payload and the world.
42
+ interface StopContext {
43
+ // The `run:hold` record for this working tree is still in place (`held` or `stale`).
44
+ hold_present: boolean
45
+ // `git status --porcelain` came back empty.
46
+ tree_clean: boolean
47
+ // A `confirmation` notify is on this run's transcript tail.
48
+ notified: boolean
49
+ // The turn's session-facing reply text.
50
+ message: string
51
+ // This stop already forced a continuation earlier in the prompt — the loop-breaker Claude Code
52
+ // documents, so a run that will not comply is not blocked forever.
53
+ stop_hook_active: boolean
54
+ // A pre-gate cut record is in place for this work tree. A dispatched lane child ends its turn at
55
+ // the cut holding the tree by design and hands off to a fresh process (`pre-gate-cut.md`), so that
56
+ // turn-end is an automatic continuation, not the person-waiting pause the block rules are for.
57
+ cut_pending: boolean
58
+ // An Issue filing no guard refused is on this run's transcript tail — `filing_cap`'s count.
59
+ filed: boolean
60
+ // The owner of the repository the session runs in, or `undefined` when it cannot be read.
61
+ session_owner: string | undefined
62
+ // This session is a headless `backlogrun` parent with lanes still in flight and no cut handed its
63
+ // record off — `run-headless.ts` → `must_keep_waiting` (joshuafolkken/kit#2437).
64
+ headless_waiting: boolean
65
+ // How many headless-wait refusals sit on this run's transcript tail — the spin bound below.
66
+ headless_refusals: number
67
+ // This session is a dispatched lane child for this checkout — `lane_child_marker.is_child_of`.
68
+ lane_child: boolean
69
+ // The resolved `JOSH_SESSION_LANG` — `session_language.resolve_session_lang` (joshuafolkken/kit#2470).
70
+ session_lang: string
71
+ }
72
+
73
+ interface StopOutcome {
74
+ reason: string | undefined
75
+ }
76
+
77
+ const NO_OUTCOME: StopOutcome = { reason: undefined }
78
+
79
+ // **A mid-workflow stop is announced off-screen before it happens.** `CLAUDE.md` → "Mid-workflow stop
80
+ // notification" requires the `confirmation` Telegram before any pause; the hold is what says a run is
81
+ // mid-workflow, and the transcript is what says the notify was sent.
82
+ const STOP_NOTIFY_REASON =
83
+ '⛔ mid-workflow stop notification: this working tree is still held by a run and no `confirmation` ' +
84
+ 'Telegram was sent this turn, so a person is being left to wait off-screen without knowing the run ' +
85
+ 'paused. `CLAUDE.md` → "Mid-workflow stop notification" requires ' +
86
+ '`pnpm josh notify --task-type confirmation --issue-url "<url>" --body=$\'<reason>\'` before any ' +
87
+ 'mid-workflow pause. Send it, then end with a one-line confirmation that it was sent — do not repeat ' +
88
+ 'your previous reply. This fires only while the hold is held and no notify is on the transcript, and ' +
89
+ '`stop_hook_active` lets a second stop through so a run is never wedged.'
90
+
91
+ // **A clean tree that still holds is a tree the next run will trample.** `SKILL.md` → §2f: a stop that
92
+ // leaves the tree clean releases the hold; a `halfrun` pre-commit stop and a `needs-human-review` stop
93
+ // keep it because their tree is dirty, which is why this row is silent whenever the tree is not clean.
94
+ const HOLD_RELEASE_REASON =
95
+ '⛔ working-tree hold not released: this working tree is clean but its `run:hold` record is still in ' +
96
+ 'place, so the next run here runs `git switch main && git pull` believing the tree is free while ' +
97
+ 'you hold it. `.claude/skills/workflow-commands/SKILL.md` → §2f: a stop that leaves the tree clean ' +
98
+ 'releases the hold with `pnpm josh run:release <N>` (bare for a `new` entry). A `halfrun` ' +
99
+ 'pre-commit stop and a `needs-human-review` stop keep the hold because their tree is dirty — this ' +
100
+ 'row is silent there. Release it, then end with a one-line confirmation that it was released — do ' +
101
+ 'not repeat your previous reply.'
102
+
103
+ // **A refusal that corrects rather than advises** (joshuafolkken/kit#2247). The bare `#N` is already
104
+ // on screen and the hook cannot unsay it, so the reason does the one thing that helps the *next* reply:
105
+ // it names the numbers it detected and hands over the exact `issue:cite` call that prints the
106
+ // paste-ready lines, then asks for the corrected citation lines alone — not the whole reply reissued
107
+ // (joshuafolkken/kit#2329). Reprinting the whole reply is what made the correction read as a duplicate;
108
+ // the bare copy already scrolled past stays, and the fix follows it as a short correction. The rule
109
+ // itself is not restated — it is resident in `CLAUDE.md` — only pointed at.
110
+ const ISSUE_CITATION_REASON =
111
+ 'Session-facing output cites an Issue as a number-link so the reader can click through and see ' +
112
+ 'which repository it is (`CLAUDE.md`, `prompts/collaboration-workflow/issue-citation.md`).'
113
+
114
+ function build_citation_reason(references: ReadonlyArray<string>): string {
115
+ const numbers = references.join(', ')
116
+ const command = `pnpm josh issue:cite ${issue_citation.cite_arguments(references).join(' ')}`
117
+
118
+ return (
119
+ `⛔ issue citation: your reply names an Issue as a bare \`#N\` (${numbers}). Run \`${command}\` ` +
120
+ `to print the paste-ready citation lines, then print the corrected citation lines alone — do not ` +
121
+ `repeat your previous reply. ${ISSUE_CITATION_REASON}`
122
+ )
123
+ }
124
+
125
+ // **An offer to file is a Tier A filing deferred to the user** (joshuafolkken/kit#2422). The judgement
126
+ // is already made, so the reason hands over the filing chain rather than a question; the rule itself
127
+ // is resident in `SKILL.md` → §2i and only pointed at.
128
+ const FILING_OFFER_REASON =
129
+ '⛔ filing offer: your reply offers to file an Issue instead of filing it. Filing into a ' +
130
+ 'first-party repository is Tier A — the trigger is the judgement that it is worth filing, not the ' +
131
+ "run's progress (`.claude/skills/workflow-commands/SKILL.md` → §2i, `observation-filing.md`). Run " +
132
+ '`pnpm josh issue:scout "<title>"`, file it, run `pnpm josh epic:bundle <new>`, then end with the ' +
133
+ 'one-line citation of what was filed — do not repeat your previous reply. If it is not worth filing ' +
134
+ 'after all, say so in one line instead.'
135
+
136
+ // **A headless parent's turn-end is its process's end** (joshuafolkken/kit#2437). Under `claude -p` the
137
+ // background waits die with the turn, so the lanes lose their parent and nothing re-invokes it. The
138
+ // reason hands over the foreground wait rather than a question, because there is nobody to answer one.
139
+ // The refusal's opening, which the transcript tail is counted by.
140
+ const HEADLESS_WAIT_MARKER = '⛔ headless parent:'
141
+
142
+ // Refusals with no foreground wait between them before the loop-breaker is honoured again. A parent
143
+ // that obeys runs a wait after each refusal, which resets the count; one that only re-stops piles them
144
+ // up. The bound lets that one end when "in flight" is a kept lane no child is working in
145
+ // (`backlogrun-park.md`), rather than spinning until the carry record expires.
146
+ const HEADLESS_REFUSAL_CAP = 3
147
+
148
+ // The foreground waits as they appear in a transcript's tool-call input — the JSON `command` field, so
149
+ // the refusal's own prose, which names the same commands, never matches.
150
+ const HEADLESS_WAIT_CALLS = ['"command":"pnpm josh lane:await', '"command":"pnpm josh run:progress']
151
+
152
+ const HEADLESS_WAIT_BODY =
153
+ ' this is a `claude -p` `backlogrun` parent (`JOSH_RUN_HEADLESS`) with lanes still ' +
154
+ 'in flight, and ending this turn ends the process — its background waits are killed with it and the ' +
155
+ 'lanes are left without a parent. Wait in the foreground instead: run `pnpm josh lane:await <N...>` ' +
156
+ 'for the in-flight lanes (and `pnpm josh run:progress --wait` for the heartbeat) as foreground ' +
157
+ 'commands within the tool timeout, act on what they report, and continue the loop. End the turn only ' +
158
+ 'after `pnpm josh run:carry --cut` or `--end` (`backlogrun-progress.md` → "The parent keeps no clock ' +
159
+ 'of its own").'
160
+
161
+ const HEADLESS_WAIT_REASON = `${HEADLESS_WAIT_MARKER}${HEADLESS_WAIT_BODY}`
162
+
163
+ // **A lane child never asks a person for the index** (joshuafolkken/kit#2445). The index rule protects
164
+ // a person's own staging, and a lane is a per-run work tree with none to protect; the sanctioned commit
165
+ // flow is already authorized, so the reason hands it over instead of letting the run wait on a person.
166
+ // Both halves must appear — an index command and a request for permission — so a report that merely
167
+ // names `git add` is not refused.
168
+ const INDEX_COMMAND_PATTERN = /git (?:add|stage|rm --cached|restore --staged|restore -S)\b/u
169
+ const PERMISSION_PATTERN = /許可|承認|permission|approve|approval|authorization/iu
170
+
171
+ const LANE_INDEX_REASON =
172
+ '⛔ lane index permission: this is a dispatched lane child (`JOSH_LANE_CHILD`) and your reply asks ' +
173
+ "a person for permission to change the git index. A lane is a per-run work tree with no person's " +
174
+ 'staging to protect, and the sanctioned commit flow is already authorized: remove any conflict ' +
175
+ 'markers, then run `pnpm josh git -y`, which stages and commits them — a conflicted merge included. ' +
176
+ 'This is Tier A (`.claude/skills/workflow-commands/chain-rule.md` → "origin/main is merged in before ' +
177
+ 'the gate"). Do it and continue the run — do not repeat your previous reply.'
178
+
179
+ function asks_index_permission(message: string): boolean {
180
+ return INDEX_COMMAND_PATTERN.test(message) && PERMISSION_PATTERN.test(message)
181
+ }
182
+
183
+ function needs_index_route(context: StopContext): boolean {
184
+ return context.lane_child && asks_index_permission(context.message)
185
+ }
186
+
187
+ // **A refusal is the turn's only input, so it names the language the answer is written in**
188
+ // (joshuafolkken/kit#2470). The session-language line reaches a turn only through `UserPromptSubmit`;
189
+ // a turn this hook continues has no prompt, and an English refusal read alone was answered in English.
190
+ function language_note(lang: string): string {
191
+ return (
192
+ `Write your reply in the session language (JOSH_SESSION_LANG: ${lang}); code, commands and ` +
193
+ 'identifiers stay as they are.'
194
+ )
195
+ }
196
+
197
+ // **A reply that drifted out of the session language is sent back once to be rewritten**
198
+ // (joshuafolkken/kit#2470). The drift persists — each turn matches the language of the one before — so
199
+ // the rewrite has to happen on the turn it starts; `stop_hook_active` bounds it to one.
200
+ function build_language_reason(lang: string): string {
201
+ return (
202
+ `⛔ session language: your reply is not written in the session language (JOSH_SESSION_LANG: ` +
203
+ `${lang}). Rewrite it in that language and keep writing in it on the turns that follow, whatever ` +
204
+ 'language a notification, tool output or hook message was in (`CLAUDE.md` → "Output language").'
205
+ )
206
+ }
207
+
208
+ function language_reason(context: StopContext): string | undefined {
209
+ if (!reply_language.is_mismatch(context.message, context.session_lang)) return undefined
210
+
211
+ return build_language_reason(context.session_lang)
212
+ }
213
+
214
+ function needs_filing(context: StopContext): boolean {
215
+ if (context.filed || !filing_offer.offers_filing(context.message)) return false
216
+
217
+ return filing_offer.is_first_party_target(context.message, context.session_owner)
218
+ }
219
+
220
+ function needs_notify(context: StopContext): boolean {
221
+ return context.hold_present && !context.notified
222
+ }
223
+
224
+ function needs_release(context: StopContext): boolean {
225
+ return context.hold_present && context.tree_clean
226
+ }
227
+
228
+ function citation_reason(message: string): string | undefined {
229
+ const references = issue_citation.bare_references(message)
230
+ if (references.length === 0) return undefined
231
+
232
+ return build_citation_reason(references)
233
+ }
234
+
235
+ // The three rules that read the reply itself, filing offer first and the language last. A drifted reply
236
+ // refused for another reason is not rewritten, but the drift still ends: `block_envelope` appends the
237
+ // session-language note to every refusal, so the turn it continues is written in the session language.
238
+ function reply_reason(context: StopContext): string | undefined {
239
+ if (needs_filing(context)) return FILING_OFFER_REASON
240
+
241
+ return citation_reason(context.message) ?? language_reason(context)
242
+ }
243
+
244
+ // The headless wait holds past the loop-breaker until the spin bound is reached.
245
+ function is_headless_held(context: StopContext): boolean {
246
+ if (!context.headless_waiting) return false
247
+
248
+ return !context.stop_hook_active || context.headless_refusals < HEADLESS_REFUSAL_CAP
249
+ }
250
+
251
+ // The headless-wait refusals on a transcript tail since the last foreground wait the parent ran — a
252
+ // wait is progress, so only refusals with none between them count toward the spin bound.
253
+ function count_headless_refusals(tail: string): number {
254
+ const last_wait = Math.max(...HEADLESS_WAIT_CALLS.map((call) => tail.lastIndexOf(call)))
255
+
256
+ return tail.slice(Math.max(last_wait, 0)).split(HEADLESS_WAIT_MARKER).length - 1
257
+ }
258
+
259
+ // The two hold rules, notify ahead of release — behind the lane index route (joshuafolkken/kit#2445),
260
+ // since the notify they would ask for announces a pause the run has no reason to take.
261
+ function hold_reason(context: StopContext): string | undefined {
262
+ if (needs_index_route(context)) return LANE_INDEX_REASON
263
+ if (needs_notify(context)) return STOP_NOTIFY_REASON
264
+ if (needs_release(context)) return HOLD_RELEASE_REASON
265
+
266
+ return undefined
267
+ }
268
+
269
+ // First-wins across every rule. Two things stand every rule down: `stop_hook_active` (the
270
+ // loop-breaker, so a run that already got one continuation this prompt may stop) and a pre-gate cut in
271
+ // flight (a lane child's automatic turn-end, not a person-waiting pause). The two hold rules keep their
272
+ // order ahead of the reply rules, so a stop that both still owes its notify and holds a bare `#N` still
273
+ // reports the notify first; the filing offer goes ahead of the citation, since the filing it forces
274
+ // produces the citation the reply then needs.
275
+ //
276
+ // **The headless wait comes first and outlasts `stop_hook_active` up to its spin bound** (joshuafolkken/kit#2437).
277
+ // The loop-breaker exists so a person is not wedged behind a rule the run will not satisfy; a headless
278
+ // parent has no person, and letting its second stop through is exactly the silent end the rule is for.
279
+ // Each continuation it forces is a foreground wait of minutes, and the rule falls silent by itself once
280
+ // the lanes finish or a cut hands the record off; refusals with no wait between them are bounded.
281
+ function block_reason(context: StopContext): string | undefined {
282
+ if (is_headless_held(context)) return HEADLESS_WAIT_REASON
283
+ if (context.stop_hook_active || context.cut_pending) return undefined
284
+
285
+ return hold_reason(context) ?? reply_reason(context)
286
+ }
287
+
288
+ function stop_outcome(context: StopContext): StopOutcome {
289
+ return { reason: block_reason(context) }
290
+ }
291
+
292
+ // The documented shape a `Stop` hook blocks with: `reason` is fed back to Claude, which then continues
293
+ // instead of stopping. Plain stdout is not it — only this envelope holds the stop. Every reason leaves
294
+ // with the session-language note, so no rule can hand the model an English-only turn.
295
+ function block_envelope(reason: string, lang: string): string {
296
+ return JSON.stringify({ decision: BLOCK_DECISION, reason: `${reason} ${language_note(lang)}` })
297
+ }
298
+
299
+ function parse_stop_payload(raw_payload: string): StopPayload | undefined {
300
+ const parsed = stop_payload_schema.safeParse(JSON.parse(raw_payload))
301
+
302
+ return parsed.success ? parsed.data : undefined
303
+ }
304
+
305
+ function is_enabled(): boolean {
306
+ return hook_decision.is_switch_enabled(SWITCH_ENV_KEY)
307
+ }
308
+
309
+ const stop_rules = {
310
+ FILING_OFFER_REASON,
311
+ HEADLESS_REFUSAL_CAP,
312
+ HEADLESS_WAIT_REASON,
313
+ HOLD_RELEASE_REASON,
314
+ ISSUE_CITATION_REASON,
315
+ LANE_INDEX_REASON,
316
+ NO_OUTCOME,
317
+ STOP_NOTIFY_REASON,
318
+ SWITCH_ENV_KEY,
319
+ block_envelope,
320
+ block_reason,
321
+ build_language_reason,
322
+ count_headless_refusals,
323
+ is_enabled,
324
+ parse_stop_payload,
325
+ stop_outcome,
326
+ }
327
+
328
+ export type { StopContext, StopOutcome }
329
+ export { stop_rules }
@@ -0,0 +1,35 @@
1
+ import { cost_blocks } from '#scripts/cost-runtime/cost-blocks'
2
+ import { time_shell } from '#scripts/time-runtime/time-shell'
3
+ import { time_transcript_line, type Block } from '#scripts/time-runtime/time-transcript-line'
4
+
5
+ // The `Bash` commands a run's transcript tail already issued, parsed once here rather than in each
6
+ // rule that needs them (joshuafolkken/kit#2119). `prior-comment-read.ts` had this reading first; the
7
+ // scout gate needs the same "what did the run already run" question, so a second copy would be the
8
+ // clone `CLAUDE.md` prohibits. The delivery path sees only the raw tail — `delivered-rules.ts` names
9
+ // the reason a run's own calls are not handed to it — so the earlier calls are recovered by parsing
10
+ // that tail the same way `time-batch-guard.ts` does.
11
+
12
+ // A `tool_use` block that ran a shell command.
13
+ function is_bash_use(block: Block): boolean {
14
+ return block.type === cost_blocks.TOOL_USE_TYPE && block.name === cost_blocks.BASH_TOOL
15
+ }
16
+
17
+ // The Bash commands one transcript line issued, empty for a line that parses to none.
18
+ function bash_commands_of(line: string): ReadonlyArray<string> {
19
+ const parsed = time_transcript_line.parse_line(line)
20
+
21
+ if (parsed === undefined) return []
22
+
23
+ return parsed.blocks
24
+ .filter((block) => is_bash_use(block))
25
+ .map((block) => time_shell.bash_command(block.input))
26
+ }
27
+
28
+ // Every Bash command the tail holds, in the order they were issued.
29
+ function prior_bash_commands(tail: string): ReadonlyArray<string> {
30
+ return tail.split('\n').flatMap((line) => bash_commands_of(line))
31
+ }
32
+
33
+ const tail_commands = { bash_commands_of, is_bash_use, prior_bash_commands }
34
+
35
+ export { tail_commands }