@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,3265 @@
1
+ import {
2
+ ENV_FILE_NAME
3
+ } from "./chunk-LRYD2GLM.js";
4
+
5
+ // scripts/josh/josh-command-types.ts
6
+ var OPTIONAL_ENV_FILE_FLAGS = [`--env-file-if-exists=${ENV_FILE_NAME}`];
7
+ var GATE_COMMAND = "gate";
8
+ var PE = ["pnpm", "exec"];
9
+ var ESLINT_CACHE_FILE = ".eslintcache";
10
+ var TS_BUILD_INFO_FILE = ".tsbuildinfo";
11
+ var CSPELL_CACHE_FILE = ".cspellcache";
12
+ var ESLINT_EDIT_CACHE_FILE = ".eslintcache.edit";
13
+ var ESLINT_RELATED_CACHE_FILE = ".eslintcache.related";
14
+ var ROOTED_JSON_PORTABILITY = "rooted-json";
15
+ var ESLINT_CACHE_SPEC = {
16
+ cache_file: ESLINT_CACHE_FILE,
17
+ portability: ROOTED_JSON_PORTABILITY
18
+ };
19
+ var TS_CACHE_SPEC = {
20
+ cache_file: TS_BUILD_INFO_FILE,
21
+ portability: "raw"
22
+ };
23
+ var CSPELL_CACHE_SPEC = {
24
+ cache_file: CSPELL_CACHE_FILE,
25
+ portability: "raw"
26
+ };
27
+ var GATE_CACHE_SPECS = [
28
+ ESLINT_CACHE_SPEC,
29
+ TS_CACHE_SPEC,
30
+ CSPELL_CACHE_SPEC
31
+ ];
32
+ var GATE_CACHE_FILES = GATE_CACHE_SPECS.map((spec) => spec.cache_file);
33
+ var IGNORED_CACHE_FILES = [
34
+ ...GATE_CACHE_FILES,
35
+ ESLINT_EDIT_CACHE_FILE,
36
+ ESLINT_RELATED_CACHE_FILE
37
+ ];
38
+ var CONTENT_CACHE_FLAGS = ["--cache", "--cache-strategy", "content"];
39
+ var CACHE_LOCATION_FLAG = "--cache-location";
40
+ function content_cache_flags(cache_file) {
41
+ return [...CONTENT_CACHE_FLAGS, CACHE_LOCATION_FLAG, cache_file];
42
+ }
43
+ var ESLINT_CACHE_FLAGS = content_cache_flags(ESLINT_CACHE_FILE);
44
+ var ESLINT_EDIT_CACHE_FLAGS = content_cache_flags(ESLINT_EDIT_CACHE_FILE);
45
+ var ESLINT_RELATED_CACHE_FLAGS = content_cache_flags(ESLINT_RELATED_CACHE_FILE);
46
+ var TS_CACHE_FLAGS = ["--incremental", "--tsBuildInfoFile", TS_BUILD_INFO_FILE];
47
+ var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
48
+
49
+ // scripts/time-runtime/time-hook-transcript.ts
50
+ import path3 from "node:path";
51
+
52
+ // scripts/cost-runtime/cost-transcript.ts
53
+ import { readdirSync, readFileSync, statSync } from "node:fs";
54
+ import { homedir } from "node:os";
55
+ import path2 from "node:path";
56
+
57
+ // scripts/lane/lane-paths.ts
58
+ import path from "node:path";
59
+ var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
60
+ var LANE_DIRECTORY_SUFFIX = "-lanes";
61
+ var LANE_BRANCH_SUFFIX = "-lane";
62
+ function default_lane_root(repository_root) {
63
+ const name = path.basename(repository_root);
64
+ return path.join(path.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
65
+ }
66
+ function lane_root(repository_root, environment = process.env) {
67
+ const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
68
+ return configured.length === 0 ? default_lane_root(repository_root) : path.resolve(configured);
69
+ }
70
+ function lane_directory(root, issue) {
71
+ return path.join(root, issue);
72
+ }
73
+ var LANE_ISSUE_PATTERN = /^\d+$/u;
74
+ var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
75
+ function is_lane_root(directory, environment) {
76
+ const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
77
+ if (configured.length > 0) return path.resolve(configured) === directory;
78
+ return DEFAULT_LANE_ROOT_PATTERN.test(path.basename(directory));
79
+ }
80
+ function lane_issue_of(directory, environment = process.env) {
81
+ const resolved = path.resolve(directory);
82
+ const issue = path.basename(resolved);
83
+ if (!LANE_ISSUE_PATTERN.test(issue)) return void 0;
84
+ return is_lane_root(path.dirname(resolved), environment) ? issue : void 0;
85
+ }
86
+ function lane_branch(issue) {
87
+ return `${issue}${LANE_BRANCH_SUFFIX}`;
88
+ }
89
+ var lane_paths = {
90
+ LANE_BRANCH_SUFFIX,
91
+ LANE_ROOT_KEY,
92
+ default_lane_root,
93
+ lane_branch,
94
+ lane_directory,
95
+ lane_issue_of,
96
+ lane_root
97
+ };
98
+
99
+ // scripts/lib/json-value.ts
100
+ function parse_or_undefined(text) {
101
+ try {
102
+ return JSON.parse(text);
103
+ } catch {
104
+ return void 0;
105
+ }
106
+ }
107
+ function is_record(value) {
108
+ return typeof value === "object" && value !== null && !Array.isArray(value);
109
+ }
110
+ var json_value = { parse_or_undefined, is_record };
111
+
112
+ // scripts/time-runtime/time-instant.ts
113
+ function parse_instant(raw) {
114
+ const parsed = Date.parse(raw ?? "");
115
+ return Number.isNaN(parsed) ? void 0 : parsed;
116
+ }
117
+ var time_instant = { parse_instant };
118
+
119
+ // scripts/cost-runtime/cost-usage.ts
120
+ import { z } from "zod";
121
+ var CACHE_CREATION_SCHEMA = z.object({
122
+ ephemeral_1h_input_tokens: z.number().nullish(),
123
+ ephemeral_5m_input_tokens: z.number().nullish()
124
+ });
125
+ var USAGE_SCHEMA = z.object({
126
+ input_tokens: z.number(),
127
+ cache_creation_input_tokens: z.number().nullish(),
128
+ cache_read_input_tokens: z.number().nullish(),
129
+ output_tokens: z.number(),
130
+ output_tokens_details: z.object({ thinking_tokens: z.number().nullish() }).nullish(),
131
+ cache_creation: CACHE_CREATION_SCHEMA.nullish()
132
+ });
133
+ var MESSAGE_SCHEMA = z.object({
134
+ id: z.string().nullish(),
135
+ model: z.string().nullish(),
136
+ usage: USAGE_SCHEMA.nullish()
137
+ });
138
+ var LINE_SCHEMA = z.object({
139
+ type: z.string(),
140
+ requestId: z.string().nullish(),
141
+ uuid: z.string().nullish(),
142
+ gitBranch: z.string().nullish(),
143
+ timestamp: z.string().nullish(),
144
+ message: MESSAGE_SCHEMA.nullish()
145
+ });
146
+ var SYNTHETIC_MODEL = "<synthetic>";
147
+ var EMPTY_TOTALS = {
148
+ input_tokens: 0,
149
+ cache_write_5m_tokens: 0,
150
+ cache_write_1h_tokens: 0,
151
+ cache_read_tokens: 0,
152
+ output_tokens: 0,
153
+ thinking_tokens: 0,
154
+ thinking_measured: false
155
+ };
156
+ var UNKNOWN_MODEL = "unknown";
157
+ var UNKNOWN_BRANCH = "";
158
+ function split_cache_write(usage) {
159
+ const total = usage.cache_creation_input_tokens ?? 0;
160
+ const detail = usage.cache_creation;
161
+ if (!detail) return { write_5m: total, write_1h: 0 };
162
+ const write_1h = detail.ephemeral_1h_input_tokens ?? 0;
163
+ return { write_5m: detail.ephemeral_5m_input_tokens ?? total - write_1h, write_1h };
164
+ }
165
+ function thinking_usage(usage) {
166
+ const raw = usage.output_tokens_details?.thinking_tokens;
167
+ return { tokens: raw ?? 0, measured: raw !== null && raw !== void 0 };
168
+ }
169
+ function to_totals(usage) {
170
+ const { write_5m, write_1h } = split_cache_write(usage);
171
+ const thinking = thinking_usage(usage);
172
+ return {
173
+ input_tokens: usage.input_tokens,
174
+ cache_write_5m_tokens: write_5m,
175
+ cache_write_1h_tokens: write_1h,
176
+ cache_read_tokens: usage.cache_read_input_tokens ?? 0,
177
+ output_tokens: usage.output_tokens,
178
+ thinking_tokens: thinking.tokens,
179
+ thinking_measured: thinking.measured
180
+ };
181
+ }
182
+ function declared_id(data) {
183
+ return data.requestId ?? data.message?.id ?? data.uuid ?? void 0;
184
+ }
185
+ function request_id_of(data, usage) {
186
+ const fallback = `${data.timestamp ?? ""}-${String(usage.output_tokens)}`;
187
+ return declared_id(data) ?? fallback;
188
+ }
189
+ function to_record(data, usage) {
190
+ return {
191
+ request_id: request_id_of(data, usage),
192
+ model: data.message?.model ?? UNKNOWN_MODEL,
193
+ branch: data.gitBranch ?? UNKNOWN_BRANCH,
194
+ at_ms: time_instant.parse_instant(data.timestamp),
195
+ totals: to_totals(usage)
196
+ };
197
+ }
198
+ var ASSISTANT_TYPE = "assistant";
199
+ function is_priced_line(data) {
200
+ return data.type === ASSISTANT_TYPE && data.message?.model !== SYNTHETIC_MODEL;
201
+ }
202
+ function classify(data) {
203
+ if (!is_priced_line(data)) return { kind: "skipped" };
204
+ const usage = data.message?.usage;
205
+ return usage ? { kind: "record", record: to_record(data, usage) } : { kind: "no_usage" };
206
+ }
207
+ function parse_line(line) {
208
+ if (line.trim() === "") return { kind: "skipped" };
209
+ const parsed = LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line));
210
+ return parsed.success ? classify(parsed.data) : { kind: "malformed" };
211
+ }
212
+ function later_instant(left, right) {
213
+ if (left === void 0) return right;
214
+ if (right === void 0) return left;
215
+ return Math.max(left, right);
216
+ }
217
+ function dedupe(records) {
218
+ const by_id = /* @__PURE__ */ new Map();
219
+ for (const record of records) {
220
+ const seen = by_id.get(record.request_id);
221
+ const at_ms = later_instant(seen?.at_ms, record.at_ms);
222
+ by_id.set(record.request_id, { ...seen ?? record, at_ms });
223
+ }
224
+ return [...by_id.values()];
225
+ }
226
+ function add_totals(left, right) {
227
+ return {
228
+ input_tokens: left.input_tokens + right.input_tokens,
229
+ cache_write_5m_tokens: left.cache_write_5m_tokens + right.cache_write_5m_tokens,
230
+ cache_write_1h_tokens: left.cache_write_1h_tokens + right.cache_write_1h_tokens,
231
+ cache_read_tokens: left.cache_read_tokens + right.cache_read_tokens,
232
+ output_tokens: left.output_tokens + right.output_tokens,
233
+ thinking_tokens: left.thinking_tokens + right.thinking_tokens,
234
+ thinking_measured: left.thinking_measured || right.thinking_measured
235
+ };
236
+ }
237
+ function sum_totals(records) {
238
+ let total = EMPTY_TOTALS;
239
+ for (const record of records) total = add_totals(total, record.totals);
240
+ return total;
241
+ }
242
+ function billed_input(totals) {
243
+ return totals.input_tokens + totals.cache_write_5m_tokens + totals.cache_write_1h_tokens + totals.cache_read_tokens;
244
+ }
245
+ var cost_usage = {
246
+ EMPTY_TOTALS,
247
+ UNKNOWN_MODEL,
248
+ SYNTHETIC_MODEL,
249
+ parse_line,
250
+ dedupe,
251
+ add_totals,
252
+ sum_totals,
253
+ billed_input
254
+ };
255
+
256
+ // scripts/cost-runtime/cost-transcript.ts
257
+ var TRANSCRIPT_ROOT = path2.join(".claude", "projects");
258
+ var TRANSCRIPT_EXTENSION = ".jsonl";
259
+ var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
260
+ var UNIT_DIRECTORY = "subagents";
261
+ var UNIT_ID_SEPARATOR = "/";
262
+ function project_slug(cwd) {
263
+ return cwd.replaceAll(SLUG_PATTERN, "-");
264
+ }
265
+ function transcript_directory(cwd, home = homedir()) {
266
+ return path2.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
267
+ }
268
+ var GIT_ENTRY = ".git";
269
+ var GITDIR_PREFIX = "gitdir:";
270
+ var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
271
+ var NOT_FOUND = -1;
272
+ function linked_worktree_gitdir(cwd) {
273
+ try {
274
+ const contents = readFileSync(path2.join(cwd, GIT_ENTRY), "utf8").trim();
275
+ return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
276
+ } catch {
277
+ return "";
278
+ }
279
+ }
280
+ function session_cwd(cwd) {
281
+ const gitdir = linked_worktree_gitdir(cwd);
282
+ const absolute = gitdir === "" ? "" : path2.resolve(cwd, gitdir);
283
+ const segment = absolute.indexOf(WORKTREE_SEGMENT);
284
+ return segment === NOT_FOUND ? cwd : absolute.slice(0, segment);
285
+ }
286
+ function read_directory(directory) {
287
+ try {
288
+ return readdirSync(directory);
289
+ } catch {
290
+ return [];
291
+ }
292
+ }
293
+ var LANE_ISSUE_SLUG = /^\d+$/u;
294
+ function lane_transcript_directories(main_cwd, home) {
295
+ const projects = path2.join(home, TRANSCRIPT_ROOT);
296
+ const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
297
+ return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path2.join(projects, name));
298
+ }
299
+ function transcript_directories(cwd, home = homedir()) {
300
+ const own = transcript_directory(cwd, home);
301
+ const lanes = session_cwd(cwd) === cwd ? lane_transcript_directories(cwd, home) : [];
302
+ return [.../* @__PURE__ */ new Set([own, ...lanes])];
303
+ }
304
+ var OWN_DEPTH = 0;
305
+ function home_directory() {
306
+ return homedir();
307
+ }
308
+ function to_session_file(full_path, session_id, depth) {
309
+ try {
310
+ return {
311
+ session_id,
312
+ path: full_path,
313
+ modified_ms: statSync(full_path).mtimeMs,
314
+ is_delegated: depth > OWN_DEPTH,
315
+ depth
316
+ };
317
+ } catch {
318
+ return void 0;
319
+ }
320
+ }
321
+ function is_transcript(name) {
322
+ return name.endsWith(TRANSCRIPT_EXTENSION);
323
+ }
324
+ function without_extension(name) {
325
+ return name.slice(0, -TRANSCRIPT_EXTENSION.length);
326
+ }
327
+ function own_files(directory, names) {
328
+ return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path2.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
329
+ }
330
+ function unit_directory(directory, session_id) {
331
+ return path2.join(directory, session_id, UNIT_DIRECTORY);
332
+ }
333
+ var UNIT_DEPTH = 1;
334
+ function level_units(subagents_directory, prefix, depth) {
335
+ return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
336
+ (name) => to_session_file(
337
+ path2.join(subagents_directory, name),
338
+ `${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
339
+ depth
340
+ )
341
+ ).filter((file) => file !== void 0);
342
+ }
343
+ function collect_units(subagents_directory, prefix, depth) {
344
+ const nested = read_directory(subagents_directory).filter((name) => !is_transcript(name)).flatMap(
345
+ (name) => collect_units(
346
+ unit_directory(subagents_directory, name),
347
+ `${prefix}${UNIT_ID_SEPARATOR}${name}`,
348
+ depth + 1
349
+ )
350
+ );
351
+ return [...level_units(subagents_directory, prefix, depth), ...nested];
352
+ }
353
+ function unit_files(directory, session_name) {
354
+ return collect_units(unit_directory(directory, session_name), session_name, UNIT_DEPTH);
355
+ }
356
+ function list_sessions(directory) {
357
+ const names = read_directory(directory);
358
+ const units = names.filter((name) => !is_transcript(name)).flatMap((name) => unit_files(directory, name));
359
+ return [...own_files(directory, names), ...units].toSorted(
360
+ (left, right) => right.modified_ms - left.modified_ms
361
+ );
362
+ }
363
+ function list_sessions_across(directories) {
364
+ const seen = /* @__PURE__ */ new Set();
365
+ const merged = directories.flatMap((directory) => list_sessions(directory));
366
+ const newest_first = merged.toSorted((left, right) => right.modified_ms - left.modified_ms);
367
+ const kept = [];
368
+ for (const file of newest_first) {
369
+ if (seen.has(file.session_id)) continue;
370
+ seen.add(file.session_id);
371
+ kept.push(file);
372
+ }
373
+ return kept;
374
+ }
375
+ function owning_session_id(file) {
376
+ const [owner] = file.session_id.split(UNIT_ID_SEPARATOR);
377
+ return owner ?? file.session_id;
378
+ }
379
+ function parent_session_id(file) {
380
+ const separator = file.session_id.lastIndexOf(UNIT_ID_SEPARATOR);
381
+ return separator === NOT_FOUND ? file.session_id : file.session_id.slice(0, separator);
382
+ }
383
+ function latest_own_index(files) {
384
+ const index = files.findIndex((file) => !file.is_delegated);
385
+ return index === -1 ? 0 : index;
386
+ }
387
+ function empty_session() {
388
+ return {
389
+ records: [],
390
+ no_usage_lines: 0,
391
+ malformed_lines: 0,
392
+ is_readable: false,
393
+ baseline_tokens: 0
394
+ };
395
+ }
396
+ function tally(content) {
397
+ const outcomes = content.split("\n").map((line) => cost_usage.parse_line(line));
398
+ const records = outcomes.flatMap(
399
+ (outcome) => outcome.kind === "record" ? [outcome.record] : []
400
+ );
401
+ const unique = cost_usage.dedupe(records);
402
+ const [first] = unique;
403
+ return {
404
+ records: unique,
405
+ no_usage_lines: outcomes.filter((outcome) => outcome.kind === "no_usage").length,
406
+ malformed_lines: outcomes.filter((outcome) => outcome.kind === "malformed").length,
407
+ is_readable: true,
408
+ baseline_tokens: first === void 0 ? 0 : cost_usage.billed_input(first.totals)
409
+ };
410
+ }
411
+ function read_text(file_path) {
412
+ try {
413
+ return readFileSync(file_path, "utf8");
414
+ } catch {
415
+ return void 0;
416
+ }
417
+ }
418
+ function read_session(file) {
419
+ const content = read_text(file.path);
420
+ if (content === void 0) return { session_id: file.session_id, ...empty_session() };
421
+ return { session_id: file.session_id, ...tally(content) };
422
+ }
423
+ function read_raw(file) {
424
+ return read_text(file.path) ?? "";
425
+ }
426
+ function read_optional(file) {
427
+ return read_text(file.path);
428
+ }
429
+ function directory_exists(directory) {
430
+ try {
431
+ return statSync(directory).isDirectory();
432
+ } catch {
433
+ return false;
434
+ }
435
+ }
436
+ function searched_directories(directories) {
437
+ return directories.map((directory) => ({
438
+ path: directory,
439
+ exists: directory_exists(directory)
440
+ }));
441
+ }
442
+ function describe_searched(directory) {
443
+ return ` ${directory.path} \u2014 ${directory.exists ? "no transcripts here" : "no such directory"}`;
444
+ }
445
+ function missing_message(searched, session_id) {
446
+ const lead = session_id === void 0 ? "No transcripts found. Searched:" : `No transcript named ${session_id}. Searched:`;
447
+ const listed = searched.map((directory) => describe_searched(directory));
448
+ if (session_id !== void 0) return [lead, ...listed];
449
+ return [
450
+ lead,
451
+ ...listed,
452
+ "Claude Code writes them per project; run this from the project it ran in."
453
+ ];
454
+ }
455
+ var cost_transcript = {
456
+ TRANSCRIPT_EXTENSION,
457
+ TRANSCRIPT_ROOT,
458
+ UNIT_DIRECTORY,
459
+ project_slug,
460
+ transcript_directory,
461
+ transcript_directories,
462
+ session_cwd,
463
+ unit_directory,
464
+ list_sessions,
465
+ list_sessions_across,
466
+ searched_directories,
467
+ owning_session_id,
468
+ parent_session_id,
469
+ latest_own_index,
470
+ tally,
471
+ read_session,
472
+ read_raw,
473
+ read_optional,
474
+ missing_message,
475
+ home_directory
476
+ };
477
+
478
+ // scripts/time-runtime/time-hook-transcript.ts
479
+ var { TRANSCRIPT_EXTENSION: TRANSCRIPT_EXTENSION2 } = cost_transcript;
480
+ var AGENT_PREFIX = "agent-";
481
+ var AGENT_ID_PATTERN = /^[\w-]+$/u;
482
+ function is_agent_id(value) {
483
+ return typeof value === "string" && AGENT_ID_PATTERN.test(value);
484
+ }
485
+ function fork_path(transcript_path, agent_id) {
486
+ const directory = path3.dirname(transcript_path);
487
+ const session_id = path3.basename(transcript_path, TRANSCRIPT_EXTENSION2);
488
+ const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION2}`;
489
+ return path3.join(cost_transcript.unit_directory(directory, session_id), file_name);
490
+ }
491
+ function transcript_of(transcript_path, agent_id) {
492
+ if (!is_agent_id(agent_id)) return transcript_path;
493
+ if (!transcript_path.endsWith(TRANSCRIPT_EXTENSION2)) return transcript_path;
494
+ return fork_path(transcript_path, agent_id);
495
+ }
496
+ var time_hook_transcript = {
497
+ fork_path,
498
+ transcript_of
499
+ };
500
+
501
+ // scripts/time-runtime/time-density-hook.ts
502
+ import { closeSync, fstatSync, openSync, readSync } from "node:fs";
503
+
504
+ // scripts/josh/stamp-file.ts
505
+ import { createHash, randomUUID } from "node:crypto";
506
+ import { lstatSync, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
507
+ import path5 from "node:path";
508
+
509
+ // scripts/init/init-paths.ts
510
+ import path4 from "node:path";
511
+ import { fileURLToPath } from "node:url";
512
+ var PACKAGE_DIR = path4.join(path4.dirname(fileURLToPath(import.meta.url)), "..", "..");
513
+ var PROJECT_ROOT = process.cwd();
514
+
515
+ // scripts/josh/platform-temporary.ts
516
+ import { accessSync, constants } from "node:fs";
517
+ import { tmpdir } from "node:os";
518
+ var POSIX_TEMP_ROOT = "/tmp";
519
+ var WINDOWS_PLATFORM = "win32";
520
+ function is_writable_directory(directory) {
521
+ try {
522
+ accessSync(directory, constants.W_OK);
523
+ return true;
524
+ } catch {
525
+ return false;
526
+ }
527
+ }
528
+ function resolve_temporary_root(platform, can_write = is_writable_directory) {
529
+ if (platform === WINDOWS_PLATFORM) return tmpdir();
530
+ return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
531
+ }
532
+ var PLATFORM_TEMP_ROOT = resolve_temporary_root(process.platform);
533
+
534
+ // scripts/josh/stamp-file.ts
535
+ var HASH_ALGORITHM = "sha256";
536
+ var STAMP_SUFFIX = ".json";
537
+ var STAMP_KEY_LENGTH = 16;
538
+ var STAMP_FILE_MODE = 384;
539
+ var STAMP_WRITE_FLAG = "wx";
540
+ var STAMP_CREATE_FLAG = STAMP_WRITE_FLAG;
541
+ var EXISTS_ERROR_CODE = "EEXIST";
542
+ var ACCOUNT_KEY_SEPARATOR = ":";
543
+ function digest(content) {
544
+ return createHash(HASH_ALGORITHM).update(content).digest("hex");
545
+ }
546
+ function account_key() {
547
+ return String(process.getuid?.() ?? "");
548
+ }
549
+ function stamp_path(prefix, root = PACKAGE_DIR, suffix = STAMP_SUFFIX) {
550
+ const key = digest(`${account_key()}${ACCOUNT_KEY_SEPARATOR}${root}`).slice(0, STAMP_KEY_LENGTH);
551
+ return path5.join(PLATFORM_TEMP_ROOT, `${prefix}${key}${suffix}`);
552
+ }
553
+ function write_exclusively(target, content) {
554
+ rmSync(target, { force: true });
555
+ writeFileSync(target, content, { flag: STAMP_WRITE_FLAG, mode: STAMP_FILE_MODE });
556
+ return target;
557
+ }
558
+ function write_stamp(target, payload) {
559
+ return write_exclusively(target, JSON.stringify(payload));
560
+ }
561
+ function replace_stamp(target, payload) {
562
+ const temporary = `${target}.${String(process.pid)}.${randomUUID()}`;
563
+ try {
564
+ writeFileSync(temporary, JSON.stringify(payload), {
565
+ flag: STAMP_CREATE_FLAG,
566
+ mode: STAMP_FILE_MODE
567
+ });
568
+ renameSync(temporary, target);
569
+ return target;
570
+ } finally {
571
+ rmSync(temporary, { force: true });
572
+ }
573
+ }
574
+ function write_text_stamp(target, text) {
575
+ return write_exclusively(target, text);
576
+ }
577
+ function create_stamp(target, payload) {
578
+ try {
579
+ writeFileSync(target, JSON.stringify(payload), {
580
+ flag: STAMP_CREATE_FLAG,
581
+ mode: STAMP_FILE_MODE
582
+ });
583
+ return true;
584
+ } catch (error) {
585
+ if (error.code === EXISTS_ERROR_CODE) return false;
586
+ throw error;
587
+ }
588
+ }
589
+ function remove_stamp(target) {
590
+ rmSync(target, { force: true });
591
+ }
592
+ function is_own_regular_file(source) {
593
+ const stats = lstatSync(source);
594
+ if (!stats.isFile()) return false;
595
+ const uid = process.getuid?.();
596
+ return uid === void 0 || stats.uid === uid;
597
+ }
598
+ function read_stamp_text(source) {
599
+ try {
600
+ if (!is_own_regular_file(source)) return void 0;
601
+ return readFileSync2(source, "utf8");
602
+ } catch {
603
+ return void 0;
604
+ }
605
+ }
606
+ var stamp_file = {
607
+ create_stamp,
608
+ digest,
609
+ is_own_regular_file,
610
+ read_stamp_text,
611
+ replace_stamp,
612
+ remove_stamp,
613
+ stamp_path,
614
+ write_stamp,
615
+ write_text_stamp
616
+ };
617
+
618
+ // scripts/time-runtime/time-density-hook.ts
619
+ import { z as z5 } from "zod";
620
+
621
+ // scripts/cost-runtime/cost-blocks.ts
622
+ import { z as z2 } from "zod";
623
+ var CONTENT_ITEM_SCHEMA = z2.object({ text: z2.string().nullish() });
624
+ var RESULT_CONTENT_SCHEMA = z2.union([z2.string(), z2.array(CONTENT_ITEM_SCHEMA)]);
625
+ var BLOCK_SCHEMA = z2.object({
626
+ type: z2.string().nullish(),
627
+ text: z2.string().nullish(),
628
+ name: z2.string().nullish(),
629
+ input: z2.unknown().nullish(),
630
+ content: RESULT_CONTENT_SCHEMA.nullish()
631
+ });
632
+ var LINE_CONTENT_SCHEMA = z2.union([z2.string(), z2.array(BLOCK_SCHEMA)]);
633
+ var MESSAGE_SCHEMA2 = z2.object({ content: LINE_CONTENT_SCHEMA.nullish() });
634
+ var CONTENT_LINE_SCHEMA = z2.object({ type: z2.string(), message: MESSAGE_SCHEMA2.nullish() });
635
+ var TEXT_TYPE = "text";
636
+ var TOOL_USE_TYPE = "tool_use";
637
+ var TOOL_RESULT_TYPE = "tool_result";
638
+ var BASH_TOOL = "Bash";
639
+ var COMMAND_KEY = "command";
640
+ function json_of(value) {
641
+ return value === void 0 || value === null ? "" : JSON.stringify(value);
642
+ }
643
+ function split_bash_input(input) {
644
+ if (!json_value.is_record(input)) return { command: "", rest: json_of(input) };
645
+ const command = input[COMMAND_KEY];
646
+ const rest = Object.entries(input).filter(([key]) => key !== COMMAND_KEY);
647
+ return {
648
+ command: typeof command === "string" ? command : "",
649
+ rest: json_of(Object.fromEntries(rest))
650
+ };
651
+ }
652
+ function to_tool_use(block) {
653
+ const tool_name = block.name ?? "";
654
+ const is_bash = tool_name === BASH_TOOL;
655
+ const { command, rest } = is_bash ? split_bash_input(block.input) : { command: "", rest: json_of(block.input) };
656
+ return { type: TOOL_USE_TYPE, tool_name, command, text: rest };
657
+ }
658
+ function result_text(content) {
659
+ if (typeof content === "string") return content;
660
+ return content.map((item) => item.text ?? "").join("");
661
+ }
662
+ function to_plain_block(block) {
663
+ const base = { type: block.type ?? "", tool_name: "", command: "" };
664
+ const text = block.type === TOOL_RESULT_TYPE ? result_text(block.content ?? "") : block.text ?? "";
665
+ return { ...base, text };
666
+ }
667
+ function to_block(block) {
668
+ return block.type === TOOL_USE_TYPE ? to_tool_use(block) : to_plain_block(block);
669
+ }
670
+ function to_blocks(content) {
671
+ if (typeof content === "string") {
672
+ return [{ type: TEXT_TYPE, tool_name: "", command: "", text: content }];
673
+ }
674
+ return content.map((block) => to_block(block));
675
+ }
676
+ function content_of(line) {
677
+ const parsed = CONTENT_LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line));
678
+ return parsed.success ? parsed.data.message?.content ?? void 0 : void 0;
679
+ }
680
+ function parse_line2(line) {
681
+ const content = content_of(line);
682
+ return content === void 0 ? [] : to_blocks(content);
683
+ }
684
+ function parse_content(text) {
685
+ return text.split("\n").flatMap((line) => parse_line2(line));
686
+ }
687
+ var cost_blocks = {
688
+ BASH_TOOL,
689
+ TEXT_TYPE,
690
+ TOOL_USE_TYPE,
691
+ TOOL_RESULT_TYPE,
692
+ parse_line: parse_line2,
693
+ parse_content
694
+ };
695
+
696
+ // scripts/time-runtime/time-phase-names.ts
697
+ var GATE_PHASE = "gate";
698
+ var PR_PHASE = "pr";
699
+ var MERGE_PHASE = "merge";
700
+ var GATE_COMMAND2 = "josh gate";
701
+ var COMMAND_PHASES = /* @__PURE__ */ new Map([
702
+ [GATE_COMMAND2, GATE_PHASE],
703
+ ["josh git", PR_PHASE],
704
+ ["josh pr", PR_PHASE],
705
+ ["josh followup", MERGE_PHASE]
706
+ ]);
707
+
708
+ // scripts/josh/josh-commands-issue.ts
709
+ var ISSUES_WITH_REPO = "<issue...> [--repo <owner/repo>]";
710
+ var ISSUE_COMMANDS = {
711
+ "issue:read": {
712
+ script: "scripts/issue/issue-read-cli.ts",
713
+ description: "Print each issue's title, body and every comment on it, in one call",
714
+ category: "AI tools",
715
+ reference: ["<issue...>", "automation", ["network"]]
716
+ },
717
+ "issue:state": {
718
+ script: "scripts/issue/issue-state-cli.ts",
719
+ description: "Print each issue's state and labels, in the spelling the documents compare against",
720
+ category: "AI tools",
721
+ reference: [ISSUES_WITH_REPO, "automation", ["network"]]
722
+ },
723
+ "issue:scout": {
724
+ script: "scripts/issue/issue-scout-cli.ts",
725
+ description: "Before filing: say whether an issue like this exists and which epic it belongs to",
726
+ category: "AI tools",
727
+ reference: ["<title> [--body <summary>]", "automation", ["network"]]
728
+ },
729
+ "issue:fold": {
730
+ script: "scripts/issue/issue-fold-cli.ts",
731
+ description: "Before a second filing: say whether findings from this session fold into one issue",
732
+ category: "AI tools",
733
+ reference: ["<title>... [--not-separable] [--json]", "automation", ["none"]]
734
+ },
735
+ "issue:cite": {
736
+ script: "scripts/issue/issue-cite-cli.ts",
737
+ description: "Print the paste-ready number-link citation line for each issue, in one call",
738
+ category: "AI tools",
739
+ reference: [ISSUES_WITH_REPO, "automation", ["network"]]
740
+ }
741
+ };
742
+
743
+ // scripts/josh/josh-commands-lane.ts
744
+ var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
745
+ var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
746
+ var ISSUE_WITH_OPTIONS = "<issue> [options]";
747
+ var LANE_COMMANDS = {
748
+ "lane:open": {
749
+ ...LANE_ARGUMENTS,
750
+ description: "Open a lane: a linked work tree with its own branch and its own port seed",
751
+ category: "AI tools",
752
+ reference: [ISSUE_WITH_OPTIONS, "automation", ["files", "git"]],
753
+ default_script_arguments: ["open"]
754
+ },
755
+ "lane:close": {
756
+ ...LANE_ARGUMENTS,
757
+ description: "Close a lane, leaving no work tree, branch or directory behind",
758
+ category: "AI tools",
759
+ reference: ["<issue>", "automation", ["files", "git"]],
760
+ default_script_arguments: ["close"]
761
+ },
762
+ "lane:list": {
763
+ ...LANE_ARGUMENTS,
764
+ description: "List the open lanes: which issue, which ports, and where each one is",
765
+ category: "AI tools",
766
+ reference: ["", "automation", ["none"]],
767
+ default_script_arguments: ["list"]
768
+ },
769
+ "lane:prune": {
770
+ ...LANE_ARGUMENTS,
771
+ description: "Close every lane an interruption left without its work tree",
772
+ category: "AI tools",
773
+ reference: ["", "automation", ["files", "git"]],
774
+ default_script_arguments: ["prune"]
775
+ },
776
+ "lane:output": {
777
+ ...LANE_ARGUMENTS,
778
+ description: "Record, or read back, where the unit running a lane\u2019s child writes",
779
+ category: "AI tools",
780
+ reference: ["<issue> [path]", "automation", ["files"]],
781
+ default_script_arguments: ["output"]
782
+ },
783
+ "lane:dispatch": {
784
+ ...LANE_ARGUMENTS,
785
+ description: "Start a lane\u2019s child as a detached process that outlives this session",
786
+ category: "AI tools",
787
+ reference: ["<issue> <prompt>", "automation", ["processes"]],
788
+ default_script_arguments: ["dispatch"]
789
+ },
790
+ "lane:await": {
791
+ ...LANE_ARGUMENTS,
792
+ description: "Block until any of the named in-flight lane children completes; prints which one finished",
793
+ category: "AI tools",
794
+ reference: ["<issue> [<issue>...]", "automation", ["processes"]],
795
+ default_script_arguments: ["await"]
796
+ },
797
+ "lane:launch": {
798
+ script: "scripts/lane/lane-launch-cli.ts",
799
+ description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
800
+ category: "AI tools",
801
+ reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
802
+ }
803
+ };
804
+
805
+ // scripts/josh/josh-commands-split.ts
806
+ var SPLIT_COMMANDS = {
807
+ "split:assess": {
808
+ script: "scripts/split/split-assess-cli.ts",
809
+ description: "Measure the branch change size (tests excluded) and answer the split assessment size question: split | single",
810
+ category: "AI tools",
811
+ reference: ["[--json]", "automation", ["none"]]
812
+ }
813
+ };
814
+
815
+ // scripts/josh/josh-commands-ai.ts
816
+ var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
817
+ var ISSUE_WITH_OPTIONS2 = "<issue> [options]";
818
+ var AI_COMMANDS = {
819
+ ...ISSUE_COMMANDS,
820
+ "pkg:scout": {
821
+ script: "scripts/package/package-scout-cli.ts",
822
+ description: "Rank package candidates by measured metrics so the Package-First tier decision is read, not judged",
823
+ category: "AI tools",
824
+ reference: ["<keywords> [--size <n>]", "automation", ["network"]]
825
+ },
826
+ "stash:pop": {
827
+ script: "scripts/git/stash-pop-cli.ts",
828
+ description: "Pop the stash matching this message, not whichever a shared stack has on top",
829
+ category: "AI tools",
830
+ reference: ["<message>", "automation", ["git"]]
831
+ },
832
+ epic: {
833
+ script: "scripts-ai/epic.ts",
834
+ description: "Create an epic issue from its child issue numbers",
835
+ category: "AI tools",
836
+ reference: ["<title> <issue...> [--ordered]", "automation", ["network"]]
837
+ },
838
+ "epic:next": {
839
+ script: "scripts/epic/epic-next.ts",
840
+ description: "List an epic's runnable children, bundled per repository",
841
+ category: "AI tools",
842
+ reference: ["<epic>", "automation", ["network"]]
843
+ },
844
+ "epic:bundle": {
845
+ script: "scripts/epic/epic-bundle-cli.ts",
846
+ description: "Say whether a newly filed issue belongs with ones already in the backlog",
847
+ category: "AI tools",
848
+ reference: ["<issue>", "automation", ["network"]]
849
+ },
850
+ "epic:audit": {
851
+ script: "scripts/epic/epic-audit-cli.ts",
852
+ description: "Audit an epic's children against each other for contradictions",
853
+ category: "AI tools",
854
+ reference: ["<epic>", "automation", ["network"]]
855
+ },
856
+ "epic:check": {
857
+ script: "scripts-ai/epic-check.ts",
858
+ description: "Check an epic issue against the tracking requirements",
859
+ category: "AI tools",
860
+ reference: ["<epic>", "automation", ["network"]]
861
+ },
862
+ "auto-ok:next": {
863
+ script: "scripts/auto-ok/auto-ok-cli.ts",
864
+ description: "Print the next opted-in issue an unattended run may pick up outside an epic",
865
+ category: "AI tools",
866
+ reference: ["[--exclude <n>[,<n>...]] [--label <name>]", "automation", ["network"]]
867
+ },
868
+ "backlog:next": {
869
+ script: "scripts/backlog/backlog-next.ts",
870
+ description: "Order the whole opted-in backlog: auto-ok issues and the descendants of auto-ok epics, transitively through nested epics",
871
+ category: "AI tools",
872
+ reference: ["[--exclude <n>[,<n>...]] [--repo <owner/repo>]", "automation", ["network"]]
873
+ },
874
+ "backlog:offer": {
875
+ script: "scripts/backlog/backlog-offer-cli.ts",
876
+ description: "Collapse a backlogrun loop-head event into one call: read backlog:next, ask backlog:budget, return the verdict and any issues to start",
877
+ category: "AI tools",
878
+ reference: ["[options]", "automation", ["network"]]
879
+ },
880
+ "backlog:plan": {
881
+ script: "scripts/backlog/backlog-plan-cli.ts",
882
+ description: "Print the whole backlog as a plan: ready now, waiting on what, waiting on a person, out of scope",
883
+ category: "AI tools",
884
+ reference: ["[issue...] [--only]", "automation", ["network"]]
885
+ },
886
+ "backlog:budget": {
887
+ script: "scripts/backlog/backlog-budget-cli.ts",
888
+ description: "Say whether a backlogrun may start more work, keep watching, or finish",
889
+ category: "AI tools",
890
+ reference: ["[options]", "automation", ["none"]]
891
+ },
892
+ cost: {
893
+ script: "scripts/cost-runtime/cost-cli.ts",
894
+ description: "Report a run's token and credit cost from Claude Code's session transcripts",
895
+ category: "AI tools",
896
+ reference: ["[--cut|--over]", "automation", ["none"]]
897
+ },
898
+ "doc:section": {
899
+ script: "scripts/document/document-section-cli.ts",
900
+ description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
901
+ category: "AI tools",
902
+ reference: ["<file> <heading>", "automation", ["none"]]
903
+ },
904
+ "read:set": {
905
+ script: "scripts/document/read-set-cli.ts",
906
+ description: "Print what an entry point reads before it starts, and what that read costs",
907
+ category: "AI tools",
908
+ reference: ["[<entry>] [--json]", "automation", ["none"]]
909
+ },
910
+ "doc:read": {
911
+ script: "scripts/document/document-read-cli.ts",
912
+ description: "Read a whole document safely: print it, or point at the Read tool when over the Bash cap",
913
+ category: "AI tools",
914
+ reference: ["<file>", "automation", ["none"]]
915
+ },
916
+ "read:files": {
917
+ script: "scripts/document/read-files-cli.ts",
918
+ description: "Read several files in one call so edit targets fold into one turn",
919
+ category: "AI tools",
920
+ reference: ["<path> [<path> ...]", "automation", ["none"]]
921
+ },
922
+ time: {
923
+ script: "scripts/time/time-cli.ts",
924
+ description: "Report where a run's wall clock went: model wait, tool execution, human wait",
925
+ category: "AI tools",
926
+ reference: ["[options]", "maintainer", ["none"]],
927
+ // Kit-only: it measures kit's own development runs and its report modules live under the
928
+ // undistributed `scripts/time/`, so it means nothing in a consumer project and is dropped from a
929
+ // consumer's help (joshuafolkken/kit#1997). The runtime analysis hooks and guards rely on stays
930
+ // distributed under `scripts/time-runtime/`.
931
+ is_kit_only: true
932
+ },
933
+ "review:brief": {
934
+ script: "scripts/review/review-brief-cli.ts",
935
+ description: "Print the whole /code-review invocation: level, what the gate already proved, target (--level-only for the level alone)",
936
+ category: "AI tools",
937
+ reference: ["[--round <1|2>] | --level-only [--staged] [--json]", "automation", ["files"]]
938
+ },
939
+ "review:attest": {
940
+ script: "scripts/review/review-attest-cli.ts",
941
+ description: "Record, or verify, which checkout a /code-review actually read",
942
+ category: "AI tools",
943
+ reference: ["<nonce> | --check", "automation", ["files"]]
944
+ },
945
+ "review:round2": {
946
+ script: "scripts/review/review-round2-cli.ts",
947
+ description: "Say whether the second /code-review round is due, or may be skipped entirely",
948
+ category: "AI tools",
949
+ reference: ["[--round-1-closed] [--json]", "automation", ["none"]]
950
+ },
951
+ delegate: {
952
+ script: "scripts/delegation/delegation-cli.ts",
953
+ description: "Say whether a run step may go to a cheaper execution tier",
954
+ category: "AI tools",
955
+ reference: ["<step> | --list", "automation", ["none"]]
956
+ },
957
+ "run:hold": {
958
+ script: RUN_HOLD_SCRIPT,
959
+ description: "Claim this working tree for a run, or say which run already holds it",
960
+ category: "AI tools",
961
+ reference: ["[issue]", "automation", ["files"]]
962
+ },
963
+ "run:release": {
964
+ script: RUN_HOLD_SCRIPT,
965
+ description: "Release this working tree's run record",
966
+ category: "AI tools",
967
+ reference: ["[issue|--force]", "automation", ["files"]],
968
+ default_script_arguments: ["--release"]
969
+ },
970
+ "run:carry": {
971
+ script: "scripts/run/run-carry-cli.ts",
972
+ description: "Carry one invocation\u2019s budget across its own session cuts",
973
+ category: "AI tools",
974
+ reference: ["<operation> [arguments...]", "automation", ["files"]]
975
+ },
976
+ "run:wake": {
977
+ script: "scripts/run/run-wake-cli.ts",
978
+ // `.env` rather than the ambient environment:
979
+ // the failure warning needs the Telegram credentials, the same
980
+ // reasons `notify` and `followup` carry these flags.
981
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
982
+ description: "Wake the next session of a cut backlogrun from outside the conversation",
983
+ category: "AI tools",
984
+ reference: ["[options]", "automation", ["processes", "notifications"]]
985
+ },
986
+ "run:cut": {
987
+ script: "scripts/run/run-cut-cli.ts",
988
+ description: "Cut a lane child before the gate and resume a fresh process",
989
+ category: "AI tools",
990
+ reference: ["[--resume] <issue>", "automation", ["files"]]
991
+ },
992
+ "run:liveness": {
993
+ script: "scripts/run/run-liveness-cli.ts",
994
+ description: "Say whether a delegated unit is still working, or stopped without reporting",
995
+ category: "AI tools",
996
+ reference: ["<issue> --output <path> [options]", "automation", ["processes"]]
997
+ },
998
+ "run:ending": {
999
+ script: "scripts/run/run-ending-cli.ts",
1000
+ description: "Classify how a dispatched lane child ended (merged, cut, abandoned, unreadable)",
1001
+ category: "AI tools",
1002
+ reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
1003
+ },
1004
+ "run:progress": {
1005
+ script: "scripts/run/run-progress-cli.ts",
1006
+ description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
1007
+ category: "AI tools",
1008
+ reference: ["[--wait|--mark]", "automation", ["files"]]
1009
+ },
1010
+ "run:prep": {
1011
+ script: "scripts/run/run-prep-cli.ts",
1012
+ description: "Bundle a run\u2019s pre-edit reads: body, comments, state, dependency scope",
1013
+ category: "AI tools",
1014
+ reference: ["<issue>", "automation", ["network"]]
1015
+ },
1016
+ "run:status": {
1017
+ script: "scripts/run/run-status-cli.ts",
1018
+ description: "Bundle a run\u2019s read-only status: issue state, cost verdict, carry counters",
1019
+ category: "AI tools",
1020
+ reference: ["<issue> [--repo <owner/repo>]", "automation", ["network"]]
1021
+ },
1022
+ "run:next": {
1023
+ script: "scripts/run/run-next-cli.ts",
1024
+ description: "Print the next step a fullrun takes, computed from the run\u2019s state",
1025
+ category: "AI tools",
1026
+ reference: ["<issue>", "automation", ["network"]]
1027
+ },
1028
+ "run:step": {
1029
+ script: "scripts/run/run-step-cli.ts",
1030
+ description: "Print the run\u2019s next single action, computed from the event stream, carry record and issue state",
1031
+ category: "AI tools",
1032
+ reference: ["<issue>", "automation", ["network", "files"]]
1033
+ },
1034
+ "repo:party": {
1035
+ script: "scripts/discovery/repo-party-cli.ts",
1036
+ description: "Say whether a repository is first-party or third-party by owner equality (computed, not judged)",
1037
+ category: "AI tools",
1038
+ reference: ["[<owner/repo>]", "automation", ["none"]]
1039
+ },
1040
+ "run:merge": {
1041
+ script: "scripts/run/run-merge-cli.ts",
1042
+ description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
1043
+ category: "AI tools",
1044
+ reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
1045
+ },
1046
+ "run:review": {
1047
+ script: "scripts/run/run-review-cli.ts",
1048
+ description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
1049
+ category: "AI tools",
1050
+ reference: ["[--join]", "automation", ["processes", "files"]]
1051
+ },
1052
+ "run:event": {
1053
+ script: "scripts/run/run-event-cli.ts",
1054
+ description: "Append to or read the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --last)",
1055
+ category: "AI tools",
1056
+ reference: ["--append <kind> <text> | --from|--follow <n> | --last", "automation", ["files"]]
1057
+ },
1058
+ "run:report": {
1059
+ script: "scripts/run/run-report-cli.ts",
1060
+ description: "Generate the session-facing report from the run\u2019s event stream (merges, parks, cuts) with the release tail \u2014 the same text josh notify sends",
1061
+ category: "AI tools",
1062
+ reference: ["", "automation", ["files", "network"]]
1063
+ },
1064
+ ...LANE_COMMANDS,
1065
+ "investigation:guard": {
1066
+ script: "scripts/delegation/investigation-guard.ts",
1067
+ description: "Claude Code hook: refuse a read once the unedited-read threshold is reached again (reads the tool call on stdin)",
1068
+ category: "AI tools",
1069
+ reference: ["", "automation", ["none"]]
1070
+ // **No `tsx_arguments`, for the reason `batch:guard` declares none** (joshuafolkken/kit#1342):
1071
+ // declaring any disqualifies a command from in-process dispatch, and this one runs in front of
1072
+ // every read. The script calls `process.loadEnvFile` itself instead, through
1073
+ // `hook-decision.ts`.
1074
+ },
1075
+ "rule:guard": {
1076
+ script: "scripts/rules/rule-guard.ts",
1077
+ description: "Claude Code hook: deliver a trigger-delivered rule at the call that binds it (reads the tool call on stdin)",
1078
+ category: "AI tools",
1079
+ reference: ["", "automation", ["none"]]
1080
+ // **No `tsx_arguments`, for the reason the other two guards declare none**
1081
+ // (joshuafolkken/kit#1342): declaring any disqualifies a command from in-process dispatch, and
1082
+ // this one runs in front of every shell call.
1083
+ },
1084
+ "run:watcher:guard": {
1085
+ script: "scripts/run/run-watcher-guard-cli.ts",
1086
+ description: "Guard: exits non-zero when lane children are in-flight but the watcher has not pinged recently",
1087
+ category: "AI tools",
1088
+ reference: ["", "automation", ["none"]]
1089
+ },
1090
+ ...SPLIT_COMMANDS,
1091
+ "oracle:list": {
1092
+ script: "scripts/rules/oracle-list-cli.ts",
1093
+ description: "Print the decision oracles \u2014 commands that answer a rule question mechanically",
1094
+ category: "AI tools",
1095
+ reference: ["", "automation", ["none"]]
1096
+ },
1097
+ eval: {
1098
+ script: "scripts/eval/eval-run.ts",
1099
+ description: "Run the agent rule-compliance scenarios (real Claude sessions)",
1100
+ category: "AI tools",
1101
+ reference: ["[scenario...]", "maintainer", ["processes", "network"]],
1102
+ // Kit-only: it replays kit's own distributed rules against real Claude sessions, so it means
1103
+ // nothing in a consumer project and is dropped from a consumer's help (joshuafolkken/kit#1988).
1104
+ is_kit_only: true
1105
+ }
1106
+ };
1107
+
1108
+ // scripts/josh/josh-commands-clone.ts
1109
+ var CLONE_COMMANDS = {
1110
+ "clone:scan": {
1111
+ script: "scripts/clone/clone-scan-cli.ts",
1112
+ description: "Count code duplication across files and first-party repositories, printing each clone as file:line pairs",
1113
+ category: "AI tools",
1114
+ reference: ["", "automation", ["files"]]
1115
+ }
1116
+ };
1117
+
1118
+ // scripts/josh/josh-commands-development.ts
1119
+ var FILE_ARGUMENTS = "[files...]";
1120
+ var REQUIRED_FILE_ARGUMENTS = "<files...>";
1121
+ var FILTER_ARGUMENTS = "[filters...]";
1122
+ var MATCH_ARGUMENTS = "[--match]";
1123
+ var PATH_ARGUMENTS = "<path...>";
1124
+ var DEV_COMMANDS = {
1125
+ [GATE_COMMAND]: {
1126
+ script: "scripts/gate/verification-gate.ts",
1127
+ description: "Run lint, type check, spell check and unit tests concurrently",
1128
+ category: "Development",
1129
+ reference: ["[--verbose|--force|--no-unit]", "developer", ["files", "processes"]]
1130
+ },
1131
+ lint: {
1132
+ script: "scripts/lint/lint-parallel.ts",
1133
+ description: "Check code with prettier and eslint",
1134
+ category: "Development",
1135
+ reference: ["", "developer", ["processes"]]
1136
+ },
1137
+ "lint:related": {
1138
+ script: "scripts/lint/lint-related.ts",
1139
+ description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
1140
+ category: "Development",
1141
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1142
+ },
1143
+ lines: {
1144
+ script: "scripts/lines/lines-command.ts",
1145
+ description: "Print a file's code lines against the max-lines limit and the headroom left",
1146
+ category: "Development",
1147
+ reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
1148
+ },
1149
+ "refactor:scan": {
1150
+ script: "scripts/refactor/refactor-scan-cli.ts",
1151
+ description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
1152
+ category: "Development",
1153
+ reference: ["", "automation", ["processes"]]
1154
+ },
1155
+ bytes: {
1156
+ script: "scripts/bytes/bytes-command.ts",
1157
+ description: "Print an agent-read document's byte size against its ceiling and the headroom left",
1158
+ category: "Development",
1159
+ reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
1160
+ },
1161
+ "rule:value": {
1162
+ script: "scripts/rules/rule-value-cli.ts",
1163
+ description: "Print each delivered rule's unaided compliance \u2014 runs reached, kept rate, refusals",
1164
+ category: "AI tools",
1165
+ reference: ["", "developer", ["none"]]
1166
+ },
1167
+ format: {
1168
+ // prettier first here, unlike `format:edited`, and deliberately: `eslint --fix` exits 1
1169
+ // whenever a non-autofixable error remains, so putting it first behind `&&` would mean one
1170
+ // unused variable anywhere in the tree stops prettier from running at all.
1171
+ shell: [
1172
+ "sh",
1173
+ "-c",
1174
+ `pnpm exec prettier --write . && pnpm exec eslint . --fix ${ESLINT_CACHE_FLAGS.join(" ")}`
1175
+ ],
1176
+ description: "Format code with prettier and eslint",
1177
+ category: "Development",
1178
+ reference: ["", "developer", ["files", "processes"]]
1179
+ },
1180
+ "format:edited": {
1181
+ script: "scripts/hooks/format-edited-file.ts",
1182
+ description: "Claude Code hook: format the file just edited (reads the tool call on stdin)",
1183
+ category: "Development",
1184
+ reference: ["", "automation", ["files", "processes"]]
1185
+ },
1186
+ "batch:guard": {
1187
+ script: "scripts/hooks/batch-guard.ts",
1188
+ description: "Claude Code hook: refuse a third consecutive single-call turn (reads the tool call on stdin)",
1189
+ category: "Development",
1190
+ reference: ["", "automation", ["none"]]
1191
+ // **No `tsx_arguments`, deliberately.** `JOSH_BATCH_GUARD` is a per-machine preference kept in
1192
+ // `.env`, which every other command reads through `OPTIONAL_ENV_FILE_FLAGS` — but declaring any
1193
+ // `tsx_arguments` disqualifies a command from in-process dispatch (`josh-in-process.ts`), and
1194
+ // this one runs before every `Bash` call. That is the hot path joshuafolkken/kit#1342 took a
1195
+ // second ~0.16 s tsx start off. The script calls `process.loadEnvFile` itself instead, which is
1196
+ // node's own `--env-file` parser with node's own precedence.
1197
+ },
1198
+ "pretool:guard": {
1199
+ script: "scripts/hooks/pretool-guard.ts",
1200
+ description: "Claude Code hook: the batch, investigation and rule guards in one process (reads the tool call on stdin)",
1201
+ category: "Development",
1202
+ reference: ["", "automation", ["none"]]
1203
+ // **No `tsx_arguments`, deliberately**, the same as `batch:guard` above: this is the one
1204
+ // PreToolUse hook consumers run before every guarded call, so it must stay eligible for
1205
+ // in-process dispatch rather than pay a second tsx start. Each guard it composes loads `.env`
1206
+ // through the shared loader.
1207
+ },
1208
+ "stop:guard": {
1209
+ script: "scripts/hooks/stop-guard.ts",
1210
+ description: "Claude Code Stop hook: deliver the three stop-time rules \u2014 hold notify/release and issue citation (reads the Stop payload on stdin)",
1211
+ category: "Development",
1212
+ reference: ["", "automation", ["none"]]
1213
+ // **No `tsx_arguments`, deliberately**, the same as `pretool:guard` above: this runs at every
1214
+ // turn end, so it must stay eligible for in-process dispatch rather than pay a second tsx start.
1215
+ // It loads `.env` through the shared `hook-decision.ts` loader.
1216
+ },
1217
+ "session:lang": {
1218
+ script: "scripts/josh/session-language-cli.ts",
1219
+ description: "Claude Code hook: print the resolved JOSH_SESSION_LANG (defaults to ja) for the session context",
1220
+ category: "Development",
1221
+ reference: ["", "automation", ["none"]]
1222
+ // **No `tsx_arguments`, deliberately**, the same as `batch:guard` above: this runs on every
1223
+ // `UserPromptSubmit`, so it must stay eligible for in-process dispatch rather than pay a second
1224
+ // tsx start each turn. It calls `process.loadEnvFile` itself through the shared loader.
1225
+ },
1226
+ "cspell:dot": {
1227
+ script: "scripts/lint/cspell-cached.ts",
1228
+ description: "Run spell check including dotfiles",
1229
+ category: "Development",
1230
+ reference: ["", "developer", ["processes"]]
1231
+ },
1232
+ "test:unit": {
1233
+ script: "scripts/test/test-unit-guard.ts",
1234
+ description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
1235
+ category: "Development",
1236
+ reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
1237
+ },
1238
+ "test:related": {
1239
+ script: "scripts/test/test-related.ts",
1240
+ description: "Run only the unit tests related to the changed files (full suite on fallback)",
1241
+ category: "Development",
1242
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1243
+ },
1244
+ "test:declared": {
1245
+ script: "scripts/test/test-declared.ts",
1246
+ description: "Report whether the working-tree change needs a test (required/exempt/satisfied); --match checks Step 0 declarations on stdin",
1247
+ category: "Development",
1248
+ reference: [MATCH_ARGUMENTS, "developer", ["processes"]]
1249
+ },
1250
+ disposition: {
1251
+ script: "scripts/review/disposition-cli.ts",
1252
+ description: "Say whether a review finding reaches a runtime path (runtime) or is inert (non-runtime)",
1253
+ category: "AI tools",
1254
+ reference: [PATH_ARGUMENTS, "automation", ["none"]]
1255
+ },
1256
+ "e2e:retry-check": {
1257
+ script: "scripts/test/e2e-retry-check.ts",
1258
+ description: "Report whether the preview server crashed during a failed E2E attempt (CI)",
1259
+ category: "Development",
1260
+ reference: ["", "automation", ["none"]]
1261
+ },
1262
+ "test:e2e": {
1263
+ script: "scripts/test/test-e2e-guard.ts",
1264
+ description: "Run E2E tests with Playwright (skips when absent or no e2e files)",
1265
+ category: "Development",
1266
+ reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
1267
+ },
1268
+ test: {
1269
+ shell: ["sh", "-c", "pnpm josh test:unit && pnpm josh test:e2e"],
1270
+ description: "Run unit and E2E tests",
1271
+ category: "Development",
1272
+ reference: ["", "developer", ["processes"]],
1273
+ argument_targets: ["test:unit", "test:e2e"]
1274
+ },
1275
+ check: {
1276
+ shell: [...PE, "tsc", "--noEmit", ...TS_CACHE_FLAGS],
1277
+ description: "Type-check TypeScript project",
1278
+ category: "Development",
1279
+ reference: ["[arguments...]", "developer", ["processes"]]
1280
+ },
1281
+ port: {
1282
+ script: "scripts/ports/port-command.ts",
1283
+ description: "Print the PORT_SEED-resolved dev or preview port",
1284
+ category: "Development",
1285
+ reference: ["<dev|preview>", "developer", ["none"]]
1286
+ }
1287
+ };
1288
+
1289
+ // scripts/josh/josh-commands-hooks.ts
1290
+ var HOOKS_COMMANDS = {
1291
+ "prevent-main-commit": {
1292
+ script: "scripts/hooks/prevent-main-commit.ts",
1293
+ description: "Git hook: block commits to main",
1294
+ category: "Git hooks",
1295
+ reference: ["", "automation", ["none"]]
1296
+ },
1297
+ "check-commit-message": {
1298
+ script: "scripts/hooks/check-commit-message.ts",
1299
+ description: "Git hook: validate commit message",
1300
+ category: "Git hooks",
1301
+ reference: ["[<message-file>]", "automation", ["none"]]
1302
+ },
1303
+ "secretlint-scan": {
1304
+ script: "scripts/security/secretlint-scan.ts",
1305
+ description: "Git hook: scan staged files for secrets",
1306
+ category: "Git hooks",
1307
+ reference: ["[paths...]", "automation", ["none"]]
1308
+ },
1309
+ "pre-push-unit": {
1310
+ script: "scripts/hooks/pre-push-unit.ts",
1311
+ description: "Git hook: run unit tests, reusing a green gate recorded on the pushed tree",
1312
+ category: "Git hooks",
1313
+ reference: ["", "automation", ["processes"]]
1314
+ },
1315
+ "pre-commit-type-check": {
1316
+ script: "scripts/gate/pre-commit-type-check.ts",
1317
+ description: "Git hook: type-check, reusing a green gate recorded on the committed tree",
1318
+ category: "Git hooks",
1319
+ reference: ["", "automation", ["processes"]]
1320
+ }
1321
+ };
1322
+
1323
+ // scripts/josh/josh-commands-lint.ts
1324
+ var LINT_COMMANDS = {
1325
+ "issue:lint": {
1326
+ script: "scripts/issue/issue-lint-cli.ts",
1327
+ description: "Check an issue body file for the template's required headings",
1328
+ category: "AI tools",
1329
+ reference: ["<path>", "automation", ["files"]]
1330
+ },
1331
+ "issue:backlinks": {
1332
+ script: "scripts/issue/issue-backlinks-cli.ts",
1333
+ description: "Classify an origin issue\u2019s upstream backlinks: ok, missing, or wrong heading",
1334
+ category: "AI tools",
1335
+ reference: ["<issue>", "automation", ["network"]]
1336
+ },
1337
+ "report:lint": {
1338
+ script: "scripts/report/report-lint-cli.ts",
1339
+ description: "Check a two-layer work summary on stdin against its mechanical format rules",
1340
+ category: "AI tools",
1341
+ reference: ["(reads stdin)", "automation", ["none"]]
1342
+ },
1343
+ cases: {
1344
+ script: "scripts/cases/cases-cli.ts",
1345
+ description: "Read changed paths and print the I/O boundaries crossed and their mandatory abnormal cases: network | process | fs | none",
1346
+ category: "AI tools",
1347
+ reference: ["<path...>", "automation", ["files"]]
1348
+ }
1349
+ };
1350
+
1351
+ // scripts/josh/josh-commands-maintenance.ts
1352
+ var MAINTENANCE_COMMANDS = {
1353
+ doctor: {
1354
+ script: "scripts/doctor/doctor.ts",
1355
+ description: "Diagnose PATH shadowing of the global josh and show the discovered repository map (--fix reclaims a stale shim)",
1356
+ category: "Maintenance",
1357
+ reference: ["[--fix]", "developer", ["files"]],
1358
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1359
+ },
1360
+ overrides: {
1361
+ script: "scripts/overrides/overrides-check.ts",
1362
+ description: "Check pnpm overrides for drift",
1363
+ category: "Maintenance",
1364
+ reference: ["[--save]", "maintainer", ["files"]]
1365
+ },
1366
+ audit: {
1367
+ script: "scripts/security/security-audit.ts",
1368
+ description: "Run security audit",
1369
+ category: "Maintenance",
1370
+ reference: ["", "developer", ["processes"]]
1371
+ },
1372
+ "audit:provision": {
1373
+ script: "scripts/security/security-audit-provision.ts",
1374
+ description: "Install the pinned osv-scanner when the audit cannot find one (no-op if present)",
1375
+ category: "Maintenance",
1376
+ reference: ["", "automation", ["files", "network"]]
1377
+ },
1378
+ "reconcile-templates": {
1379
+ script: "scripts/sync/reconcile-templates.ts",
1380
+ description: "Record template source hashes (--check to verify drift)",
1381
+ category: "Maintenance",
1382
+ reference: ["", "maintainer", ["files"]]
1383
+ },
1384
+ latest: {
1385
+ shell: [
1386
+ "sh",
1387
+ "-c",
1388
+ "export NODE_AUTH_TOKEN=$(gh auth token) && pnpm josh latest:guard && pnpm josh latest:corepack && pnpm josh latest:update && pnpm josh ranges && pnpm josh audit && pnpm josh latest:scope --record"
1389
+ ],
1390
+ description: "Update pnpm, dependencies, and run security audit",
1391
+ category: "Maintenance",
1392
+ reference: ["", "maintainer", ["files", "network", "processes"]],
1393
+ argument_targets: ["latest:corepack", "latest:update", "audit"]
1394
+ },
1395
+ "latest:scope": {
1396
+ script: "scripts/version/latest-scope-cli.ts",
1397
+ description: "Say whether this run has to update dependencies, from when josh latest last finished (--record notes a run)",
1398
+ category: "Maintenance",
1399
+ reference: ["[--record] [--json]", "automation", ["files"]],
1400
+ // `JOSH_LATEST_MAX_AGE_HOURS` is documented as a project setting, so it has to be readable
1401
+ // where the project keeps its settings — a variable that only works when exported from the
1402
+ // shell is one a user follows the documentation for and gets the default from, silently.
1403
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1404
+ },
1405
+ "latest:guard": {
1406
+ script: "scripts/version/latest-lane-guard.ts",
1407
+ description: "Refuse josh latest inside a lane (the update stamp is keyed to the project root)",
1408
+ category: "Maintenance",
1409
+ reference: ["", "automation", ["files"]]
1410
+ },
1411
+ "latest:corepack": {
1412
+ script: "scripts/version/latest-corepack.ts",
1413
+ description: "Update pnpm via corepack to the latest release on the current major",
1414
+ category: "Maintenance",
1415
+ reference: ["", "maintainer", ["files", "network"]]
1416
+ },
1417
+ "latest:update": {
1418
+ script: "scripts/version/latest-update.ts",
1419
+ description: "Update all dependencies to latest",
1420
+ category: "Maintenance",
1421
+ reference: ["", "maintainer", ["files", "network"]]
1422
+ }
1423
+ };
1424
+
1425
+ // scripts/josh/josh-commands-project.ts
1426
+ var PROJECT_COMMANDS = {
1427
+ init: {
1428
+ script: "scripts/init/init.ts",
1429
+ description: "Initialize config in a new project",
1430
+ category: "Project",
1431
+ reference: ["", "developer", ["files", "processes"]]
1432
+ },
1433
+ sync: {
1434
+ script: "scripts/sync/sync.ts",
1435
+ description: "Sync config files",
1436
+ category: "Project",
1437
+ reference: ["", "developer", ["files"]]
1438
+ },
1439
+ "sync:scope": {
1440
+ script: "scripts/sync/managed-config-scope-cli.ts",
1441
+ description: "Say whether this change touches a file josh sync distributes",
1442
+ category: "Project",
1443
+ reference: ["[--staged] [--json]", "automation", ["none"]]
1444
+ },
1445
+ "sonar:hotspots": {
1446
+ script: "scripts/sonar/sonar-hotspots-cli.ts",
1447
+ description: "Fetch SonarCloud hotspots on a pull request and print each one's Step B disposition",
1448
+ category: "Project",
1449
+ reference: ["<PR>", "automation", ["network"]]
1450
+ },
1451
+ "ui:routes": {
1452
+ script: "scripts/ui/ui-routes-cli.ts",
1453
+ description: "List the screenshot-target routes the current change touches",
1454
+ category: "Project",
1455
+ reference: ["[--staged]", "automation", ["none"]]
1456
+ },
1457
+ propagate: {
1458
+ script: "scripts/propagate/propagate.ts",
1459
+ description: "Carry the published release into every consumer repository next to this one",
1460
+ category: "Project",
1461
+ reference: ["[--dry-run] [--skip-publish-wait]", "maintainer", ["files", "network"]]
1462
+ },
1463
+ adopt: {
1464
+ script: "scripts/adopt/adopt.ts",
1465
+ description: "Upgrade every installed @joshuafolkken toolkit here and open the pull request",
1466
+ category: "Project",
1467
+ reference: ["[--dry-run]", "developer", ["files", "git", "network", "processes"]]
1468
+ }
1469
+ };
1470
+
1471
+ // scripts/josh/josh-commands-versioning.ts
1472
+ var VERSIONING_COMMANDS = {
1473
+ bump: {
1474
+ script: "scripts/version/bump-version.ts",
1475
+ description: "Bump package version",
1476
+ category: "Versioning",
1477
+ reference: ["[major|minor|patch]", "maintainer", ["files"]]
1478
+ },
1479
+ version: {
1480
+ script: "scripts/version/version-check.ts",
1481
+ description: "Show kit versions; --upgrade updates the global and project install",
1482
+ category: "Versioning",
1483
+ reference: ["[--upgrade]", "developer", ["files", "network", "processes"]]
1484
+ },
1485
+ // A `script` entry, not a shell one: script paths resolve against the kit package root, so this
1486
+ // keeps working from a consumer repo where the file lives under node_modules. The registry
1487
+ // probes need NODE_AUTH_TOKEN for any `@joshuafolkken/*` dependency; `josh latest` exports it
1488
+ // before chaining here, exactly as it already does for `latest:update`.
1489
+ ranges: {
1490
+ script: "scripts/version/publishable-range-check.ts",
1491
+ description: "Check that every published dependency range still resolves for a consumer",
1492
+ category: "Versioning",
1493
+ reference: ["", "developer", ["network"]]
1494
+ },
1495
+ // The one place that decides a version (joshuafolkken/kit#1169). A `script` entry for the same
1496
+ // reason `ranges` is one: script paths resolve against the kit package root, so it keeps working
1497
+ // from a consumer repository where the file lives under node_modules.
1498
+ release: {
1499
+ script: "scripts/release/release-cli.ts",
1500
+ description: "Release the merges main has taken since the version last changed",
1501
+ category: "Versioning",
1502
+ reference: ["[version]", "maintainer", ["git", "network", "release"]]
1503
+ },
1504
+ // The read-only half of the one above (joshuafolkken/kit#1582). `release --dry-run` cannot
1505
+ // answer this question: it refuses off the default branch and on a dirty tree, which is every
1506
+ // position a run asks it from. A `script` entry for the same reason `release` is one.
1507
+ "release:scope": {
1508
+ script: "scripts/release/release-scope-cli.ts",
1509
+ description: "Say whether a release is owed, from the unreleased merges on main",
1510
+ category: "Versioning",
1511
+ reference: ["[--json]", "automation", ["none"]]
1512
+ }
1513
+ };
1514
+
1515
+ // scripts/josh/josh-commands-workflow.ts
1516
+ var GIT_WORKFLOW_SCRIPT = "scripts-ai/git-workflow.ts";
1517
+ var GIT_MESSAGE_ARGUMENTS = "[-y] <message>";
1518
+ var WORKFLOW_COMMANDS = {
1519
+ git: {
1520
+ script: GIT_WORKFLOW_SCRIPT,
1521
+ description: "Git workflow helper",
1522
+ category: "Workflow",
1523
+ reference: [GIT_MESSAGE_ARGUMENTS, "developer", ["git", "network"]]
1524
+ },
1525
+ pr: {
1526
+ script: GIT_WORKFLOW_SCRIPT,
1527
+ description: "Create PR only (skip commit and push)",
1528
+ category: "Workflow",
1529
+ // Not `GIT_MESSAGE_ARGUMENTS`: `-y` is already in the default arguments below, so advertising
1530
+ // it would document a flag that cannot change what this command does.
1531
+ reference: ["<message>", "developer", ["network"]],
1532
+ default_script_arguments: ["-y", "--skip-commit", "--skip-push"]
1533
+ },
1534
+ // **The optional form, on both** (joshuafolkken/kit#1564). These two were the last commands
1535
+ // passing the mandatory `--env-file=.env`, which node resolves before the script's first line: on
1536
+ // a machine with no `.env` they died as `.env: not found` with exit code 9, even where
1537
+ // `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` existed as real environment variables — a cloud
1538
+ // session, and `followup` with them the merge step of every `fullrun` there. `doctor` was moved to
1539
+ // this form for the same reason in joshuafolkken/kit#869.
1540
+ //
1541
+ // Nothing is lost by relaxing it: both scripts already call `load_optional_environment()`
1542
+ // themselves, so the file is read either way and node's precedence — an existing environment
1543
+ // variable wins over the file — is node's own in both spellings.
1544
+ //
1545
+ // **What the mandatory flag was accidentally providing was noise**, and that is replaced rather
1546
+ // than dropped: `telegram_notify.send` now throws on missing credentials and on a failed send, so
1547
+ // `josh notify` exits non-zero instead of warning and answering 0.
1548
+ followup: {
1549
+ script: "scripts-ai/git-followup-workflow.ts",
1550
+ description: "Follow-up git workflow",
1551
+ category: "Workflow",
1552
+ reference: [
1553
+ "<title> [--notify-message <text>]",
1554
+ "automation",
1555
+ ["git", "network", "notifications"]
1556
+ ],
1557
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1558
+ },
1559
+ notify: {
1560
+ script: "scripts-ai/telegram-test.ts",
1561
+ description: "Send Telegram notification",
1562
+ category: "Workflow",
1563
+ reference: ["--task-type <type> --body <text>", "automation", ["notifications"]],
1564
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1565
+ },
1566
+ // The observation ledger's only commit path (joshuafolkken/kit#1756). `pnpm josh git` excludes the
1567
+ // ledger from what it stages, so without this command a parent's appended line has no route to the
1568
+ // default branch at all — and the recurrence count the promotion rule reads is a count of main.
1569
+ "observations:flush": {
1570
+ script: "scripts/observations/observations-flush-cli.ts",
1571
+ description: "Commit the observation ledger as a pull request of its own, and merge it",
1572
+ category: "Workflow",
1573
+ reference: ["", "automation", ["git", "network"]]
1574
+ },
1575
+ // After a behavior-change Issue merges, re-run its declared baseline and print before/after; a value
1576
+ // that did not move appends a refuted-premise line to the observation ledger (joshuafolkken/kit#2212).
1577
+ "measure:rerun": {
1578
+ script: "scripts/issue/measure-rerun-cli.ts",
1579
+ description: "Re-run a merged issue\u2019s baseline command and print the before/after pair",
1580
+ category: "Workflow",
1581
+ reference: ["<path>", "automation", ["processes", "files"]]
1582
+ },
1583
+ // A script rather than an `sh -c` chain, because it has a precondition to enforce: run inside a
1584
+ // linked work tree it would hijack the default branch from every other one (joshuafolkken/kit#1535).
1585
+ "main:sync": {
1586
+ script: "scripts/git/main-sync.ts",
1587
+ description: "Checkout default branch and pull latest (refuses inside a lane)",
1588
+ category: "Workflow",
1589
+ reference: ["", "developer", ["git", "network"]]
1590
+ },
1591
+ // A script rather than an `sh -c` chain, because the strategy has to be named rather than left to
1592
+ // the caller's git configuration: the `git pull` this replaced aborted with `Need to specify how
1593
+ // to reconcile divergent branches` on exactly the diverged branch the command exists for
1594
+ // (joshuafolkken/kit#1659).
1595
+ "main:merge": {
1596
+ script: "scripts/git/main-merge.ts",
1597
+ description: "Merge origin default branch into the current branch",
1598
+ category: "Workflow",
1599
+ reference: ["", "developer", ["git", "network"]]
1600
+ }
1601
+ };
1602
+
1603
+ // scripts/josh/josh-command-map.ts
1604
+ var COMMAND_MAP = {
1605
+ ...DEV_COMMANDS,
1606
+ ...PROJECT_COMMANDS,
1607
+ ...WORKFLOW_COMMANDS,
1608
+ ...VERSIONING_COMMANDS,
1609
+ ...MAINTENANCE_COMMANDS,
1610
+ ...HOOKS_COMMANDS,
1611
+ ...AI_COMMANDS,
1612
+ ...LINT_COMMANDS,
1613
+ ...CLONE_COMMANDS
1614
+ };
1615
+ var ALIASES = {
1616
+ ga: "gate",
1617
+ l: "lint",
1618
+ lr: "lint:related",
1619
+ ln: "lines",
1620
+ by: "bytes",
1621
+ f: "format",
1622
+ fd: "format:edited",
1623
+ bg: "batch:guard",
1624
+ sd: "cspell:dot",
1625
+ t: "test",
1626
+ tu: "test:unit",
1627
+ tr: "test:related",
1628
+ td: "test:declared",
1629
+ te: "test:e2e",
1630
+ er: "e2e:retry-check",
1631
+ sl: "session:lang",
1632
+ c: "check",
1633
+ pt: "port",
1634
+ i: "init",
1635
+ sy: "sync",
1636
+ sys: "sync:scope",
1637
+ g: "git",
1638
+ gp: "pr",
1639
+ fu: "followup",
1640
+ nf: "notify",
1641
+ obf: "observations:flush",
1642
+ mrr: "measure:rerun",
1643
+ ms: "main:sync",
1644
+ mm: "main:merge",
1645
+ bp: "bump",
1646
+ re: "release",
1647
+ res: "release:scope",
1648
+ v: "version",
1649
+ r: "ranges",
1650
+ dr: "doctor",
1651
+ pg: "propagate",
1652
+ ad: "adopt",
1653
+ ov: "overrides",
1654
+ a: "audit",
1655
+ ap: "audit:provision",
1656
+ rt: "reconcile-templates",
1657
+ u: "latest",
1658
+ lg: "latest:guard",
1659
+ lc: "latest:corepack",
1660
+ lu: "latest:update",
1661
+ ls: "latest:scope",
1662
+ pm: "prevent-main-commit",
1663
+ cm: "check-commit-message",
1664
+ ss: "secretlint-scan",
1665
+ ppu: "pre-push-unit",
1666
+ ptc: "pre-commit-type-check",
1667
+ ird: "issue:read",
1668
+ ist: "issue:state",
1669
+ isc: "issue:scout",
1670
+ isf: "issue:fold",
1671
+ ici: "issue:cite",
1672
+ pks: "pkg:scout",
1673
+ iln: "issue:lint",
1674
+ ibl: "issue:backlinks",
1675
+ rl: "report:lint",
1676
+ ep: "epic",
1677
+ ec: "epic:check",
1678
+ en: "epic:next",
1679
+ ea: "epic:audit",
1680
+ eb: "epic:bundle",
1681
+ ao: "auto-ok:next",
1682
+ bl: "backlog:next",
1683
+ blo: "backlog:offer",
1684
+ blp: "backlog:plan",
1685
+ bb: "backlog:budget",
1686
+ co: "cost",
1687
+ ds: "doc:section",
1688
+ rs: "read:set",
1689
+ dcr: "doc:read",
1690
+ rf: "read:files",
1691
+ rfs: "refactor:scan",
1692
+ tm: "time",
1693
+ rb: "review:brief",
1694
+ r2: "review:round2",
1695
+ ra: "review:attest",
1696
+ dp: "disposition",
1697
+ dg: "delegate",
1698
+ rh: "run:hold",
1699
+ rr: "run:release",
1700
+ rc: "run:carry",
1701
+ rw: "run:wake",
1702
+ rct: "run:cut",
1703
+ rv: "run:liveness",
1704
+ red: "run:ending",
1705
+ rg: "run:progress",
1706
+ rp: "run:prep",
1707
+ rst: "run:status",
1708
+ rn: "run:next",
1709
+ rsp: "run:step",
1710
+ rpy: "repo:party",
1711
+ rmg: "run:merge",
1712
+ rrp: "run:report",
1713
+ rrv: "run:review",
1714
+ rev: "run:event",
1715
+ sp: "stash:pop",
1716
+ lno: "lane:open",
1717
+ lnc: "lane:close",
1718
+ lnl: "lane:list",
1719
+ lnp: "lane:prune",
1720
+ lnv: "lane:output",
1721
+ lnd: "lane:dispatch",
1722
+ lna: "lane:await",
1723
+ lnla: "lane:launch",
1724
+ rwg: "run:watcher:guard",
1725
+ ig: "investigation:guard",
1726
+ rug: "rule:guard",
1727
+ ruv: "rule:value",
1728
+ ptg: "pretool:guard",
1729
+ sg: "stop:guard",
1730
+ ev: "eval",
1731
+ ol: "oracle:list",
1732
+ sa: "split:assess",
1733
+ shs: "sonar:hotspots",
1734
+ uir: "ui:routes",
1735
+ cs: "clone:scan",
1736
+ ca: "cases"
1737
+ };
1738
+ function canonical_command(name) {
1739
+ if (!Object.hasOwn(ALIASES, name)) return name;
1740
+ return ALIASES[name] ?? name;
1741
+ }
1742
+
1743
+ // scripts/time-runtime/time-shell.ts
1744
+ var BASH_SEPARATOR = ": ";
1745
+ var WHITESPACE_PATTERN = /\s+/u;
1746
+ var SEGMENT_PATTERN = /&&|\|\||;|\|/u;
1747
+ var PIPE_PATTERN = /(?<!\|)\|(?!\|)/u;
1748
+ var CHAIN_PATTERN = /&&|\|\||;/u;
1749
+ var QUOTED_SPAN_PATTERN = /'[^']*'|"[^"]*"/gu;
1750
+ var PIPEFAIL_PATTERN = /\bset\s+-[a-z]*o\s+pipefail\b/u;
1751
+ var COMMAND_WORD_PATTERN = /^[\w./@:+][\w./@:+-]*$/u;
1752
+ var ASSIGNMENT_PATTERN = /^\w+=/u;
1753
+ var SUBSHELL_OPENER = "$(";
1754
+ var FLAG_PREFIX = "-";
1755
+ var WRAPPER_COMMANDS = /* @__PURE__ */ new Set(["time", "env", "sudo"]);
1756
+ var NAVIGATION_COMMANDS = /* @__PURE__ */ new Set(["cd", "pushd", "popd", "export", "source", "set", "."]);
1757
+ var JOSH_PATTERN = /^(?:pnpm\s+(?:exec\s+)?)?josh\s+([a-z][\w:-]*)/u;
1758
+ var JOSH_PREFIX = "josh ";
1759
+ var COMMAND_KEY2 = "command";
1760
+ function bash_command(input) {
1761
+ if (!json_value.is_record(input)) return "";
1762
+ const command = input[COMMAND_KEY2];
1763
+ return typeof command === "string" ? command : "";
1764
+ }
1765
+ function is_skippable(word) {
1766
+ if (word.startsWith(FLAG_PREFIX)) return true;
1767
+ return ASSIGNMENT_PATTERN.test(word) || WRAPPER_COMMANDS.has(word);
1768
+ }
1769
+ function command_words(segment) {
1770
+ const words = segment.replaceAll(SUBSHELL_OPENER, " ").trim().split(WHITESPACE_PATTERN);
1771
+ const start = words.findIndex((word) => !is_skippable(word));
1772
+ return start === -1 ? [] : words.slice(start);
1773
+ }
1774
+ function segment_command(segment) {
1775
+ const [head] = command_words(segment);
1776
+ if (head === void 0 || NAVIGATION_COMMANDS.has(head)) return "";
1777
+ return COMMAND_WORD_PATTERN.test(head) ? head : "";
1778
+ }
1779
+ function command_segment(command) {
1780
+ return command.split(SEGMENT_PATTERN).find((segment) => segment_command(segment) !== "") ?? "";
1781
+ }
1782
+ function leading_word(command) {
1783
+ return segment_command(command_segment(command));
1784
+ }
1785
+ function unquoted(command) {
1786
+ return command.replaceAll(QUOTED_SPAN_PATTERN, " ");
1787
+ }
1788
+ function discarded_commands(command) {
1789
+ const plain = unquoted(command);
1790
+ if (PIPEFAIL_PATTERN.test(plain)) return [];
1791
+ return plain.split(PIPE_PATTERN).slice(0, -1).map((segment) => segment.split(CHAIN_PATTERN).at(-1) ?? "");
1792
+ }
1793
+ function bash_label(command) {
1794
+ const word = leading_word(command);
1795
+ return word === "" ? cost_blocks.BASH_TOOL : `${cost_blocks.BASH_TOOL}${BASH_SEPARATOR}${word}`;
1796
+ }
1797
+ function josh_command_of_segment(segment) {
1798
+ const name = JOSH_PATTERN.exec(command_words(segment).join(" "))?.[1];
1799
+ return name === void 0 ? "" : `${JOSH_PREFIX}${canonical_command(name)}`;
1800
+ }
1801
+ function josh_command_of(command) {
1802
+ return josh_command_of_segment(command_segment(command));
1803
+ }
1804
+ function josh_commands_of(command) {
1805
+ return unquoted(command).split(SEGMENT_PATTERN).map((segment) => josh_command_of_segment(segment)).filter((name) => name !== "");
1806
+ }
1807
+ var REDIRECTION_CHARACTERS = ["<", ">"];
1808
+ function is_redirection(word) {
1809
+ return REDIRECTION_CHARACTERS.some((character) => word.includes(character));
1810
+ }
1811
+ function ends_in_redirection(word) {
1812
+ return REDIRECTION_CHARACTERS.some((character) => word.endsWith(character));
1813
+ }
1814
+ function drop_redirections(words) {
1815
+ const kept = [];
1816
+ let is_target2 = false;
1817
+ for (const word of words) {
1818
+ const is_dropped = is_target2 || is_redirection(word);
1819
+ is_target2 = ends_in_redirection(word);
1820
+ if (!is_dropped) kept.push(word);
1821
+ }
1822
+ return kept;
1823
+ }
1824
+ function josh_arguments(command) {
1825
+ const text = command_words(command_segment(command)).join(" ");
1826
+ const match = JOSH_PATTERN.exec(text);
1827
+ if (match === null) return [];
1828
+ const words = text.slice(match[0].length).split(WHITESPACE_PATTERN).filter((word) => word !== "");
1829
+ return drop_redirections(words);
1830
+ }
1831
+ var time_shell = {
1832
+ JOSH_PREFIX,
1833
+ bash_command,
1834
+ bash_label,
1835
+ command_segment,
1836
+ discarded_commands,
1837
+ josh_arguments,
1838
+ josh_command_of,
1839
+ josh_commands_of,
1840
+ leading_word,
1841
+ unquoted
1842
+ };
1843
+
1844
+ // scripts/time-runtime/time-background.ts
1845
+ var NO_BACKGROUND = "";
1846
+ var NO_FINISH = 0;
1847
+ var LAUNCH_PATTERN = /running in background with ID:\s*([\w-]+)/iu;
1848
+ var FINISH_PATTERN = /^<task-notification>[\s\S]*?<task-id>([\w-]+)<\/task-id>/u;
1849
+ var OUTPUT_PATTERN = /tasks\/([\w-]+)\.output/u;
1850
+ var BASH_ID_KEY = "bash_id";
1851
+ function read_id(command) {
1852
+ return OUTPUT_PATTERN.exec(time_shell.unquoted(command))?.[1] ?? NO_BACKGROUND;
1853
+ }
1854
+ function read_id_of(input) {
1855
+ if (!json_value.is_record(input)) return NO_BACKGROUND;
1856
+ const id = input[BASH_ID_KEY];
1857
+ return typeof id === "string" ? id : read_id(time_shell.bash_command(input));
1858
+ }
1859
+ function launch_id(text) {
1860
+ return LAUNCH_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
1861
+ }
1862
+ function finished_id(text) {
1863
+ return FINISH_PATTERN.exec(text)?.[1] ?? NO_BACKGROUND;
1864
+ }
1865
+ function finished_at(lines) {
1866
+ const notices = lines.filter((one) => one.finished_background !== NO_BACKGROUND).toSorted((left, right) => right.timestamp_ms - left.timestamp_ms);
1867
+ return new Map(notices.map((one) => [one.finished_background, one.timestamp_ms]));
1868
+ }
1869
+ function started_ms(span) {
1870
+ return span.ended_ms - span.duration_ms;
1871
+ }
1872
+ function read_end_ms(spans, run) {
1873
+ if (run.background_ended_ms === NO_FINISH) return void 0;
1874
+ const found = spans.find(
1875
+ (span) => span.reads_background === run.background_id && span.ended_ms >= run.background_ended_ms
1876
+ );
1877
+ return found?.ended_ms;
1878
+ }
1879
+ function to_run(spans, launch) {
1880
+ const read = read_end_ms(spans, launch);
1881
+ return {
1882
+ id: launch.background_id,
1883
+ josh_command: launch.josh_command,
1884
+ started_ms: started_ms(launch),
1885
+ ended_ms: read ?? launch.ended_ms,
1886
+ is_read: read !== void 0
1887
+ };
1888
+ }
1889
+ function is_launch(span) {
1890
+ return span.background_id !== NO_BACKGROUND;
1891
+ }
1892
+ function runs(spans) {
1893
+ return spans.filter((span) => is_launch(span)).map((launch) => to_run(spans, launch));
1894
+ }
1895
+ function is_within(span, run) {
1896
+ const start = started_ms(span);
1897
+ return start >= run.started_ms && start < run.ended_ms;
1898
+ }
1899
+ function latest_first(all) {
1900
+ return all.filter((run) => run.is_read).toSorted((left, right) => right.started_ms - left.started_ms);
1901
+ }
1902
+ function own_run(span, all) {
1903
+ return is_launch(span) ? all.find((run) => run.id === span.background_id) : void 0;
1904
+ }
1905
+ function placed(span, all, ordered) {
1906
+ const own = own_run(span, all);
1907
+ const run = own ?? ordered.find((one) => is_within(span, one));
1908
+ if (run === void 0) return span;
1909
+ const beside = { ...span, background_command: run.josh_command };
1910
+ return own === void 0 ? beside : { ...beside, own_duration_ms: own.ended_ms - own.started_ms };
1911
+ }
1912
+ function positioned(spans) {
1913
+ const all = runs(spans);
1914
+ if (all.length === 0) return [...spans];
1915
+ const ordered = latest_first(all);
1916
+ return spans.map((span) => placed(span, all, ordered));
1917
+ }
1918
+ function unread_phases(spans) {
1919
+ const names = runs(spans).filter((run) => !run.is_read).map((run) => COMMAND_PHASES.get(run.josh_command));
1920
+ return new Set(names.filter((phase) => phase !== void 0));
1921
+ }
1922
+ var time_background = {
1923
+ NO_BACKGROUND,
1924
+ NO_FINISH,
1925
+ launch_id,
1926
+ finished_id,
1927
+ finished_at,
1928
+ read_id,
1929
+ read_id_of,
1930
+ runs,
1931
+ positioned,
1932
+ unread_phases
1933
+ };
1934
+
1935
+ // scripts/time-runtime/time-bundle-call.ts
1936
+ var { BASH_TOOL: BASH_TOOL2 } = cost_blocks;
1937
+ var BUNDLEABLE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Glob", "Grep", "Read", "WebFetch", "WebSearch", "Write"]);
1938
+ var LAUNCH_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task"]);
1939
+ var PRIOR_REFERENCE_MARKERS = [
1940
+ "previous finding",
1941
+ "prior finding",
1942
+ "earlier finding",
1943
+ "previous result",
1944
+ "prior result",
1945
+ "earlier result",
1946
+ "based on the previous",
1947
+ "based on the earlier",
1948
+ "from the previous agent",
1949
+ "from the prior agent",
1950
+ "the finding above",
1951
+ "as found earlier",
1952
+ "as found above",
1953
+ "building on the previous"
1954
+ ];
1955
+ var READ_COMMANDS = /* @__PURE__ */ new Set([
1956
+ "awk",
1957
+ "basename",
1958
+ "cat",
1959
+ "comm",
1960
+ "cut",
1961
+ "diff",
1962
+ "dirname",
1963
+ "du",
1964
+ "echo",
1965
+ "file",
1966
+ "find",
1967
+ "gh",
1968
+ "grep",
1969
+ "head",
1970
+ "jq",
1971
+ "ls",
1972
+ "nl",
1973
+ "printf",
1974
+ "pwd",
1975
+ "realpath",
1976
+ "rg",
1977
+ // **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
1978
+ // the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
1979
+ // same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
1980
+ // caught by the target test instead, which is where that ordering actually lives.
1981
+ "sed",
1982
+ "sort",
1983
+ "stat",
1984
+ "tail",
1985
+ "tree",
1986
+ "uniq",
1987
+ "wc",
1988
+ "which"
1989
+ ]);
1990
+ var MUTATION_WORDS = /* @__PURE__ */ new Set([
1991
+ "--field",
1992
+ "--method",
1993
+ "--raw-field",
1994
+ "-F",
1995
+ "-X",
1996
+ "-delete",
1997
+ "-exec",
1998
+ "-f",
1999
+ "add",
2000
+ "chmod",
2001
+ "chown",
2002
+ "close",
2003
+ "comment",
2004
+ "cp",
2005
+ "create",
2006
+ "dd",
2007
+ "delete",
2008
+ "edit",
2009
+ "git",
2010
+ "install",
2011
+ "kill",
2012
+ "ln",
2013
+ "merge",
2014
+ "mkdir",
2015
+ "mv",
2016
+ "node",
2017
+ "npm",
2018
+ "npx",
2019
+ "pkill",
2020
+ "pnpm",
2021
+ "remove",
2022
+ "rm",
2023
+ "scp",
2024
+ "secret",
2025
+ "set",
2026
+ "ssh",
2027
+ "sudo",
2028
+ "tee",
2029
+ "touch",
2030
+ "truncate",
2031
+ "tsx",
2032
+ "upload",
2033
+ "wget"
2034
+ ]);
2035
+ var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
2036
+ "backlog:budget",
2037
+ "backlog:next",
2038
+ "cost",
2039
+ "delegate",
2040
+ "epic:audit",
2041
+ "epic:bundle",
2042
+ "epic:check",
2043
+ "epic:next",
2044
+ "issue:read",
2045
+ "issue:scout",
2046
+ "issue:state",
2047
+ "lane:list",
2048
+ "latest:scope",
2049
+ "release:scope",
2050
+ "review:brief",
2051
+ "review:round2",
2052
+ "run:liveness"
2053
+ ]);
2054
+ var JOSH_WORD = "josh";
2055
+ var JOSH_SCRIPT_SUFFIX = "josh.ts";
2056
+ var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
2057
+ var WHITESPACE_PATTERN2 = /\s+/u;
2058
+ var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
2059
+ var TARGET_ARRAY_FIELD = "file_paths";
2060
+ var MAX_TARGETS = 8;
2061
+ var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
2062
+ var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
2063
+ var MAX_EXTENSION = 5;
2064
+ var AFTER_DOT = 1;
2065
+ var FIRST_INDEX = 0;
2066
+ var CURRENT_DIRECTORY = "./";
2067
+ var LAST_CHARACTER = -1;
2068
+ var FLAG_PREFIX2 = "-";
2069
+ var PATH_SEPARATOR = "/";
2070
+ var MIN_TARGET_LENGTH = 3;
2071
+ var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
2072
+ var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
2073
+ var REDIRECTION = ">";
2074
+ var IN_PLACE_COMMAND = "sed";
2075
+ var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
2076
+ function not_bundleable() {
2077
+ return {
2078
+ is_bundleable: false,
2079
+ targets: [],
2080
+ is_writing: false,
2081
+ may_write: false,
2082
+ has_prior_reference: false
2083
+ };
2084
+ }
2085
+ function is_launch_tool(name) {
2086
+ return LAUNCH_TOOLS.has(name);
2087
+ }
2088
+ function words_of(command) {
2089
+ return command.split(WORD_PATTERN).filter((word) => word !== "");
2090
+ }
2091
+ function has_mutation(command) {
2092
+ return words_of(command).some((word) => MUTATION_WORDS.has(word));
2093
+ }
2094
+ function josh_subcommand(command) {
2095
+ const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
2096
+ const josh_index = tokens.findIndex(
2097
+ (token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
2098
+ );
2099
+ return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
2100
+ }
2101
+ function is_read_josh(command) {
2102
+ if (COMMAND_CHAIN.test(command)) return false;
2103
+ const subcommand = josh_subcommand(command);
2104
+ if (subcommand === void 0) return false;
2105
+ return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
2106
+ }
2107
+ function may_write_command(command) {
2108
+ if (command.includes(REDIRECTION)) return true;
2109
+ return words_of(command).some((word) => WRITING_WORDS.has(word));
2110
+ }
2111
+ function write_segment(command) {
2112
+ return time_shell.command_segment(time_shell.unquoted(command));
2113
+ }
2114
+ function is_in_place_sed(segment) {
2115
+ if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
2116
+ return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
2117
+ }
2118
+ function normalize(word) {
2119
+ const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
2120
+ return head.endsWith(PATH_SEPARATOR) ? head.slice(0, LAST_CHARACTER) : head;
2121
+ }
2122
+ function has_extension(word) {
2123
+ const dot = word.lastIndexOf(".");
2124
+ if (dot <= FIRST_INDEX) return false;
2125
+ const suffix = word.slice(dot + AFTER_DOT);
2126
+ return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
2127
+ }
2128
+ function is_target(word) {
2129
+ if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
2130
+ return word.includes(PATH_SEPARATOR) || has_extension(word);
2131
+ }
2132
+ function targets_in(text) {
2133
+ return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
2134
+ }
2135
+ function field_text(input, field) {
2136
+ if (!json_value.is_record(input)) return "";
2137
+ const value = input[field];
2138
+ return typeof value === "string" ? value : "";
2139
+ }
2140
+ function field_targets(input) {
2141
+ if (!json_value.is_record(input)) return [];
2142
+ const value = input[TARGET_ARRAY_FIELD];
2143
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
2144
+ }
2145
+ function tool_targets(input) {
2146
+ const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
2147
+ const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
2148
+ return [...new Set(targets)].filter((target) => target !== "");
2149
+ }
2150
+ function prompt_references_prior(input) {
2151
+ const prompt = field_text(input, "prompt").toLowerCase();
2152
+ return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
2153
+ }
2154
+ function tool_facts(name, input) {
2155
+ const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
2156
+ const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
2157
+ if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
2158
+ return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
2159
+ }
2160
+ function bash_facts(command) {
2161
+ const writes = {
2162
+ is_writing: is_in_place_sed(write_segment(command)),
2163
+ may_write: may_write_command(command)
2164
+ };
2165
+ if (is_read_josh(command)) {
2166
+ return {
2167
+ is_bundleable: true,
2168
+ targets: targets_in(time_shell.unquoted(command)),
2169
+ ...writes,
2170
+ has_prior_reference: false
2171
+ };
2172
+ }
2173
+ if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
2174
+ return { ...not_bundleable(), ...writes };
2175
+ }
2176
+ return {
2177
+ is_bundleable: true,
2178
+ targets: targets_in(time_shell.unquoted(command)),
2179
+ ...writes,
2180
+ has_prior_reference: false
2181
+ };
2182
+ }
2183
+ function call_facts(name, input) {
2184
+ if (name !== BASH_TOOL2) return tool_facts(name, input);
2185
+ return bash_facts(time_shell.bash_command(input));
2186
+ }
2187
+ var time_bundle_call = {
2188
+ MAX_TARGETS,
2189
+ not_bundleable,
2190
+ bash_facts,
2191
+ call_facts,
2192
+ tool_facts,
2193
+ // Exported for `time-agent-bundles.ts` (joshuafolkken/kit#1854), which asks the launch question of a
2194
+ // span's `label` — the tool name for a non-Bash call — so the set lives in one place.
2195
+ is_launch_tool,
2196
+ // Exported for `time-writes.ts` (joshuafolkken/kit#1472), which asks what a call *wrote* rather
2197
+ // than what it named. The extraction is the same one either way — a second copy of it would let a
2198
+ // path be recognized as a target when read and missed when written.
2199
+ targets_in,
2200
+ tool_targets,
2201
+ // Exported for the batching guard's own word scan (joshuafolkken/kit#1390), so the two scanners
2202
+ // cannot come to disagree about where one word of a shell line ends and the next begins.
2203
+ words_of,
2204
+ // Exported for `time-writes.ts` (joshuafolkken/kit#1509), which needs the same two answers to say
2205
+ // *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
2206
+ // once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
2207
+ write_segment,
2208
+ is_in_place_sed,
2209
+ // Exported for the drift test in `time-bundle-call.test.ts` (joshuafolkken/kit#1875), which pins that
2210
+ // every name here is a real `josh` command and none of them writes.
2211
+ READ_JOSH_SUBCOMMANDS
2212
+ };
2213
+
2214
+ // scripts/time-runtime/time-format.ts
2215
+ var MS_PER_MINUTE = 6e4;
2216
+ var MS_PER_SECOND = 1e3;
2217
+ var MINUTE_DECIMALS = 1;
2218
+ var SECOND_DECIMALS = 1;
2219
+ var PERCENT_SCALE = 100;
2220
+ var PERCENT_DECIMALS = 1;
2221
+ var LABEL_WIDTH = 24;
2222
+ var MINUTES_WIDTH = 9;
2223
+ var NOT_MEASURED = "not measured";
2224
+ var NO_CALLS = "no tool call to divide";
2225
+ var NAKED_PREFIX = "naked ";
2226
+ var MODEL_LABEL = "model wait";
2227
+ var TOOL_LABEL = "tool execution";
2228
+ var HUMAN_LABEL = "human wait";
2229
+ var CI_LABEL = "CI wait";
2230
+ var MAX_ROWS = 15;
2231
+ var SUFFIX_SEPARATOR = " \xB7 ";
2232
+ var RANGE_SEPARATOR = " \u2013 ";
2233
+ var RUN_UNIT = "run(s)";
2234
+ var CLOCK_START = 11;
2235
+ var CLOCK_END = 19;
2236
+ var WINDOW_ARROW = " \u2192 ";
2237
+ function overflow_line(row_count) {
2238
+ if (row_count <= MAX_ROWS) return [];
2239
+ return [
2240
+ ` \u2026 and ${String(row_count - MAX_ROWS)} more (--json carries every row this report holds)`
2241
+ ];
2242
+ }
2243
+ function format_minutes(duration_ms) {
2244
+ return `${(duration_ms / MS_PER_MINUTE).toFixed(MINUTE_DECIMALS)} min`;
2245
+ }
2246
+ function format_seconds(duration_ms) {
2247
+ return `${(duration_ms / MS_PER_SECOND).toFixed(SECOND_DECIMALS)} s`;
2248
+ }
2249
+ function format_share(part, whole) {
2250
+ if (whole === 0) return "n/a";
2251
+ return `${(part / whole * PERCENT_SCALE).toFixed(PERCENT_DECIMALS)}%`;
2252
+ }
2253
+ function usd(amount, decimals) {
2254
+ return `$${amount.toFixed(decimals)}`;
2255
+ }
2256
+ function format_columns(label, minutes, suffix) {
2257
+ return ` ${label.padEnd(LABEL_WIDTH)}${minutes.padStart(MINUTES_WIDTH)} ${suffix}`;
2258
+ }
2259
+ function format_row(label, duration_ms, suffix) {
2260
+ return format_columns(label, format_minutes(duration_ms), suffix);
2261
+ }
2262
+ function unmeasured_row(label) {
2263
+ return format_columns(label, "", NOT_MEASURED);
2264
+ }
2265
+ function format_spread(min, max, sample_count) {
2266
+ const range = `${min}${RANGE_SEPARATOR}${max}`;
2267
+ return `${range}${SUFFIX_SEPARATOR}${String(sample_count)} ${RUN_UNIT}`;
2268
+ }
2269
+ function format_clock(timestamp_ms) {
2270
+ return new Date(timestamp_ms).toISOString().slice(CLOCK_START, CLOCK_END);
2271
+ }
2272
+ function format_window(started_ms3, ended_ms) {
2273
+ return `${format_clock(started_ms3)}${WINDOW_ARROW}${format_clock(ended_ms)}`;
2274
+ }
2275
+ function note_lines(notes) {
2276
+ return notes.map((note) => ` ${note}`);
2277
+ }
2278
+ var time_format = {
2279
+ MAX_ROWS,
2280
+ NO_CALLS,
2281
+ NAKED_PREFIX,
2282
+ SUFFIX_SEPARATOR,
2283
+ NOT_MEASURED,
2284
+ MODEL_LABEL,
2285
+ TOOL_LABEL,
2286
+ HUMAN_LABEL,
2287
+ CI_LABEL,
2288
+ overflow_line,
2289
+ format_minutes,
2290
+ format_seconds,
2291
+ format_share,
2292
+ usd,
2293
+ format_columns,
2294
+ format_row,
2295
+ format_spread,
2296
+ // `format_clock` stays private: `format_window` is its only caller, and a namespace that offers
2297
+ // both invites a second renderer to join the two with its own arrow.
2298
+ format_window,
2299
+ unmeasured_row,
2300
+ note_lines
2301
+ };
2302
+
2303
+ // scripts/git/git-followup-stages.ts
2304
+ var STAGE_LINE_PREFIX = "followup stage: ";
2305
+ var STAGE_TOTAL_PREFIX = "followup stages total: ";
2306
+ var STAGE_NAME_WIDTH = 26;
2307
+ var VALUE_COLUMN = STAGE_LINE_PREFIX.length + STAGE_NAME_WIDTH;
2308
+ var NO_DURATION = 0;
2309
+ var STAGE = {
2310
+ closes_and_context: "closes-and-context",
2311
+ checks_wait: "checks-wait",
2312
+ coderabbit_comments: "coderabbit-comments",
2313
+ ai_review_comments: "ai-review-comments",
2314
+ telegram: "telegram",
2315
+ merge: "merge",
2316
+ completion_and_epic_close: "completion-and-epic-close",
2317
+ // The lap that was still running when a stage threw. `followup` exits non-zero on an AI-review
2318
+ // blocker and on a red check, and those are the runs whose wait is longest — reporting nothing for
2319
+ // them would leave the measurement blind to exactly the invocations worth measuring.
2320
+ interrupted: "interrupted"
2321
+ };
2322
+ function new_log() {
2323
+ return { stages: [], last_ms: performance.now() };
2324
+ }
2325
+ function lap(log, name) {
2326
+ const now_ms = performance.now();
2327
+ log.stages.push({ name, duration_ms: now_ms - log.last_ms });
2328
+ log.last_ms = now_ms;
2329
+ }
2330
+ function total_ms(stages) {
2331
+ return stages.reduce((sum, stage) => sum + stage.duration_ms, NO_DURATION);
2332
+ }
2333
+ function format_stage(stage) {
2334
+ const name = stage.name.padEnd(STAGE_NAME_WIDTH);
2335
+ return `${STAGE_LINE_PREFIX}${name}${time_format.format_seconds(stage.duration_ms)}`;
2336
+ }
2337
+ function format_stages(log) {
2338
+ if (log.stages.length === 0) return [];
2339
+ const rows = log.stages.map((stage) => format_stage(stage));
2340
+ const total = time_format.format_seconds(total_ms(log.stages));
2341
+ return ["", ...rows, `${STAGE_TOTAL_PREFIX.padEnd(VALUE_COLUMN)}${total}`];
2342
+ }
2343
+ function print_stages(log) {
2344
+ for (const line of format_stages(log)) console.info(line);
2345
+ }
2346
+ var git_followup_stages = {
2347
+ STAGE,
2348
+ STAGE_LINE_PREFIX,
2349
+ STAGE_TOTAL_PREFIX,
2350
+ new_log,
2351
+ lap,
2352
+ total_ms,
2353
+ format_stages,
2354
+ print_stages
2355
+ };
2356
+
2357
+ // scripts/time-runtime/time-followup-stage.ts
2358
+ var LINE_SEPARATOR = "\n";
2359
+ var SECONDS_SUFFIX = " s";
2360
+ var DIGIT_OR_POINT = /[\d.]/u;
2361
+ var MS_PER_SECOND2 = 1e3;
2362
+ var NO_STAGES = [];
2363
+ function stage_body(line) {
2364
+ const trimmed = line.trimStart();
2365
+ if (!trimmed.startsWith(git_followup_stages.STAGE_LINE_PREFIX)) return void 0;
2366
+ return trimmed.slice(git_followup_stages.STAGE_LINE_PREFIX.length);
2367
+ }
2368
+ function digits_start(head) {
2369
+ let index = head.length;
2370
+ while (index > 0 && DIGIT_OR_POINT.test(head.charAt(index - 1))) index -= 1;
2371
+ return index;
2372
+ }
2373
+ function is_duration(digits) {
2374
+ return digits !== "" && Number.isFinite(Number(digits));
2375
+ }
2376
+ function to_stage(body) {
2377
+ const text = body.trimEnd();
2378
+ if (!text.endsWith(SECONDS_SUFFIX)) return void 0;
2379
+ const head = text.slice(0, -SECONDS_SUFFIX.length);
2380
+ const start = digits_start(head);
2381
+ const name = head.slice(0, start).trim();
2382
+ const digits = head.slice(start);
2383
+ if (name === "" || !is_duration(digits)) return void 0;
2384
+ return { name, duration_ms: Number(digits) * MS_PER_SECOND2 };
2385
+ }
2386
+ function read_stages(text) {
2387
+ if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
2388
+ return text.split(LINE_SEPARATOR).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
2389
+ }
2390
+ var time_followup_stage = { NO_STAGES, read_stages };
2391
+
2392
+ // scripts/cost-runtime/cost-attribute.ts
2393
+ var ISSUE_BRANCH_PATTERN = /^(\d+)-/u;
2394
+ var UNATTRIBUTED_KEY = -1;
2395
+ function issue_from_branch(branch) {
2396
+ const matched = ISSUE_BRANCH_PATTERN.exec(branch);
2397
+ return matched?.[1] === void 0 ? UNATTRIBUTED_KEY : Number(matched[1]);
2398
+ }
2399
+ function declared_issue(record) {
2400
+ const declared = record.issue ?? UNATTRIBUTED_KEY;
2401
+ return declared === UNATTRIBUTED_KEY ? issue_from_branch(record.branch) : declared;
2402
+ }
2403
+ function fill(declared, is_reverse) {
2404
+ const filled = Array.from({ length: declared.length }, () => UNATTRIBUTED_KEY);
2405
+ const order = declared.map((_value, index) => is_reverse ? declared.length - 1 - index : index);
2406
+ let carried = UNATTRIBUTED_KEY;
2407
+ for (const index of order) {
2408
+ const own = declared[index] ?? UNATTRIBUTED_KEY;
2409
+ carried = own === UNATTRIBUTED_KEY ? carried : own;
2410
+ filled[index] = carried;
2411
+ }
2412
+ return filled;
2413
+ }
2414
+ function is_attributed(value) {
2415
+ return value !== void 0 && value !== UNATTRIBUTED_KEY;
2416
+ }
2417
+ function pick(own, carried, next, previous) {
2418
+ if (is_attributed(own)) return own;
2419
+ if (is_attributed(carried)) return carried;
2420
+ if (is_attributed(next)) return next;
2421
+ return previous ?? UNATTRIBUTED_KEY;
2422
+ }
2423
+ function announcements(records) {
2424
+ return fill(
2425
+ records.map((record) => record.issue ?? UNATTRIBUTED_KEY),
2426
+ false
2427
+ );
2428
+ }
2429
+ function attribute(records) {
2430
+ const declared = records.map((record) => declared_issue(record));
2431
+ const carried = announcements(records);
2432
+ const next = fill(declared, true);
2433
+ const previous = fill(declared, false);
2434
+ return declared.map(
2435
+ (own, index) => pick(own, carried[index] ?? UNATTRIBUTED_KEY, next[index], previous[index])
2436
+ );
2437
+ }
2438
+ function group_by_issue(records) {
2439
+ const issues = attribute(records);
2440
+ const grouped = /* @__PURE__ */ new Map();
2441
+ for (const [index, record] of records.entries()) {
2442
+ const bucket = grouped.get(issues[index] ?? UNATTRIBUTED_KEY) ?? [];
2443
+ bucket.push(record);
2444
+ grouped.set(issues[index] ?? UNATTRIBUTED_KEY, bucket);
2445
+ }
2446
+ return [...grouped].toSorted(([left], [right]) => left - right).map(([issue, bucket]) => ({ issue, records: bucket }));
2447
+ }
2448
+ function records_for_issue(records, issue_number) {
2449
+ const issues = attribute(records);
2450
+ return records.filter((_record, index) => issues[index] === issue_number);
2451
+ }
2452
+ var cost_attribute = {
2453
+ UNATTRIBUTED_KEY,
2454
+ issue_from_branch,
2455
+ declared_issue,
2456
+ fill,
2457
+ attribute,
2458
+ group_by_issue,
2459
+ records_for_issue
2460
+ };
2461
+
2462
+ // scripts/time-runtime/time-markers.ts
2463
+ var NO_MARKER = "none";
2464
+ var PLAN_MARKER = "plan";
2465
+ var EDIT_MARKER = "edit";
2466
+ var REVIEW_MARKER = "review";
2467
+ var WORKFLOW_MARKER = "workflow";
2468
+ var EDIT_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
2469
+ var SKILL_TOOL = "Skill";
2470
+ var SKILL_KEY = "skill";
2471
+ var REVIEW_SKILL = "code-review";
2472
+ var WORKFLOW_SKILL = "workflow-commands";
2473
+ var AGENT_TOOL = "Agent";
2474
+ var PROMPT_KEY = "prompt";
2475
+ var REVIEW_INVOCATION = "/code-review";
2476
+ var REVIEW_ATTEST = "review:attest";
2477
+ var SKILL_MARKERS = /* @__PURE__ */ new Map([
2478
+ [REVIEW_SKILL, REVIEW_MARKER],
2479
+ [WORKFLOW_SKILL, WORKFLOW_MARKER]
2480
+ ]);
2481
+ var ISSUE_API_PATTERN = /repos\/\S+\/issues\/\d+/u;
2482
+ var BODY_FIELD_PATTERN = /\bbody=/u;
2483
+ var ISSUE_COMMENT_PATTERN = /\bgh\s+issue\s+comment\b/u;
2484
+ var BODY_FLAG_PATTERN = /--body(?:-file)?\b/u;
2485
+ var ISSUE_LABELS_PATTERN = /repos\/\S+\/issues\/(\d+)\/labels\b(?!\/)/u;
2486
+ var IN_PROGRESS_FIELD = "labels[]=in-progress";
2487
+ var NO_ISSUE = cost_attribute.UNATTRIBUTED_KEY;
2488
+ function string_field(input, key) {
2489
+ if (!json_value.is_record(input)) return "";
2490
+ const value = input[key];
2491
+ return typeof value === "string" ? value : "";
2492
+ }
2493
+ function skill_name(input) {
2494
+ return string_field(input, SKILL_KEY);
2495
+ }
2496
+ function agent_marker(input) {
2497
+ const prompt = string_field(input, PROMPT_KEY);
2498
+ const is_review = prompt.includes(REVIEW_INVOCATION) && prompt.includes(REVIEW_ATTEST);
2499
+ return is_review ? REVIEW_MARKER : NO_MARKER;
2500
+ }
2501
+ function tool_marker(name, input) {
2502
+ if (EDIT_TOOLS.has(name)) return EDIT_MARKER;
2503
+ if (name === AGENT_TOOL) return agent_marker(input);
2504
+ if (name !== SKILL_TOOL) return NO_MARKER;
2505
+ return SKILL_MARKERS.get(skill_name(input)) ?? NO_MARKER;
2506
+ }
2507
+ function is_api_body_write(command) {
2508
+ return ISSUE_API_PATTERN.test(command) && BODY_FIELD_PATTERN.test(command);
2509
+ }
2510
+ function is_issue_comment(command) {
2511
+ return ISSUE_COMMENT_PATTERN.test(command) && BODY_FLAG_PATTERN.test(command);
2512
+ }
2513
+ function is_in_progress_label(command) {
2514
+ return ISSUE_LABELS_PATTERN.test(command) && command.includes(IN_PROGRESS_FIELD);
2515
+ }
2516
+ var COMMAND_SEPARATOR = /&&|\|\||;/u;
2517
+ function label_issue(part) {
2518
+ const matched = ISSUE_LABELS_PATTERN.exec(part);
2519
+ return matched?.[1] === void 0 ? NO_ISSUE : Number(matched[1]);
2520
+ }
2521
+ function bash_issue(command) {
2522
+ for (const part of command.split(COMMAND_SEPARATOR)) {
2523
+ if (is_in_progress_label(part)) return label_issue(part);
2524
+ }
2525
+ return NO_ISSUE;
2526
+ }
2527
+ function bash_marker(command) {
2528
+ if (is_in_progress_label(command)) return WORKFLOW_MARKER;
2529
+ return is_api_body_write(command) || is_issue_comment(command) ? PLAN_MARKER : NO_MARKER;
2530
+ }
2531
+ var time_markers = {
2532
+ NO_MARKER,
2533
+ PLAN_MARKER,
2534
+ EDIT_MARKER,
2535
+ REVIEW_MARKER,
2536
+ WORKFLOW_MARKER,
2537
+ NO_ISSUE,
2538
+ tool_marker,
2539
+ bash_marker,
2540
+ bash_issue
2541
+ };
2542
+
2543
+ // scripts/lib/status-icons.ts
2544
+ var FAIL_ICON = "\u2717";
2545
+ var PASS_ICON = "\u2714";
2546
+ var status_icons = { FAIL_ICON, PASS_ICON };
2547
+
2548
+ // scripts/josh/josh-verdict.ts
2549
+ var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
2550
+ var GATE_SUBJECT = "verification gate";
2551
+ var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
2552
+ var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
2553
+ var PASSED_VERDICT = "passed";
2554
+ var FAILED_VERDICT = "failed";
2555
+ function format_gate_passed(step_count, total) {
2556
+ return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
2557
+ }
2558
+ function format_gate_failed(failed_labels, total) {
2559
+ return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
2560
+ }
2561
+ var GATE_OPENING_PREFIX = "plan: ";
2562
+ var GATE_OPENING_MARK = " checks at once";
2563
+ function is_gate_opening(line) {
2564
+ const trimmed = line.trimStart();
2565
+ return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
2566
+ }
2567
+ function read_verdict(line) {
2568
+ const trimmed = line.trimStart();
2569
+ if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
2570
+ if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
2571
+ return void 0;
2572
+ }
2573
+ var josh_verdict = {
2574
+ PASSED_VERDICT,
2575
+ FAILED_VERDICT,
2576
+ format_gate_passed,
2577
+ format_gate_failed,
2578
+ GATE_OPENING_MARK,
2579
+ GATE_OPENING_PREFIX,
2580
+ is_gate_opening,
2581
+ read_verdict
2582
+ };
2583
+
2584
+ // scripts/time-runtime/time-reported-failure.ts
2585
+ import { z as z3 } from "zod";
2586
+ var TEXT_BLOCK_SCHEMA = z3.object({ text: z3.string().nullish() });
2587
+ var CONTENT_SCHEMA = z3.union([z3.string(), z3.array(z3.unknown())]);
2588
+ var LINE_SEPARATOR2 = "\n";
2589
+ function block_text(block) {
2590
+ const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
2591
+ return parsed.success ? parsed.data.text ?? "" : "";
2592
+ }
2593
+ function result_text2(content) {
2594
+ const parsed = CONTENT_SCHEMA.safeParse(content);
2595
+ if (!parsed.success) return "";
2596
+ if (typeof parsed.data === "string") return parsed.data;
2597
+ return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
2598
+ }
2599
+ function is_failure_line(line) {
2600
+ return line.trimStart().startsWith(status_icons.FAIL_ICON);
2601
+ }
2602
+ function is_failed_verdict(line) {
2603
+ return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
2604
+ }
2605
+ function is_passed_verdict(line) {
2606
+ return josh_verdict.read_verdict(line) === josh_verdict.PASSED_VERDICT;
2607
+ }
2608
+ function new_scan() {
2609
+ return {
2610
+ did_find: false,
2611
+ has_failure_before_region: false,
2612
+ has_failure_in_region: false,
2613
+ is_region_open: false
2614
+ };
2615
+ }
2616
+ function close_region(scan) {
2617
+ scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
2618
+ scan.has_failure_before_region = false;
2619
+ scan.has_failure_in_region = false;
2620
+ scan.is_region_open = false;
2621
+ }
2622
+ function note_failure(scan) {
2623
+ if (scan.is_region_open) {
2624
+ scan.has_failure_in_region = true;
2625
+ return;
2626
+ }
2627
+ scan.has_failure_before_region = true;
2628
+ }
2629
+ function scan_line(scan, line) {
2630
+ if (is_passed_verdict(line)) {
2631
+ close_region(scan);
2632
+ return;
2633
+ }
2634
+ if (is_failure_line(line)) {
2635
+ note_failure(scan);
2636
+ return;
2637
+ }
2638
+ if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
2639
+ }
2640
+ function scan_body(lines) {
2641
+ const scan = new_scan();
2642
+ for (const line of lines) scan_line(scan, line);
2643
+ return scan;
2644
+ }
2645
+ function did_scan_find(scan) {
2646
+ return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
2647
+ }
2648
+ function has_failure_line(content) {
2649
+ const lines = result_text2(content).split(LINE_SEPARATOR2);
2650
+ if (lines.some((line) => is_failed_verdict(line))) return true;
2651
+ return did_scan_find(scan_body(lines));
2652
+ }
2653
+ function is_reported_failure(josh_command, did_print_failure) {
2654
+ return josh_command !== "" && did_print_failure;
2655
+ }
2656
+ var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
2657
+
2658
+ // scripts/time-runtime/time-single-check.ts
2659
+ var CHECK_COMMANDS = /* @__PURE__ */ new Set([
2660
+ "josh check",
2661
+ "josh cspell",
2662
+ "josh cspell:dot",
2663
+ "josh lint",
2664
+ "josh lint:related",
2665
+ "josh test:related",
2666
+ "josh test:unit"
2667
+ ]);
2668
+ var NO_CHECK = "";
2669
+ var KEY_SEPARATOR = " ";
2670
+ function argument_key(command) {
2671
+ return [...new Set(time_shell.josh_arguments(command))].toSorted(
2672
+ (left, right) => left.localeCompare(right)
2673
+ );
2674
+ }
2675
+ function check_key(josh_command, command) {
2676
+ if (!CHECK_COMMANDS.has(josh_command)) return NO_CHECK;
2677
+ return [josh_command, ...argument_key(command)].join(KEY_SEPARATOR);
2678
+ }
2679
+ var time_single_check = { CHECK_COMMANDS, NO_CHECK, check_key };
2680
+
2681
+ // scripts/time-runtime/time-transcript-line.ts
2682
+ import { z as z4 } from "zod";
2683
+ var BLOCK_SCHEMA2 = z4.object({
2684
+ type: z4.string().nullish(),
2685
+ name: z4.string().nullish(),
2686
+ id: z4.string().nullish(),
2687
+ tool_use_id: z4.string().nullish(),
2688
+ input: z4.unknown().nullish(),
2689
+ // Whether the harness wrote this result back as a failure (joshuafolkken/kit#1309). Present on a
2690
+ // `tool_result` block and on nothing else, and absent even there for the tools that never report
2691
+ // one — which is why it is read as three answers rather than as a boolean with a default.
2692
+ is_error: z4.boolean().nullish(),
2693
+ // What the call printed. Read only to recover the outcome a pipeline threw away
2694
+ // (joshuafolkken/kit#1361): it is kept as flattened text rather than as blocks, because that is
2695
+ // the whole of what `time-reported-failure.ts` asks of it.
2696
+ content: z4.unknown().nullish()
2697
+ });
2698
+ var CONTENT_SCHEMA2 = z4.union([z4.string(), z4.array(BLOCK_SCHEMA2)]);
2699
+ var MESSAGE_SCHEMA3 = z4.object({ id: z4.string().nullish(), content: CONTENT_SCHEMA2.nullish() });
2700
+ var LINE_SCHEMA2 = z4.object({
2701
+ type: z4.string().nullish(),
2702
+ timestamp: z4.string().nullish(),
2703
+ // The branch the line was written on, which is where the issue number lives — `josh git` names a
2704
+ // branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
2705
+ // and `josh cost --issue` answer from the same field (joshuafolkken/kit#1268).
2706
+ gitBranch: z4.string().nullish(),
2707
+ // The two fields outside `message` that the harness writes an end-of-task notice on
2708
+ // (joshuafolkken/kit#1696). **Both are read as `unknown` rather than as strings**: a schema
2709
+ // insisting on a string here would reject every line whose `content` is a list of blocks — which is
2710
+ // most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
2711
+ // reconstructing the elapsed time. The shape is checked at the read below instead.
2712
+ content: z4.unknown().nullish(),
2713
+ attachment: z4.unknown().nullish(),
2714
+ message: MESSAGE_SCHEMA3.nullish()
2715
+ });
2716
+ var UNKNOWN_BRANCH2 = "";
2717
+ var PROMPT_KEY2 = "prompt";
2718
+ var NO_MESSAGE_ID = "";
2719
+ var ERROR_TEXT_LIMIT = 256;
2720
+ var REFUSAL_MARKER = "\u26D4";
2721
+ function block_names(raw) {
2722
+ return {
2723
+ type: raw.type ?? "",
2724
+ name: raw.name ?? "",
2725
+ id: raw.id ?? "",
2726
+ result_id: raw.tool_use_id ?? ""
2727
+ };
2728
+ }
2729
+ function guard_from_refusal(text) {
2730
+ const trimmed = text.trimStart();
2731
+ if (!trimmed.startsWith(REFUSAL_MARKER)) return "";
2732
+ const headline = trimmed.slice(REFUSAL_MARKER.length).split("\n", 1)[0]?.trimStart() ?? "";
2733
+ const colon = headline.indexOf(":");
2734
+ return (colon === -1 ? headline : headline.slice(0, colon)).trim();
2735
+ }
2736
+ function to_block2(raw) {
2737
+ const text = time_reported_failure.result_text(raw.content);
2738
+ const is_error = raw.is_error ?? void 0;
2739
+ return {
2740
+ ...block_names(raw),
2741
+ input: raw.input,
2742
+ is_error,
2743
+ has_failure_line: time_reported_failure.has_failure_line(text),
2744
+ followup_stages: time_followup_stage.read_stages(text),
2745
+ error_text: is_error === true ? text.slice(0, ERROR_TEXT_LIMIT) : "",
2746
+ refusal_guard: is_error === true ? guard_from_refusal(text) : "",
2747
+ background_id: time_background.launch_id(text)
2748
+ };
2749
+ }
2750
+ function to_blocks2(content) {
2751
+ return typeof content === "string" || content === null || content === void 0 ? [] : content.map((block) => to_block2(block));
2752
+ }
2753
+ function message_fields(message) {
2754
+ return { message_id: message?.id ?? NO_MESSAGE_ID, blocks: to_blocks2(message?.content) };
2755
+ }
2756
+ function notice_text(data) {
2757
+ const attachment = json_value.is_record(data.attachment) ? data.attachment[PROMPT_KEY2] : void 0;
2758
+ const carried = [data.message?.content, data.content, attachment];
2759
+ return carried.find((one) => typeof one === "string") ?? "";
2760
+ }
2761
+ function to_line(data) {
2762
+ const timestamp_ms = time_instant.parse_instant(data.timestamp);
2763
+ if (timestamp_ms === void 0) return void 0;
2764
+ return {
2765
+ type: data.type ?? "",
2766
+ timestamp_ms,
2767
+ branch: data.gitBranch ?? UNKNOWN_BRANCH2,
2768
+ finished_background: time_background.finished_id(notice_text(data)),
2769
+ ...message_fields(data.message)
2770
+ };
2771
+ }
2772
+ function parse_line3(line) {
2773
+ const parsed = LINE_SCHEMA2.safeParse(json_value.parse_or_undefined(line));
2774
+ return parsed.success ? to_line(parsed.data) : void 0;
2775
+ }
2776
+ var time_transcript_line = {
2777
+ ERROR_TEXT_LIMIT,
2778
+ REFUSAL_MARKER,
2779
+ NO_MESSAGE_ID,
2780
+ guard_from_refusal,
2781
+ parse_line: parse_line3
2782
+ };
2783
+
2784
+ // scripts/time-runtime/time-writes.ts
2785
+ function bash_writes(command) {
2786
+ const segment = time_bundle_call.write_segment(command);
2787
+ return time_bundle_call.is_in_place_sed(segment) ? time_bundle_call.targets_in(segment) : [];
2788
+ }
2789
+ function tool_writes(name, input) {
2790
+ if (time_markers.tool_marker(name, input) !== time_markers.EDIT_MARKER) return [];
2791
+ return time_bundle_call.tool_targets(input);
2792
+ }
2793
+ var time_writes = {
2794
+ bash_writes,
2795
+ tool_writes
2796
+ };
2797
+
2798
+ // scripts/time-runtime/time-spans.ts
2799
+ var { NO_MESSAGE_ID: NO_MESSAGE_ID2, parse_line: parse_line4 } = time_transcript_line;
2800
+ var ASSISTANT_TYPE2 = "assistant";
2801
+ var USER_TYPE = "user";
2802
+ var UNKNOWN_TOOL = "unknown";
2803
+ var MODEL_CATEGORY = "model";
2804
+ var TOOL_CATEGORY = "tool";
2805
+ var HUMAN_CATEGORY = "human";
2806
+ var OK_OUTCOME = "ok";
2807
+ var FAILED_OUTCOME = "failed";
2808
+ var UNKNOWN_OUTCOME = "unknown";
2809
+ var NO_RESULT = {
2810
+ call_id: "",
2811
+ outcome: UNKNOWN_OUTCOME,
2812
+ refusal_guard: "",
2813
+ background_id: time_background.NO_BACKGROUND,
2814
+ followup_stages: time_followup_stage.NO_STAGES
2815
+ };
2816
+ var NO_CALL = {
2817
+ label: "",
2818
+ josh_command: "",
2819
+ josh_commands: [],
2820
+ check_key: time_single_check.NO_CHECK,
2821
+ marker: time_markers.NO_MARKER,
2822
+ message_id: NO_MESSAGE_ID2,
2823
+ writes: [],
2824
+ issue: time_markers.NO_ISSUE,
2825
+ reads_background: time_background.NO_BACKGROUND,
2826
+ ...time_bundle_call.not_bundleable()
2827
+ };
2828
+ var UNKNOWN_CALL = {
2829
+ label: UNKNOWN_TOOL,
2830
+ josh_command: "",
2831
+ josh_commands: [],
2832
+ check_key: time_single_check.NO_CHECK,
2833
+ marker: time_markers.NO_MARKER,
2834
+ message_id: NO_MESSAGE_ID2,
2835
+ writes: [],
2836
+ issue: time_markers.NO_ISSUE,
2837
+ reads_background: time_background.NO_BACKGROUND,
2838
+ ...time_bundle_call.not_bundleable()
2839
+ };
2840
+ function non_bash_call(name, input, message_id) {
2841
+ return {
2842
+ label: name,
2843
+ josh_command: "",
2844
+ josh_commands: [],
2845
+ check_key: time_single_check.NO_CHECK,
2846
+ marker: time_markers.tool_marker(name, input),
2847
+ message_id,
2848
+ writes: time_writes.tool_writes(name, input),
2849
+ issue: time_markers.NO_ISSUE,
2850
+ // A non-Bash tool joins a backgrounded command too — `BashOutput` carries the shell id in a
2851
+ // field of its own, `Monitor` names the same `…/tasks/<id>.output` path in a command — so the
2852
+ // same reader is asked here rather than the field being left empty for every tool but `Bash`.
2853
+ reads_background: time_background.read_id_of(input),
2854
+ ...time_bundle_call.tool_facts(name, input)
2855
+ };
2856
+ }
2857
+ function bash_call(input, message_id) {
2858
+ const command = time_shell.bash_command(input);
2859
+ const josh_command = time_shell.josh_command_of(command);
2860
+ return {
2861
+ label: time_shell.bash_label(command),
2862
+ josh_command,
2863
+ josh_commands: time_shell.josh_commands_of(command),
2864
+ check_key: time_single_check.check_key(josh_command, command),
2865
+ marker: time_markers.bash_marker(command),
2866
+ message_id,
2867
+ writes: time_writes.bash_writes(command),
2868
+ issue: time_markers.bash_issue(command),
2869
+ reads_background: time_background.read_id_of(input),
2870
+ ...time_bundle_call.bash_facts(command)
2871
+ };
2872
+ }
2873
+ function to_tool_call(name, input, message_id) {
2874
+ if (name !== cost_blocks.BASH_TOOL) return non_bash_call(name, input, message_id);
2875
+ return bash_call(input, message_id);
2876
+ }
2877
+ function tool_use_blocks(lines) {
2878
+ return lines.flatMap(
2879
+ (line) => line.blocks.filter((block) => block.type === cost_blocks.TOOL_USE_TYPE && block.id !== "").map((block) => ({ block, message_id: line.message_id }))
2880
+ );
2881
+ }
2882
+ function collect_calls(lines) {
2883
+ return new Map(
2884
+ tool_use_blocks(lines).map(({ block, message_id }) => [
2885
+ block.id,
2886
+ to_tool_call(block.name, block.input, message_id)
2887
+ ])
2888
+ );
2889
+ }
2890
+ function result_block(line) {
2891
+ return line.blocks.find((block) => block.type === cost_blocks.TOOL_RESULT_TYPE);
2892
+ }
2893
+ function event_of(line, category, call, result = NO_RESULT) {
2894
+ return { timestamp_ms: line.timestamp_ms, branch: line.branch, category, ...result, ...call };
2895
+ }
2896
+ function outcome_of(result, call) {
2897
+ if (time_reported_failure.is_reported_failure(call.josh_command, result.has_failure_line)) {
2898
+ return FAILED_OUTCOME;
2899
+ }
2900
+ if (result.is_error === void 0) return UNKNOWN_OUTCOME;
2901
+ return result.is_error ? FAILED_OUTCOME : OK_OUTCOME;
2902
+ }
2903
+ function facts_of(result, call) {
2904
+ return {
2905
+ call_id: result.result_id,
2906
+ outcome: outcome_of(result, call),
2907
+ refusal_guard: result.refusal_guard,
2908
+ background_id: result.background_id,
2909
+ followup_stages: result.followup_stages
2910
+ };
2911
+ }
2912
+ function user_event(line, calls) {
2913
+ const result = result_block(line);
2914
+ if (result === void 0) return event_of(line, HUMAN_CATEGORY, NO_CALL);
2915
+ const call = calls.get(result.result_id) ?? UNKNOWN_CALL;
2916
+ return event_of(line, TOOL_CATEGORY, call, facts_of(result, call));
2917
+ }
2918
+ function to_event(line, calls) {
2919
+ if (line.type === ASSISTANT_TYPE2) {
2920
+ return event_of(line, MODEL_CATEGORY, { ...NO_CALL, message_id: line.message_id });
2921
+ }
2922
+ return line.type === USER_TYPE ? user_event(line, calls) : void 0;
2923
+ }
2924
+ function to_events(lines, calls) {
2925
+ return lines.map((line) => to_event(line, calls)).filter((event) => event !== void 0).toSorted((left, right) => left.timestamp_ms - right.timestamp_ms);
2926
+ }
2927
+ function equal_durations(duration_ms) {
2928
+ return { duration_ms, own_duration_ms: duration_ms };
2929
+ }
2930
+ function no_background() {
2931
+ const none = time_background.NO_BACKGROUND;
2932
+ return {
2933
+ background_id: none,
2934
+ reads_background: none,
2935
+ background_command: none,
2936
+ background_ended_ms: time_background.NO_FINISH
2937
+ };
2938
+ }
2939
+ function background_fields(event, finished) {
2940
+ return {
2941
+ background_id: event.background_id,
2942
+ reads_background: event.reads_background,
2943
+ background_command: time_background.NO_BACKGROUND,
2944
+ background_ended_ms: finished.get(event.background_id) ?? time_background.NO_FINISH
2945
+ };
2946
+ }
2947
+ function result_facts_of(event) {
2948
+ return {
2949
+ call_id: event.call_id,
2950
+ outcome: event.outcome,
2951
+ refusal_guard: event.refusal_guard,
2952
+ followup_stages: event.followup_stages
2953
+ };
2954
+ }
2955
+ function to_spans(events, finished) {
2956
+ return events.slice(1).map((event, index) => ({
2957
+ category: event.category,
2958
+ label: event.label,
2959
+ josh_command: event.josh_command,
2960
+ josh_commands: event.josh_commands,
2961
+ check_key: event.check_key,
2962
+ marker: event.marker,
2963
+ is_bundleable: event.is_bundleable,
2964
+ targets: event.targets,
2965
+ is_writing: event.is_writing,
2966
+ has_prior_reference: event.has_prior_reference,
2967
+ writes: event.writes,
2968
+ message_id: event.message_id,
2969
+ issue: event.issue,
2970
+ branch: event.branch,
2971
+ ...result_facts_of(event),
2972
+ is_continuation: false,
2973
+ ...background_fields(event, finished),
2974
+ ended_ms: event.timestamp_ms,
2975
+ ...equal_durations(event.timestamp_ms - (events[index]?.timestamp_ms ?? event.timestamp_ms))
2976
+ }));
2977
+ }
2978
+ function parse_timeline(text) {
2979
+ const lines = text.split("\n").map((line) => parse_line4(line)).filter((line) => line !== void 0);
2980
+ const events = to_events(lines, collect_calls(lines));
2981
+ return {
2982
+ started_ms: events[0]?.timestamp_ms ?? 0,
2983
+ ended_ms: events.at(-1)?.timestamp_ms ?? 0,
2984
+ // **The positioning happens here rather than in a caller** (joshuafolkken/kit#1662): a launch and
2985
+ // the call that reads its output are in one transcript, and by the time spans have been merged
2986
+ // across sessions and trimmed they are fragments rather than calls.
2987
+ spans: time_background.positioned(to_spans(events, time_background.finished_at(lines)))
2988
+ };
2989
+ }
2990
+ function has_transcript_data(span_count) {
2991
+ return span_count > 0;
2992
+ }
2993
+ var time_spans = {
2994
+ ASSISTANT_TYPE: ASSISTANT_TYPE2,
2995
+ MODEL_CATEGORY,
2996
+ TOOL_CATEGORY,
2997
+ HUMAN_CATEGORY,
2998
+ OK_OUTCOME,
2999
+ FAILED_OUTCOME,
3000
+ UNKNOWN_OUTCOME,
3001
+ NO_MESSAGE_ID: NO_MESSAGE_ID2,
3002
+ UNKNOWN_TOOL,
3003
+ has_transcript_data,
3004
+ equal_durations,
3005
+ no_background,
3006
+ // Re-exported so the suites that measure how a command is read keep asking one namespace, and so
3007
+ // `time-shell.ts` moving out of this file changed no call site (joshuafolkken/kit#1344).
3008
+ bash_label: time_shell.bash_label,
3009
+ josh_command_of: time_shell.josh_command_of,
3010
+ josh_commands_of: time_shell.josh_commands_of,
3011
+ to_tool_call,
3012
+ parse_line: parse_line4,
3013
+ parse_timeline
3014
+ };
3015
+
3016
+ // scripts/time-runtime/time-round-trips.ts
3017
+ var CALLS_PER_ROUND_TRIP_FLOOR = 1.5;
3018
+ var DENSITY_DECIMALS = 2;
3019
+ var NONE = 0;
3020
+ function is_tool(span) {
3021
+ return span.category === time_spans.TOOL_CATEGORY;
3022
+ }
3023
+ function is_model(span) {
3024
+ return span.category === time_spans.MODEL_CATEGORY;
3025
+ }
3026
+ function started_ms2(span) {
3027
+ return span.ended_ms - span.duration_ms;
3028
+ }
3029
+ function in_time_order(spans) {
3030
+ return spans.toSorted((left, right) => started_ms2(left) - started_ms2(right));
3031
+ }
3032
+ function is_tool_at(spans, index) {
3033
+ const span = spans[index];
3034
+ return span !== void 0 && is_tool(span);
3035
+ }
3036
+ function is_call(span) {
3037
+ return is_tool(span) && !span.is_continuation;
3038
+ }
3039
+ function count_calls(spans) {
3040
+ return spans.filter((span) => is_call(span)).length;
3041
+ }
3042
+ function previous_break(spans, index) {
3043
+ for (let back = index - 1; back >= 0; back -= 1) {
3044
+ const span = spans[back];
3045
+ if (span === void 0 || !is_model(span)) return span;
3046
+ }
3047
+ return void 0;
3048
+ }
3049
+ function continues_turn(spans, index, message_id) {
3050
+ if (message_id === time_spans.NO_MESSAGE_ID) return false;
3051
+ const earlier = previous_break(spans, index);
3052
+ return earlier !== void 0 && !earlier.is_continuation && earlier.message_id === message_id;
3053
+ }
3054
+ function opens_round_trip(spans, index) {
3055
+ const span = spans[index];
3056
+ if (span === void 0 || !is_tool(span) || span.is_continuation || is_tool_at(spans, index - 1)) {
3057
+ return false;
3058
+ }
3059
+ return !continues_turn(spans, index, span.message_id);
3060
+ }
3061
+ function open_trip(walk) {
3062
+ walk.open = [];
3063
+ walk.trips.push(walk.open);
3064
+ }
3065
+ function place_call(walk, span) {
3066
+ if (is_call(span)) walk.open?.push(span);
3067
+ }
3068
+ function step_trip(walk, span, is_opener) {
3069
+ if (is_opener) open_trip(walk);
3070
+ if (is_tool(span)) place_call(walk, span);
3071
+ else if (!is_model(span)) walk.open = void 0;
3072
+ }
3073
+ function group_round_trips(spans) {
3074
+ const ordered = in_time_order(spans);
3075
+ const walk = { trips: [], open: void 0 };
3076
+ for (const [index, span] of ordered.entries()) {
3077
+ step_trip(walk, span, opens_round_trip(ordered, index));
3078
+ }
3079
+ return walk.trips;
3080
+ }
3081
+ function count_round_trips(spans) {
3082
+ return group_round_trips(spans).length;
3083
+ }
3084
+ function turn_key(span, index) {
3085
+ return span.message_id === time_spans.NO_MESSAGE_ID ? `#${String(index)}` : span.message_id;
3086
+ }
3087
+ function count_turns(spans) {
3088
+ const keys = spans.filter((span) => is_model(span)).map((span, index) => turn_key(span, index));
3089
+ return new Set(keys).size;
3090
+ }
3091
+ function per_round_trip(total, round_trip_count) {
3092
+ if (round_trip_count === NONE) return NONE;
3093
+ return total / round_trip_count;
3094
+ }
3095
+ function format_density(density) {
3096
+ return density.toFixed(DENSITY_DECIMALS);
3097
+ }
3098
+ function is_below_floor(density) {
3099
+ return density > NONE && density < CALLS_PER_ROUND_TRIP_FLOOR;
3100
+ }
3101
+ var time_round_trips = {
3102
+ CALLS_PER_ROUND_TRIP_FLOOR,
3103
+ count_calls,
3104
+ count_round_trips,
3105
+ // Exported since joshuafolkken/kit#1406, so a turn is defined in the one module that already
3106
+ // defines a round trip rather than as a span filter in the report next door.
3107
+ count_turns,
3108
+ format_density,
3109
+ // Exported since joshuafolkken/kit#1385, so the per-tool counts are read off the very groups this
3110
+ // module counts rather than off a second grouping beside them.
3111
+ group_round_trips,
3112
+ // Exported since joshuafolkken/kit#1309, so the failure aggregation orders a run's spans through
3113
+ // the one function that already knows why they need it — a second `toSorted` beside it would be
3114
+ // the clone `CLAUDE.md` prohibits, and the seam it guards (a delegated unit's spans appended
3115
+ // after the parent's) is not one a second copy would keep remembering.
3116
+ in_time_order,
3117
+ is_below_floor,
3118
+ // The four below are exported since joshuafolkken/kit#1406, when the model-gap walk moved to
3119
+ // `time-model-gaps.ts` and needed the same predicates and the same opener test this walk uses. A
3120
+ // private copy there would be the clone `CLAUDE.md` prohibits, in the one place a drift would have
3121
+ // the distribution and the count disagreeing about what a round trip is.
3122
+ is_call,
3123
+ is_model,
3124
+ opens_round_trip,
3125
+ per_round_trip,
3126
+ started_ms: started_ms2
3127
+ };
3128
+
3129
+ // scripts/time-runtime/time-density.ts
3130
+ var MIN_ROUND_TRIPS = 10;
3131
+ var NOTICE_INTERVAL_MS = 3e5;
3132
+ var ONE_CALL = 1;
3133
+ var NONE2 = 0;
3134
+ function has_whole_tail(text) {
3135
+ const last = text.split("\n").findLast((line) => line.trim() !== "");
3136
+ return last !== void 0 && time_spans.parse_line(last) !== void 0;
3137
+ }
3138
+ function assistant_lines(text) {
3139
+ return text.split("\n").map((line) => time_spans.parse_line(line)).filter((line) => line?.type === time_spans.ASSISTANT_TYPE);
3140
+ }
3141
+ function last_turn_calls(text) {
3142
+ if (!has_whole_tail(text)) return NONE2;
3143
+ const lines = assistant_lines(text);
3144
+ const message_id = lines.at(-1)?.message_id;
3145
+ if (message_id === void 0 || message_id === time_spans.NO_MESSAGE_ID) return NONE2;
3146
+ return lines.filter((line) => line.message_id === message_id).flatMap((line) => line.blocks).filter((block) => block.type === cost_blocks.TOOL_USE_TYPE).length;
3147
+ }
3148
+ function read_window(text) {
3149
+ const { spans } = time_spans.parse_timeline(text);
3150
+ const round_trip_count = time_round_trips.count_round_trips(spans);
3151
+ const call_count = time_round_trips.count_calls(spans);
3152
+ return {
3153
+ density: time_round_trips.per_round_trip(call_count, round_trip_count),
3154
+ round_trip_count,
3155
+ turn_calls: last_turn_calls(text)
3156
+ };
3157
+ }
3158
+ function is_due(reading, since_last_ms) {
3159
+ if (reading.round_trip_count < MIN_ROUND_TRIPS || reading.turn_calls !== ONE_CALL || !time_round_trips.is_below_floor(reading.density)) {
3160
+ return false;
3161
+ }
3162
+ return since_last_ms >= NOTICE_INTERVAL_MS;
3163
+ }
3164
+ function format_notice(reading) {
3165
+ const density = time_round_trips.format_density(reading.density);
3166
+ const floor = time_round_trips.format_density(time_round_trips.CALLS_PER_ROUND_TRIP_FLOOR);
3167
+ return `\u26A0 batching: ${density} calls per round trip over the last ${String(reading.round_trip_count)}, under the ${floor} floor, and this turn issued one call. Independent reads, greps, gh queries and edits go out together; the criterion is whether this call's input needs another call's result, not what kind of call it is \u2014 prompts/collaboration-workflow/turn-batching.md.`;
3168
+ }
3169
+ var time_density = {
3170
+ MIN_ROUND_TRIPS,
3171
+ NOTICE_INTERVAL_MS,
3172
+ format_notice,
3173
+ is_due,
3174
+ last_turn_calls,
3175
+ read_window
3176
+ };
3177
+
3178
+ // scripts/time-runtime/time-density-hook.ts
3179
+ var TAIL_BYTES = 262144;
3180
+ var FILE_START = 0;
3181
+ var NOTICE_PREFIX = "josh-density-notice-";
3182
+ var NEVER_MS = 0;
3183
+ var payload_schema = z5.object({
3184
+ transcript_path: z5.string().min(1).optional(),
3185
+ // **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
3186
+ // fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
3187
+ // edit of the main line — the opposite of this module's stated failure direction.
3188
+ agent_id: z5.string().nullish()
3189
+ });
3190
+ var notice_schema = z5.object({ notified_at_ms: z5.number() });
3191
+ function parse_transcript_path(raw_payload) {
3192
+ const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
3193
+ if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
3194
+ return time_hook_transcript.transcript_of(parsed.data.transcript_path, parsed.data.agent_id);
3195
+ }
3196
+ function read_tail(file_path, max_bytes = TAIL_BYTES) {
3197
+ const descriptor = openSync(file_path, "r");
3198
+ try {
3199
+ const { size } = fstatSync(descriptor);
3200
+ const length = Math.min(size, max_bytes);
3201
+ const buffer = Buffer.alloc(length);
3202
+ const read = readSync(descriptor, buffer, FILE_START, length, size - length);
3203
+ return buffer.subarray(FILE_START, read).toString("utf8");
3204
+ } finally {
3205
+ closeSync(descriptor);
3206
+ }
3207
+ }
3208
+ function notice_path(transcript_path) {
3209
+ return stamp_file.stamp_path(NOTICE_PREFIX, transcript_path);
3210
+ }
3211
+ function last_notice_ms(source) {
3212
+ const raw = stamp_file.read_stamp_text(source);
3213
+ if (raw === void 0) return NEVER_MS;
3214
+ try {
3215
+ return notice_schema.parse(JSON.parse(raw)).notified_at_ms;
3216
+ } catch {
3217
+ return NEVER_MS;
3218
+ }
3219
+ }
3220
+ function arm_throttle(target, now_ms) {
3221
+ try {
3222
+ stamp_file.write_stamp(target, { notified_at_ms: now_ms });
3223
+ } catch {
3224
+ }
3225
+ }
3226
+ function notice_for(raw_payload, now_ms) {
3227
+ const transcript_path = parse_transcript_path(raw_payload);
3228
+ if (transcript_path === void 0) return void 0;
3229
+ const reading = time_density.read_window(read_tail(transcript_path));
3230
+ const target = notice_path(transcript_path);
3231
+ if (!time_density.is_due(reading, now_ms - last_notice_ms(target))) return void 0;
3232
+ arm_throttle(target, now_ms);
3233
+ return time_density.format_notice(reading);
3234
+ }
3235
+ function density_notice(raw_payload, now_ms = Date.now()) {
3236
+ try {
3237
+ return notice_for(raw_payload, now_ms);
3238
+ } catch {
3239
+ return void 0;
3240
+ }
3241
+ }
3242
+ var time_density_hook = {
3243
+ NOTICE_PREFIX,
3244
+ TAIL_BYTES,
3245
+ density_notice,
3246
+ notice_path,
3247
+ read_tail
3248
+ };
3249
+
3250
+ export {
3251
+ stamp_file,
3252
+ json_value,
3253
+ cost_blocks,
3254
+ ESLINT_EDIT_CACHE_FLAGS,
3255
+ time_shell,
3256
+ time_bundle_call,
3257
+ time_format,
3258
+ time_transcript_line,
3259
+ time_spans,
3260
+ time_round_trips,
3261
+ lane_paths,
3262
+ cost_transcript,
3263
+ time_hook_transcript,
3264
+ time_density_hook
3265
+ };