@joshuafolkken/kit 1.1178.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 (425) 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 +6 -2
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +23 -2
  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 +21 -13
  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 +6 -1
  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 +32 -31
  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-S6X6WYKR.js → chunk-55HHG5PX.js} +1210 -711
  43. package/dist/hooks/{chunk-ZAL3NRGL.js → chunk-5VMKCCC4.js} +25 -10
  44. package/dist/hooks/chunk-5VNDSNG3.js +12 -0
  45. package/dist/hooks/{chunk-32GQTL4F.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-VESKRQOF.js → chunk-F56MFS4B.js} +3 -3
  49. package/dist/hooks/{chunk-UAGLLIGZ.js → chunk-FIVDHQGT.js} +7 -6
  50. package/dist/hooks/{chunk-3V37IID6.js → chunk-JBBMAPC4.js} +23 -14
  51. package/dist/hooks/{chunk-G6KRCKEC.js → chunk-JUDKDCDP.js} +496 -378
  52. package/dist/hooks/{chunk-GDS5N2KB.js → chunk-NV2JRZZO.js} +718 -681
  53. package/dist/hooks/{chunk-VQLLNFNT.js → chunk-RNWHN5BP.js} +3 -3
  54. package/dist/hooks/{chunk-DO6NWWHU.js → chunk-TQNPDZNH.js} +4 -4
  55. package/dist/hooks/{chunk-I4XSL4TT.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 +217 -195
  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 +66 -58
  64. package/dist/josh.js +868 -74
  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 +16 -5
  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 +1 -1
  111. package/scripts/backlog/backlog-pool.ts +57 -11
  112. package/scripts/backlog/backlog-ready.ts +1 -1
  113. package/scripts/backlog/backlog-scope.ts +1 -1
  114. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  115. package/scripts/backlog/backlog-stalled.ts +1 -1
  116. package/scripts/build/build-codex-hooks.ts +3 -1
  117. package/scripts/build/build-commands.ts +66 -0
  118. package/scripts/build/build-hooks.ts +2 -1
  119. package/scripts/build/build-library.ts +12 -3
  120. package/scripts/build/build.ts +70 -0
  121. package/scripts/build/local-bin.ts +3 -13
  122. package/scripts/delegation/investigation-reads.ts +3 -1
  123. package/scripts/discovery/repo-origin.ts +5 -5
  124. package/scripts/doctor/doctor-consumer.ts +2 -2
  125. package/scripts/doctor/doctor-io.ts +2 -3
  126. package/scripts/document/capped-print-part.ts +30 -0
  127. package/scripts/document/capped-print.ts +3 -4
  128. package/scripts/document/document-byte-budget.ts +11 -2
  129. package/scripts/document/document-scan.ts +117 -0
  130. package/scripts/document/document-section.ts +143 -16
  131. package/scripts/document/entry-read-budget.ts +5 -3
  132. package/scripts/document/entry-read-set.ts +10 -89
  133. package/scripts/document/read-set-cost.ts +98 -0
  134. package/scripts/epic/epic-add-body.ts +1 -0
  135. package/scripts/epic/epic-audit-checks.ts +1 -1
  136. package/scripts/epic/epic-audit-rationale.ts +4 -3
  137. package/scripts/epic/epic-bundle-cli.ts +14 -3
  138. package/scripts/epic/epic-bundle-poll.ts +41 -0
  139. package/scripts/epic/epic-busy.ts +1 -1
  140. package/scripts/epic/epic-candidate-confirm.ts +3 -2
  141. package/scripts/epic/epic-classify.ts +1 -1
  142. package/scripts/epic/epic-cli-argv.ts +78 -46
  143. package/scripts/epic/epic-cli-remove.ts +11 -19
  144. package/scripts/epic/epic-cli.ts +74 -73
  145. package/scripts/epic/epic-close-comment.ts +1 -1
  146. package/scripts/epic/epic-close.ts +1 -1
  147. package/scripts/epic/epic-cross-repo.ts +5 -5
  148. package/scripts/epic/epic-graph.ts +1 -1
  149. package/scripts/epic/epic-index.ts +1 -1
  150. package/scripts/epic/epic-issue.ts +2 -6
  151. package/scripts/epic/epic-lane-offer.ts +2 -2
  152. package/scripts/epic/epic-next.ts +29 -42
  153. package/scripts/epic/epic-solo-stale.ts +1 -1
  154. package/scripts/epic/epic-triage.ts +8 -4
  155. package/scripts/epic/epic-validate.ts +1 -1
  156. package/scripts/followup/git-followup-finish.ts +2 -2
  157. package/scripts/followup/git-followup-label.ts +2 -2
  158. package/scripts/followup/git-followup-merged.ts +2 -2
  159. package/scripts/followup/git-pr-followup-checks.ts +142 -0
  160. package/scripts/followup/git-pr-followup.ts +4 -129
  161. package/scripts/gate/core-budget.ts +69 -1
  162. package/scripts/gate/gate-plan.ts +47 -7
  163. package/scripts/gate/gate-skip.ts +38 -7
  164. package/scripts/gate/hook-gate-reuse.ts +12 -10
  165. package/scripts/gate/pre-commit-type-check.ts +4 -1
  166. package/scripts/gate/project-checks.ts +6 -9
  167. package/scripts/gate/type-check-step.ts +2 -3
  168. package/scripts/gate/verification-gate.ts +27 -8
  169. package/scripts/gh/git-gh-api-path.ts +2 -2
  170. package/scripts/gh/git-gh-issue-rest.ts +3 -3
  171. package/scripts/gh/git-gh-issue-write.ts +53 -7
  172. package/scripts/gh/git-gh-pr-read.ts +64 -19
  173. package/scripts/gh/git-gh-pr-rest.ts +1 -1
  174. package/scripts/gh/git-gh-pr.ts +5 -1
  175. package/scripts/gh/git-pr-ai-review.ts +1 -1
  176. package/scripts/gh/git-pr-checks-eval.ts +1 -3
  177. package/scripts/gh/git-pr-checks-parse.ts +1 -1
  178. package/scripts/gh/git-pr-checks-watch.ts +6 -5
  179. package/scripts/gh/git-pr-checks.ts +7 -5
  180. package/scripts/gh/git-pr-coderabbit.ts +1 -1
  181. package/scripts/gh/git-pr-error.ts +1 -3
  182. package/scripts/gh/git-pr.ts +9 -13
  183. package/scripts/gh/github-issue-url.ts +2 -2
  184. package/scripts/git/constants.ts +2 -6
  185. package/scripts/git/git-command.ts +20 -218
  186. package/scripts/git/git-diff-reads.ts +225 -0
  187. package/scripts/git/git-error.ts +4 -12
  188. package/scripts/git/git-pre-push-hook.ts +139 -0
  189. package/scripts/git/git-prompt.ts +2 -6
  190. package/scripts/git/git-spawn-sync.ts +3 -1
  191. package/scripts/git/git-spawn.ts +1 -1
  192. package/scripts/git/git-staging.ts +4 -6
  193. package/scripts/git/git-status.ts +3 -9
  194. package/scripts/hooks/codex-hook-adapter.ts +1 -1
  195. package/scripts/hooks/edited-cspell.ts +2 -4
  196. package/scripts/hooks/format-edited-file.ts +3 -12
  197. package/scripts/hooks/pre-push-unit.ts +31 -9
  198. package/scripts/hooks/reserved-run.ts +2 -2
  199. package/scripts/hooks/run-hook.sh +5 -4
  200. package/scripts/hooks/stop-guard.ts +5 -3
  201. package/scripts/init/init-actions.ts +0 -5
  202. package/scripts/init/init-ai-copy.ts +13 -2
  203. package/scripts/init/init-logic-json-merge.ts +19 -0
  204. package/scripts/init/init-logic-secretlint.ts +7 -7
  205. package/scripts/init/init-logic-workspace.ts +41 -2
  206. package/scripts/init/init-logic.ts +16 -26
  207. package/scripts/init/init.ts +5 -15
  208. package/scripts/init/initial-commit.ts +4 -4
  209. package/scripts/init/kit-development-versions.ts +40 -0
  210. package/scripts/init/kit-setup-state.ts +2 -2
  211. package/scripts/init/start-exec.ts +68 -19
  212. package/scripts/init/start-setup-pr.ts +9 -9
  213. package/scripts/init/start-steps.ts +6 -10
  214. package/scripts/issue/defect-rate-cli.ts +1 -1
  215. package/scripts/issue/git-next-issues.ts +1 -1
  216. package/scripts/issue/issue-auto-ok.ts +1 -1
  217. package/scripts/issue/issue-backlinks-cli.ts +2 -2
  218. package/scripts/issue/issue-backlinks.ts +9 -9
  219. package/scripts/issue/issue-comment-cli.ts +19 -13
  220. package/scripts/issue/issue-file-cli.ts +45 -18
  221. package/scripts/issue/issue-file.ts +24 -1
  222. package/scripts/issue/issue-scout-closed.ts +1 -1
  223. package/scripts/issue/issue-state-cli.ts +30 -74
  224. package/scripts/josh/josh-command-map.ts +2 -0
  225. package/scripts/josh/josh-command-types.ts +11 -0
  226. package/scripts/josh/josh-commands-ai.ts +4 -4
  227. package/scripts/josh/josh-commands-backlog.ts +4 -1
  228. package/scripts/josh/josh-commands-development.ts +10 -0
  229. package/scripts/josh/josh-commands-document.ts +1 -0
  230. package/scripts/josh/josh-commands-lane.ts +22 -0
  231. package/scripts/josh/josh-commands-maintenance.ts +4 -4
  232. package/scripts/josh/josh-commands-run.ts +12 -7
  233. package/scripts/josh/josh-in-process.ts +28 -9
  234. package/scripts/josh/josh-logic.ts +33 -15
  235. package/scripts/josh/process-identity.ts +1 -3
  236. package/scripts/josh/session-language-cli.ts +3 -4
  237. package/scripts/lane/lane-await.ts +5 -1
  238. package/scripts/lane/lane-child-invocation.ts +2 -2
  239. package/scripts/lane/lane-cli.ts +3 -3
  240. package/scripts/lane/lane-dispatch.ts +14 -10
  241. package/scripts/lane/lane-environment.ts +5 -1
  242. package/scripts/lane/lane-handoff.ts +1 -1
  243. package/scripts/lane/lane-install.ts +2 -13
  244. package/scripts/lane/lane-launch-cli.ts +15 -1
  245. package/scripts/lane/lane-ledger.ts +145 -0
  246. package/scripts/lane/lane-leftover.ts +1 -1
  247. package/scripts/lane/lane-load.ts +108 -0
  248. package/scripts/lane/lane-measure-cli.ts +149 -0
  249. package/scripts/lane/lane-occupancy.ts +3 -0
  250. package/scripts/lane/lane-reap.ts +1 -3
  251. package/scripts/lane/lane-relaunch.ts +1 -1
  252. package/scripts/lane/lane-stats.ts +224 -0
  253. package/scripts/lane/lane-vacant.ts +36 -0
  254. package/scripts/lane/openai-lane-ship.ts +2 -2
  255. package/scripts/lane/openai-lane-supervisor-owner.ts +180 -0
  256. package/scripts/lane/openai-lane-supervisor.ts +7 -165
  257. package/scripts/lane/openai-review-broker.ts +2 -4
  258. package/scripts/lib/ancestor-directories.ts +35 -0
  259. package/scripts/lib/animation-helpers.ts +2 -2
  260. package/scripts/lib/buffered-process.ts +3 -7
  261. package/scripts/lib/cli-flags.ts +71 -1
  262. package/scripts/lib/spawn-exit.ts +2 -2
  263. package/scripts/lib/timeouts.ts +35 -2
  264. package/scripts/lines/line-budget.ts +4 -6
  265. package/scripts/notify/telegram-test.ts +6 -0
  266. package/scripts/observations/observation-ledger-line.ts +6 -6
  267. package/scripts/observations/observation-ledger-migrate.ts +55 -4
  268. package/scripts/observations/observation-ledger.ts +26 -7
  269. package/scripts/overrides/lockfile-overrides.ts +1 -1
  270. package/scripts/overrides/overrides-logic.ts +1 -1
  271. package/scripts/propagate/propagate-git.ts +1 -1
  272. package/scripts/propagate/propagate-publish.ts +2 -2
  273. package/scripts/propagate/propagate-steps.ts +20 -15
  274. package/scripts/propagate/propagate.ts +36 -27
  275. package/scripts/refactor/import-graph.ts +18 -1
  276. package/scripts/refactor/refactor-lint.ts +4 -4
  277. package/scripts/repo/repository-labels.ts +2 -2
  278. package/scripts/repo/required-checks-logic.ts +1 -3
  279. package/scripts/review/live-evidence.ts +2 -4
  280. package/scripts/review/review-brief-cli.ts +1 -1
  281. package/scripts/review/review-finding-ledger.ts +1 -1
  282. package/scripts/review/review-findings-cli.ts +1 -3
  283. package/scripts/rules/decision-oracle-batch.ts +128 -0
  284. package/scripts/rules/decision-oracle-tokens.ts +21 -0
  285. package/scripts/rules/decision-oracle.ts +8 -120
  286. package/scripts/rules/delivered-rules.ts +26 -182
  287. package/scripts/rules/direct-filing.ts +1 -1
  288. package/scripts/rules/early-heartbeat.ts +3 -3
  289. package/scripts/rules/git-argv.ts +1 -1
  290. package/scripts/rules/git-force.ts +1 -1
  291. package/scripts/rules/implementation-cut.ts +2 -2
  292. package/scripts/rules/index-guard.ts +1 -1
  293. package/scripts/rules/issue-comments.ts +118 -0
  294. package/scripts/rules/{issue-fold.ts → issue-fold-rule.ts} +2 -2
  295. package/scripts/rules/lane-background.ts +2 -2
  296. package/scripts/rules/lane-park.ts +18 -0
  297. package/scripts/rules/lane-split-park.ts +128 -0
  298. package/scripts/rules/oracle-firing.ts +1 -1
  299. package/scripts/rules/poll-loop.ts +1 -1
  300. package/scripts/rules/pre-gate-cut.ts +1 -1
  301. package/scripts/rules/protected-files.ts +59 -4
  302. package/scripts/rules/{run-tail.ts → run-tail-rule.ts} +2 -2
  303. package/scripts/rules/shell-body-trigger.ts +1 -1
  304. package/scripts/rules/stop-rules.ts +18 -7
  305. package/scripts/rules/test-declared-commit.ts +4 -4
  306. package/scripts/rules/wip-cap.ts +63 -0
  307. package/scripts/run/{run-carry-args.ts → carry/run-carry-args.ts} +37 -13
  308. package/scripts/run/{run-carry-change.ts → carry/run-carry-change.ts} +29 -7
  309. package/scripts/run/{run-carry-cli.ts → carry/run-carry-cli.ts} +4 -6
  310. package/scripts/run/{run-carry.ts → carry/run-carry.ts} +1 -1
  311. package/scripts/run/{run-cut-args.ts → cut/run-cut-args.ts} +1 -1
  312. package/scripts/run/{run-cut-cli.ts → cut/run-cut-cli.ts} +2 -2
  313. package/scripts/run/{run-cut.ts → cut/run-cut.ts} +1 -1
  314. package/scripts/run/{run-entry-cli.ts → entry/run-entry-cli.ts} +11 -11
  315. package/scripts/run/{run-entry.ts → entry/run-entry.ts} +2 -2
  316. package/scripts/run/{run-event-scope.ts → event/run-event-scope.ts} +1 -1
  317. package/scripts/run/{run-event-stream-emit.ts → event/run-event-stream-emit.ts} +1 -1
  318. package/scripts/run/{run-event-stream.ts → event/run-event-stream.ts} +16 -2
  319. package/scripts/run/{run-hold-cli.ts → hold/run-hold-cli.ts} +5 -5
  320. package/scripts/run/{run-merge-cli.ts → merge/run-merge-cli.ts} +10 -5
  321. package/scripts/run/{run-merge-steps.ts → merge/run-merge-steps.ts} +53 -5
  322. package/scripts/run/{run-merge.ts → merge/run-merge.ts} +1 -1
  323. package/scripts/run/{run-progress-cli.ts → progress/run-progress-cli.ts} +1 -1
  324. package/scripts/run/{run-progress-config.ts → progress/run-progress-config.ts} +2 -17
  325. package/scripts/run/{run-progress-read.ts → progress/run-progress-read.ts} +5 -5
  326. package/scripts/run/{run-progress.ts → progress/run-progress.ts} +1 -1
  327. package/scripts/run/{run-review-steps.ts → review/run-review-steps.ts} +2 -3
  328. package/scripts/run/run-ending.ts +2 -2
  329. package/scripts/run/run-halfrun-resume.ts +6 -1
  330. package/scripts/run/run-headless.ts +1 -1
  331. package/scripts/run/run-invocation.ts +85 -84
  332. package/scripts/run/run-liveness.ts +1 -1
  333. package/scripts/run/run-parent-cut-hook.ts +1 -1
  334. package/scripts/run/run-preflight.ts +6 -6
  335. package/scripts/run/run-prep-cli.ts +1 -1
  336. package/scripts/run/run-prrun-resume.ts +1 -1
  337. package/scripts/run/run-report-cli.ts +4 -4
  338. package/scripts/run/run-report.ts +2 -2
  339. package/scripts/run/run-status-cli.ts +1 -1
  340. package/scripts/run/run-step-cli.ts +3 -3
  341. package/scripts/run/run-step.ts +2 -2
  342. package/scripts/run/run-stop-notify.ts +1 -1
  343. package/scripts/run/run-stranded-detect.ts +4 -4
  344. package/scripts/run/run-stranded.ts +2 -2
  345. package/scripts/run/run-watcher-guard-cli.ts +1 -1
  346. package/scripts/run/run-watcher-guard.ts +5 -3
  347. package/scripts/run/run-watcher-hook.ts +1 -1
  348. package/scripts/run/{run-ship-cli.ts → ship/run-ship-cli.ts} +2 -2
  349. package/scripts/run/{run-ship-detach.ts → ship/run-ship-detach.ts} +3 -3
  350. package/scripts/run/ship/run-ship-lock.ts +50 -0
  351. package/scripts/run/{run-ship-preflight.ts → ship/run-ship-preflight.ts} +6 -2
  352. package/scripts/run/{run-ship-probe.ts → ship/run-ship-probe.ts} +2 -2
  353. package/scripts/run/{run-ship-return.ts → ship/run-ship-return.ts} +4 -3
  354. package/scripts/run/{run-ship-review-steps.ts → ship/run-ship-review-steps.ts} +3 -3
  355. package/scripts/run/{run-ship-scoped.ts → ship/run-ship-scoped.ts} +10 -1
  356. package/scripts/run/{run-ship-steps.ts → ship/run-ship-steps.ts} +11 -12
  357. package/scripts/run/ship/run-ship-stop-text.ts +13 -0
  358. package/scripts/run/{run-ship-sync.ts → ship/run-ship-sync.ts} +25 -11
  359. package/scripts/run/{run-tidy-lanes.ts → tidy/run-tidy-lanes.ts} +1 -1
  360. package/scripts/run/{run-wake-cli.ts → wake/run-wake-cli.ts} +23 -8
  361. package/scripts/run/{run-wake-describe.ts → wake/run-wake-describe.ts} +3 -3
  362. package/scripts/run/{run-wake-driver.ts → wake/run-wake-driver.ts} +59 -8
  363. package/scripts/run/{run-wake-handoff.ts → wake/run-wake-handoff.ts} +1 -1
  364. package/scripts/run/{run-wake-loop.ts → wake/run-wake-loop.ts} +8 -2
  365. package/scripts/run/wake/run-wake-restart.ts +58 -0
  366. package/scripts/run/{run-wake-session.ts → wake/run-wake-session.ts} +3 -3
  367. package/scripts/run/{run-wake.ts → wake/run-wake.ts} +1 -1
  368. package/scripts/safe-chain/preinstall-command.ts +20 -21
  369. package/scripts/safe-chain/project-config.ts +19 -15
  370. package/scripts/sync/sync-ai-files.ts +1 -1
  371. package/scripts/sync/sync-configs.ts +2 -1
  372. package/scripts/sync/sync.ts +15 -2
  373. package/scripts/test/unit-worker-share.ts +1 -0
  374. package/scripts/time-runtime/time-background.ts +5 -1
  375. package/scripts/time-runtime/time-instant.ts +3 -1
  376. package/scripts/time-runtime/time-spans.ts +6 -139
  377. package/scripts/time-runtime/time-tool-call.ts +160 -0
  378. package/scripts/version/effective-upstream.ts +2 -20
  379. package/scripts/version/latest-corepack.ts +17 -17
  380. package/scripts/version/latest-regression.ts +1 -1
  381. package/scripts/version/latest-update.ts +4 -4
  382. package/scripts/version/npm-registry.ts +20 -5
  383. package/scripts/version/publishable-range-check.ts +2 -2
  384. package/scripts/version/publishable-range.ts +1 -1
  385. package/scripts/version/release-age.ts +48 -38
  386. package/scripts/version/release-hold.ts +1 -1
  387. package/scripts/version/safe-chain-version-update.ts +40 -0
  388. package/scripts/version/upgrade-shell-command.ts +48 -8
  389. package/scripts/version/version-check-logic.ts +23 -14
  390. package/scripts/version/version-commands.ts +23 -11
  391. package/scripts/version/version-remote.ts +28 -13
  392. package/templates/pnpm-workspace.basic.yaml +4 -0
  393. package/templates/workflows/dependabot-auto-merge.yml +5 -5
  394. package/templates/workflows/github-release.yml +2 -0
  395. package/scripts/build/build-config-merge.ts +0 -27
  396. package/scripts/build/build-managed-marker.ts +0 -27
  397. package/scripts/build/build-self-sync-guard.ts +0 -27
  398. package/scripts/build/build-version.ts +0 -26
  399. package/scripts/version/preinstall-version-update.ts +0 -86
  400. /package/scripts/git/{schemas.ts → git-schemas.ts} +0 -0
  401. /package/scripts/overrides/{schemas.ts → overrides-schemas.ts} +0 -0
  402. /package/scripts/run/{run-carry-conversation.ts → carry/run-carry-conversation.ts} +0 -0
  403. /package/scripts/run/{run-carry-reclaim.ts → carry/run-carry-reclaim.ts} +0 -0
  404. /package/scripts/run/{run-carry-stash.ts → carry/run-carry-stash.ts} +0 -0
  405. /package/scripts/run/{run-carry-streak.ts → carry/run-carry-streak.ts} +0 -0
  406. /package/scripts/run/{run-cut-handoff.ts → cut/run-cut-handoff.ts} +0 -0
  407. /package/scripts/run/{run-cut-report.ts → cut/run-cut-report.ts} +0 -0
  408. /package/scripts/run/{run-entry-stop.ts → entry/run-entry-stop.ts} +0 -0
  409. /package/scripts/run/{run-event-cli.ts → event/run-event-cli.ts} +0 -0
  410. /package/scripts/run/{run-event-follow.ts → event/run-event-follow.ts} +0 -0
  411. /package/scripts/run/{run-event-render.ts → event/run-event-render.ts} +0 -0
  412. /package/scripts/run/{run-event-watch.ts → event/run-event-watch.ts} +0 -0
  413. /package/scripts/run/{run-hold.ts → hold/run-hold.ts} +0 -0
  414. /package/scripts/run/{run-progress-args.ts → progress/run-progress-args.ts} +0 -0
  415. /package/scripts/run/{run-progress-clock.ts → progress/run-progress-clock.ts} +0 -0
  416. /package/scripts/run/{run-review-cli.ts → review/run-review-cli.ts} +0 -0
  417. /package/scripts/run/{run-review.ts → review/run-review.ts} +0 -0
  418. /package/scripts/run/{run-ship-next.ts → ship/run-ship-next.ts} +0 -0
  419. /package/scripts/run/{run-ship-pre-detach.ts → ship/run-ship-pre-detach.ts} +0 -0
  420. /package/scripts/run/{run-ship-review.ts → ship/run-ship-review.ts} +0 -0
  421. /package/scripts/run/{run-ship-stage.ts → ship/run-ship-stage.ts} +0 -0
  422. /package/scripts/run/{run-ship.ts → ship/run-ship.ts} +0 -0
  423. /package/scripts/run/{run-tidy-cli.ts → tidy/run-tidy-cli.ts} +0 -0
  424. /package/scripts/run/{run-tidy-stashes.ts → tidy/run-tidy-stashes.ts} +0 -0
  425. /package/scripts/run/{run-tidy.ts → tidy/run-tidy.ts} +0 -0
@@ -1,6 +1,11 @@
1
1
  import {
2
2
  ENV_FILE_NAME
3
3
  } from "./chunk-RKUAD3I6.js";
4
+ import {
5
+ PLATFORM_TEMP_ROOT,
6
+ PROBE_TIMEOUT_MS,
7
+ stamp_file
8
+ } from "./chunk-ELCN5LCH.js";
4
9
 
5
10
  // scripts/lib/json-value.ts
6
11
  function parse_or_undefined(text) {
@@ -176,6 +181,9 @@ var BACKLOG_COMMANDS = {
176
181
  },
177
182
  "backlog:stalled": {
178
183
  script: "scripts/backlog/backlog-stalled-cli.ts",
184
+ // A stall sends one Telegram warning (joshuafolkken/kit#3357). The `Stop` hook calls the detector
185
+ // directly, so this flag costs only the manual command its in-process dispatch.
186
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
179
187
  description: "Report whether ready backlog work is sitting undispatched with a free lane and no recent dispatch",
180
188
  category: "AI tools",
181
189
  reference: ["", "automation", ["network"]]
@@ -194,7 +202,8 @@ var DOCUMENT_COMMANDS = {
194
202
  script: "scripts/document/document-section-cli.ts",
195
203
  description: 'Print one section of a markdown document, for a `file.md` \u2192 "Heading" reference',
196
204
  category: "AI tools",
197
- reference: ["<file> <heading>", "automation", ["none"]]
205
+ reference: ["<file> <heading>", "automation", ["none"]],
206
+ is_bundled: true
198
207
  },
199
208
  "read:set": {
200
209
  script: "scripts/document/read-set-cli.ts",
@@ -311,6 +320,10 @@ var ISSUE_COMMANDS = {
311
320
  var LANE_SCRIPT = "scripts/lane/lane-cli.ts";
312
321
  var LANE_ARGUMENTS = { script: LANE_SCRIPT, tsx_arguments: OPTIONAL_ENV_FILE_FLAGS };
313
322
  var ISSUE_WITH_OPTIONS = "<issue> [options]";
323
+ var MEASURE_ARGUMENTS = {
324
+ script: "scripts/lane/lane-measure-cli.ts",
325
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS
326
+ };
314
327
  var LANE_COMMANDS = {
315
328
  "lane:open": {
316
329
  ...LANE_ARGUMENTS,
@@ -366,11 +379,27 @@ var LANE_COMMANDS = {
366
379
  description: "Collapse a backlogrun lane-start event into one call: open the lane, pop and re-install on the first, dispatch the child",
367
380
  category: "AI tools",
368
381
  reference: ["<issue> [--stash <message>]", "automation", ["files", "git", "processes"]]
382
+ },
383
+ // The lane-limit measurement (joshuafolkken/kit#3355): `.env` is read so `lane:stats` labels the row
384
+ // with the `JOSH_LANE_LIMIT` a person set there.
385
+ "lane:sample": {
386
+ ...MEASURE_ARGUMENTS,
387
+ description: "Record the machine load (load average, swap, free memory, working lanes) to the lane ledger",
388
+ category: "AI tools",
389
+ reference: ["[--every <seconds>]", "maintainer", ["files"]],
390
+ default_script_arguments: ["sample"]
391
+ },
392
+ "lane:stats": {
393
+ ...MEASURE_ARGUMENTS,
394
+ description: "Print one table row of lane throughput, gate duration and machine load over a period",
395
+ category: "AI tools",
396
+ reference: ["--period <days> [--limit <lane-limit>]", "maintainer", ["none"]],
397
+ default_script_arguments: ["stats"]
369
398
  }
370
399
  };
371
400
 
372
401
  // scripts/josh/josh-commands-run.ts
373
- var RUN_HOLD_SCRIPT = "scripts/run/run-hold-cli.ts";
402
+ var RUN_HOLD_SCRIPT = "scripts/run/hold/run-hold-cli.ts";
374
403
  var RUN_COMMANDS = {
375
404
  "run:hold": {
376
405
  script: RUN_HOLD_SCRIPT,
@@ -386,19 +415,22 @@ var RUN_COMMANDS = {
386
415
  default_script_arguments: ["--release"]
387
416
  },
388
417
  "run:tidy": {
389
- script: "scripts/run/run-tidy-cli.ts",
418
+ script: "scripts/run/tidy/run-tidy-cli.ts",
390
419
  description: "Close merged lanes and drop stashes whose issues are all merged",
391
420
  category: "AI tools",
392
421
  reference: ["", "automation", ["git", "network", "files"]]
393
422
  },
394
423
  "run:carry": {
395
- script: "scripts/run/run-carry-cli.ts",
424
+ script: "scripts/run/carry/run-carry-cli.ts",
425
+ // `--stopped` sends the stop confirmation, so the Telegram credentials come from `.env` as for
426
+ // `run:wake` below (joshuafolkken/kit#3357).
427
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
396
428
  description: "Carry one invocation\u2019s budget across its own session cuts",
397
429
  category: "AI tools",
398
430
  reference: ["<operation> [arguments...]", "automation", ["files"]]
399
431
  },
400
432
  "run:wake": {
401
- script: "scripts/run/run-wake-cli.ts",
433
+ script: "scripts/run/wake/run-wake-cli.ts",
402
434
  // `.env` rather than the ambient environment:
403
435
  // the failure warning needs the Telegram credentials, the same
404
436
  // reasons `notify` and `followup` carry these flags.
@@ -408,7 +440,7 @@ var RUN_COMMANDS = {
408
440
  reference: ["[options]", "automation", ["processes", "notifications"]]
409
441
  },
410
442
  "run:cut": {
411
- script: "scripts/run/run-cut-cli.ts",
443
+ script: "scripts/run/cut/run-cut-cli.ts",
412
444
  description: "Cut a lane child before the gate and resume a fresh process",
413
445
  category: "AI tools",
414
446
  reference: ["[--resume] <issue> [--impl] [--handoff <path>]", "automation", ["files"]]
@@ -426,7 +458,7 @@ var RUN_COMMANDS = {
426
458
  reference: ["<issue> --output <path> [--repo <owner/repo>]", "automation", ["network"]]
427
459
  },
428
460
  "run:progress": {
429
- script: "scripts/run/run-progress-cli.ts",
461
+ script: "scripts/run/progress/run-progress-cli.ts",
430
462
  description: "Report an unattended run\u2019s progress once it has gone quiet for an interval",
431
463
  category: "AI tools",
432
464
  reference: [
@@ -445,7 +477,9 @@ var RUN_COMMANDS = {
445
477
  // read the budget, gather the issue reads and decide the pre-implementation step. `run:hold`,
446
478
  // `cost --cut`, `run:prep` and `run:step` were four round trips re-billing a lane's full context each.
447
479
  "run:entry": {
448
- script: "scripts/run/run-entry-cli.ts",
480
+ script: "scripts/run/entry/run-entry-cli.ts",
481
+ // A `busy` hold or an `over` budget sends the stop confirmation (joshuafolkken/kit#3357).
482
+ tsx_arguments: OPTIONAL_ENV_FILE_FLAGS,
449
483
  description: "Open a run in one call: claim the tree, read the budget, bundle the reads, decide the pre-implementation step",
450
484
  category: "AI tools",
451
485
  reference: ["<issue> [--to <command>]", "automation", ["git", "network", "files"]]
@@ -609,13 +643,13 @@ var AI_COMMANDS = {
609
643
  reference: ["[<owner/repo>]", "automation", ["none"]]
610
644
  },
611
645
  "run:merge": {
612
- script: "scripts/run/run-merge-cli.ts",
646
+ script: "scripts/run/merge/run-merge-cli.ts",
613
647
  description: "Collapse a backlogrun merge event into one call: confirm the child, do the post-merge steps, offer the next child",
614
648
  category: "AI tools",
615
649
  reference: [ISSUE_WITH_OPTIONS2, "automation", ["git", "network"]]
616
650
  },
617
651
  "run:review": {
618
- script: "scripts/run/run-review-cli.ts",
652
+ script: "scripts/run/review/run-review-cli.ts",
619
653
  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)",
620
654
  category: "AI tools",
621
655
  reference: ["[--join]", "automation", ["processes", "files"]]
@@ -634,7 +668,7 @@ var AI_COMMANDS = {
634
668
  // (`run:tail`) were four round trips re-billing the run's full context each. It stops at the first
635
669
  // failed step and names it, so the run reads only the step to fix.
636
670
  ship: {
637
- script: "scripts/run/run-ship-cli.ts",
671
+ script: "scripts/run/ship/run-ship-cli.ts",
638
672
  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",
639
673
  category: "AI tools",
640
674
  reference: [
@@ -644,7 +678,7 @@ var AI_COMMANDS = {
644
678
  ]
645
679
  },
646
680
  "run:event": {
647
- script: "scripts/run/run-event-cli.ts",
681
+ script: "scripts/run/event/run-event-cli.ts",
648
682
  description: "Append to, read or watch the run\u2019s append-only event stream (--append <kind> <text> | --from|--follow <n> | --watch [<n>] | --last)",
649
683
  category: "AI tools",
650
684
  reference: [
@@ -704,6 +738,614 @@ var CLONE_COMMANDS = {
704
738
  }
705
739
  };
706
740
 
741
+ // scripts/gate/core-budget.ts
742
+ import { randomUUID as randomUUID2 } from "node:crypto";
743
+ import { readdirSync as readdirSync2 } from "node:fs";
744
+ import { availableParallelism as availableParallelism2 } from "node:os";
745
+ import path3 from "node:path";
746
+
747
+ // scripts/josh/process-identity.ts
748
+ import { execFileSync, spawnSync } from "node:child_process";
749
+ import { randomUUID } from "node:crypto";
750
+ import { readFileSync, rmSync } from "node:fs";
751
+ import { createServer } from "node:net";
752
+ import path from "node:path";
753
+ var PS_COMMAND = "/bin/ps";
754
+ var FORMAT_FLAG = "-o";
755
+ var START_TIME_FORMAT = "lstart=";
756
+ var PID_FLAG = "-p";
757
+ var PROBE_ENVIRONMENT = { TZ: "UTC", LC_ALL: "C" };
758
+ var LIVENESS_SIGNAL = 0;
759
+ var LOWEST_REAL_PID = 1;
760
+ var PROC_START_FIELD_INDEX = 19;
761
+ var BEACON_SCHEME = "socket:";
762
+ var BEACON_SUFFIX = ".sock";
763
+ var BEACON_PREFIX = `josh-process-identity-${String(process.getuid?.() ?? "")}-`;
764
+ var BEACON_ID_LENGTH = 36;
765
+ var BEACON_ID_PATTERN = /^[\da-f-]+$/u;
766
+ var WINDOWS_PLATFORM = "win32";
767
+ 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));";
768
+ var beacons = /* @__PURE__ */ new Map();
769
+ var exit_cleanup = { is_registered: false };
770
+ function is_live_pid(pid) {
771
+ if (pid < LOWEST_REAL_PID) return false;
772
+ try {
773
+ process.kill(pid, LIVENESS_SIGNAL);
774
+ return true;
775
+ } catch {
776
+ return false;
777
+ }
778
+ }
779
+ function read_proc_start(pid) {
780
+ try {
781
+ const stat = readFileSync(`/proc/${String(pid)}/stat`, "utf8");
782
+ const fields = stat.slice(stat.lastIndexOf(")") + 1).trim().split(/\s+/u);
783
+ const start = fields[PROC_START_FIELD_INDEX];
784
+ return start === void 0 ? void 0 : `proc:${start}`;
785
+ } catch {
786
+ return void 0;
787
+ }
788
+ }
789
+ function read_ps_start(pid) {
790
+ try {
791
+ const printed = execFileSync(
792
+ PS_COMMAND,
793
+ [FORMAT_FLAG, START_TIME_FORMAT, PID_FLAG, String(pid)],
794
+ {
795
+ encoding: "utf8",
796
+ timeout: PROBE_TIMEOUT_MS,
797
+ stdio: ["ignore", "pipe", "ignore"],
798
+ env: PROBE_ENVIRONMENT
799
+ }
800
+ ).trim();
801
+ return printed.length > 0 ? printed : void 0;
802
+ } catch {
803
+ return void 0;
804
+ }
805
+ }
806
+ var START_PROBES = { read_proc_start, read_ps_start };
807
+ function safe_probe(probe, pid) {
808
+ try {
809
+ return probe(pid);
810
+ } catch {
811
+ return void 0;
812
+ }
813
+ }
814
+ function read_start(pid, probes = START_PROBES) {
815
+ return safe_probe(probes.read_proc_start, pid) ?? safe_probe(probes.read_ps_start, pid);
816
+ }
817
+ function close_beacon(token) {
818
+ const server = beacons.get(token);
819
+ if (server === void 0) return;
820
+ beacons.delete(token);
821
+ server.close();
822
+ rmSync(token.slice(BEACON_SCHEME.length), { force: true });
823
+ }
824
+ function close_beacons() {
825
+ for (const token of beacons.keys()) close_beacon(token);
826
+ }
827
+ function ensure_exit_cleanup() {
828
+ if (exit_cleanup.is_registered) return;
829
+ exit_cleanup.is_registered = true;
830
+ process.once("exit", close_beacons);
831
+ }
832
+ function ignore_beacon_error() {
833
+ }
834
+ function bind_beacon(target) {
835
+ return createServer().on("error", ignore_beacon_error).listen(target);
836
+ }
837
+ function try_bind_beacon(bind, target) {
838
+ try {
839
+ const server = bind(target);
840
+ return server.listening ? server : void 0;
841
+ } catch {
842
+ return void 0;
843
+ }
844
+ }
845
+ function open_beacon(bind = bind_beacon) {
846
+ const target = path.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
847
+ const token = `${BEACON_SCHEME}${target}`;
848
+ const server = try_bind_beacon(bind, target);
849
+ if (server === void 0) return void 0;
850
+ server.unref();
851
+ beacons.set(token, server);
852
+ ensure_exit_cleanup();
853
+ return token;
854
+ }
855
+ function resolve_own_start(probes = START_PROBES, platform = process.platform) {
856
+ const start = read_start(process.pid, probes);
857
+ if (start !== void 0 || platform === WINDOWS_PLATFORM) return start;
858
+ return open_beacon();
859
+ }
860
+ function is_valid_beacon_name(name) {
861
+ if (!name.startsWith(BEACON_PREFIX) || !name.endsWith(BEACON_SUFFIX)) return false;
862
+ const id = name.slice(BEACON_PREFIX.length, -BEACON_SUFFIX.length);
863
+ return id.length === BEACON_ID_LENGTH && BEACON_ID_PATTERN.test(id);
864
+ }
865
+ function beacon_target(token) {
866
+ if (!token.startsWith(BEACON_SCHEME)) return void 0;
867
+ const target = token.slice(BEACON_SCHEME.length);
868
+ if (path.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
869
+ return is_valid_beacon_name(path.basename(target)) ? target : void 0;
870
+ }
871
+ function is_live_beacon(target) {
872
+ return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
873
+ stdio: "ignore",
874
+ timeout: PROBE_TIMEOUT_MS
875
+ }).status === 0;
876
+ }
877
+ function has_matching_start(pid, recorded_start, read) {
878
+ const observed = read(pid);
879
+ return observed === void 0 ? void 0 : observed === recorded_start;
880
+ }
881
+ function matches_recorded_start(pid, recorded_start, read) {
882
+ const target = beacon_target(recorded_start);
883
+ return target === void 0 ? has_matching_start(pid, recorded_start, read) : is_live_beacon(target);
884
+ }
885
+ var own_probe = /* @__PURE__ */ new Map();
886
+ function own_start() {
887
+ if (!own_probe.has(process.pid)) own_probe.set(process.pid, resolve_own_start());
888
+ return own_probe.get(process.pid);
889
+ }
890
+ function own_fields() {
891
+ const start = own_start();
892
+ return { pid: process.pid, ...start !== void 0 && { process_start: start } };
893
+ }
894
+ function is_same_process(pid, recorded_start, read = read_start) {
895
+ if (pid === void 0 || !is_live_pid(pid)) return false;
896
+ if (recorded_start === void 0) return void 0;
897
+ return matches_recorded_start(pid, recorded_start, read);
898
+ }
899
+ function is_own_process(pid, recorded_start) {
900
+ return pid === process.pid && recorded_start === own_start();
901
+ }
902
+ var process_identity = {
903
+ close_beacon,
904
+ is_live_pid,
905
+ is_own_process,
906
+ is_same_process,
907
+ open_beacon,
908
+ own_fields,
909
+ own_start,
910
+ read_start,
911
+ resolve_own_start
912
+ };
913
+
914
+ // scripts/josh/process-owner.ts
915
+ import { z as z2 } from "zod";
916
+ var process_owner_schema = z2.object({ pid: z2.number(), process_start: z2.string().optional() });
917
+
918
+ // scripts/test/unit-worker-share.ts
919
+ import { readdirSync } from "node:fs";
920
+ import { availableParallelism } from "node:os";
921
+ import path2 from "node:path";
922
+ var RUN_PREFIX = "josh-unit-running-";
923
+ var WORKER_FLAG = "--maxWorkers";
924
+ var WORKER_FLAGS = [WORKER_FLAG, "--max-workers"];
925
+ var MIN_WORKERS = 1;
926
+ var SOLO_RUNS = 1;
927
+ function marker_path(pid = process.pid) {
928
+ return stamp_file.stamp_path(RUN_PREFIX, String(pid));
929
+ }
930
+ function is_running(marker) {
931
+ return process_identity.is_same_process(marker.pid, marker.process_start) !== false;
932
+ }
933
+ function read_marker(source) {
934
+ const raw = stamp_file.read_stamp_text(source);
935
+ if (raw === void 0) return void 0;
936
+ const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
937
+ return parsed.success ? parsed.data : void 0;
938
+ }
939
+ function marker_files(directory = PLATFORM_TEMP_ROOT) {
940
+ try {
941
+ return readdirSync(directory).filter((name) => name.startsWith(RUN_PREFIX));
942
+ } catch {
943
+ return [];
944
+ }
945
+ }
946
+ function sweep_marker(source) {
947
+ try {
948
+ stamp_file.remove_stamp(source);
949
+ } catch {
950
+ }
951
+ }
952
+ function is_marker_live(source) {
953
+ const marker = read_marker(source);
954
+ if (marker === void 0) return false;
955
+ if (is_running(marker)) return true;
956
+ sweep_marker(source);
957
+ return false;
958
+ }
959
+ function live_run_count(directory = PLATFORM_TEMP_ROOT) {
960
+ return marker_files(directory).filter((name) => is_marker_live(path2.join(directory, name))).length;
961
+ }
962
+ var NESTED_KEY = "JOSH_UNIT_RUN_MARKED";
963
+ var NESTED_VALUE = "1";
964
+ function is_nested_run() {
965
+ return process.env[NESTED_KEY] === NESTED_VALUE;
966
+ }
967
+ function resolve_unit_workers(available_cores, runs2) {
968
+ if (runs2 <= SOLO_RUNS) return void 0;
969
+ return Math.max(MIN_WORKERS, Math.floor(available_cores / runs2));
970
+ }
971
+ function current_share(available_cores = availableParallelism(), live_runs = live_run_count()) {
972
+ const own_run2 = is_nested_run() ? 0 : SOLO_RUNS;
973
+ return resolve_unit_workers(available_cores, live_runs + own_run2);
974
+ }
975
+ function is_worker_flag(argument) {
976
+ return WORKER_FLAGS.some((flag) => argument === flag || argument.startsWith(`${flag}=`));
977
+ }
978
+ function worker_arguments(vitest_arguments, share) {
979
+ if (share === void 0) return [];
980
+ if (vitest_arguments.some((argument) => is_worker_flag(argument))) return [];
981
+ return [`${WORKER_FLAG}=${String(share)}`];
982
+ }
983
+ function mark_run_started(target) {
984
+ try {
985
+ stamp_file.write_stamp(target, process_identity.own_fields());
986
+ } catch {
987
+ }
988
+ }
989
+ async function with_run_marker(run) {
990
+ if (is_nested_run()) return await run();
991
+ const target = marker_path();
992
+ mark_run_started(target);
993
+ process.env[NESTED_KEY] = NESTED_VALUE;
994
+ try {
995
+ return await run();
996
+ } finally {
997
+ process.env[NESTED_KEY] = "";
998
+ stamp_file.remove_stamp(target);
999
+ }
1000
+ }
1001
+ var unit_worker_share = {
1002
+ MIN_WORKERS,
1003
+ NESTED_KEY,
1004
+ NESTED_VALUE,
1005
+ RUN_PREFIX,
1006
+ SOLO_RUNS,
1007
+ current_share,
1008
+ is_nested_run,
1009
+ live_run_count,
1010
+ marker_path,
1011
+ read_marker,
1012
+ resolve_unit_workers,
1013
+ with_run_marker,
1014
+ worker_arguments
1015
+ };
1016
+
1017
+ // scripts/gate/core-budget.ts
1018
+ import { z as z3 } from "zod";
1019
+ var RESERVED_PREFIX = "josh-core-reserved-";
1020
+ var RESERVED_SUFFIX = ".json";
1021
+ var POLL_INTERVAL_MS = 50;
1022
+ var WAIT_CAP_MS = 12e4;
1023
+ var MIN_BUDGET = 1;
1024
+ var CORE_WEIGHTS = {
1025
+ lint: 2,
1026
+ type_check: 1,
1027
+ spell_check: 1,
1028
+ eslint_scan: 1
1029
+ };
1030
+ var HELD_KEY = "JOSH_CORE_RESERVED";
1031
+ var HELD_VALUE = "1";
1032
+ var reservation_schema = process_owner_schema.extend({
1033
+ weight: z3.number(),
1034
+ claimed_at: z3.number()
1035
+ });
1036
+ function marker_name(key) {
1037
+ return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`;
1038
+ }
1039
+ function is_running2(reservation) {
1040
+ return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false;
1041
+ }
1042
+ function read_reservation(source) {
1043
+ const raw = stamp_file.read_stamp_text(source);
1044
+ if (raw === void 0) return void 0;
1045
+ try {
1046
+ const parsed = reservation_schema.safeParse(JSON.parse(raw));
1047
+ return parsed.success ? parsed.data : void 0;
1048
+ } catch {
1049
+ return void 0;
1050
+ }
1051
+ }
1052
+ function sweep_marker2(source) {
1053
+ try {
1054
+ stamp_file.remove_stamp(source);
1055
+ } catch {
1056
+ }
1057
+ }
1058
+ function live_reservation(source) {
1059
+ const reservation = read_reservation(source);
1060
+ if (reservation === void 0) return void 0;
1061
+ if (is_running2(reservation)) return reservation;
1062
+ sweep_marker2(source);
1063
+ return void 0;
1064
+ }
1065
+ function marker_files2(directory) {
1066
+ try {
1067
+ return readdirSync2(directory).filter((name) => name.startsWith(RESERVED_PREFIX));
1068
+ } catch {
1069
+ return [];
1070
+ }
1071
+ }
1072
+ function live_reservations(directory = PLATFORM_TEMP_ROOT) {
1073
+ return marker_files2(directory).flatMap((name) => {
1074
+ const reservation = live_reservation(path3.join(directory, name));
1075
+ return reservation === void 0 ? [] : { key: name, reservation };
1076
+ });
1077
+ }
1078
+ function compare_claim(left, right) {
1079
+ const by_time = left.reservation.claimed_at - right.reservation.claimed_at;
1080
+ return by_time === 0 ? left.key.localeCompare(right.key) : by_time;
1081
+ }
1082
+ function admitted_keys(reservations, budget) {
1083
+ const admitted = /* @__PURE__ */ new Set();
1084
+ let cumulative = 0;
1085
+ for (const [index, entry] of reservations.toSorted(compare_claim).entries()) {
1086
+ cumulative += entry.reservation.weight;
1087
+ if (index !== 0 && cumulative > budget) break;
1088
+ admitted.add(entry.key);
1089
+ }
1090
+ return admitted;
1091
+ }
1092
+ function is_admitted(key, reservations, budget) {
1093
+ return admitted_keys(reservations, budget).has(key);
1094
+ }
1095
+ function admitted_load(reservations, budget) {
1096
+ const admitted = admitted_keys(reservations, budget);
1097
+ return reservations.filter((entry) => admitted.has(entry.key)).reduce((total, entry) => total + entry.reservation.weight, 0);
1098
+ }
1099
+ function normalize_budget(budget) {
1100
+ return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET;
1101
+ }
1102
+ async function default_sleep(ms) {
1103
+ await new Promise((resolve) => {
1104
+ setTimeout(resolve, ms);
1105
+ });
1106
+ }
1107
+ function write_reservation(target, weight, claimed_at) {
1108
+ stamp_file.write_stamp(target, { ...process_identity.own_fields(), weight, claimed_at });
1109
+ }
1110
+ function resolve_timing(options) {
1111
+ return {
1112
+ now: options.now ?? Date.now,
1113
+ sleep: options.sleep ?? default_sleep,
1114
+ poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS
1115
+ };
1116
+ }
1117
+ async function await_admission(context) {
1118
+ while (!is_admitted(context.key, live_reservations(context.directory), context.budget)) {
1119
+ if (context.now() >= context.deadline) return;
1120
+ await context.sleep(context.poll_interval_ms);
1121
+ }
1122
+ }
1123
+ async function reserve(weight, options = {}) {
1124
+ const timing = resolve_timing(options);
1125
+ const directory = options.directory ?? PLATFORM_TEMP_ROOT;
1126
+ const budget = normalize_budget(options.budget ?? availableParallelism2());
1127
+ const claimed_at = timing.now();
1128
+ const name = marker_name(randomUUID2());
1129
+ const target = path3.join(directory, name);
1130
+ write_reservation(target, weight, claimed_at);
1131
+ await await_admission({
1132
+ ...timing,
1133
+ key: name,
1134
+ directory,
1135
+ budget,
1136
+ deadline: claimed_at + (options.wait_cap_ms ?? WAIT_CAP_MS)
1137
+ });
1138
+ return { target };
1139
+ }
1140
+ function release(handle) {
1141
+ sweep_marker2(handle.target);
1142
+ }
1143
+ async function with_core_reservation(weight, run, options = {}) {
1144
+ const handle = await reserve(weight, options);
1145
+ try {
1146
+ return await run();
1147
+ } finally {
1148
+ release(handle);
1149
+ }
1150
+ }
1151
+ function is_held() {
1152
+ return process.env[HELD_KEY] === HELD_VALUE;
1153
+ }
1154
+ function set_held_mark(value) {
1155
+ process.env[HELD_KEY] = value;
1156
+ }
1157
+ async function with_held_mark(run) {
1158
+ const previous = process.env[HELD_KEY] ?? "";
1159
+ set_held_mark(HELD_VALUE);
1160
+ try {
1161
+ return await run();
1162
+ } finally {
1163
+ set_held_mark(previous);
1164
+ }
1165
+ }
1166
+ async function with_command_reservation(weight, run, options = {}) {
1167
+ if (is_held() || unit_worker_share.is_nested_run()) return await run();
1168
+ return await with_core_reservation(weight, async () => await with_held_mark(run), options);
1169
+ }
1170
+ var core_budget = {
1171
+ CORE_WEIGHTS,
1172
+ HELD_KEY,
1173
+ HELD_VALUE,
1174
+ RESERVED_PREFIX,
1175
+ admitted_keys,
1176
+ admitted_load,
1177
+ is_held,
1178
+ live_reservations,
1179
+ release,
1180
+ reserve,
1181
+ with_command_reservation,
1182
+ with_core_reservation,
1183
+ with_held_mark
1184
+ };
1185
+
1186
+ // scripts/gate/gate-plan.ts
1187
+ import { availableParallelism as availableParallelism3 } from "node:os";
1188
+
1189
+ // scripts/lib/status-icons.ts
1190
+ var FAIL_ICON = "\u2717";
1191
+ var PASS_ICON = "\u2714";
1192
+ var status_icons = { FAIL_ICON, PASS_ICON };
1193
+
1194
+ // scripts/josh/josh-verdict.ts
1195
+ var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
1196
+ var GATE_SUBJECT = "verification gate";
1197
+ var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
1198
+ var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
1199
+ var PASSED_VERDICT = "passed";
1200
+ var FAILED_VERDICT = "failed";
1201
+ function format_gate_passed(step_count, total) {
1202
+ return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
1203
+ }
1204
+ function format_gate_failed(failed_labels, total) {
1205
+ return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
1206
+ }
1207
+ var GATE_OPENING_PREFIX = "plan: ";
1208
+ var GATE_OPENING_MARK = " checks at once";
1209
+ function is_gate_opening(line) {
1210
+ const trimmed = line.trimStart();
1211
+ return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
1212
+ }
1213
+ function read_verdict(line) {
1214
+ const trimmed = line.trimStart();
1215
+ if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
1216
+ if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
1217
+ return void 0;
1218
+ }
1219
+ var josh_verdict = {
1220
+ PASSED_VERDICT,
1221
+ FAILED_VERDICT,
1222
+ format_gate_passed,
1223
+ format_gate_failed,
1224
+ GATE_OPENING_MARK,
1225
+ GATE_OPENING_PREFIX,
1226
+ is_gate_opening,
1227
+ read_verdict
1228
+ };
1229
+
1230
+ // scripts/gate/gate-plan.ts
1231
+ var LINT_LABEL = "lint";
1232
+ var TYPE_CHECK_LABEL = "check";
1233
+ var UNIT_LABEL = "test:unit";
1234
+ var BEHAVIOR_LABEL = "behavior";
1235
+ var WARNING_CHECKER_LABELS = [LINT_LABEL, TYPE_CHECK_LABEL];
1236
+ var STATIC_CHECKS = [
1237
+ { label: LINT_LABEL, target: "lint", reserved_cores: core_budget.CORE_WEIGHTS.lint },
1238
+ {
1239
+ label: TYPE_CHECK_LABEL,
1240
+ target: "check",
1241
+ reserved_cores: core_budget.CORE_WEIGHTS.type_check
1242
+ },
1243
+ { label: "cspell", target: "cspell:dot", reserved_cores: core_budget.CORE_WEIGHTS.spell_check },
1244
+ { label: BEHAVIOR_LABEL, target: BEHAVIOR_LABEL, reserved_cores: 0 },
1245
+ // **The unused-member check reserves no core** (joshuafolkken/kit#2987): it builds one TypeScript
1246
+ // program and walks it for about 5s, and it is over well before lint and the type check. A
1247
+ // reservation would only take a place from the four-core CI runner's fan-out and a worker from the
1248
+ // unit suite for the whole gate.
1249
+ { label: "exports", target: "exports:unused", reserved_cores: 0 }
1250
+ ];
1251
+ var GATE_CHECKS = [
1252
+ ...STATIC_CHECKS,
1253
+ { label: UNIT_LABEL, target: UNIT_LABEL, reserved_cores: 0 }
1254
+ ];
1255
+ function select_gate_checks(is_unit_included) {
1256
+ return is_unit_included ? GATE_CHECKS : STATIC_CHECKS;
1257
+ }
1258
+ function has_unit_check(checks) {
1259
+ return checks.some((check) => check.label === UNIT_LABEL);
1260
+ }
1261
+ var RESERVED_CORES = STATIC_CHECKS.reduce(
1262
+ (total, check) => total + check.reserved_cores,
1263
+ 0
1264
+ );
1265
+ var MEASURED_CORES = 11;
1266
+ var MIN_CONCURRENCY = 1;
1267
+ var MIN_SHARED_CORES = 1;
1268
+ function shared_cores(available_cores, concurrent_runs) {
1269
+ const runs2 = Number.isFinite(concurrent_runs) ? Math.max(unit_worker_share.SOLO_RUNS, concurrent_runs) : unit_worker_share.SOLO_RUNS;
1270
+ return Math.max(MIN_SHARED_CORES, Math.floor(available_cores / runs2));
1271
+ }
1272
+ function resolve_concurrency(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS, checks = GATE_CHECKS) {
1273
+ const share = shared_cores(available_cores, concurrent_runs);
1274
+ let admitted = 0;
1275
+ let reserved = 0;
1276
+ for (const check of checks) {
1277
+ reserved += check.reserved_cores;
1278
+ if (reserved > share) break;
1279
+ admitted += 1;
1280
+ }
1281
+ return Math.max(MIN_CONCURRENCY, admitted);
1282
+ }
1283
+ function resolve_unit_worker_cap(available_cores, concurrent_runs = unit_worker_share.SOLO_RUNS) {
1284
+ const share = unit_worker_share.resolve_unit_workers(available_cores, concurrent_runs);
1285
+ if (share !== void 0) return share;
1286
+ if (available_cores < MEASURED_CORES) return void 0;
1287
+ return available_cores - RESERVED_CORES;
1288
+ }
1289
+ function solo_unit_weight(available_cores) {
1290
+ return Math.max(0, available_cores - RESERVED_CORES);
1291
+ }
1292
+ function check_weight(check, plan, available_cores) {
1293
+ if (check.label !== UNIT_LABEL) return check.reserved_cores;
1294
+ return plan.unit_worker_cap ?? solo_unit_weight(available_cores);
1295
+ }
1296
+ function direct_unit_weight(available_cores = availableParallelism3(), live_runs = unit_worker_share.live_run_count()) {
1297
+ const weight = unit_worker_share.current_share(available_cores, live_runs) ?? solo_unit_weight(available_cores);
1298
+ return Math.max(unit_worker_share.MIN_WORKERS, weight);
1299
+ }
1300
+ function plan_of(concurrency, unit_worker_cap, checks = GATE_CHECKS) {
1301
+ return { checks, concurrency, unit_worker_cap };
1302
+ }
1303
+ function resolve_gate_plan(available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS, is_unit_included = true) {
1304
+ const checks = select_gate_checks(is_unit_included);
1305
+ return {
1306
+ checks,
1307
+ concurrency: resolve_concurrency(available_cores, concurrent_runs, checks),
1308
+ unit_worker_cap: is_unit_included ? resolve_unit_worker_cap(available_cores, concurrent_runs) : void 0
1309
+ };
1310
+ }
1311
+ function format_machine(available_cores, concurrent_runs) {
1312
+ const cores = `${String(available_cores)} cores`;
1313
+ if (concurrent_runs <= unit_worker_share.SOLO_RUNS) return cores;
1314
+ return `${cores}, ${String(concurrent_runs)} unit runs`;
1315
+ }
1316
+ function format_unit_cap(plan) {
1317
+ if (!has_unit_check(plan.checks)) return `${UNIT_LABEL} elsewhere`;
1318
+ if (plan.unit_worker_cap === void 0) return `${UNIT_LABEL} unrestricted`;
1319
+ return `${UNIT_LABEL} at ${String(plan.unit_worker_cap)} workers`;
1320
+ }
1321
+ function format_gate_plan(plan, available_cores = availableParallelism3(), concurrent_runs = unit_worker_share.SOLO_RUNS) {
1322
+ const cap = format_unit_cap(plan);
1323
+ const count = `${String(plan.concurrency)} of ${String(plan.checks.length)}`;
1324
+ const width = `${count}${josh_verdict.GATE_OPENING_MARK}`;
1325
+ const machine = format_machine(available_cores, concurrent_runs);
1326
+ return `${josh_verdict.GATE_OPENING_PREFIX}${width}, ${cap} (${machine})`;
1327
+ }
1328
+ var gate_plan = {
1329
+ GATE_CHECKS,
1330
+ LINT_LABEL,
1331
+ MEASURED_CORES,
1332
+ RESERVED_CORES,
1333
+ STATIC_CHECKS,
1334
+ TYPE_CHECK_LABEL,
1335
+ UNIT_LABEL,
1336
+ WARNING_CHECKER_LABELS,
1337
+ check_weight,
1338
+ direct_unit_weight,
1339
+ format_gate_plan,
1340
+ format_machine,
1341
+ has_unit_check,
1342
+ plan_of,
1343
+ resolve_concurrency,
1344
+ resolve_gate_plan,
1345
+ resolve_unit_worker_cap,
1346
+ select_gate_checks
1347
+ };
1348
+
707
1349
  // scripts/josh/josh-commands-development.ts
708
1350
  var FILE_ARGUMENTS = "[files...]";
709
1351
  var REQUIRED_FILE_ARGUMENTS = "<files...>";
@@ -727,25 +1369,29 @@ var DEV_COMMANDS = {
727
1369
  script: "scripts/lint/lint-parallel.ts",
728
1370
  description: "Check code with prettier and eslint (skips a tool a basic project lacks)",
729
1371
  category: "Development",
730
- reference: ["", "developer", ["processes"]]
1372
+ reference: ["", "developer", ["processes"]],
1373
+ core_weight: core_budget.CORE_WEIGHTS.lint
731
1374
  },
732
1375
  "lint:related": {
733
1376
  script: "scripts/lint/lint-related.ts",
734
1377
  description: "Check only the changed files with prettier and eslint (whole tree on fallback)",
735
1378
  category: "Development",
736
- reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1379
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]],
1380
+ core_weight: core_budget.CORE_WEIGHTS.lint
737
1381
  },
738
1382
  lines: {
739
1383
  script: "scripts/lines/lines-command.ts",
740
1384
  description: "Print a file's code lines against the max-lines limit and the headroom left",
741
1385
  category: "Development",
742
- reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]]
1386
+ reference: [REQUIRED_FILE_ARGUMENTS, "developer", ["none"]],
1387
+ core_weight: core_budget.CORE_WEIGHTS.eslint_scan
743
1388
  },
744
1389
  "refactor:scan": {
745
1390
  script: "scripts/refactor/refactor-scan-cli.ts",
746
1391
  description: "List refactoring candidates in the changed scope by category and answer clear/candidates",
747
1392
  category: "Development",
748
- reference: ["", "automation", ["processes"]]
1393
+ reference: ["", "automation", ["processes"]],
1394
+ core_weight: core_budget.CORE_WEIGHTS.eslint_scan
749
1395
  },
750
1396
  bytes: {
751
1397
  script: "scripts/lines/bytes-command.ts",
@@ -824,7 +1470,8 @@ var DEV_COMMANDS = {
824
1470
  script: "scripts/lint/cspell-cached.ts",
825
1471
  description: "Run spell check including dotfiles",
826
1472
  category: "Development",
827
- reference: ["", "developer", ["processes"]]
1473
+ reference: ["", "developer", ["processes"]],
1474
+ core_weight: core_budget.CORE_WEIGHTS.spell_check
828
1475
  },
829
1476
  behavior: {
830
1477
  script: "scripts/behavior/behavior-cli.ts",
@@ -842,13 +1489,15 @@ var DEV_COMMANDS = {
842
1489
  script: "scripts/test/test-unit-guard.ts",
843
1490
  description: "Run unit tests with Vitest (skips when Vitest is absent; fails when it has no tests)",
844
1491
  category: "Development",
845
- reference: [FILTER_ARGUMENTS, "developer", ["processes"]]
1492
+ reference: [FILTER_ARGUMENTS, "developer", ["processes"]],
1493
+ core_weight: gate_plan.direct_unit_weight
846
1494
  },
847
1495
  "test:related": {
848
1496
  script: "scripts/test/test-related.ts",
849
1497
  description: "Run only the unit tests related to the changed files (full suite on fallback)",
850
1498
  category: "Development",
851
- reference: [FILE_ARGUMENTS, "developer", ["processes"]]
1499
+ reference: [FILE_ARGUMENTS, "developer", ["processes"]],
1500
+ core_weight: gate_plan.direct_unit_weight
852
1501
  },
853
1502
  "test:declared": {
854
1503
  script: "scripts/test/test-declared.ts",
@@ -891,7 +1540,8 @@ var DEV_COMMANDS = {
891
1540
  script: "scripts/gate/type-check-command.ts",
892
1541
  description: "Type-check with tsc (skips a basic project with no TypeScript to check)",
893
1542
  category: "Development",
894
- reference: ["[arguments...]", "developer", ["processes"]]
1543
+ reference: ["[arguments...]", "developer", ["processes"]],
1544
+ core_weight: core_budget.CORE_WEIGHTS.type_check
895
1545
  },
896
1546
  port: {
897
1547
  script: "scripts/ports/port-command.ts",
@@ -988,7 +1638,7 @@ var MAINTENANCE_COMMANDS = {
988
1638
  script: "scripts/overrides/overrides-check.ts",
989
1639
  description: "Check pnpm overrides for drift",
990
1640
  category: "Maintenance",
991
- reference: ["[--save]", "maintainer", ["files"]]
1641
+ reference: ["[--save]", "developer", ["files"]]
992
1642
  },
993
1643
  audit: {
994
1644
  script: "scripts/security/security-audit.ts",
@@ -1016,7 +1666,7 @@ var MAINTENANCE_COMMANDS = {
1016
1666
  ],
1017
1667
  description: "Update pnpm, dependencies, and run security audit",
1018
1668
  category: "Maintenance",
1019
- reference: ["", "maintainer", ["files", "network", "processes"]],
1669
+ reference: ["", "developer", ["files", "network", "processes"]],
1020
1670
  argument_targets: ["latest:corepack", "latest:update", "audit"]
1021
1671
  },
1022
1672
  "latest:scope": {
@@ -1039,13 +1689,13 @@ var MAINTENANCE_COMMANDS = {
1039
1689
  script: "scripts/version/latest-corepack.ts",
1040
1690
  description: "Update pnpm on the current major while preserving the integrity pin",
1041
1691
  category: "Maintenance",
1042
- reference: ["", "maintainer", ["files", "network"]]
1692
+ reference: ["", "developer", ["files", "network"]]
1043
1693
  },
1044
1694
  "latest:update": {
1045
1695
  script: "scripts/version/latest-update.ts",
1046
1696
  description: "Update all dependencies to latest",
1047
1697
  category: "Maintenance",
1048
- reference: ["", "maintainer", ["files", "network"]]
1698
+ reference: ["", "developer", ["files", "network"]]
1049
1699
  }
1050
1700
  };
1051
1701
 
@@ -1359,7 +2009,9 @@ var ALIASES = {
1359
2009
  rtr: "retrospective",
1360
2010
  rvf: "review:findings",
1361
2011
  ruv: "rule:value",
1362
- ev: "eval"
2012
+ ev: "eval",
2013
+ lsm: "lane:sample",
2014
+ lst: "lane:stats"
1363
2015
  };
1364
2016
  function canonical_command(name) {
1365
2017
  if (!Object.hasOwn(ALIASES, name)) return name;
@@ -1488,7 +2140,7 @@ var time_shell = {
1488
2140
  // scripts/time-runtime/time-background.ts
1489
2141
  var NO_BACKGROUND = "";
1490
2142
  var NO_FINISH = 0;
1491
- var LAUNCH_PATTERN = /running in background with ID:\s*([\w-]+)/iu;
2143
+ var LAUNCH_PATTERN = /(?:running in background with ID:|moved to the background \(ID:)\s*([\w-]+)/iu;
1492
2144
  var AGENT_LAUNCH_PATTERN = /^Async agent launched[\s\S]*?\bagentId:\s*([\w-]+)/u;
1493
2145
  var FINISH_PATTERN = /^<task-notification>[\s\S]*?<task-id>([\w-]+)<\/task-id>/u;
1494
2146
  var OUTPUT_PATTERN = /tasks\/([\w-]+)\.output/u;
@@ -1581,358 +2233,75 @@ var time_background = {
1581
2233
  unread_phases
1582
2234
  };
1583
2235
 
1584
- // scripts/time-runtime/time-bundle-call.ts
1585
- var { BASH_TOOL: BASH_TOOL2 } = cost_blocks;
1586
- var BUNDLEABLE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Glob", "Grep", "Read", "WebFetch", "WebSearch", "Write"]);
1587
- var LAUNCH_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task"]);
1588
- var PRIOR_REFERENCE_MARKERS = [
1589
- "previous finding",
1590
- "prior finding",
1591
- "earlier finding",
1592
- "previous result",
1593
- "prior result",
1594
- "earlier result",
1595
- "based on the previous",
1596
- "based on the earlier",
1597
- "from the previous agent",
1598
- "from the prior agent",
1599
- "the finding above",
1600
- "as found earlier",
1601
- "as found above",
1602
- "building on the previous"
1603
- ];
1604
- var READ_COMMANDS = /* @__PURE__ */ new Set([
1605
- "awk",
1606
- "basename",
1607
- "cat",
1608
- "comm",
1609
- "cut",
1610
- "diff",
1611
- "dirname",
1612
- "du",
1613
- "echo",
1614
- "file",
1615
- "find",
1616
- "gh",
1617
- "grep",
1618
- "head",
1619
- "jq",
1620
- "ls",
1621
- "nl",
1622
- "printf",
1623
- "pwd",
1624
- "realpath",
1625
- "rg",
1626
- // **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
1627
- // the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
1628
- // same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
1629
- // caught by the target test instead, which is where that ordering actually lives.
1630
- "sed",
1631
- "sort",
1632
- "stat",
1633
- "tail",
1634
- "tree",
1635
- "uniq",
1636
- "wc",
1637
- "which"
1638
- ]);
1639
- var MUTATION_WORDS = /* @__PURE__ */ new Set([
1640
- "--field",
1641
- "--method",
1642
- "--raw-field",
1643
- "-F",
1644
- "-X",
1645
- "-delete",
1646
- "-exec",
1647
- "-f",
1648
- "add",
1649
- "chmod",
1650
- "chown",
1651
- "close",
1652
- "comment",
1653
- "cp",
1654
- "create",
1655
- "dd",
1656
- "delete",
1657
- "edit",
1658
- "git",
1659
- "install",
1660
- "kill",
1661
- "ln",
1662
- "merge",
1663
- "mkdir",
1664
- "mv",
1665
- "node",
1666
- "npm",
1667
- "npx",
1668
- "pkill",
1669
- "pnpm",
1670
- "remove",
1671
- "rm",
1672
- "scp",
1673
- "secret",
1674
- "set",
1675
- "ssh",
1676
- "sudo",
1677
- "tee",
1678
- "touch",
1679
- "truncate",
1680
- "tsx",
1681
- "upload",
1682
- "wget"
1683
- ]);
1684
- var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
1685
- "backlog:budget",
1686
- "backlog:next",
1687
- "cost",
1688
- "delegate",
1689
- "epic:audit",
1690
- "epic:bundle",
1691
- "epic:check",
1692
- "epic:next",
1693
- "issue:read",
1694
- "issue:scout",
1695
- "issue:state",
1696
- "lane:list",
1697
- "latest:scope",
1698
- "release:scope",
1699
- "review:brief",
1700
- "review:round2",
1701
- "run:liveness"
1702
- ]);
1703
- var JOSH_WORD = "josh";
1704
- var JOSH_SCRIPT_SUFFIX = "josh.ts";
1705
- var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
1706
- var WHITESPACE_PATTERN2 = /\s+/u;
1707
- var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
1708
- var TARGET_ARRAY_FIELD = "file_paths";
1709
- var MAX_TARGETS = 8;
1710
- var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
1711
- var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
1712
- var MAX_EXTENSION = 5;
1713
- var AFTER_DOT = 1;
1714
- var FIRST_INDEX = 0;
1715
- var CURRENT_DIRECTORY = "./";
1716
- var LAST_CHARACTER = -1;
1717
- var FLAG_PREFIX2 = "-";
1718
- var PATH_SEPARATOR = "/";
1719
- var MIN_TARGET_LENGTH = 3;
1720
- var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
1721
- var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
1722
- var REDIRECTION = ">";
1723
- var IN_PLACE_COMMAND = "sed";
1724
- var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
1725
- function not_bundleable() {
1726
- return {
1727
- is_bundleable: false,
1728
- targets: [],
1729
- is_writing: false,
1730
- may_write: false,
1731
- has_prior_reference: false
1732
- };
1733
- }
1734
- function is_launch_tool(name) {
1735
- return LAUNCH_TOOLS.has(name);
1736
- }
1737
- function words_of(command) {
1738
- return command.split(WORD_PATTERN).filter((word) => word !== "");
1739
- }
1740
- function has_mutation(command) {
1741
- return words_of(command).some((word) => MUTATION_WORDS.has(word));
1742
- }
1743
- function josh_subcommand(command) {
1744
- const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
1745
- const josh_index = tokens.findIndex(
1746
- (token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
1747
- );
1748
- return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
1749
- }
1750
- function is_read_josh(command) {
1751
- if (COMMAND_CHAIN.test(command)) return false;
1752
- const subcommand = josh_subcommand(command);
1753
- if (subcommand === void 0) return false;
1754
- return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
1755
- }
1756
- function may_write_command(command) {
1757
- if (command.includes(REDIRECTION)) return true;
1758
- return words_of(command).some((word) => WRITING_WORDS.has(word));
1759
- }
1760
- function write_segment(command) {
1761
- return time_shell.command_segment(time_shell.unquoted(command));
1762
- }
1763
- function is_in_place_sed(segment) {
1764
- if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
1765
- return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
1766
- }
1767
- function normalize(word) {
1768
- const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
1769
- return head.endsWith(PATH_SEPARATOR) ? head.slice(0, LAST_CHARACTER) : head;
1770
- }
1771
- function has_extension(word) {
1772
- const dot = word.lastIndexOf(".");
1773
- if (dot <= FIRST_INDEX) return false;
1774
- const suffix = word.slice(dot + AFTER_DOT);
1775
- return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
1776
- }
1777
- function is_target(word) {
1778
- if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
1779
- return word.includes(PATH_SEPARATOR) || has_extension(word);
1780
- }
1781
- function targets_in(text) {
1782
- return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
1783
- }
1784
- function field_text(input, field) {
1785
- if (!json_value.is_record(input)) return "";
1786
- const value = input[field];
1787
- return typeof value === "string" ? value : "";
1788
- }
1789
- function field_targets(input) {
1790
- if (!json_value.is_record(input)) return [];
1791
- const value = input[TARGET_ARRAY_FIELD];
1792
- return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
1793
- }
1794
- function tool_targets(input) {
1795
- const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
1796
- const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
1797
- return [...new Set(targets)].filter((target) => target !== "");
1798
- }
1799
- function prompt_references_prior(input) {
1800
- const prompt = field_text(input, "prompt").toLowerCase();
1801
- return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
1802
- }
1803
- function tool_facts(name, input) {
1804
- const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
1805
- const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
1806
- if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
1807
- return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
1808
- }
1809
- function bash_facts(command) {
1810
- const writes = {
1811
- is_writing: is_in_place_sed(write_segment(command)),
1812
- may_write: may_write_command(command)
1813
- };
1814
- if (is_read_josh(command)) {
1815
- return {
1816
- is_bundleable: true,
1817
- targets: targets_in(time_shell.unquoted(command)),
1818
- ...writes,
1819
- has_prior_reference: false
1820
- };
1821
- }
1822
- if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
1823
- return { ...not_bundleable(), ...writes };
1824
- }
1825
- return {
1826
- is_bundleable: true,
1827
- targets: targets_in(time_shell.unquoted(command)),
1828
- ...writes,
1829
- has_prior_reference: false
1830
- };
1831
- }
1832
- function call_facts(name, input) {
1833
- if (name !== BASH_TOOL2) return tool_facts(name, input);
1834
- return bash_facts(time_shell.bash_command(input));
1835
- }
1836
- var time_bundle_call = {
1837
- MAX_TARGETS,
1838
- not_bundleable,
1839
- bash_facts,
1840
- call_facts,
1841
- tool_facts,
1842
- // Exported for `time-agent-bundles.ts` (joshuafolkken/kit#1854), which asks the launch question of a
1843
- // span's `label` — the tool name for a non-Bash call — so the set lives in one place.
1844
- is_launch_tool,
1845
- // Exported for `time-writes.ts` (joshuafolkken/kit#1472), which asks what a call *wrote* rather
1846
- // than what it named. The extraction is the same one either way — a second copy of it would let a
1847
- // path be recognized as a target when read and missed when written.
1848
- targets_in,
1849
- tool_targets,
1850
- // Exported for the batching guard's own word scan (joshuafolkken/kit#1390), so the two scanners
1851
- // cannot come to disagree about where one word of a shell line ends and the next begins.
1852
- // Exported for the read-fold notice (joshuafolkken/kit#2311), which offers `read:files <path>` only
1853
- // over file-shaped targets — a bare directory like `scripts/` is a target here but not something
1854
- // `read:files` can read, so the notice reuses this test rather than keep a second copy that could
1855
- // drift from what counts as a file path.
1856
- has_extension,
1857
- // Exported for `time-writes.ts` (joshuafolkken/kit#1509), which needs the same two answers to say
1858
- // *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
1859
- // once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
1860
- write_segment,
1861
- is_in_place_sed,
1862
- // Exported for the drift test in `time-bundle-call.test.ts` (joshuafolkken/kit#1875), which pins that
1863
- // every name here is a real `josh` command and none of them writes.
1864
- READ_JOSH_SUBCOMMANDS
1865
- };
1866
-
1867
- // scripts/git/schemas.ts
1868
- import { z as z2 } from "zod";
1869
- var package_name_schema = z2.object({ name: z2.string().min(1) });
1870
- var rollup_item_schema = z2.looseObject({
2236
+ // scripts/git/git-schemas.ts
2237
+ import { z as z4 } from "zod";
2238
+ var package_name_schema = z4.object({ name: z4.string().min(1) });
2239
+ var rollup_item_schema = z4.looseObject({
1871
2240
  // eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
1872
- __typename: z2.string().optional(),
1873
- state: z2.string().optional(),
1874
- status: z2.string().optional(),
1875
- conclusion: z2.string().optional(),
1876
- name: z2.string().optional(),
1877
- context: z2.string().optional()
2241
+ __typename: z4.string().optional(),
2242
+ state: z4.string().optional(),
2243
+ status: z4.string().optional(),
2244
+ conclusion: z4.string().optional(),
2245
+ name: z4.string().optional(),
2246
+ context: z4.string().optional()
1878
2247
  });
1879
- var pr_raw_schema = z2.object({
1880
- statusCheckRollup: z2.array(rollup_item_schema).optional(),
1881
- mergeStateStatus: z2.string().optional(),
1882
- reviewDecision: z2.string().optional()
2248
+ var pr_raw_schema = z4.object({
2249
+ statusCheckRollup: z4.array(rollup_item_schema).optional(),
2250
+ mergeStateStatus: z4.string().optional(),
2251
+ reviewDecision: z4.string().optional()
1883
2252
  });
1884
- var pull_comment_schema = z2.object({
1885
- body: z2.string().optional(),
1886
- html_url: z2.string().optional(),
1887
- user: z2.object({ login: z2.string().optional() }).optional()
2253
+ var pull_comment_schema = z4.object({
2254
+ body: z4.string().optional(),
2255
+ html_url: z4.string().optional(),
2256
+ user: z4.object({ login: z4.string().optional() }).optional()
1888
2257
  });
1889
- var ai_review_pull_comment_schema = z2.object({
1890
- body: z2.string().optional(),
1891
- url: z2.string().optional(),
1892
- author: z2.object({ login: z2.string().optional() }).optional()
2258
+ var ai_review_pull_comment_schema = z4.object({
2259
+ body: z4.string().optional(),
2260
+ url: z4.string().optional(),
2261
+ author: z4.object({ login: z4.string().optional() }).optional()
1893
2262
  });
1894
- var pr_info_schema = z2.object({
1895
- mergeable: z2.union([z2.boolean(), z2.string()]).nullable().optional(),
1896
- mergeStateStatus: z2.string().nullable().optional(),
1897
- state: z2.string().optional()
2263
+ var pr_info_schema = z4.object({
2264
+ mergeable: z4.union([z4.boolean(), z4.string()]).nullable().optional(),
2265
+ mergeStateStatus: z4.string().nullable().optional(),
2266
+ state: z4.string().optional()
1898
2267
  });
1899
- var epic_issue_schema = z2.object({
1900
- number: z2.number(),
1901
- body: z2.string().optional()
2268
+ var epic_issue_schema = z4.object({
2269
+ number: z4.number(),
2270
+ body: z4.string().optional()
1902
2271
  });
1903
- var blocking_issue_schema = z2.object({
1904
- number: z2.number(),
1905
- state: z2.string().optional(),
1906
- repository_url: z2.string().optional()
2272
+ var blocking_issue_schema = z4.object({
2273
+ number: z4.number(),
2274
+ state: z4.string().optional(),
2275
+ repository_url: z4.string().optional()
1907
2276
  });
1908
- var blocked_by_schema = z2.object({
1909
- nodes: z2.array(blocking_issue_schema).default([]),
1910
- totalCount: z2.number().optional()
2277
+ var blocked_by_schema = z4.object({
2278
+ nodes: z4.array(blocking_issue_schema).default([]),
2279
+ totalCount: z4.number().optional()
1911
2280
  }).optional();
1912
- var epic_child_schema = z2.object({
1913
- state: z2.string().optional(),
2281
+ var epic_child_schema = z4.object({
2282
+ state: z4.string().optional(),
1914
2283
  blockedBy: blocked_by_schema
1915
2284
  });
1916
- var rest_comment_schema = z2.looseObject({
1917
- body: z2.string().nullish(),
1918
- html_url: z2.string().optional(),
1919
- user: z2.looseObject({ login: z2.string().optional() }).nullish()
2285
+ var rest_comment_schema = z4.looseObject({
2286
+ body: z4.string().nullish(),
2287
+ html_url: z4.string().optional(),
2288
+ user: z4.looseObject({ login: z4.string().optional() }).nullish()
1920
2289
  });
1921
- var issue_label_schema = z2.object({ name: z2.string() });
1922
- var epic_subject_schema = z2.object({
1923
- number: z2.number(),
1924
- state: z2.string().optional(),
1925
- labels: z2.array(issue_label_schema).optional(),
1926
- body: z2.string().optional()
2290
+ var issue_label_schema = z4.object({ name: z4.string() });
2291
+ var epic_subject_schema = z4.object({
2292
+ number: z4.number(),
2293
+ state: z4.string().optional(),
2294
+ labels: z4.array(issue_label_schema).optional(),
2295
+ body: z4.string().optional()
1927
2296
  });
1928
- var open_issue_schema = z2.object({
1929
- number: z2.number(),
1930
- title: z2.string(),
1931
- labels: z2.array(issue_label_schema).optional(),
1932
- createdAt: z2.string(),
2297
+ var open_issue_schema = z4.object({
2298
+ number: z4.number(),
2299
+ title: z4.string(),
2300
+ labels: z4.array(issue_label_schema).optional(),
2301
+ createdAt: z4.string(),
1933
2302
  blockedBy: blocked_by_schema,
1934
2303
  // Present only on the pickup listing, which reads it for the restructures each issue declares.
1935
- body: z2.string().optional()
2304
+ body: z4.string().optional()
1936
2305
  });
1937
2306
 
1938
2307
  // scripts/gh/git-pr-checks-parse.ts
@@ -2098,9 +2467,7 @@ function evaluate_pr_state(snapshot) {
2098
2467
  merge_state_status: snapshot.merge_state_status
2099
2468
  });
2100
2469
  if (failure !== void 0) return failure;
2101
- if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) {
2102
- return "success";
2103
- }
2470
+ if (is_mergeable_state(snapshot) && is_every_required_passing(statuses)) return "success";
2104
2471
  return "pending";
2105
2472
  }
2106
2473
  function is_review_decision_decisive(snapshot) {
@@ -2254,11 +2621,368 @@ function to_stage(body) {
2254
2621
  if (name === "" || !is_duration(digits)) return void 0;
2255
2622
  return { name, duration_ms: Number(digits) * MS_PER_SECOND2 };
2256
2623
  }
2257
- function read_stages(text) {
2258
- if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
2259
- return text.split(LINE_SEPARATOR).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
2624
+ function read_stages(text) {
2625
+ if (!text.includes(git_followup_stages.STAGE_LINE_PREFIX)) return NO_STAGES;
2626
+ return text.split(LINE_SEPARATOR).map((line) => stage_body(line)).filter((body) => body !== void 0).map((body) => to_stage(body)).filter((stage) => stage !== void 0);
2627
+ }
2628
+ var time_followup_stage = { NO_STAGES, read_stages };
2629
+
2630
+ // scripts/time-runtime/time-reported-failure.ts
2631
+ import { z as z5 } from "zod";
2632
+ var TEXT_BLOCK_SCHEMA = z5.object({ text: z5.string().nullish() });
2633
+ var CONTENT_SCHEMA = z5.union([z5.string(), z5.array(z5.unknown())]);
2634
+ var LINE_SEPARATOR2 = "\n";
2635
+ function block_text(block) {
2636
+ const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
2637
+ return parsed.success ? parsed.data.text ?? "" : "";
2638
+ }
2639
+ function result_text2(content) {
2640
+ const parsed = CONTENT_SCHEMA.safeParse(content);
2641
+ if (!parsed.success) return "";
2642
+ if (typeof parsed.data === "string") return parsed.data;
2643
+ return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
2644
+ }
2645
+ function is_failure_line(line) {
2646
+ return line.trimStart().startsWith(status_icons.FAIL_ICON);
2647
+ }
2648
+ function is_failed_verdict(line) {
2649
+ return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
2650
+ }
2651
+ function is_passed_verdict(line) {
2652
+ return josh_verdict.read_verdict(line) === josh_verdict.PASSED_VERDICT;
2653
+ }
2654
+ function new_scan() {
2655
+ return {
2656
+ did_find: false,
2657
+ has_failure_before_region: false,
2658
+ has_failure_in_region: false,
2659
+ is_region_open: false
2660
+ };
2661
+ }
2662
+ function close_region(scan) {
2663
+ scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
2664
+ scan.has_failure_before_region = false;
2665
+ scan.has_failure_in_region = false;
2666
+ scan.is_region_open = false;
2667
+ }
2668
+ function note_failure(scan) {
2669
+ if (scan.is_region_open) {
2670
+ scan.has_failure_in_region = true;
2671
+ return;
2672
+ }
2673
+ scan.has_failure_before_region = true;
2674
+ }
2675
+ function scan_line(scan, line) {
2676
+ if (is_passed_verdict(line)) {
2677
+ close_region(scan);
2678
+ return;
2679
+ }
2680
+ if (is_failure_line(line)) {
2681
+ note_failure(scan);
2682
+ return;
2683
+ }
2684
+ if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
2685
+ }
2686
+ function scan_body(lines) {
2687
+ const scan = new_scan();
2688
+ for (const line of lines) scan_line(scan, line);
2689
+ return scan;
2690
+ }
2691
+ function did_scan_find(scan) {
2692
+ return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
2693
+ }
2694
+ function has_failure_line(content) {
2695
+ const lines = result_text2(content).split(LINE_SEPARATOR2);
2696
+ if (lines.some((line) => is_failed_verdict(line))) return true;
2697
+ return did_scan_find(scan_body(lines));
2698
+ }
2699
+ function is_reported_failure(josh_command, did_print_failure) {
2700
+ return josh_command !== "" && did_print_failure;
2701
+ }
2702
+ var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
2703
+
2704
+ // scripts/time-runtime/time-bundle-call.ts
2705
+ var { BASH_TOOL: BASH_TOOL2 } = cost_blocks;
2706
+ var BUNDLEABLE_TOOLS = /* @__PURE__ */ new Set(["Edit", "Glob", "Grep", "Read", "WebFetch", "WebSearch", "Write"]);
2707
+ var LAUNCH_TOOLS = /* @__PURE__ */ new Set(["Agent", "Task"]);
2708
+ var PRIOR_REFERENCE_MARKERS = [
2709
+ "previous finding",
2710
+ "prior finding",
2711
+ "earlier finding",
2712
+ "previous result",
2713
+ "prior result",
2714
+ "earlier result",
2715
+ "based on the previous",
2716
+ "based on the earlier",
2717
+ "from the previous agent",
2718
+ "from the prior agent",
2719
+ "the finding above",
2720
+ "as found earlier",
2721
+ "as found above",
2722
+ "building on the previous"
2723
+ ];
2724
+ var READ_COMMANDS = /* @__PURE__ */ new Set([
2725
+ "awk",
2726
+ "basename",
2727
+ "cat",
2728
+ "comm",
2729
+ "cut",
2730
+ "diff",
2731
+ "dirname",
2732
+ "du",
2733
+ "echo",
2734
+ "file",
2735
+ "find",
2736
+ "gh",
2737
+ "grep",
2738
+ "head",
2739
+ "jq",
2740
+ "ls",
2741
+ "nl",
2742
+ "printf",
2743
+ "pwd",
2744
+ "realpath",
2745
+ "rg",
2746
+ // **`sed -i` is deliberately not excluded.** An in-place edit is what `Edit` does, and `Edit` is on
2747
+ // the allow-list above — a turn may issue several of them, so rejecting the shell spelling of the
2748
+ // same thing would exclude a call the tool form counts. Two in-place edits of the *same* file are
2749
+ // caught by the target test instead, which is where that ordering actually lives.
2750
+ "sed",
2751
+ "sort",
2752
+ "stat",
2753
+ "tail",
2754
+ "tree",
2755
+ "uniq",
2756
+ "wc",
2757
+ "which"
2758
+ ]);
2759
+ var MUTATION_WORDS = /* @__PURE__ */ new Set([
2760
+ "--field",
2761
+ "--method",
2762
+ "--raw-field",
2763
+ "-F",
2764
+ "-X",
2765
+ "-delete",
2766
+ "-exec",
2767
+ "-f",
2768
+ "add",
2769
+ "chmod",
2770
+ "chown",
2771
+ "close",
2772
+ "comment",
2773
+ "cp",
2774
+ "create",
2775
+ "dd",
2776
+ "delete",
2777
+ "edit",
2778
+ "git",
2779
+ "install",
2780
+ "kill",
2781
+ "ln",
2782
+ "merge",
2783
+ "mkdir",
2784
+ "mv",
2785
+ "node",
2786
+ "npm",
2787
+ "npx",
2788
+ "pkill",
2789
+ "pnpm",
2790
+ "remove",
2791
+ "rm",
2792
+ "scp",
2793
+ "secret",
2794
+ "set",
2795
+ "ssh",
2796
+ "sudo",
2797
+ "tee",
2798
+ "touch",
2799
+ "truncate",
2800
+ "tsx",
2801
+ "upload",
2802
+ "wget"
2803
+ ]);
2804
+ var READ_JOSH_SUBCOMMANDS = /* @__PURE__ */ new Set([
2805
+ "backlog:budget",
2806
+ "backlog:next",
2807
+ "cost",
2808
+ "delegate",
2809
+ "epic:audit",
2810
+ "epic:bundle",
2811
+ "epic:check",
2812
+ "epic:next",
2813
+ "issue:read",
2814
+ "issue:scout",
2815
+ "issue:state",
2816
+ "lane:list",
2817
+ "latest:scope",
2818
+ "release:scope",
2819
+ "review:brief",
2820
+ "review:round2",
2821
+ "run:liveness"
2822
+ ]);
2823
+ var JOSH_WORD = "josh";
2824
+ var JOSH_SCRIPT_SUFFIX = "josh.ts";
2825
+ var COMMAND_CHAIN = /[|;&`>]|\$\(/u;
2826
+ var WHITESPACE_PATTERN2 = /\s+/u;
2827
+ var TARGET_FIELDS = ["file_path", "notebook_path", "path", "url"];
2828
+ var TARGET_ARRAY_FIELD = "file_paths";
2829
+ var MAX_TARGETS = 8;
2830
+ var WORD_PATTERN = /[\s'"=(),;:|&]+/u;
2831
+ var EXTENSION_PATTERN = /^[A-Za-z]+$/u;
2832
+ var MAX_EXTENSION = 5;
2833
+ var AFTER_DOT = 1;
2834
+ var FIRST_INDEX = 0;
2835
+ var CURRENT_DIRECTORY = "./";
2836
+ var LAST_CHARACTER = -1;
2837
+ var FLAG_PREFIX2 = "-";
2838
+ var PATH_SEPARATOR = "/";
2839
+ var MIN_TARGET_LENGTH = 3;
2840
+ var WRITING_TOOLS = /* @__PURE__ */ new Set(["Edit", "Write", "NotebookEdit"]);
2841
+ var WRITING_WORDS = /* @__PURE__ */ new Set(["dd", "sed", "tee"]);
2842
+ var REDIRECTION = ">";
2843
+ var IN_PLACE_COMMAND = "sed";
2844
+ var IN_PLACE_FLAG_PATTERN = /^--in-place\b|^-[A-Za-z]*i/u;
2845
+ function not_bundleable() {
2846
+ return {
2847
+ is_bundleable: false,
2848
+ targets: [],
2849
+ is_writing: false,
2850
+ may_write: false,
2851
+ has_prior_reference: false
2852
+ };
2853
+ }
2854
+ function is_launch_tool(name) {
2855
+ return LAUNCH_TOOLS.has(name);
2856
+ }
2857
+ function words_of(command) {
2858
+ return command.split(WORD_PATTERN).filter((word) => word !== "");
2859
+ }
2860
+ function has_mutation(command) {
2861
+ return words_of(command).some((word) => MUTATION_WORDS.has(word));
2862
+ }
2863
+ function josh_subcommand(command) {
2864
+ const tokens = command.split(WHITESPACE_PATTERN2).filter((token) => token !== "");
2865
+ const josh_index = tokens.findIndex(
2866
+ (token) => token === JOSH_WORD || token.endsWith(JOSH_SCRIPT_SUFFIX)
2867
+ );
2868
+ return josh_index < FIRST_INDEX ? void 0 : tokens[josh_index + 1];
2869
+ }
2870
+ function is_read_josh(command) {
2871
+ if (COMMAND_CHAIN.test(command)) return false;
2872
+ const subcommand = josh_subcommand(command);
2873
+ if (subcommand === void 0) return false;
2874
+ return READ_JOSH_SUBCOMMANDS.has(canonical_command(subcommand));
2875
+ }
2876
+ function may_write_command(command) {
2877
+ if (command.includes(REDIRECTION)) return true;
2878
+ return words_of(command).some((word) => WRITING_WORDS.has(word));
2879
+ }
2880
+ function write_segment(command) {
2881
+ return time_shell.command_segment(time_shell.unquoted(command));
2882
+ }
2883
+ function is_in_place_sed(segment) {
2884
+ if (time_shell.leading_word(segment) !== IN_PLACE_COMMAND) return false;
2885
+ return words_of(segment).some((word) => IN_PLACE_FLAG_PATTERN.test(word));
2886
+ }
2887
+ function normalize(word) {
2888
+ const head = word.startsWith(CURRENT_DIRECTORY) ? word.slice(CURRENT_DIRECTORY.length) : word;
2889
+ return head.endsWith(PATH_SEPARATOR) ? head.slice(0, LAST_CHARACTER) : head;
2890
+ }
2891
+ function has_extension(word) {
2892
+ const dot = word.lastIndexOf(".");
2893
+ if (dot <= FIRST_INDEX) return false;
2894
+ const suffix = word.slice(dot + AFTER_DOT);
2895
+ return suffix.length <= MAX_EXTENSION && EXTENSION_PATTERN.test(suffix);
2896
+ }
2897
+ function is_target(word) {
2898
+ if (word.startsWith(FLAG_PREFIX2) || word.length < MIN_TARGET_LENGTH) return false;
2899
+ return word.includes(PATH_SEPARATOR) || has_extension(word);
2900
+ }
2901
+ function targets_in(text) {
2902
+ return words_of(text).map((word) => normalize(word)).filter((word) => is_target(word)).slice(0, MAX_TARGETS);
2903
+ }
2904
+ function field_text(input, field) {
2905
+ if (!json_value.is_record(input)) return "";
2906
+ const value = input[field];
2907
+ return typeof value === "string" ? value : "";
2908
+ }
2909
+ function field_targets(input) {
2910
+ if (!json_value.is_record(input)) return [];
2911
+ const value = input[TARGET_ARRAY_FIELD];
2912
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
2913
+ }
2914
+ function tool_targets(input) {
2915
+ const scalar_targets = TARGET_FIELDS.map((field) => field_text(input, field));
2916
+ const targets = [...scalar_targets, ...field_targets(input)].map((target) => normalize(target));
2917
+ return [...new Set(targets)].filter((target) => target !== "");
2918
+ }
2919
+ function prompt_references_prior(input) {
2920
+ const prompt = field_text(input, "prompt").toLowerCase();
2921
+ return PRIOR_REFERENCE_MARKERS.some((marker) => prompt.includes(marker));
2922
+ }
2923
+ function tool_facts(name, input) {
2924
+ const writes = { is_writing: WRITING_TOOLS.has(name), may_write: WRITING_TOOLS.has(name) };
2925
+ const has_prior_reference = LAUNCH_TOOLS.has(name) && prompt_references_prior(input);
2926
+ if (!BUNDLEABLE_TOOLS.has(name)) return { ...not_bundleable(), ...writes, has_prior_reference };
2927
+ return { is_bundleable: true, targets: tool_targets(input), ...writes, has_prior_reference };
2928
+ }
2929
+ function bash_facts(command) {
2930
+ const writes = {
2931
+ is_writing: is_in_place_sed(write_segment(command)),
2932
+ may_write: may_write_command(command)
2933
+ };
2934
+ if (is_read_josh(command)) {
2935
+ return {
2936
+ is_bundleable: true,
2937
+ targets: targets_in(time_shell.unquoted(command)),
2938
+ ...writes,
2939
+ has_prior_reference: false
2940
+ };
2941
+ }
2942
+ if (!READ_COMMANDS.has(time_shell.leading_word(command)) || has_mutation(command)) {
2943
+ return { ...not_bundleable(), ...writes };
2944
+ }
2945
+ return {
2946
+ is_bundleable: true,
2947
+ targets: targets_in(time_shell.unquoted(command)),
2948
+ ...writes,
2949
+ has_prior_reference: false
2950
+ };
2951
+ }
2952
+ function call_facts(name, input) {
2953
+ if (name !== BASH_TOOL2) return tool_facts(name, input);
2954
+ return bash_facts(time_shell.bash_command(input));
2260
2955
  }
2261
- var time_followup_stage = { NO_STAGES, read_stages };
2956
+ var time_bundle_call = {
2957
+ MAX_TARGETS,
2958
+ not_bundleable,
2959
+ bash_facts,
2960
+ call_facts,
2961
+ tool_facts,
2962
+ // Exported for `time-agent-bundles.ts` (joshuafolkken/kit#1854), which asks the launch question of a
2963
+ // span's `label` — the tool name for a non-Bash call — so the set lives in one place.
2964
+ is_launch_tool,
2965
+ // Exported for `time-writes.ts` (joshuafolkken/kit#1472), which asks what a call *wrote* rather
2966
+ // than what it named. The extraction is the same one either way — a second copy of it would let a
2967
+ // path be recognized as a target when read and missed when written.
2968
+ targets_in,
2969
+ tool_targets,
2970
+ // Exported for the batching guard's own word scan (joshuafolkken/kit#1390), so the two scanners
2971
+ // cannot come to disagree about where one word of a shell line ends and the next begins.
2972
+ // Exported for the read-fold notice (joshuafolkken/kit#2311), which offers `read:files <path>` only
2973
+ // over file-shaped targets — a bare directory like `scripts/` is a target here but not something
2974
+ // `read:files` can read, so the notice reuses this test rather than keep a second copy that could
2975
+ // drift from what counts as a file path.
2976
+ has_extension,
2977
+ // Exported for `time-writes.ts` (joshuafolkken/kit#1509), which needs the same two answers to say
2978
+ // *which* files an in-place `sed` wrote. Two copies of this test disagreed in both directions at
2979
+ // once — one called a piped `grep -i` a write, the other missed a bundled `sed -ni`.
2980
+ write_segment,
2981
+ is_in_place_sed,
2982
+ // Exported for the drift test in `time-bundle-call.test.ts` (joshuafolkken/kit#1875), which pins that
2983
+ // every name here is a real `josh` command and none of them writes.
2984
+ READ_JOSH_SUBCOMMANDS
2985
+ };
2262
2986
 
2263
2987
  // scripts/cost-runtime/cost-attribute.ts
2264
2988
  var ISSUE_BRANCH_PATTERN = /^(\d+)-/u;
@@ -2415,121 +3139,6 @@ var time_markers = {
2415
3139
  bash_issue
2416
3140
  };
2417
3141
 
2418
- // scripts/lib/status-icons.ts
2419
- var FAIL_ICON = "\u2717";
2420
- var PASS_ICON = "\u2714";
2421
- var status_icons = { FAIL_ICON, PASS_ICON };
2422
-
2423
- // scripts/josh/josh-verdict.ts
2424
- var { FAIL_ICON: FAIL_ICON2, PASS_ICON: PASS_ICON2 } = status_icons;
2425
- var GATE_SUBJECT = "verification gate";
2426
- var GATE_PASSED_PREFIX = `${PASS_ICON2} ${GATE_SUBJECT} passed`;
2427
- var GATE_FAILED_PREFIX = `${FAIL_ICON2} ${GATE_SUBJECT} failed`;
2428
- var PASSED_VERDICT = "passed";
2429
- var FAILED_VERDICT = "failed";
2430
- function format_gate_passed(step_count, total) {
2431
- return `${GATE_PASSED_PREFIX} (${step_count} checks) in ${total}.`;
2432
- }
2433
- function format_gate_failed(failed_labels, total) {
2434
- return `${GATE_FAILED_PREFIX}: ${failed_labels} (${total})`;
2435
- }
2436
- var GATE_OPENING_PREFIX = "plan: ";
2437
- var GATE_OPENING_MARK = " checks at once";
2438
- function is_gate_opening(line) {
2439
- const trimmed = line.trimStart();
2440
- return trimmed.startsWith(GATE_OPENING_PREFIX) && trimmed.includes(GATE_OPENING_MARK);
2441
- }
2442
- function read_verdict(line) {
2443
- const trimmed = line.trimStart();
2444
- if (trimmed.startsWith(GATE_FAILED_PREFIX)) return FAILED_VERDICT;
2445
- if (trimmed.startsWith(GATE_PASSED_PREFIX)) return PASSED_VERDICT;
2446
- return void 0;
2447
- }
2448
- var josh_verdict = {
2449
- PASSED_VERDICT,
2450
- FAILED_VERDICT,
2451
- format_gate_passed,
2452
- format_gate_failed,
2453
- GATE_OPENING_MARK,
2454
- GATE_OPENING_PREFIX,
2455
- is_gate_opening,
2456
- read_verdict
2457
- };
2458
-
2459
- // scripts/time-runtime/time-reported-failure.ts
2460
- import { z as z3 } from "zod";
2461
- var TEXT_BLOCK_SCHEMA = z3.object({ text: z3.string().nullish() });
2462
- var CONTENT_SCHEMA = z3.union([z3.string(), z3.array(z3.unknown())]);
2463
- var LINE_SEPARATOR2 = "\n";
2464
- function block_text(block) {
2465
- const parsed = TEXT_BLOCK_SCHEMA.safeParse(block);
2466
- return parsed.success ? parsed.data.text ?? "" : "";
2467
- }
2468
- function result_text2(content) {
2469
- const parsed = CONTENT_SCHEMA.safeParse(content);
2470
- if (!parsed.success) return "";
2471
- if (typeof parsed.data === "string") return parsed.data;
2472
- return parsed.data.map((block) => block_text(block)).join(LINE_SEPARATOR2);
2473
- }
2474
- function is_failure_line(line) {
2475
- return line.trimStart().startsWith(status_icons.FAIL_ICON);
2476
- }
2477
- function is_failed_verdict(line) {
2478
- return josh_verdict.read_verdict(line) === josh_verdict.FAILED_VERDICT;
2479
- }
2480
- function is_passed_verdict(line) {
2481
- return josh_verdict.read_verdict(line) === josh_verdict.PASSED_VERDICT;
2482
- }
2483
- function new_scan() {
2484
- return {
2485
- did_find: false,
2486
- has_failure_before_region: false,
2487
- has_failure_in_region: false,
2488
- is_region_open: false
2489
- };
2490
- }
2491
- function close_region(scan) {
2492
- scan.did_find ||= scan.is_region_open && scan.has_failure_before_region;
2493
- scan.has_failure_before_region = false;
2494
- scan.has_failure_in_region = false;
2495
- scan.is_region_open = false;
2496
- }
2497
- function note_failure(scan) {
2498
- if (scan.is_region_open) {
2499
- scan.has_failure_in_region = true;
2500
- return;
2501
- }
2502
- scan.has_failure_before_region = true;
2503
- }
2504
- function scan_line(scan, line) {
2505
- if (is_passed_verdict(line)) {
2506
- close_region(scan);
2507
- return;
2508
- }
2509
- if (is_failure_line(line)) {
2510
- note_failure(scan);
2511
- return;
2512
- }
2513
- if (josh_verdict.is_gate_opening(line)) scan.is_region_open = true;
2514
- }
2515
- function scan_body(lines) {
2516
- const scan = new_scan();
2517
- for (const line of lines) scan_line(scan, line);
2518
- return scan;
2519
- }
2520
- function did_scan_find(scan) {
2521
- return scan.did_find || scan.has_failure_before_region || scan.has_failure_in_region;
2522
- }
2523
- function has_failure_line(content) {
2524
- const lines = result_text2(content).split(LINE_SEPARATOR2);
2525
- if (lines.some((line) => is_failed_verdict(line))) return true;
2526
- return did_scan_find(scan_body(lines));
2527
- }
2528
- function is_reported_failure(josh_command, did_print_failure) {
2529
- return josh_command !== "" && did_print_failure;
2530
- }
2531
- var time_reported_failure = { result_text: result_text2, has_failure_line, is_reported_failure };
2532
-
2533
3142
  // scripts/time-runtime/time-single-check.ts
2534
3143
  var CHECK_COMMANDS = /* @__PURE__ */ new Set([
2535
3144
  "josh check",
@@ -2554,47 +3163,48 @@ function check_key(josh_command, command) {
2554
3163
  var time_single_check = { NO_CHECK, check_key };
2555
3164
 
2556
3165
  // scripts/time-runtime/time-transcript-line.ts
2557
- import { z as z4 } from "zod";
3166
+ import { z as z6 } from "zod";
2558
3167
 
2559
3168
  // scripts/time-runtime/time-instant.ts
2560
3169
  function parse_instant(raw) {
2561
- const parsed = Date.parse(raw ?? "");
3170
+ if (raw === null || raw === void 0) return void 0;
3171
+ const parsed = Date.parse(raw);
2562
3172
  return Number.isNaN(parsed) ? void 0 : parsed;
2563
3173
  }
2564
3174
  var time_instant = { parse_instant };
2565
3175
 
2566
3176
  // scripts/time-runtime/time-transcript-line.ts
2567
- var BLOCK_SCHEMA2 = z4.object({
2568
- type: z4.string().nullish(),
2569
- name: z4.string().nullish(),
2570
- id: z4.string().nullish(),
2571
- tool_use_id: z4.string().nullish(),
2572
- input: z4.unknown().nullish(),
3177
+ var BLOCK_SCHEMA2 = z6.object({
3178
+ type: z6.string().nullish(),
3179
+ name: z6.string().nullish(),
3180
+ id: z6.string().nullish(),
3181
+ tool_use_id: z6.string().nullish(),
3182
+ input: z6.unknown().nullish(),
2573
3183
  // Whether the harness wrote this result back as a failure (joshuafolkken/kit#1309). Present on a
2574
3184
  // `tool_result` block and on nothing else, and absent even there for the tools that never report
2575
3185
  // one — which is why it is read as three answers rather than as a boolean with a default.
2576
- is_error: z4.boolean().nullish(),
3186
+ is_error: z6.boolean().nullish(),
2577
3187
  // What the call printed. Read only to recover the outcome a pipeline threw away
2578
3188
  // (joshuafolkken/kit#1361): it is kept as flattened text rather than as blocks, because that is
2579
3189
  // the whole of what `time-reported-failure.ts` asks of it.
2580
- content: z4.unknown().nullish()
3190
+ content: z6.unknown().nullish()
2581
3191
  });
2582
- var CONTENT_SCHEMA2 = z4.union([z4.string(), z4.array(BLOCK_SCHEMA2)]);
2583
- var MESSAGE_SCHEMA2 = z4.object({ id: z4.string().nullish(), content: CONTENT_SCHEMA2.nullish() });
2584
- var LINE_SCHEMA = z4.object({
2585
- type: z4.string().nullish(),
2586
- timestamp: z4.string().nullish(),
3192
+ var CONTENT_SCHEMA2 = z6.union([z6.string(), z6.array(BLOCK_SCHEMA2)]);
3193
+ var MESSAGE_SCHEMA2 = z6.object({ id: z6.string().nullish(), content: CONTENT_SCHEMA2.nullish() });
3194
+ var LINE_SCHEMA = z6.object({
3195
+ type: z6.string().nullish(),
3196
+ timestamp: z6.string().nullish(),
2587
3197
  // The branch the line was written on, which is where the issue number lives — `josh git` names a
2588
3198
  // branch `<N>-<slug>`. Read here rather than re-parsed by a second reader so `josh time --issue`
2589
3199
  // and `josh cost --issue` answer from the same field (joshuafolkken/kit#1268).
2590
- gitBranch: z4.string().nullish(),
3200
+ gitBranch: z6.string().nullish(),
2591
3201
  // The two fields outside `message` that the harness writes an end-of-task notice on
2592
3202
  // (joshuafolkken/kit#1696). **Both are read as `unknown` rather than as strings**: a schema
2593
3203
  // insisting on a string here would reject every line whose `content` is a list of blocks — which is
2594
3204
  // most of them — and a rejected line is dropped from the timeline entirely, so the shares would stop
2595
3205
  // reconstructing the elapsed time. The shape is checked at the read below instead.
2596
- content: z4.unknown().nullish(),
2597
- attachment: z4.unknown().nullish(),
3206
+ content: z6.unknown().nullish(),
3207
+ attachment: z6.unknown().nullish(),
2598
3208
  message: MESSAGE_SCHEMA2.nullish()
2599
3209
  });
2600
3210
  var UNKNOWN_BRANCH = "";
@@ -2687,24 +3297,9 @@ var time_writes = {
2687
3297
  tool_writes
2688
3298
  };
2689
3299
 
2690
- // scripts/time-runtime/time-spans.ts
2691
- var { NO_MESSAGE_ID: NO_MESSAGE_ID2, parse_line: parse_line3 } = time_transcript_line;
2692
- var ASSISTANT_TYPE = "assistant";
2693
- var USER_TYPE = "user";
3300
+ // scripts/time-runtime/time-tool-call.ts
3301
+ var { NO_MESSAGE_ID: NO_MESSAGE_ID2 } = time_transcript_line;
2694
3302
  var UNKNOWN_TOOL = "unknown";
2695
- var MODEL_CATEGORY = "model";
2696
- var TOOL_CATEGORY = "tool";
2697
- var HUMAN_CATEGORY = "human";
2698
- var OK_OUTCOME = "ok";
2699
- var FAILED_OUTCOME = "failed";
2700
- var UNKNOWN_OUTCOME = "unknown";
2701
- var NO_RESULT = {
2702
- call_id: "",
2703
- outcome: UNKNOWN_OUTCOME,
2704
- refusal_guard: "",
2705
- background_id: time_background.NO_BACKGROUND,
2706
- followup_stages: time_followup_stage.NO_STAGES
2707
- };
2708
3303
  var NO_CALL = {
2709
3304
  label: "",
2710
3305
  josh_command: "",
@@ -2766,6 +3361,31 @@ function to_tool_call(name, input, message_id) {
2766
3361
  if (name !== cost_blocks.BASH_TOOL) return non_bash_call(name, input, message_id);
2767
3362
  return bash_call(input, message_id);
2768
3363
  }
3364
+ var time_tool_call = {
3365
+ UNKNOWN_TOOL,
3366
+ NO_CALL,
3367
+ UNKNOWN_CALL,
3368
+ to_tool_call
3369
+ };
3370
+
3371
+ // scripts/time-runtime/time-spans.ts
3372
+ var { NO_MESSAGE_ID: NO_MESSAGE_ID3, parse_line: parse_line3 } = time_transcript_line;
3373
+ var { NO_CALL: NO_CALL2, UNKNOWN_CALL: UNKNOWN_CALL2, UNKNOWN_TOOL: UNKNOWN_TOOL2, to_tool_call: to_tool_call2 } = time_tool_call;
3374
+ var ASSISTANT_TYPE = "assistant";
3375
+ var USER_TYPE = "user";
3376
+ var MODEL_CATEGORY = "model";
3377
+ var TOOL_CATEGORY = "tool";
3378
+ var HUMAN_CATEGORY = "human";
3379
+ var OK_OUTCOME = "ok";
3380
+ var FAILED_OUTCOME = "failed";
3381
+ var UNKNOWN_OUTCOME = "unknown";
3382
+ var NO_RESULT = {
3383
+ call_id: "",
3384
+ outcome: UNKNOWN_OUTCOME,
3385
+ refusal_guard: "",
3386
+ background_id: time_background.NO_BACKGROUND,
3387
+ followup_stages: time_followup_stage.NO_STAGES
3388
+ };
2769
3389
  function tool_use_blocks(lines) {
2770
3390
  return lines.flatMap(
2771
3391
  (line) => line.blocks.filter((block) => block.type === cost_blocks.TOOL_USE_TYPE && block.id !== "").map((block) => ({ block, message_id: line.message_id }))
@@ -2775,7 +3395,7 @@ function collect_calls(lines) {
2775
3395
  return new Map(
2776
3396
  tool_use_blocks(lines).map(({ block, message_id }) => [
2777
3397
  block.id,
2778
- to_tool_call(block.name, block.input, message_id)
3398
+ to_tool_call2(block.name, block.input, message_id)
2779
3399
  ])
2780
3400
  );
2781
3401
  }
@@ -2803,13 +3423,13 @@ function facts_of(result, call) {
2803
3423
  }
2804
3424
  function user_event(line, calls) {
2805
3425
  const result = result_block(line);
2806
- if (result === void 0) return event_of(line, HUMAN_CATEGORY, NO_CALL);
2807
- const call = calls.get(result.result_id) ?? UNKNOWN_CALL;
3426
+ if (result === void 0) return event_of(line, HUMAN_CATEGORY, NO_CALL2);
3427
+ const call = calls.get(result.result_id) ?? UNKNOWN_CALL2;
2808
3428
  return event_of(line, TOOL_CATEGORY, call, facts_of(result, call));
2809
3429
  }
2810
3430
  function to_event(line, calls) {
2811
3431
  if (line.type === ASSISTANT_TYPE) {
2812
- return event_of(line, MODEL_CATEGORY, { ...NO_CALL, message_id: line.message_id });
3432
+ return event_of(line, MODEL_CATEGORY, { ...NO_CALL2, message_id: line.message_id });
2813
3433
  }
2814
3434
  return line.type === USER_TYPE ? user_event(line, calls) : void 0;
2815
3435
  }
@@ -2891,8 +3511,8 @@ var time_spans = {
2891
3511
  OK_OUTCOME,
2892
3512
  FAILED_OUTCOME,
2893
3513
  UNKNOWN_OUTCOME,
2894
- NO_MESSAGE_ID: NO_MESSAGE_ID2,
2895
- UNKNOWN_TOOL,
3514
+ NO_MESSAGE_ID: NO_MESSAGE_ID3,
3515
+ UNKNOWN_TOOL: UNKNOWN_TOOL2,
2896
3516
  has_transcript_data,
2897
3517
  equal_durations,
2898
3518
  no_background,
@@ -2901,7 +3521,7 @@ var time_spans = {
2901
3521
  bash_label: time_shell.bash_label,
2902
3522
  josh_command_of: time_shell.josh_command_of,
2903
3523
  josh_commands_of: time_shell.josh_commands_of,
2904
- to_tool_call,
3524
+ to_tool_call: to_tool_call2,
2905
3525
  parse_line: parse_line3,
2906
3526
  parse_timeline
2907
3527
  };
@@ -3370,7 +3990,7 @@ function describe_span(span) {
3370
3990
  }
3371
3991
  var FOLD_MINIMUM = 2;
3372
3992
  function read_targets(sequence) {
3373
- const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path6) => path6 !== "" && time_bundle_call.has_extension(path6));
3993
+ const paths = sequence.filter((span) => span.is_bundleable && !span.is_writing).map((span) => span.targets[0] ?? "").filter((path7) => path7 !== "" && time_bundle_call.has_extension(path7));
3374
3994
  return [...new Set(paths)];
3375
3995
  }
3376
3996
  function read_fold_directive(sequence) {
@@ -3379,7 +3999,7 @@ function read_fold_directive(sequence) {
3379
3999
  return ` Fold them into one call: \`pnpm josh read:files ${paths.join(" ")}\`.`;
3380
4000
  }
3381
4001
  function write_targets(sequence) {
3382
- const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path6) => path6 !== "" && time_bundle_call.has_extension(path6));
4002
+ const paths = sequence.filter((span) => span.label === EDIT_TOOL).map((span) => span.targets[0] ?? "").filter((path7) => path7 !== "" && time_bundle_call.has_extension(path7));
3383
4003
  return [...new Set(paths)];
3384
4004
  }
3385
4005
  function write_fold_directive(sequence) {
@@ -3431,41 +4051,41 @@ var time_batch_guard = {
3431
4051
  };
3432
4052
 
3433
4053
  // scripts/time-runtime/time-hook-transcript.ts
3434
- import path3 from "node:path";
4054
+ import path6 from "node:path";
3435
4055
 
3436
4056
  // scripts/cost-runtime/cost-transcript.ts
3437
- import { readdirSync, readFileSync as readFileSync2, statSync } from "node:fs";
4057
+ import { readdirSync as readdirSync3, readFileSync as readFileSync3, statSync } from "node:fs";
3438
4058
  import { homedir } from "node:os";
3439
- import path2 from "node:path";
4059
+ import path5 from "node:path";
3440
4060
 
3441
4061
  // scripts/lane/lane-paths.ts
3442
- import path from "node:path";
4062
+ import path4 from "node:path";
3443
4063
  var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
3444
4064
  var LANE_DIRECTORY_SUFFIX = "-lanes";
3445
4065
  var LANE_BRANCH_SUFFIX = "-lane";
3446
4066
  function default_lane_root(repository_root) {
3447
- const name = path.basename(repository_root);
3448
- return path.join(path.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
4067
+ const name = path4.basename(repository_root);
4068
+ return path4.join(path4.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
3449
4069
  }
3450
4070
  function lane_root(repository_root, environment = process.env) {
3451
4071
  const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
3452
- return configured.length === 0 ? default_lane_root(repository_root) : path.resolve(configured);
4072
+ return configured.length === 0 ? default_lane_root(repository_root) : path4.resolve(configured);
3453
4073
  }
3454
4074
  function lane_directory(root, issue) {
3455
- return path.join(root, issue);
4075
+ return path4.join(root, issue);
3456
4076
  }
3457
4077
  var LANE_ISSUE_PATTERN = /^\d+$/u;
3458
4078
  var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
3459
4079
  function is_lane_root(directory, environment) {
3460
4080
  const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
3461
- if (configured.length > 0) return path.resolve(configured) === directory;
3462
- return DEFAULT_LANE_ROOT_PATTERN.test(path.basename(directory));
4081
+ if (configured.length > 0) return path4.resolve(configured) === directory;
4082
+ return DEFAULT_LANE_ROOT_PATTERN.test(path4.basename(directory));
3463
4083
  }
3464
4084
  function lane_issue_of(directory, environment = process.env) {
3465
- const resolved = path.resolve(directory);
3466
- const issue = path.basename(resolved);
4085
+ const resolved = path4.resolve(directory);
4086
+ const issue = path4.basename(resolved);
3467
4087
  if (!LANE_ISSUE_PATTERN.test(issue)) return void 0;
3468
- return is_lane_root(path.dirname(resolved), environment) ? issue : void 0;
4088
+ return is_lane_root(path4.dirname(resolved), environment) ? issue : void 0;
3469
4089
  }
3470
4090
  function lane_branch(issue) {
3471
4091
  return `${issue}${LANE_BRANCH_SUFFIX}`;
@@ -3481,25 +4101,25 @@ var lane_paths = {
3481
4101
  };
3482
4102
 
3483
4103
  // scripts/lib/read-file.ts
3484
- import { readFileSync } from "node:fs";
4104
+ import { readFileSync as readFileSync2 } from "node:fs";
3485
4105
  var ABSENT_CODE = "ENOENT";
3486
4106
  function is_absent(error) {
3487
4107
  return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
3488
4108
  }
3489
- function read_optional(path6) {
4109
+ function read_optional(path7) {
3490
4110
  try {
3491
- return readFileSync(path6, "utf8");
4111
+ return readFileSync2(path7, "utf8");
3492
4112
  } catch (error) {
3493
4113
  if (is_absent(error)) return void 0;
3494
4114
  throw error;
3495
4115
  }
3496
4116
  }
3497
- function read_file_or_empty(path6) {
3498
- return read_optional(path6) ?? "";
4117
+ function read_file_or_empty(path7) {
4118
+ return read_optional(path7) ?? "";
3499
4119
  }
3500
- function read_if_readable(path6) {
4120
+ function read_if_readable(path7) {
3501
4121
  try {
3502
- return readFileSync(path6, "utf8");
4122
+ return readFileSync2(path7, "utf8");
3503
4123
  } catch {
3504
4124
  return void 0;
3505
4125
  }
@@ -3507,30 +4127,30 @@ function read_if_readable(path6) {
3507
4127
  var file_reader = { read_optional, read_file_or_empty, read_if_readable };
3508
4128
 
3509
4129
  // scripts/cost-runtime/cost-usage.ts
3510
- import { z as z5 } from "zod";
3511
- var CACHE_CREATION_SCHEMA = z5.object({
3512
- ephemeral_1h_input_tokens: z5.number().nullish(),
3513
- ephemeral_5m_input_tokens: z5.number().nullish()
4130
+ import { z as z7 } from "zod";
4131
+ var CACHE_CREATION_SCHEMA = z7.object({
4132
+ ephemeral_1h_input_tokens: z7.number().nullish(),
4133
+ ephemeral_5m_input_tokens: z7.number().nullish()
3514
4134
  });
3515
- var USAGE_SCHEMA = z5.object({
3516
- input_tokens: z5.number(),
3517
- cache_creation_input_tokens: z5.number().nullish(),
3518
- cache_read_input_tokens: z5.number().nullish(),
3519
- output_tokens: z5.number(),
3520
- output_tokens_details: z5.object({ thinking_tokens: z5.number().nullish() }).nullish(),
4135
+ var USAGE_SCHEMA = z7.object({
4136
+ input_tokens: z7.number(),
4137
+ cache_creation_input_tokens: z7.number().nullish(),
4138
+ cache_read_input_tokens: z7.number().nullish(),
4139
+ output_tokens: z7.number(),
4140
+ output_tokens_details: z7.object({ thinking_tokens: z7.number().nullish() }).nullish(),
3521
4141
  cache_creation: CACHE_CREATION_SCHEMA.nullish()
3522
4142
  });
3523
- var MESSAGE_SCHEMA3 = z5.object({
3524
- id: z5.string().nullish(),
3525
- model: z5.string().nullish(),
4143
+ var MESSAGE_SCHEMA3 = z7.object({
4144
+ id: z7.string().nullish(),
4145
+ model: z7.string().nullish(),
3526
4146
  usage: USAGE_SCHEMA.nullish()
3527
4147
  });
3528
- var LINE_SCHEMA2 = z5.object({
3529
- type: z5.string(),
3530
- requestId: z5.string().nullish(),
3531
- uuid: z5.string().nullish(),
3532
- gitBranch: z5.string().nullish(),
3533
- timestamp: z5.string().nullish(),
4148
+ var LINE_SCHEMA2 = z7.object({
4149
+ type: z7.string(),
4150
+ requestId: z7.string().nullish(),
4151
+ uuid: z7.string().nullish(),
4152
+ gitBranch: z7.string().nullish(),
4153
+ timestamp: z7.string().nullish(),
3534
4154
  message: MESSAGE_SCHEMA3.nullish()
3535
4155
  });
3536
4156
  var SYNTHETIC_MODEL = "<synthetic>";
@@ -3644,7 +4264,7 @@ var cost_usage = {
3644
4264
  };
3645
4265
 
3646
4266
  // scripts/cost-runtime/cost-transcript.ts
3647
- var TRANSCRIPT_ROOT = path2.join(".claude", "projects");
4267
+ var TRANSCRIPT_ROOT = path5.join(".claude", "projects");
3648
4268
  var TRANSCRIPT_EXTENSION = ".jsonl";
3649
4269
  var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
3650
4270
  var UNIT_DIRECTORY = "subagents";
@@ -3653,7 +4273,7 @@ function project_slug(cwd) {
3653
4273
  return cwd.replaceAll(SLUG_PATTERN, "-");
3654
4274
  }
3655
4275
  function transcript_directory(cwd, home = homedir()) {
3656
- return path2.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
4276
+ return path5.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
3657
4277
  }
3658
4278
  var GIT_ENTRY = ".git";
3659
4279
  var GITDIR_PREFIX = "gitdir:";
@@ -3661,7 +4281,7 @@ var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
3661
4281
  var NOT_FOUND = -1;
3662
4282
  function linked_worktree_gitdir(cwd) {
3663
4283
  try {
3664
- const contents = readFileSync2(path2.join(cwd, GIT_ENTRY), "utf8").trim();
4284
+ const contents = readFileSync3(path5.join(cwd, GIT_ENTRY), "utf8").trim();
3665
4285
  return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
3666
4286
  } catch {
3667
4287
  return "";
@@ -3669,22 +4289,22 @@ function linked_worktree_gitdir(cwd) {
3669
4289
  }
3670
4290
  function session_cwd(cwd) {
3671
4291
  const gitdir = linked_worktree_gitdir(cwd);
3672
- const absolute = gitdir === "" ? "" : path2.resolve(cwd, gitdir);
4292
+ const absolute = gitdir === "" ? "" : path5.resolve(cwd, gitdir);
3673
4293
  const segment = absolute.indexOf(WORKTREE_SEGMENT);
3674
4294
  return segment === NOT_FOUND ? cwd : absolute.slice(0, segment);
3675
4295
  }
3676
4296
  function read_directory(directory) {
3677
4297
  try {
3678
- return readdirSync(directory);
4298
+ return readdirSync3(directory);
3679
4299
  } catch {
3680
4300
  return [];
3681
4301
  }
3682
4302
  }
3683
4303
  var LANE_ISSUE_SLUG = /^\d+$/u;
3684
4304
  function lane_transcript_directories(main_cwd, home) {
3685
- const projects = path2.join(home, TRANSCRIPT_ROOT);
4305
+ const projects = path5.join(home, TRANSCRIPT_ROOT);
3686
4306
  const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
3687
- return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path2.join(projects, name));
4307
+ return read_directory(projects).filter((name) => name.startsWith(prefix) && LANE_ISSUE_SLUG.test(name.slice(prefix.length))).map((name) => path5.join(projects, name));
3688
4308
  }
3689
4309
  function transcript_directories(cwd, home = homedir()) {
3690
4310
  const own = transcript_directory(cwd, home);
@@ -3715,16 +4335,16 @@ function without_extension(name) {
3715
4335
  return name.slice(0, -TRANSCRIPT_EXTENSION.length);
3716
4336
  }
3717
4337
  function own_files(directory, names) {
3718
- return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path2.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
4338
+ return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path5.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
3719
4339
  }
3720
4340
  function unit_directory(directory, session_id) {
3721
- return path2.join(directory, session_id, UNIT_DIRECTORY);
4341
+ return path5.join(directory, session_id, UNIT_DIRECTORY);
3722
4342
  }
3723
4343
  var UNIT_DEPTH = 1;
3724
4344
  function level_units(subagents_directory, prefix, depth) {
3725
4345
  return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
3726
4346
  (name) => to_session_file(
3727
- path2.join(subagents_directory, name),
4347
+ path5.join(subagents_directory, name),
3728
4348
  `${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
3729
4349
  depth
3730
4350
  )
@@ -3866,10 +4486,10 @@ function is_agent_id(value) {
3866
4486
  return typeof value === "string" && AGENT_ID_PATTERN.test(value);
3867
4487
  }
3868
4488
  function fork_path(transcript_path, agent_id) {
3869
- const directory = path3.dirname(transcript_path);
3870
- const session_id = path3.basename(transcript_path, TRANSCRIPT_EXTENSION2);
4489
+ const directory = path6.dirname(transcript_path);
4490
+ const session_id = path6.basename(transcript_path, TRANSCRIPT_EXTENSION2);
3871
4491
  const file_name = `${AGENT_PREFIX}${agent_id}${TRANSCRIPT_EXTENSION2}`;
3872
- return path3.join(cost_transcript.unit_directory(directory, session_id), file_name);
4492
+ return path6.join(cost_transcript.unit_directory(directory, session_id), file_name);
3873
4493
  }
3874
4494
  function transcript_of(transcript_path, agent_id) {
3875
4495
  if (!is_agent_id(agent_id)) return transcript_path;
@@ -3883,127 +4503,7 @@ var time_hook_transcript = {
3883
4503
 
3884
4504
  // scripts/time-runtime/time-density-hook.ts
3885
4505
  import { closeSync, fstatSync, openSync, readSync } from "node:fs";
3886
-
3887
- // scripts/josh/stamp-file.ts
3888
- import { createHash, randomUUID } from "node:crypto";
3889
- import { lstatSync, readFileSync as readFileSync3, renameSync, rmSync, writeFileSync } from "node:fs";
3890
- import path5 from "node:path";
3891
-
3892
- // scripts/init/init-paths.ts
3893
- import path4 from "node:path";
3894
- import { fileURLToPath } from "node:url";
3895
- var PACKAGE_DIR = path4.join(path4.dirname(fileURLToPath(import.meta.url)), "..", "..");
3896
- var PROJECT_ROOT = process.cwd();
3897
-
3898
- // scripts/josh/platform-temporary.ts
3899
- import { accessSync, constants } from "node:fs";
3900
- import { tmpdir } from "node:os";
3901
- var POSIX_TEMP_ROOT = "/tmp";
3902
- var WINDOWS_PLATFORM = "win32";
3903
- function is_writable_directory(directory) {
3904
- try {
3905
- accessSync(directory, constants.W_OK);
3906
- return true;
3907
- } catch {
3908
- return false;
3909
- }
3910
- }
3911
- function resolve_temporary_root(platform, can_write = is_writable_directory) {
3912
- if (platform === WINDOWS_PLATFORM) return tmpdir();
3913
- return can_write(POSIX_TEMP_ROOT) ? POSIX_TEMP_ROOT : tmpdir();
3914
- }
3915
- var TEMP_ROOT_KEY = "JOSH_TEMP_ROOT";
3916
- function temporary_root(override, platform) {
3917
- return override === void 0 || override === "" ? resolve_temporary_root(platform) : override;
3918
- }
3919
- var PLATFORM_TEMP_ROOT = temporary_root(process.env[TEMP_ROOT_KEY], process.platform);
3920
-
3921
- // scripts/josh/stamp-file.ts
3922
- var HASH_ALGORITHM = "sha256";
3923
- var STAMP_SUFFIX = ".json";
3924
- var STAMP_KEY_LENGTH = 16;
3925
- var STAMP_FILE_MODE = 384;
3926
- var STAMP_WRITE_FLAG = "wx";
3927
- var STAMP_CREATE_FLAG = STAMP_WRITE_FLAG;
3928
- var EXISTS_ERROR_CODE = "EEXIST";
3929
- var ACCOUNT_KEY_SEPARATOR = ":";
3930
- function digest(content) {
3931
- return createHash(HASH_ALGORITHM).update(content).digest("hex");
3932
- }
3933
- function account_key() {
3934
- return String(process.getuid?.() ?? "");
3935
- }
3936
- function stamp_path(prefix, root = PACKAGE_DIR, suffix = STAMP_SUFFIX) {
3937
- const key = digest(`${account_key()}${ACCOUNT_KEY_SEPARATOR}${root}`).slice(0, STAMP_KEY_LENGTH);
3938
- return path5.join(PLATFORM_TEMP_ROOT, `${prefix}${key}${suffix}`);
3939
- }
3940
- function write_exclusively(target, content) {
3941
- rmSync(target, { force: true });
3942
- writeFileSync(target, content, { flag: STAMP_WRITE_FLAG, mode: STAMP_FILE_MODE });
3943
- return target;
3944
- }
3945
- function write_stamp(target, payload) {
3946
- return write_exclusively(target, JSON.stringify(payload));
3947
- }
3948
- function replace_stamp(target, payload) {
3949
- const temporary = `${target}.${String(process.pid)}.${randomUUID()}`;
3950
- try {
3951
- writeFileSync(temporary, JSON.stringify(payload), {
3952
- flag: STAMP_CREATE_FLAG,
3953
- mode: STAMP_FILE_MODE
3954
- });
3955
- renameSync(temporary, target);
3956
- return target;
3957
- } finally {
3958
- rmSync(temporary, { force: true });
3959
- }
3960
- }
3961
- function write_text_stamp(target, text) {
3962
- return write_exclusively(target, text);
3963
- }
3964
- function create_stamp(target, payload) {
3965
- try {
3966
- writeFileSync(target, JSON.stringify(payload), {
3967
- flag: STAMP_CREATE_FLAG,
3968
- mode: STAMP_FILE_MODE
3969
- });
3970
- return true;
3971
- } catch (error) {
3972
- if (error.code === EXISTS_ERROR_CODE) return false;
3973
- throw error;
3974
- }
3975
- }
3976
- function remove_stamp(target) {
3977
- rmSync(target, { force: true });
3978
- }
3979
- function is_own_regular_file(source) {
3980
- const stats = lstatSync(source);
3981
- if (!stats.isFile()) return false;
3982
- const uid = process.getuid?.();
3983
- return uid === void 0 || stats.uid === uid;
3984
- }
3985
- function read_stamp_text(source) {
3986
- try {
3987
- if (!is_own_regular_file(source)) return void 0;
3988
- return readFileSync3(source, "utf8");
3989
- } catch {
3990
- return void 0;
3991
- }
3992
- }
3993
- var stamp_file = {
3994
- create_stamp,
3995
- digest,
3996
- is_own_regular_file,
3997
- read_stamp_text,
3998
- replace_stamp,
3999
- remove_stamp,
4000
- stamp_path,
4001
- write_stamp,
4002
- write_text_stamp
4003
- };
4004
-
4005
- // scripts/time-runtime/time-density-hook.ts
4006
- import { z as z6 } from "zod";
4506
+ import { z as z8 } from "zod";
4007
4507
 
4008
4508
  // scripts/time-runtime/time-density.ts
4009
4509
  var MIN_ROUND_TRIPS = 10;
@@ -4059,15 +4559,15 @@ var TAIL_BYTES = 262144;
4059
4559
  var FILE_START = 0;
4060
4560
  var NOTICE_PREFIX = "josh-density-notice-";
4061
4561
  var NEVER_MS = 0;
4062
- var payload_schema = z6.object({
4063
- transcript_path: z6.string().min(1).optional(),
4562
+ var payload_schema = z8.object({
4563
+ transcript_path: z8.string().min(1).optional(),
4064
4564
  // **`nullish`, not `optional`.** A payload spelling the absent agent as `null` has to read as "no
4065
4565
  // fork"; rejected, it would fail `safeParse` for the whole payload and silence the line for every
4066
4566
  // edit of the main line — the opposite of this module's stated failure direction.
4067
- agent_id: z6.string().nullish()
4567
+ agent_id: z8.string().nullish()
4068
4568
  });
4069
- var notice_schema = z6.object({ notified_at_ms: z6.number() });
4070
- var call_schema = z6.object({ tool_name: z6.string().min(1), tool_input: z6.unknown() });
4569
+ var notice_schema = z8.object({ notified_at_ms: z8.number() });
4570
+ var call_schema = z8.object({ tool_name: z8.string().min(1), tool_input: z8.unknown() });
4071
4571
  function parse_transcript_path(raw_payload) {
4072
4572
  const parsed = payload_schema.safeParse(JSON.parse(raw_payload));
4073
4573
  if (!parsed.success || parsed.data.transcript_path === void 0) return void 0;
@@ -4134,12 +4634,11 @@ var time_density_hook = {
4134
4634
  };
4135
4635
 
4136
4636
  export {
4137
- PROJECT_ROOT,
4138
- PLATFORM_TEMP_ROOT,
4139
- stamp_file,
4140
4637
  json_value,
4141
4638
  cost_blocks,
4142
4639
  ESLINT_EDIT_CACHE_FLAGS,
4640
+ process_identity,
4641
+ process_owner_schema,
4143
4642
  time_shell,
4144
4643
  time_bundle_call,
4145
4644
  blocking_issue_schema,
@@ -4156,8 +4655,8 @@ export {
4156
4655
  evaluate_pr_state,
4157
4656
  is_review_decision_decisive,
4158
4657
  PrConflictError,
4159
- cost_attribute,
4160
4658
  time_reported_failure,
4659
+ cost_attribute,
4161
4660
  time_transcript_line,
4162
4661
  time_spans,
4163
4662
  time_batch_guard,