@joshuafolkken/kit 1.1166.0 → 1.1229.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 (437) hide show
  1. package/.claude/.claude-plugin/plugin.json +1 -1
  2. package/.claude/settings.json +2 -2
  3. package/.claude/skills/dependency-update/SKILL.md +4 -8
  4. package/.claude/skills/epic-commands/SKILL.md +2 -2
  5. package/.claude/skills/epic-commands/epic-bundle.md +1 -1
  6. package/.claude/skills/workflow-commands/SKILL.md +2 -4
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +9 -5
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +29 -9
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +7 -2
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +4 -3
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +24 -15
  13. package/.claude/skills/workflow-commands/chain-rule.md +1 -1
  14. package/.claude/skills/workflow-commands/delegation.md +2 -2
  15. package/.claude/skills/workflow-commands/followup.md +5 -0
  16. package/.claude/skills/workflow-commands/fullrun-steps.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  19. package/.claude/skills/workflow-commands/kickoff.md +1 -1
  20. package/.claude/skills/workflow-commands/observation-ledger.md +3 -3
  21. package/.claude/skills/workflow-commands/pre-gate-cut.md +10 -5
  22. package/.claude/skills/workflow-commands/prerequisite.md +2 -2
  23. package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
  24. package/.claude/skills/workflow-commands/working-tree-hold.md +1 -1
  25. package/.codex/hooks.json +2 -2
  26. package/.cursorrules +6 -41
  27. package/.github/actions/setup-node/action.yml +1 -1
  28. package/.github/workflows/auto-tag.yml +3 -4
  29. package/.github/workflows/ci.yml +47 -33
  30. package/.github/workflows/dependabot-auto-merge.yml +13 -6
  31. package/.github/workflows/publish.yml +48 -4
  32. package/.github/workflows/sonar-qube.yml +3 -0
  33. package/.pnpmfile.mjs +4 -3
  34. package/.prettierignore +8 -2
  35. package/CLAUDE.md +18 -20
  36. package/README.md +26 -19
  37. package/SECURITY.md +15 -1
  38. package/dist/CLAUDE.md +18 -20
  39. package/dist/commands/document-section-cli.js +734 -0
  40. package/dist/hooks/audit-provision.js +346 -0
  41. package/dist/hooks/batch-guard.js +5 -4
  42. package/dist/hooks/{chunk-DYAVAM6S.js → chunk-55HHG5PX.js} +1405 -631
  43. package/dist/hooks/{chunk-A6P7PN7P.js → chunk-5VMKCCC4.js} +25 -10
  44. package/dist/hooks/chunk-5VNDSNG3.js +12 -0
  45. package/dist/hooks/{chunk-5KTCMCOT.js → chunk-6HJJXRBX.js} +4 -2
  46. package/dist/hooks/chunk-CDY4NFQG.js +15 -0
  47. package/dist/hooks/chunk-ELCN5LCH.js +135 -0
  48. package/dist/hooks/{chunk-ENA7P5FB.js → chunk-F56MFS4B.js} +3 -3
  49. package/dist/hooks/{chunk-ANJ2WGFD.js → chunk-FIVDHQGT.js} +7 -6
  50. package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
  51. package/dist/hooks/{chunk-GU5MATVE.js → chunk-JUDKDCDP.js} +499 -389
  52. package/dist/hooks/{chunk-ZDZ555YH.js → chunk-NV2JRZZO.js} +743 -909
  53. package/dist/hooks/{chunk-V2BTOZHT.js → chunk-RNWHN5BP.js} +3 -3
  54. package/dist/hooks/{chunk-URJA6XY4.js → chunk-TQNPDZNH.js} +4 -4
  55. package/dist/hooks/{chunk-GYNGP7HI.js → chunk-VC3PZPZO.js} +1 -1
  56. package/dist/hooks/codex-hook-adapter.js +14 -12
  57. package/dist/hooks/duplicate-read-guard.js +6 -5
  58. package/dist/hooks/format-edited.js +4 -3
  59. package/dist/hooks/inputs.json +232 -210
  60. package/dist/hooks/investigation-guard.js +6 -5
  61. package/dist/hooks/pretool-guard.js +12 -10
  62. package/dist/hooks/session-lang.js +2 -4
  63. package/dist/hooks/stop-guard.js +81 -59
  64. package/dist/josh.js +872 -75
  65. package/dist/version/index.d.ts +7 -2
  66. package/dist/version/index.js +152 -75
  67. package/eslint/base.js +23 -1
  68. package/eslint/rules/code-quality.js +3 -0
  69. package/eslint/rules/early-return-one-liner.js +98 -0
  70. package/eslint/rules/unicorn.js +16 -1
  71. package/package.json +7 -6
  72. package/pnpm-workspace.yaml +9 -4
  73. package/prettier/basic.d.ts +3 -1
  74. package/prettier/index.d.ts +3 -1
  75. package/prettier/static.d.ts +3 -1
  76. package/prompts/coding-standards.md +1 -1
  77. package/prompts/collaboration-workflow/file-edits.md +4 -4
  78. package/prompts/collaboration-workflow/glossary.md +1 -1
  79. package/prompts/collaboration-workflow/operating-rules.md +17 -9
  80. package/prompts/collaboration-workflow/overview.md +2 -2
  81. package/prompts/collaboration-workflow/principles.md +14 -12
  82. package/prompts/collaboration-workflow/report-format.md +1 -1
  83. package/prompts/collaboration-workflow/residency.md +1 -1
  84. package/prompts/collaboration-workflow/rule-delivery.md +6 -6
  85. package/prompts/collaboration-workflow/shell-body.md +6 -6
  86. package/prompts/collaboration-workflow/turn-batching.md +1 -1
  87. package/prompts/collaboration-workflow/upstream-interrupt.md +12 -2
  88. package/prompts/collaboration-workflow/wip-cap.md +10 -10
  89. package/prompts/review-rubric.md +1 -2
  90. package/prompts/review.md +1 -1
  91. package/scripts/agent/agent-headless.ts +29 -0
  92. package/scripts/agent/agent-launch-environment.ts +6 -2
  93. package/scripts/agent/codex-agent-argv.ts +2 -1
  94. package/scripts/auto-ok/auto-ok-cli.ts +1 -1
  95. package/scripts/backlog/backlog-arrival.ts +3 -3
  96. package/scripts/backlog/backlog-budget.ts +1 -1
  97. package/scripts/backlog/backlog-drive-args.ts +135 -0
  98. package/scripts/backlog/backlog-drive-cli.ts +11 -137
  99. package/scripts/backlog/backlog-drive-launch.ts +39 -0
  100. package/scripts/backlog/backlog-drive-named-offer.ts +3 -5
  101. package/scripts/backlog/backlog-drive-named.ts +3 -3
  102. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  103. package/scripts/backlog/backlog-drive-owner.ts +1 -1
  104. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  105. package/scripts/backlog/backlog-drive-retrospective.ts +1 -1
  106. package/scripts/backlog/backlog-drive.ts +1 -1
  107. package/scripts/backlog/backlog-next.ts +31 -9
  108. package/scripts/backlog/backlog-offer-cli.ts +6 -6
  109. package/scripts/backlog/backlog-offer.ts +1 -1
  110. package/scripts/backlog/backlog-plan-cli.ts +7 -6
  111. package/scripts/backlog/backlog-pool.ts +57 -11
  112. package/scripts/backlog/backlog-rank.ts +18 -9
  113. package/scripts/backlog/backlog-ready.ts +1 -1
  114. package/scripts/backlog/backlog-restructure.ts +152 -0
  115. package/scripts/backlog/backlog-scope.ts +1 -1
  116. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  117. package/scripts/backlog/backlog-stalled.ts +1 -1
  118. package/scripts/backlog/backlog-waves.ts +15 -17
  119. package/scripts/build/build-codex-hooks.ts +3 -1
  120. package/scripts/build/build-commands.ts +66 -0
  121. package/scripts/build/build-hooks.ts +2 -1
  122. package/scripts/build/build-library.ts +12 -3
  123. package/scripts/build/build.ts +70 -0
  124. package/scripts/build/local-bin.ts +3 -13
  125. package/scripts/cost-runtime/context-cut-threshold.ts +1 -9
  126. package/scripts/cost-runtime/cost-verdict.ts +15 -28
  127. package/scripts/delegation/investigation-reads.ts +3 -1
  128. package/scripts/discovery/repo-origin.ts +5 -5
  129. package/scripts/doctor/doctor-consumer.ts +2 -2
  130. package/scripts/doctor/doctor-io.ts +2 -3
  131. package/scripts/document/capped-print-part.ts +30 -0
  132. package/scripts/document/capped-print.ts +3 -4
  133. package/scripts/document/document-byte-budget.ts +11 -2
  134. package/scripts/document/document-scan.ts +117 -0
  135. package/scripts/document/document-section.ts +143 -16
  136. package/scripts/document/entry-read-budget.ts +5 -3
  137. package/scripts/document/entry-read-set.ts +10 -89
  138. package/scripts/document/read-set-cost.ts +98 -0
  139. package/scripts/epic/epic-add-body.ts +1 -0
  140. package/scripts/epic/epic-audit-checks.ts +1 -1
  141. package/scripts/epic/epic-audit-rationale.ts +4 -3
  142. package/scripts/epic/epic-bundle-cli.ts +14 -3
  143. package/scripts/epic/epic-bundle-poll.ts +41 -0
  144. package/scripts/epic/epic-busy.ts +1 -1
  145. package/scripts/epic/epic-candidate-confirm.ts +3 -2
  146. package/scripts/epic/epic-classify.ts +1 -1
  147. package/scripts/epic/epic-cli-argv.ts +78 -46
  148. package/scripts/epic/epic-cli-remove.ts +11 -19
  149. package/scripts/epic/epic-cli.ts +74 -73
  150. package/scripts/epic/epic-close-comment.ts +1 -1
  151. package/scripts/epic/epic-close.ts +1 -1
  152. package/scripts/epic/epic-cross-repo.ts +5 -5
  153. package/scripts/epic/epic-graph.ts +1 -1
  154. package/scripts/epic/epic-index.ts +1 -1
  155. package/scripts/epic/epic-issue.ts +2 -6
  156. package/scripts/epic/epic-lane-offer.ts +2 -2
  157. package/scripts/epic/epic-next.ts +29 -42
  158. package/scripts/epic/epic-solo-stale.ts +1 -1
  159. package/scripts/epic/epic-triage.ts +8 -4
  160. package/scripts/epic/epic-validate.ts +1 -1
  161. package/scripts/followup/git-followup-finish.ts +2 -2
  162. package/scripts/followup/git-followup-label.ts +2 -2
  163. package/scripts/followup/git-followup-merged.ts +2 -2
  164. package/scripts/followup/git-followup-stages.ts +9 -0
  165. package/scripts/followup/git-pr-followup-checks.ts +142 -0
  166. package/scripts/followup/git-pr-followup.ts +5 -130
  167. package/scripts/gate/core-budget.ts +69 -1
  168. package/scripts/gate/gate-plan.ts +47 -7
  169. package/scripts/gate/gate-skip.ts +38 -7
  170. package/scripts/gate/hook-gate-reuse.ts +12 -10
  171. package/scripts/gate/pre-commit-type-check.ts +4 -1
  172. package/scripts/gate/project-checks.ts +6 -9
  173. package/scripts/gate/type-check-step.ts +2 -3
  174. package/scripts/gate/verification-gate.ts +27 -8
  175. package/scripts/gh/git-gh-api-path.ts +2 -2
  176. package/scripts/gh/git-gh-issue-rest.ts +3 -3
  177. package/scripts/gh/git-gh-issue-write.ts +53 -7
  178. package/scripts/gh/git-gh-issue.ts +5 -3
  179. package/scripts/gh/git-gh-pr-read.ts +68 -19
  180. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  181. package/scripts/gh/git-gh-pr.ts +5 -1
  182. package/scripts/gh/git-pr-ai-review.ts +1 -1
  183. package/scripts/gh/git-pr-checks-eval.ts +9 -3
  184. package/scripts/gh/git-pr-checks-parse.ts +1 -1
  185. package/scripts/gh/git-pr-checks-watch.ts +6 -5
  186. package/scripts/gh/git-pr-checks.ts +18 -6
  187. package/scripts/gh/git-pr-coderabbit.ts +1 -1
  188. package/scripts/gh/git-pr-error.ts +1 -3
  189. package/scripts/gh/git-pr.ts +9 -13
  190. package/scripts/gh/github-issue-url.ts +2 -2
  191. package/scripts/git/constants.ts +12 -6
  192. package/scripts/git/git-command.ts +20 -218
  193. package/scripts/git/git-diff-reads.ts +225 -0
  194. package/scripts/git/git-error.ts +4 -12
  195. package/scripts/git/git-pre-push-hook.ts +139 -0
  196. package/scripts/git/git-prompt.ts +2 -6
  197. package/scripts/git/{schemas.ts → git-schemas.ts} +2 -0
  198. package/scripts/git/git-spawn-sync.ts +3 -1
  199. package/scripts/git/git-spawn.ts +1 -1
  200. package/scripts/git/git-staging.ts +4 -6
  201. package/scripts/git/git-status.ts +3 -9
  202. package/scripts/git/main-merge.ts +57 -21
  203. package/scripts/hooks/codex-hook-adapter.ts +1 -1
  204. package/scripts/hooks/edited-cspell.ts +2 -4
  205. package/scripts/hooks/format-edited-file.ts +3 -12
  206. package/scripts/hooks/pre-push-unit.ts +31 -9
  207. package/scripts/hooks/reserved-run.ts +2 -2
  208. package/scripts/hooks/run-hook.sh +5 -4
  209. package/scripts/hooks/stop-guard.ts +5 -3
  210. package/scripts/init/init-actions.ts +0 -5
  211. package/scripts/init/init-ai-copy.ts +13 -2
  212. package/scripts/init/init-logic-json-merge.ts +19 -0
  213. package/scripts/init/init-logic-secretlint.ts +7 -7
  214. package/scripts/init/init-logic-workspace.ts +41 -2
  215. package/scripts/init/init-logic.ts +16 -26
  216. package/scripts/init/init.ts +5 -15
  217. package/scripts/init/initial-commit.ts +4 -4
  218. package/scripts/init/kit-development-versions.ts +40 -0
  219. package/scripts/init/kit-setup-state.ts +2 -2
  220. package/scripts/init/start-exec.ts +68 -19
  221. package/scripts/init/start-setup-pr.ts +9 -9
  222. package/scripts/init/start-steps.ts +6 -10
  223. package/scripts/issue/defect-rate-cli.ts +1 -1
  224. package/scripts/issue/git-next-issues.ts +1 -1
  225. package/scripts/issue/issue-auto-ok.ts +1 -1
  226. package/scripts/issue/issue-backlinks-cli.ts +2 -2
  227. package/scripts/issue/issue-backlinks.ts +9 -9
  228. package/scripts/issue/issue-comment-cli.ts +19 -13
  229. package/scripts/issue/issue-file-cli.ts +45 -18
  230. package/scripts/issue/issue-file.ts +24 -1
  231. package/scripts/issue/issue-scout-closed.ts +1 -1
  232. package/scripts/issue/issue-state-cli.ts +30 -74
  233. package/scripts/josh/josh-command-map.ts +2 -0
  234. package/scripts/josh/josh-command-types.ts +11 -0
  235. package/scripts/josh/josh-commands-ai.ts +4 -4
  236. package/scripts/josh/josh-commands-backlog.ts +4 -1
  237. package/scripts/josh/josh-commands-development.ts +11 -1
  238. package/scripts/josh/josh-commands-document.ts +1 -0
  239. package/scripts/josh/josh-commands-lane.ts +22 -0
  240. package/scripts/josh/josh-commands-maintenance.ts +4 -4
  241. package/scripts/josh/josh-commands-run.ts +12 -7
  242. package/scripts/josh/josh-in-process.ts +28 -9
  243. package/scripts/josh/josh-logic.ts +33 -15
  244. package/scripts/josh/process-identity.ts +1 -3
  245. package/scripts/josh/session-language-cli.ts +3 -4
  246. package/scripts/lane/lane-await.ts +5 -1
  247. package/scripts/lane/lane-child-invocation.ts +2 -2
  248. package/scripts/lane/lane-cli.ts +3 -3
  249. package/scripts/lane/lane-dispatch.ts +14 -10
  250. package/scripts/lane/lane-environment.ts +5 -1
  251. package/scripts/lane/lane-handoff.ts +1 -1
  252. package/scripts/lane/lane-install.ts +2 -13
  253. package/scripts/lane/lane-launch-cli.ts +35 -3
  254. package/scripts/lane/lane-ledger.ts +145 -0
  255. package/scripts/lane/lane-leftover.ts +1 -1
  256. package/scripts/lane/lane-load.ts +108 -0
  257. package/scripts/lane/lane-measure-cli.ts +149 -0
  258. package/scripts/lane/lane-occupancy.ts +3 -0
  259. package/scripts/lane/lane-reap.ts +1 -3
  260. package/scripts/lane/lane-relaunch.ts +1 -1
  261. package/scripts/lane/lane-stats.ts +224 -0
  262. package/scripts/lane/lane-vacant.ts +36 -0
  263. package/scripts/lane/openai-lane-ship.ts +2 -2
  264. package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
  265. package/scripts/lane/openai-lane-supervisor.ts +7 -165
  266. package/scripts/lane/openai-review-broker.ts +2 -4
  267. package/scripts/lib/ancestor-directories.ts +35 -0
  268. package/scripts/lib/animation-helpers.ts +2 -2
  269. package/scripts/lib/buffered-process.ts +3 -7
  270. package/scripts/lib/cli-flags.ts +71 -1
  271. package/scripts/lib/spawn-exit.ts +2 -2
  272. package/scripts/lib/timeouts.ts +35 -2
  273. package/scripts/lines/line-budget.ts +4 -6
  274. package/scripts/notify/telegram-notify.ts +26 -1
  275. package/scripts/notify/telegram-test.ts +6 -0
  276. package/scripts/observations/observation-ledger-line.ts +6 -6
  277. package/scripts/observations/observation-ledger-migrate.ts +55 -4
  278. package/scripts/observations/observation-ledger.ts +26 -7
  279. package/scripts/overrides/lockfile-overrides.ts +1 -1
  280. package/scripts/overrides/overrides-logic.ts +1 -1
  281. package/scripts/propagate/propagate-git.ts +1 -1
  282. package/scripts/propagate/propagate-publish.ts +2 -2
  283. package/scripts/propagate/propagate-steps.ts +20 -15
  284. package/scripts/propagate/propagate.ts +36 -27
  285. package/scripts/refactor/import-graph.ts +18 -1
  286. package/scripts/refactor/refactor-lint.ts +4 -4
  287. package/scripts/repo/repository-labels.ts +2 -2
  288. package/scripts/repo/required-checks-logic.ts +1 -3
  289. package/scripts/review/live-evidence.ts +2 -4
  290. package/scripts/review/review-brief-cli.ts +1 -1
  291. package/scripts/review/review-finding-ledger.ts +1 -1
  292. package/scripts/review/review-findings-cli.ts +1 -3
  293. package/scripts/rules/decision-oracle-batch.ts +128 -0
  294. package/scripts/rules/decision-oracle-tokens.ts +21 -0
  295. package/scripts/rules/decision-oracle.ts +8 -120
  296. package/scripts/rules/delivered-rules.ts +26 -182
  297. package/scripts/rules/direct-filing.ts +1 -1
  298. package/scripts/rules/early-heartbeat.ts +3 -3
  299. package/scripts/rules/git-argv.ts +1 -1
  300. package/scripts/rules/git-force.ts +1 -1
  301. package/scripts/rules/implementation-cut.ts +2 -2
  302. package/scripts/rules/index-guard.ts +1 -1
  303. package/scripts/rules/issue-comments.ts +118 -0
  304. package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
  305. package/scripts/rules/lane-background.ts +2 -2
  306. package/scripts/rules/lane-park.ts +18 -0
  307. package/scripts/rules/lane-split-park.ts +128 -0
  308. package/scripts/rules/oracle-firing.ts +1 -1
  309. package/scripts/rules/poll-loop.ts +1 -1
  310. package/scripts/rules/pre-gate-cut.ts +3 -3
  311. package/scripts/rules/protected-files.ts +59 -4
  312. package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
  313. package/scripts/rules/shell-body-trigger.ts +1 -1
  314. package/scripts/rules/stop-rules.ts +18 -7
  315. package/scripts/rules/test-declared-commit.ts +4 -4
  316. package/scripts/rules/wip-cap.ts +63 -0
  317. package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
  318. package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
  319. package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
  320. package/scripts/run/{run-carry.ts → carry/run-carry.ts} +12 -6
  321. package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
  322. package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +3 -3
  323. package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +2 -2
  324. package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
  325. package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
  326. package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
  327. package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
  328. package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
  329. package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +16 -2
  330. package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
  331. package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
  332. package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
  333. package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
  334. package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
  335. package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
  336. package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
  337. package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
  338. package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
  339. package/scripts/run/run-ending.ts +2 -2
  340. package/scripts/run/run-halfrun-resume.ts +6 -1
  341. package/scripts/run/run-headless.ts +1 -1
  342. package/scripts/run/run-invocation.ts +85 -84
  343. package/scripts/run/run-liveness.ts +1 -1
  344. package/scripts/run/run-parent-cut-hook.ts +1 -1
  345. package/scripts/run/run-preflight.ts +6 -6
  346. package/scripts/run/run-prep-cli.ts +1 -1
  347. package/scripts/run/run-prrun-resume.ts +1 -1
  348. package/scripts/run/run-report-cli.ts +4 -4
  349. package/scripts/run/run-report.ts +2 -2
  350. package/scripts/run/run-status-cli.ts +1 -1
  351. package/scripts/run/run-step-cli.ts +3 -3
  352. package/scripts/run/run-step.ts +2 -2
  353. package/scripts/run/run-stop-notify.ts +1 -1
  354. package/scripts/run/run-stranded-detect.ts +4 -4
  355. package/scripts/run/run-stranded.ts +2 -2
  356. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  357. package/scripts/run/run-watcher-guard.ts +5 -3
  358. package/scripts/run/run-watcher-hook.ts +1 -1
  359. package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +29 -8
  360. package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
  361. package/scripts/run/ship/run-ship-lock.ts +50 -0
  362. package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +13 -0
  363. package/scripts/run/ship/run-ship-pre-detach.ts +66 -0
  364. package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
  365. package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
  366. package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +10 -6
  367. package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
  368. package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
  369. package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +13 -0
  370. package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +15 -8
  371. package/scripts/run/ship/run-ship-stop-text.ts +13 -0
  372. package/scripts/run/ship/run-ship-sync.ts +128 -0
  373. package/scripts/run/{run-ship.ts → ship/run-ship.ts} +6 -0
  374. package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
  375. package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +31 -9
  376. package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +3 -3
  377. package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +99 -17
  378. package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
  379. package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +8 -2
  380. package/scripts/run/wake/run-wake-restart.ts +58 -0
  381. package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
  382. package/scripts/run/{run-wake.ts → wake/run-wake.ts} +1 -1
  383. package/scripts/safe-chain/preinstall-command.ts +20 -21
  384. package/scripts/safe-chain/project-config.ts +19 -15
  385. package/scripts/sync/sync-ai-files.ts +1 -1
  386. package/scripts/sync/sync-configs.ts +2 -1
  387. package/scripts/sync/sync.ts +15 -2
  388. package/scripts/test/test-red-logic.ts +17 -2
  389. package/scripts/test/test-red.ts +8 -7
  390. package/scripts/test/unit-worker-share.ts +1 -0
  391. package/scripts/time-runtime/time-background.ts +5 -1
  392. package/scripts/time-runtime/time-instant.ts +3 -1
  393. package/scripts/time-runtime/time-spans.ts +6 -139
  394. package/scripts/time-runtime/time-tool-call.ts +160 -0
  395. package/scripts/time-runtime/time-transcript-line.ts +27 -1
  396. package/scripts/version/effective-upstream.ts +2 -20
  397. package/scripts/version/latest-corepack.ts +17 -17
  398. package/scripts/version/latest-regression.ts +1 -1
  399. package/scripts/version/latest-update.ts +4 -4
  400. package/scripts/version/npm-registry.ts +20 -5
  401. package/scripts/version/publishable-range-check.ts +2 -2
  402. package/scripts/version/publishable-range.ts +1 -1
  403. package/scripts/version/release-age.ts +48 -38
  404. package/scripts/version/release-hold.ts +1 -1
  405. package/scripts/version/safe-chain-version-update.ts +40 -0
  406. package/scripts/version/upgrade-shell-command.ts +48 -8
  407. package/scripts/version/version-check-logic.ts +23 -14
  408. package/scripts/version/version-commands.ts +23 -11
  409. package/scripts/version/version-remote.ts +28 -13
  410. package/templates/pnpm-workspace.basic.yaml +4 -0
  411. package/templates/workflows/dependabot-auto-merge.yml +5 -5
  412. package/templates/workflows/github-release.yml +2 -0
  413. package/scripts/build/build-config-merge.ts +0 -27
  414. package/scripts/build/build-managed-marker.ts +0 -27
  415. package/scripts/build/build-self-sync-guard.ts +0 -27
  416. package/scripts/build/build-version.ts +0 -26
  417. package/scripts/version/preinstall-version-update.ts +0 -86
  418. /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
  419. /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
  420. /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
  421. /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
  422. /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
  423. /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
  424. /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
  425. /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
  426. /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
  427. /package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +0 -0
  428. /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
  429. /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
  430. /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
  431. /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
  432. /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
  433. /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
  434. /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
  435. /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
  436. /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
  437. /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
