@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,3425 @@
1
+ import {
2
+ lane_child_marker,
3
+ run_issue_number
4
+ } from "./chunk-N3MJADY7.js";
5
+ import {
6
+ PLATFORM_TEMP_ROOT,
7
+ cost_blocks,
8
+ cost_usage,
9
+ lane_paths,
10
+ stamp_file,
11
+ time_density_hook,
12
+ time_shell,
13
+ time_transcript_line
14
+ } from "./chunk-IMYMAODK.js";
15
+ import {
16
+ ENV_FILE_NAME,
17
+ LANE_SEAT_KEY,
18
+ PORT_SEED_KEY,
19
+ ports
20
+ } from "./chunk-SSX23SJ2.js";
21
+
22
+ // scripts/rules/bash-triggers.ts
23
+ function on_bash_command(is_match) {
24
+ return function is_trigger(call) {
25
+ if (call.name !== cost_blocks.BASH_TOOL) return false;
26
+ return is_match(time_shell.bash_command(call.input));
27
+ };
28
+ }
29
+ var ISSUE_CREATE_COMMAND = /\bgh\s+(?:\S+\s+)*?issue\s+create\b/u;
30
+ var ISSUES_ENDPOINT = /repos\/[^\s'"]*\/issues(?=$|["'\s])/u;
31
+ var TITLE_FIELD = /(?:-f|-F|--field|--raw-field)\s*'?title=/u;
32
+ function is_issue_filing(command) {
33
+ if (ISSUE_CREATE_COMMAND.test(command)) return true;
34
+ return ISSUES_ENDPOINT.test(command) && TITLE_FIELD.test(command);
35
+ }
36
+ var bash_triggers = { is_issue_filing, on_bash_command };
37
+
38
+ // scripts/rules/tail-commands.ts
39
+ function is_bash_use(block) {
40
+ return block.type === cost_blocks.TOOL_USE_TYPE && block.name === cost_blocks.BASH_TOOL;
41
+ }
42
+ function bash_commands_of(line) {
43
+ const parsed = time_transcript_line.parse_line(line);
44
+ if (parsed === void 0) return [];
45
+ return parsed.blocks.filter((block) => is_bash_use(block)).map((block) => time_shell.bash_command(block.input));
46
+ }
47
+ function prior_bash_commands(tail) {
48
+ return tail.split("\n").flatMap((line) => bash_commands_of(line));
49
+ }
50
+ var tail_commands = { bash_commands_of, is_bash_use, prior_bash_commands };
51
+
52
+ // scripts/rules/filing-cap.ts
53
+ var FILING_CAP = 10;
54
+ var CAP_REACHED = FILING_CAP;
55
+ function is_filing_use(block) {
56
+ if (!tail_commands.is_bash_use(block)) return false;
57
+ return bash_triggers.is_issue_filing(time_shell.bash_command(block.input));
58
+ }
59
+ function collect_block(block, found) {
60
+ if (block.result_id !== "") found.refusals.set(block.result_id, block.refusal_guard);
61
+ if (is_filing_use(block)) found.filing_ids.push(block.id);
62
+ }
63
+ function collect_line(line, found) {
64
+ const parsed = time_transcript_line.parse_line(line);
65
+ if (parsed === void 0) return;
66
+ for (const block of parsed.blocks) collect_block(block, found);
67
+ }
68
+ function scan_tail(tail) {
69
+ const found = { filing_ids: [], refusals: /* @__PURE__ */ new Map() };
70
+ for (const line of tail.split("\n")) collect_line(line, found);
71
+ return found;
72
+ }
73
+ function prior_filing_count(tail) {
74
+ const { filing_ids, refusals } = scan_tail(tail);
75
+ return filing_ids.filter((id) => (refusals.get(id) ?? "") === "").length;
76
+ }
77
+ function is_prompt_line(line) {
78
+ const parsed = time_transcript_line.parse_line(line);
79
+ if (parsed?.type !== "user") return false;
80
+ return parsed.blocks.every((block) => block.result_id === "");
81
+ }
82
+ function current_turn(tail) {
83
+ const lines = tail.split("\n");
84
+ const start = lines.findLastIndex((line) => is_prompt_line(line));
85
+ return lines.slice(Math.max(start, 0)).join("\n");
86
+ }
87
+ function turn_filing_count(tail) {
88
+ return prior_filing_count(current_turn(tail));
89
+ }
90
+ function decide(_call, run2) {
91
+ return prior_filing_count(time_density_hook.read_tail(run2.transcript)) >= CAP_REACHED;
92
+ }
93
+ var FILING_CAP_REASON = `\u26D4 filing cap: this run has already filed ${String(FILING_CAP)} Issues, the per-run ceiling \u2014 on reaching it, stop and report rather than filing more. Automatic filing is capped so a run cannot manufacture Issues faster than they can be closed (\`.claude/skills/workflow-commands/SKILL.md\` \u2192 \xA72d, \`observation-filing.md\`). A further Issue that genuinely must exist is a person's call, not this run's. **This rule fires on every filing past the cap, not once per run**, so reissuing the same filing will be refused again.`;
94
+ var ROW = {
95
+ id: "filing-cap",
96
+ is_trigger: bash_triggers.on_bash_command(bash_triggers.is_issue_filing),
97
+ reason: FILING_CAP_REASON,
98
+ decide
99
+ };
100
+ var filing_cap = {
101
+ FILING_CAP,
102
+ FILING_CAP_REASON,
103
+ ROW,
104
+ current_turn,
105
+ decide,
106
+ prior_filing_count,
107
+ turn_filing_count
108
+ };
109
+
110
+ // scripts/git/constants.ts
111
+ import { platform } from "node:os";
112
+ var GIT_COMMAND_UNIX = "/usr/bin/git";
113
+ var PORCELAIN_FLAG = "--porcelain";
114
+ function get_git_command() {
115
+ if (platform() === "win32") {
116
+ return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
117
+ }
118
+ return GIT_COMMAND_UNIX;
119
+ }
120
+ function get_git_command_for_spawn() {
121
+ if (platform() === "win32") {
122
+ return String.raw`C:\Program Files\Git\cmd\git.exe`;
123
+ }
124
+ return GIT_COMMAND_UNIX;
125
+ }
126
+ var git_utilities = {
127
+ get_git_command,
128
+ get_git_command_for_spawn
129
+ };
130
+
131
+ // scripts/git/git-push-transport.ts
132
+ import { execa } from "execa";
133
+
134
+ // scripts/git/git-execa-error.ts
135
+ function get_exit_code(error) {
136
+ if (typeof error !== "object" || error === null) return void 0;
137
+ if (!("exitCode" in error)) return void 0;
138
+ const { exitCode: exit_code } = error;
139
+ return typeof exit_code === "number" ? exit_code : void 0;
140
+ }
141
+ function has_timed_out(error) {
142
+ if (typeof error !== "object" || error === null || !("timedOut" in error)) return false;
143
+ return error.timedOut === true;
144
+ }
145
+ function create_spawn_error(command, exit_code) {
146
+ const exit_code_string = exit_code === void 0 ? "unknown" : String(exit_code);
147
+ const error_message = `git ${command} exited with code ${exit_code_string}`;
148
+ return new Error(error_message, { cause: { exit_code: exit_code_string } });
149
+ }
150
+
151
+ // scripts/git/git-push-transport.ts
152
+ var MS_PER_SECOND = 1e3;
153
+ var PUSH_TIMEOUT_SECONDS = 120;
154
+ var PUSH_TIMEOUT_MS = PUSH_TIMEOUT_SECONDS * MS_PER_SECOND;
155
+ var PUSH_TIMEOUT_LABEL = `${String(PUSH_TIMEOUT_SECONDS)}s`;
156
+ var PUSH_TIMEOUT_MESSAGE = "git push timed out";
157
+ var PUSH_TIMEOUT_EXIT_CODE = "timeout";
158
+ var SSH_KEEPALIVE_OPTIONS = "-o ServerAliveInterval=15 -o ServerAliveCountMax=3";
159
+ var SSH_COMMAND_VARIABLE = "GIT_SSH_COMMAND";
160
+ var SSH_LEGACY_VARIABLE = "GIT_SSH";
161
+ var KEEPALIVE_SSH_COMMAND = `ssh ${SSH_KEEPALIVE_OPTIONS}`;
162
+ var SSH_COMMAND_CONFIG_KEY = "core.sshCommand";
163
+ var PUSH_SUBCOMMAND = "push";
164
+ function to_environment_value(name) {
165
+ return process.env[name]?.trim() ?? "";
166
+ }
167
+ function to_configured_ssh_command() {
168
+ const from_command = to_environment_value(SSH_COMMAND_VARIABLE);
169
+ return from_command === "" ? to_environment_value(SSH_LEGACY_VARIABLE) : from_command;
170
+ }
171
+ async function has_configured_ssh_command() {
172
+ if (to_configured_ssh_command() !== "") return true;
173
+ try {
174
+ const git_command_bin = git_utilities.get_git_command_for_spawn();
175
+ const { stdout } = await execa(git_command_bin, ["config", "--get", SSH_COMMAND_CONFIG_KEY]);
176
+ return stdout.trim() !== "";
177
+ } catch {
178
+ return false;
179
+ }
180
+ }
181
+ async function to_push_options() {
182
+ const should_keep_alive = !await has_configured_ssh_command();
183
+ return {
184
+ stdio: "inherit",
185
+ timeout: PUSH_TIMEOUT_MS,
186
+ env: should_keep_alive ? { [SSH_COMMAND_VARIABLE]: KEEPALIVE_SSH_COMMAND } : {}
187
+ };
188
+ }
189
+ async function did_push_time_out(arguments_list) {
190
+ const git_command_bin = git_utilities.get_git_command_for_spawn();
191
+ const options = await to_push_options();
192
+ try {
193
+ await execa(git_command_bin, [PUSH_SUBCOMMAND, ...arguments_list], options);
194
+ return false;
195
+ } catch (error) {
196
+ if (has_timed_out(error)) return true;
197
+ throw create_spawn_error(PUSH_SUBCOMMAND, get_exit_code(error));
198
+ }
199
+ }
200
+ function to_manual_command(arguments_list) {
201
+ return ["git", PUSH_SUBCOMMAND, ...arguments_list].join(" ");
202
+ }
203
+ function to_retry_notice(arguments_list) {
204
+ return `${PUSH_TIMEOUT_MESSAGE} after ${PUSH_TIMEOUT_LABEL} \u2014 retrying once: ${to_manual_command(arguments_list)}`;
205
+ }
206
+ function create_timeout_error(arguments_list) {
207
+ const message = `${PUSH_TIMEOUT_MESSAGE} twice (${PUSH_TIMEOUT_LABEL} each). Re-run it by hand: ${to_manual_command(arguments_list)}`;
208
+ return new Error(message, { cause: { exit_code: PUSH_TIMEOUT_EXIT_CODE } });
209
+ }
210
+ async function push(arguments_list) {
211
+ if (!await did_push_time_out(arguments_list)) return;
212
+ console.warn(to_retry_notice(arguments_list));
213
+ if (!await did_push_time_out(arguments_list)) return;
214
+ throw create_timeout_error(arguments_list);
215
+ }
216
+ var git_push_transport = {
217
+ push
218
+ };
219
+
220
+ // scripts/git/git-spawn.ts
221
+ import { execa as execa2 } from "execa";
222
+ async function read(arguments_) {
223
+ const git_cmd = git_utilities.get_git_command_for_spawn();
224
+ const { stdout } = await execa2(git_cmd, arguments_);
225
+ return stdout.trimEnd();
226
+ }
227
+ async function with_output(command, arguments_list) {
228
+ const git_command_bin = git_utilities.get_git_command_for_spawn();
229
+ try {
230
+ await execa2(git_command_bin, [command, ...arguments_list], { stdio: "inherit" });
231
+ } catch (error) {
232
+ throw create_spawn_error(command, get_exit_code(error));
233
+ }
234
+ }
235
+ var git_spawn = {
236
+ read,
237
+ with_output
238
+ };
239
+
240
+ // scripts/git/git-command.ts
241
+ async function branch() {
242
+ return await git_spawn.read(["rev-parse", "--abbrev-ref", "HEAD"]);
243
+ }
244
+ async function status() {
245
+ return await git_spawn.read(["status", PORCELAIN_FLAG, "--untracked-files=normal"]);
246
+ }
247
+ async function repository_root() {
248
+ return await git_spawn.read(["rev-parse", "--show-toplevel"]);
249
+ }
250
+ async function head_commit() {
251
+ return await git_spawn.read(["rev-parse", "HEAD"]);
252
+ }
253
+ var GIT_DIRECTORY_ARGUMENTS = [
254
+ "rev-parse",
255
+ "--absolute-git-dir",
256
+ "--path-format=absolute",
257
+ "--git-common-dir"
258
+ ];
259
+ async function git_directories() {
260
+ const output = await git_spawn.read([...GIT_DIRECTORY_ARGUMENTS]);
261
+ return output.split("\n").filter((line) => line !== "");
262
+ }
263
+ async function diff_cached(file_path) {
264
+ return await git_spawn.read(["diff", "--cached", file_path]);
265
+ }
266
+ var REFS_REMOTES_ORIGIN_PREFIX = "refs/remotes/origin/";
267
+ var NAME_ONLY_FLAG = "--name-only";
268
+ var DEFAULT_BRANCH_FALLBACK = "main";
269
+ async function get_default_branch() {
270
+ try {
271
+ const output = await git_spawn.read(["symbolic-ref", "refs/remotes/origin/HEAD"]);
272
+ const trimmed2 = output.trim();
273
+ if (trimmed2.startsWith(REFS_REMOTES_ORIGIN_PREFIX)) {
274
+ return trimmed2.slice(REFS_REMOTES_ORIGIN_PREFIX.length);
275
+ }
276
+ } catch {
277
+ }
278
+ return DEFAULT_BRANCH_FALLBACK;
279
+ }
280
+ var MERGE_BASE_COMMAND = "merge-base";
281
+ async function reference_exists(reference) {
282
+ try {
283
+ await git_spawn.read(["rev-parse", "--verify", "--quiet", reference]);
284
+ return true;
285
+ } catch {
286
+ return false;
287
+ }
288
+ }
289
+ async function default_branch_reference() {
290
+ const default_branch = await get_default_branch();
291
+ const remote_reference = `${REFS_REMOTES_ORIGIN_PREFIX}${default_branch}`;
292
+ return await reference_exists(remote_reference) ? remote_reference : default_branch;
293
+ }
294
+ async function change_base() {
295
+ const default_branch = await default_branch_reference();
296
+ try {
297
+ return await git_spawn.read([MERGE_BASE_COMMAND, default_branch, "HEAD"]);
298
+ } catch {
299
+ return default_branch;
300
+ }
301
+ }
302
+ async function diff_main(file_path) {
303
+ return await git_spawn.read(["diff", await change_base(), "--", file_path]);
304
+ }
305
+ var NO_PATH_QUOTING = ["-c", "core.quotePath=false"];
306
+ var NO_RELATIVE_PATHS = "--no-relative";
307
+ var NO_RENAME_DETECTION = "--no-renames";
308
+ async function change_base_commit() {
309
+ return await git_spawn.read(["rev-parse", await change_base()]);
310
+ }
311
+ async function diff_main_names() {
312
+ return await git_spawn.read([
313
+ ...NO_PATH_QUOTING,
314
+ "diff",
315
+ NAME_ONLY_FLAG,
316
+ NO_RELATIVE_PATHS,
317
+ NO_RENAME_DETECTION,
318
+ await change_base(),
319
+ "--"
320
+ ]);
321
+ }
322
+ async function diff_cached_names() {
323
+ return await git_spawn.read([
324
+ ...NO_PATH_QUOTING,
325
+ "diff",
326
+ "--cached",
327
+ NAME_ONLY_FLAG,
328
+ NO_RELATIVE_PATHS,
329
+ NO_RENAME_DETECTION
330
+ ]);
331
+ }
332
+ async function diff_main_numstat() {
333
+ return await git_spawn.read([
334
+ ...NO_PATH_QUOTING,
335
+ "diff",
336
+ "--numstat",
337
+ NO_RELATIVE_PATHS,
338
+ NO_RENAME_DETECTION,
339
+ await change_base(),
340
+ "--"
341
+ ]);
342
+ }
343
+ var WHOLE_TREE_PATHSPEC = ":/";
344
+ async function untracked_names() {
345
+ return await git_spawn.read([
346
+ ...NO_PATH_QUOTING,
347
+ "ls-files",
348
+ "--others",
349
+ "--exclude-standard",
350
+ "--full-name",
351
+ WHOLE_TREE_PATHSPEC
352
+ ]);
353
+ }
354
+ async function fetch_branch(branch_name) {
355
+ const refspec = `+refs/heads/${branch_name}:refs/remotes/origin/${branch_name}`;
356
+ return await git_spawn.read(["fetch", "origin", refspec]);
357
+ }
358
+ async function merge_fast_forward(branch_name) {
359
+ return await git_spawn.read(["merge", "--ff-only", `origin/${branch_name}`]);
360
+ }
361
+ async function merge_branch(branch_name, message) {
362
+ const message_arguments = message === void 0 ? [] : ["-m", message];
363
+ await git_spawn.with_output("merge", [...message_arguments, `origin/${branch_name}`]);
364
+ }
365
+ async function checkout_b(branch_name) {
366
+ return await git_spawn.read(["checkout", "-b", branch_name]);
367
+ }
368
+ async function checkout(branch_name) {
369
+ return await git_spawn.read(["checkout", branch_name]);
370
+ }
371
+ async function commit(message) {
372
+ await git_spawn.with_output("commit", ["-m", message]);
373
+ }
374
+ async function delete_branch(branch_name) {
375
+ await git_spawn.read(["branch", "-d", branch_name]);
376
+ }
377
+ async function commit_count_beyond(base, tip) {
378
+ const range = `${base}..${tip}`;
379
+ const output = await git_spawn.read(["rev-list", "--count", range]);
380
+ const parsed = Number(output);
381
+ if (output.length > 0 && Number.isFinite(parsed)) return parsed;
382
+ throw new Error(`\`git rev-list --count ${range}\` printed \`${output}\` rather than a count`);
383
+ }
384
+ function is_exit_code_128(cause) {
385
+ return typeof cause === "object" && cause !== null && "exit_code" in cause && cause.exit_code === "128";
386
+ }
387
+ function is_upstream_not_set_error(error) {
388
+ if (!(error instanceof Error)) return false;
389
+ const { cause } = error;
390
+ return cause !== void 0 && is_exit_code_128(cause);
391
+ }
392
+ async function push_with_upstream(branch_name) {
393
+ await git_push_transport.push(["--set-upstream", "origin", branch_name]);
394
+ }
395
+ async function push2() {
396
+ try {
397
+ await git_push_transport.push([]);
398
+ } catch (error) {
399
+ if (is_upstream_not_set_error(error)) {
400
+ const current_branch = await branch();
401
+ await push_with_upstream(current_branch);
402
+ return;
403
+ }
404
+ throw error;
405
+ }
406
+ }
407
+ async function pull_fast_forward() {
408
+ await git_spawn.with_output("pull", ["--ff-only"]);
409
+ }
410
+ var SHORT_NAME_FORMAT = "--format=%(refname:short)";
411
+ var REMOTES_FLAG = "--remotes";
412
+ async function list_branches(flags, pattern) {
413
+ try {
414
+ const output = await git_spawn.read([
415
+ "branch",
416
+ "--list",
417
+ SHORT_NAME_FORMAT,
418
+ ...flags,
419
+ pattern
420
+ ]);
421
+ return output.split("\n").filter((line) => line.trim() !== "");
422
+ } catch {
423
+ return [];
424
+ }
425
+ }
426
+ async function branch_names(pattern) {
427
+ return await list_branches([], pattern);
428
+ }
429
+ async function branch_names_remote(pattern) {
430
+ return await list_branches([REMOTES_FLAG], pattern);
431
+ }
432
+ async function branch_exists(branch_name) {
433
+ const names = await branch_names(branch_name);
434
+ return names.length > 0;
435
+ }
436
+ var ALL_PATHS_PATHSPEC = ":/";
437
+ function exclude_pathspec(file_path) {
438
+ return `:(exclude,top)${file_path}`;
439
+ }
440
+ async function add_tracked(excluded_paths) {
441
+ const exclusions = excluded_paths.map((file_path) => exclude_pathspec(file_path));
442
+ await git_spawn.read(["add", "-u", "--", ALL_PATHS_PATHSPEC, ...exclusions]);
443
+ }
444
+ async function add_path(file_path) {
445
+ await git_spawn.with_output("add", ["--", file_path]);
446
+ }
447
+ var FIRST_PARENT_FLAG = "--first-parent";
448
+ async function log_first_parent(limit, file_path, tip = "HEAD") {
449
+ const output = await git_spawn.read([
450
+ "log",
451
+ FIRST_PARENT_FLAG,
452
+ "--format=%H",
453
+ `-n`,
454
+ String(limit),
455
+ tip,
456
+ "--",
457
+ file_path
458
+ ]);
459
+ return output.split("\n").filter((line) => line.length > 0);
460
+ }
461
+ async function show_file(spec) {
462
+ return await git_spawn.read(["show", spec]);
463
+ }
464
+ var MERGE_COUNT_ARGUMENTS = [
465
+ "rev-list",
466
+ "--count",
467
+ "--merges",
468
+ FIRST_PARENT_FLAG
469
+ ];
470
+ function merge_count_arguments(range) {
471
+ return [...MERGE_COUNT_ARGUMENTS, range];
472
+ }
473
+ async function count_merges(range) {
474
+ const output = await git_spawn.read(merge_count_arguments(range));
475
+ const parsed = Number(output.trim());
476
+ return Number.isFinite(parsed) ? parsed : 0;
477
+ }
478
+ var git_command = {
479
+ GIT_DIRECTORY_ARGUMENTS,
480
+ branch,
481
+ status,
482
+ repository_root,
483
+ head_commit,
484
+ git_directories,
485
+ diff_cached,
486
+ diff_cached_names,
487
+ diff_main,
488
+ change_base,
489
+ change_base_commit,
490
+ diff_main_names,
491
+ diff_main_numstat,
492
+ untracked_names,
493
+ get_default_branch,
494
+ default_branch_reference,
495
+ fetch_branch,
496
+ merge_fast_forward,
497
+ merge_branch,
498
+ checkout_b,
499
+ checkout,
500
+ commit,
501
+ commit_count_beyond,
502
+ delete_branch,
503
+ push: push2,
504
+ pull_fast_forward,
505
+ branch_exists,
506
+ branch_names,
507
+ branch_names_remote,
508
+ add_tracked,
509
+ add_path,
510
+ log_first_parent,
511
+ show_file,
512
+ count_merges,
513
+ merge_count_arguments,
514
+ is_upstream_not_set_error
515
+ };
516
+
517
+ // scripts/run/run-hold.ts
518
+ import { z } from "zod";
519
+ var HOLD_PREFIX = "josh-run-hold-";
520
+ var UNNUMBERED_ISSUE = "new";
521
+ var HOLD_MAX_AGE_HOURS = 8;
522
+ var MILLISECONDS_PER_HOUR = 36e5;
523
+ var HOLD_MAX_AGE_MS = HOLD_MAX_AGE_HOURS * MILLISECONDS_PER_HOUR;
524
+ var RELEASE_COMMAND = "pnpm josh run:release";
525
+ var FORCE_RELEASE_COMMAND = `${RELEASE_COMMAND} --force`;
526
+ var NOT_IDLE = 'that is not "nothing is running here"';
527
+ var FREE_READ = { kind: "free" };
528
+ var UNREADABLE_READ = { kind: "unreadable" };
529
+ function hold_path(git_directory) {
530
+ return stamp_file.stamp_path(HOLD_PREFIX, git_directory);
531
+ }
532
+ async function worktree_directory() {
533
+ const directories = await git_command.git_directories();
534
+ return directories[0];
535
+ }
536
+ async function is_linked_worktree() {
537
+ const directories = await git_command.git_directories();
538
+ return directories[0] !== void 0 && directories[0] !== directories[1];
539
+ }
540
+ var run_hold_schema = z.object({
541
+ issue: z.string(),
542
+ taken_at: z.string(),
543
+ pid: z.number()
544
+ });
545
+ function parse_hold(raw) {
546
+ try {
547
+ const parsed = run_hold_schema.safeParse(JSON.parse(raw));
548
+ return parsed.success ? parsed.data : void 0;
549
+ } catch {
550
+ return void 0;
551
+ }
552
+ }
553
+ function is_stale(hold, now) {
554
+ const taken = Date.parse(hold.taken_at);
555
+ if (Number.isNaN(taken)) return true;
556
+ return now.getTime() - taken > HOLD_MAX_AGE_MS;
557
+ }
558
+ function classify(raw, now) {
559
+ if (raw === void 0) return FREE_READ;
560
+ const hold = parse_hold(raw);
561
+ if (hold === void 0) return UNREADABLE_READ;
562
+ return { kind: is_stale(hold, now) ? "stale" : "held", hold };
563
+ }
564
+ function read_hold(target, now = /* @__PURE__ */ new Date()) {
565
+ return classify(stamp_file.read_stamp_text(target), now);
566
+ }
567
+ function build_hold(issue, now) {
568
+ return { issue, taken_at: now.toISOString(), pid: process.pid };
569
+ }
570
+ function write_hold(target, issue, now = /* @__PURE__ */ new Date()) {
571
+ const hold = build_hold(issue, now);
572
+ stamp_file.write_stamp(target, hold);
573
+ return hold;
574
+ }
575
+ function create_hold(target, issue, now = /* @__PURE__ */ new Date()) {
576
+ return stamp_file.create_stamp(target, build_hold(issue, now));
577
+ }
578
+ async function is_tree_dirty() {
579
+ try {
580
+ const status2 = await git_command.status();
581
+ return status2.trim() !== "";
582
+ } catch {
583
+ return true;
584
+ }
585
+ }
586
+ function release_hold(target) {
587
+ stamp_file.remove_stamp(target);
588
+ }
589
+ function describe_holder(hold) {
590
+ const holder = hold.issue === UNNUMBERED_ISSUE ? "an unnumbered run" : `#${hold.issue}`;
591
+ return `${holder}, recorded ${hold.taken_at} (pid ${String(hold.pid)})`;
592
+ }
593
+ function own_release_command(issue) {
594
+ return issue === UNNUMBERED_ISSUE ? RELEASE_COMMAND : `${RELEASE_COMMAND} ${issue}`;
595
+ }
596
+ function is_own_hold(hold, claimant) {
597
+ return hold.issue === claimant;
598
+ }
599
+ function held_message(hold) {
600
+ return `This working tree is already held by ${describe_holder(hold)}. One run at a time per working tree: a second run here commits its files onto the other run's branch. If that record is stale, run \`${FORCE_RELEASE_COMMAND}\` in this working tree \u2014 it removes a record this run did not write, so be sure the run that did has ended \u2014 and ask again.`;
601
+ }
602
+ function foreign_release_message(hold) {
603
+ return `This working tree is held by ${describe_holder(hold)}, and this release did not claim it \u2014 nothing was removed. Release it as that run with \`${own_release_command(hold.issue)}\`, or, once you are sure it has ended, remove the record with \`${FORCE_RELEASE_COMMAND}\`.`;
604
+ }
605
+ function forced_release_message(hold) {
606
+ return `Forced: removed the run record held by ${describe_holder(hold)}.`;
607
+ }
608
+ function unreadable_message() {
609
+ return `This working tree's run record could not be read \u2014 ${NOT_IDLE}. Run \`${FORCE_RELEASE_COMMAND}\` in this working tree to clear it, then ask again.`;
610
+ }
611
+ function stale_message(hold) {
612
+ return `Replaced a stale run record held by ${describe_holder(hold)}: older than ${String(HOLD_MAX_AGE_HOURS)} hours, so the run that wrote it has ended without releasing it.`;
613
+ }
614
+ function uncommitted_message(hold) {
615
+ return `This working tree still has uncommitted changes, and its run record \u2014 held by ${describe_holder(hold)} \u2014 has expired. That is a run which stopped for a person rather than one that finished, so the tree is not free: commit or stash the work, or run \`${own_release_command(hold.issue)}\` once you are done with it, then ask again.`;
616
+ }
617
+ function race_message(read2, target) {
618
+ if (read2.kind === "held") return held_message(read2.hold);
619
+ return `A record already exists at ${target} and this run did not write it \u2014 ${NOT_IDLE}. Either another run claimed the tree at the same moment, or the record belongs to another account. Run \`${FORCE_RELEASE_COMMAND}\`, and remove that file by hand if it is still there.`;
620
+ }
621
+ function unknown_message() {
622
+ return `Could not read this working tree's git directory \u2014 ${NOT_IDLE}. Run this from inside the checkout the run will edit.`;
623
+ }
624
+ var run_hold = {
625
+ FORCE_RELEASE_COMMAND,
626
+ HOLD_MAX_AGE_HOURS,
627
+ HOLD_MAX_AGE_MS,
628
+ RELEASE_COMMAND,
629
+ UNNUMBERED_ISSUE,
630
+ classify,
631
+ create_hold,
632
+ describe_holder,
633
+ foreign_release_message,
634
+ forced_release_message,
635
+ held_message,
636
+ hold_path,
637
+ is_linked_worktree,
638
+ is_own_hold,
639
+ is_tree_dirty,
640
+ own_release_command,
641
+ parse_hold,
642
+ race_message,
643
+ read_hold,
644
+ release_hold,
645
+ stale_message,
646
+ uncommitted_message,
647
+ unknown_message,
648
+ unreadable_message,
649
+ worktree_directory,
650
+ write_hold
651
+ };
652
+
653
+ // scripts/run/run-cut.ts
654
+ import { execFileSync } from "node:child_process";
655
+
656
+ // scripts/josh/agent-session-environment.ts
657
+ var SESSION_ID_KEY = "CLAUDE_CODE_SESSION_ID";
658
+ var PARENT_SESSION_KEYS = [
659
+ "CLAUDE_CODE_MESSAGING_SOCKET",
660
+ "CLAUDE_CODE_MESSAGING_TOKEN",
661
+ SESSION_ID_KEY,
662
+ "CLAUDE_CODE_CHILD_SESSION"
663
+ ];
664
+ var PROXY_KEYS = [
665
+ "ALL_PROXY",
666
+ "HTTP_PROXY",
667
+ "HTTPS_PROXY",
668
+ "all_proxy",
669
+ "http_proxy",
670
+ "https_proxy",
671
+ "GLOBAL_AGENT_HTTP_PROXY",
672
+ "GLOBAL_AGENT_HTTPS_PROXY"
673
+ ];
674
+ var PROXY_CERTIFICATE_KEY = "NODE_EXTRA_CA_CERTS";
675
+ var LOOPBACK_HOSTS = ["localhost", "ip6-localhost", "[::1]"];
676
+ var LOOPBACK_PREFIX = "127.";
677
+ var NO_HOST = "";
678
+ function parsed_host(value) {
679
+ try {
680
+ return new URL(value).hostname;
681
+ } catch {
682
+ return NO_HOST;
683
+ }
684
+ }
685
+ function proxy_host(value) {
686
+ const direct = parsed_host(value);
687
+ return direct === NO_HOST ? parsed_host(`http://${value}`) : direct;
688
+ }
689
+ function is_loopback_host(host) {
690
+ return host.startsWith(LOOPBACK_PREFIX) || LOOPBACK_HOSTS.includes(host);
691
+ }
692
+ function is_loopback_proxy(value) {
693
+ if (value === void 0 || value === NO_HOST) return false;
694
+ return is_loopback_host(proxy_host(value));
695
+ }
696
+ function is_declared(value) {
697
+ return value !== void 0 && value !== NO_HOST;
698
+ }
699
+ function loopback_proxy_keys(source, is_removed = is_loopback_proxy) {
700
+ const declared = PROXY_KEYS.filter((key) => is_declared(source[key]));
701
+ const matched = declared.filter((key) => is_removed(source[key]));
702
+ const is_certificate_included = matched.length > 0 && matched.length === declared.length;
703
+ return is_certificate_included ? [...matched, PROXY_CERTIFICATE_KEY] : matched;
704
+ }
705
+ function to_removed(keys) {
706
+ return Object.fromEntries(keys.map((key) => [key, void 0]));
707
+ }
708
+ function removed_environment(source = process.env) {
709
+ return to_removed([...PARENT_SESSION_KEYS, ...loopback_proxy_keys(source)]);
710
+ }
711
+ var SCANNER_DIRECTORY = ".safe-chain";
712
+ var PATH_SEPARATOR = /[/\\]/u;
713
+ function is_scanner_certificate(value) {
714
+ return value?.split(PATH_SEPARATOR).includes(SCANNER_DIRECTORY) ?? false;
715
+ }
716
+ var SCANNER_PROXY_KEY = "HTTPS_PROXY";
717
+ function is_scanner_proxy(source) {
718
+ const scanner_proxy = source[SCANNER_PROXY_KEY];
719
+ return function is_match(value) {
720
+ return value === scanner_proxy && is_loopback_proxy(value);
721
+ };
722
+ }
723
+ function removed_proxy_environment(source = process.env) {
724
+ if (!is_scanner_certificate(source[PROXY_CERTIFICATE_KEY])) return {};
725
+ return to_removed(loopback_proxy_keys(source, is_scanner_proxy(source)));
726
+ }
727
+ var agent_session_environment = {
728
+ LOOPBACK_HOSTS,
729
+ PARENT_SESSION_KEYS,
730
+ PROXY_CERTIFICATE_KEY,
731
+ PROXY_KEYS,
732
+ SESSION_ID_KEY,
733
+ removed_environment,
734
+ removed_proxy_environment
735
+ };
736
+
737
+ // scripts/agent/agent-role-profile.ts
738
+ import { z as z2 } from "zod";
739
+ var FIRST_PRINTABLE_CODE = 32;
740
+ var DELETE_CODE = 127;
741
+ var FIRST_CODE_POINT = 0;
742
+ var EMPTY_LENGTH = 0;
743
+ var MAX_VALUE_LENGTH = 4096;
744
+ var ROLE_SCHEMA = z2.enum(["scheduler", "worker", "reviewer"]);
745
+ var PROVIDER_SCHEMA = z2.enum(["anthropic", "openai"]);
746
+ var EFFORT_SCHEMA = z2.enum(["low", "medium", "high", "xhigh", "max"]);
747
+ var PHASE_SCHEMA = z2.enum(["setup", "implementation", "pre-gate"]);
748
+ var PROFILE_SCHEMA = z2.object({
749
+ provider: PROVIDER_SCHEMA.default("anthropic"),
750
+ role: ROLE_SCHEMA,
751
+ model: z2.string(),
752
+ effort: EFFORT_SCHEMA
753
+ });
754
+ var SCHEDULER = "scheduler";
755
+ var WORKER = "worker";
756
+ var REVIEWER = "reviewer";
757
+ var SETUP_PHASE = "setup";
758
+ var IMPLEMENTATION_PHASE = "implementation";
759
+ var PRE_GATE_PHASE = "pre-gate";
760
+ var ANTHROPIC_PROVIDER = "anthropic";
761
+ var OPENAI_PROVIDER = "openai";
762
+ var OPENAI_MODEL = "gpt-6-sol";
763
+ var ANTHROPIC_MODEL = "claude-opus-5-5";
764
+ var CODEX_SESSION_KEY = "CODEX_THREAD_ID";
765
+ var DEFAULT_PROFILES = {
766
+ scheduler: {
767
+ provider: ANTHROPIC_PROVIDER,
768
+ role: SCHEDULER,
769
+ model: ANTHROPIC_MODEL,
770
+ effort: "medium"
771
+ },
772
+ worker: { provider: ANTHROPIC_PROVIDER, role: WORKER, model: ANTHROPIC_MODEL, effort: "medium" },
773
+ reviewer: {
774
+ provider: ANTHROPIC_PROVIDER,
775
+ role: REVIEWER,
776
+ model: ANTHROPIC_MODEL,
777
+ effort: "high"
778
+ }
779
+ };
780
+ var OPENAI_PROFILES = {
781
+ scheduler: { provider: OPENAI_PROVIDER, role: SCHEDULER, model: OPENAI_MODEL, effort: "medium" },
782
+ worker: { provider: OPENAI_PROVIDER, role: WORKER, model: OPENAI_MODEL, effort: "medium" },
783
+ reviewer: { provider: OPENAI_PROVIDER, role: REVIEWER, model: OPENAI_MODEL, effort: "high" }
784
+ };
785
+ var PROVIDER_PROFILES = { anthropic: DEFAULT_PROFILES, openai: OPENAI_PROFILES };
786
+ var SHIP_EFFORT = "low";
787
+ var PHASE_EFFORT = {
788
+ worker: { [PRE_GATE_PHASE]: SHIP_EFFORT }
789
+ };
790
+ var ENV_KEYS = {
791
+ scheduler: { model: "JOSH_SCHEDULER_MODEL", effort: "JOSH_SCHEDULER_EFFORT" },
792
+ worker: { model: "JOSH_WORKER_MODEL", effort: "JOSH_WORKER_EFFORT" },
793
+ reviewer: { model: "JOSH_REVIEWER_MODEL", effort: "JOSH_REVIEWER_EFFORT" }
794
+ };
795
+ var LEGACY_WORKER_KEYS = { model: "JOSH_LANE_MODEL", effort: "JOSH_LANE_EFFORT" };
796
+ function is_control_character(character) {
797
+ const code = character.codePointAt(FIRST_CODE_POINT) ?? FIRST_PRINTABLE_CODE;
798
+ return code < FIRST_PRINTABLE_CODE || code === DELETE_CODE;
799
+ }
800
+ function is_safe_value(value) {
801
+ if (value.length === EMPTY_LENGTH || value.length > MAX_VALUE_LENGTH) return false;
802
+ for (const character of value) if (is_control_character(character)) return false;
803
+ return true;
804
+ }
805
+ function trimmed(value) {
806
+ const result = value?.trim();
807
+ return result === void 0 || result.length === EMPTY_LENGTH ? void 0 : result;
808
+ }
809
+ function override_value(role, field, environment2) {
810
+ const key = ENV_KEYS[role][field];
811
+ const value = trimmed(environment2[key]);
812
+ if (value !== void 0) return { key, value };
813
+ if (role !== WORKER) return { key, value: void 0 };
814
+ const legacy = LEGACY_WORKER_KEYS[field];
815
+ const legacy_value = trimmed(environment2[legacy]);
816
+ return legacy_value === void 0 ? { key, value: void 0 } : { key: legacy, value: legacy_value };
817
+ }
818
+ function model_override(role, environment2, provider) {
819
+ const key = ENV_KEYS[role].model;
820
+ return provider === OPENAI_PROVIDER ? { key, value: void 0 } : override_value(role, "model", environment2);
821
+ }
822
+ function rejection(key, value, expected) {
823
+ return { kind: "rejected", note: `${key}=${value} ${expected}, so the agent was not started` };
824
+ }
825
+ function resolved_effort(override, fallback) {
826
+ const parsed = EFFORT_SCHEMA.safeParse(override.value ?? fallback);
827
+ return parsed.success ? { kind: "effort", effort: parsed.data } : rejection(override.key, override.value ?? "", "is not an allowed effort");
828
+ }
829
+ function has_session(environment2, keys) {
830
+ return keys.some((key) => trimmed(environment2[key]) !== void 0);
831
+ }
832
+ function session_rejection(is_conflicting) {
833
+ const note = is_conflicting ? "both Codex and Claude Code sessions were detected" : "no Codex or Claude Code session was detected";
834
+ return { kind: "rejected", note };
835
+ }
836
+ function resolve_provider(environment2 = process.env) {
837
+ const has_codex = has_session(environment2, [CODEX_SESSION_KEY]);
838
+ const has_claude = has_session(environment2, agent_session_environment.PARENT_SESSION_KEYS);
839
+ if (has_codex === has_claude) return session_rejection(has_codex);
840
+ return { kind: "provider", provider: has_codex ? OPENAI_PROVIDER : ANTHROPIC_PROVIDER };
841
+ }
842
+ function validate(profile, model_key) {
843
+ if (!is_safe_value(profile.model)) {
844
+ return rejection(model_key, profile.model, "is not a safe model");
845
+ }
846
+ return { kind: "profile", profile };
847
+ }
848
+ function phase_effort(role, phase, fallback) {
849
+ const parsed = PHASE_SCHEMA.safeParse(phase);
850
+ if (!parsed.success) return fallback;
851
+ return PHASE_EFFORT[role]?.[parsed.data] ?? fallback;
852
+ }
853
+ function overridden_effort(profile, phase, environment2) {
854
+ const parsed = EFFORT_SCHEMA.safeParse(override_value(profile.role, "effort", environment2).value);
855
+ return parsed.success ? parsed.data : phase_effort(profile.role, phase, profile.effort);
856
+ }
857
+ function with_phase_effort(profile, phase, environment2 = process.env) {
858
+ return { ...profile, effort: overridden_effort(profile, phase, environment2) };
859
+ }
860
+ function resolve(role, environment2 = process.env, phase) {
861
+ const selected = resolve_provider(environment2);
862
+ if (selected.kind === "rejected") return selected;
863
+ const defaults = PROVIDER_PROFILES[selected.provider][role];
864
+ const model = model_override(role, environment2, selected.provider);
865
+ const effort = override_value(role, "effort", environment2);
866
+ const resolved = resolved_effort(effort, phase_effort(role, phase, defaults.effort));
867
+ if (resolved.kind === "rejected") return resolved;
868
+ const profile = {
869
+ provider: selected.provider,
870
+ role,
871
+ model: model.value ?? defaults.model,
872
+ effort: resolved.effort
873
+ };
874
+ return validate(profile, model.key);
875
+ }
876
+ function describe(profile) {
877
+ return `provider=${profile.provider} role=${profile.role} model=${profile.model} effort=${profile.effort}`;
878
+ }
879
+ function parse(value) {
880
+ const parsed = PROFILE_SCHEMA.safeParse(value);
881
+ return parsed.success && is_safe_value(parsed.data.model) ? parsed.data : void 0;
882
+ }
883
+ var agent_role_profile = {
884
+ DEFAULT_PROFILES,
885
+ EFFORT_SCHEMA,
886
+ ENV_KEYS,
887
+ IMPLEMENTATION_PHASE,
888
+ LEGACY_WORKER_KEYS,
889
+ MAX_VALUE_LENGTH,
890
+ OPENAI_PROFILES,
891
+ PHASE_EFFORT,
892
+ PHASE_SCHEMA,
893
+ PRE_GATE_PHASE,
894
+ PROVIDER_SCHEMA,
895
+ PROFILE_SCHEMA,
896
+ REVIEWER,
897
+ SCHEDULER,
898
+ SETUP_PHASE,
899
+ WORKER,
900
+ describe,
901
+ is_safe_value,
902
+ parse,
903
+ phase_effort,
904
+ resolve,
905
+ resolve_provider,
906
+ with_phase_effort
907
+ };
908
+
909
+ // scripts/backlog/backlog-budget.ts
910
+ var MS_PER_MINUTE = 6e4;
911
+ var MINUTES_PER_HOUR = 60;
912
+ var WHOLE_RUN_BUDGET_HOURS = 8;
913
+ var WHOLE_RUN_BUDGET_MINUTES = WHOLE_RUN_BUDGET_HOURS * MINUTES_PER_HOUR;
914
+ var WHOLE_RUN_BUDGET_MS = WHOLE_RUN_BUDGET_MINUTES * MS_PER_MINUTE;
915
+ var DEFAULT_IDLE_MINUTES = 30;
916
+ var DEFAULT_IDLE_MS = DEFAULT_IDLE_MINUTES * MS_PER_MINUTE;
917
+ var IDLE_POLL_MINUTES = 5;
918
+ var RUN_VERDICT = "run";
919
+ var WATCH_VERDICT = "watch";
920
+ var STOP_VERDICT = "stop";
921
+ var ANSWERS = ["blocked", "candidates", "exhausted", "parked", "unreadable"];
922
+ var WHOLE_RUN_REASON = `The whole-run bound of ${String(WHOLE_RUN_BUDGET_HOURS)} hours has passed. An unattended run that has not finished overnight needs a person, not more waiting.`;
923
+ var PARKED_REASON = "Nothing opted in can proceed without a person. Report the parked issues and finish.";
924
+ var UNREADABLE_REASON = "The backlog listing could not be read, so nothing was offered. Report what the command printed and finish \u2014 it is not an empty backlog.";
925
+ var BLOCKED_REASON = "Everything opted in is blocked or already running, so waiting can still change the answer. Poll again at the polling interval.";
926
+ var NO_IDLE_WATCH_REASON = "The backlog is empty and the idle watch was turned off with `--idle 0`, so the run finishes here.";
927
+ function to_minutes(duration_ms) {
928
+ return String(Math.ceil(duration_ms / MS_PER_MINUTE));
929
+ }
930
+ function max_reached_reason(merged, max_issues) {
931
+ return `This run's maximum of ${String(max_issues)} is reached, with ${String(merged)} merged. Report what was done, including how many were picked up during an idle watch, and finish.`;
932
+ }
933
+ function draining_reason(running, reason) {
934
+ return `Start nothing more and poll until the running children merge (running: ${String(running)}). Then report and finish \u2014 ${reason}`;
935
+ }
936
+ function idle_expired_reason(idle_budget_ms) {
937
+ return `The backlog stayed empty for the whole ${to_minutes(idle_budget_ms)}-minute idle watch. Report what was done, including how many were picked up during the watch, and finish.`;
938
+ }
939
+ function next_ask_minutes(left_ms) {
940
+ const left_minutes = Number(to_minutes(left_ms));
941
+ return String(Math.min(IDLE_POLL_MINUTES, left_minutes));
942
+ }
943
+ function idle_watch_reason(left_ms) {
944
+ return `The backlog is empty and the idle watch has about ${to_minutes(left_ms)} minutes left. Release the working tree, ask again in ${next_ask_minutes(left_ms)} minutes, and restart the watch the moment a candidate appears.`;
945
+ }
946
+ function running_watch_reason(running, left_ms) {
947
+ return `The backlog is empty and the idle watch has about ${to_minutes(left_ms)} minutes left, with ${String(running)} still running. Keep the working tree until they merge and poll at the polling interval, not the idle poll \u2014 the watch is running down meanwhile.`;
948
+ }
949
+ function watching_reason(input, left_ms) {
950
+ if (input.running === 0) return idle_watch_reason(left_ms);
951
+ return running_watch_reason(input.running, left_ms);
952
+ }
953
+ function taken_by(input) {
954
+ return input.merged + input.running;
955
+ }
956
+ function run_reason(input) {
957
+ const { max_issues } = input;
958
+ if (max_issues === void 0) return "No maximum was given, so start every issue offered.";
959
+ return `Start at most ${String(max_issues - taken_by(input))} more: this run's maximum is ${String(max_issues)}, with ${String(input.merged)} merged and ${String(input.running)} running.`;
960
+ }
961
+ var ANSWER_STOP_REASONS = {
962
+ parked: PARKED_REASON,
963
+ unreadable: UNREADABLE_REASON
964
+ };
965
+ function whole_run_reason(input) {
966
+ if (input.now_ms - input.started_at_ms < WHOLE_RUN_BUDGET_MS) return void 0;
967
+ return WHOLE_RUN_REASON;
968
+ }
969
+ function stop_reason(input) {
970
+ return ANSWER_STOP_REASONS[input.answer] ?? whole_run_reason(input);
971
+ }
972
+ function stopping(input, reason) {
973
+ if (input.running === 0) return { verdict: STOP_VERDICT, reason };
974
+ return { verdict: WATCH_VERDICT, reason: draining_reason(input.running, reason) };
975
+ }
976
+ function max_decision(input) {
977
+ const { max_issues } = input;
978
+ if (max_issues === void 0 || taken_by(input) < max_issues) return void 0;
979
+ return stopping(input, max_reached_reason(input.merged, max_issues));
980
+ }
981
+ function idle_decision(input) {
982
+ const { idle_budget_ms } = input;
983
+ if (idle_budget_ms === void 0) return stopping(input, NO_IDLE_WATCH_REASON);
984
+ const left_ms = idle_budget_ms - (input.now_ms - input.active_at_ms);
985
+ if (left_ms <= 0) return stopping(input, idle_expired_reason(idle_budget_ms));
986
+ return { verdict: WATCH_VERDICT, reason: watching_reason(input, left_ms) };
987
+ }
988
+ function decide2(input) {
989
+ const reason = stop_reason(input);
990
+ if (reason !== void 0) return stopping(input, reason);
991
+ const capped = max_decision(input);
992
+ if (capped !== void 0) return capped;
993
+ if (input.answer === "candidates") return { verdict: RUN_VERDICT, reason: run_reason(input) };
994
+ if (input.answer === "blocked") return { verdict: WATCH_VERDICT, reason: BLOCKED_REASON };
995
+ return idle_decision(input);
996
+ }
997
+ var backlog_budget = {
998
+ ANSWERS,
999
+ ANSWER_STOP_REASONS,
1000
+ BLOCKED_REASON,
1001
+ DEFAULT_IDLE_MINUTES,
1002
+ DEFAULT_IDLE_MS,
1003
+ IDLE_POLL_MINUTES,
1004
+ MS_PER_MINUTE,
1005
+ NO_IDLE_WATCH_REASON,
1006
+ PARKED_REASON,
1007
+ RUN_VERDICT,
1008
+ STOP_VERDICT,
1009
+ UNREADABLE_REASON,
1010
+ WATCH_VERDICT,
1011
+ WHOLE_RUN_BUDGET_HOURS,
1012
+ WHOLE_RUN_BUDGET_MINUTES,
1013
+ WHOLE_RUN_BUDGET_MS,
1014
+ WHOLE_RUN_REASON,
1015
+ decide: decide2,
1016
+ draining_reason,
1017
+ idle_expired_reason,
1018
+ idle_watch_reason,
1019
+ max_reached_reason,
1020
+ run_reason,
1021
+ running_watch_reason,
1022
+ taken_by
1023
+ };
1024
+
1025
+ // scripts/cost-runtime/cost-pricing.ts
1026
+ var CACHE_WRITE_5M_MULTIPLIER = 1.25;
1027
+ var CACHE_WRITE_1H_MULTIPLIER = 2;
1028
+ var CACHE_READ_MULTIPLIER = 0.1;
1029
+ var TOKENS_PER_MILLION = 1e6;
1030
+ var MODEL_PRICES = {
1031
+ "claude-fable-5": { input: 10, output: 50 },
1032
+ "claude-mythos-5": { input: 10, output: 50 },
1033
+ "claude-opus-5": { input: 5, output: 25 },
1034
+ "claude-opus-4-8": { input: 5, output: 25 },
1035
+ "claude-opus-4-7": { input: 5, output: 25 },
1036
+ "claude-opus-4-6": { input: 5, output: 25 },
1037
+ "claude-sonnet-5": { input: 2, output: 10 },
1038
+ "claude-sonnet-4-6": { input: 3, output: 15 },
1039
+ "claude-haiku-4-5": { input: 1, output: 5 }
1040
+ };
1041
+ var CONTEXT_MARKER = "[";
1042
+ function resolve_price(model) {
1043
+ const base = model.split(CONTEXT_MARKER)[0] ?? model;
1044
+ const direct = MODEL_PRICES[base];
1045
+ if (direct !== void 0) return direct;
1046
+ const [matched] = Object.keys(MODEL_PRICES).filter((id) => base.startsWith(id)).toSorted((left, right) => right.length - left.length);
1047
+ return matched === void 0 ? void 0 : MODEL_PRICES[matched];
1048
+ }
1049
+ function estimate_cost(totals, price) {
1050
+ const weighted_input = totals.input_tokens + totals.cache_write_5m_tokens * CACHE_WRITE_5M_MULTIPLIER + totals.cache_write_1h_tokens * CACHE_WRITE_1H_MULTIPLIER + totals.cache_read_tokens * CACHE_READ_MULTIPLIER;
1051
+ return (weighted_input * price.input + totals.output_tokens * price.output) / TOKENS_PER_MILLION;
1052
+ }
1053
+ function priced(tokens, rate) {
1054
+ return tokens * rate / TOKENS_PER_MILLION;
1055
+ }
1056
+ function estimate_composition(totals, price) {
1057
+ return {
1058
+ input_usd: priced(totals.input_tokens, price.input),
1059
+ cache_write_5m_usd: priced(
1060
+ totals.cache_write_5m_tokens * CACHE_WRITE_5M_MULTIPLIER,
1061
+ price.input
1062
+ ),
1063
+ cache_write_1h_usd: priced(
1064
+ totals.cache_write_1h_tokens * CACHE_WRITE_1H_MULTIPLIER,
1065
+ price.input
1066
+ ),
1067
+ cache_read_usd: priced(totals.cache_read_tokens * CACHE_READ_MULTIPLIER, price.input),
1068
+ output_usd: priced(totals.output_tokens, price.output)
1069
+ };
1070
+ }
1071
+ function to_model_cost(model, totals) {
1072
+ const price = resolve_price(model);
1073
+ if (price === void 0) return { model, totals };
1074
+ return { model, totals, cost_usd: estimate_cost(totals, price) };
1075
+ }
1076
+ function cost_by_model(records) {
1077
+ const grouped = /* @__PURE__ */ new Map();
1078
+ for (const record of records) {
1079
+ const running = grouped.get(record.model) ?? cost_usage.EMPTY_TOTALS;
1080
+ grouped.set(record.model, cost_usage.add_totals(running, record.totals));
1081
+ }
1082
+ return [...grouped].map(([model, totals]) => to_model_cost(model, totals));
1083
+ }
1084
+ function total_cost(costs) {
1085
+ return {
1086
+ usd: costs.reduce((sum, entry) => sum + (entry.cost_usd ?? 0), 0),
1087
+ unpriced: costs.filter((entry) => entry.cost_usd === void 0).map((entry) => entry.model)
1088
+ };
1089
+ }
1090
+ function cost_of(records) {
1091
+ return total_cost(cost_by_model(records)).usd;
1092
+ }
1093
+ var cost_pricing = {
1094
+ CACHE_WRITE_5M_MULTIPLIER,
1095
+ CACHE_WRITE_1H_MULTIPLIER,
1096
+ CACHE_READ_MULTIPLIER,
1097
+ MODEL_PRICES,
1098
+ resolve_price,
1099
+ estimate_cost,
1100
+ estimate_composition,
1101
+ cost_by_model,
1102
+ total_cost,
1103
+ cost_of
1104
+ };
1105
+
1106
+ // scripts/cost-runtime/context-cut-payback.ts
1107
+ var POST_CUT_CONTEXT = 6e4;
1108
+ var EXPECTED_REMAINING_REQUESTS = 10;
1109
+ function write_over_read() {
1110
+ return cost_pricing.CACHE_WRITE_5M_MULTIPLIER / cost_pricing.CACHE_READ_MULTIPLIER;
1111
+ }
1112
+ function break_even_context(remaining = EXPECTED_REMAINING_REQUESTS) {
1113
+ if (remaining <= 0) return Infinity;
1114
+ return Math.round(POST_CUT_CONTEXT * (1 + write_over_read() / remaining));
1115
+ }
1116
+ function break_even_requests(current_context) {
1117
+ const saved_per_request = current_context - POST_CUT_CONTEXT;
1118
+ if (saved_per_request <= 0) return Infinity;
1119
+ return POST_CUT_CONTEXT * write_over_read() / saved_per_request;
1120
+ }
1121
+ function pays_back(current_context, remaining = EXPECTED_REMAINING_REQUESTS) {
1122
+ return current_context > break_even_context(remaining);
1123
+ }
1124
+ var context_cut_payback = {
1125
+ POST_CUT_CONTEXT,
1126
+ EXPECTED_REMAINING_REQUESTS,
1127
+ break_even_context,
1128
+ break_even_requests,
1129
+ pays_back
1130
+ };
1131
+
1132
+ // scripts/cost-runtime/context-cut-threshold.ts
1133
+ var CONTEXT_CUT_THRESHOLD = context_cut_payback.break_even_context();
1134
+ var RECENT_REQUEST_WINDOW = 10;
1135
+
1136
+ // scripts/lane/lane-child-invocation.ts
1137
+ var CHILD_INVOCATION = "fullrun";
1138
+ var RESUME_GUIDE = ".claude/skills/workflow-commands/pre-gate-cut.md";
1139
+ var SHIP_PROCESS = String.raw`(josh(\.[jt]s)? ship|run-ship-cli\.ts)`;
1140
+ function child_invocation(issue) {
1141
+ run_issue_number.require_issue_number(issue);
1142
+ return `${CHILD_INVOCATION} #${issue}`;
1143
+ }
1144
+ function process_pattern(issue) {
1145
+ run_issue_number.require_issue_number(issue);
1146
+ return `(${CHILD_INVOCATION}|${SHIP_PROCESS} .*) #${issue}$`;
1147
+ }
1148
+ function resume_invocation(issue) {
1149
+ const preamble = `Resuming the lane child for issue #${issue} \u2014 do not re-read the workflow-commands entry documents (SKILL.md, fullrun.md). Run \`pnpm josh run:cut --resume ${issue}\` before anything else and follow the matching verdict in ${RESUME_GUIDE}: \`resume\` goes to the gate, \`resume-impl\` continues implementation. Only on \`fresh\` proceed as an ordinary`;
1150
+ return `${preamble} ${child_invocation(issue)}`;
1151
+ }
1152
+ function outage_resume_invocation(issue) {
1153
+ const preamble = `Resuming the lane child for issue #${issue} after an API disconnection \u2014 your session was restored with its full context, so do not re-read the workflow-commands entry documents (SKILL.md, fullrun.md). Continue the run from where it stopped: run \`pnpm josh run:step ${issue}\` to find the next action, redoing only the last step if it did not complete.`;
1154
+ return `${preamble} ${child_invocation(issue)}`;
1155
+ }
1156
+ function ship_stop_invocation(issue) {
1157
+ const preamble = `Resuming the lane child for issue #${issue} after its detached ship supervisor stopped at a failed stage \u2014 do not re-read the workflow-commands entry documents (SKILL.md, fullrun.md). Run \`pnpm josh run:step ${issue}\` and read the stopped report it names, fix what stopped the ship, then hand the region back per chain-rule.md. Do not re-plan or re-implement what is already on the branch.`;
1158
+ return `${preamble} ${child_invocation(issue)}`;
1159
+ }
1160
+ var lane_child_invocation = {
1161
+ CHILD_INVOCATION,
1162
+ child_invocation,
1163
+ outage_resume_invocation,
1164
+ process_pattern,
1165
+ resume_invocation,
1166
+ ship_stop_invocation
1167
+ };
1168
+
1169
+ // scripts/run/run-cut.ts
1170
+ import { z as z4 } from "zod";
1171
+
1172
+ // scripts/run/run-cut-handoff.ts
1173
+ import { readFileSync } from "node:fs";
1174
+ import { z as z3 } from "zod";
1175
+ var handoff_schema = z3.object({
1176
+ instruction: z3.string(),
1177
+ completed: z3.array(z3.string()),
1178
+ remaining: z3.array(z3.string()),
1179
+ untouched: z3.array(z3.string())
1180
+ });
1181
+ var COMPLETED_LABEL = "Completed";
1182
+ var REMAINING_LABEL = "Remaining";
1183
+ var UNTOUCHED_LABEL = "Deliberately untouched";
1184
+ var INSTRUCTION_LABEL = "Instruction (verbatim)";
1185
+ var EMPTY_LIST_NOTE = "(none)";
1186
+ function parse_handoff(raw) {
1187
+ try {
1188
+ const parsed = handoff_schema.safeParse(JSON.parse(raw));
1189
+ return parsed.success ? parsed.data : void 0;
1190
+ } catch {
1191
+ return void 0;
1192
+ }
1193
+ }
1194
+ function read_handoff_file(handoff_path) {
1195
+ try {
1196
+ return parse_handoff(readFileSync(handoff_path, "utf8"));
1197
+ } catch {
1198
+ return void 0;
1199
+ }
1200
+ }
1201
+ function is_complete_handoff(handoff) {
1202
+ return handoff !== void 0 && handoff.instruction.trim() !== "";
1203
+ }
1204
+ function is_within_bound(handoff, max_bytes) {
1205
+ return Buffer.byteLength(JSON.stringify(handoff), "utf8") <= max_bytes;
1206
+ }
1207
+ function load_handoff(handoff_path, max_bytes) {
1208
+ if (handoff_path === void 0) return { kind: "ok", handoff: void 0 };
1209
+ const handoff = read_handoff_file(handoff_path);
1210
+ if (handoff === void 0) {
1211
+ return { kind: "bad", note: `--handoff ${handoff_path} is not a readable handoff file` };
1212
+ }
1213
+ if (!is_within_bound(handoff, max_bytes)) {
1214
+ return { kind: "bad", note: `--handoff ${handoff_path} is too large to carry across the cut` };
1215
+ }
1216
+ return { kind: "ok", handoff };
1217
+ }
1218
+ function describe_list(label, items) {
1219
+ if (items.length === 0) return `${label}: ${EMPTY_LIST_NOTE}`;
1220
+ const bullets = items.map((item) => ` - ${item}`).join("\n");
1221
+ return `${label}:
1222
+ ${bullets}`;
1223
+ }
1224
+ function describe_handoff(handoff) {
1225
+ return [
1226
+ `${INSTRUCTION_LABEL}:
1227
+ ${handoff.instruction}`,
1228
+ describe_list(COMPLETED_LABEL, handoff.completed),
1229
+ describe_list(REMAINING_LABEL, handoff.remaining),
1230
+ describe_list(UNTOUCHED_LABEL, handoff.untouched)
1231
+ ].join("\n\n");
1232
+ }
1233
+ var run_cut_handoff = {
1234
+ describe_handoff,
1235
+ handoff_schema,
1236
+ is_complete_handoff,
1237
+ load_handoff,
1238
+ parse_handoff,
1239
+ read_handoff_file
1240
+ };
1241
+
1242
+ // scripts/run/run-cut.ts
1243
+ var CUT_PREFIX = "josh-run-cut-";
1244
+ var { PRE_GATE_PHASE: PRE_GATE_PHASE2, IMPLEMENTATION_PHASE: IMPLEMENTATION_PHASE2, SETUP_PHASE: SETUP_PHASE2 } = agent_role_profile;
1245
+ var IMPLEMENTATION_CONTEXT_THRESHOLD = CONTEXT_CUT_THRESHOLD;
1246
+ var CUT_MAX_AGE_MS = backlog_budget.WHOLE_RUN_BUDGET_MS;
1247
+ var CUT_MAX_AGE_HOURS = backlog_budget.WHOLE_RUN_BUDGET_HOURS;
1248
+ var GIT_READ_TIMEOUT_MS = 5e3;
1249
+ var WORKTREE_DIRECTORY_INDEX = 0;
1250
+ var COMMON_DIRECTORY_INDEX = 1;
1251
+ var END_COMMAND = "pnpm josh run:cut --end";
1252
+ var READ_COMMAND = "pnpm josh run:cut --json";
1253
+ var MAX_HANDOFF_BYTES = 8192;
1254
+ var NONE_READ = { kind: "none" };
1255
+ var UNREADABLE_READ2 = { kind: "unreadable" };
1256
+ var run_cut_schema = z4.object({
1257
+ invocation: z4.string(),
1258
+ issue: z4.string(),
1259
+ branch: z4.string(),
1260
+ phase: z4.string(),
1261
+ cut_at: z4.string(),
1262
+ is_handed_off: z4.boolean().optional(),
1263
+ handoff: run_cut_handoff.handoff_schema.optional()
1264
+ });
1265
+ function cut_path(git_directory) {
1266
+ return stamp_file.stamp_path(CUT_PREFIX, git_directory);
1267
+ }
1268
+ var { worktree_directory: worktree_directory2 } = run_hold;
1269
+ function invocation_for(issue) {
1270
+ return lane_child_invocation.child_invocation(issue);
1271
+ }
1272
+ function parse_cut(raw) {
1273
+ try {
1274
+ const parsed = run_cut_schema.safeParse(JSON.parse(raw));
1275
+ return parsed.success ? parsed.data : void 0;
1276
+ } catch {
1277
+ return void 0;
1278
+ }
1279
+ }
1280
+ function is_expired(cut, now) {
1281
+ const started = Date.parse(cut.cut_at);
1282
+ if (Number.isNaN(started)) return true;
1283
+ return now.getTime() - started > CUT_MAX_AGE_MS;
1284
+ }
1285
+ function classify2(raw, now) {
1286
+ if (raw === void 0) return NONE_READ;
1287
+ const cut = parse_cut(raw);
1288
+ if (cut === void 0) return UNREADABLE_READ2;
1289
+ return { kind: is_expired(cut, now) ? "expired" : "carried", cut };
1290
+ }
1291
+ function read_cut(target, now = /* @__PURE__ */ new Date()) {
1292
+ return classify2(stamp_file.read_stamp_text(target), now);
1293
+ }
1294
+ function git_directories_sync() {
1295
+ try {
1296
+ const output = execFileSync(
1297
+ git_utilities.get_git_command_for_spawn(),
1298
+ [...git_command.GIT_DIRECTORY_ARGUMENTS],
1299
+ // git's own diagnostics are discarded: a checkout it cannot describe is already the
1300
+ // `undefined` below, and a hook that let `fatal: not a git repository` through would print it
1301
+ // in front of a tool call that is about to be allowed.
1302
+ // A `PreToolUse` hook holds the tool call while it runs, so the read is bounded rather than
1303
+ // left to whatever git does.
1304
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: GIT_READ_TIMEOUT_MS }
1305
+ );
1306
+ return output.split("\n").filter((line) => line !== "");
1307
+ } catch {
1308
+ return [];
1309
+ }
1310
+ }
1311
+ function worktree_git_directory_sync() {
1312
+ return git_directories_sync()[WORKTREE_DIRECTORY_INDEX];
1313
+ }
1314
+ function common_git_directory_sync() {
1315
+ return git_directories_sync()[COMMON_DIRECTORY_INDEX];
1316
+ }
1317
+ function carried_cut_sync(now = /* @__PURE__ */ new Date(), directory = worktree_git_directory_sync()) {
1318
+ if (directory === void 0) return void 0;
1319
+ const read2 = read_cut(cut_path(directory), now);
1320
+ return read2.kind === "carried" ? read2.cut : void 0;
1321
+ }
1322
+ function fresh_cut(spec, now) {
1323
+ return {
1324
+ invocation: invocation_for(spec.issue),
1325
+ issue: spec.issue,
1326
+ branch: spec.branch,
1327
+ phase: spec.phase,
1328
+ cut_at: now.toISOString(),
1329
+ is_handed_off: true,
1330
+ handoff: spec.handoff
1331
+ };
1332
+ }
1333
+ function resumes_into_implementation(phase) {
1334
+ return phase === SETUP_PHASE2 || phase === IMPLEMENTATION_PHASE2;
1335
+ }
1336
+ function within_handoff_bound(cut) {
1337
+ return Buffer.byteLength(JSON.stringify(cut), "utf8") <= MAX_HANDOFF_BYTES;
1338
+ }
1339
+ function record_within_bound(spec, now = /* @__PURE__ */ new Date()) {
1340
+ return within_handoff_bound(fresh_cut(spec, now));
1341
+ }
1342
+ function begin_cut(target, spec, now = /* @__PURE__ */ new Date()) {
1343
+ const cut = fresh_cut(spec, now);
1344
+ if (!within_handoff_bound(cut)) return void 0;
1345
+ return stamp_file.create_stamp(target, cut) ? cut : void 0;
1346
+ }
1347
+ function is_declared_cut(cut, issue) {
1348
+ return cut.is_handed_off === true && cut.invocation === invocation_for(issue);
1349
+ }
1350
+ function matches_state(cut, request) {
1351
+ return cut.branch === request.current_branch && cut.issue === request.issue && request.is_dirty && request.is_held;
1352
+ }
1353
+ function is_adopted_cut(cut, issue) {
1354
+ return cut.is_handed_off === false && cut.invocation === invocation_for(issue);
1355
+ }
1356
+ function has_required_handoff(cut) {
1357
+ return !resumes_into_implementation(cut.phase) || run_cut_handoff.is_complete_handoff(cut.handoff);
1358
+ }
1359
+ function classify_resume(cut, request) {
1360
+ if (is_adopted_cut(cut, request.issue)) return "handed-off";
1361
+ if (!is_declared_cut(cut, request.issue) || !matches_state(cut, request)) return "stale";
1362
+ return has_required_handoff(cut) ? "resume" : "incomplete";
1363
+ }
1364
+ function adopt_cut(target, cut) {
1365
+ const next = { ...cut, is_handed_off: false };
1366
+ stamp_file.remove_stamp(target);
1367
+ return stamp_file.create_stamp(target, next) ? next : void 0;
1368
+ }
1369
+ function end_cut(target) {
1370
+ stamp_file.remove_stamp(target);
1371
+ }
1372
+ function tree_is_held(directory) {
1373
+ if (directory === void 0) return false;
1374
+ const read2 = run_hold.read_hold(run_hold.hold_path(directory));
1375
+ return read2.kind === "held" || read2.kind === "stale";
1376
+ }
1377
+ async function current_state() {
1378
+ const branch2 = await git_command.branch();
1379
+ const is_dirty = await run_hold.is_tree_dirty();
1380
+ const directory = await worktree_directory2();
1381
+ return { branch: branch2, is_dirty, is_held: tree_is_held(directory) };
1382
+ }
1383
+ function describe_cut(cut) {
1384
+ return `${cut.invocation} cut at ${cut.cut_at} on ${cut.branch} (${cut.phase})`;
1385
+ }
1386
+ function busy_message(cut) {
1387
+ return `Another process already resumed this cut \u2014 ${describe_cut(cut)}. Nothing was resumed here; a double launch was detected.`;
1388
+ }
1389
+ function handed_off_message(cut) {
1390
+ return `This cut was already handed off to a successor \u2014 ${describe_cut(cut)}. Nothing was resumed here; the run is being carried on by the process that adopted it, so this one has nothing to do.`;
1391
+ }
1392
+ function stale_message2(cut) {
1393
+ return `This cut does not match the current tree \u2014 ${describe_cut(cut)}. Resume failed; verify the branch and the uncommitted work, then clear it with \`${END_COMMAND}\` if the run is over.`;
1394
+ }
1395
+ function incomplete_message(cut) {
1396
+ return `This cut carries no instruction to resume on \u2014 ${describe_cut(cut)}. Resume was refused rather than continuing without it; recover the run's instruction and work state before implementing, and clear the record with \`${END_COMMAND}\` if the run is over.`;
1397
+ }
1398
+ function unreadable_message2() {
1399
+ return `A cut record is here but could not be read; clear it with \`${END_COMMAND}\` once you know no run is using it. Read it with \`${READ_COMMAND}\`.`;
1400
+ }
1401
+ function unknown_message2() {
1402
+ return "This working tree\u2019s git directory could not be read, so no cut record was acted on.";
1403
+ }
1404
+ var run_cut = {
1405
+ CUT_MAX_AGE_HOURS,
1406
+ CUT_MAX_AGE_MS,
1407
+ END_COMMAND,
1408
+ IMPLEMENTATION_CONTEXT_THRESHOLD,
1409
+ IMPLEMENTATION_PHASE: IMPLEMENTATION_PHASE2,
1410
+ MAX_HANDOFF_BYTES,
1411
+ PRE_GATE_PHASE: PRE_GATE_PHASE2,
1412
+ SETUP_PHASE: SETUP_PHASE2,
1413
+ adopt_cut,
1414
+ begin_cut,
1415
+ busy_message,
1416
+ carried_cut_sync,
1417
+ classify: classify2,
1418
+ classify_resume,
1419
+ common_git_directory_sync,
1420
+ current_state,
1421
+ cut_path,
1422
+ describe_cut,
1423
+ end_cut,
1424
+ fresh_cut,
1425
+ handed_off_message,
1426
+ incomplete_message,
1427
+ invocation_for,
1428
+ is_expired,
1429
+ read_cut,
1430
+ record_within_bound,
1431
+ resumes_into_implementation,
1432
+ stale_message: stale_message2,
1433
+ unknown_message: unknown_message2,
1434
+ unreadable_message: unreadable_message2,
1435
+ within_handoff_bound,
1436
+ worktree_directory: worktree_directory2,
1437
+ worktree_git_directory_sync
1438
+ };
1439
+
1440
+ // scripts/git/issue-labels.ts
1441
+ var IN_PROGRESS_LABEL = "in-progress";
1442
+ var NEEDS_DECISION_LABEL = "needs-decision";
1443
+ var NEEDS_HUMAN_REVIEW_LABEL = "needs-human-review";
1444
+ var ALREADY_DONE_LABEL = "already-done";
1445
+ function has_any_label(labels, wanted) {
1446
+ return (labels ?? []).some((label) => wanted.has(label.name.toLowerCase()));
1447
+ }
1448
+
1449
+ // scripts/rules/shell-segments.ts
1450
+ var SEGMENT_SEPARATOR = /&&|\|\||;|\n/u;
1451
+ function segments_of(command) {
1452
+ return command.split(SEGMENT_SEPARATOR).map((segment) => segment.trim());
1453
+ }
1454
+ function is_josh_command(segment, names) {
1455
+ const named = time_shell.josh_command_of(segment);
1456
+ if (!named.startsWith(time_shell.JOSH_PREFIX)) return false;
1457
+ return names.has(named.slice(time_shell.JOSH_PREFIX.length));
1458
+ }
1459
+ var shell_segments = {
1460
+ SEGMENT_SEPARATOR,
1461
+ is_josh_command,
1462
+ segments_of
1463
+ };
1464
+
1465
+ // scripts/rules/lane-park.ts
1466
+ var NOTIFY_COMMANDS = /* @__PURE__ */ new Set(["notify"]);
1467
+ var CONFIRMATION_TASK_TYPE = /(?:^|\s)--task-type[=\s]+["']?confirmation\b/u;
1468
+ function is_confirmation_notify(command) {
1469
+ return shell_segments.segments_of(command).some(
1470
+ (segment) => shell_segments.is_josh_command(segment, NOTIFY_COMMANDS) && CONFIRMATION_TASK_TYPE.test(segment)
1471
+ );
1472
+ }
1473
+ var NOTIFY_INVOCATION = /josh\s+(?:notify|nf)\b/u;
1474
+ function mentions_confirmation_notify(text) {
1475
+ return NOTIFY_INVOCATION.test(text) && CONFIRMATION_TASK_TYPE.test(text);
1476
+ }
1477
+ function is_unparked_stop(command, is_lane_child = lane_child_marker.is_child_of(process.cwd())) {
1478
+ if (!is_confirmation_notify(command)) return false;
1479
+ return is_lane_child;
1480
+ }
1481
+ var APPLIES_NEEDS_DECISION = new RegExp(
1482
+ String.raw`(?:labels\[\]=|--add-label[= ]'?)${NEEDS_DECISION_LABEL}\b`,
1483
+ "u"
1484
+ );
1485
+ function records_the_park(command) {
1486
+ return APPLIES_NEEDS_DECISION.test(command);
1487
+ }
1488
+ var LANE_PARK_REASON = '\u26D4 lane child park: this session is a dispatched lane child, and a stop that waits on a person must leave the question on the Issue before it sends this Telegram \u2014 otherwise the parent finds an OPEN Issue with `in-progress` and no question, and a person cannot tell what to answer (joshuafolkken/kit#2034 measured this twice in one run). The child is the only process that knows the question, the options and whether it stashed, so it records the park itself rather than leaving the parent to guess from a log. Before you notify and stop: apply `needs-decision` and post a comment carrying the question, the options, and whether work was stashed \u2014 `gh api repos/{owner}/{repo}/issues/<N>/labels -f \'labels[]=needs-decision\'` then `pnpm josh issue:comment <N> --body-file <path>`. If this stop is a `needs-human-review` or `already-done` one, that label is already on the Issue and there is nothing to add. Then reissue this notify \u2014 it fires once per run and cannot repeat on the call in hand. The procedure is `.claude/skills/workflow-commands/pre-gate-cut.md` \u2192 "A lane child records its park before it stops", and the park itself is `backlogrun-park.md` \u2192 "park and continue".';
1489
+ var lane_park = {
1490
+ LANE_PARK_REASON,
1491
+ is_confirmation_notify,
1492
+ is_unparked_stop,
1493
+ mentions_confirmation_notify,
1494
+ records_the_park
1495
+ };
1496
+
1497
+ // scripts/run/run-event-stream.ts
1498
+ import { z as z5 } from "zod";
1499
+ var EVENT_PREFIX = "josh-run-events-";
1500
+ var EVENT_SUFFIX = ".jsonl";
1501
+ var EVENT_CAP = 500;
1502
+ var FIRST_POSITION = 0;
1503
+ var POSITION_INCREMENT = 1;
1504
+ var LINE_SEPARATOR = "\n";
1505
+ var EVENT_KIND = {
1506
+ PLAN: "plan",
1507
+ CHILD_LAUNCH: "child-launch",
1508
+ MERGE: "merge",
1509
+ PARK: "park",
1510
+ OUTAGE: "outage",
1511
+ CUT: "cut",
1512
+ // The backlog emptied while nothing of the run's own was in flight — the drain
1513
+ // (joshuafolkken/kit#2335). It marks the position at which the end-of-run retrospective is owed,
1514
+ // *before* the idle watch opens, so `run:step` fires the retrospective at the drain rather than after
1515
+ // the watch runs its course. It is not itself a stop: the run watches on once the retrospective has
1516
+ // run, and the real `STOP` follows when the watch expires.
1517
+ DRAIN: "drain",
1518
+ STOP: "stop",
1519
+ PR_OPENED: "pr-opened",
1520
+ REVIEW_ROUND: "review-round",
1521
+ // The end-of-run retrospective's result, recorded when the run marks the retrospective done
1522
+ // (joshuafolkken/kit#2342). A retrospective that files zero improvements and one that never ran look
1523
+ // the same from outside — no new Issue either way — so the result is put on the stream the report is
1524
+ // generated from: the issues filed (or that none were), and the candidates dropped with why. It is
1525
+ // emitted from the `run:carry --retrospective` close, so marking the retrospective done and recording
1526
+ // what it found are one action rather than two the run could do only one of.
1527
+ RETROSPECTIVE: "retrospective",
1528
+ // Ready backlog work is sitting undispatched while a lane is free and nothing has dispatched for a
1529
+ // while (joshuafolkken/kit#2359). Emitted once per stall episode by the stop-time detector, it is
1530
+ // both the dedup marker — `emit_once` refuses a second while it is the newest event — and the line a
1531
+ // terminal reader following the stream sees. `run:step` reads it as `backlog:next`, so a run that
1532
+ // stalled is pointed straight at dispatching the work rather than left waiting.
1533
+ STALL: "stall",
1534
+ // The run's own driver is gone: the cut handed the budget off, the owner has died, and no supervisor
1535
+ // is watching (joshuafolkken/kit#2375). Emitted once per strand episode by the stop-time detector,
1536
+ // exactly as `STALL` is — the newest-event dedup keeps a run polled every stop from notifying more
1537
+ // than once, and a terminal reader following the stream sees the line. The strand is the step before
1538
+ // the stall: a stalled run still has a driver that could dispatch, a stranded one has none.
1539
+ STRANDED: "stranded",
1540
+ // One `josh ship` stage starting, succeeding or failing (joshuafolkken/kit#2426). It is a trace of the
1541
+ // composite's progress rather than a position the run is at — the positions a ship leaves behind are
1542
+ // the closed issue its `followup` merges, or a detached supervisor's `SHIP_LAUNCH` / `SHIP_STOP` below
1543
+ // — so it is one of the `TRACE_KINDS` the last-event read skips.
1544
+ SHIP_STAGE: "ship-stage",
1545
+ // One progress watcher line — the `at … / next …` heartbeat `run:progress` prints
1546
+ // (joshuafolkken/kit#2437). Printed only to the watcher's own output, a headless successor's heartbeat
1547
+ // was buried in its log after a cut; on the stream it reaches the attached session's relay. It says
1548
+ // the run is alive rather than where it is, so it is a trace kind like `SHIP_STAGE`.
1549
+ HEARTBEAT: "heartbeat",
1550
+ // The post-implementation region handed to a detached `josh ship --detach` supervisor
1551
+ // (joshuafolkken/kit#2428). Unlike a stage trace it is a position: the agent has ended and the
1552
+ // supervisor carries the run, so `run:step` answers `wait` until it stops or the issue closes.
1553
+ SHIP_LAUNCH: "ship-launch",
1554
+ // The supervisor stopped at a failed stage — a red gate, a High/Medium review, a failed push, red CI
1555
+ // (joshuafolkken/kit#2428). The position that hands control back: `run:step` prints the command that
1556
+ // shows the stopped report, so the agent fixes it and relaunches rather than rebuilding the context.
1557
+ SHIP_STOP: "ship-stop"
1558
+ };
1559
+ var EVENT_KINDS = Object.values(EVENT_KIND);
1560
+ var TRACE_KINDS = /* @__PURE__ */ new Set([EVENT_KIND.SHIP_STAGE, EVENT_KIND.HEARTBEAT]);
1561
+ var event_schema = z5.object({
1562
+ pos: z5.number(),
1563
+ at: z5.string(),
1564
+ kind: z5.string(),
1565
+ text: z5.string()
1566
+ });
1567
+ function is_event_kind(value) {
1568
+ return EVENT_KINDS.includes(value);
1569
+ }
1570
+ function target_of(repository) {
1571
+ return stamp_file.stamp_path(EVENT_PREFIX, repository, EVENT_SUFFIX);
1572
+ }
1573
+ function is_present(event) {
1574
+ return event !== void 0;
1575
+ }
1576
+ function parse_line(line) {
1577
+ try {
1578
+ return event_schema.safeParse(JSON.parse(line)).data;
1579
+ } catch {
1580
+ return void 0;
1581
+ }
1582
+ }
1583
+ function read_events(target) {
1584
+ const raw = stamp_file.read_stamp_text(target);
1585
+ if (raw === void 0) return [];
1586
+ return raw.split(LINE_SEPARATOR).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parse_line(line)).filter(is_present);
1587
+ }
1588
+ function last_position(events) {
1589
+ return events[events.length - POSITION_INCREMENT]?.pos ?? FIRST_POSITION;
1590
+ }
1591
+ function serialize(events) {
1592
+ return `${events.map((event) => JSON.stringify(event)).join(LINE_SEPARATOR)}${LINE_SEPARATOR}`;
1593
+ }
1594
+ function append(target, kind, text, at) {
1595
+ if (!is_event_kind(kind)) return { appended: false, position: FIRST_POSITION };
1596
+ const existing = read_events(target);
1597
+ const position = last_position(existing) + POSITION_INCREMENT;
1598
+ const bounded = [...existing, { pos: position, at, kind, text }].slice(-EVENT_CAP);
1599
+ stamp_file.write_text_stamp(target, serialize(bounded));
1600
+ return { appended: true, position };
1601
+ }
1602
+ function read_from(target, position) {
1603
+ const events = read_events(target);
1604
+ return {
1605
+ events: events.filter((event) => event.pos > position),
1606
+ next_position: last_position(events)
1607
+ };
1608
+ }
1609
+ function read_last(target) {
1610
+ return read_events(target).findLast((event) => !TRACE_KINDS.has(event.kind));
1611
+ }
1612
+ var FIELD_SEPARATOR = " \xB7 ";
1613
+ function format_event(event) {
1614
+ return [event.at, event.kind, event.text].join(FIELD_SEPARATOR);
1615
+ }
1616
+ var run_event_stream = {
1617
+ EVENT_CAP,
1618
+ EVENT_KIND,
1619
+ EVENT_KINDS,
1620
+ EVENT_PREFIX,
1621
+ EVENT_SUFFIX,
1622
+ TRACE_KINDS,
1623
+ append,
1624
+ format_event,
1625
+ is_event_kind,
1626
+ read_events,
1627
+ read_from,
1628
+ read_last,
1629
+ target_of
1630
+ };
1631
+
1632
+ // scripts/discovery/repo-discovery.ts
1633
+ import { existsSync, readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
1634
+ import path from "node:path";
1635
+
1636
+ // scripts/discovery/repo-origin.ts
1637
+ var GITHUB_HOST = "github.com";
1638
+ var SSH_ALIAS_PATTERN = /^github(?:-\w+)*$/u;
1639
+ var GIT_SUFFIX = ".git";
1640
+ var PATH_SEPARATOR2 = "/";
1641
+ var USER_SEPARATOR = "@";
1642
+ var HOST_SEPARATOR = ":";
1643
+ var OWNER_INDEX = 0;
1644
+ var REPO_INDEX = 1;
1645
+ var REPO_PATH_SEGMENTS = 2;
1646
+ var NOT_FOUND = -1;
1647
+ var SECTION_PREFIX = "[";
1648
+ var ORIGIN_SECTION = /^\[remote\s+"origin"\]$/u;
1649
+ var URL_KEY = "url";
1650
+ function is_github_hostname(host) {
1651
+ return host.toLowerCase() === GITHUB_HOST;
1652
+ }
1653
+ function is_github_ssh_host(host) {
1654
+ const normalized = host.toLowerCase();
1655
+ return is_github_hostname(normalized) || SSH_ALIAS_PATTERN.test(normalized);
1656
+ }
1657
+ function strip_git_suffix(name) {
1658
+ return name.endsWith(GIT_SUFFIX) ? name.slice(0, -GIT_SUFFIX.length) : name;
1659
+ }
1660
+ function to_identity(repository_path) {
1661
+ const segments = repository_path.split(PATH_SEPARATOR2).filter((segment) => segment !== "");
1662
+ if (segments.length !== REPO_PATH_SEGMENTS) return void 0;
1663
+ const owner = segments[OWNER_INDEX] ?? "";
1664
+ const repo = strip_git_suffix(segments[REPO_INDEX] ?? "");
1665
+ return repo === "" ? void 0 : { owner, repo };
1666
+ }
1667
+ function parse_scp_like(url) {
1668
+ const user_end = url.indexOf(USER_SEPARATOR);
1669
+ const authority = user_end === NOT_FOUND ? url : url.slice(user_end + 1);
1670
+ const host_end = authority.indexOf(HOST_SEPARATOR);
1671
+ if (host_end === NOT_FOUND) return void 0;
1672
+ if (!is_github_ssh_host(authority.slice(0, host_end))) return void 0;
1673
+ return to_identity(authority.slice(host_end + 1));
1674
+ }
1675
+ function parse_url_like(url) {
1676
+ try {
1677
+ const parsed = new URL(url);
1678
+ return is_github_hostname(parsed.hostname) ? to_identity(parsed.pathname) : void 0;
1679
+ } catch {
1680
+ return void 0;
1681
+ }
1682
+ }
1683
+ function parse_origin_url(url) {
1684
+ const trimmed2 = url.trim();
1685
+ if (trimmed2 === "") return void 0;
1686
+ return parse_url_like(trimmed2) ?? parse_scp_like(trimmed2);
1687
+ }
1688
+ function is_section_header(line) {
1689
+ return line.startsWith(SECTION_PREFIX);
1690
+ }
1691
+ function origin_section_lines(lines) {
1692
+ const start = lines.findIndex((line) => ORIGIN_SECTION.test(line));
1693
+ if (start === NOT_FOUND) return [];
1694
+ const rest = lines.slice(start + 1);
1695
+ const end = rest.findIndex((line) => is_section_header(line));
1696
+ return end === NOT_FOUND ? rest : rest.slice(0, end);
1697
+ }
1698
+ function entry_value(line, key) {
1699
+ const separator = line.indexOf("=");
1700
+ if (separator === NOT_FOUND) return void 0;
1701
+ if (line.slice(0, separator).trim() !== key) return void 0;
1702
+ return line.slice(separator + 1).trim();
1703
+ }
1704
+ function parse_origin_from_config(content) {
1705
+ const lines = content.split("\n").map((line) => line.trim());
1706
+ return origin_section_lines(lines).map((line) => entry_value(line, URL_KEY)).find((url) => url !== void 0);
1707
+ }
1708
+ function format_identity(identity) {
1709
+ return `${identity.owner}${PATH_SEPARATOR2}${identity.repo}`.toLowerCase();
1710
+ }
1711
+ var repo_origin = {
1712
+ GITHUB_HOST,
1713
+ is_github_hostname,
1714
+ is_github_ssh_host,
1715
+ parse_origin_from_config,
1716
+ parse_origin_url,
1717
+ format_identity
1718
+ };
1719
+
1720
+ // scripts/discovery/repo-map-logic.ts
1721
+ var OVERRIDE_ENTRY_SEPARATOR = ",";
1722
+ var OVERRIDE_PAIR_SEPARATOR = "=";
1723
+ var OVERRIDE_PAIR_PARTS = 2;
1724
+ var KEY_INDEX = 0;
1725
+ var PATH_INDEX = 1;
1726
+ function is_same_owner(identity, current_owner2) {
1727
+ return identity.owner.toLowerCase() === current_owner2.toLowerCase();
1728
+ }
1729
+ function add_entry(target, origin_url, repository_path, current_owner2) {
1730
+ if (origin_url === void 0) return;
1731
+ const identity = repo_origin.parse_origin_url(origin_url);
1732
+ if (identity === void 0 || !is_same_owner(identity, current_owner2)) return;
1733
+ target.set(repo_origin.format_identity(identity), repository_path);
1734
+ }
1735
+ function parse_override_entry(entry) {
1736
+ const parts = entry.split(OVERRIDE_PAIR_SEPARATOR).map((part) => part.trim());
1737
+ if (parts.length !== OVERRIDE_PAIR_PARTS) return void 0;
1738
+ const key = parts[KEY_INDEX] ?? "";
1739
+ const repository_path = parts[PATH_INDEX] ?? "";
1740
+ if (repository_path === "") return void 0;
1741
+ return { path: repository_path, origin_url: `https://${repo_origin.GITHUB_HOST}/${key}` };
1742
+ }
1743
+ function parse_overrides(raw) {
1744
+ if (raw === void 0) return [];
1745
+ return raw.split(OVERRIDE_ENTRY_SEPARATOR).map((entry) => parse_override_entry(entry)).filter((entry) => entry !== void 0);
1746
+ }
1747
+ function build_repository_map(discovered, current_owner2, override_value2) {
1748
+ const result = /* @__PURE__ */ new Map();
1749
+ for (const entry of discovered) add_entry(result, entry.origin_url, entry.path, current_owner2);
1750
+ for (const entry of parse_overrides(override_value2)) {
1751
+ add_entry(result, entry.origin_url, entry.path, current_owner2);
1752
+ }
1753
+ return result;
1754
+ }
1755
+ var repo_map_logic = {
1756
+ is_same_owner,
1757
+ parse_overrides,
1758
+ build_repository_map
1759
+ };
1760
+
1761
+ // scripts/discovery/repo-discovery.ts
1762
+ var GIT_DIRECTORY = ".git";
1763
+ var GIT_CONFIG = "config";
1764
+ var GITDIR_PREFIX = "gitdir:";
1765
+ var COMMON_DIRECTORY_FILE = "commondir";
1766
+ var OVERRIDE_ENV_KEY = "JOSH_REPO_PATHS";
1767
+ function resolve_common_directory(git_directory) {
1768
+ const pointer = path.join(git_directory, COMMON_DIRECTORY_FILE);
1769
+ if (!existsSync(pointer)) return git_directory;
1770
+ try {
1771
+ return path.resolve(git_directory, readFileSync2(pointer, "utf8").trim());
1772
+ } catch {
1773
+ return git_directory;
1774
+ }
1775
+ }
1776
+ function follow_git_file(repository_path, git_file) {
1777
+ const pointer = readFileSync2(git_file, "utf8").trim();
1778
+ if (!pointer.startsWith(GITDIR_PREFIX)) return void 0;
1779
+ return path.resolve(repository_path, pointer.slice(GITDIR_PREFIX.length).trim());
1780
+ }
1781
+ function resolve_git_directory(repository_path) {
1782
+ const candidate = path.join(repository_path, GIT_DIRECTORY);
1783
+ if (!existsSync(candidate)) return void 0;
1784
+ try {
1785
+ if (statSync(candidate).isDirectory()) return candidate;
1786
+ const linked = follow_git_file(repository_path, candidate);
1787
+ return linked === void 0 ? void 0 : resolve_common_directory(linked);
1788
+ } catch {
1789
+ return void 0;
1790
+ }
1791
+ }
1792
+ function read_origin_url(repository_path) {
1793
+ const git_directory = resolve_git_directory(repository_path);
1794
+ if (git_directory === void 0) return void 0;
1795
+ try {
1796
+ return repo_origin.parse_origin_from_config(
1797
+ readFileSync2(path.join(git_directory, GIT_CONFIG), "utf8")
1798
+ );
1799
+ } catch {
1800
+ return void 0;
1801
+ }
1802
+ }
1803
+ function sibling_directories(parent) {
1804
+ try {
1805
+ return readdirSync(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path.join(parent, entry.name)).toSorted((left, right) => left.localeCompare(right));
1806
+ } catch {
1807
+ return [];
1808
+ }
1809
+ }
1810
+ function scan_siblings(parent) {
1811
+ return sibling_directories(parent).map((repository_path) => ({
1812
+ path: repository_path,
1813
+ origin_url: read_origin_url(repository_path)
1814
+ }));
1815
+ }
1816
+ function resolve_current_owner(repository_path) {
1817
+ const origin_url = read_origin_url(repository_path);
1818
+ if (origin_url === void 0) return void 0;
1819
+ return repo_origin.parse_origin_url(origin_url)?.owner;
1820
+ }
1821
+ function main_worktree(repository_path) {
1822
+ const git_directory = resolve_git_directory(repository_path);
1823
+ if (git_directory === void 0) return repository_path;
1824
+ if (path.basename(git_directory) !== GIT_DIRECTORY) return repository_path;
1825
+ return path.dirname(git_directory);
1826
+ }
1827
+ function discover_repositories(repository_path, environment2 = process.env) {
1828
+ const main2 = main_worktree(repository_path);
1829
+ const current_owner2 = resolve_current_owner(main2);
1830
+ if (current_owner2 === void 0) return /* @__PURE__ */ new Map();
1831
+ return repo_map_logic.build_repository_map(
1832
+ scan_siblings(path.dirname(main2)),
1833
+ current_owner2,
1834
+ environment2[OVERRIDE_ENV_KEY]
1835
+ );
1836
+ }
1837
+ var repo_discovery = {
1838
+ OVERRIDE_ENV_KEY,
1839
+ main_worktree,
1840
+ read_origin_url,
1841
+ resolve_current_owner,
1842
+ scan_siblings,
1843
+ discover_repositories
1844
+ };
1845
+
1846
+ // scripts/discovery/repo-party.ts
1847
+ var FIRST_PARTY = "first-party";
1848
+ var THIRD_PARTY = "third-party";
1849
+ var UNKNOWN = "unknown";
1850
+ function classify3(session_owner, target) {
1851
+ if (session_owner === void 0 || target === void 0) return UNKNOWN;
1852
+ return session_owner.toLowerCase() === target.toLowerCase() ? FIRST_PARTY : THIRD_PARTY;
1853
+ }
1854
+ function target_owner(owner_repo) {
1855
+ return repo_origin.parse_origin_url(`https://${repo_origin.GITHUB_HOST}/${owner_repo}`)?.owner;
1856
+ }
1857
+ function current_owner(repository_path = process.cwd()) {
1858
+ return repo_discovery.resolve_current_owner(repository_path);
1859
+ }
1860
+ var repo_party = { FIRST_PARTY, THIRD_PARTY, UNKNOWN, classify: classify3, current_owner, target_owner };
1861
+
1862
+ // scripts/josh/process-identity.ts
1863
+ import { execFileSync as execFileSync2, spawnSync } from "node:child_process";
1864
+ import { randomUUID } from "node:crypto";
1865
+ import { readFileSync as readFileSync3, rmSync } from "node:fs";
1866
+ import { createServer } from "node:net";
1867
+ import path2 from "node:path";
1868
+ var PS_COMMAND = "/bin/ps";
1869
+ var FORMAT_FLAG = "-o";
1870
+ var START_TIME_FORMAT = "lstart=";
1871
+ var PID_FLAG = "-p";
1872
+ var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
1873
+ var PROBE_TIMEOUT_MS = 2e3;
1874
+ var LIVENESS_SIGNAL = 0;
1875
+ var LOWEST_REAL_PID = 1;
1876
+ var PROC_START_FIELD_INDEX = 19;
1877
+ var BEACON_SCHEME = "socket:";
1878
+ var BEACON_SUFFIX = ".sock";
1879
+ var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
1880
+ var BEACON_ID_LENGTH = 36;
1881
+ var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
1882
+ var WINDOWS_PLATFORM = "win32";
1883
+ var SOCKET_PROBE_SOURCE = "const net=require('node:net');const socket=net.createConnection(process.argv[1]);socket.once('connect',()=>process.exit(0));socket.once('error',()=>process.exit(1));socket.setTimeout(1000,()=>process.exit(1));";
1884
+ var beacons = /* @__PURE__ */ new Map();
1885
+ var exit_cleanup = { is_registered: false };
1886
+ function is_live_pid(pid) {
1887
+ if (pid < LOWEST_REAL_PID) return false;
1888
+ try {
1889
+ process.kill(pid, LIVENESS_SIGNAL);
1890
+ return true;
1891
+ } catch {
1892
+ return false;
1893
+ }
1894
+ }
1895
+ function read_proc_start(pid) {
1896
+ try {
1897
+ const stat = readFileSync3(`/proc/${String(pid)}/stat`, "utf8");
1898
+ const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
1899
+ const start = fields[PROC_START_FIELD_INDEX];
1900
+ return start === void 0 ? void 0 : `proc:${start}`;
1901
+ } catch {
1902
+ return void 0;
1903
+ }
1904
+ }
1905
+ function read_ps_start(pid) {
1906
+ try {
1907
+ const printed = execFileSync2(
1908
+ PS_COMMAND,
1909
+ [FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
1910
+ {
1911
+ encoding: "utf8",
1912
+ timeout: PROBE_TIMEOUT_MS,
1913
+ stdio: ["ignore", "pipe", "ignore"],
1914
+ env: PROBE_ENVIRONMENT
1915
+ }
1916
+ ).trim();
1917
+ return printed.length > 0 ? printed : void 0;
1918
+ } catch {
1919
+ return void 0;
1920
+ }
1921
+ }
1922
+ var START_PROBES = { read_proc_start, read_ps_start };
1923
+ function safe_probe(probe, pid) {
1924
+ try {
1925
+ return probe(pid);
1926
+ } catch {
1927
+ return void 0;
1928
+ }
1929
+ }
1930
+ function read_start(pid, probes = START_PROBES) {
1931
+ return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
1932
+ }
1933
+ function close_beacon(token) {
1934
+ const server = beacons.get(token);
1935
+ if (server === void 0) return;
1936
+ beacons.delete(token);
1937
+ server.close();
1938
+ rmSync(token.slice(BEACON_SCHEME.length), { force: true });
1939
+ }
1940
+ function close_beacons() {
1941
+ for (const token of beacons.keys()) close_beacon(token);
1942
+ }
1943
+ function ensure_exit_cleanup() {
1944
+ if (exit_cleanup.is_registered) return;
1945
+ exit_cleanup.is_registered = true;
1946
+ process.once("exit", close_beacons);
1947
+ }
1948
+ function ignore_beacon_error() {
1949
+ }
1950
+ function bind_beacon(target) {
1951
+ return createServer().on("error", ignore_beacon_error).listen(target);
1952
+ }
1953
+ function try_bind_beacon(bind, target) {
1954
+ try {
1955
+ const server = bind(target);
1956
+ return server.listening ? server : void 0;
1957
+ } catch {
1958
+ return void 0;
1959
+ }
1960
+ }
1961
+ function open_beacon(bind = bind_beacon) {
1962
+ const target = path2.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
1963
+ const token = `${BEACON_SCHEME}${target}`;
1964
+ const server = try_bind_beacon(bind, target);
1965
+ if (server === void 0) return void 0;
1966
+ server.unref();
1967
+ beacons.set(token, server);
1968
+ ensure_exit_cleanup();
1969
+ return token;
1970
+ }
1971
+ function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
1972
+ const start = read_start(process.pid, probes);
1973
+ if (start !== void 0 || platform2 === WINDOWS_PLATFORM) return start;
1974
+ return open_beacon();
1975
+ }
1976
+ function is_valid_beacon_name(name) {
1977
+ if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
1978
+ const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
1979
+ return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
1980
+ }
1981
+ function beacon_target(token) {
1982
+ if (!token.startsWith(BEACON_SCHEME)) return void 0;
1983
+ const target = token.slice(BEACON_SCHEME.length);
1984
+ if (path2.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
1985
+ return is_valid_beacon_name(path2.basename(target)) ? target : void 0;
1986
+ }
1987
+ function is_live_beacon(target) {
1988
+ return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
1989
+ stdio: "ignore",
1990
+ timeout: PROBE_TIMEOUT_MS
1991
+ }).status === 0;
1992
+ }
1993
+ function has_matching_start(pid, recorded_start, read2) {
1994
+ const observed = read2(pid);
1995
+ return observed === void 0 ? void 0 : observed === recorded_start;
1996
+ }
1997
+ function matches_recorded_start(pid, recorded_start, read2) {
1998
+ const target = beacon_target(recorded_start);
1999
+ return target === void 0 ? has_matching_start(pid, recorded_start, read2) : is_live_beacon(target);
2000
+ }
2001
+ var own_probe = /* @__PURE__ */ new Map();
2002
+ function own_start() {
2003
+ if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
2004
+ return own_probe.get(process.pid);
2005
+ }
2006
+ function own_fields() {
2007
+ const start = own_start();
2008
+ return { pid: process.pid, ...start !== void 0 && { process_start: start } };
2009
+ }
2010
+ function is_same_process(pid, recorded_start, read2 = read_start) {
2011
+ if (pid === void 0 || !is_live_pid(pid)) return false;
2012
+ if (recorded_start === void 0) return void 0;
2013
+ return matches_recorded_start(pid, recorded_start, read2);
2014
+ }
2015
+ function is_own_process(pid, recorded_start) {
2016
+ return pid === process.pid && recorded_start === own_start();
2017
+ }
2018
+ var process_identity = {
2019
+ close_beacon,
2020
+ is_live_pid,
2021
+ is_own_process,
2022
+ is_same_process,
2023
+ open_beacon,
2024
+ own_fields,
2025
+ own_start,
2026
+ read_start,
2027
+ resolve_own_start
2028
+ };
2029
+
2030
+ // scripts/run/run-carry.ts
2031
+ import { z as z6 } from "zod";
2032
+
2033
+ // scripts/run/run-carry-streak.ts
2034
+ var NO_INCREMENT = 0;
2035
+ var OUTAGE_FOLD_WINDOW_MS = 12e4;
2036
+ function has_increment(value) {
2037
+ return (value ?? NO_INCREMENT) > NO_INCREMENT;
2038
+ }
2039
+ function next_failures(carry, change) {
2040
+ if (has_increment(change.merged)) return NO_INCREMENT;
2041
+ return carry.failures + (change.failures ?? NO_INCREMENT);
2042
+ }
2043
+ function is_within_fold_window(last_outage_at, now) {
2044
+ if (last_outage_at === void 0) return false;
2045
+ const last = Date.parse(last_outage_at);
2046
+ if (Number.isNaN(last)) return false;
2047
+ return now.getTime() - last <= OUTAGE_FOLD_WINDOW_MS;
2048
+ }
2049
+ function folded_outage(carry) {
2050
+ return { outages: carry.outages, last_outage_at: carry.last_outage_at };
2051
+ }
2052
+ function counted_outage(carry, change, now) {
2053
+ const outages = carry.outages + (change.outages ?? NO_INCREMENT);
2054
+ return { outages, last_outage_at: now.toISOString() };
2055
+ }
2056
+ function next_outage(carry, change, now) {
2057
+ if (has_increment(change.outages)) {
2058
+ return is_within_fold_window(carry.last_outage_at, now) ? folded_outage(carry) : counted_outage(carry, change, now);
2059
+ }
2060
+ const is_reachable = has_increment(change.merged) || has_increment(change.failures);
2061
+ return is_reachable ? { outages: NO_INCREMENT, last_outage_at: void 0 } : folded_outage(carry);
2062
+ }
2063
+ function next_state(carry, change, now) {
2064
+ const outage = next_outage(carry, change, now);
2065
+ return {
2066
+ failures: next_failures(carry, change),
2067
+ outages: outage.outages,
2068
+ last_outage_at: outage.last_outage_at
2069
+ };
2070
+ }
2071
+ var run_carry_streak = { OUTAGE_FOLD_WINDOW_MS, next_state };
2072
+
2073
+ // scripts/backlog/backlog-budget-cli.ts
2074
+ import { fileURLToPath } from "node:url";
2075
+ import { parseArgs } from "node:util";
2076
+
2077
+ // scripts/git/changed-paths.ts
2078
+ function to_paths(raw) {
2079
+ return raw.split("\n").map((line) => line.trim()).filter((line) => line !== "");
2080
+ }
2081
+ async function read_changed_paths(is_staged) {
2082
+ if (is_staged) return to_paths(await git_command.diff_cached_names());
2083
+ const tracked = to_paths(await git_command.diff_main_names());
2084
+ const untracked = to_paths(await git_command.untracked_names());
2085
+ return [...tracked, ...untracked];
2086
+ }
2087
+ var changed_paths = { read_changed_paths, to_paths };
2088
+
2089
+ // scripts/josh/path-decision.ts
2090
+ var STAGED_FLAG = "--staged";
2091
+ var JSON_FLAG = "--json";
2092
+ var KNOWN_FLAGS = [STAGED_FLAG, JSON_FLAG];
2093
+ var FAILURE_EXIT_CODE = 1;
2094
+ var MAX_LISTED_PATHS = 5;
2095
+ function has_unknown_flag(argv, known) {
2096
+ return argv.some((argument) => !known.includes(argument));
2097
+ }
2098
+ function parse_options(argv) {
2099
+ if (has_unknown_flag(argv, KNOWN_FLAGS)) return void 0;
2100
+ return { is_staged: argv.includes(STAGED_FLAG), is_json: argv.includes(JSON_FLAG) };
2101
+ }
2102
+ function format_path_list(paths) {
2103
+ const listed = paths.slice(0, MAX_LISTED_PATHS).join(", ");
2104
+ if (paths.length <= MAX_LISTED_PATHS) return listed;
2105
+ return `${listed}, +${String(paths.length - MAX_LISTED_PATHS)} more`;
2106
+ }
2107
+ function print_decision(key, answer, reason, is_json) {
2108
+ if (is_json) {
2109
+ console.info(JSON.stringify({ [key]: answer, reason }));
2110
+ return;
2111
+ }
2112
+ console.info(answer);
2113
+ console.error(reason);
2114
+ }
2115
+ async function run_path_decision(argv, command) {
2116
+ const options = parse_options(argv);
2117
+ if (options === void 0) {
2118
+ console.error(command.usage);
2119
+ return FAILURE_EXIT_CODE;
2120
+ }
2121
+ const paths = await changed_paths.read_changed_paths(options.is_staged);
2122
+ const answer = command.decide(paths);
2123
+ print_decision(command.key, answer, command.explain(paths, answer), options.is_json);
2124
+ return 0;
2125
+ }
2126
+ var path_decision = {
2127
+ format_path_list,
2128
+ has_unknown_flag,
2129
+ JSON_FLAG,
2130
+ KNOWN_FLAGS,
2131
+ MAX_LISTED_PATHS,
2132
+ parse_options,
2133
+ print_decision,
2134
+ run_path_decision,
2135
+ STAGED_FLAG
2136
+ };
2137
+
2138
+ // scripts/backlog/backlog-budget-cli.ts
2139
+ var ARGV_OFFSET = 2;
2140
+ var SUCCESS_EXIT_CODE = 0;
2141
+ var FAILURE_EXIT_CODE2 = 1;
2142
+ var JSON_KEY = "budget";
2143
+ var USAGE = `Usage: josh backlog:budget --answer <${backlog_budget.ANSWERS.join("|")}> --started <ISO-8601> [--active <ISO-8601>, required unless the watch is off] [--merged <count>] [--running <count>] [--max <count>] [--idle <minutes>, 0 to turn the watch off] [--json]`;
2144
+ var OPTIONS = {
2145
+ active: { type: "string" },
2146
+ answer: { type: "string" },
2147
+ idle: { type: "string" },
2148
+ json: { type: "boolean" },
2149
+ max: { type: "string" },
2150
+ merged: { type: "string" },
2151
+ running: { type: "string" },
2152
+ started: { type: "string" }
2153
+ };
2154
+ function read_arguments(argv) {
2155
+ try {
2156
+ return parseArgs({ args: [...argv], options: OPTIONS, strict: true }).values;
2157
+ } catch {
2158
+ return void 0;
2159
+ }
2160
+ }
2161
+ function text_of(value) {
2162
+ return typeof value === "string" ? value : void 0;
2163
+ }
2164
+ function to_answer(raw) {
2165
+ return backlog_budget.ANSWERS.find((answer) => answer === raw);
2166
+ }
2167
+ function to_time_ms(raw) {
2168
+ if (raw === void 0) return void 0;
2169
+ const parsed = Date.parse(raw);
2170
+ return Number.isNaN(parsed) ? void 0 : parsed;
2171
+ }
2172
+ var COUNT_PATTERN = /^\d+$/u;
2173
+ function to_count(raw) {
2174
+ if (raw === void 0 || !COUNT_PATTERN.test(raw)) return void 0;
2175
+ const parsed = Number(raw);
2176
+ return Number.isSafeInteger(parsed) ? parsed : void 0;
2177
+ }
2178
+ function is_readable(raw, parsed) {
2179
+ return raw === void 0 || parsed !== void 0;
2180
+ }
2181
+ var COUNT_NAMES = ["idle", "max", "merged", "running"];
2182
+ function counts_of(values) {
2183
+ return {
2184
+ idle: to_count(text_of(values.idle)),
2185
+ max: to_count(text_of(values.max)),
2186
+ merged: to_count(text_of(values.merged)),
2187
+ running: to_count(text_of(values.running))
2188
+ };
2189
+ }
2190
+ function are_counts_readable(values, counts) {
2191
+ return COUNT_NAMES.every((name) => is_readable(text_of(values[name]), counts[name]));
2192
+ }
2193
+ var NO_IDLE_MINUTES = 0;
2194
+ function to_idle_ms(idle_minutes) {
2195
+ if (idle_minutes === void 0) return backlog_budget.DEFAULT_IDLE_MS;
2196
+ if (idle_minutes === NO_IDLE_MINUTES) return void 0;
2197
+ return idle_minutes * backlog_budget.MS_PER_MINUTE;
2198
+ }
2199
+ function is_watch_readable(values) {
2200
+ if (to_idle_ms(to_count(text_of(values.idle))) === void 0) return true;
2201
+ return text_of(values.active) !== void 0;
2202
+ }
2203
+ function are_values_readable(values) {
2204
+ return is_readable(text_of(values.active), to_time_ms(text_of(values.active))) && is_watch_readable(values) && are_counts_readable(values, counts_of(values));
2205
+ }
2206
+ function input_of(values, base) {
2207
+ const counts = counts_of(values);
2208
+ return {
2209
+ ...base,
2210
+ active_at_ms: to_time_ms(text_of(values.active)) ?? base.started_at_ms,
2211
+ merged: counts.merged ?? 0,
2212
+ running: counts.running ?? 0,
2213
+ max_issues: counts.max,
2214
+ idle_budget_ms: to_idle_ms(counts.idle)
2215
+ };
2216
+ }
2217
+ function build_input(values, now_ms) {
2218
+ const answer = to_answer(text_of(values.answer));
2219
+ if (answer === void 0) return void 0;
2220
+ const started_at_ms = to_time_ms(text_of(values.started));
2221
+ if (started_at_ms === void 0) return void 0;
2222
+ if (!are_values_readable(values)) return void 0;
2223
+ return input_of(values, { answer, now_ms, started_at_ms });
2224
+ }
2225
+ function refuse() {
2226
+ console.error(USAGE);
2227
+ return FAILURE_EXIT_CODE2;
2228
+ }
2229
+ function run(argv, now_ms = Date.now()) {
2230
+ const values = read_arguments(argv);
2231
+ if (values === void 0) return refuse();
2232
+ const input = build_input(values, now_ms);
2233
+ if (input === void 0) return refuse();
2234
+ const { verdict, reason } = backlog_budget.decide(input);
2235
+ path_decision.print_decision(JSON_KEY, verdict, reason, values.json === true);
2236
+ return SUCCESS_EXIT_CODE;
2237
+ }
2238
+ function main(argv) {
2239
+ process.exitCode = run(argv);
2240
+ }
2241
+ var backlog_budget_cli = {
2242
+ JSON_KEY,
2243
+ OPTIONS,
2244
+ SUCCESS_EXIT_CODE,
2245
+ USAGE,
2246
+ build_input,
2247
+ main,
2248
+ read_arguments,
2249
+ run,
2250
+ to_answer,
2251
+ to_count,
2252
+ to_time_ms
2253
+ };
2254
+ if (process.argv[1] === fileURLToPath(import.meta.url)) main(process.argv.slice(ARGV_OFFSET));
2255
+
2256
+ // scripts/run/run-invocation.ts
2257
+ var BACKLOG_COMMAND = "backlogrun";
2258
+ var KNOWN_FLAGS2 = ["--max", "--idle"];
2259
+ var ONLY_FLAG = "--only";
2260
+ var ISSUE_PREFIX = "#";
2261
+ var TOKEN_SEPARATOR = " ";
2262
+ var FIRST_TOKEN = 0;
2263
+ var FIRST_ARGUMENT_INDEX = 1;
2264
+ var VALUE_OFFSET = 1;
2265
+ var FLAG_PAIR_LENGTH = 2;
2266
+ var ONLY_STEP = 1;
2267
+ var EMPTY_LENGTH2 = 0;
2268
+ var NOT_FOUND2 = -1;
2269
+ function tokens_of(invocation) {
2270
+ return invocation.split(TOKEN_SEPARATOR).filter((token) => token.length > EMPTY_LENGTH2);
2271
+ }
2272
+ function flag_token(token, raw) {
2273
+ const flag = KNOWN_FLAGS2.find((known) => known === token);
2274
+ const value = backlog_budget_cli.to_count(raw);
2275
+ if (flag === void 0 || value === void 0) return void 0;
2276
+ return `${flag} ${String(value)}`;
2277
+ }
2278
+ function read_flag(tokens, index) {
2279
+ const token = tokens[index] ?? "";
2280
+ if (token === ONLY_FLAG) return { part: ONLY_FLAG, advance: ONLY_STEP };
2281
+ const part = flag_token(token, tokens[index + VALUE_OFFSET]);
2282
+ return part === void 0 ? void 0 : { part, advance: FLAG_PAIR_LENGTH };
2283
+ }
2284
+ function flag_tokens(tokens, start) {
2285
+ const rendered = [];
2286
+ let index = start;
2287
+ while (index < tokens.length) {
2288
+ const read2 = read_flag(tokens, index);
2289
+ if (read2 === void 0) return void 0;
2290
+ rendered.push(read2.part);
2291
+ index += read2.advance;
2292
+ }
2293
+ return rendered;
2294
+ }
2295
+ function issue_of(token) {
2296
+ if (!token.startsWith(ISSUE_PREFIX)) return void 0;
2297
+ const digits = token.slice(ISSUE_PREFIX.length);
2298
+ if (!run_issue_number.ISSUE_NUMBER_PATTERN.test(digits)) return void 0;
2299
+ const issue = Number(digits);
2300
+ return Number.isSafeInteger(issue) ? issue : void 0;
2301
+ }
2302
+ function take_leading_prefixed(args) {
2303
+ const stop = args.findIndex((token) => !token.startsWith(ISSUE_PREFIX));
2304
+ return args.slice(FIRST_TOKEN, stop === NOT_FOUND2 ? args.length : stop);
2305
+ }
2306
+ function leading_issues(tokens) {
2307
+ const issues = [];
2308
+ const prefixed = take_leading_prefixed(tokens.slice(FIRST_ARGUMENT_INDEX));
2309
+ for (const token of prefixed) {
2310
+ const issue = issue_of(token);
2311
+ if (issue === void 0) return void 0;
2312
+ issues.push(issue);
2313
+ }
2314
+ return issues;
2315
+ }
2316
+ function issue_token(issue) {
2317
+ return `${ISSUE_PREFIX}${String(issue)}`;
2318
+ }
2319
+ function joined(command, rendered) {
2320
+ return [command, ...rendered].join(TOKEN_SEPARATOR);
2321
+ }
2322
+ function rebuilt_backlog(tokens) {
2323
+ const issues = leading_issues(tokens);
2324
+ if (issues === void 0) return void 0;
2325
+ const flags = flag_tokens(tokens, FIRST_ARGUMENT_INDEX + issues.length);
2326
+ if (flags === void 0) return void 0;
2327
+ return joined(BACKLOG_COMMAND, [...issues.map((issue) => issue_token(issue)), ...flags]);
2328
+ }
2329
+ function rebuild(invocation) {
2330
+ const tokens = tokens_of(invocation);
2331
+ if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return void 0;
2332
+ return rebuilt_backlog(tokens);
2333
+ }
2334
+ function issue_numbers(invocation) {
2335
+ const tokens = tokens_of(invocation);
2336
+ if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return void 0;
2337
+ const issues = leading_issues(tokens);
2338
+ if (issues === void 0 || issues.length === EMPTY_LENGTH2) return void 0;
2339
+ return issues;
2340
+ }
2341
+ function has_only(invocation) {
2342
+ const tokens = tokens_of(invocation);
2343
+ if (tokens[FIRST_TOKEN] !== BACKLOG_COMMAND) return false;
2344
+ return tokens.slice(FIRST_ARGUMENT_INDEX).includes(ONLY_FLAG);
2345
+ }
2346
+ var run_invocation = {
2347
+ has_only,
2348
+ issue_numbers,
2349
+ rebuild
2350
+ };
2351
+
2352
+ // scripts/run/run-carry.ts
2353
+ var CARRY_PREFIX = "josh-run-carry-";
2354
+ var REPOSITORY_DIRECTORY_INDEX = 1;
2355
+ var CARRY_MAX_AGE_HOURS = backlog_budget.WHOLE_RUN_BUDGET_HOURS;
2356
+ var CARRY_MAX_AGE_MS = backlog_budget.WHOLE_RUN_BUDGET_MS;
2357
+ var NO_INCREMENT2 = 0;
2358
+ var MAX_CUTS = 6;
2359
+ var END_COMMAND2 = "pnpm josh run:carry --end";
2360
+ var RESUME_COMMAND = "pnpm josh run:carry --resume";
2361
+ var READ_COMMAND2 = "pnpm josh run:carry --json";
2362
+ var OWNER_ARGUMENT = '--owner "$PPID"';
2363
+ var NONE_READ2 = { kind: "none" };
2364
+ var UNREADABLE_READ3 = { kind: "unreadable" };
2365
+ var NO_OWNER = {};
2366
+ var run_carry_schema = z6.object({
2367
+ invocation: z6.string(),
2368
+ started_at: z6.string(),
2369
+ merged: z6.number(),
2370
+ filed: z6.number(),
2371
+ cuts: z6.number(),
2372
+ // Defaulted, so a record written before this field existed parses with a zero streak rather than
2373
+ // failing to read — the same backward-compatibility the optional owner fields below carry.
2374
+ failures: z6.number().default(0),
2375
+ // Defaulted for the same backward-compatibility as `failures` (joshuafolkken/kit#2240).
2376
+ outages: z6.number().default(0),
2377
+ // Optional, so a record written before the outage fold existed still parses (joshuafolkken/kit#2317).
2378
+ last_outage_at: z6.string().optional(),
2379
+ // Optional, so a record written by the previous shape still parses. Read as "no owner declared",
2380
+ // which is the not-provably-live answer rather than a live one.
2381
+ owner_pid: z6.number().optional(),
2382
+ owner_start: z6.string().optional(),
2383
+ is_handed_off: z6.boolean().optional(),
2384
+ done: z6.array(z6.number()).optional(),
2385
+ // Optional, so a record written before the retrospective existed still parses (joshuafolkken/kit#2328).
2386
+ retrospective: z6.boolean().optional()
2387
+ });
2388
+ function carry_path(git_directory) {
2389
+ return stamp_file.stamp_path(CARRY_PREFIX, git_directory);
2390
+ }
2391
+ async function repository_directory() {
2392
+ const directories = await git_command.git_directories();
2393
+ return directories[REPOSITORY_DIRECTORY_INDEX];
2394
+ }
2395
+ function parse_carry(raw) {
2396
+ try {
2397
+ const parsed = run_carry_schema.safeParse(JSON.parse(raw));
2398
+ return parsed.success ? parsed.data : void 0;
2399
+ } catch {
2400
+ return void 0;
2401
+ }
2402
+ }
2403
+ function is_expired2(carry, now) {
2404
+ const started = Date.parse(carry.started_at);
2405
+ if (Number.isNaN(started)) return true;
2406
+ return now.getTime() - started > CARRY_MAX_AGE_MS;
2407
+ }
2408
+ function classify4(raw, now) {
2409
+ if (raw === void 0) return NONE_READ2;
2410
+ const carry = parse_carry(raw);
2411
+ if (carry === void 0) return UNREADABLE_READ3;
2412
+ return { kind: is_expired2(carry, now) ? "expired" : "carried", carry };
2413
+ }
2414
+ function read_carry(target, now = /* @__PURE__ */ new Date()) {
2415
+ return classify4(stamp_file.read_stamp_text(target), now);
2416
+ }
2417
+ function owner_of(pid, read2 = process_identity.read_start) {
2418
+ return { pid, start: read2(pid) };
2419
+ }
2420
+ function fresh_carry(invocation, owner, now) {
2421
+ return {
2422
+ invocation,
2423
+ started_at: now.toISOString(),
2424
+ merged: NO_INCREMENT2,
2425
+ filed: NO_INCREMENT2,
2426
+ cuts: NO_INCREMENT2,
2427
+ failures: NO_INCREMENT2,
2428
+ outages: NO_INCREMENT2,
2429
+ owner_pid: owner.pid,
2430
+ owner_start: owner.start
2431
+ };
2432
+ }
2433
+ function begin_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
2434
+ const carry = fresh_carry(invocation, owner, now);
2435
+ return stamp_file.create_stamp(target, carry) ? carry : void 0;
2436
+ }
2437
+ function replace_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
2438
+ stamp_file.remove_stamp(target);
2439
+ return begin_carry(target, invocation, owner, now);
2440
+ }
2441
+ function adopt_carry(target, carry, owner = NO_OWNER) {
2442
+ const next = {
2443
+ ...carry,
2444
+ owner_pid: owner.pid,
2445
+ owner_start: owner.start,
2446
+ is_handed_off: false
2447
+ };
2448
+ stamp_file.remove_stamp(target);
2449
+ return stamp_file.create_stamp(target, next) ? next : void 0;
2450
+ }
2451
+ function next_done(carry, done) {
2452
+ if (done === void 0) return carry.done;
2453
+ const current = carry.done ?? [];
2454
+ return current.includes(done) ? current : [...current, done];
2455
+ }
2456
+ function next_retrospective(carry, change) {
2457
+ return change.retrospective === true || carry.retrospective;
2458
+ }
2459
+ function apply_change(target, carry, change, now = /* @__PURE__ */ new Date()) {
2460
+ const cuts = change.cuts ?? NO_INCREMENT2;
2461
+ const streak = run_carry_streak.next_state(carry, change, now);
2462
+ const next = {
2463
+ ...carry,
2464
+ merged: carry.merged + (change.merged ?? NO_INCREMENT2),
2465
+ filed: carry.filed + (change.filed ?? NO_INCREMENT2),
2466
+ cuts: carry.cuts + cuts,
2467
+ failures: streak.failures,
2468
+ outages: streak.outages,
2469
+ last_outage_at: streak.last_outage_at,
2470
+ done: next_done(carry, change.done),
2471
+ retrospective: next_retrospective(carry, change),
2472
+ // A cut declares the hand-off; any other count is the run carrying on, which spends it.
2473
+ is_handed_off: cuts > NO_INCREMENT2
2474
+ };
2475
+ stamp_file.write_stamp(target, next);
2476
+ return next;
2477
+ }
2478
+ function is_owner_live(carry) {
2479
+ return process_identity.is_same_process(carry.owner_pid, carry.owner_start) !== false;
2480
+ }
2481
+ function is_owned_by(carry, owner) {
2482
+ return carry.owner_pid === owner.pid && carry.owner_start === owner.start;
2483
+ }
2484
+ function is_foreign_live_owner(carry, owner) {
2485
+ return is_owner_live(carry) && !is_owned_by(carry, owner);
2486
+ }
2487
+ function is_handed_off_to(carry, invocation) {
2488
+ return carry.is_handed_off === true && carry.invocation === invocation;
2489
+ }
2490
+ function classify_claim(carry, request) {
2491
+ if (is_handed_off_to(carry, request.invocation)) return "resume";
2492
+ if (is_foreign_live_owner(carry, request.owner)) return "busy";
2493
+ if (carry.invocation !== request.invocation) return "mismatch";
2494
+ return request.is_adoption ? "resume" : "standing";
2495
+ }
2496
+ function is_count_refused(carry, owner) {
2497
+ return carry.is_handed_off === true || is_foreign_live_owner(carry, owner);
2498
+ }
2499
+ function is_at_cut_cap(carry) {
2500
+ return carry.cuts >= MAX_CUTS;
2501
+ }
2502
+ function end_carry(target) {
2503
+ stamp_file.remove_stamp(target);
2504
+ }
2505
+ function retrospective_done_of(read2) {
2506
+ if (read2.kind !== "carried" && read2.kind !== "expired") return false;
2507
+ return read2.carry.retrospective === true;
2508
+ }
2509
+ function remaining_of(carry) {
2510
+ if (carry === void 0) return void 0;
2511
+ const declared = run_invocation.issue_numbers(carry.invocation);
2512
+ if (declared === void 0) return void 0;
2513
+ const done = carry.done ?? [];
2514
+ return declared.filter((issue) => !done.includes(issue));
2515
+ }
2516
+ function done_note(carry) {
2517
+ const done = carry.done ?? [];
2518
+ return done.length === 0 ? "" : `, issues ${done.join(", ")} done`;
2519
+ }
2520
+ function describe_carry(carry) {
2521
+ return `${carry.invocation} started ${carry.started_at}; ${String(carry.merged)} merged, ${String(carry.filed)} filed, ${String(carry.failures)} failed in a row, ${String(carry.outages)} outage(s) in a row, ${String(carry.cuts)} cut(s) crossed${done_note(carry)}`;
2522
+ }
2523
+ function expired_message(carry) {
2524
+ return `The ${String(CARRY_MAX_AGE_HOURS)}-hour whole-run bound is spent: ${describe_carry(carry)}. Clear it with \`${END_COMMAND2}\`.`;
2525
+ }
2526
+ function mismatch_message(carry, invocation) {
2527
+ return `A different invocation is carried here \u2014 ${describe_carry(carry)}. This one is \`${invocation}\`. End the standing record with \`${END_COMMAND2}\` once you know its run is over, then begin again.`;
2528
+ }
2529
+ function busy_message2(carry) {
2530
+ return `A live run holds this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was established. Wait for that run, or end its record with \`${END_COMMAND2}\` once you know it is over.`;
2531
+ }
2532
+ function standing_message(carry) {
2533
+ return `A run record is standing here that no cut handed off \u2014 ${describe_carry(carry)}. Nothing was established. Carry that budget with \`${RESUME_COMMAND} "${carry.invocation}" ${OWNER_ARGUMENT}\`, or discard it with \`${END_COMMAND2}\` and begin again.`;
2534
+ }
2535
+ function count_refused_message(carry) {
2536
+ if (carry.is_handed_off === true) {
2537
+ return `This budget was handed off at a cut and is waiting for its successor \u2014 ${describe_carry(carry)}. Nothing was counted; the cutting session must not advance a handed-off budget.`;
2538
+ }
2539
+ return `A live run owns this budget \u2014 ${describe_carry(carry)}, owner pid ${String(carry.owner_pid)} still running. Nothing was counted; only its owner advances the budget.`;
2540
+ }
2541
+ function lost_message() {
2542
+ return `Another process established a run record here first, so nothing was established. Read it with \`${READ_COMMAND2}\`.`;
2543
+ }
2544
+ function nothing_to_resume_message() {
2545
+ return `Nothing is carried here, so there is no budget to resume. Begin one with \`pnpm josh run:carry --begin "<invocation>"\`.`;
2546
+ }
2547
+ function unreadable_message3() {
2548
+ return `A run record is here but could not be read; clear it with \`${END_COMMAND2}\` once you know no run is using it.`;
2549
+ }
2550
+ function unknown_message3() {
2551
+ return "This repository\u2019s git directory could not be read, so no run record was established.";
2552
+ }
2553
+ var run_carry = {
2554
+ CARRY_MAX_AGE_HOURS,
2555
+ CARRY_MAX_AGE_MS,
2556
+ END_COMMAND: END_COMMAND2,
2557
+ MAX_CUTS,
2558
+ NO_OWNER,
2559
+ RESUME_COMMAND,
2560
+ adopt_carry,
2561
+ apply_change,
2562
+ begin_carry,
2563
+ busy_message: busy_message2,
2564
+ carry_path,
2565
+ classify: classify4,
2566
+ classify_claim,
2567
+ count_refused_message,
2568
+ is_at_cut_cap,
2569
+ describe_carry,
2570
+ end_carry,
2571
+ expired_message,
2572
+ mismatch_message,
2573
+ fresh_carry,
2574
+ is_count_refused,
2575
+ is_expired: is_expired2,
2576
+ is_foreign_live_owner,
2577
+ is_owner_live,
2578
+ lost_message,
2579
+ nothing_to_resume_message,
2580
+ owner_of,
2581
+ parse_carry,
2582
+ read_carry,
2583
+ remaining_of,
2584
+ replace_carry,
2585
+ repository_directory,
2586
+ retrospective_done_of,
2587
+ standing_message,
2588
+ unknown_message: unknown_message3,
2589
+ unreadable_message: unreadable_message3
2590
+ };
2591
+
2592
+ // scripts/lane/lane-registry.ts
2593
+ import { existsSync as existsSync2, readFileSync as readFileSync4 } from "node:fs";
2594
+ import path3 from "node:path";
2595
+
2596
+ // scripts/git/git-ls-remote.ts
2597
+ var LS_REMOTE_COMMAND = "ls-remote";
2598
+ var HEADS_FLAG = "--heads";
2599
+ var ORIGIN_REMOTE = "origin";
2600
+ var HEADS_REF_PREFIX = "refs/heads/";
2601
+ function ls_remote_branch_arguments(branch_name) {
2602
+ return [LS_REMOTE_COMMAND, HEADS_FLAG, ORIGIN_REMOTE, `${HEADS_REF_PREFIX}${branch_name}`];
2603
+ }
2604
+
2605
+ // scripts/git/git-worktree.ts
2606
+ var WORKTREE = "worktree";
2607
+ async function worktree_list() {
2608
+ return await git_spawn.read([WORKTREE, "list", PORCELAIN_FLAG]);
2609
+ }
2610
+ async function worktree_add(directory, branch_name, start_point) {
2611
+ const flags = start_point === void 0 ? ["add"] : ["add", "--no-track", "-b", branch_name];
2612
+ return await git_spawn.read([WORKTREE, ...flags, directory, start_point ?? branch_name]);
2613
+ }
2614
+ async function worktree_remove(directory) {
2615
+ return await git_spawn.read([WORKTREE, "remove", "--force", directory]);
2616
+ }
2617
+ async function worktree_prune() {
2618
+ return await git_spawn.read([WORKTREE, "prune"]);
2619
+ }
2620
+ async function ls_remote_branch(branch_name) {
2621
+ return await git_spawn.read(ls_remote_branch_arguments(branch_name));
2622
+ }
2623
+ async function branch_delete(branch_name) {
2624
+ return await git_spawn.read(["branch", "-D", branch_name]);
2625
+ }
2626
+ var git_worktree = {
2627
+ branch_delete,
2628
+ ls_remote_branch,
2629
+ worktree_add,
2630
+ worktree_list,
2631
+ worktree_prune,
2632
+ worktree_remove
2633
+ };
2634
+
2635
+ // scripts/lane/lane-environment.ts
2636
+ var LANE_OUTPUT_KEY = "JOSH_LANE_OUTPUT";
2637
+ var LANE_PROVIDER_KEY = "JOSH_LANE_AGENT_PROVIDER";
2638
+ var LANE_ROLE_KEY = "JOSH_LANE_AGENT_ROLE";
2639
+ var LANE_MODEL_KEY = "JOSH_LANE_AGENT_MODEL";
2640
+ var LANE_EFFORT_KEY = "JOSH_LANE_AGENT_EFFORT";
2641
+ var ASSIGNMENT_SEPARATOR = "=";
2642
+ var EXPORT_PREFIX = "export ";
2643
+ var QUOTE_CHARACTERS = /* @__PURE__ */ new Set(['"', "'"]);
2644
+ var MIN_QUOTED_LENGTH = 2;
2645
+ var FIRST_CHARACTER_END = 1;
2646
+ var LAST_CHARACTER_START = -1;
2647
+ function strip_export(line) {
2648
+ const trimmed2 = line.trimStart();
2649
+ return trimmed2.startsWith(EXPORT_PREFIX) ? trimmed2.slice(EXPORT_PREFIX.length).trimStart() : trimmed2;
2650
+ }
2651
+ function is_key_line(line, key) {
2652
+ const body = strip_export(line);
2653
+ if (!body.startsWith(key)) return false;
2654
+ return body.slice(key.length).trimStart().startsWith(ASSIGNMENT_SEPARATOR);
2655
+ }
2656
+ function is_seed_line(line) {
2657
+ return is_key_line(line, PORT_SEED_KEY);
2658
+ }
2659
+ function is_seat_line(line) {
2660
+ return is_key_line(line, LANE_SEAT_KEY);
2661
+ }
2662
+ function is_output_line(line) {
2663
+ return is_key_line(line, LANE_OUTPUT_KEY);
2664
+ }
2665
+ function split_lines(content) {
2666
+ const trimmed2 = content.trimEnd();
2667
+ return trimmed2.length === 0 ? [] : trimmed2.split("\n");
2668
+ }
2669
+ function is_quoted(raw) {
2670
+ const first = raw.slice(0, FIRST_CHARACTER_END);
2671
+ if (!QUOTE_CHARACTERS.has(first)) return false;
2672
+ return raw.length >= MIN_QUOTED_LENGTH && raw.endsWith(first);
2673
+ }
2674
+ function unquote(raw) {
2675
+ return is_quoted(raw) ? raw.slice(FIRST_CHARACTER_END, LAST_CHARACTER_START) : raw;
2676
+ }
2677
+ function assignment_value(line) {
2678
+ return unquote(line.slice(line.indexOf(ASSIGNMENT_SEPARATOR) + FIRST_CHARACTER_END).trim());
2679
+ }
2680
+ function read_assignment(content, key) {
2681
+ const line = split_lines(content).findLast((entry) => is_key_line(entry, key));
2682
+ return line === void 0 ? void 0 : assignment_value(line);
2683
+ }
2684
+ function read_root_seed(content) {
2685
+ return ports.resolve_seed({ [PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY) });
2686
+ }
2687
+ function read_lane_seat(content) {
2688
+ const raw = read_assignment(content, LANE_SEAT_KEY);
2689
+ return raw === void 0 ? void 0 : ports.resolve_lane({ [LANE_SEAT_KEY]: raw });
2690
+ }
2691
+ function read_lane_ports(content) {
2692
+ const environment2 = {
2693
+ [PORT_SEED_KEY]: read_assignment(content, PORT_SEED_KEY),
2694
+ [LANE_SEAT_KEY]: read_assignment(content, LANE_SEAT_KEY)
2695
+ };
2696
+ return {
2697
+ development: ports.resolve_development_port(environment2),
2698
+ preview: ports.resolve_preview_port(environment2)
2699
+ };
2700
+ }
2701
+ function read_lane_output(content) {
2702
+ const line = split_lines(content).findLast((entry) => is_output_line(entry));
2703
+ const raw = line === void 0 ? void 0 : assignment_value(line);
2704
+ return raw === void 0 || raw.length === 0 ? void 0 : raw;
2705
+ }
2706
+ function read_lane_profile(content) {
2707
+ return agent_role_profile.parse({
2708
+ provider: read_assignment(content, LANE_PROVIDER_KEY),
2709
+ role: read_assignment(content, LANE_ROLE_KEY),
2710
+ model: read_assignment(content, LANE_MODEL_KEY),
2711
+ effort: read_assignment(content, LANE_EFFORT_KEY)
2712
+ });
2713
+ }
2714
+ function replace_assignment(lines, keep, assignment, key) {
2715
+ return lines.flatMap((entry, index) => {
2716
+ if (index === keep) return [assignment];
2717
+ return is_key_line(entry, key) ? [] : [entry];
2718
+ });
2719
+ }
2720
+ function upsert_assignment(content, key, value) {
2721
+ const assignment = `${key}${ASSIGNMENT_SEPARATOR}${value}`;
2722
+ const lines = split_lines(content);
2723
+ const last = lines.findLastIndex((entry) => is_key_line(entry, key));
2724
+ const body = last === -1 ? [...lines, assignment] : replace_assignment(lines, last, assignment, key);
2725
+ return `${body.join("\n")}
2726
+ `;
2727
+ }
2728
+ function lane_file_content(root_content, seat) {
2729
+ return upsert_assignment(root_content, LANE_SEAT_KEY, String(seat));
2730
+ }
2731
+ function with_lane_output(content, output, profile) {
2732
+ const recorded = upsert_assignment(content, LANE_OUTPUT_KEY, `"${output}"`);
2733
+ if (profile === void 0) return recorded;
2734
+ const with_provider = upsert_assignment(recorded, LANE_PROVIDER_KEY, profile.provider);
2735
+ const with_role = upsert_assignment(with_provider, LANE_ROLE_KEY, profile.role);
2736
+ const with_model = upsert_assignment(with_role, LANE_MODEL_KEY, profile.model);
2737
+ return upsert_assignment(with_model, LANE_EFFORT_KEY, profile.effort);
2738
+ }
2739
+ var lane_environment = {
2740
+ LANE_OUTPUT_KEY,
2741
+ LANE_PROVIDER_KEY,
2742
+ LANE_ROLE_KEY,
2743
+ is_output_line,
2744
+ is_seat_line,
2745
+ is_seed_line,
2746
+ lane_file_content,
2747
+ read_lane_output,
2748
+ read_lane_profile,
2749
+ read_lane_ports,
2750
+ read_lane_seat,
2751
+ read_root_seed,
2752
+ with_lane_output
2753
+ };
2754
+
2755
+ // scripts/lane/lane-registry.ts
2756
+ var WORKTREE_PREFIX = "worktree ";
2757
+ var BRANCH_PREFIX = "branch refs/heads/";
2758
+ var BLOCK_SEPARATOR = "\n\n";
2759
+ var ISSUE_PATTERN = /^[1-9]\d*$/u;
2760
+ function line_value(lines, prefix) {
2761
+ return lines.find((line) => line.startsWith(prefix))?.slice(prefix.length);
2762
+ }
2763
+ function seat_from_content(content) {
2764
+ const seat = lane_environment.read_lane_seat(content);
2765
+ if (seat === void 0) return void 0;
2766
+ const port_pair = lane_environment.read_lane_ports(content);
2767
+ return { seat, development_port: port_pair.development, preview_port: port_pair.preview };
2768
+ }
2769
+ var EMPTY_SEAT = {
2770
+ seat: void 0,
2771
+ development_port: void 0,
2772
+ preview_port: void 0
2773
+ };
2774
+ function held_seat(content) {
2775
+ if (content === void 0) return EMPTY_SEAT;
2776
+ return seat_from_content(content) ?? EMPTY_SEAT;
2777
+ }
2778
+ function read_environment(directory) {
2779
+ try {
2780
+ return readFileSync4(path3.join(directory, ENV_FILE_NAME), "utf8");
2781
+ } catch {
2782
+ return void 0;
2783
+ }
2784
+ }
2785
+ function branch_issue(branch2) {
2786
+ if (!branch2?.endsWith(lane_paths.LANE_BRANCH_SUFFIX)) return void 0;
2787
+ const issue = branch2.slice(0, -lane_paths.LANE_BRANCH_SUFFIX.length);
2788
+ return ISSUE_PATTERN.test(issue) ? issue : void 0;
2789
+ }
2790
+ function is_gone(directory) {
2791
+ return !existsSync2(directory);
2792
+ }
2793
+ function build_lane(issue, branch2, directory, is_stranded) {
2794
+ const content = is_stranded ? void 0 : read_environment(directory);
2795
+ const held = held_seat(content);
2796
+ const output = content === void 0 ? void 0 : lane_environment.read_lane_output(content);
2797
+ const profile = content === void 0 ? void 0 : lane_environment.read_lane_profile(content);
2798
+ return {
2799
+ issue,
2800
+ branch: branch2,
2801
+ directory,
2802
+ seat: held.seat,
2803
+ development_port: held.development_port,
2804
+ preview_port: held.preview_port,
2805
+ output,
2806
+ profile,
2807
+ is_stranded
2808
+ };
2809
+ }
2810
+ function is_lane_directory(root, issue, directory) {
2811
+ return directory === lane_paths.lane_directory(root, issue);
2812
+ }
2813
+ function parse_block(block, root) {
2814
+ const lines = block.split("\n");
2815
+ const directory = line_value(lines, WORKTREE_PREFIX);
2816
+ const branch2 = line_value(lines, BRANCH_PREFIX);
2817
+ const issue = branch_issue(branch2);
2818
+ if (directory === void 0 || branch2 === void 0 || issue === void 0) return void 0;
2819
+ if (!is_lane_directory(root, issue, directory)) return void 0;
2820
+ return build_lane(issue, branch2, directory, is_gone(directory));
2821
+ }
2822
+ function is_lane(lane) {
2823
+ return lane !== void 0;
2824
+ }
2825
+ async function worktree_blocks() {
2826
+ const listing = await git_worktree.worktree_list();
2827
+ return listing.split(BLOCK_SEPARATOR);
2828
+ }
2829
+ async function main_repository_root() {
2830
+ return repo_discovery.main_worktree(await git_command.repository_root());
2831
+ }
2832
+ async function list_lanes() {
2833
+ const root = lane_paths.lane_root(await main_repository_root());
2834
+ const blocks = await worktree_blocks();
2835
+ const lanes = blocks.map((block) => parse_block(block, root)).filter(is_lane);
2836
+ return lanes.toSorted((left, right) => Number(left.issue) - Number(right.issue));
2837
+ }
2838
+ function used_seats(lanes) {
2839
+ return lanes.map((lane) => lane.seat).filter((seat) => seat !== void 0);
2840
+ }
2841
+ function unreadable_lanes(lanes) {
2842
+ return lanes.filter((lane) => !lane.is_stranded && lane.seat === void 0);
2843
+ }
2844
+ function find_lane(lanes, issue) {
2845
+ return lanes.find((lane) => lane.issue === issue);
2846
+ }
2847
+ async function find_open_lane(issue) {
2848
+ return find_lane(await list_lanes(), issue);
2849
+ }
2850
+ var lane_registry = {
2851
+ find_lane,
2852
+ find_open_lane,
2853
+ list_lanes,
2854
+ main_repository_root,
2855
+ parse_block,
2856
+ read_environment,
2857
+ unreadable_lanes,
2858
+ used_seats
2859
+ };
2860
+
2861
+ // scripts/run/run-event-follow.ts
2862
+ var MS_PER_SECOND2 = 1e3;
2863
+ var SECONDS_PER_MINUTE = 60;
2864
+ var FOLLOW_INTERVAL_MINUTES = 20;
2865
+ var FOLLOW_INTERVAL_MS = FOLLOW_INTERVAL_MINUTES * SECONDS_PER_MINUTE * MS_PER_SECOND2;
2866
+ var FOLLOW_TICK_MS = MS_PER_SECOND2;
2867
+ async function follow(ports2, position, options) {
2868
+ const deadline = ports2.now() + options.interval_ms;
2869
+ let read2 = ports2.read(position);
2870
+ while (read2.events.length === 0 && ports2.now() < deadline) {
2871
+ await ports2.sleep(options.tick_ms);
2872
+ read2 = ports2.read(position);
2873
+ }
2874
+ return read2;
2875
+ }
2876
+ var run_event_follow = { FOLLOW_INTERVAL_MS, FOLLOW_TICK_MS, follow };
2877
+
2878
+ // scripts/run/run-progress-clock.ts
2879
+ import { execaSync } from "execa";
2880
+ import { z as z7 } from "zod";
2881
+ var PROGRESS_PREFIX = "josh-run-progress-";
2882
+ var LIFE_PREFIX = "josh-run-progress-life-";
2883
+ var LOG_SUFFIX = ".log";
2884
+ var LOG_KEEP = 12;
2885
+ var MS_PER_MINUTE2 = 6e4;
2886
+ var LOG_STALE_MINUTES = 90;
2887
+ var LOG_STALE_MS = LOG_STALE_MINUTES * MS_PER_MINUTE2;
2888
+ var BLOCK_SEPARATOR2 = "\n\n";
2889
+ var GIT_TIMEOUT_MS = 5e3;
2890
+ var GIT_DIRECTORY_ARGUMENTS2 = ["rev-parse", "--absolute-git-dir"];
2891
+ var report_stamp_schema = z7.object({ reported_at: z7.string(), line: z7.string().optional() });
2892
+ function parse_stamp(raw) {
2893
+ const parsed = report_stamp_schema.safeParse(JSON.parse(raw));
2894
+ if (!parsed.success) return void 0;
2895
+ const reported_at = Date.parse(parsed.data.reported_at);
2896
+ return Number.isNaN(reported_at) ? void 0 : reported_at;
2897
+ }
2898
+ function read_last_line(target) {
2899
+ const raw = stamp_file.read_stamp_text(target);
2900
+ if (raw === void 0) return void 0;
2901
+ try {
2902
+ return report_stamp_schema.safeParse(JSON.parse(raw)).data?.line;
2903
+ } catch {
2904
+ return void 0;
2905
+ }
2906
+ }
2907
+ function read_last_report(target) {
2908
+ const raw = stamp_file.read_stamp_text(target);
2909
+ if (raw === void 0) return void 0;
2910
+ try {
2911
+ return parse_stamp(raw);
2912
+ } catch {
2913
+ return void 0;
2914
+ }
2915
+ }
2916
+ function log_path_of(target) {
2917
+ return `${target}${LOG_SUFFIX}`;
2918
+ }
2919
+ function is_log_stale(target, now_ms) {
2920
+ const previous_ms = read_last_report(target);
2921
+ return previous_ms === void 0 || now_ms - previous_ms > LOG_STALE_MS;
2922
+ }
2923
+ function recent_blocks(log_target, is_fresh) {
2924
+ if (is_fresh) return [];
2925
+ const raw = stamp_file.read_stamp_text(log_target);
2926
+ if (raw === void 0) return [];
2927
+ return raw.split(BLOCK_SEPARATOR2).map((block) => block.trimEnd()).filter((block) => block.length > 0);
2928
+ }
2929
+ function append_line(log_target, reported_at, line, is_fresh) {
2930
+ const block = `${reported_at}
2931
+ ${line}`;
2932
+ const blocks = [...recent_blocks(log_target, is_fresh), block].slice(-LOG_KEEP);
2933
+ stamp_file.write_text_stamp(log_target, `${blocks.join(BLOCK_SEPARATOR2)}
2934
+ `);
2935
+ }
2936
+ function mark(target, now_ms, line) {
2937
+ const reported_at = new Date(now_ms).toISOString();
2938
+ const kept = line ?? read_last_line(target);
2939
+ if (line !== void 0) {
2940
+ append_line(log_path_of(target), reported_at, line, is_log_stale(target, now_ms));
2941
+ }
2942
+ stamp_file.write_stamp(target, kept === void 0 ? { reported_at } : { reported_at, line: kept });
2943
+ }
2944
+ function stamp_target_of(git_directory) {
2945
+ return stamp_file.stamp_path(PROGRESS_PREFIX, git_directory);
2946
+ }
2947
+ function life_target_of(git_directory) {
2948
+ return stamp_file.stamp_path(LIFE_PREFIX, git_directory);
2949
+ }
2950
+ var life_schema = z7.object({ alive: z7.literal(true), pinged_at: z7.string().optional() });
2951
+ function begin_life(target) {
2952
+ stamp_file.write_stamp(target, { alive: true, pinged_at: (/* @__PURE__ */ new Date()).toISOString() });
2953
+ }
2954
+ function ping_life(target) {
2955
+ begin_life(target);
2956
+ }
2957
+ function parse_pinged_at(raw) {
2958
+ const parsed = life_schema.safeParse(JSON.parse(raw));
2959
+ if (!parsed.success || parsed.data.pinged_at === void 0) return void 0;
2960
+ const pinged_ms = Date.parse(parsed.data.pinged_at);
2961
+ return Number.isNaN(pinged_ms) ? void 0 : pinged_ms;
2962
+ }
2963
+ function is_life_fresh(target, threshold_ms) {
2964
+ const raw = stamp_file.read_stamp_text(target);
2965
+ if (raw === void 0) return false;
2966
+ try {
2967
+ const pinged_ms = parse_pinged_at(raw);
2968
+ return pinged_ms !== void 0 && Date.now() - pinged_ms < threshold_ms;
2969
+ } catch {
2970
+ return false;
2971
+ }
2972
+ }
2973
+ function is_life_ended(target) {
2974
+ return stamp_file.read_stamp_text(target) === void 0;
2975
+ }
2976
+ function end_life(target) {
2977
+ stamp_file.remove_stamp(target);
2978
+ }
2979
+ function git_directory_sync() {
2980
+ const git_binary = git_utilities.get_git_command_for_spawn();
2981
+ const result = execaSync(git_binary, GIT_DIRECTORY_ARGUMENTS2, {
2982
+ reject: false,
2983
+ timeout: GIT_TIMEOUT_MS
2984
+ });
2985
+ if (result.exitCode !== 0) return void 0;
2986
+ const output = result.stdout.trim();
2987
+ return output === "" ? void 0 : output;
2988
+ }
2989
+ function stamp_target_sync() {
2990
+ const directory = git_directory_sync();
2991
+ return directory === void 0 ? void 0 : stamp_target_of(directory);
2992
+ }
2993
+ function read_last_report_sync() {
2994
+ const target = stamp_target_sync();
2995
+ return target === void 0 ? void 0 : read_last_report(target);
2996
+ }
2997
+ var run_progress_clock = {
2998
+ LIFE_PREFIX,
2999
+ LOG_KEEP,
3000
+ LOG_STALE_MS,
3001
+ PROGRESS_PREFIX,
3002
+ append_line,
3003
+ begin_life,
3004
+ end_life,
3005
+ is_life_ended,
3006
+ is_life_fresh,
3007
+ life_target_of,
3008
+ log_path_of,
3009
+ mark,
3010
+ parse_stamp,
3011
+ ping_life,
3012
+ read_last_line,
3013
+ read_last_report,
3014
+ read_last_report_sync,
3015
+ stamp_target_of,
3016
+ stamp_target_sync
3017
+ };
3018
+
3019
+ // scripts/run/run-watcher-guard.ts
3020
+ var WATCHER_TICK_MS = 3e4;
3021
+ var TICK_MULTIPLIER = 3;
3022
+ var MS_PER_SECOND3 = 1e3;
3023
+ var NO_CUTS = 0;
3024
+ var RELAY_LIFE_PREFIX = "josh-run-relay-life-";
3025
+ var STALE_THRESHOLD_MS = WATCHER_TICK_MS * TICK_MULTIPLIER;
3026
+ var STALE_THRESHOLD_S = STALE_THRESHOLD_MS / MS_PER_SECOND3;
3027
+ var RELAY_STALE_THRESHOLD_MS = run_event_follow.FOLLOW_INTERVAL_MS + STALE_THRESHOLD_MS;
3028
+ var STALE_NOTE = `Lane children are in-flight but the progress watcher has not pinged in the last ${String(STALE_THRESHOLD_S)}s \u2014 run \`pnpm josh run:progress --wait\` in the background before proceeding`;
3029
+ var RELAY_STALE_NOTE = 'This `backlogrun` has cut, and nothing is relaying its event stream to this session \u2014 run `pnpm josh run:event --follow <position>` in the background, relay what it prints, and restart it from the `next_position` it reports each time it exits (`backlogrun-progress.md` \u2192 "The report surface belongs to the run")';
3030
+ var OK_RESULT = { kind: "ok" };
3031
+ async function has_lanes_in_flight() {
3032
+ const all_lanes = await lane_registry.list_lanes();
3033
+ return all_lanes.some((lane) => !lane.is_stranded);
3034
+ }
3035
+ async function check(life_target) {
3036
+ if (!await has_lanes_in_flight()) return OK_RESULT;
3037
+ if (run_progress_clock.is_life_fresh(life_target, STALE_THRESHOLD_MS)) return OK_RESULT;
3038
+ return { kind: "stale", note: STALE_NOTE };
3039
+ }
3040
+ function has_cut(read2) {
3041
+ if (read2.kind !== "carried" && read2.kind !== "expired") return false;
3042
+ return read2.carry.cuts > NO_CUTS;
3043
+ }
3044
+ function check_relay(relay_target, read2) {
3045
+ if (!has_cut(read2)) return OK_RESULT;
3046
+ if (run_progress_clock.is_life_fresh(relay_target, RELAY_STALE_THRESHOLD_MS)) return OK_RESULT;
3047
+ return { kind: "stale", note: RELAY_STALE_NOTE };
3048
+ }
3049
+ function relay_target_of(repository) {
3050
+ return stamp_file.stamp_path(RELAY_LIFE_PREFIX, repository);
3051
+ }
3052
+ async function relay_inputs() {
3053
+ const repository = await run_carry.repository_directory();
3054
+ if (repository === void 0) return void 0;
3055
+ return {
3056
+ target: relay_target_of(repository),
3057
+ read: run_carry.read_carry(run_carry.carry_path(repository))
3058
+ };
3059
+ }
3060
+ async function check_relay_here() {
3061
+ const inputs = await relay_inputs();
3062
+ return inputs === void 0 ? OK_RESULT : check_relay(inputs.target, inputs.read);
3063
+ }
3064
+ async function ping_relay() {
3065
+ try {
3066
+ const repository = await run_carry.repository_directory();
3067
+ if (repository !== void 0) run_progress_clock.ping_life(relay_target_of(repository));
3068
+ } catch {
3069
+ }
3070
+ }
3071
+ var run_watcher_guard = {
3072
+ RELAY_STALE_NOTE,
3073
+ RELAY_STALE_THRESHOLD_MS,
3074
+ STALE_NOTE,
3075
+ STALE_THRESHOLD_MS,
3076
+ check,
3077
+ check_relay,
3078
+ check_relay_here,
3079
+ has_lanes_in_flight,
3080
+ ping_relay,
3081
+ relay_target_of
3082
+ };
3083
+
3084
+ // scripts/run/run-headless.ts
3085
+ var HEADLESS_ENV_KEY = "JOSH_RUN_HEADLESS";
3086
+ var HEADLESS_VALUE = "1";
3087
+ function environment() {
3088
+ return { [HEADLESS_ENV_KEY]: HEADLESS_VALUE };
3089
+ }
3090
+ function is_headless(source = process.env) {
3091
+ return source[HEADLESS_ENV_KEY] === HEADLESS_VALUE;
3092
+ }
3093
+ function is_driving(read2) {
3094
+ return read2?.kind === "carried" && read2.carry.is_handed_off !== true;
3095
+ }
3096
+ async function read_carry_here() {
3097
+ const repository = await run_carry.repository_directory();
3098
+ return repository === void 0 ? void 0 : run_carry.read_carry(run_carry.carry_path(repository));
3099
+ }
3100
+ async function must_keep_waiting(source = process.env) {
3101
+ const is_candidate = is_headless(source) && lane_child_marker.marked_issue(source) === void 0;
3102
+ if (!is_candidate || !await run_watcher_guard.has_lanes_in_flight()) return false;
3103
+ return is_driving(await read_carry_here());
3104
+ }
3105
+ async function is_backlog_parent(source = process.env) {
3106
+ if (lane_child_marker.marked_issue(source) !== void 0) return false;
3107
+ return is_driving(await read_carry_here());
3108
+ }
3109
+ var run_headless = {
3110
+ HEADLESS_ENV_KEY,
3111
+ environment,
3112
+ is_backlog_parent,
3113
+ is_headless,
3114
+ must_keep_waiting
3115
+ };
3116
+
3117
+ // scripts/git/git-gh-api-path.ts
3118
+ var FULL_PAGE_QUERY = "?per_page=100";
3119
+ function repo_api_path(repo) {
3120
+ return `repos/${repo ?? "{owner}/{repo}"}`;
3121
+ }
3122
+ function issues_api_path(repo) {
3123
+ return `${repo_api_path(repo)}/issues`;
3124
+ }
3125
+ function issue_api_path(issue_number, repo) {
3126
+ return `${issues_api_path(repo)}/${issue_number}`;
3127
+ }
3128
+ function blocked_by_api_path(issue_number, repo) {
3129
+ return `${issue_api_path(issue_number, repo)}/dependencies/blocked_by`;
3130
+ }
3131
+ function issue_comments_api_path(issue_number, repo) {
3132
+ return `${issue_api_path(issue_number, repo)}/comments`;
3133
+ }
3134
+ function pulls_api_path(repo) {
3135
+ return `${repo_api_path(repo)}/pulls`;
3136
+ }
3137
+ function pull_api_path(pr_number, repo) {
3138
+ return `${pulls_api_path(repo)}/${pr_number}`;
3139
+ }
3140
+ function pull_merge_api_path(pr_number, repo) {
3141
+ return `${pull_api_path(pr_number, repo)}/merge`;
3142
+ }
3143
+ function pull_comments_api_path(pr_number, repo) {
3144
+ return `${pull_api_path(pr_number, repo)}/comments`;
3145
+ }
3146
+ function pull_reviews_api_path(pr_number, repo) {
3147
+ return `${pull_api_path(pr_number, repo)}/reviews`;
3148
+ }
3149
+ function commit_api_path(commit_sha, repo) {
3150
+ return `${repo_api_path(repo)}/commits/${commit_sha}`;
3151
+ }
3152
+ function commit_check_runs_api_path(commit_sha, repo) {
3153
+ return `${commit_api_path(commit_sha, repo)}/check-runs`;
3154
+ }
3155
+ function commit_status_api_path(commit_sha, repo) {
3156
+ return `${commit_api_path(commit_sha, repo)}/status`;
3157
+ }
3158
+ function tag_reference_api_path(tag, repo) {
3159
+ return `${repo_api_path(repo)}/git/ref/tags/${tag}`;
3160
+ }
3161
+ var git_gh_api_path = {
3162
+ FULL_PAGE_QUERY,
3163
+ repo_api_path,
3164
+ tag_ref_api_path: tag_reference_api_path,
3165
+ issues_api_path,
3166
+ issue_api_path,
3167
+ blocked_by_api_path,
3168
+ issue_comments_api_path,
3169
+ pulls_api_path,
3170
+ pull_api_path,
3171
+ pull_merge_api_path,
3172
+ pull_comments_api_path,
3173
+ pull_reviews_api_path,
3174
+ commit_api_path,
3175
+ commit_check_runs_api_path,
3176
+ commit_status_api_path
3177
+ };
3178
+
3179
+ // scripts/git/parse-json-array.ts
3180
+ var MALFORMED_JSON = /* @__PURE__ */ Symbol("malformed-json");
3181
+ function parse_json_loose(raw_json) {
3182
+ try {
3183
+ return JSON.parse(raw_json);
3184
+ } catch (error) {
3185
+ if (error instanceof SyntaxError) return MALFORMED_JSON;
3186
+ throw error;
3187
+ }
3188
+ }
3189
+ function parse_json_array_or_undefined(raw_json, element_schema) {
3190
+ const value = parse_json_loose(raw_json);
3191
+ if (value === MALFORMED_JSON || !Array.isArray(value)) return void 0;
3192
+ return element_schema.array().parse(value);
3193
+ }
3194
+ function read_json_listing(raw_json, element_schema) {
3195
+ try {
3196
+ const rows = parse_json_array_or_undefined(raw_json, element_schema);
3197
+ return rows === void 0 ? { kind: "unreadable" } : { kind: "read", rows };
3198
+ } catch {
3199
+ return { kind: "unexpected_shape" };
3200
+ }
3201
+ }
3202
+ function parse_json_array_safe(raw_json, element_schema) {
3203
+ const value = parse_json_loose(raw_json);
3204
+ if (value === MALFORMED_JSON) return [];
3205
+ return element_schema.array().parse(value);
3206
+ }
3207
+ function parse_json_object_safe(raw_json, schema) {
3208
+ const value = parse_json_loose(raw_json);
3209
+ if (value === MALFORMED_JSON) return void 0;
3210
+ return schema.parse(value);
3211
+ }
3212
+ var parse_json = {
3213
+ parse_json_array_safe,
3214
+ parse_json_array_or_undefined,
3215
+ parse_json_object_safe,
3216
+ read_json_listing
3217
+ };
3218
+
3219
+ // scripts/git/git-gh-exec.ts
3220
+ import { execa as execa4, execaSync as execaSync2 } from "execa";
3221
+
3222
+ // scripts/git/git-gh-check.ts
3223
+ import { execa as execa3 } from "execa";
3224
+ var GH_NOT_INSTALLED_MSG = "gh CLI is not installed. Install it from https://cli.github.com/";
3225
+ var gh_check = {};
3226
+ async function run_gh_check() {
3227
+ try {
3228
+ await execa3("gh", ["--version"]);
3229
+ } catch {
3230
+ delete gh_check.promise;
3231
+ throw new Error(GH_NOT_INSTALLED_MSG);
3232
+ }
3233
+ }
3234
+ async function check_gh_installed() {
3235
+ gh_check.promise ??= run_gh_check();
3236
+ await gh_check.promise;
3237
+ }
3238
+
3239
+ // scripts/git/git-gh-failure.ts
3240
+ import { z as z8 } from "zod";
3241
+ var error_document_schema = z8.object({ status: z8.union([z8.string(), z8.number()]).optional() }).catch({});
3242
+ var GH_FAILURE_FIELD = "gh_failure";
3243
+ function has_gh_failure(error) {
3244
+ return error instanceof Error && Object.hasOwn(error, GH_FAILURE_FIELD);
3245
+ }
3246
+ function parse_response_status(stdout) {
3247
+ const document = parse_json.parse_json_object_safe(stdout, error_document_schema);
3248
+ if (document?.status === void 0) return void 0;
3249
+ const status2 = Number(document.status);
3250
+ return Number.isSafeInteger(status2) ? status2 : void 0;
3251
+ }
3252
+ function classify_stdout(stdout) {
3253
+ return { status: parse_response_status(stdout) };
3254
+ }
3255
+ function attach(error, failure) {
3256
+ Object.defineProperty(error, GH_FAILURE_FIELD, {
3257
+ value: failure,
3258
+ enumerable: false,
3259
+ configurable: true
3260
+ });
3261
+ return error;
3262
+ }
3263
+ function failure_of(error) {
3264
+ return has_gh_failure(error) ? error.gh_failure : void 0;
3265
+ }
3266
+ var gh_failure = { attach, classify_stdout, failure_of, parse_response_status };
3267
+
3268
+ // scripts/git/git-gh-exec.ts
3269
+ var BODY_FROM_STDIN = "-";
3270
+ var GH_REQUEST_TIMEOUT_MS = 6e4;
3271
+ function to_timeout_option(timeout_ms) {
3272
+ return { timeout: timeout_ms ?? GH_REQUEST_TIMEOUT_MS };
3273
+ }
3274
+ function direct_environment() {
3275
+ const removed = agent_session_environment.removed_proxy_environment();
3276
+ return Object.keys(removed).length > 0 ? { env: removed } : {};
3277
+ }
3278
+ function to_spawn_options(timeout_ms) {
3279
+ return { ...to_timeout_option(timeout_ms), ...direct_environment() };
3280
+ }
3281
+ var GH_REQUEST_TIMEOUT_MESSAGE = "gh request timed out";
3282
+ function has_stderr_field(error) {
3283
+ return error instanceof Error && "stderr" in error && typeof error.stderr === "string";
3284
+ }
3285
+ function has_stdout_field(error) {
3286
+ return error instanceof Error && "stdout" in error && typeof error.stdout === "string";
3287
+ }
3288
+ function to_timeout_prefix(error) {
3289
+ return has_timed_out(error) ? `${GH_REQUEST_TIMEOUT_MESSAGE}: ` : "";
3290
+ }
3291
+ function to_error_message(error) {
3292
+ return error instanceof Error ? error.message : String(error);
3293
+ }
3294
+ function to_gh_error(error) {
3295
+ const stderr = has_stderr_field(error) ? error.stderr.trim() : "";
3296
+ const stdout = has_stdout_field(error) ? error.stdout.trim() : "";
3297
+ const summary = stderr.length > 0 ? stderr : to_error_message(error);
3298
+ const detail = stdout.length > 0 ? `${summary}
3299
+ ${stdout}` : summary;
3300
+ return gh_failure.attach(
3301
+ new Error(`${to_timeout_prefix(error)}${detail}`, { cause: error }),
3302
+ gh_failure.classify_stdout(stdout)
3303
+ );
3304
+ }
3305
+ async function exec_gh_command(arguments_, timeout_ms) {
3306
+ await check_gh_installed();
3307
+ try {
3308
+ const { stdout } = await execa4("gh", arguments_, to_spawn_options(timeout_ms));
3309
+ return stdout.trimEnd();
3310
+ } catch (error) {
3311
+ throw to_gh_error(error);
3312
+ }
3313
+ }
3314
+ async function exec_gh_command_with_stdin(input) {
3315
+ await check_gh_installed();
3316
+ const options = { input: input.stdin_body, ...to_spawn_options(input.timeout_ms) };
3317
+ try {
3318
+ const { stdout } = await execa4("gh", input.args, options);
3319
+ return stdout.trimEnd();
3320
+ } catch (error) {
3321
+ throw to_gh_error(error);
3322
+ }
3323
+ }
3324
+ var STATUS_LINE_PATTERN = /^HTTP\/[\d.]+ (?<status>\d{3})\b/u;
3325
+ function parse_status_line(output) {
3326
+ const { status: status2 } = STATUS_LINE_PATTERN.exec(output)?.groups ?? {};
3327
+ return status2 === void 0 ? void 0 : Number(status2);
3328
+ }
3329
+ async function exec_gh_api_status(path4, timeout_ms) {
3330
+ const options = to_spawn_options(timeout_ms);
3331
+ try {
3332
+ await check_gh_installed();
3333
+ const { stdout } = await execa4("gh", ["api", "--include", "--silent", path4], options);
3334
+ return parse_status_line(stdout);
3335
+ } catch (error) {
3336
+ return has_stdout_field(error) ? parse_status_line(error.stdout) : void 0;
3337
+ }
3338
+ }
3339
+ var METHOD_FLAG = "--method";
3340
+ var INPUT_FLAG = "--input";
3341
+ var PAGINATE_FLAG = "--paginate";
3342
+ var SLURP_FLAG = "--slurp";
3343
+ var JQ_FLAG = "--jq";
3344
+ function optional_flag(flag, value) {
3345
+ return value === void 0 ? [] : [flag, value];
3346
+ }
3347
+ function to_gh_api_args(request) {
3348
+ const body_args = request.body === void 0 ? [] : [INPUT_FLAG, BODY_FROM_STDIN];
3349
+ const paginate_args = request.should_paginate === true ? [PAGINATE_FLAG] : [];
3350
+ const slurp_args = request.should_slurp === true ? [SLURP_FLAG] : [];
3351
+ return [
3352
+ "api",
3353
+ request.path,
3354
+ ...optional_flag(METHOD_FLAG, request.method),
3355
+ ...body_args,
3356
+ ...paginate_args,
3357
+ ...slurp_args,
3358
+ ...optional_flag(JQ_FLAG, request.jq_filter)
3359
+ ];
3360
+ }
3361
+ async function exec_gh_api(request) {
3362
+ const args = to_gh_api_args(request);
3363
+ if (request.body === void 0) return await exec_gh_command(args, request.timeout_ms);
3364
+ return await exec_gh_command_with_stdin({
3365
+ args,
3366
+ stdin_body: request.body,
3367
+ timeout_ms: request.timeout_ms
3368
+ });
3369
+ }
3370
+ function exec_gh_api_sync(request) {
3371
+ const body_option = request.body === void 0 ? {} : { input: request.body };
3372
+ const options = { ...body_option, ...to_spawn_options(request.timeout_ms) };
3373
+ try {
3374
+ const { stdout } = execaSync2("gh", to_gh_api_args(request), options);
3375
+ return stdout.trimEnd();
3376
+ } catch (error) {
3377
+ throw to_gh_error(error);
3378
+ }
3379
+ }
3380
+ var git_gh_exec = {
3381
+ direct_environment,
3382
+ exec_gh_command,
3383
+ exec_gh_command_with_stdin,
3384
+ exec_gh_api,
3385
+ exec_gh_api_sync,
3386
+ exec_gh_api_status,
3387
+ parse_status_line
3388
+ };
3389
+
3390
+ export {
3391
+ bash_triggers,
3392
+ run_progress_clock,
3393
+ shell_segments,
3394
+ tail_commands,
3395
+ filing_cap,
3396
+ CONTEXT_CUT_THRESHOLD,
3397
+ RECENT_REQUEST_WINDOW,
3398
+ agent_session_environment,
3399
+ agent_role_profile,
3400
+ backlog_budget,
3401
+ git_command,
3402
+ run_hold,
3403
+ run_cut,
3404
+ IN_PROGRESS_LABEL,
3405
+ NEEDS_DECISION_LABEL,
3406
+ NEEDS_HUMAN_REVIEW_LABEL,
3407
+ ALREADY_DONE_LABEL,
3408
+ has_any_label,
3409
+ lane_park,
3410
+ run_event_stream,
3411
+ repo_party,
3412
+ process_identity,
3413
+ run_carry,
3414
+ lane_registry,
3415
+ run_watcher_guard,
3416
+ run_headless,
3417
+ FULL_PAGE_QUERY,
3418
+ git_gh_api_path,
3419
+ parse_json_array_or_undefined,
3420
+ read_json_listing,
3421
+ parse_json_object_safe,
3422
+ gh_failure,
3423
+ has_stderr_field,
3424
+ git_gh_exec
3425
+ };