package/dist/josh.js CHANGED
@@ -20,22 +20,25 @@ function read_spawn_stderr(result) {
20
20
  return result.stderr ?? "";
21
21
  }
22
22
 
23
+ // scripts/lib/timeouts.ts
24
+ var PROBE_TIMEOUT_MS = 2e3;
25
+ var GIT_TIMEOUT_MS = 1e4;
26
+
23
27
  // scripts/git/git-spawn-sync.ts
24
28
  import { execaSync } from "execa";
25
29
 
26
30
  // scripts/git/constants.ts
27
31
  import { platform } from "node:os";
28
32
  var GIT_COMMAND_UNIX = "/usr/bin/git";
33
+ var GIT_BINARY_KEY = "JOSH_GIT_BINARY";
29
34
  function get_git_command() {
30
- if (platform() === "win32") {
31
- return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
32
- }
35
+ if (platform() === "win32") return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
33
36
  return GIT_COMMAND_UNIX;
34
37
  }
35
38
  function get_git_command_for_spawn() {
36
- if (platform() === "win32") {
37
- return String.raw`C:\Program Files\Git\cmd\git.exe`;
38
- }
39
+ const binary = process.env[GIT_BINARY_KEY];
40
+ if (binary !== void 0 && binary !== "") return binary;
41
+ if (platform() === "win32") return String.raw`C:\Program Files\Git\cmd\git.exe`;
39
42
  return GIT_COMMAND_UNIX;
40
43
  }
41
44
  var git_utilities = {
@@ -44,7 +47,6 @@ var git_utilities = {
44
47
  };
45
48
 
46
49
  // scripts/git/git-spawn-sync.ts
47
- var GIT_TIMEOUT_MS = 1e4;
48
50
  var SUCCESS_EXIT_CODE = 0;
49
51
  var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
50
52
  function run(args, options = {}) {
@@ -91,20 +93,20 @@ var ABSENT_CODE = "ENOENT";
91
93
  function is_absent(error) {
92
94
  return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
93
95
  }
94
- function read_optional(path5) {
96
+ function read_optional(path12) {
95
97
  try {
96
- return readFileSync(path5, "utf8");
98
+ return readFileSync(path12, "utf8");
97
99
  } catch (error) {
98
100
  if (is_absent(error)) return void 0;
99
101
  throw error;
100
102
  }
101
103
  }
102
- function read_file_or_empty(path5) {
103
- return read_optional(path5) ?? "";
104
+ function read_file_or_empty(path12) {
105
+ return read_optional(path12) ?? "";
104
106
  }
105
- function read_if_readable(path5) {
107
+ function read_if_readable(path12) {
106
108
  try {
107
- return readFileSync(path5, "utf8");
109
+ return readFileSync(path12, "utf8");
108
110
  } catch {
109
111
  return void 0;
110
112
  }
@@ -122,7 +124,6 @@ var CLAUDE_MD = "CLAUDE.md";
122
124
  var PLUGIN_ID = "kit@kit";
123
125
  var CLAUDE_MD_POINTER = `@${NODE_MODULES}/${KIT_PACKAGE_NAME}/dist/${CLAUDE_MD}`;
124
126
  var SECRETLINT_BIN = path.join(NODE_MODULES, ".bin", "secretlint");
125
- var GIT_TIMEOUT_MS2 = 2e3;
126
127
  var manifest_schema = z.object({
127
128
  name: z.string().optional(),
128
129
  dependencies: z.record(z.string(), z.string()).optional(),
@@ -157,7 +158,7 @@ function is_plugin_declared(root) {
157
158
  }
158
159
  function configured_hooks_path(root) {
159
160
  const value = git_spawn_sync.read(["-C", root, "config", "--get", "core.hooksPath"], {
160
- timeout: GIT_TIMEOUT_MS2
161
+ timeout: PROBE_TIMEOUT_MS
161
162
  });
162
163
  return value === "" ? void 0 : value;
163
164
  }
@@ -229,14 +230,31 @@ var doctor_consumer = {
229
230
  };
230
231
 
231
232
  // scripts/josh/josh-logic.ts
232
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
233
- import path4 from "node:path";
234
- import { fileURLToPath } from "node:url";
233
+ import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
234
+ import path11 from "node:path";
235
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
235
236
 
236
237
  // scripts/build/local-bin.ts
237
238
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
238
239
  import { createRequire } from "node:module";
240
+ import path3 from "node:path";
241
+
242
+ // scripts/lib/ancestor-directories.ts
239
243
  import path2 from "node:path";
244
+ var MAX_DEPTH = 64;
245
+ function list(start_directory) {
246
+ const directories = [];
247
+ let current = path2.resolve(start_directory);
248
+ while (directories.length < MAX_DEPTH && !directories.includes(current)) {
249
+ directories.push(current);
250
+ current = path2.dirname(current);
251
+ }
252
+ return directories;
253
+ }
254
+ function nearest(start_directory, is_match) {
255
+ return list(start_directory).find((directory) => is_match(directory));
256
+ }
257
+ var ancestor_directories = { list, nearest };
240
258
 
241
259
  // scripts/lib/schemas.ts
242
260
  import { z as z2 } from "zod";
@@ -278,26 +296,589 @@ var WINDOWS_SHIM_SUFFIX = ".cmd";
278
296
  var PACKAGE_JSON = "package.json";
279
297
  function resolve_local_bin(project_root, bin_name) {
280
298
  const shim = process.platform === WINDOWS_PLATFORM ? `${bin_name}${WINDOWS_SHIM_SUFFIX}` : bin_name;
281
- return path2.join(project_root, NODE_MODULES2, BIN_DIR, shim);
299
+ return path3.join(project_root, NODE_MODULES2, BIN_DIR, shim);
282
300
  }
283
301
  function read_bin_entry(manifest_path, package_name, bin_name) {
284
302
  const { bin } = package_bin_schema.parse(JSON.parse(readFileSync2(manifest_path, "utf8")));
285
- if (typeof bin === "string") return bin_name === path2.basename(package_name) ? bin : void 0;
303
+ if (typeof bin === "string") return bin_name === path3.basename(package_name) ? bin : void 0;
286
304
  return bin?.[bin_name];
287
305
  }
288
306
  function resolve_package_bin(base_directory, package_name, bin_name) {
289
307
  try {
290
- const resolve_from = createRequire(path2.join(base_directory, PACKAGE_JSON));
308
+ const resolve_from = createRequire(path3.join(base_directory, PACKAGE_JSON));
291
309
  const manifest_path = resolve_from.resolve(`${package_name}/${PACKAGE_JSON}`);
292
310
  const bin_entry = read_bin_entry(manifest_path, package_name, bin_name);
293
311
  if (bin_entry === void 0) return void 0;
294
- const cli_entry = path2.join(path2.dirname(manifest_path), bin_entry);
312
+ const cli_entry = path3.join(path3.dirname(manifest_path), bin_entry);
295
313
  return existsSync2(cli_entry) ? cli_entry : void 0;
296
314
  } catch {
297
315
  return void 0;
298
316
  }
299
317
  }
300
318
 
319
+ // scripts/gate/core-budget.ts
320
+ import { randomUUID as randomUUID3 } from "node:crypto";
321
+ import { readdirSync as readdirSync2 } from "node:fs";
322
+ import { availableParallelism as availableParallelism2 } from "node:os";
323
+ import path8 from "node:path";
324
+
325
+ // scripts/josh/platform-temporary.ts
326
+ import { accessSync, constants } from "node:fs";
327
+ import { tmpdir } from "node:os";
328
+ var POSIX_TEMP_ROOT = "/tmp";
329
+ var WINDOWS_PLATFORM2 = "win32";
330
+ function is_writable_directory(directory) {
331
+ try {
332
+ accessSync(directory, constants.W_OK);
333
+ return true;
334
+ } catch {
335
+ return false;
336
+ }
337
+ }
338
+ function resolve_temporary_root(platform2, can_write = is_writable_directory) {
339
+ if (platform2 === WINDOWS_PLATFORM2) return tmpdir();
340
+ return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
341
+ }
342
+ var TEMP_ROOT_KEY = "JOSH_TEMP_ROOT";
343
+ function temporary_root(override, platform2) {
344
+ return override === void 0 || override === "" ? resolve_temporary_root(platform2) : override;
345
+ }
346
+ var PLATFORM_TEMP_ROOT = temporary_root(process.env[TEMP_ROOT_KEY], process.platform);
347
+
348
+ // scripts/josh/process-identity.ts
349
+ import { execFileSync, spawnSync } from "node:child_process";
350
+ import { randomUUID } from "node:crypto";
351
+ import { readFileSync as readFileSync3, rmSync } from "node:fs";
352
+ import { createServer } from "node:net";
353
+ import path4 from "node:path";
354
+ var PS_COMMAND = "/bin/ps";
355
+ var FORMAT_FLAG = "-o";
356
+ var START_TIME_FORMAT = "lstart=";
357
+ var PID_FLAG = "-p";
358
+ var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
359
+ var LIVENESS_SIGNAL = 0;
360
+ var LOWEST_REAL_PID = 1;
361
+ var PROC_START_FIELD_INDEX = 19;
362
+ var BEACON_SCHEME = "socket:";
363
+ var BEACON_SUFFIX = ".sock";
364
+ var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
365
+ var BEACON_ID_LENGTH = 36;
366
+ var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
367
+ var WINDOWS_PLATFORM3 = "win32";
368
+ 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));";
369
+ var beacons = /* @__PURE__ */ new Map();
370
+ var exit_cleanup = { is_registered: false };
371
+ function is_live_pid(pid) {
372
+ if (pid < LOWEST_REAL_PID) return false;
373
+ try {
374
+ process.kill(pid, LIVENESS_SIGNAL);
375
+ return true;
376
+ } catch {
377
+ return false;
378
+ }
379
+ }
380
+ function read_proc_start(pid) {
381
+ try {
382
+ const stat = readFileSync3(`/proc/${String(pid)}/stat`, "utf8");
383
+ const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
384
+ const start = fields[PROC_START_FIELD_INDEX];
385
+ return start === void 0 ? void 0 : `proc:${start}`;
386
+ } catch {
387
+ return void 0;
388
+ }
389
+ }
390
+ function read_ps_start(pid) {
391
+ try {
392
+ const printed = execFileSync(
393
+ PS_COMMAND,
394
+ [FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
395
+ {
396
+ encoding: "utf8",
397
+ timeout: PROBE_TIMEOUT_MS,
398
+ stdio: ["ignore", "pipe", "ignore"],
399
+ env: PROBE_ENVIRONMENT
400
+ }
401
+ ).trim();
402
+ return printed.length > 0 ? printed : void 0;
403
+ } catch {
404
+ return void 0;
405
+ }
406
+ }
407
+ var START_PROBES = { read_proc_start, read_ps_start };
408
+ function safe_probe(probe, pid) {
409
+ try {
410
+ return probe(pid);
411
+ } catch {
412
+ return void 0;
413
+ }
414
+ }
415
+ function read_start(pid, probes = START_PROBES) {
416
+ return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
417
+ }
418
+ function close_beacon(token) {
419
+ const server = beacons.get(token);
420
+ if (server === void 0) return;
421
+ beacons.delete(token);
422
+ server.close();
423
+ rmSync(token.slice(BEACON_SCHEME.length), { force: true });
424
+ }
425
+ function close_beacons() {
426
+ for (const token of beacons.keys()) close_beacon(token);
427
+ }
428
+ function ensure_exit_cleanup() {
429
+ if (exit_cleanup.is_registered) return;
430
+ exit_cleanup.is_registered = true;
431
+ process.once("exit", close_beacons);
432
+ }
433
+ function ignore_beacon_error() {
434
+ }
435
+ function bind_beacon(target) {
436
+ return createServer().on("error", ignore_beacon_error).listen(target);
437
+ }
438
+ function try_bind_beacon(bind, target) {
439
+ try {
440
+ const server = bind(target);
441
+ return server.listening ? server : void 0;
442
+ } catch {
443
+ return void 0;
444
+ }
445
+ }
446
+ function open_beacon(bind = bind_beacon) {
447
+ const target = path4.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
448
+ const token = `${BEACON_SCHEME}${target}`;
449
+ const server = try_bind_beacon(bind, target);
450
+ if (server === void 0) return void 0;
451
+ server.unref();
452
+ beacons.set(token, server);
453
+ ensure_exit_cleanup();
454
+ return token;
455
+ }
456
+ function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
457
+ const start = read_start(process.pid, probes);
458
+ if (start !== void 0 || platform2 === WINDOWS_PLATFORM3) return start;
459
+ return open_beacon();
460
+ }
461
+ function is_valid_beacon_name(name) {
462
+ if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
463
+ const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
464
+ return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
465
+ }
466
+ function beacon_target(token) {
467
+ if (!token.startsWith(BEACON_SCHEME)) return void 0;
468
+ const target = token.slice(BEACON_SCHEME.length);
469
+ if (path4.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
470
+ return is_valid_beacon_name(path4.basename(target)) ? target : void 0;
471
+ }
472
+ function is_live_beacon(target) {
473
+ return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
474
+ stdio: "ignore",
475
+ timeout: PROBE_TIMEOUT_MS
476
+ }).status === 0;
477
+ }
478
+ function has_matching_start(pid, recorded_start, read2) {
479
+ const observed = read2(pid);
480
+ return observed === void 0 ? void 0 : observed === recorded_start;
481
+ }
482
+ function matches_recorded_start(pid, recorded_start, read2) {
483
+ const target = beacon_target(recorded_start);
484
+ return target === void 0 ? has_matching_start(pid, recorded_start, read2) : is_live_beacon(target);
485
+ }
486
+ var own_probe = /* @__PURE__ */ new Map();
487
+ function own_start() {
488
+ if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
489
+ return own_probe.get(process.pid);
490
+ }
491
+ function own_fields() {
492
+ const start = own_start();
493
+ return { pid: process.pid, ...start !== void 0 && { process_start: start } };
494
+ }
495
+ function is_same_process(pid, recorded_start, read2 = read_start) {
496
+ if (pid === void 0 || !is_live_pid(pid)) return false;
497
+ if (recorded_start === void 0) return void 0;
498
+ return matches_recorded_start(pid, recorded_start, read2);
499
+ }
500
+ function is_own_process(pid, recorded_start) {
501
+ return pid === process.pid && recorded_start === own_start();
502
+ }
503
+ var process_identity = {
504
+ close_beacon,
505
+ is_live_pid,
506
+ is_own_process,
507
+ is_same_process,
508
+ open_beacon,
509
+ own_fields,
510
+ own_start,
511
+ read_start,
512
+ resolve_own_start
513
+ };
514
+
515
+ // scripts/josh/process-owner.ts
516
+ import { z as z3 } from "zod";
517
+ var process_owner_schema = z3.object({ pid: z3.number(), process_start: z3.string().optional() });
518
+
519
+ // scripts/josh/stamp-file.ts
520
+ import { createHash, randomUUID as randomUUID2 } from "node:crypto";
521
+ import { lstatSync, readFileSync as readFileSync4, renameSync, rmSync as rmSync2, writeFileSync } from "node:fs";
522
+ import path6 from "node:path";
523
+
524
+ // scripts/init/init-paths.ts
525
+ import path5 from "node:path";
526
+ import { fileURLToPath } from "node:url";
527
+ var PACKAGE_DIR = path5.join(path5.dirname(fileURLToPath(import.meta.url)), "..", "..");
528
+ var PROJECT_ROOT = process.cwd();
529
+
530
+ // scripts/josh/stamp-file.ts
531
+ var HASH_ALGORITHM = "sha256";
532
+ var STAMP_SUFFIX = ".json";
533
+ var STAMP_KEY_LENGTH = 16;
534
+ var STAMP_FILE_MODE = 384;
535
+ var STAMP_WRITE_FLAG = "wx";
536
+ var STAMP_CREATE_FLAG = STAMP_WRITE_FLAG;
537
+ var EXISTS_ERROR_CODE = "EEXIST";
538
+ var ACCOUNT_KEY_SEPARATOR = ":";
539
+ function digest(content) {
540
+ return createHash(HASH_ALGORITHM).update(content).digest("hex");
541
+ }
542
+ function account_key() {
543
+ return String(process.getuid?.() ?? "");
544
+ }
545
+ function stamp_path(prefix, root = PACKAGE_DIR, suffix = STAMP_SUFFIX) {
546
+ const key = digest(`${account_key()}${ACCOUNT_KEY_SEPARATOR}${root}`).slice(0, STAMP_KEY_LENGTH);
547
+ return path6.join(PLATFORM_TEMP_ROOT, `${prefix}${key}${suffix}`);
548
+ }
549
+ function write_exclusively(target, content) {
550
+ rmSync2(target, { force: true });
551
+ writeFileSync(target, content, { flag: STAMP_WRITE_FLAG, mode: STAMP_FILE_MODE });
552
+ return target;
553
+ }
554
+ function write_stamp(target, payload) {
555
+ return write_exclusively(target, JSON.stringify(payload));
556
+ }
557
+ function replace_stamp(target, payload) {
558
+ const temporary = `${target}.${String(process.pid)}.${randomUUID2()}`;
559
+ try {
560
+ writeFileSync(temporary, JSON.stringify(payload), {
561
+ flag: STAMP_CREATE_FLAG,
562
+ mode: STAMP_FILE_MODE
563
+ });
564
+ renameSync(temporary, target);
565
+ return target;
566
+ } finally {
567
+ rmSync2(temporary, { force: true });
568
+ }
569
+ }
570
+ function write_text_stamp(target, text) {
571
+ return write_exclusively(target, text);
572
+ }
573
+ function create_stamp(target, payload) {
574
+ try {
575
+ writeFileSync(target, JSON.stringify(payload), {
576
+ flag: STAMP_CREATE_FLAG,
577
+ mode: STAMP_FILE_MODE
578
+ });
579
+ return true;
580
+ } catch (error) {
581
+ if (error.code === EXISTS_ERROR_CODE) return false;
582
+ throw error;
583
+ }
584
+ }
585
+ function remove_stamp(target) {
586
+ rmSync2(target, { force: true });
587
+ }
588
+ function is_own_regular_file(source) {
589
+ const stats = lstatSync(source);
590
+ if (!stats.isFile()) return false;
591
+ const uid = process.getuid?.();
592
+ return uid === void 0 || stats.uid === uid;
593
+ }
594
+ function read_stamp_text(source) {
595
+ try {
596
+ if (!is_own_regular_file(source)) return void 0;
597
+ return readFileSync4(source, "utf8");
598
+ } catch {
599
+ return void 0;
600
+ }
601
+ }
602
+ var stamp_file = {
603
+ create_stamp,
604
+ digest,
605
+ is_own_regular_file,
606
+ read_stamp_text,
607
+ replace_stamp,
608
+ remove_stamp,
609
+ stamp_path,
610
+ write_stamp,
611
+ write_text_stamp
612
+ };
613
+
614
+ // scripts/test/unit-worker-share.ts
615
+ import { readdirSync } from "node:fs";
616
+ import { availableParallelism } from "node:os";
617
+ import path7 from "node:path";
618
+ var RUN_PREFIX = "josh-unit-running-";
619
+ var WORKER_FLAG = "--maxWorkers";
620
+ var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
621
+ var MIN_WORKERS = 1;
622
+ var SOLO_RUNS = 1;
623
+ function marker_path(pid = process.pid) {
624
+ return stamp_file.stamp_path(RUN_PREFIX, String(pid));
625
+ }
626
+ function is_running(marker) {
627
+ return process_identity.is_same_process(marker.pid, marker.process_start) !== false;
628
+ }
629
+ function read_marker(source) {
630
+ const raw = stamp_file.read_stamp_text(source);
631
+ if (raw === void 0) return void 0;
632
+ const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
633
+ return parsed.success ? parsed.data : void 0;
634
+ }
635
+ function marker_files(directory = PLATFORM_TEMP_ROOT) {
636
+ try {
637
+ return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
638
+ } catch {
639
+ return [];
640
+ }
641
+ }
642
+ function sweep_marker(source) {
643
+ try {
644
+ stamp_file.remove_stamp(source);
645
+ } catch {
646
+ }
647
+ }
648
+ function is_marker_live(source) {
649
+ const marker = read_marker(source);
650
+ if (marker === void 0) return false;
651
+ if (is_running(marker)) return true;
652
+ sweep_marker(source);
653
+ return false;
654
+ }
655
+ function live_run_count(directory = PLATFORM_TEMP_ROOT) {
656
+ return marker_files(directory).filter((name) => is_marker_live(path7.join(directory, name))).length;
657
+ }
658
+ var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
659
+ var NESTED_VALUE = "1";
660
+ function is_nested_run() {
661
+ return process.env[NESTED_KEY] === NESTED_VALUE;
662
+ }
663
+ function resolve_unit_workers(available_cores, runs) {
664
+ if (runs <= SOLO_RUNS) return void 0;
665
+ return Math.max(MIN_WORKERS, Math.floor(available_cores / runs));
666
+ }
667
+ function current_share(available_cores = availableParallelism(), live_runs = live_run_count()) {
668
+ const own_run = is_nested_run() ? 0 : SOLO_RUNS;
669
+ return resolve_unit_workers(available_cores, live_runs + own_run);
670
+ }
671
+ function is_worker_flag(argument) {
672
+ return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
673
+ }
674
+ function worker_arguments(vitest_arguments, share) {
675
+ if (share === void 0) return [];
676
+ if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
677
+ return [`${WORKER_FLAG}=${String(share)}`];
678
+ }
679
+ function mark_run_started(target) {
680
+ try {
681
+ stamp_file.write_stamp(target, process_identity.own_fields());
682
+ } catch {
683
+ }
684
+ }
685
+ async function with_run_marker(run2) {
686
+ if (is_nested_run()) return await run2();
687
+ const target = marker_path();
688
+ mark_run_started(target);
689
+ process.env[NESTED_KEY] = NESTED_VALUE;
690
+ try {
691
+ return await run2();
692
+ } finally {
693
+ process.env[NESTED_KEY] = "";
694
+ stamp_file.remove_stamp(target);
695
+ }
696
+ }
697
+ var unit_worker_share = {
698
+ MIN_WORKERS,
699
+ NESTED_KEY,
700
+ NESTED_VALUE,
701
+ RUN_PREFIX,
702
+ SOLO_RUNS,
703
+ current_share,
704
+ is_nested_run,
705
+ live_run_count,
706
+ marker_path,
707
+ read_marker,
708
+ resolve_unit_workers,
709
+ with_run_marker,
710
+ worker_arguments
711
+ };
712
+
713
+ // scripts/gate/core-budget.ts
714
+ import { z as z4 } from "zod";
715
+ var RESERVED_PREFIX = "josh-core-reserved-";
716
+ var RESERVED_SUFFIX = ".json";
717
+ var POLL_INTERVAL_MS = 50;
718
+ var WAIT_CAP_MS = 12e4;
719
+ var MIN_BUDGET = 1;
720
+ var CORE_WEIGHTS = {
721
+ lint: 2,
722
+ type_check: 1,
723
+ spell_check: 1,
724
+ eslint_scan: 1
725
+ };
726
+ var HELD_KEY = "JOSH_CORE_RESERVED";
727
+ var HELD_VALUE = "1";
728
+ var reservation_schema = process_owner_schema.extend({
729
+ weight: z4.number(),
730
+ claimed_at: z4.number()
731
+ });
732
+ function marker_name(key) {
733
+ return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
734
+ }
735
+ function is_running2(reservation) {
736
+ return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
737
+ }
738
+ function read_reservation(source) {
739
+ const raw = stamp_file.read_stamp_text(source);
740
+ if (raw === void 0) return void 0;
741
+ try {
742
+ const parsed = reservation_schema.safeParse(JSON.parse(raw));
743
+ return parsed.success ? parsed.data : void 0;
744
+ } catch {
745
+ return void 0;
746
+ }
747
+ }
748
+ function sweep_marker2(source) {
749
+ try {
750
+ stamp_file.remove_stamp(source);
751
+ } catch {
752
+ }
753
+ }
754
+ function live_reservation(source) {
755
+ const reservation = read_reservation(source);
756
+ if (reservation === void 0) return void 0;
757
+ if (is_running2(reservation)) return reservation;
758
+ sweep_marker2(source);
759
+ return void 0;
760
+ }
761
+ function marker_files2(directory) {
762
+ try {
763
+ return readdirSync2(directory).filter((name) => name.startsWith(RESERVED_PREFIX));
764
+ } catch {
765
+ return [];
766
+ }
767
+ }
768
+ function live_reservations(directory = PLATFORM_TEMP_ROOT) {
769
+ return marker_files2(directory).flatMap((name) => {
770
+ const reservation = live_reservation(path8.join(directory, name));
771
+ return reservation === void 0 ? [] : { key: name, reservation };
772
+ });
773
+ }
774
+ function compare_claim(left, right) {
775
+ const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
776
+ return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
777
+ }
778
+ function admitted_keys(reservations, budget) {
779
+ const admitted = /* @__PURE__ */ new Set();
780
+ let cumulative = 0;
781
+ for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
782
+ cumulative += entry.reservation.weight;
783
+ if (index !== 0 && cumulative > budget) break;
784
+ admitted.add(entry.key);
785
+ }
786
+ return admitted;
787
+ }
788
+ function is_admitted(key, reservations, budget) {
789
+ return admitted_keys(reservations, budget).has(key);
790
+ }
791
+ function admitted_load(reservations, budget) {
792
+ const admitted = admitted_keys(reservations, budget);
793
+ return reservations.filter((entry) => admitted.has(entry.key)).reduce((total, entry) => total + entry.reservation.weight, 0);
794
+ }
795
+ function normalize_budget(budget) {
796
+ return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
797
+ }
798
+ async function default_sleep(ms) {
799
+ await new Promise((resolve) => {
800
+ setTimeout(resolve, ms);
801
+ });
802
+ }
803
+ function write_reservation(target, weight, claimed_at) {
804
+ stamp_file.write_stamp(target, { ...process_identity.own_fields(), weight, claimed_at });
805
+ }
806
+ function resolve_timing(options) {
807
+ return {
808
+ now: options.now ?? Date.now,
809
+ sleep: options.sleep ?? default_sleep,
810
+ poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS
811
+ };
812
+ }
813
+ async function await_admission(context) {
814
+ while (!is_admitted(context.key, live_reservations(context.directory), context.budget)) {
815
+ if (context.now() >= context.deadline) return;
816
+ await context.sleep(context.poll_interval_ms);
817
+ }
818
+ }
819
+ async function reserve(weight, options = {}) {
820
+ const timing = resolve_timing(options);
821
+ const directory = options.directory ?? PLATFORM_TEMP_ROOT;
822
+ const budget = normalize_budget(options.budget ?? availableParallelism2());
823
+ const claimed_at = timing.now();
824
+ const name = marker_name(randomUUID3());
825
+ const target = path8.join(directory, name);
826
+ write_reservation(target, weight, claimed_at);
827
+ await await_admission({
828
+ ...timing,
829
+ key: name,
830
+ directory,
831
+ budget,
832
+ deadline: claimed_at + (options.wait_cap_ms ?? WAIT_CAP_MS)
833
+ });
834
+ return { target };
835
+ }
836
+ function release(handle) {
837
+ sweep_marker2(handle.target);
838
+ }
839
+ async function with_core_reservation(weight, run2, options = {}) {
840
+ const handle = await reserve(weight, options);
841
+ try {
842
+ return await run2();
843
+ } finally {
844
+ release(handle);
845
+ }
846
+ }
847
+ function is_held() {
848
+ return process.env[HELD_KEY] === HELD_VALUE;
849
+ }
850
+ function set_held_mark(value) {
851
+ process.env[HELD_KEY] = value;
852
+ }
853
+ async function with_held_mark(run2) {
854
+ const previous = process.env[HELD_KEY] ?? "";
855
+ set_held_mark(HELD_VALUE);
856
+ try {
857
+ return await run2();
858
+ } finally {
859
+ set_held_mark(previous);
860
+ }
861
+ }
862
+ async function with_command_reservation(weight, run2, options = {}) {
863
+ if (is_held() || unit_worker_share.is_nested_run()) return await run2();
864
+ return await with_core_reservation(weight, async () => await with_held_mark(run2), options);
865
+ }
866
+ var core_budget = {
867
+ CORE_WEIGHTS,
868
+ HELD_KEY,
869
+ HELD_VALUE,
870
+ RESERVED_PREFIX,
871
+ admitted_keys,
872
+ admitted_load,
873
+ is_held,
874
+ live_reservations,
875
+ release,
876
+ reserve,
877
+ with_command_reservation,
878
+ with_core_reservation,
879
+ with_held_mark
880
+ };
881
+
301
882
  // scripts/josh/josh-logic.ts
302
883
  import { execaSync as execaSync2 } from "execa";
303
884
 
@@ -407,6 +988,9 @@ var BACKLOG_COMMANDS = {
407
988
  },
408
989
  "backlog:stalled": {
409
990
  script: "scripts/backlog/backlog-stalled-cli.ts",
991
+ // A stall sends one Telegram warning (joshuafolkken/kit#3357). The `Stop` hook calls the detector
992
+ // directly, so this flag costs only the manual command its in-process dispatch.
993
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
410
994
  description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
411
995
  category: "AI tools",
412
996
  reference: ["", "automation", ["network"]]
@@ -425,7 +1009,8 @@ var DOCUMENT_COMMANDS = {
425
1009
  script: "scripts/document/document-section-cli.ts",
426
1010
  description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
427
1011
  category: "AI tools",
428
- reference: ["<file> <heading>", "automation", ["none"]]
1012
+ reference: ["<file> <heading>", "automation", ["none"]],
1013
+ is_bundled: true
429
1014
  },
430
1015
  "read:set": {
431
1016
  script: "scripts/document/read-set-cli.ts",
@@ -542,6 +1127,10 @@ var ISSUE_COMMANDS = {
542
1127
  var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
543
1128
  var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
544
1129
  var ISSUE_WITH_OPTIONS = "<issue> [options]";
1130
+ var MEASURE_ARGUMENTS = {
1131
+ script: "scripts/lane/lane-measure-cli.ts",
1132
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
1133
+ };
545
1134
  var LANE_COMMANDS = {
546
1135
  "lane:open": {
547
1136
  ...LANE_ARGUMENTS,
@@ -597,11 +1186,27 @@ var LANE_COMMANDS = {
597
1186
  description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
598
1187
  category: "AI tools",
599
1188
  reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
1189
+ },
1190
+ // The lane-limit measurement (joshuafolkken/kit#3355): `.env` is read so `lane:stats` labels the row
1191
+ // with the `JOSH_LANE_LIMIT` a person set there.
1192
+ "lane:sample": {
1193
+ ...MEASURE_ARGUMENTS,
1194
+ description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
1195
+ category: "AI tools",
1196
+ reference: ["[--every <seconds>]", "maintainer", ["files"]],
1197
+ default_script_arguments: ["sample"]
1198
+ },
1199
+ "lane:stats": {
1200
+ ...MEASURE_ARGUMENTS,
1201
+ description: "Print one table row of lane throughput, gate duration and machine load over a period",
1202
+ category: "AI tools",
1203
+ reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
1204
+ default_script_arguments: ["stats"]
600
1205
  }
601
1206
  };
602
1207
 
603
1208
  // scripts/josh/josh-commands-run.ts
604
- var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
1209
+ var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
605
1210
  var RUN_COMMANDS = {
606
1211
  "run:hold": {
607
1212
  script: RUN_HOLD_SCRIPT,
@@ -617,19 +1222,22 @@ var RUN_COMMANDS = {
617
1222
  default_script_arguments: ["--release"]
618
1223
  },
619
1224
  "run:tidy": {
620
- script: "scripts/run/run-tidy-cli.ts",
1225
+ script: "scripts/run/tidy/run-tidy-cli.ts",
621
1226
  description: "Close merged lanes and drop stashes whose issues are all merged",
622
1227
  category: "AI tools",
623
1228
  reference: ["", "automation", ["git", "network", "files"]]
624
1229
  },
625
1230
  "run:carry": {
626
- script: "scripts/run/run-carry-cli.ts",
1231
+ script: "scripts/run/carry/run-carry-cli.ts",
1232
+ // `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
1233
+ // `run:wake` below (joshuafolkken/kit#3357).
1234
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
627
1235
  description: "Carry one invocation\u2019s budget across its own session cuts",
628
1236
  category: "AI tools",
629
1237
  reference: ["<operation> [arguments...]", "automation", ["files"]]
630
1238
  },
631
1239
  "run:wake": {
632
- script: "scripts/run/run-wake-cli.ts",
1240
+ script: "scripts/run/wake/run-wake-cli.ts",
633
1241
  // `.env` rather than the ambient environment:
634
1242
  // the failure warning needs the Telegram credentials, the same
635
1243
  // reasons `notify` and `followup` carry these flags.
@@ -639,7 +1247,7 @@ var RUN_COMMANDS = {
639
1247
  reference: ["[options]", "automation", ["processes", "notifications"]]
640
1248
  },
641
1249
  "run:cut": {
642
- script: "scripts/run/run-cut-cli.ts",
1250
+ script: "scripts/run/cut/run-cut-cli.ts",
643
1251
  description: "Cut a lane child before the gate and resume a fresh process",
644
1252
  category: "AI tools",
645
1253
  reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
@@ -657,7 +1265,7 @@ var RUN_COMMANDS = {
657
1265
  reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
658
1266
  },
659
1267
  "run:progress": {
660
- script: "scripts/run/run-progress-cli.ts",
1268
+ script: "scripts/run/progress/run-progress-cli.ts",
661
1269
  description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
662
1270
  category: "AI tools",
663
1271
  reference: [
@@ -676,7 +1284,9 @@ var RUN_COMMANDS = {
676
1284
  // read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
677
1285
  // `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
678
1286
  "run:entry": {
679
- script: "scripts/run/run-entry-cli.ts",
1287
+ script: "scripts/run/entry/run-entry-cli.ts",
1288
+ // A `busy` hold or an `over` budget sends the stop confirmation (joshuafolkken/kit#3357).
1289
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
680
1290
  description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
681
1291
  category: "AI tools",
682
1292
  reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
@@ -840,13 +1450,13 @@ var AI_COMMANDS = {
840
1450
  reference: ["[<owner/repo>]", "automation", ["none"]]
841
1451
  },
842
1452
  "run:merge": {
843
- script: "scripts/run/run-merge-cli.ts",
1453
+ script: "scripts/run/merge/run-merge-cli.ts",
844
1454
  description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
845
1455
  category: "AI tools",
846
1456
  reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
847
1457
  },
848
1458
  "run:review": {
849
- script: "scripts/run/run-review-cli.ts",
1459
+ script: "scripts/run/review/run-review-cli.ts",
850
1460
  description: "Start the gate in the background and print the /code-review brief in one call so the two overlap (--join to join the gate and check its verdict)",
851
1461
  category: "AI tools",
852
1462
  reference: ["[--join]", "automation", ["processes", "files"]]
@@ -865,7 +1475,7 @@ var AI_COMMANDS = {
865
1475
  // (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
866
1476
  // failed step and names it, so the run reads only the step to fix.
867
1477
  ship: {
868
- script: "scripts/run/run-ship-cli.ts",
1478
+ script: "scripts/run/ship/run-ship-cli.ts",
869
1479
  description: "Ship a change in one call: gate, commit/push/PR, the CI-wait merge and the report bookkeeping, stopping at the first failed step",
870
1480
  category: "AI tools",
871
1481
  reference: [
@@ -875,7 +1485,7 @@ var AI_COMMANDS = {
875
1485
  ]
876
1486
  },
877
1487
  "run:event": {
878
- script: "scripts/run/run-event-cli.ts",
1488
+ script: "scripts/run/event/run-event-cli.ts",
879
1489
  description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
880
1490
  category: "AI tools",
881
1491
  reference: [
@@ -935,6 +1545,169 @@ var CLONE_COMMANDS = {
935
1545
  }
936
1546
  };
937
1547
 
1548
+ // scripts/gate/gate-plan.ts
1549
+ import { availableParallelism as availableParallelism3 } from "node:os";
1550
+
1551
+ // scripts/lib/status-icons.ts
1552
+ var FAIL_ICON = "\u2717";
1553
+ var PASS_ICON = "\u2714";
1554
+ var status_icons = { FAIL_ICON, PASS_ICON };
1555
+
1556
+ // scripts/josh/josh-verdict.ts
1557
+ var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
1558
+ var GATE_SUBJECT = "verification gate";
1559
+ var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
1560
+ var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
1561
+ var PASSED_VERDICT = "passed";
1562
+ var FAILED_VERDICT = "failed";
1563
+ function format_gate_passed(step_count, total) {
1564
+ return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
1565
+ }
1566
+ function format_gate_failed(failed_labels, total) {
1567
+ return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
1568
+ }
1569
+ var GATE_OPENING_PREFIX = "plan: ";
1570
+ var GATE_OPENING_MARK = " checks at once";
1571
+ function is_gate_opening(line) {
1572
+ const trimmed = line.trimStart();
1573
+ return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
1574
+ }
1575
+ function read_verdict(line) {
1576
+ const trimmed = line.trimStart();
1577
+ if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
1578
+ if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
1579
+ return void 0;
1580
+ }
1581
+ var josh_verdict = {
1582
+ PASSED_VERDICT,
1583
+ FAILED_VERDICT,
1584
+ format_gate_passed,
1585
+ format_gate_failed,
1586
+ GATE_OPENING_MARK,
1587
+ GATE_OPENING_PREFIX,
1588
+ is_gate_opening,
1589
+ read_verdict
1590
+ };
1591
+
1592
+ // scripts/gate/gate-plan.ts
1593
+ var LINT_LABEL = "lint";
1594
+ var TYPE_CHECK_LABEL = "check";
1595
+ var UNIT_LABEL = "test:unit";
1596
+ var BEHAVIOR_LABEL = "behavior";
1597
+ var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
1598
+ var STATIC_CHECKS = [
1599
+ { label: LINT_LABEL, target: "lint", reserved_cores: core_budget.CORE_WEIGHTS.lint },
1600
+ {
1601
+ label: TYPE_CHECK_LABEL,
1602
+ target: "check",
1603
+ reserved_cores: core_budget.CORE_WEIGHTS.type_check
1604
+ },
1605
+ { label: "cspell", target: "cspell:dot", reserved_cores: core_budget.CORE_WEIGHTS.spell_check },
1606
+ { label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
1607
+ // **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
1608
+ // program and walks it for about 5s, and it is over well before lint and the type check. A
1609
+ // reservation would only take a place from the four-core CI runner's fan-out and a worker from the
1610
+ // unit suite for the whole gate.
1611
+ { label: "exports", target: "exports:unused", reserved_cores: 0 }
1612
+ ];
1613
+ var GATE_CHECKS = [
1614
+ ...STATIC_CHECKS,
1615
+ { label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
1616
+ ];
1617
+ function select_gate_checks(is_unit_included) {
1618
+ return is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
1619
+ }
1620
+ function has_unit_check(checks) {
1621
+ return checks.some((check) => check.label === UNIT_LABEL);
1622
+ }
1623
+ var RESERVED_CORES = STATIC_CHECKS.reduce(
1624
+ (total, check) => total + check.reserved_cores,
1625
+ 0
1626
+ );
1627
+ var MEASURED_CORES = 11;
1628
+ var MIN_CONCURRENCY = 1;
1629
+ var MIN_SHARED_CORES = 1;
1630
+ function shared_cores(available_cores, concurrent_runs) {
1631
+ const runs = Number.isFinite(concurrent_runs) ? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs) : unit_worker_share.SOLO_RUNS;
1632
+ return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs));
1633
+ }
1634
+ function resolve_concurrency(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS, checks = GATE_CHECKS) {
1635
+ const share = shared_cores(available_cores, concurrent_runs);
1636
+ let admitted = 0;
1637
+ let reserved = 0;
1638
+ for (const check of checks) {
1639
+ reserved += check.reserved_cores;
1640
+ if (reserved > share) break;
1641
+ admitted += 1;
1642
+ }
1643
+ return Math.max(MIN_CONCURRENCY, admitted);
1644
+ }
1645
+ function resolve_unit_worker_cap(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS) {
1646
+ const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs);
1647
+ if (share !== void 0) return share;
1648
+ if (available_cores < MEASURED_CORES) return void 0;
1649
+ return available_cores - RESERVED_CORES;
1650
+ }
1651
+ function solo_unit_weight(available_cores) {
1652
+ return Math.max(0, available_cores - RESERVED_CORES);
1653
+ }
1654
+ function check_weight(check, plan, available_cores) {
1655
+ if (check.label !== UNIT_LABEL) return check.reserved_cores;
1656
+ return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
1657
+ }
1658
+ function direct_unit_weight(available_cores = availableParallelism3(), live_runs = unit_worker_share.live_run_count()) {
1659
+ const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
1660
+ return Math.max(unit_worker_share.MIN_WORKERS, weight);
1661
+ }
1662
+ function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
1663
+ return { checks, concurrency, unit_worker_cap };
1664
+ }
1665
+ function resolve_gate_plan(available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
1666
+ const checks = select_gate_checks(is_unit_included);
1667
+ return {
1668
+ checks,
1669
+ concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
1670
+ unit_worker_cap: is_unit_included ? resolve_unit_worker_cap(available_cores, concurrent_runs) : void 0
1671
+ };
1672
+ }
1673
+ function format_machine(available_cores, concurrent_runs) {
1674
+ const cores = `${String(available_cores)} cores`;
1675
+ if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
1676
+ return `${cores}, ${String(concurrent_runs)} unit runs`;
1677
+ }
1678
+ function format_unit_cap(plan) {
1679
+ if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`;
1680
+ if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
1681
+ return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
1682
+ }
1683
+ function format_gate_plan(plan, available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
1684
+ const cap = format_unit_cap(plan);
1685
+ const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
1686
+ const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
1687
+ const machine = format_machine(available_cores, concurrent_runs);
1688
+ return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
1689
+ }
1690
+ var gate_plan = {
1691
+ GATE_CHECKS,
1692
+ LINT_LABEL,
1693
+ MEASURED_CORES,
1694
+ RESERVED_CORES,
1695
+ STATIC_CHECKS,
1696
+ TYPE_CHECK_LABEL,
1697
+ UNIT_LABEL,
1698
+ WARNING_CHECKER_LABELS,
1699
+ check_weight,
1700
+ direct_unit_weight,
1701
+ format_gate_plan,
1702
+ format_machine,
1703
+ has_unit_check,
1704
+ plan_of,
1705
+ resolve_concurrency,
1706
+ resolve_gate_plan,
1707
+ resolve_unit_worker_cap,
1708
+ select_gate_checks
1709
+ };
1710
+
938
1711
  // scripts/josh/josh-commands-development.ts
939
1712
  var FILE_ARGUMENTS = "[files...]";
940
1713
  var REQUIRED_FILE_ARGUMENTS = "<files...>";
@@ -958,25 +1731,29 @@ var DEV_COMMANDS = {
958
1731
  script: "scripts/lint/lint-parallel.ts",
959
1732
  description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
960
1733
  category: "Development",
961
- reference: ["", "developer", ["processes"]]
1734
+ reference: ["", "developer", ["processes"]],
1735
+ core_weight: core_budget.CORE_WEIGHTS.lint
962
1736
  },
963
1737
  "lint:related": {
964
1738
  script: "scripts/lint/lint-related.ts",
965
1739
  description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
966
1740
  category: "Development",
967
- reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1741
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]],
1742
+ core_weight: core_budget.CORE_WEIGHTS.lint
968
1743
  },
969
1744
  lines: {
970
1745
  script: "scripts/lines/lines-command.ts",
971
1746
  description: "Print a file's code lines against the max-lines limit and the headroom left",
972
1747
  category: "Development",
973
- reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
1748
+ reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
1749
+ core_weight: core_budget.CORE_WEIGHTS.eslint_scan
974
1750
  },
975
1751
  "refactor:scan": {
976
1752
  script: "scripts/refactor/refactor-scan-cli.ts",
977
1753
  description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
978
1754
  category: "Development",
979
- reference: ["", "automation", ["processes"]]
1755
+ reference: ["", "automation", ["processes"]],
1756
+ core_weight: core_budget.CORE_WEIGHTS.eslint_scan
980
1757
  },
981
1758
  bytes: {
982
1759
  script: "scripts/lines/bytes-command.ts",
@@ -1055,7 +1832,8 @@ var DEV_COMMANDS = {
1055
1832
  script: "scripts/lint/cspell-cached.ts",
1056
1833
  description: "Run spell check including dotfiles",
1057
1834
  category: "Development",
1058
- reference: ["", "developer", ["processes"]]
1835
+ reference: ["", "developer", ["processes"]],
1836
+ core_weight: core_budget.CORE_WEIGHTS.spell_check
1059
1837
  },
1060
1838
  behavior: {
1061
1839
  script: "scripts/behavior/behavior-cli.ts",
@@ -1073,13 +1851,15 @@ var DEV_COMMANDS = {
1073
1851
  script: "scripts/test/test-unit-guard.ts",
1074
1852
  description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
1075
1853
  category: "Development",
1076
- reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
1854
+ reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
1855
+ core_weight: gate_plan.direct_unit_weight
1077
1856
  },
1078
1857
  "test:related": {
1079
1858
  script: "scripts/test/test-related.ts",
1080
1859
  description: "Run only the unit tests related to the changed files (full suite on fallback)",
1081
1860
  category: "Development",
1082
- reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1861
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]],
1862
+ core_weight: gate_plan.direct_unit_weight
1083
1863
  },
1084
1864
  "test:declared": {
1085
1865
  script: "scripts/test/test-declared.ts",
@@ -1089,7 +1869,7 @@ var DEV_COMMANDS = {
1089
1869
  },
1090
1870
  "test:red": {
1091
1871
  script: "scripts/test/test-red.ts",
1092
- description: "Run the changed unit tests against the pre-fix tree (merge-base worktree) and report red/green/no-test",
1872
+ description: "Run the changed unit tests against the pre-fix tree (merge-base worktree) and report red/green/no-test/test-only",
1093
1873
  category: "Development",
1094
1874
  reference: ["", "developer", ["git", "processes"]]
1095
1875
  },
@@ -1122,7 +1902,8 @@ var DEV_COMMANDS = {
1122
1902
  script: "scripts/gate/type-check-command.ts",
1123
1903
  description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
1124
1904
  category: "Development",
1125
- reference: ["[arguments...]", "developer", ["processes"]]
1905
+ reference: ["[arguments...]", "developer", ["processes"]],
1906
+ core_weight: core_budget.CORE_WEIGHTS.type_check
1126
1907
  },
1127
1908
  port: {
1128
1909
  script: "scripts/ports/port-command.ts",
@@ -1219,7 +2000,7 @@ var MAINTENANCE_COMMANDS = {
1219
2000
  script: "scripts/overrides/overrides-check.ts",
1220
2001
  description: "Check pnpm overrides for drift",
1221
2002
  category: "Maintenance",
1222
- reference: ["[--save]", "maintainer", ["files"]]
2003
+ reference: ["[--save]", "developer", ["files"]]
1223
2004
  },
1224
2005
  audit: {
1225
2006
  script: "scripts/security/security-audit.ts",
@@ -1247,7 +2028,7 @@ var MAINTENANCE_COMMANDS = {
1247
2028
  ],
1248
2029
  description: "Update pnpm, dependencies, and run security audit",
1249
2030
  category: "Maintenance",
1250
- reference: ["", "maintainer", ["files", "network", "processes"]],
2031
+ reference: ["", "developer", ["files", "network", "processes"]],
1251
2032
  argument_targets: ["latest:corepack", "latest:update", "audit"]
1252
2033
  },
1253
2034
  "latest:scope": {
@@ -1270,13 +2051,13 @@ var MAINTENANCE_COMMANDS = {
1270
2051
  script: "scripts/version/latest-corepack.ts",
1271
2052
  description: "Update pnpm on the current major while preserving the integrity pin",
1272
2053
  category: "Maintenance",
1273
- reference: ["", "maintainer", ["files", "network"]]
2054
+ reference: ["", "developer", ["files", "network"]]
1274
2055
  },
1275
2056
  "latest:update": {
1276
2057
  script: "scripts/version/latest-update.ts",
1277
2058
  description: "Update all dependencies to latest",
1278
2059
  category: "Maintenance",
1279
- reference: ["", "maintainer", ["files", "network"]]
2060
+ reference: ["", "developer", ["files", "network"]]
1280
2061
  }
1281
2062
  };
1282
2063
 
@@ -1599,7 +2380,9 @@ var ALIASES = {
1599
2380
  rtr: "retrospective",
1600
2381
  rvf: "review:findings",
1601
2382
  ruv: "rule:value",
1602
- ev: "eval"
2383
+ ev: "eval",
2384
+ lsm: "lane:sample",
2385
+ lst: "lane:stats"
1603
2386
  };
1604
2387
 
1605
2388
  // scripts/josh/josh-composite-arguments.ts
@@ -1630,15 +2413,23 @@ var composite_arguments = { format_rejection, is_composite_shell, reject_extra_a
1630
2413
 
1631
2414
  // scripts/josh/josh-in-process.ts
1632
2415
  import { realpathSync } from "node:fs";
2416
+ import path9 from "node:path";
1633
2417
  import { pathToFileURL } from "node:url";
1634
2418
  var TYPESCRIPT_EXTENSION = ".ts";
2419
+ var JAVASCRIPT_EXTENSION = ".js";
2420
+ var BUNDLED_COMMAND_DIRECTORY = path9.join("dist", "commands");
1635
2421
  var FAILURE_EXIT_CODE = 1;
1636
2422
  function is_typescript_dispatcher(dispatcher_url) {
1637
2423
  return dispatcher_url.endsWith(TYPESCRIPT_EXTENSION);
1638
2424
  }
1639
- function can_run_in_process(entry, dispatcher_url) {
1640
- if (entry.script === void 0 || entry.tsx_arguments !== void 0) return false;
1641
- return is_typescript_dispatcher(dispatcher_url);
2425
+ function bundled_script_path(package_directory, script) {
2426
+ const name = `${path9.basename(script, TYPESCRIPT_EXTENSION)}${JAVASCRIPT_EXTENSION}`;
2427
+ return path9.join(package_directory, BUNDLED_COMMAND_DIRECTORY, name);
2428
+ }
2429
+ function in_process_target(entry, package_directory, dispatcher_url) {
2430
+ if (entry.script === void 0 || entry.tsx_arguments !== void 0) return void 0;
2431
+ if (is_typescript_dispatcher(dispatcher_url)) return path9.join(package_directory, entry.script);
2432
+ return entry.is_bundled === true ? bundled_script_path(package_directory, entry.script) : void 0;
1642
2433
  }
1643
2434
  function read_exit_code() {
1644
2435
  const code = process.exitCode;
@@ -1662,7 +2453,7 @@ async function run_in_process(script_path, script_arguments) {
1662
2453
  }
1663
2454
  return read_exit_code();
1664
2455
  }
1665
- var josh_in_process = { can_run_in_process, run_in_process };
2456
+ var josh_in_process = { bundled_script_path, in_process_target, run_in_process };
1666
2457
 
1667
2458
  // scripts/josh/kit-only.ts
1668
2459
  function kit_only_notice(cmd) {
@@ -1682,7 +2473,7 @@ var kit_only = {
1682
2473
 
1683
2474
  // scripts/josh/run-github-prerequisite.ts
1684
2475
  import { existsSync as existsSync3 } from "node:fs";
1685
- import path3 from "node:path";
2476
+ import path10 from "node:path";
1686
2477
 
1687
2478
  // scripts/discovery/repo-origin.ts
1688
2479
  var GITHUB_HOST = "github.com";
@@ -1747,15 +2538,15 @@ function origin_section_lines(lines) {
1747
2538
  const end = rest.findIndex((line) => is_section_header(line));
1748
2539
  return end === NOT_FOUND ? rest : rest.slice(0, end);
1749
2540
  }
1750
- function entry_value(line, key) {
2541
+ function url_value(line) {
1751
2542
  const separator = line.indexOf("=");
1752
2543
  if (separator === NOT_FOUND) return void 0;
1753
- if (line.slice(0, separator).trim() !== key) return void 0;
2544
+ if (line.slice(0, separator).trim() !== URL_KEY) return void 0;
1754
2545
  return line.slice(separator + 1).trim();
1755
2546
  }
1756
2547
  function parse_origin_from_config(content) {
1757
2548
  const lines = content.split("\n").map((line) => line.trim());
1758
- return origin_section_lines(lines).map((line) => entry_value(line, URL_KEY)).find((url) => url !== void 0);
2549
+ return origin_section_lines(lines).map((line) => url_value(line)).find((url) => url !== void 0);
1759
2550
  }
1760
2551
  function section_groups(lines) {
1761
2552
  const groups = [];
@@ -1767,7 +2558,7 @@ function section_groups(lines) {
1767
2558
  }
1768
2559
  function parse_remote_urls_from_config(content) {
1769
2560
  const lines = content.split("\n").map((line) => line.trim());
1770
- return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) => entry_value(line, URL_KEY))).filter((url) => url !== void 0);
2561
+ return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) => url_value(line))).filter((url) => url !== void 0);
1771
2562
  }
1772
2563
  function format_identity(identity) {
1773
2564
  return `${identity.owner}${PATH_SEPARATOR2}${identity.repo}`.toLowerCase();
@@ -1793,7 +2584,7 @@ var GITHUB_RUN_COMMANDS = /* @__PURE__ */ new Set([
1793
2584
  ]);
1794
2585
  function explanation(root, command) {
1795
2586
  if (!GITHUB_RUN_COMMANDS.has(command)) return void 0;
1796
- if (!existsSync3(path3.join(root, ".git"))) {
2587
+ if (!existsSync3(path10.join(root, ".git"))) {
1797
2588
  return `${command} requires Git and a GitHub origin. Run git init and add a GitHub origin first.`;
1798
2589
  }
1799
2590
  const url = git_spawn_sync.origin_url(root);
@@ -1810,24 +2601,21 @@ var TSX_PACKAGE = "tsx";
1810
2601
  var PACKAGE_JSON2 = "package.json";
1811
2602
  var UNKNOWN_COMMAND_EXIT_CODE = -1;
1812
2603
  function find_package_directory(start_directory) {
1813
- let current = start_directory;
1814
- while (!existsSync4(path4.join(current, PACKAGE_JSON2))) {
1815
- const parent = path4.dirname(current);
1816
- if (parent === current) return start_directory;
1817
- current = parent;
1818
- }
1819
- return current;
2604
+ return ancestor_directories.nearest(
2605
+ start_directory,
2606
+ (directory) => existsSync4(path11.join(directory, PACKAGE_JSON2))
2607
+ ) ?? start_directory;
1820
2608
  }
1821
- var PACKAGE_DIR = find_package_directory(path4.dirname(fileURLToPath(import.meta.url)));
2609
+ var PACKAGE_DIR2 = find_package_directory(path11.dirname(fileURLToPath2(import.meta.url)));
1822
2610
  function resolve_tsx_executable() {
1823
2611
  const candidates = [
1824
- resolve_local_bin(PACKAGE_DIR, TSX_BIN),
2612
+ resolve_local_bin(PACKAGE_DIR2, TSX_BIN),
1825
2613
  resolve_local_bin(process.cwd(), TSX_BIN)
1826
2614
  ];
1827
2615
  return candidates.find(existsSync4) ?? TSX_BIN;
1828
2616
  }
1829
2617
  function resolve_tsx_cli_entry() {
1830
- for (const base_directory of [PACKAGE_DIR, process.cwd()]) {
2618
+ for (const base_directory of [PACKAGE_DIR2, process.cwd()]) {
1831
2619
  const cli_entry = resolve_package_bin(base_directory, TSX_PACKAGE, TSX_BIN);
1832
2620
  if (cli_entry !== void 0) return cli_entry;
1833
2621
  }
@@ -1841,7 +2629,7 @@ function resolve_tsx_runner() {
1841
2629
  return { executable: resolve_tsx_executable(), leading_arguments: [] };
1842
2630
  }
1843
2631
  function read_package_version() {
1844
- const raw = readFileSync3(path4.join(PACKAGE_DIR, PACKAGE_JSON2), "utf8");
2632
+ const raw = readFileSync5(path11.join(PACKAGE_DIR2, PACKAGE_JSON2), "utf8");
1845
2633
  return package_version_schema.parse(JSON.parse(raw)).version;
1846
2634
  }
1847
2635
  var HEADER = `josh v${read_package_version()} \u2014 Joshua Folkken's dev toolkit`;
@@ -1925,12 +2713,10 @@ function spawn_script_entry(entry, script_path, script_arguments) {
1925
2713
  ]);
1926
2714
  }
1927
2715
  async function run_script_entry(entry, subcommand_arguments) {
1928
- const script_path = path4.join(PACKAGE_DIR, entry.script ?? "");
1929
2716
  const script_arguments = [...entry.default_script_arguments ?? [], ...subcommand_arguments];
1930
- if (josh_in_process.can_run_in_process(entry, import.meta.url)) {
1931
- return await josh_in_process.run_in_process(script_path, script_arguments);
1932
- }
1933
- return spawn_script_entry(entry, script_path, script_arguments);
2717
+ const target = josh_in_process.in_process_target(entry, PACKAGE_DIR2, import.meta.url);
2718
+ if (target !== void 0) return await josh_in_process.run_in_process(target, script_arguments);
2719
+ return spawn_script_entry(entry, path11.join(PACKAGE_DIR2, entry.script ?? ""), script_arguments);
1934
2720
  }
1935
2721
  function github_prerequisite_exit(resolved, is_consumer) {
1936
2722
  if (!is_consumer) return void 0;
@@ -1955,10 +2741,21 @@ function pre_dispatch_exit(resolved, entry, subcommand_arguments, is_consumer) {
1955
2741
  console.error(rejection);
1956
2742
  return USAGE_ERROR_EXIT_CODE;
1957
2743
  }
1958
- async function dispatch_entry(entry, subcommand_arguments) {
2744
+ async function run_entry(entry, subcommand_arguments) {
1959
2745
  if (entry.shell) return run_shell_command(entry.shell, subcommand_arguments);
1960
2746
  return await run_script_entry(entry, subcommand_arguments);
1961
2747
  }
2748
+ function command_weight(entry) {
2749
+ return typeof entry.core_weight === "function" ? entry.core_weight() : entry.core_weight;
2750
+ }
2751
+ async function dispatch_entry(entry, subcommand_arguments) {
2752
+ const weight = command_weight(entry);
2753
+ if (weight === void 0) return await run_entry(entry, subcommand_arguments);
2754
+ return await core_budget.with_command_reservation(
2755
+ weight,
2756
+ async () => await run_entry(entry, subcommand_arguments)
2757
+ );
2758
+ }
1962
2759
  async function run_command(cmd, subcommand_arguments, is_consumer = false) {
1963
2760
  const resolved = resolve_alias(cmd);
1964
2761
  const entry = Object.hasOwn(COMMAND_MAP, resolved) ? COMMAND_MAP[resolved] : void 0;