@joshuafolkken/kit 1.1784.0 → 1.2116.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 (690) hide show
  1. package/.claude/agents/reviewer-verification.md +19 -0
  2. package/.claude/agents/reviewer.md +19 -0
  3. package/.claude/settings.json +5 -6
  4. package/.claude/skills/dependency-update/SKILL.md +9 -10
  5. package/.claude/skills/workflow-commands/SKILL.md +6 -6
  6. package/.claude/skills/workflow-commands/background-commands.md +8 -5
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
  11. package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
  12. package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
  13. package/.claude/skills/workflow-commands/backlogrun.md +1 -1
  14. package/.claude/skills/workflow-commands/chain-rule.md +41 -32
  15. package/.claude/skills/workflow-commands/delegation.md +6 -6
  16. package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
  17. package/.claude/skills/workflow-commands/followup.md +7 -5
  18. package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
  19. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  20. package/.claude/skills/workflow-commands/issue-comments.md +9 -4
  21. package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
  22. package/.claude/skills/workflow-commands/kickoff.md +2 -2
  23. package/.claude/skills/workflow-commands/observation-filing.md +1 -1
  24. package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
  25. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
  26. package/.claude/skills/workflow-commands/prerequisite.md +3 -2
  27. package/.claude/skills/workflow-commands/retrospective.md +2 -2
  28. package/.claude/skills/workflow-commands/split-assessment.md +7 -5
  29. package/.codex/hooks.json +5 -5
  30. package/.github/actions/setup-pnpm/action.yml +9 -16
  31. package/.github/dependabot.yml +16 -0
  32. package/.github/workflows/auto-tag.yml +45 -0
  33. package/.github/workflows/ci.yml +155 -15
  34. package/.github/workflows/dependabot-auto-merge.yml +63 -4
  35. package/.github/workflows/production.yml +8 -0
  36. package/.github/workflows/publish.yml +60 -45
  37. package/.vscode/settings.json +19 -0
  38. package/CLAUDE.md +5 -12
  39. package/SECURITY.md +2 -2
  40. package/dist/CLAUDE.md +5 -12
  41. package/dist/commands/document-read-cli.js +2 -1
  42. package/dist/commands/document-section-main.js +2 -1
  43. package/dist/commands/read-set-cli.js +194 -134
  44. package/dist/commands/run-prep-main.js +9694 -10173
  45. package/dist/commands/run-step-cli.js +22138 -18285
  46. package/dist/hooks/audit-provision.js +23 -5
  47. package/dist/hooks/chunk-3GKE653K.js +6204 -0
  48. package/dist/hooks/chunk-45CJJOO7.js +1243 -0
  49. package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
  50. package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
  51. package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
  52. package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
  53. package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
  54. package/dist/hooks/chunk-VVNYJWEI.js +30 -0
  55. package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
  56. package/dist/hooks/codex-hook-adapter.js +8 -8
  57. package/dist/hooks/format-edited.js +4 -5
  58. package/dist/hooks/inputs.json +386 -360
  59. package/dist/hooks/pretool-guard.js +7 -6
  60. package/dist/hooks/session-lang.js +101 -258
  61. package/dist/hooks/stop-guard.js +1744 -2576
  62. package/dist/josh.js +7133 -6368
  63. package/dist/version/index.js +161 -1
  64. package/eslint/rules/comment-why-only.js +108 -0
  65. package/package.json +16 -9
  66. package/prompts/coding-standards.md +1 -1
  67. package/prompts/collaboration-workflow/file-edits.md +14 -11
  68. package/prompts/collaboration-workflow/issue-citation.md +0 -4
  69. package/prompts/collaboration-workflow/issue-template.md +40 -21
  70. package/prompts/collaboration-workflow/lane-instructions.md +3 -1
  71. package/prompts/collaboration-workflow/measurement.md +8 -1
  72. package/prompts/collaboration-workflow/operating-rules.md +11 -2
  73. package/prompts/collaboration-workflow/output-bounds.md +6 -2
  74. package/prompts/collaboration-workflow/plan-comment.md +1 -1
  75. package/prompts/collaboration-workflow/principles.md +9 -0
  76. package/prompts/collaboration-workflow/residency.md +3 -2
  77. package/prompts/collaboration-workflow/rule-delivery.md +13 -1
  78. package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
  79. package/prompts/collaboration-workflow/wip-cap.md +3 -1
  80. package/prompts/review-rubric.md +8 -0
  81. package/prompts/review.md +31 -22
  82. package/prompts/testing-guide.md +1 -0
  83. package/scripts/agent/agent-argv.ts +14 -16
  84. package/scripts/agent/agent-provider.ts +138 -0
  85. package/scripts/agent/agent-role-profile.ts +108 -156
  86. package/scripts/agent/agent-safe-text.ts +20 -5
  87. package/scripts/agent/api-usage-limit.ts +65 -0
  88. package/scripts/agent/claude-agent-argv.ts +19 -9
  89. package/scripts/agent/codex-agent-argv.ts +118 -22
  90. package/scripts/agent/usage-limit-reset.ts +179 -0
  91. package/scripts/auth/claude-token-output.ts +2 -2
  92. package/scripts/auto-ok/auto-ok-author.ts +53 -0
  93. package/scripts/auto-ok/auto-ok-cli.ts +20 -9
  94. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  95. package/scripts/backlog/backlog-drive-cli.ts +6 -1
  96. package/scripts/backlog/backlog-drive-hold.ts +3 -3
  97. package/scripts/backlog/backlog-drive-idle.ts +10 -0
  98. package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
  99. package/scripts/backlog/backlog-drive-launch.ts +8 -2
  100. package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
  101. package/scripts/backlog/backlog-drive-named.ts +28 -7
  102. package/scripts/backlog/backlog-drive-paused.ts +5 -4
  103. package/scripts/backlog/backlog-drive-restore.ts +11 -3
  104. package/scripts/backlog/backlog-drive.ts +21 -60
  105. package/scripts/backlog/backlog-gate-scope.ts +61 -0
  106. package/scripts/backlog/backlog-measure-close.ts +112 -0
  107. package/scripts/backlog/backlog-next.ts +39 -49
  108. package/scripts/backlog/backlog-occupied.ts +2 -2
  109. package/scripts/backlog/backlog-overlap.ts +42 -8
  110. package/scripts/backlog/backlog-plan-cli.ts +4 -1
  111. package/scripts/backlog/backlog-plan-comment.ts +81 -0
  112. package/scripts/backlog/backlog-plan-read.ts +19 -6
  113. package/scripts/backlog/backlog-pool.ts +50 -12
  114. package/scripts/backlog/backlog-rank.ts +60 -13
  115. package/scripts/backlog/backlog-stalled-detect.ts +2 -1
  116. package/scripts/backlog/backlog-waves.ts +17 -2
  117. package/scripts/backlog/backlogrun-launch.ts +7 -4
  118. package/scripts/cost-runtime/context-cut-payback.ts +27 -25
  119. package/scripts/cost-runtime/cost-cli.ts +37 -16
  120. package/scripts/cost-runtime/cost-pricing.ts +9 -0
  121. package/scripts/cost-runtime/cost-verdict.ts +4 -1
  122. package/scripts/delegation/delegation-policy.ts +2 -2
  123. package/scripts/delegation/duplicate-read-guard.ts +1 -0
  124. package/scripts/delegation/investigation-guard.ts +14 -2
  125. package/scripts/delegation/investigation-reads.ts +45 -23
  126. package/scripts/dependabot/dependabot-cooldown.ts +3 -2
  127. package/scripts/discovery/repo-party.ts +80 -20
  128. package/scripts/discovery/session-owner-pin.ts +51 -0
  129. package/scripts/document/capped-print.ts +1 -1
  130. package/scripts/document/command-reference-line-budget.ts +42 -0
  131. package/scripts/document/document-byte-budget.ts +17 -7
  132. package/scripts/document/document-checks.ts +20 -0
  133. package/scripts/document/document-ratchet-check.ts +101 -0
  134. package/scripts/document/document-section.ts +1 -0
  135. package/scripts/document/entry-read-budget.ts +7 -3
  136. package/scripts/document/issue-citation-budget.ts +94 -0
  137. package/scripts/epic/epic-cli-argv.ts +2 -2
  138. package/scripts/epic/epic-fetch.ts +4 -2
  139. package/scripts/epic/epic-graph.ts +7 -2
  140. package/scripts/epic/epic-issue.ts +3 -1
  141. package/scripts/epic/epic-rank.ts +5 -0
  142. package/scripts/exports/unused-members-check.ts +62 -0
  143. package/scripts/exports/unused-members-cli.ts +6 -51
  144. package/scripts/followup/followup-ci-path.ts +67 -0
  145. package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
  146. package/scripts/followup/followup-coderabbit-wait.ts +13 -10
  147. package/scripts/followup/followup-failed-tests.ts +160 -0
  148. package/scripts/followup/followup-job-needs.ts +100 -0
  149. package/scripts/followup/followup-job-rerun.ts +303 -0
  150. package/scripts/followup/followup-main-move.ts +113 -0
  151. package/scripts/followup/git-followup-finish.ts +43 -11
  152. package/scripts/followup/git-followup-pending.ts +3 -3
  153. package/scripts/followup/git-followup-stages.ts +41 -11
  154. package/scripts/followup/git-pr-followup-checks.ts +55 -16
  155. package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
  156. package/scripts/followup/git-pr-followup.ts +62 -27
  157. package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
  158. package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
  159. package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
  160. package/scripts/gate/busy-average.ts +34 -2
  161. package/scripts/gate/check-related-pinned.ts +43 -0
  162. package/scripts/gate/check-related-reuse.ts +64 -0
  163. package/scripts/gate/check-related-section.ts +57 -0
  164. package/scripts/gate/check-related-unplanned.ts +34 -0
  165. package/scripts/gate/check-related.ts +265 -0
  166. package/scripts/gate/command-memory.ts +1 -1
  167. package/scripts/gate/core-admission.ts +24 -6
  168. package/scripts/gate/core-budget-timing.ts +20 -6
  169. package/scripts/gate/core-budget.ts +40 -11
  170. package/scripts/gate/core-wait-record.ts +3 -2
  171. package/scripts/gate/core-wait.ts +25 -2
  172. package/scripts/gate/core-weights.ts +15 -7
  173. package/scripts/gate/gate-labels.ts +46 -0
  174. package/scripts/gate/gate-ledger.ts +14 -6
  175. package/scripts/gate/gate-plan.ts +103 -58
  176. package/scripts/gate/gate-report.ts +9 -7
  177. package/scripts/gate/gate-run-steps.ts +26 -3
  178. package/scripts/gate/gate-skip.ts +45 -6
  179. package/scripts/gate/gate-static-group.ts +60 -0
  180. package/scripts/gate/gate-steps.ts +2 -1
  181. package/scripts/gate/gate-tree.ts +4 -2
  182. package/scripts/gate/hook-gate-reuse.ts +19 -2
  183. package/scripts/gate/metrics-totals.ts +59 -0
  184. package/scripts/gate/scoped-green.ts +68 -15
  185. package/scripts/gate/since-green.ts +14 -6
  186. package/scripts/gate/structural-checks.ts +96 -0
  187. package/scripts/gate/verification-gate.ts +51 -16
  188. package/scripts/gate/verification-inputs.ts +21 -6
  189. package/scripts/gate/verification-tail.ts +52 -0
  190. package/scripts/gh/gh-author-association.ts +23 -2
  191. package/scripts/gh/git-ai-review-scan.ts +1 -1
  192. package/scripts/gh/git-gh-api-path.ts +12 -3
  193. package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
  194. package/scripts/gh/git-gh-exec.ts +32 -2
  195. package/scripts/gh/git-gh-issue-read.ts +4 -2
  196. package/scripts/gh/git-gh-issue-rest.ts +1 -0
  197. package/scripts/gh/git-gh-issue-write.ts +8 -2
  198. package/scripts/gh/git-gh-issue.ts +12 -5
  199. package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
  200. package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
  201. package/scripts/gh/git-gh-pr-read.ts +74 -13
  202. package/scripts/gh/git-gh-pr-rest.ts +3 -1
  203. package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
  204. package/scripts/gh/git-gh-pr-too-large.ts +20 -0
  205. package/scripts/gh/git-gh-pr.ts +21 -7
  206. package/scripts/gh/git-gh-retry.ts +141 -0
  207. package/scripts/gh/git-pr-ai-review.ts +15 -6
  208. package/scripts/gh/git-pr-checks-eval.ts +3 -0
  209. package/scripts/gh/git-pr-checks.ts +5 -5
  210. package/scripts/git/base-tree.ts +30 -0
  211. package/scripts/git/change-base.ts +4 -10
  212. package/scripts/git/changed-paths-sync.ts +63 -0
  213. package/scripts/git/changed-paths.ts +16 -1
  214. package/scripts/git/git-common-directory.ts +11 -1
  215. package/scripts/git/git-diff-reads.ts +66 -20
  216. package/scripts/git/git-error.ts +9 -2
  217. package/scripts/git/git-schemas.ts +13 -0
  218. package/scripts/git/git-worktree.ts +13 -0
  219. package/scripts/git/gone-branch.ts +4 -1
  220. package/scripts/git/main-merge-budget-conflict.ts +89 -0
  221. package/scripts/git/main-merge-guard.ts +55 -18
  222. package/scripts/git/main-merge-regenerate.ts +59 -25
  223. package/scripts/git/main-merge.ts +53 -5
  224. package/scripts/git/no-base-checkout.ts +127 -0
  225. package/scripts/git/stash/git-stash.ts +11 -2
  226. package/scripts/git/stash/stash-push-cli.ts +10 -0
  227. package/scripts/hooks/batch-guard.ts +40 -21
  228. package/scripts/hooks/edited-cspell.ts +37 -11
  229. package/scripts/hooks/format-edited-file.ts +22 -2
  230. package/scripts/hooks/lane-plan-guard.ts +50 -0
  231. package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
  232. package/scripts/hooks/pre-commit-lint.ts +14 -1
  233. package/scripts/hooks/pre-push-related-switch.ts +10 -0
  234. package/scripts/hooks/pre-push-unit.ts +76 -10
  235. package/scripts/hooks/pretool-guard.ts +2 -0
  236. package/scripts/hooks/reserved-run.ts +14 -1
  237. package/scripts/hooks/run-hook.sh +23 -8
  238. package/scripts/hooks/step-zero-notice.ts +6 -1
  239. package/scripts/hooks/stop-actions.ts +3 -15
  240. package/scripts/hooks/stop-guard.ts +7 -6
  241. package/scripts/init/distributed-paths.ts +1 -0
  242. package/scripts/init/hook-command-rewrite.ts +5 -1
  243. package/scripts/init/hook-launch.ts +4 -2
  244. package/scripts/issue/aggregation-split.ts +52 -0
  245. package/scripts/issue/defect-origin-line.ts +19 -1
  246. package/scripts/issue/defect-rate-cli.ts +5 -102
  247. package/scripts/issue/defect-report.ts +4 -4
  248. package/scripts/issue/effect-audit-cli.ts +178 -0
  249. package/scripts/issue/effect-audit.ts +185 -0
  250. package/scripts/issue/expected-effect-lint.ts +64 -9
  251. package/scripts/issue/git-next-issues.ts +5 -0
  252. package/scripts/issue/issue-body-or-comment.ts +38 -4
  253. package/scripts/issue/issue-cite-cli.ts +1 -3
  254. package/scripts/issue/issue-classification.ts +1 -0
  255. package/scripts/issue/issue-closing-pr.ts +8 -1
  256. package/scripts/issue/issue-evidence-exit.ts +4 -2
  257. package/scripts/issue/issue-file-cap.ts +58 -0
  258. package/scripts/issue/issue-file-cli.ts +111 -38
  259. package/scripts/issue/issue-file-deferral.ts +52 -0
  260. package/scripts/issue/issue-file-fold.ts +29 -10
  261. package/scripts/issue/issue-file-interrupt.ts +85 -0
  262. package/scripts/issue/issue-file-lane-hint.ts +30 -0
  263. package/scripts/issue/issue-file.ts +43 -6
  264. package/scripts/issue/issue-labels.ts +19 -2
  265. package/scripts/issue/issue-lint-cli.ts +27 -2
  266. package/scripts/issue/issue-measured-cli.ts +13 -35
  267. package/scripts/issue/issue-measured-close.ts +58 -0
  268. package/scripts/issue/issue-not-before-label.ts +2 -2
  269. package/scripts/issue/issue-not-before.ts +4 -1
  270. package/scripts/issue/issue-priority-cli.ts +60 -0
  271. package/scripts/issue/issue-priority-raise.ts +55 -0
  272. package/scripts/issue/issue-priority.ts +174 -43
  273. package/scripts/issue/issue-rank.ts +21 -4
  274. package/scripts/issue/issue-read-cli.ts +32 -6
  275. package/scripts/issue/issue-read.ts +37 -12
  276. package/scripts/issue/issue-sample-gate.ts +95 -74
  277. package/scripts/issue/issue-sample-prime.ts +127 -0
  278. package/scripts/issue/issue-sample-required.ts +57 -0
  279. package/scripts/issue/issue-sample-source.ts +12 -11
  280. package/scripts/issue/issue-search.ts +124 -0
  281. package/scripts/issue/issue-state.ts +13 -1
  282. package/scripts/issue/issue-template-section.ts +43 -0
  283. package/scripts/issue/issue-watch-diff.ts +31 -1
  284. package/scripts/issue/issue-watch-hook.ts +11 -2
  285. package/scripts/issue/issue-watch.ts +55 -12
  286. package/scripts/issue/markdown-section.ts +1 -0
  287. package/scripts/issue/measure-declaration.ts +121 -0
  288. package/scripts/issue/measure-rerun-cli.ts +7 -70
  289. package/scripts/issue/plan-consumers-section.ts +22 -1
  290. package/scripts/issue/reproduction-measure.ts +3 -1
  291. package/scripts/issue/size-estimate.ts +90 -0
  292. package/scripts/issue/trusted-measure.ts +84 -0
  293. package/scripts/josh/command-usage.ts +3 -2
  294. package/scripts/josh/durable-state-migrate.ts +105 -0
  295. package/scripts/josh/durable-state.ts +112 -0
  296. package/scripts/josh/josh-aliases.ts +95 -0
  297. package/scripts/josh/josh-command-map.ts +1 -82
  298. package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
  299. package/scripts/josh/josh-commands-ai.ts +5 -5
  300. package/scripts/josh/josh-commands-development.ts +59 -58
  301. package/scripts/josh/josh-commands-issue-write.ts +23 -4
  302. package/scripts/josh/josh-commands-issue.ts +32 -0
  303. package/scripts/josh/josh-commands-lane.ts +87 -4
  304. package/scripts/josh/josh-commands-lint.ts +16 -3
  305. package/scripts/josh/josh-commands-maintenance.ts +15 -0
  306. package/scripts/josh/josh-commands-review.ts +41 -6
  307. package/scripts/josh/josh-commands-ship.ts +56 -8
  308. package/scripts/josh/josh-commands-test-check.ts +80 -0
  309. package/scripts/josh/josh-commands-workflow.ts +1 -1
  310. package/scripts/josh/josh-environment-file.ts +43 -3
  311. package/scripts/josh/josh-in-process.ts +2 -2
  312. package/scripts/josh/josh-logic.ts +5 -3
  313. package/scripts/josh/josh-run.ts +19 -1
  314. package/scripts/josh/run-record-path.ts +15 -0
  315. package/scripts/josh/stamp-file.ts +11 -2
  316. package/scripts/lane/lane-adopt-cli.ts +98 -0
  317. package/scripts/lane/lane-adopt.ts +208 -0
  318. package/scripts/lane/lane-await.ts +5 -8
  319. package/scripts/lane/lane-baseline.ts +123 -0
  320. package/scripts/lane/lane-breakdown-cli.ts +64 -0
  321. package/scripts/lane/lane-breakdown-implement.ts +170 -0
  322. package/scripts/lane/lane-breakdown-laps.ts +107 -0
  323. package/scripts/lane/lane-breakdown-pinned.ts +76 -0
  324. package/scripts/lane/lane-breakdown-text.ts +145 -0
  325. package/scripts/lane/lane-breakdown.ts +239 -0
  326. package/scripts/lane/lane-check-stats.ts +29 -8
  327. package/scripts/lane/lane-child-invocation.ts +9 -2
  328. package/scripts/lane/lane-child-mark-keys.ts +12 -0
  329. package/scripts/lane/lane-child-marker.ts +20 -1
  330. package/scripts/lane/lane-ci-path-stats.ts +73 -0
  331. package/scripts/lane/lane-claim-stats.ts +84 -0
  332. package/scripts/lane/lane-close.ts +8 -3
  333. package/scripts/lane/lane-dispatch-log.ts +3 -3
  334. package/scripts/lane/lane-dispatch.ts +2 -2
  335. package/scripts/lane/lane-gap-stats.ts +7 -6
  336. package/scripts/lane/lane-guard-policy.ts +7 -1
  337. package/scripts/lane/lane-implement-stats.ts +207 -0
  338. package/scripts/lane/lane-implement-subagents.ts +90 -0
  339. package/scripts/lane/lane-investigation-switch.ts +16 -0
  340. package/scripts/lane/lane-ledger-kind.ts +31 -0
  341. package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
  342. package/scripts/lane/lane-ledger-schema.ts +119 -36
  343. package/scripts/lane/lane-ledger-write.ts +257 -0
  344. package/scripts/lane/lane-ledger.ts +31 -177
  345. package/scripts/lane/lane-load.ts +1 -1
  346. package/scripts/lane/lane-measure-cli.ts +176 -59
  347. package/scripts/lane/lane-net-read.ts +44 -0
  348. package/scripts/lane/lane-net-time.ts +212 -0
  349. package/scripts/lane/lane-open.ts +16 -7
  350. package/scripts/lane/lane-output.ts +2 -4
  351. package/scripts/lane/lane-overrun-prompt.ts +147 -0
  352. package/scripts/lane/lane-overrun.ts +274 -0
  353. package/scripts/lane/lane-paths.ts +24 -1
  354. package/scripts/lane/lane-pause-cli.ts +4 -1
  355. package/scripts/lane/lane-paused-spans.ts +97 -0
  356. package/scripts/lane/lane-plan-check.ts +207 -0
  357. package/scripts/lane/lane-plan-cli.ts +41 -0
  358. package/scripts/lane/lane-plan.ts +144 -0
  359. package/scripts/lane/lane-registry.ts +14 -1
  360. package/scripts/lane/lane-relaunch.ts +1 -1
  361. package/scripts/lane/lane-round-one-stats.ts +51 -0
  362. package/scripts/lane/lane-sampler.ts +23 -4
  363. package/scripts/lane/lane-session-action.ts +93 -18
  364. package/scripts/lane/lane-session-broker.ts +49 -21
  365. package/scripts/lane/lane-session-reread-main.ts +14 -0
  366. package/scripts/lane/lane-session-reread.ts +51 -0
  367. package/scripts/lane/lane-ship-lap-stats.ts +74 -0
  368. package/scripts/lane/lane-sleep.ts +58 -0
  369. package/scripts/lane/lane-spent.ts +1 -1
  370. package/scripts/lane/lane-split-stats.ts +28 -0
  371. package/scripts/lane/lane-stage-stats.ts +13 -1
  372. package/scripts/lane/lane-state.ts +41 -9
  373. package/scripts/lane/lane-stats-tables.ts +58 -0
  374. package/scripts/lane/lane-stats.ts +21 -5
  375. package/scripts/lane/lane-stop-stats.ts +51 -19
  376. package/scripts/lane/lane-tail-stats.ts +32 -0
  377. package/scripts/lane/lane-transcript-calls.ts +67 -10
  378. package/scripts/lane/lane-transcript-stats.ts +44 -12
  379. package/scripts/lane/lane-value-cell.ts +72 -0
  380. package/scripts/lane/lane-value.ts +118 -0
  381. package/scripts/lane/lane-withdraw-closed.ts +124 -0
  382. package/scripts/lane/lane-withdraw.ts +108 -31
  383. package/scripts/lane/lane-yield.ts +85 -0
  384. package/scripts/lane/openai-lane-ship.ts +12 -11
  385. package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
  386. package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
  387. package/scripts/lane/openai-lane-supervisor.ts +5 -4
  388. package/scripts/lib/poll.ts +38 -9
  389. package/scripts/lib/settled-together.ts +10 -0
  390. package/scripts/lib/shell-quote.ts +21 -0
  391. package/scripts/lib/token-shape.ts +111 -0
  392. package/scripts/lint/eslint-daemon-sources.ts +79 -0
  393. package/scripts/lint/eslint-daemon.ts +45 -6
  394. package/scripts/lint/eslint-warm-cli.ts +7 -0
  395. package/scripts/lint/eslint-warm.ts +66 -0
  396. package/scripts/lint/import-graph.ts +141 -11
  397. package/scripts/lint/lint-gate-scope.ts +2 -2
  398. package/scripts/lint/lint-parallel.ts +54 -6
  399. package/scripts/lint/lint-related.ts +154 -33
  400. package/scripts/lint/rename-cli.ts +179 -0
  401. package/scripts/lint/rename-identifier.ts +192 -0
  402. package/scripts/lint/type-only-imports.ts +58 -0
  403. package/scripts/notify/telegram-notify.ts +12 -3
  404. package/scripts/observations/observation-record.ts +42 -16
  405. package/scripts/observations/observations-flush.ts +32 -9
  406. package/scripts/overrides/overrides-check.ts +9 -1
  407. package/scripts/release/release-approval-prune.ts +7 -1
  408. package/scripts/repo/required-checks-logic.ts +4 -1
  409. package/scripts/repo/ruleset-check.ts +4 -3
  410. package/scripts/report/markdown-shape.ts +28 -0
  411. package/scripts/report/report-format-reference.ts +15 -1
  412. package/scripts/report/report-labels.ts +12 -1
  413. package/scripts/report/report-lint-child-summary.ts +94 -0
  414. package/scripts/report/report-lint-cli.ts +26 -7
  415. package/scripts/report/report-lint.ts +2 -20
  416. package/scripts/review/prose-stale-cli.ts +88 -0
  417. package/scripts/review/prose-stale-scan.ts +152 -0
  418. package/scripts/review/review-attest.ts +73 -23
  419. package/scripts/review/review-brief-cli.ts +68 -19
  420. package/scripts/review/review-brief-paths.ts +22 -0
  421. package/scripts/review/review-brief.ts +14 -7
  422. package/scripts/review/review-comment-carry.ts +47 -0
  423. package/scripts/review/review-comment-round.ts +85 -22
  424. package/scripts/review/review-finding-ledger.ts +109 -7
  425. package/scripts/review/review-finding-text.ts +43 -0
  426. package/scripts/review/review-interaction.ts +11 -0
  427. package/scripts/review/review-lane-handover.ts +68 -0
  428. package/scripts/review/review-lint-cli.ts +57 -0
  429. package/scripts/review/review-lint-findings.ts +92 -0
  430. package/scripts/review/review-lint-sections.ts +80 -0
  431. package/scripts/review/review-lint.ts +221 -0
  432. package/scripts/review/review-prior-findings.ts +102 -0
  433. package/scripts/review/review-readers-scan.ts +4 -2
  434. package/scripts/review/review-record-cli.ts +177 -54
  435. package/scripts/review/review-record-code-round.ts +55 -0
  436. package/scripts/review/review-record-comment.ts +60 -0
  437. package/scripts/review/review-record-interaction.ts +35 -0
  438. package/scripts/review/review-record-pinned.ts +108 -0
  439. package/scripts/review/review-record.ts +25 -1
  440. package/scripts/review/review-reviewed-tree.ts +307 -0
  441. package/scripts/review/review-round-one-closure.ts +62 -0
  442. package/scripts/review/review-round-reuse.ts +106 -0
  443. package/scripts/review/review-round2-cli.ts +91 -29
  444. package/scripts/review/review-round2-skip-comment.ts +55 -0
  445. package/scripts/review/review-round2.ts +24 -8
  446. package/scripts/review/review-stamps.ts +7 -3
  447. package/scripts/review/review-stop-log.ts +20 -6
  448. package/scripts/review/review-stops-cli.ts +2 -1
  449. package/scripts/review/review-submit-cli.ts +101 -0
  450. package/scripts/rules/agent-model.ts +1 -1
  451. package/scripts/rules/bash-triggers.ts +3 -3
  452. package/scripts/rules/concise-reply.ts +88 -0
  453. package/scripts/rules/credential-body.ts +77 -0
  454. package/scripts/rules/decision-oracle.ts +1 -1
  455. package/scripts/rules/delivered-rules.ts +36 -17
  456. package/scripts/rules/destructive-command.ts +3 -11
  457. package/scripts/rules/direct-issue-comment.ts +34 -12
  458. package/scripts/rules/direct-issue-read.ts +191 -0
  459. package/scripts/rules/direct-pr-create.ts +4 -24
  460. package/scripts/rules/early-heartbeat.ts +2 -0
  461. package/scripts/rules/edit-tool.ts +27 -0
  462. package/scripts/rules/file-edit-rows.ts +17 -0
  463. package/scripts/rules/file-rewrite.ts +146 -0
  464. package/scripts/rules/firing-point.ts +3 -2
  465. package/scripts/rules/gh-api.ts +128 -7
  466. package/scripts/rules/gh-repo-selector.ts +84 -0
  467. package/scripts/rules/git-force.ts +2 -2
  468. package/scripts/rules/guard-remedy.ts +14 -5
  469. package/scripts/rules/implementation-cut.ts +61 -28
  470. package/scripts/rules/investigator-foreground.ts +231 -0
  471. package/scripts/rules/issue-citation.ts +15 -60
  472. package/scripts/rules/issue-comments.ts +9 -4
  473. package/scripts/rules/josh-git-bare.ts +1 -1
  474. package/scripts/rules/lane-background.ts +41 -13
  475. package/scripts/rules/lane-direct-tool.ts +107 -9
  476. package/scripts/rules/lane-interactive-ask.ts +4 -1
  477. package/scripts/rules/lane-park.ts +4 -2
  478. package/scripts/rules/lane-spilled-read.ts +90 -0
  479. package/scripts/rules/lane-split-park.ts +1 -1
  480. package/scripts/rules/lane-switch-main.ts +4 -4
  481. package/scripts/rules/last-prompt.ts +20 -47
  482. package/scripts/rules/oracle-consulted.ts +1 -1
  483. package/scripts/rules/permission-guards.ts +5 -1
  484. package/scripts/rules/piped-verification-shapes.ts +110 -0
  485. package/scripts/rules/piped-verification.ts +67 -17
  486. package/scripts/rules/poll-loop.ts +72 -9
  487. package/scripts/rules/pr-merge.ts +5 -5
  488. package/scripts/rules/pre-gate-cut.ts +3 -3
  489. package/scripts/rules/protected-files.ts +88 -24
  490. package/scripts/rules/reply-language.ts +3 -17
  491. package/scripts/rules/reply-prose.ts +34 -0
  492. package/scripts/rules/repo-admin.ts +132 -0
  493. package/scripts/rules/reviewer-foreground.ts +88 -0
  494. package/scripts/rules/round-one-check-related.ts +120 -0
  495. package/scripts/rules/rule-body-guard.ts +5 -15
  496. package/scripts/rules/rule-value-cache.ts +53 -5
  497. package/scripts/rules/rule-value-candidates.ts +84 -0
  498. package/scripts/rules/rule-value-cli.ts +59 -11
  499. package/scripts/rules/rule-value.ts +17 -4
  500. package/scripts/rules/run-tail-rule.ts +1 -1
  501. package/scripts/rules/sed-in-place.ts +196 -0
  502. package/scripts/rules/shell-segments.ts +10 -2
  503. package/scripts/rules/stop-rule-rows.ts +1 -13
  504. package/scripts/rules/stop-rules.ts +33 -58
  505. package/scripts/rules/test-declared-commit.ts +1 -1
  506. package/scripts/rules/third-party-write.ts +110 -23
  507. package/scripts/rules/timed-rerun.ts +1 -1
  508. package/scripts/rules/turn-filings.ts +90 -0
  509. package/scripts/rules/worktree-guard.ts +22 -7
  510. package/scripts/run/board/run-board-ending-reason.ts +6 -2
  511. package/scripts/run/board/run-board-fit.ts +24 -1
  512. package/scripts/run/board/run-board-found.ts +134 -0
  513. package/scripts/run/board/run-board-header.ts +8 -0
  514. package/scripts/run/board/run-board-labels.ts +11 -1
  515. package/scripts/run/board/run-board-lane-time.ts +1 -0
  516. package/scripts/run/board/run-board-link.ts +15 -2
  517. package/scripts/run/board/run-board-notes.ts +7 -1
  518. package/scripts/run/board/run-board-operation.ts +4 -2
  519. package/scripts/run/board/run-board-phase.ts +2 -5
  520. package/scripts/run/board/run-board-plan.ts +1 -1
  521. package/scripts/run/board/run-board-read.ts +46 -1
  522. package/scripts/run/board/run-board-reason.ts +20 -8
  523. package/scripts/run/board/run-board-render-checks.ts +3 -2
  524. package/scripts/run/board/run-board-render-drawn.ts +11 -0
  525. package/scripts/run/board/run-board-render-found.ts +157 -0
  526. package/scripts/run/board/run-board-render-lead.ts +9 -0
  527. package/scripts/run/board/run-board-render-legend.ts +19 -0
  528. package/scripts/run/board/run-board-render-tail.ts +1 -1
  529. package/scripts/run/board/run-board-render.ts +82 -18
  530. package/scripts/run/board/run-board-spin.ts +1 -3
  531. package/scripts/run/board/run-board-status.ts +2 -0
  532. package/scripts/run/board/run-board-tick.ts +39 -10
  533. package/scripts/run/carry/run-carry-ended.ts +3 -2
  534. package/scripts/run/carry/run-carry.ts +3 -2
  535. package/scripts/run/cut/run-cut-cli.ts +33 -133
  536. package/scripts/run/cut/run-cut-digest.ts +152 -0
  537. package/scripts/run/cut/run-cut-handoff.ts +52 -8
  538. package/scripts/run/cut/run-cut-report.ts +24 -3
  539. package/scripts/run/cut/run-cut-resume.ts +129 -0
  540. package/scripts/run/cut/run-cut-review.ts +105 -0
  541. package/scripts/run/cut/run-cut.ts +18 -7
  542. package/scripts/run/detached-launch.ts +1 -1
  543. package/scripts/run/entry/run-entry-cli.ts +88 -19
  544. package/scripts/run/entry/run-entry-spill.ts +83 -0
  545. package/scripts/run/entry/run-entry-stop.ts +5 -1
  546. package/scripts/run/entry/run-entry-trust.ts +91 -0
  547. package/scripts/run/event/run-event-baseline.ts +56 -0
  548. package/scripts/run/event/run-event-filed.ts +9 -3
  549. package/scripts/run/event/run-event-overrun.ts +197 -0
  550. package/scripts/run/event/run-event-render.ts +4 -0
  551. package/scripts/run/event/run-event-stream.ts +25 -3
  552. package/scripts/run/hold/run-stop-notify.ts +3 -8
  553. package/scripts/run/merge/run-merge-cap.ts +57 -0
  554. package/scripts/run/merge/run-merge-cli.ts +66 -23
  555. package/scripts/run/merge/run-merge-outcome.ts +2 -0
  556. package/scripts/run/merge/run-merge-ship.ts +13 -3
  557. package/scripts/run/merge/run-merge-signals.ts +40 -23
  558. package/scripts/run/merge/run-merge-steps.ts +56 -36
  559. package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
  560. package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
  561. package/scripts/run/merge/run-merge.ts +41 -14
  562. package/scripts/run/review/run-review-cli.ts +306 -20
  563. package/scripts/run/review/run-review-early-push.ts +121 -0
  564. package/scripts/run/review/run-review-join-read.ts +94 -0
  565. package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
  566. package/scripts/run/review/run-review-pinned-join.ts +216 -0
  567. package/scripts/run/review/run-review-pinned-steps.ts +383 -0
  568. package/scripts/run/review/run-review-pinned-tree.ts +37 -0
  569. package/scripts/run/review/run-review-pinned.ts +53 -0
  570. package/scripts/run/review/run-review-steps.ts +70 -34
  571. package/scripts/run/review/run-review.ts +26 -6
  572. package/scripts/run/run-parent-cut-hook.ts +3 -4
  573. package/scripts/run/run-prep.ts +1 -0
  574. package/scripts/run/run-stage-read.ts +2 -6
  575. package/scripts/run/run-step-cli.ts +17 -5
  576. package/scripts/run/run-step-lane-plan.ts +27 -0
  577. package/scripts/run/run-step-section.ts +26 -7
  578. package/scripts/run/run-step.ts +5 -2
  579. package/scripts/run/ship/run-ship-args.ts +19 -0
  580. package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
  581. package/scripts/run/ship/run-ship-cli.ts +131 -39
  582. package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
  583. package/scripts/run/ship/run-ship-detach.ts +10 -4
  584. package/scripts/run/ship/run-ship-handover.ts +106 -0
  585. package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
  586. package/scripts/run/ship/run-ship-lap.ts +63 -0
  587. package/scripts/run/ship/run-ship-next.ts +27 -26
  588. package/scripts/run/ship/run-ship-overlap.ts +8 -3
  589. package/scripts/run/ship/run-ship-place.ts +9 -2
  590. package/scripts/run/ship/run-ship-planned.ts +92 -0
  591. package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
  592. package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
  593. package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
  594. package/scripts/run/ship/run-ship-preflight.ts +16 -4
  595. package/scripts/run/ship/run-ship-probe.ts +23 -9
  596. package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
  597. package/scripts/run/ship/run-ship-relaunch.ts +51 -0
  598. package/scripts/run/ship/run-ship-return.ts +103 -29
  599. package/scripts/run/ship/run-ship-review-reason.ts +24 -0
  600. package/scripts/run/ship/run-ship-review-steps.ts +230 -59
  601. package/scripts/run/ship/run-ship-review.ts +171 -51
  602. package/scripts/run/ship/run-ship-reviewer.ts +138 -42
  603. package/scripts/run/ship/run-ship-scoped.ts +39 -10
  604. package/scripts/run/ship/run-ship-stage.ts +49 -13
  605. package/scripts/run/ship/run-ship-steps.ts +24 -4
  606. package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
  607. package/scripts/run/ship/run-ship-stop-context.ts +50 -13
  608. package/scripts/run/ship/run-ship-sync.ts +171 -30
  609. package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
  610. package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
  611. package/scripts/run/ship/run-ship-waiter.ts +114 -0
  612. package/scripts/run/ship/run-ship.ts +16 -2
  613. package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
  614. package/scripts/run/wake/run-wake-cli.ts +6 -113
  615. package/scripts/run/wake/run-wake-code.ts +53 -11
  616. package/scripts/run/wake/run-wake-driver.ts +5 -3
  617. package/scripts/run/wake/run-wake-finish.ts +137 -0
  618. package/scripts/run/wake/run-wake-loop.ts +5 -3
  619. package/scripts/run/wake/run-wake-ports.ts +11 -3
  620. package/scripts/run/wake/run-wake-session.ts +2 -0
  621. package/scripts/run/wake/run-wake.ts +3 -2
  622. package/scripts/safe-chain/ci-installer-pin.ts +49 -8
  623. package/scripts/safe-chain/project-config.ts +3 -2
  624. package/scripts/security/secretlint-scan.ts +42 -9
  625. package/scripts/security/security-audit-provision-main.ts +9 -1
  626. package/scripts/security/security-audit-provision.ts +1 -1
  627. package/scripts/security/security-audit.ts +21 -1
  628. package/scripts/security/sonar-file.ts +10 -5
  629. package/scripts/split/split-assess.ts +12 -3
  630. package/scripts/split/split-early-notice.ts +116 -0
  631. package/scripts/split/split-measure.ts +20 -2
  632. package/scripts/split/split-resolution.ts +107 -0
  633. package/scripts/test/direct-importers.ts +185 -0
  634. package/scripts/test/pure-files-entries.ts +83 -0
  635. package/scripts/test/related-heavy-tests.ts +81 -0
  636. package/scripts/test/test-no-base.ts +88 -0
  637. package/scripts/test/test-pinned-cache-logic.ts +363 -0
  638. package/scripts/test/test-pinned-cache.ts +337 -0
  639. package/scripts/test/test-pinned-emit.ts +49 -0
  640. package/scripts/test/test-pinned-functions.ts +116 -0
  641. package/scripts/test/test-pinned-ledger.ts +80 -0
  642. package/scripts/test/test-pinned-logic.ts +208 -20
  643. package/scripts/test/test-pinned-main.ts +84 -18
  644. package/scripts/test/test-pinned-pool.ts +73 -0
  645. package/scripts/test/test-pinned-probe.ts +254 -0
  646. package/scripts/test/test-pinned-prune-logic.ts +118 -0
  647. package/scripts/test/test-pinned-reach.ts +194 -0
  648. package/scripts/test/test-pinned-record.ts +196 -0
  649. package/scripts/test/test-pinned-rewire.ts +148 -0
  650. package/scripts/test/test-pinned-spawn.ts +81 -0
  651. package/scripts/test/test-pinned-stage.ts +70 -0
  652. package/scripts/test/test-pinned.ts +258 -47
  653. package/scripts/test/test-reach-cli.ts +61 -0
  654. package/scripts/test/test-read-map.ts +35 -11
  655. package/scripts/test/test-read-recording.ts +17 -5
  656. package/scripts/test/test-read-trace.ts +26 -8
  657. package/scripts/test/test-red-logic.ts +46 -7
  658. package/scripts/test/test-red.ts +34 -14
  659. package/scripts/test/test-related-claim.ts +37 -0
  660. package/scripts/test/test-related-main.ts +4 -1
  661. package/scripts/test/test-related-moved.ts +91 -0
  662. package/scripts/test/test-related-record.ts +43 -23
  663. package/scripts/test/test-related-scope.ts +99 -34
  664. package/scripts/test/test-related-synced.ts +135 -0
  665. package/scripts/test/test-related-touched.ts +84 -0
  666. package/scripts/test/test-related.ts +167 -83
  667. package/scripts/test/test-unit-guard.ts +28 -5
  668. package/scripts/test/unit-durations.ts +41 -0
  669. package/scripts/test/unit-worker-share.ts +5 -4
  670. package/scripts/test/vitest-cache-directory.ts +19 -0
  671. package/scripts/test/vitest-cli-excludes.ts +14 -0
  672. package/scripts/test/vitest-failure-summary.ts +111 -0
  673. package/scripts/test/whole-suite-files.ts +12 -1
  674. package/scripts/time-runtime/time-batch-guard.ts +42 -4
  675. package/scripts/time-runtime/time-bundle-call.ts +1 -1
  676. package/scripts/time-runtime/time-bundles.ts +36 -5
  677. package/scripts/time-runtime/time-markers.ts +2 -2
  678. package/scripts/time-runtime/time-search-call.ts +38 -0
  679. package/scripts/time-runtime/time-shell.ts +1 -1
  680. package/scripts/time-runtime/time-transcript-line.ts +17 -5
  681. package/scripts/version/development-engines-verdict.ts +124 -0
  682. package/scripts/version/latest-corepack.ts +2 -0
  683. package/templates/gitignore +2 -0
  684. package/templates/workflows/ci.yml +41 -0
  685. package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
  686. package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
  687. package/dist/hooks/chunk-TUIFS5E7.js +0 -72
  688. package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
  689. package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
  690. package/scripts/rules/filing-cap.ts +0 -139
@@ -1,13 +1,15 @@
1
1
  import {
2
- GIT_TIMEOUT_MS,
3
2
  MS_PER_MINUTE,
4
- MS_PER_SECOND,
5
3
  PLATFORM_TEMP_ROOT,
6
4
  PROBE_TIMEOUT_MS,
7
- SUITE_TIMEOUT_MS,
8
5
  error_text,
6
+ git_command,
7
+ git_common_directory,
8
+ platform_temporary,
9
+ repo_discovery,
10
+ repo_origin,
9
11
  stamp_file
10
- } from "./chunk-AZX4FGQ3.js";
12
+ } from "./chunk-45CJJOO7.js";
11
13
 
12
14
  // scripts/lib/json-value.ts
13
15
  function parse_or_undefined(text2) {
@@ -32,661 +34,141 @@ function is_record(value) {
32
34
  }
33
35
  var json_value = { parse_or_undefined, parse_with, parse_array, is_record };
34
36
 
35
- // scripts/git/constants.ts
36
- import { platform } from "node:os";
37
- var GIT_COMMAND_UNIX = "/usr/bin/git";
38
- var PORCELAIN_FLAG = "--porcelain";
39
- var UNTRACKED_FILES_FLAG = "--untracked-files=all";
40
- var GIT_BINARY_KEY = "JOSH_GIT_BINARY";
41
- function get_git_command() {
42
- if (platform() === "win32") return String.raw`"C:\Program Files\Git\cmd\git.exe"`;
43
- return GIT_COMMAND_UNIX;
44
- }
45
- function get_git_command_for_spawn() {
46
- const binary = process.env[GIT_BINARY_KEY];
47
- if (binary !== void 0 && binary !== "") return binary;
48
- if (platform() === "win32") return String.raw`C:\Program Files\Git\cmd\git.exe`;
49
- return GIT_COMMAND_UNIX;
50
- }
51
- var git_utilities = {
52
- get_git_command,
53
- get_git_command_for_spawn
54
- };
55
-
56
- // scripts/git/git-spawn.ts
57
- import { execa as execa3 } from "execa";
58
-
59
- // scripts/git/git-execa-error.ts
60
- function get_exit_code(error) {
61
- if (typeof error !== "object" || error === null || !("exitCode" in error)) return void 0;
62
- const { exitCode: exit_code } = error;
63
- return typeof exit_code === "number" ? exit_code : void 0;
64
- }
65
- function has_timed_out(error) {
66
- if (typeof error !== "object" || error === null || !("timedOut" in error)) return false;
67
- return error.timedOut === true;
68
- }
69
- var TIMEOUT_EXIT_CODE = "timeout";
70
- function create_spawn_error(command, exit_code) {
71
- const exit_code_string = exit_code === void 0 ? "unknown" : String(exit_code);
72
- const error_message = `git ${command} exited with code ${exit_code_string}`;
73
- return new Error(error_message, { cause: { exit_code: exit_code_string } });
74
- }
75
-
76
- // scripts/git/git-push-transport.ts
77
- import { execa as execa2 } from "execa";
78
-
79
- // scripts/git/git-ssh-keepalive.ts
80
- import { execa } from "execa";
81
- var SSH_KEEPALIVE_OPTIONS = "-o ServerAliveInterval=15 -o ServerAliveCountMax=3";
82
- var SSH_COMMAND_VARIABLE = "GIT_SSH_COMMAND";
83
- var SSH_LEGACY_VARIABLE = "GIT_SSH";
84
- var KEEPALIVE_SSH_COMMAND = `ssh ${SSH_KEEPALIVE_OPTIONS}`;
85
- var SSH_COMMAND_CONFIG_KEY = "core.sshCommand";
86
- var CONFIG_PROBE_ARGUMENTS = ["config", "--get", SSH_COMMAND_CONFIG_KEY];
87
- var PROBE_OPTIONS = { timeout: PROBE_TIMEOUT_MS };
88
- function to_environment_value(name) {
89
- return process.env[name]?.trim() ?? "";
90
- }
91
- function to_configured_ssh_command() {
92
- const from_command = to_environment_value(SSH_COMMAND_VARIABLE);
93
- return from_command === "" ? to_environment_value(SSH_LEGACY_VARIABLE) : from_command;
94
- }
95
- async function has_configured_ssh_command() {
96
- if (to_configured_ssh_command() !== "") return true;
97
- try {
98
- const git_command_bin = git_utilities.get_git_command_for_spawn();
99
- const { stdout } = await execa(git_command_bin, CONFIG_PROBE_ARGUMENTS, PROBE_OPTIONS);
100
- return stdout.trim() !== "";
101
- } catch (error) {
102
- return has_timed_out(error);
103
- }
104
- }
105
- async function to_environment() {
106
- const should_keep_alive = !await has_configured_ssh_command();
107
- return should_keep_alive ? { [SSH_COMMAND_VARIABLE]: KEEPALIVE_SSH_COMMAND } : {};
108
- }
109
- var git_ssh_keepalive = {
110
- to_environment
111
- };
112
-
113
- // scripts/git/git-push-transport.ts
114
- var PUSH_TIMEOUT_SECONDS = 120;
115
- var PUSH_TIMEOUT_MS = PUSH_TIMEOUT_SECONDS * MS_PER_SECOND;
116
- var PUSH_TIMEOUT_LABEL = `${String(PUSH_TIMEOUT_SECONDS)}s`;
117
- var PUSH_TIMEOUT_MESSAGE = "git push timed out";
118
- var PUSH_SUBCOMMAND = "push";
119
- async function to_push_options() {
120
- return {
121
- stdio: "inherit",
122
- timeout: PUSH_TIMEOUT_MS,
123
- env: await git_ssh_keepalive.to_environment()
124
- };
125
- }
126
- async function did_push_time_out(arguments_list) {
127
- const git_command_bin = git_utilities.get_git_command_for_spawn();
128
- const options = await to_push_options();
129
- try {
130
- await execa2(git_command_bin, [PUSH_SUBCOMMAND, ...arguments_list], options);
131
- return false;
132
- } catch (error) {
133
- if (has_timed_out(error)) return true;
134
- throw create_spawn_error(PUSH_SUBCOMMAND, get_exit_code(error));
135
- }
136
- }
137
- function to_manual_command(arguments_list) {
138
- return ["git", PUSH_SUBCOMMAND, ...arguments_list].join(" ");
139
- }
140
- function to_retry_notice(arguments_list) {
141
- return `${PUSH_TIMEOUT_MESSAGE} after ${PUSH_TIMEOUT_LABEL} \u2014 retrying once: ${to_manual_command(arguments_list)}`;
142
- }
143
- function create_timeout_error(arguments_list) {
144
- const message = `${PUSH_TIMEOUT_MESSAGE} twice (${PUSH_TIMEOUT_LABEL} each). Re-run it by hand: ${to_manual_command(arguments_list)}`;
145
- return new Error(message, { cause: { exit_code: TIMEOUT_EXIT_CODE } });
146
- }
147
- async function push(arguments_list) {
148
- if (!await did_push_time_out(arguments_list)) return;
149
- console.warn(to_retry_notice(arguments_list));
150
- if (!await did_push_time_out(arguments_list)) return;
151
- throw create_timeout_error(arguments_list);
152
- }
153
- var git_push_transport = {
154
- push
155
- };
156
-
157
- // scripts/git/git-spawn.ts
158
- async function read(arguments_, timeout_ms = GIT_TIMEOUT_MS) {
159
- const git_cmd = git_utilities.get_git_command_for_spawn();
160
- const { stdout } = await execa3(git_cmd, arguments_, { timeout: timeout_ms });
161
- return stdout.trimEnd();
162
- }
163
- var REMOTE_TIMEOUT_MS = PUSH_TIMEOUT_MS;
164
- function to_budget_error(command, error, timeout_ms) {
165
- if (!has_timed_out(error)) return create_spawn_error(command, get_exit_code(error));
166
- const seconds = String(Math.round(timeout_ms / MS_PER_SECOND));
167
- return new Error(`git ${command} timed out after ${seconds}s`, {
168
- cause: { exit_code: TIMEOUT_EXIT_CODE }
169
- });
170
- }
171
- async function spawn_remote(arguments_, options) {
172
- const git_cmd = git_utilities.get_git_command_for_spawn();
173
- try {
174
- const { stdout } = await execa3(git_cmd, arguments_, options);
175
- return typeof stdout === "string" ? stdout.trimEnd() : "";
176
- } catch (error) {
177
- throw to_budget_error(arguments_[0] ?? "", error, options.timeout);
178
- }
179
- }
180
- async function read_remote(arguments_, timeout_ms = REMOTE_TIMEOUT_MS) {
181
- return await spawn_remote(arguments_, {
182
- timeout: timeout_ms,
183
- env: await git_ssh_keepalive.to_environment()
184
- });
185
- }
186
- async function with_output_remote(command, arguments_list) {
187
- await spawn_remote([command, ...arguments_list], {
188
- stdio: "inherit",
189
- timeout: REMOTE_TIMEOUT_MS,
190
- env: await git_ssh_keepalive.to_environment()
191
- });
192
- }
193
- async function with_output(command, arguments_list, options = {}) {
194
- const { config_options = [], timeout_ms = GIT_TIMEOUT_MS } = options;
195
- const git_command_bin = git_utilities.get_git_command_for_spawn();
196
- const spawn_arguments = [...config_options, command, ...arguments_list];
197
- try {
198
- await execa3(git_command_bin, spawn_arguments, { stdio: "inherit", timeout: timeout_ms });
199
- } catch (error) {
200
- throw to_budget_error(command, error, timeout_ms);
201
- }
202
- }
203
- var git_spawn = {
204
- read,
205
- read_remote,
206
- with_output,
207
- with_output_remote
208
- };
37
+ // scripts/josh/durable-state.ts
38
+ import { mkdirSync } from "node:fs";
39
+ import path2 from "node:path";
209
40
 
210
- // scripts/git/git-diff-reads.ts
211
- var REFS_REMOTES_ORIGIN_PREFIX = "refs/remotes/origin/";
212
- var NAME_ONLY_FLAG = "--name-only";
213
- var DEFAULT_BRANCH_FALLBACK = "main";
214
- var DEFAULT_BRANCH_ARGUMENTS = ["symbolic-ref", "refs/remotes/origin/HEAD"];
215
- function default_branch_of(output) {
216
- const trimmed = output?.trim() ?? "";
217
- if (!trimmed.startsWith(REFS_REMOTES_ORIGIN_PREFIX)) return DEFAULT_BRANCH_FALLBACK;
218
- return trimmed.slice(REFS_REMOTES_ORIGIN_PREFIX.length);
219
- }
220
- async function get_default_branch() {
41
+ // scripts/josh/durable-state-migrate.ts
42
+ import { constants, copyFileSync, lstatSync, readdirSync, rmSync, writeFileSync } from "node:fs";
43
+ import path from "node:path";
44
+ var COPIED_MARKER = ".legacy-copied";
45
+ var MARKER_MODE = 384;
46
+ var LOG_RETENTION_DAYS = 14;
47
+ var DAY_MS = 864e5;
48
+ var LOG_SUFFIX = ".log";
49
+ var RECORD_SUFFIXES = [".json", ".jsonl", LOG_SUFFIX];
50
+ function is_record_name(name, prefixes) {
51
+ const has_prefix = prefixes.some((prefix) => name.startsWith(prefix));
52
+ return has_prefix && RECORD_SUFFIXES.some((suffix) => name.endsWith(suffix));
53
+ }
54
+ function list_names(directory) {
221
55
  try {
222
- return default_branch_of(await git_spawn.read([...DEFAULT_BRANCH_ARGUMENTS]));
56
+ return readdirSync(directory);
223
57
  } catch {
224
- return DEFAULT_BRANCH_FALLBACK;
58
+ return [];
225
59
  }
226
60
  }
227
- var MERGE_BASE_COMMAND = "merge-base";
228
- async function reference_exists(reference2) {
61
+ function copy_record(from, to) {
229
62
  try {
230
- await git_spawn.read(["rev-parse", "--verify", "--quiet", reference2]);
231
- return true;
63
+ if (!stamp_file.is_own_regular_file(from)) return;
64
+ copyFileSync(from, to, constants.COPYFILE_EXCL);
232
65
  } catch {
233
- return false;
234
66
  }
235
67
  }
236
- async function default_branch_reference() {
237
- const default_branch = await get_default_branch();
238
- const remote_reference = `${REFS_REMOTES_ORIGIN_PREFIX}${default_branch}`;
239
- return await reference_exists(remote_reference) ? remote_reference : default_branch;
240
- }
241
- async function change_base() {
242
- const default_branch = await default_branch_reference();
243
- try {
244
- return await git_spawn.read([MERGE_BASE_COMMAND, default_branch, "HEAD"]);
245
- } catch {
246
- return default_branch;
247
- }
248
- }
249
- async function diff_main(file_path) {
250
- return await git_spawn.read(["diff", await change_base(), "--", file_path]);
251
- }
252
- var NO_PATH_QUOTING = ["-c", "core.quotePath=false"];
253
- var NO_RELATIVE_PATHS = "--no-relative";
254
- var NO_RENAME_DETECTION = "--no-renames";
255
- async function change_base_commit() {
256
- return await git_spawn.read(["rev-parse", await change_base()]);
257
- }
258
- async function diff_names_since(commit2) {
259
- return await git_spawn.read([
260
- ...NO_PATH_QUOTING,
261
- "diff",
262
- NAME_ONLY_FLAG,
263
- NO_RELATIVE_PATHS,
264
- NO_RENAME_DETECTION,
265
- commit2,
266
- "--"
267
- ]);
268
- }
269
- async function tree_names_at(commit2, paths) {
270
- return await git_spawn.read([
271
- ...NO_PATH_QUOTING,
272
- "ls-tree",
273
- "-r",
274
- NAME_ONLY_FLAG,
275
- "--full-tree",
276
- commit2,
277
- "--",
278
- ...paths
279
- ]);
280
- }
281
- async function diff_main_names() {
282
- return await diff_names_since(await change_base());
283
- }
284
- async function diff_cached_names() {
285
- return await git_spawn.read([
286
- ...NO_PATH_QUOTING,
287
- "diff",
288
- "--cached",
289
- NAME_ONLY_FLAG,
290
- NO_RELATIVE_PATHS,
291
- NO_RENAME_DETECTION
292
- ]);
293
- }
294
- async function diff_main_numstat() {
295
- return await git_spawn.read([
296
- ...NO_PATH_QUOTING,
297
- "diff",
298
- "--numstat",
299
- NO_RELATIVE_PATHS,
300
- NO_RENAME_DETECTION,
301
- await change_base(),
302
- "--"
303
- ]);
304
- }
305
- var WHOLE_TREE_PATHSPEC = ":/";
306
- async function untracked_names() {
307
- return await git_spawn.read([
308
- ...NO_PATH_QUOTING,
309
- "ls-files",
310
- "--others",
311
- "--exclude-standard",
312
- "--full-name",
313
- WHOLE_TREE_PATHSPEC
314
- ]);
315
- }
316
- var git_diff_reads = {
317
- DEFAULT_BRANCH_ARGUMENTS,
318
- change_base,
319
- change_base_commit,
320
- default_branch_of,
321
- default_branch_reference,
322
- diff_cached_names,
323
- diff_main,
324
- diff_main_names,
325
- diff_main_numstat,
326
- diff_names_since,
327
- get_default_branch,
328
- tree_names_at,
329
- untracked_names
330
- };
331
-
332
- // scripts/git/git-pre-push-hook.ts
333
- import { mkdtemp, rm, writeFile } from "node:fs/promises";
334
- import { tmpdir } from "node:os";
335
- import path from "node:path";
336
- var REMOTE = "origin";
337
- var HOOK_NAME = "pre-push";
338
- var PROBE_HOOK_NAME = "kit-hook-run-probe";
339
- var ALLOW_UNKNOWN_HOOK_NAME_FLAG = "--allow-unknown-hook-name";
340
- var HOOK_RUN = "run";
341
- var STDIN_FILE = "refs";
342
- var TEMPORARY_PREFIX = "kit-pre-push-";
343
- var ZERO_DIGIT = "0";
344
- async function read_remote_oid(branch2) {
345
- try {
346
- return await git_spawn.read([
347
- "rev-parse",
348
- "--verify",
349
- "--quiet",
350
- `refs/remotes/${REMOTE}/${branch2}`
351
- ]);
352
- } catch {
353
- return void 0;
68
+ function copy_legacy(from, to, prefixes) {
69
+ if (from === to) return;
70
+ for (const name of list_names(from)) {
71
+ if (is_record_name(name, prefixes)) copy_record(path.join(from, name), path.join(to, name));
354
72
  }
355
73
  }
356
- async function read_push_references() {
357
- const [branch2, local_oid] = await Promise.all([
358
- git_spawn.read(["rev-parse", "--abbrev-ref", "HEAD"]),
359
- git_spawn.read(["rev-parse", "HEAD"])
360
- ]);
361
- return { branch: branch2, local_oid, remote_oid: await read_remote_oid(branch2) };
362
- }
363
- function to_stdin_line(references) {
364
- const reference2 = `refs/heads/${references.branch}`;
365
- const remote_oid = references.remote_oid ?? ZERO_DIGIT.repeat(references.local_oid.length);
366
- return `${reference2} ${references.local_oid} ${reference2} ${remote_oid}
367
- `;
368
- }
369
- function to_hook_run_arguments(stdin_path, hook_name) {
370
- return [HOOK_RUN, "--ignore-missing", `--to-stdin=${stdin_path}`, hook_name];
371
- }
372
- async function can_probe(probe_arguments) {
74
+ function claim_copy(directory) {
373
75
  try {
374
- await git_spawn.read(["hook", ...probe_arguments]);
76
+ writeFileSync(path.join(directory, COPIED_MARKER), "", { flag: "wx", mode: MARKER_MODE });
375
77
  return true;
376
78
  } catch {
377
79
  return false;
378
80
  }
379
81
  }
380
- async function can_run_hooks(stdin_path) {
381
- const [, ...options] = to_hook_run_arguments(stdin_path, PROBE_HOOK_NAME);
382
- if (await can_probe([HOOK_RUN, ALLOW_UNKNOWN_HOOK_NAME_FLAG, ...options])) return true;
383
- return await can_probe([HOOK_RUN, ...options]);
82
+ function copy_once(from, to, prefixes) {
83
+ if (claim_copy(to)) copy_legacy(from, to, prefixes);
84
+ }
85
+ function is_stale(target2, now_ms) {
86
+ const age_ms = now_ms - lstatSync(target2).mtimeMs;
87
+ return age_ms > LOG_RETENTION_DAYS * DAY_MS && stamp_file.is_own_regular_file(target2);
384
88
  }
385
- async function run_with_stdin(stdin_line) {
386
- const directory = await mkdtemp(path.join(tmpdir(), TEMPORARY_PREFIX));
387
- const stdin_path = path.join(directory, STDIN_FILE);
89
+ function prune_log(target2, now_ms) {
388
90
  try {
389
- await writeFile(stdin_path, stdin_line);
390
- if (!await can_run_hooks(stdin_path)) return false;
391
- const url = await git_spawn.read(["remote", "get-url", REMOTE]);
392
- await git_spawn.with_output(
393
- "hook",
394
- [...to_hook_run_arguments(stdin_path, HOOK_NAME), "--", REMOTE, url],
395
- { timeout_ms: SUITE_TIMEOUT_MS }
396
- );
397
- return true;
398
- } finally {
399
- await rm(directory, { force: true, recursive: true });
91
+ if (is_stale(target2, now_ms)) rmSync(target2, { force: true });
92
+ } catch {
400
93
  }
401
94
  }
402
- async function run() {
403
- const references = await read_push_references();
404
- if (references.local_oid === references.remote_oid) return true;
405
- return await run_with_stdin(to_stdin_line(references));
406
- }
407
- var git_pre_push_hook = {
408
- run
409
- };
410
-
411
- // scripts/lib/spawn-exit.ts
412
- function read_spawn_stdout(result) {
413
- return result.stdout ?? "";
414
- }
415
- function read_spawn_stderr(result) {
416
- return result.stderr ?? "";
417
- }
418
-
419
- // scripts/git/git-spawn-sync.ts
420
- import { execaSync } from "execa";
421
-
422
- // scripts/git/git-location-environment.ts
423
- var GIT_LOCATION_VARIABLES = [
424
- "GIT_ALTERNATE_OBJECT_DIRECTORIES",
425
- "GIT_COMMON_DIR",
426
- "GIT_DIR",
427
- "GIT_INDEX_FILE",
428
- "GIT_NAMESPACE",
429
- "GIT_OBJECT_DIRECTORY",
430
- "GIT_WORK_TREE"
431
- ];
432
- function location_free_environment() {
433
- return Object.fromEntries(GIT_LOCATION_VARIABLES.map((name) => [name, void 0]));
434
- }
435
- function forget(name) {
436
- Reflect.deleteProperty(process.env, name);
437
- }
438
- function restore_one(name, value) {
439
- if (value === void 0) forget(name);
440
- else process.env[name] = value;
441
- }
442
- function clear_git_location_variables() {
443
- const previous = GIT_LOCATION_VARIABLES.map((name) => [name, process.env[name]]);
444
- for (const [name] of previous) forget(name);
445
- return () => {
446
- for (const [name, value] of previous) restore_one(name, value);
447
- };
448
- }
449
- var git_location_environment = { clear_git_location_variables, location_free_environment };
450
-
451
- // scripts/git/git-spawn-sync.ts
452
- var SUCCESS_EXIT_CODE = 0;
453
- var C_LOCALE = { LC_ALL: "C", LANGUAGE: "C" };
454
- function run2(args, options = {}) {
455
- const result = execaSync(git_utilities.get_git_command_for_spawn(), args, {
456
- ...options,
457
- extendEnv: true,
458
- reject: false,
459
- timeout: options.timeout ?? GIT_TIMEOUT_MS
460
- });
461
- return {
462
- exit_code: result.exitCode,
463
- stdout: read_spawn_stdout(result),
464
- stderr: read_spawn_stderr(result)
465
- };
466
- }
467
- function read2(args, options = {}) {
468
- const result = run2(args, options);
469
- return result.exit_code === SUCCESS_EXIT_CODE ? result.stdout.trim() : void 0;
470
- }
471
- function origin_url(cwd) {
472
- return read2(["config", "--get", "remote.origin.url"], {
473
- cwd,
474
- env: git_location_environment.location_free_environment()
475
- });
476
- }
477
- function toplevel(timeout = GIT_TIMEOUT_MS) {
478
- return run2(["rev-parse", "--show-toplevel"], { env: C_LOCALE, timeout });
479
- }
480
- var git_spawn_sync = { GIT_TIMEOUT_MS, C_LOCALE, run: run2, read: read2, origin_url, toplevel };
481
-
482
- // scripts/git/git-command.ts
483
- async function branch() {
484
- return await git_spawn.read(["rev-parse", "--abbrev-ref", "HEAD"]);
485
- }
486
- async function status(directory) {
487
- const location = directory === void 0 ? [] : ["-C", directory];
488
- return await git_spawn.read([...location, "status", PORCELAIN_FLAG, UNTRACKED_FILES_FLAG]);
489
- }
490
- async function repository_root() {
491
- const result = git_spawn_sync.toplevel();
492
- if (result.exit_code !== 0) throw create_spawn_error("rev-parse", result.exit_code);
493
- return result.stdout.trim();
494
- }
495
- async function head_commit() {
496
- return await git_spawn.read(["rev-parse", "HEAD"]);
497
- }
498
- var GIT_DIRECTORY_ARGUMENTS = [
499
- "rev-parse",
500
- "--absolute-git-dir",
501
- "--path-format=absolute",
502
- "--git-common-dir"
503
- ];
504
- async function git_directories() {
505
- const output = await git_spawn.read([...GIT_DIRECTORY_ARGUMENTS]);
506
- return output.split("\n").filter((line) => line !== "");
507
- }
508
- async function diff_cached(file_path) {
509
- return await git_spawn.read(["diff", "--cached", file_path]);
510
- }
511
- async function fetch_branch(branch_name) {
512
- const refspec = `+refs/heads/${branch_name}:refs/remotes/origin/${branch_name}`;
513
- return await git_spawn.read_remote(["fetch", "origin", refspec]);
514
- }
515
- async function merge_fast_forward(branch_name) {
516
- return await git_spawn.read(["merge", "--ff-only", `origin/${branch_name}`], SUITE_TIMEOUT_MS);
517
- }
518
- async function fast_forward_local(branch_name) {
519
- return await git_spawn.read_remote(["fetch", "origin", `${branch_name}:${branch_name}`]);
520
- }
521
- async function merge_branch(branch_name, message) {
522
- const message_arguments = message === void 0 ? [] : ["-m", message];
523
- await git_spawn.with_output("merge", [...message_arguments, `origin/${branch_name}`], {
524
- timeout_ms: SUITE_TIMEOUT_MS
525
- });
526
- }
527
- async function checkout_b(branch_name) {
528
- return await git_spawn.read(["checkout", "-b", branch_name], SUITE_TIMEOUT_MS);
529
- }
530
- async function checkout(branch_name) {
531
- return await git_spawn.read(["checkout", branch_name], SUITE_TIMEOUT_MS);
532
- }
533
- async function commit(message) {
534
- await git_spawn.with_output("commit", ["-m", message], { timeout_ms: SUITE_TIMEOUT_MS });
535
- }
536
- async function delete_branch(branch_name) {
537
- await git_spawn.read(["branch", "-d", branch_name]);
538
- }
539
- async function read_commit_count(revisions) {
540
- const output = await git_spawn.read(["rev-list", "--count", ...revisions]);
541
- const parsed = Number(output);
542
- if (output.length > 0 && Number.isFinite(parsed)) return parsed;
543
- throw new Error(
544
- `\`git rev-list --count ${revisions.join(" ")}\` printed \`${output}\` rather than a count`
545
- );
546
- }
547
- async function commit_count_beyond(base, tip) {
548
- return await read_commit_count([`${base}..${tip}`]);
549
- }
550
- async function commit_count_unpushed(branch_name) {
551
- return await read_commit_count([branch_name, "--not", "--remotes"]);
552
- }
553
- function is_exit_code_128(cause) {
554
- return typeof cause === "object" && cause !== null && "exit_code" in cause && cause.exit_code === "128";
555
- }
556
- function is_upstream_not_set_error(error) {
557
- if (!(error instanceof Error)) return false;
558
- const { cause } = error;
559
- return cause !== void 0 && is_exit_code_128(cause);
560
- }
561
- var NO_VERIFY_FLAG = "--no-verify";
562
- async function push_with_upstream(branch_name, verify_flags) {
563
- await git_push_transport.push([...verify_flags, "--set-upstream", "origin", branch_name]);
564
- }
565
- async function push2() {
566
- const verify_flags = await git_pre_push_hook.run() ? [NO_VERIFY_FLAG] : [];
567
- try {
568
- await git_push_transport.push([...verify_flags]);
569
- } catch (error) {
570
- if (is_upstream_not_set_error(error)) {
571
- const current_branch = await branch();
572
- await push_with_upstream(current_branch, verify_flags);
573
- return;
95
+ function prune_stale_logs(directory, prefixes, now_ms) {
96
+ for (const name of list_names(directory)) {
97
+ if (name.endsWith(LOG_SUFFIX) && is_record_name(name, prefixes)) {
98
+ prune_log(path.join(directory, name), now_ms);
574
99
  }
575
- throw error;
576
100
  }
577
101
  }
578
- async function pull_fast_forward() {
579
- await git_spawn.with_output_remote("pull", ["--ff-only"]);
580
- }
581
- var SHORT_NAME_FORMAT = "--format=%(refname:short)";
582
- var REMOTES_FLAG = "--remotes";
583
- async function list_branches(flags, pattern) {
102
+ var durable_state_migrate = { LOG_RETENTION_DAYS, copy_once, is_record_name, prune_stale_logs };
103
+
104
+ // scripts/josh/durable-state.ts
105
+ var RUN_STATE_DIRECTORY = "run-state";
106
+ var OVERRIDE_STATE_DIRECTORY = "josh-state";
107
+ var STATE_DIRECTORY_MODE = 448;
108
+ function state_root(override, common) {
109
+ if (override !== void 0 && override !== "") {
110
+ return path2.join(override, OVERRIDE_STATE_DIRECTORY);
111
+ }
112
+ if (common === void 0) return PLATFORM_TEMP_ROOT;
113
+ return path2.join(common, git_common_directory.STATE_DIRECTORY, RUN_STATE_DIRECTORY);
114
+ }
115
+ var STATE_ROOT_OVERRIDE = process.env[platform_temporary.TEMP_ROOT_KEY];
116
+ function root_for(common) {
117
+ return state_root(STATE_ROOT_OVERRIDE, common);
118
+ }
119
+ function root() {
120
+ return root_for(git_common_directory.repository());
121
+ }
122
+ var PREFIX = {
123
+ CARRY: "josh-run-carry-",
124
+ ENDED: "josh-run-ended-",
125
+ EVENTS: "josh-run-events-",
126
+ LANE_STATE: "josh-lane-state-",
127
+ LANE_LEDGER: "josh-lane-ledger-",
128
+ WAKE_LOG: "josh-run-wake-log-",
129
+ BACKLOGRUN_LAUNCH: "josh-backlogrun-launch-",
130
+ BACKLOGRUN_LOG: "josh-backlogrun-log-",
131
+ SHIP_LOG: "josh-ship-log-",
132
+ SHIP_RESULT: "josh-ship-result-",
133
+ LANE_DISPATCH: "josh-lane-dispatch-",
134
+ LANE_PLAN: "josh-lane-plan-"
135
+ };
136
+ var PREFIXES = Object.values(PREFIX);
137
+ var ensured = /* @__PURE__ */ new Set();
138
+ function prepare(directory) {
139
+ mkdirSync(directory, { recursive: true, mode: STATE_DIRECTORY_MODE });
140
+ durable_state_migrate.copy_once(PLATFORM_TEMP_ROOT, directory, PREFIXES);
141
+ durable_state_migrate.prune_stale_logs(directory, PREFIXES, Date.now());
142
+ }
143
+ function ensure(directory) {
144
+ if (ensured.has(directory)) return directory;
584
145
  try {
585
- const output = await git_spawn.read([
586
- "branch",
587
- "--list",
588
- SHORT_NAME_FORMAT,
589
- ...flags,
590
- pattern
591
- ]);
592
- return output.split("\n").filter((line) => line.trim() !== "");
146
+ prepare(directory);
593
147
  } catch {
594
- return [];
595
- }
596
- }
597
- async function branch_names(pattern) {
598
- return await list_branches([], pattern);
599
- }
600
- async function branch_names_remote(pattern) {
601
- return await list_branches([REMOTES_FLAG], pattern);
602
- }
603
- async function branch_exists(branch_name) {
604
- const names = await branch_names(branch_name);
605
- return names.length > 0;
606
- }
607
- var ALL_PATHS_PATHSPEC = ":/";
608
- function exclude_pathspec(file_path) {
609
- return `:(exclude,top)${file_path}`;
610
- }
611
- async function add_tracked(excluded_paths) {
612
- const exclusions = excluded_paths.map((file_path) => exclude_pathspec(file_path));
613
- await git_spawn.read(["add", "-u", "--", ALL_PATHS_PATHSPEC, ...exclusions]);
614
- }
615
- async function add_path(file_path) {
616
- await git_spawn.with_output("add", ["--", file_path]);
617
- }
618
- var FIRST_PARENT_FLAG = "--first-parent";
619
- async function log_first_parent(limit, file_path, tip = "HEAD") {
620
- const output = await git_spawn.read([
621
- "log",
622
- FIRST_PARENT_FLAG,
623
- "--format=%H",
624
- `-n`,
625
- String(limit),
626
- tip,
627
- "--",
628
- file_path
629
- ]);
630
- return output.split("\n").filter((line) => line.length > 0);
631
- }
632
- async function show_file(spec) {
633
- return await git_spawn.read(["show", spec]);
634
- }
635
- var MERGE_COUNT_ARGUMENTS = [
636
- "rev-list",
637
- "--count",
638
- "--merges",
639
- FIRST_PARENT_FLAG
640
- ];
641
- function merge_count_arguments(range) {
642
- return [...MERGE_COUNT_ARGUMENTS, range];
643
- }
644
- async function count_merges(range) {
645
- const output = await git_spawn.read(merge_count_arguments(range));
646
- const parsed = Number(output.trim());
647
- return Number.isFinite(parsed) ? parsed : 0;
648
- }
649
- var git_command = {
650
- GIT_DIRECTORY_ARGUMENTS,
651
- branch,
652
- status,
653
- repository_root,
654
- head_commit,
655
- git_directories,
656
- diff_cached,
657
- // The default branch, the change base and every reading against it are `git-diff-reads.ts`'s,
658
- // re-exported here so no call site, mock or spy moved with them.
659
- ...git_diff_reads,
660
- fetch_branch,
661
- merge_fast_forward,
662
- fast_forward_local,
663
- merge_branch,
664
- checkout_b,
665
- checkout,
666
- commit,
667
- commit_count_beyond,
668
- commit_count_unpushed,
669
- delete_branch,
670
- push: push2,
671
- pull_fast_forward,
672
- branch_exists,
673
- branch_names,
674
- branch_names_remote,
675
- add_tracked,
676
- add_path,
677
- log_first_parent,
678
- show_file,
679
- count_merges,
680
- merge_count_arguments,
681
- is_upstream_not_set_error
148
+ return PLATFORM_TEMP_ROOT;
149
+ }
150
+ ensured.add(directory);
151
+ return directory;
152
+ }
153
+ function durable_path(prefix, key_root, suffix) {
154
+ return path2.join(ensure(root()), stamp_file.stamp_name(prefix, key_root, suffix));
155
+ }
156
+ var durable_state = {
157
+ PREFIX,
158
+ STATE_DIRECTORY_MODE,
159
+ ensure,
160
+ path: durable_path,
161
+ root,
162
+ root_for,
163
+ state_root
682
164
  };
683
165
 
684
166
  // scripts/josh/process-identity.ts
685
167
  import { execFileSync, spawnSync } from "node:child_process";
686
168
  import { randomUUID } from "node:crypto";
687
- import { readFileSync, rmSync } from "node:fs";
169
+ import { readFileSync, rmSync as rmSync2 } from "node:fs";
688
170
  import { createServer } from "node:net";
689
- import path2 from "node:path";
171
+ import path3 from "node:path";
690
172
  var PS_COMMAND = "/bin/ps";
691
173
  var FORMAT_FLAG = "-o";
692
174
  var START_TIME_FORMAT = "lstart=";
@@ -765,7 +247,7 @@ function close_beacon(token) {
765
247
  if (server === void 0) return;
766
248
  beacons.delete(token);
767
249
  server.close();
768
- rmSync(token.slice(BEACON_SCHEME.length), { force: true });
250
+ rmSync2(token.slice(BEACON_SCHEME.length), { force: true });
769
251
  }
770
252
  function close_beacons() {
771
253
  for (const token of beacons.keys()) close_beacon(token);
@@ -777,30 +259,30 @@ function ensure_exit_cleanup() {
777
259
  }
778
260
  function ignore_beacon_error() {
779
261
  }
780
- function bind_beacon(target) {
781
- return createServer().on("error", ignore_beacon_error).listen(target);
262
+ function bind_beacon(target2) {
263
+ return createServer().on("error", ignore_beacon_error).listen(target2);
782
264
  }
783
- function try_bind_beacon(bind, target) {
265
+ function try_bind_beacon(bind, target2) {
784
266
  try {
785
- const server = bind(target);
267
+ const server = bind(target2);
786
268
  return server.listening ? server : void 0;
787
269
  } catch {
788
270
  return void 0;
789
271
  }
790
272
  }
791
273
  function open_beacon(bind = bind_beacon) {
792
- const target = path2.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
793
- const token = `${BEACON_SCHEME}${target}`;
794
- const server = try_bind_beacon(bind, target);
274
+ const target2 = path3.join(PLATFORM_TEMP_ROOT, `${BEACON_PREFIX}${randomUUID()}${BEACON_SUFFIX}`);
275
+ const token = `${BEACON_SCHEME}${target2}`;
276
+ const server = try_bind_beacon(bind, target2);
795
277
  if (server === void 0) return void 0;
796
278
  server.unref();
797
279
  beacons.set(token, server);
798
280
  ensure_exit_cleanup();
799
281
  return token;
800
282
  }
801
- function resolve_own_start(probes = START_PROBES, platform2 = process.platform) {
283
+ function resolve_own_start(probes = START_PROBES, platform = process.platform) {
802
284
  const start = read_start(process.pid, probes);
803
- if (start !== void 0 || platform2 === WINDOWS_PLATFORM) return start;
285
+ if (start !== void 0 || platform === WINDOWS_PLATFORM) return start;
804
286
  return open_beacon();
805
287
  }
806
288
  function is_valid_beacon_name(name) {
@@ -810,28 +292,28 @@ function is_valid_beacon_name(name) {
810
292
  }
811
293
  function beacon_target(token) {
812
294
  if (!token.startsWith(BEACON_SCHEME)) return void 0;
813
- const target = token.slice(BEACON_SCHEME.length);
814
- if (path2.dirname(target) !== PLATFORM_TEMP_ROOT) return void 0;
815
- return is_valid_beacon_name(path2.basename(target)) ? target : void 0;
295
+ const target2 = token.slice(BEACON_SCHEME.length);
296
+ if (path3.dirname(target2) !== PLATFORM_TEMP_ROOT) return void 0;
297
+ return is_valid_beacon_name(path3.basename(target2)) ? target2 : void 0;
816
298
  }
817
- function run_socket_probe(target, kill_after_ms = PROBE_TIMEOUT_MS) {
818
- return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target], {
299
+ function run_socket_probe(target2, kill_after_ms = PROBE_TIMEOUT_MS) {
300
+ return spawnSync(process.execPath, ["-e", SOCKET_PROBE_SOURCE, target2], {
819
301
  stdio: "ignore",
820
302
  timeout: kill_after_ms
821
303
  }).status ?? void 0;
822
304
  }
823
- function is_live_beacon(target, probe = run_socket_probe) {
824
- const status2 = probe(target);
825
- if (status2 === BEACON_LIVE_STATUS) return true;
826
- return status2 === BEACON_GONE_STATUS ? false : void 0;
305
+ function is_live_beacon(target2, probe = run_socket_probe) {
306
+ const status = probe(target2);
307
+ if (status === BEACON_LIVE_STATUS) return true;
308
+ return status === BEACON_GONE_STATUS ? false : void 0;
827
309
  }
828
- function has_matching_start(pid, recorded_start, read3) {
829
- const observed = read3(pid);
310
+ function has_matching_start(pid, recorded_start, read) {
311
+ const observed = read(pid);
830
312
  return observed === void 0 ? void 0 : observed === recorded_start;
831
313
  }
832
- function matches_recorded_start(pid, recorded_start, read3) {
833
- const target = beacon_target(recorded_start);
834
- return target === void 0 ? has_matching_start(pid, recorded_start, read3) : is_live_beacon(target);
314
+ function matches_recorded_start(pid, recorded_start, read) {
315
+ const target2 = beacon_target(recorded_start);
316
+ return target2 === void 0 ? has_matching_start(pid, recorded_start, read) : is_live_beacon(target2);
835
317
  }
836
318
  var own_probe = /* @__PURE__ */ new Map();
837
319
  function own_start() {
@@ -842,15 +324,15 @@ function own_fields() {
842
324
  const start = own_start();
843
325
  return { pid: process.pid, ...start !== void 0 && { process_start: start } };
844
326
  }
845
- function is_same_process(pid, recorded_start, read3 = read_start) {
327
+ function is_same_process(pid, recorded_start, read = read_start) {
846
328
  if (pid === void 0 || !is_live_pid(pid)) return false;
847
329
  if (recorded_start === void 0) return void 0;
848
- return matches_recorded_start(pid, recorded_start, read3);
330
+ return matches_recorded_start(pid, recorded_start, read);
849
331
  }
850
- function is_present_process(pid, recorded_start, read3 = read_start) {
332
+ function is_present_process(pid, recorded_start, read = read_start) {
851
333
  if (!is_present_pid(pid)) return false;
852
334
  if (recorded_start === void 0) return void 0;
853
- return matches_recorded_start(pid, recorded_start, read3);
335
+ return matches_recorded_start(pid, recorded_start, read);
854
336
  }
855
337
  function is_own_process(pid, recorded_start) {
856
338
  return pid === process.pid && recorded_start === own_start();
@@ -1124,9 +606,9 @@ function next_added(carry, additions) {
1124
606
  }
1125
607
  return next;
1126
608
  }
1127
- function add_issues(target, carry, additions) {
609
+ function add_issues(target2, carry, additions) {
1128
610
  const next = { ...carry, added: next_added(carry, additions) };
1129
- stamp_file.replace_stamp(target, next);
611
+ stamp_file.replace_stamp(target2, next);
1130
612
  return next;
1131
613
  }
1132
614
  var run_carry_added = { add_issues, ordered };
@@ -1205,7 +687,7 @@ function next_counts(carry, change) {
1205
687
  is_handed_off: cuts > NO_INCREMENT2
1206
688
  };
1207
689
  }
1208
- function apply_change(target, carry, change, now = /* @__PURE__ */ new Date()) {
690
+ function apply_change(target2, carry, change, now = /* @__PURE__ */ new Date()) {
1209
691
  const effective = effective_change(carry, change);
1210
692
  if (effective === void 0) return carry;
1211
693
  const streak = run_carry_streak.next_state(carry, effective, now);
@@ -1219,47 +701,55 @@ function apply_change(target, carry, change, now = /* @__PURE__ */ new Date()) {
1219
701
  done: next_done(carry, effective.done),
1220
702
  retrospective: effective.retrospective === true || carry.retrospective
1221
703
  };
1222
- stamp_file.replace_stamp(target, next);
704
+ stamp_file.replace_stamp(target2, next);
1223
705
  return next;
1224
706
  }
1225
707
  var run_carry_change = { apply_change };
1226
708
 
1227
709
  // scripts/run/carry/run-carry-conversation.ts
1228
710
  import { existsSync, statSync as statSync2 } from "node:fs";
1229
- import path5 from "node:path";
711
+ import path6 from "node:path";
1230
712
 
1231
713
  // scripts/cost-runtime/cost-transcript.ts
1232
- import { readdirSync, readFileSync as readFileSync3, statSync } from "node:fs";
714
+ import { readdirSync as readdirSync2, readFileSync as readFileSync3, statSync } from "node:fs";
1233
715
  import { homedir } from "node:os";
1234
- import path4 from "node:path";
716
+ import path5 from "node:path";
1235
717
 
1236
718
  // scripts/lane/lane-paths.ts
1237
- import path3 from "node:path";
719
+ import path4 from "node:path";
1238
720
  var LANE_ROOT_KEY = "JOSH_LANE_ROOT";
1239
721
  var LANE_DIRECTORY_SUFFIX = "-lanes";
1240
722
  var LANE_BRANCH_SUFFIX = "-lane";
1241
- function default_lane_root(repository_root2) {
1242
- const name = path3.basename(repository_root2);
1243
- return path3.join(path3.dirname(repository_root2), `.${name}${LANE_DIRECTORY_SUFFIX}`);
723
+ function default_lane_root(repository_root) {
724
+ const name = path4.basename(repository_root);
725
+ return path4.join(path4.dirname(repository_root), `.${name}${LANE_DIRECTORY_SUFFIX}`);
1244
726
  }
1245
- function lane_root(repository_root2, environment = process.env) {
727
+ function lane_root(repository_root, environment = process.env) {
1246
728
  const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
1247
- return configured.length === 0 ? default_lane_root(repository_root2) : path3.resolve(configured);
729
+ return configured.length === 0 ? default_lane_root(repository_root) : path4.resolve(configured);
1248
730
  }
1249
- function lane_directory(root, issue2) {
1250
- return path3.join(root, issue2);
731
+ function lane_directory(root2, issue2) {
732
+ return path4.join(root2, issue2);
1251
733
  }
1252
734
  var DEFAULT_LANE_ROOT_PATTERN = new RegExp(String.raw`^\..+${LANE_DIRECTORY_SUFFIX}$`, "u");
1253
735
  function is_lane_root(directory, environment) {
1254
736
  const configured = environment[LANE_ROOT_KEY]?.trim() ?? "";
1255
- if (configured.length > 0) return path3.resolve(configured) === directory;
1256
- return DEFAULT_LANE_ROOT_PATTERN.test(path3.basename(directory));
737
+ if (configured.length > 0) return path4.resolve(configured) === directory;
738
+ return DEFAULT_LANE_ROOT_PATTERN.test(path4.basename(directory));
739
+ }
740
+ var CLAUDE_WORKTREES_PATTERN = /[/\\]\.claude[/\\]worktrees[/\\][^/\\]+(?:[/\\].*)?$/u;
741
+ function checkout_of(directory) {
742
+ return directory.replace(CLAUDE_WORKTREES_PATTERN, "");
1257
743
  }
1258
744
  function lane_issue_of(directory, environment = process.env) {
1259
- const resolved = path3.resolve(directory);
1260
- const issue2 = path3.basename(resolved);
745
+ const resolved = checkout_of(path4.resolve(directory));
746
+ const issue2 = path4.basename(resolved);
1261
747
  if (!issue_number_shape.ISSUE_NUMBER_PATTERN.test(issue2)) return void 0;
1262
- return is_lane_root(path3.dirname(resolved), environment) ? issue2 : void 0;
748
+ return is_lane_root(path4.dirname(resolved), environment) ? issue2 : void 0;
749
+ }
750
+ function issue_here(directory = process.cwd(), environment = process.env) {
751
+ const lane = lane_issue_of(directory, environment);
752
+ return lane === void 0 ? void 0 : Number(lane);
1263
753
  }
1264
754
  function lane_branch(issue2) {
1265
755
  return `${issue2}${LANE_BRANCH_SUFFIX}`;
@@ -1272,8 +762,10 @@ var lane_paths = {
1272
762
  LANE_BRANCH_SUFFIX,
1273
763
  LANE_ROOT_KEY,
1274
764
  SEAT_LOCK_DIR,
765
+ checkout_of,
1275
766
  default_lane_root,
1276
767
  is_lane_entry,
768
+ issue_here,
1277
769
  lane_branch,
1278
770
  lane_directory,
1279
771
  lane_issue_of,
@@ -1286,20 +778,20 @@ var ABSENT_CODE = "ENOENT";
1286
778
  function is_absent(error) {
1287
779
  return error instanceof Error && "code" in error && error.code === ABSENT_CODE;
1288
780
  }
1289
- function read_optional(path11) {
781
+ function read_optional(path12) {
1290
782
  try {
1291
- return readFileSync2(path11, "utf8");
783
+ return readFileSync2(path12, "utf8");
1292
784
  } catch (error) {
1293
785
  if (is_absent(error)) return void 0;
1294
786
  throw error;
1295
787
  }
1296
788
  }
1297
- function read_file_or_empty(path11) {
1298
- return read_optional(path11) ?? "";
789
+ function read_file_or_empty(path12) {
790
+ return read_optional(path12) ?? "";
1299
791
  }
1300
- function read_if_readable(path11) {
792
+ function read_if_readable(path12) {
1301
793
  try {
1302
- return readFileSync2(path11, "utf8");
794
+ return readFileSync2(path12, "utf8");
1303
795
  } catch {
1304
796
  return void 0;
1305
797
  }
@@ -1414,10 +906,10 @@ function later_instant(left, right) {
1414
906
  }
1415
907
  function dedupe(records) {
1416
908
  const by_id = /* @__PURE__ */ new Map();
1417
- for (const record of records) {
1418
- const seen = by_id.get(record.request_id);
1419
- const at_ms = later_instant(seen?.at_ms, record.at_ms);
1420
- by_id.set(record.request_id, { ...seen ?? record, at_ms });
909
+ for (const record2 of records) {
910
+ const seen = by_id.get(record2.request_id);
911
+ const at_ms = later_instant(seen?.at_ms, record2.at_ms);
912
+ by_id.set(record2.request_id, { ...seen ?? record2, at_ms });
1421
913
  }
1422
914
  return [...by_id.values()];
1423
915
  }
@@ -1434,7 +926,7 @@ function add_totals(left, right) {
1434
926
  }
1435
927
  function sum_totals(records) {
1436
928
  let total = EMPTY_TOTALS;
1437
- for (const record of records) total = add_totals(total, record.totals);
929
+ for (const record2 of records) total = add_totals(total, record2.totals);
1438
930
  return total;
1439
931
  }
1440
932
  function billed_input(totals) {
@@ -1452,7 +944,7 @@ var cost_usage = {
1452
944
  };
1453
945
 
1454
946
  // scripts/cost-runtime/cost-transcript.ts
1455
- var TRANSCRIPT_ROOT = path4.join(".claude", "projects");
947
+ var TRANSCRIPT_ROOT = path5.join(".claude", "projects");
1456
948
  var TRANSCRIPT_EXTENSION = ".jsonl";
1457
949
  var SLUG_PATTERN = /[^a-zA-Z0-9-]/gu;
1458
950
  var UNIT_DIRECTORY = "subagents";
@@ -1461,7 +953,7 @@ function project_slug(cwd) {
1461
953
  return cwd.replaceAll(SLUG_PATTERN, "-");
1462
954
  }
1463
955
  function transcript_directory(cwd, home = homedir()) {
1464
- return path4.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
956
+ return path5.join(home, TRANSCRIPT_ROOT, project_slug(cwd));
1465
957
  }
1466
958
  var GIT_ENTRY = ".git";
1467
959
  var GITDIR_PREFIX = "gitdir:";
@@ -1469,7 +961,7 @@ var WORKTREE_SEGMENT = `/${GIT_ENTRY}/worktrees/`;
1469
961
  var NOT_FOUND2 = -1;
1470
962
  function linked_worktree_gitdir(cwd) {
1471
963
  try {
1472
- const contents = readFileSync3(path4.join(cwd, GIT_ENTRY), "utf8").trim();
964
+ const contents = readFileSync3(path5.join(cwd, GIT_ENTRY), "utf8").trim();
1473
965
  return contents.startsWith(GITDIR_PREFIX) ? contents.slice(GITDIR_PREFIX.length).trim() : "";
1474
966
  } catch {
1475
967
  return "";
@@ -1477,28 +969,28 @@ function linked_worktree_gitdir(cwd) {
1477
969
  }
1478
970
  function session_cwd(cwd) {
1479
971
  const gitdir = linked_worktree_gitdir(cwd);
1480
- const absolute = gitdir === "" ? "" : path4.resolve(cwd, gitdir);
972
+ const absolute = gitdir === "" ? "" : path5.resolve(cwd, gitdir);
1481
973
  const segment = absolute.indexOf(WORKTREE_SEGMENT);
1482
974
  return segment === NOT_FOUND2 ? cwd : absolute.slice(0, segment);
1483
975
  }
1484
976
  function read_directory(directory) {
1485
977
  try {
1486
- return readdirSync(directory);
978
+ return readdirSync2(directory);
1487
979
  } catch {
1488
980
  return [];
1489
981
  }
1490
982
  }
1491
983
  function lane_transcript_directories(main_cwd, home) {
1492
- const projects = path4.join(home, TRANSCRIPT_ROOT);
984
+ const projects = path5.join(home, TRANSCRIPT_ROOT);
1493
985
  const prefix = `${project_slug(lane_paths.lane_root(main_cwd))}-`;
1494
986
  return read_directory(projects).filter(
1495
987
  (name) => name.startsWith(prefix) && issue_number_shape.ISSUE_NUMBER_PATTERN.test(name.slice(prefix.length))
1496
- ).map((name) => path4.join(projects, name));
988
+ ).map((name) => path5.join(projects, name));
1497
989
  }
1498
990
  function transcript_directories(cwd, home = homedir()) {
1499
- const own2 = transcript_directory(cwd, home);
991
+ const own = transcript_directory(cwd, home);
1500
992
  const lanes = session_cwd(cwd) === cwd ? lane_transcript_directories(cwd, home) : [];
1501
- return [.../* @__PURE__ */ new Set([own2, ...lanes])];
993
+ return [.../* @__PURE__ */ new Set([own, ...lanes])];
1502
994
  }
1503
995
  var OWN_DEPTH = 0;
1504
996
  function home_directory() {
@@ -1524,16 +1016,16 @@ function without_extension(name) {
1524
1016
  return name.slice(0, -TRANSCRIPT_EXTENSION.length);
1525
1017
  }
1526
1018
  function own_files(directory, names) {
1527
- return names.filter((name) => is_transcript(name)).map((name) => to_session_file(path4.join(directory, name), without_extension(name), OWN_DEPTH)).filter((file) => file !== void 0);
1019
+ 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);
1528
1020
  }
1529
1021
  function unit_directory(directory, session_id) {
1530
- return path4.join(directory, session_id, UNIT_DIRECTORY);
1022
+ return path5.join(directory, session_id, UNIT_DIRECTORY);
1531
1023
  }
1532
1024
  var UNIT_DEPTH = 1;
1533
1025
  function level_units(subagents_directory, prefix, depth) {
1534
1026
  return read_directory(subagents_directory).filter((name) => is_transcript(name)).map(
1535
1027
  (name) => to_session_file(
1536
- path4.join(subagents_directory, name),
1028
+ path5.join(subagents_directory, name),
1537
1029
  `${prefix}${UNIT_ID_SEPARATOR}${without_extension(name)}`,
1538
1030
  depth
1539
1031
  )
@@ -1559,9 +1051,9 @@ function list_sessions(directory) {
1559
1051
  (left, right) => right.modified_ms - left.modified_ms
1560
1052
  );
1561
1053
  }
1562
- function list_sessions_across(directories2) {
1054
+ function list_sessions_across(directories) {
1563
1055
  const seen = /* @__PURE__ */ new Set();
1564
- const merged = directories2.flatMap((directory) => list_sessions(directory));
1056
+ const merged = directories.flatMap((directory) => list_sessions(directory));
1565
1057
  const newest_first = merged.toSorted((left, right) => right.modified_ms - left.modified_ms);
1566
1058
  const kept = [];
1567
1059
  for (const file of newest_first) {
@@ -1625,8 +1117,8 @@ function directory_exists(directory) {
1625
1117
  return false;
1626
1118
  }
1627
1119
  }
1628
- function searched_directories(directories2) {
1629
- return directories2.map((directory) => ({
1120
+ function searched_directories(directories) {
1121
+ return directories.map((directory) => ({
1630
1122
  path: directory,
1631
1123
  exists: directory_exists(directory)
1632
1124
  }));
@@ -1772,11 +1264,11 @@ var own_session = {
1772
1264
 
1773
1265
  // scripts/run/carry/run-carry-conversation.ts
1774
1266
  var CONVERSATION_QUIET_MS = 6e5;
1775
- function own_transcript(environment = process.env, directories2 = cost_transcript.transcript_directories(process.cwd())) {
1267
+ function own_transcript(environment = process.env, directories = cost_transcript.transcript_directories(process.cwd())) {
1776
1268
  const session_id = own_session.session_id_of(environment);
1777
1269
  if (session_id === void 0) return void 0;
1778
1270
  const name = `${session_id}${cost_transcript.TRANSCRIPT_EXTENSION}`;
1779
- return directories2.map((directory) => path5.join(directory, name)).find((file) => existsSync(file));
1271
+ return directories.map((directory) => path6.join(directory, name)).find((file) => existsSync(file));
1780
1272
  }
1781
1273
  function modified_ms(transcript) {
1782
1274
  try {
@@ -1810,7 +1302,7 @@ var run_carry_conversation = {
1810
1302
  };
1811
1303
 
1812
1304
  // scripts/run/carry/run-carry.ts
1813
- var CARRY_PREFIX = "josh-run-carry-";
1305
+ var CARRY_PREFIX = durable_state.PREFIX.CARRY;
1814
1306
  var REPOSITORY_DIRECTORY_INDEX = 1;
1815
1307
  var NO_INCREMENT3 = 0;
1816
1308
  var MAX_CUTS = 6;
@@ -1844,11 +1336,11 @@ var run_carry_schema = z2.object({
1844
1336
  lane_limit: z2.number().int().positive().optional()
1845
1337
  });
1846
1338
  function carry_path(git_directory) {
1847
- return stamp_file.stamp_path(CARRY_PREFIX, git_directory);
1339
+ return durable_state.path(CARRY_PREFIX, git_directory);
1848
1340
  }
1849
1341
  async function repository_directory() {
1850
- const directories2 = await git_command.git_directories();
1851
- return directories2[REPOSITORY_DIRECTORY_INDEX];
1342
+ const directories = await git_command.git_directories();
1343
+ return directories[REPOSITORY_DIRECTORY_INDEX];
1852
1344
  }
1853
1345
  function parse_carry(raw) {
1854
1346
  return json_value.parse_with(raw, run_carry_schema);
@@ -1861,11 +1353,11 @@ function classify2(raw) {
1861
1353
  }
1862
1354
  return { kind: "carried", carry };
1863
1355
  }
1864
- function read_carry(target) {
1865
- return classify2(stamp_file.read_stamp_text(target));
1356
+ function read_carry(target2) {
1357
+ return classify2(stamp_file.read_stamp_text(target2));
1866
1358
  }
1867
- function owner_of(pid, read3 = process_identity.read_start, transcript = run_carry_conversation.own_transcript()) {
1868
- return { pid, start: read3(pid), transcript };
1359
+ function owner_of(pid, read = process_identity.read_start, transcript = run_carry_conversation.own_transcript()) {
1360
+ return { pid, start: read(pid), transcript };
1869
1361
  }
1870
1362
  function fresh_carry(invocation, owner, now) {
1871
1363
  return {
@@ -1882,11 +1374,11 @@ function fresh_carry(invocation, owner, now) {
1882
1374
  is_owner_headless: owner.is_headless
1883
1375
  };
1884
1376
  }
1885
- function begin_carry(target, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
1377
+ function begin_carry(target2, invocation, owner = NO_OWNER, now = /* @__PURE__ */ new Date()) {
1886
1378
  const carry = fresh_carry(invocation, owner, now);
1887
- return stamp_file.create_stamp(target, carry) ? carry : void 0;
1379
+ return stamp_file.create_stamp(target2, carry) ? carry : void 0;
1888
1380
  }
1889
- function adopt_carry(target, carry, owner = NO_OWNER) {
1381
+ function adopt_carry(target2, carry, owner = NO_OWNER) {
1890
1382
  const next = {
1891
1383
  ...carry,
1892
1384
  owner_pid: owner.pid,
@@ -1895,8 +1387,8 @@ function adopt_carry(target, carry, owner = NO_OWNER) {
1895
1387
  is_owner_headless: owner.is_headless,
1896
1388
  is_handed_off: false
1897
1389
  };
1898
- stamp_file.remove_stamp(target);
1899
- return stamp_file.create_stamp(target, next) ? next : void 0;
1390
+ stamp_file.remove_stamp(target2);
1391
+ return stamp_file.create_stamp(target2, next) ? next : void 0;
1900
1392
  }
1901
1393
  function is_owner_live(carry, now = /* @__PURE__ */ new Date(), same_process = process_identity.is_same_process) {
1902
1394
  if (same_process(carry.owner_pid, carry.owner_start) !== false) return true;
@@ -1929,11 +1421,11 @@ function is_count_refused(carry, owner) {
1929
1421
  function is_at_cut_cap(carry) {
1930
1422
  return carry.cuts >= MAX_CUTS;
1931
1423
  }
1932
- function end_carry(target) {
1933
- stamp_file.remove_stamp(target);
1424
+ function end_carry(target2) {
1425
+ stamp_file.remove_stamp(target2);
1934
1426
  }
1935
- function retrospective_done_of(read3) {
1936
- return read3.kind === "carried" && read3.carry.retrospective === true;
1427
+ function retrospective_done_of(read) {
1428
+ return read.kind === "carried" && read.carry.retrospective === true;
1937
1429
  }
1938
1430
  function remaining_of(carry) {
1939
1431
  if (carry === void 0) return void 0;
@@ -2015,88 +1507,413 @@ var run_carry = {
2015
1507
  unreadable_message
2016
1508
  };
2017
1509
 
2018
- // ports/index.js
2019
- import { existsSync as existsSync2 } from "node:fs";
2020
- import path6 from "node:path";
2021
- var PORT_SEED_KEY = "PORT_SEED";
2022
- var LANE_SEAT_KEY = "JOSH_LANE_SEAT";
2023
- var ENV_FILE_NAME = ".env";
2024
- var PACKAGE_FILE_NAME = "package.json";
2025
- var PROJECT_ENVIRONMENT_KEYS = /* @__PURE__ */ new Set([PORT_SEED_KEY, LANE_SEAT_KEY, "PLAYWRIGHT_REUSE_SERVER"]);
2026
- var DEV_PORT_BASE = 5173;
2027
- var PREVIEW_PORT_BASE = 4173;
2028
- var MIN_SEED = 0;
2029
- var SEED_LANE_MULTIPLIER = 10;
2030
- var MAX_LANE = 9;
2031
- var MAX_SEED = 99;
2032
- var INTEGER_PATTERN = /^\d+$/u;
2033
- function fail_invalid(key, raw, max) {
2034
- throw new Error(
2035
- `${key} must be an integer between ${MIN_SEED} and ${max}, got ${JSON.stringify(raw)}. Unset it to use the default ports (dev ${DEV_PORT_BASE}, preview ${PREVIEW_PORT_BASE}).`
2036
- );
1510
+ // scripts/lane/lane-ledger-write.ts
1511
+ import { closeSync, constants as constants2, openSync, writeSync } from "node:fs";
1512
+
1513
+ // scripts/lane/lane-ledger-schema.ts
1514
+ import { z as z4 } from "zod";
1515
+
1516
+ // scripts/lane/lane-ledger-kind.ts
1517
+ var KIND = {
1518
+ MERGE: "merge",
1519
+ GATE: "gate",
1520
+ LOAD: "load",
1521
+ DISPATCH: "dispatch",
1522
+ STAGE: "stage",
1523
+ STOP: "stop",
1524
+ OVERLAP: "overlap",
1525
+ HELD: "held",
1526
+ RELEASED: "released",
1527
+ ROUND_ONE: "round-one",
1528
+ ROUND_TWO: "round-two",
1529
+ OFFERABLE: "offerable",
1530
+ CORE_WAIT: "core-wait",
1531
+ UNIT_FILES: "unit-files",
1532
+ TEST_RELATED: "test-related",
1533
+ TEST_PINNED: "test-pinned",
1534
+ SPLIT_NOTICE: "split-notice",
1535
+ SPLIT_FILED: "split-filed",
1536
+ UNPLANNED_NOTICE: "unplanned-notice",
1537
+ LANE_STATE: "lane-state",
1538
+ PUSH_MISS: "push-miss",
1539
+ SHIP_LAP: "ship-lap"
1540
+ };
1541
+ var lane_ledger_kind = { KIND };
1542
+
1543
+ // scripts/lane/lane-ledger-schema-ship.ts
1544
+ import { z as z3 } from "zod";
1545
+ var { KIND: KIND2 } = lane_ledger_kind;
1546
+ var stop_schema = z3.object({
1547
+ kind: z3.literal(KIND2.STOP),
1548
+ at: z3.string(),
1549
+ issue: z3.number(),
1550
+ reason: z3.string(),
1551
+ cause: z3.string().optional(),
1552
+ preconditions: z3.array(z3.string()).optional(),
1553
+ findings: z3.array(z3.string()).optional()
1554
+ });
1555
+ var unplanned_notice_schema = z3.object({
1556
+ kind: z3.literal(KIND2.UNPLANNED_NOTICE),
1557
+ at: z3.string(),
1558
+ issue: z3.number(),
1559
+ files: z3.array(z3.string())
1560
+ });
1561
+ var ship_lap_schema = z3.object({
1562
+ kind: z3.literal(KIND2.SHIP_LAP),
1563
+ at: z3.string(),
1564
+ issue: z3.number(),
1565
+ stage: z3.string(),
1566
+ step: z3.string(),
1567
+ elapsed_ms: z3.number()
1568
+ });
1569
+ var lane_ledger_schema_ship = { ship_lap_schema, stop_schema, unplanned_notice_schema };
1570
+
1571
+ // scripts/lane/lane-ledger-schema.ts
1572
+ var { KIND: KIND3 } = lane_ledger_kind;
1573
+ var { ship_lap_schema: ship_lap_schema2, stop_schema: stop_schema2, unplanned_notice_schema: unplanned_notice_schema2 } = lane_ledger_schema_ship;
1574
+ var merge_schema = z4.object({ kind: z4.literal(KIND3.MERGE), at: z4.string(), issue: z4.number() });
1575
+ var check_schema = z4.object({
1576
+ label: z4.string(),
1577
+ elapsed_ms: z4.number(),
1578
+ is_passed: z4.boolean(),
1579
+ is_reused: z4.boolean().optional(),
1580
+ // The CPU milliseconds the check's process tree spent, so a core weight can be re-measured from
1581
+ // the ledger (joshuafolkken/kit#4362). Absent where the gate could not read it (off macOS).
1582
+ cpu_ms: z4.number().optional(),
1583
+ // Why the unit leg ran the whole suite instead of the related tests — a stable kind, never the
1584
+ // file it names (joshuafolkken/kit#4397). Absent when it narrowed, and on every other check.
1585
+ fallback: z4.string().optional(),
1586
+ // The unit leg's since-green no-op: nothing moved, so it ran no test (joshuafolkken/kit#4457).
1587
+ is_unmoved: z4.boolean().optional(),
1588
+ // The width the check asked the core budget for, the width it ran at and how long it waited, so a
1589
+ // unit claim's wait for room is read per run (joshuafolkken/kit#4451). Absent on a check that
1590
+ // claimed none — a reused one, or one inside another gate's claim.
1591
+ claim: z4.object({ requested: z4.number(), granted: z4.number(), waited_ms: z4.number() }).optional()
1592
+ });
1593
+ var gate_schema = z4.object({
1594
+ kind: z4.literal(KIND3.GATE),
1595
+ at: z4.string(),
1596
+ elapsed_ms: z4.number(),
1597
+ is_passed: z4.boolean(),
1598
+ // The unit suite's own duration, present when this gate ran it — the one
1599
+ // record of a full vitest run `josh metrics` reads, so the suite is never timed twice.
1600
+ unit_ms: z4.number().optional(),
1601
+ // The whole cores busy outside this gate, beyond the machine's baseline, at its start or its end —
1602
+ // whichever was higher. Absent when the machine could not be read.
1603
+ external_cores: z4.number().optional(),
1604
+ // Each check's own duration and verdict, so `josh lane:stats` can name the check a slow gate waited
1605
+ // on. A reused check started no process: its row says so, and its zero is no timing.
1606
+ checks: z4.array(check_schema).optional(),
1607
+ // A gate that reused a green record for this tree and base and started no check: counted, never
1608
+ // timed (joshuafolkken/kit#4397).
1609
+ is_reused: z4.boolean().optional(),
1610
+ // The lane the gate ran in, so `josh lane:breakdown` puts its checks under the lane's ship gate;
1611
+ // absent outside a lane and on a row written before it (joshuafolkken/kit#5319).
1612
+ issue: z4.number().optional()
1613
+ });
1614
+ var process_kind_schema = z4.object({
1615
+ kind: z4.string(),
1616
+ cpu_percent: z4.number(),
1617
+ rss_mb: z4.number(),
1618
+ count: z4.number()
1619
+ });
1620
+ var load_schema = z4.object({
1621
+ kind: z4.literal(KIND3.LOAD),
1622
+ at: z4.string(),
1623
+ load: z4.number(),
1624
+ available_mb: z4.number().optional(),
1625
+ swapped_mb: z4.number().optional(),
1626
+ lanes: z4.number().optional(),
1627
+ // The heaviest process kinds at the instant of the sample (`lane-process-load.ts`), so the load the
1628
+ // core budget's ledger does not explain can be read back by what made it (joshuafolkken/kit#3874).
1629
+ processes: z4.array(process_kind_schema).optional()
1630
+ });
1631
+ var dispatch_schema = z4.object({
1632
+ kind: z4.literal(KIND3.DISPATCH),
1633
+ at: z4.string(),
1634
+ issue: z4.number()
1635
+ });
1636
+ var stage_schema = z4.object({
1637
+ kind: z4.literal(KIND3.STAGE),
1638
+ at: z4.string(),
1639
+ stage: z4.string(),
1640
+ elapsed_ms: z4.number(),
1641
+ issue: z4.number().optional(),
1642
+ last_check: z4.string().optional(),
1643
+ check_ms: z4.record(z4.string(), z4.number()).optional()
1644
+ });
1645
+ var overlap_schema = z4.object({
1646
+ kind: z4.literal(KIND3.OVERLAP),
1647
+ at: z4.string(),
1648
+ issue: z4.number(),
1649
+ lanes: z4.array(z4.number()),
1650
+ paths: z4.array(z4.string()),
1651
+ waited_ms: z4.number(),
1652
+ is_cleared: z4.boolean()
1653
+ });
1654
+ var held_schema = z4.object({
1655
+ kind: z4.literal(KIND3.HELD),
1656
+ at: z4.string(),
1657
+ reason: z4.string(),
1658
+ waiting: z4.array(z4.number()).optional()
1659
+ });
1660
+ var released_schema = z4.object({ kind: z4.literal(KIND3.RELEASED), at: z4.string() });
1661
+ var lane_state_schema = z4.object({
1662
+ kind: z4.literal(KIND3.LANE_STATE),
1663
+ at: z4.string(),
1664
+ issue: z4.number(),
1665
+ state: z4.enum(["paused", "running"])
1666
+ });
1667
+ var round_one_schema = z4.object({
1668
+ kind: z4.literal(KIND3.ROUND_ONE),
1669
+ at: z4.string(),
1670
+ issue: z4.number(),
1671
+ verdict: z4.string()
1672
+ });
1673
+ var round_two_schema = z4.object({
1674
+ kind: z4.literal(KIND3.ROUND_TWO),
1675
+ at: z4.string(),
1676
+ issue: z4.number(),
1677
+ verdict: z4.string(),
1678
+ code: z4.string()
1679
+ });
1680
+ var offerable_schema = z4.object({
1681
+ kind: z4.literal(KIND3.OFFERABLE),
1682
+ at: z4.string(),
1683
+ is_offerable: z4.boolean()
1684
+ });
1685
+ var core_wait_schema = z4.object({
1686
+ kind: z4.literal(KIND3.CORE_WAIT),
1687
+ at: z4.string(),
1688
+ command: z4.string(),
1689
+ waited_ms: z4.number(),
1690
+ issue: z4.number().optional()
1691
+ });
1692
+ var unit_file_schema = z4.object({ file: z4.string(), elapsed_ms: z4.number() });
1693
+ var unit_files_schema = z4.object({
1694
+ kind: z4.literal(KIND3.UNIT_FILES),
1695
+ at: z4.string(),
1696
+ files: z4.array(unit_file_schema)
1697
+ });
1698
+ var test_related_schema = z4.object({
1699
+ kind: z4.literal(KIND3.TEST_RELATED),
1700
+ at: z4.string(),
1701
+ scope: z4.string(),
1702
+ changed: z4.number(),
1703
+ synced: z4.number(),
1704
+ since_map: z4.number(),
1705
+ readers: z4.number(),
1706
+ test_files: z4.number().optional(),
1707
+ trigger_files: z4.array(z4.string()).optional(),
1708
+ elapsed_ms: z4.number()
1709
+ });
1710
+ var pinned_origin_schema = z4.enum(["run-review", "pre-detach", "manual"]);
1711
+ var test_pinned_probe_schema = z4.object({
1712
+ file: z4.string(),
1713
+ tests: z4.number().optional(),
1714
+ elapsed_ms: z4.number()
1715
+ });
1716
+ var test_pinned_schema = z4.object({
1717
+ kind: z4.literal(KIND3.TEST_PINNED),
1718
+ at: z4.string(),
1719
+ issue: z4.number().optional(),
1720
+ held: z4.number(),
1721
+ rewired: z4.number().optional(),
1722
+ probes: z4.array(test_pinned_probe_schema),
1723
+ elapsed_ms: z4.number(),
1724
+ origin: pinned_origin_schema.optional(),
1725
+ discarded: z4.boolean().optional()
1726
+ });
1727
+ var split_notice_schema = z4.object({
1728
+ kind: z4.literal(KIND3.SPLIT_NOTICE),
1729
+ at: z4.string(),
1730
+ issue: z4.number(),
1731
+ files: z4.number(),
1732
+ lines: z4.number()
1733
+ });
1734
+ var split_filed_schema = z4.object({
1735
+ kind: z4.literal(KIND3.SPLIT_FILED),
1736
+ at: z4.string(),
1737
+ issue: z4.number(),
1738
+ child: z4.string()
1739
+ });
1740
+ var push_miss_schema = z4.object({
1741
+ kind: z4.literal(KIND3.PUSH_MISS),
1742
+ at: z4.string(),
1743
+ scope: z4.enum(["whole", "related"]),
1744
+ reason: z4.string()
1745
+ });
1746
+ var entry_schema = z4.discriminatedUnion("kind", [
1747
+ merge_schema,
1748
+ gate_schema,
1749
+ load_schema,
1750
+ dispatch_schema,
1751
+ stage_schema,
1752
+ stop_schema2,
1753
+ overlap_schema,
1754
+ held_schema,
1755
+ released_schema,
1756
+ round_one_schema,
1757
+ round_two_schema,
1758
+ offerable_schema,
1759
+ core_wait_schema,
1760
+ unit_files_schema,
1761
+ test_related_schema,
1762
+ test_pinned_schema,
1763
+ split_notice_schema,
1764
+ split_filed_schema,
1765
+ unplanned_notice_schema2,
1766
+ lane_state_schema,
1767
+ push_miss_schema,
1768
+ ship_lap_schema2
1769
+ ]);
1770
+ var lane_ledger_schema = { KIND: KIND3, entry_schema, pinned_origin_schema };
1771
+
1772
+ // scripts/lane/lane-ledger-write.ts
1773
+ var LEDGER_PREFIX = durable_state.PREFIX.LANE_LEDGER;
1774
+ var LEDGER_SUFFIX = ".jsonl";
1775
+ var LINE_SEPARATOR = "\n";
1776
+ var CI_WAIT_STAGE = "ci-wait";
1777
+ var CODERABBIT_WAIT_STAGE = "coderabbit-wait";
1778
+ var CODERABBIT_RATE_LIMIT_STAGE = "coderabbit-rate-limit";
1779
+ var CODERABBIT_RETRIGGER_STAGE = "coderabbit-retriggered";
1780
+ var PRE_DETACH_STAGE = "pre-detach";
1781
+ var ROUND_ONE_REUSED = "reused";
1782
+ var LEDGER_FILE_MODE = 384;
1783
+ var { O_APPEND, O_CREAT, O_NOFOLLOW, O_WRONLY } = constants2;
1784
+ var APPEND_FLAGS = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
1785
+ var { KIND: KIND4 } = lane_ledger_schema;
1786
+ function target_of(repository) {
1787
+ return durable_state.path(LEDGER_PREFIX, repository, LEDGER_SUFFIX);
1788
+ }
1789
+ async function target() {
1790
+ if (process.env["VITEST"] !== void 0) return void 0;
1791
+ try {
1792
+ const repository = await run_carry.repository_directory();
1793
+ return repository === void 0 ? void 0 : target_of(repository);
1794
+ } catch {
1795
+ return void 0;
1796
+ }
2037
1797
  }
2038
- function read_trimmed(environment, key) {
2039
- const raw = environment[key];
2040
- return raw === void 0 ? "" : raw.trim();
1798
+ function append(path12, entry) {
1799
+ const descriptor = openSync(path12, APPEND_FLAGS, LEDGER_FILE_MODE);
1800
+ try {
1801
+ if (stamp_file.is_own_regular_file(path12)) {
1802
+ writeSync(descriptor, `${JSON.stringify(entry)}${LINE_SEPARATOR}`);
1803
+ }
1804
+ } finally {
1805
+ closeSync(descriptor);
1806
+ }
2041
1807
  }
2042
- function resolve_bounded(environment, key, max) {
2043
- const trimmed = read_trimmed(environment, key);
2044
- if (trimmed.length === 0) return MIN_SEED;
2045
- if (!INTEGER_PATTERN.test(trimmed)) fail_invalid(key, trimmed, max);
2046
- const value = Number(trimmed);
2047
- if (value > max) fail_invalid(key, trimmed, max);
2048
- return value;
1808
+ async function record(entry, path12) {
1809
+ try {
1810
+ const destination = path12 ?? await target();
1811
+ if (destination !== void 0) append(destination, entry);
1812
+ } catch {
1813
+ }
2049
1814
  }
2050
- function resolve_seed(environment = process.env) {
2051
- return resolve_bounded(environment, PORT_SEED_KEY, MAX_SEED);
1815
+ function now_iso() {
1816
+ return (/* @__PURE__ */ new Date()).toISOString();
2052
1817
  }
2053
- function resolve_lane(environment = process.env) {
2054
- return resolve_bounded(environment, LANE_SEAT_KEY, MAX_LANE);
1818
+ async function record_gate(path12, gate) {
1819
+ await record({ kind: KIND4.GATE, at: now_iso(), ...gate }, path12);
2055
1820
  }
2056
- function resolve_offset(environment = process.env) {
2057
- return resolve_seed(environment) * SEED_LANE_MULTIPLIER + resolve_lane(environment);
1821
+ async function record_merge(issue2, at = /* @__PURE__ */ new Date()) {
1822
+ await record({ kind: KIND4.MERGE, at: at.toISOString(), issue: issue2 });
2058
1823
  }
2059
- function offset_from(base, environment) {
2060
- return base + resolve_offset(environment);
1824
+ async function record_dispatch(issue2, path12) {
1825
+ await record({ kind: KIND4.DISPATCH, at: now_iso(), issue: issue2 }, path12);
2061
1826
  }
2062
- function resolve_development_port(environment = process.env) {
2063
- return offset_from(DEV_PORT_BASE, environment);
1827
+ async function record_stage(stage, path12) {
1828
+ await record({ kind: KIND4.STAGE, at: now_iso(), ...stage }, path12);
2064
1829
  }
2065
- function resolve_preview_port(environment = process.env) {
2066
- return offset_from(PREVIEW_PORT_BASE, environment);
1830
+ async function record_stop(stop, path12) {
1831
+ await record({ kind: KIND4.STOP, at: now_iso(), ...stop }, path12);
2067
1832
  }
2068
- function resolve_project_directory(directory) {
2069
- const start = path6.resolve(directory);
2070
- let current = start;
2071
- while (!existsSync2(path6.join(current, PACKAGE_FILE_NAME))) {
2072
- const parent = path6.dirname(current);
2073
- if (parent === current) return start;
2074
- current = parent;
2075
- }
2076
- return current;
1833
+ async function record_overlap(overlap, path12) {
1834
+ await record({ kind: KIND4.OVERLAP, at: now_iso(), ...overlap }, path12);
2077
1835
  }
2078
- function discard_loaded_keys(snapshot) {
2079
- for (const key of Object.keys(process.env)) {
2080
- if (!PROJECT_ENVIRONMENT_KEYS.has(key) && !Object.hasOwn(snapshot, key)) {
2081
- Reflect.deleteProperty(process.env, key);
2082
- }
2083
- }
1836
+ async function record_held(held, path12) {
1837
+ const waiting = held.waiting ?? [];
1838
+ const named = waiting.length > 0 ? { waiting: [...waiting] } : {};
1839
+ await record({ kind: KIND4.HELD, at: now_iso(), reason: held.reason, ...named }, path12);
2084
1840
  }
2085
- function load_environment_file(directory = process.cwd()) {
2086
- const file = path6.join(resolve_project_directory(directory), ENV_FILE_NAME);
2087
- if (!existsSync2(file)) return false;
2088
- const snapshot = { ...process.env };
2089
- process.loadEnvFile(file);
2090
- discard_loaded_keys(snapshot);
2091
- return true;
1841
+ async function record_released(path12) {
1842
+ await record({ kind: KIND4.RELEASED, at: now_iso() }, path12);
2092
1843
  }
2093
- var ports = {
2094
- load_environment_file,
2095
- resolve_project_directory,
2096
- resolve_seed,
2097
- resolve_lane,
2098
- resolve_development_port,
2099
- resolve_preview_port
1844
+ async function record_lane_state(change, path12) {
1845
+ await record({ kind: KIND4.LANE_STATE, at: now_iso(), ...change }, path12);
1846
+ }
1847
+ async function record_offerable(is_offerable, path12) {
1848
+ await record({ kind: KIND4.OFFERABLE, at: now_iso(), is_offerable }, path12);
1849
+ }
1850
+ async function record_round_one(round_one, path12) {
1851
+ await record({ kind: KIND4.ROUND_ONE, at: now_iso(), ...round_one }, path12);
1852
+ }
1853
+ async function record_round_two(round_two, path12) {
1854
+ await record({ kind: KIND4.ROUND_TWO, at: now_iso(), ...round_two }, path12);
1855
+ }
1856
+ async function record_core_wait(wait, path12) {
1857
+ await record({ kind: KIND4.CORE_WAIT, at: now_iso(), ...wait }, path12);
1858
+ }
1859
+ async function record_unit_files(files, path12) {
1860
+ await record({ kind: KIND4.UNIT_FILES, at: now_iso(), files: [...files] }, path12);
1861
+ }
1862
+ async function record_test_related(run, path12) {
1863
+ await record({ kind: KIND4.TEST_RELATED, at: now_iso(), ...run }, path12);
1864
+ }
1865
+ async function record_test_pinned(run, path12) {
1866
+ await record({ kind: KIND4.TEST_PINNED, at: now_iso(), ...run }, path12);
1867
+ }
1868
+ async function record_split_notice(notice, path12) {
1869
+ await record({ kind: KIND4.SPLIT_NOTICE, at: now_iso(), ...notice }, path12);
1870
+ }
1871
+ async function record_split_filed(filed, path12) {
1872
+ await record({ kind: KIND4.SPLIT_FILED, at: now_iso(), ...filed }, path12);
1873
+ }
1874
+ async function record_push_miss(miss, path12) {
1875
+ await record({ kind: KIND4.PUSH_MISS, at: now_iso(), ...miss }, path12);
1876
+ }
1877
+ async function record_ship_lap(lap, path12) {
1878
+ await record({ kind: KIND4.SHIP_LAP, at: now_iso(), ...lap }, path12);
1879
+ }
1880
+ async function record_unplanned_notice(notice, path12) {
1881
+ await record({ kind: KIND4.UNPLANNED_NOTICE, at: now_iso(), ...notice }, path12);
1882
+ }
1883
+ var lane_ledger_write = {
1884
+ CI_WAIT_STAGE,
1885
+ CODERABBIT_RATE_LIMIT_STAGE,
1886
+ CODERABBIT_RETRIGGER_STAGE,
1887
+ CODERABBIT_WAIT_STAGE,
1888
+ KIND: KIND4,
1889
+ LINE_SEPARATOR,
1890
+ PRE_DETACH_STAGE,
1891
+ ROUND_ONE_REUSED,
1892
+ append,
1893
+ record,
1894
+ record_core_wait,
1895
+ record_dispatch,
1896
+ record_gate,
1897
+ record_held,
1898
+ record_lane_state,
1899
+ record_released,
1900
+ record_merge,
1901
+ record_overlap,
1902
+ record_offerable,
1903
+ record_push_miss,
1904
+ record_round_one,
1905
+ record_round_two,
1906
+ record_ship_lap,
1907
+ record_split_filed,
1908
+ record_split_notice,
1909
+ record_stage,
1910
+ record_stop,
1911
+ record_test_pinned,
1912
+ record_test_related,
1913
+ record_unit_files,
1914
+ record_unplanned_notice,
1915
+ target,
1916
+ target_of
2100
1917
  };
2101
1918
 
2102
1919
  // scripts/issue/issue-cite.ts
@@ -2138,17 +1955,17 @@ function bare_target(token, default_repo) {
2138
1955
  function parse_target(token, default_repo) {
2139
1956
  return qualified_target(token) ?? bare_target(token, default_repo);
2140
1957
  }
2141
- function label(target) {
2142
- return plain(target.number, target.repo);
1958
+ function label(target2) {
1959
+ return plain(target2.number, target2.repo);
2143
1960
  }
2144
- function missing_line(target) {
2145
- return `\u2716 ${label(target)}: issue does not resolve \u2014 check the number and the repository`;
1961
+ function missing_line(target2) {
1962
+ return `\u2716 ${label(target2)}: issue does not resolve \u2014 check the number and the repository`;
2146
1963
  }
2147
- function unreadable_line(target) {
2148
- return `\u2716 ${label(target)}: could not be read \u2014 a rate limit, expired auth, or a dropped connection`;
1964
+ function unreadable_line(target2) {
1965
+ return `\u2716 ${label(target2)}: could not be read \u2014 a rate limit, expired auth, or a dropped connection`;
2149
1966
  }
2150
- function no_repo_line(target) {
2151
- return `\u2716 ${label(target)}: could not read this repository \u2014 check gh auth and the origin remote`;
1967
+ function no_repo_line(target2) {
1968
+ return `\u2716 ${label(target2)}: could not read this repository \u2014 check gh auth and the origin remote`;
2152
1969
  }
2153
1970
  var issue_cite = {
2154
1971
  citation_line,
@@ -2162,65 +1979,8 @@ var issue_cite = {
2162
1979
  unreadable_line
2163
1980
  };
2164
1981
 
2165
- // scripts/git/git-common-directory.ts
2166
- import { execFileSync as execFileSync2 } from "node:child_process";
2167
- var OWN_GIT_DIRECTORY = 0;
2168
- var COMMON_GIT_DIRECTORY = 1;
2169
- var PROBE_TIMEOUT_MS2 = 5e3;
2170
- var answers = /* @__PURE__ */ new Map();
2171
- function probe_environment(cwd) {
2172
- if (cwd === void 0) return process.env;
2173
- return { ...process.env, ...git_location_environment.location_free_environment() };
2174
- }
2175
- function cache_key(cwd) {
2176
- if (cwd !== void 0) return `explicit\0${cwd}`;
2177
- const locations = GIT_LOCATION_VARIABLES.map((name) => process.env[name] ?? "");
2178
- return ["inherited", process.cwd(), ...locations].join("\0");
2179
- }
2180
- function read_directories(cwd) {
2181
- try {
2182
- const output = execFileSync2(
2183
- git_utilities.get_git_command_for_spawn(),
2184
- [...git_command.GIT_DIRECTORY_ARGUMENTS],
2185
- {
2186
- cwd,
2187
- env: probe_environment(cwd),
2188
- encoding: "utf8",
2189
- stdio: ["ignore", "pipe", "ignore"],
2190
- timeout: PROBE_TIMEOUT_MS2
2191
- }
2192
- );
2193
- return output.split("\n").filter((line) => line !== "");
2194
- } catch {
2195
- return [];
2196
- }
2197
- }
2198
- function directories(cwd) {
2199
- const key = cache_key(cwd);
2200
- const known = answers.get(key);
2201
- if (known !== void 0) return known;
2202
- const read3 = read_directories(cwd);
2203
- if (read3.length > 0) answers.set(key, read3);
2204
- return read3;
2205
- }
2206
- function own(cwd) {
2207
- return directories(cwd)[OWN_GIT_DIRECTORY];
2208
- }
2209
- function repository(cwd) {
2210
- return directories(cwd)[COMMON_GIT_DIRECTORY];
2211
- }
2212
- function select_linked(found) {
2213
- const own_directory = found[OWN_GIT_DIRECTORY];
2214
- const common = found[COMMON_GIT_DIRECTORY];
2215
- return own_directory === void 0 || common === void 0 || own_directory === common ? void 0 : common;
2216
- }
2217
- function resolve(cwd) {
2218
- return select_linked(directories(cwd));
2219
- }
2220
- var git_common_directory = { directories, own, repository, resolve, select_linked };
2221
-
2222
1982
  // scripts/run/ship/run-ship-stage.ts
2223
- import { z as z3 } from "zod";
1983
+ import { z as z5 } from "zod";
2224
1984
  var STAGE = {
2225
1985
  PREFLIGHT: "preflight",
2226
1986
  REVIEW: "review",
@@ -2245,11 +2005,12 @@ var WORD_SEPARATOR = " ";
2245
2005
  var STARTED_SEPARATOR = ",";
2246
2006
  var STARTED_INDEX = 3;
2247
2007
  var WORD_COUNT = STARTED_INDEX + 1;
2248
- var record_schema = z3.object({
2249
- done: z3.array(z3.string()),
2250
- started: z3.array(z3.string()).default([]),
2251
- is_merge_waiting: z3.boolean().default(false),
2252
- is_place_waiting: z3.boolean().default(false)
2008
+ var REASON_SEPARATOR = " | ";
2009
+ var record_schema = z5.object({
2010
+ done: z5.array(z5.string()),
2011
+ started: z5.array(z5.string()).default([]),
2012
+ is_merge_waiting: z5.boolean().default(false),
2013
+ is_place_waiting: z5.boolean().default(false)
2253
2014
  });
2254
2015
  var EMPTY_RECORD = {
2255
2016
  done: [],
@@ -2257,70 +2018,70 @@ var EMPTY_RECORD = {
2257
2018
  is_merge_waiting: false,
2258
2019
  is_place_waiting: false
2259
2020
  };
2260
- function record_path(repository2, issue2) {
2261
- return stamp_file.stamp_path(`${RECORD_PREFIX}${issue2}${RECORD_SEPARATOR}`, repository2);
2021
+ function record_path(repository, issue2) {
2022
+ return stamp_file.stamp_path(`${RECORD_PREFIX}${issue2}${RECORD_SEPARATOR}`, repository);
2262
2023
  }
2263
2024
  function parse_record(raw) {
2264
2025
  return json_value.parse_with(raw, record_schema) ?? EMPTY_RECORD;
2265
2026
  }
2266
- function read_record(target) {
2267
- const raw = stamp_file.read_stamp_text(target);
2027
+ function read_record(target2) {
2028
+ const raw = stamp_file.read_stamp_text(target2);
2268
2029
  return raw === void 0 ? EMPTY_RECORD : parse_record(raw);
2269
2030
  }
2270
- function read_done(target) {
2271
- return new Set(read_record(target).done);
2031
+ function read_done(target2) {
2032
+ return new Set(read_record(target2).done);
2272
2033
  }
2273
- function mark_done(target, stage) {
2274
- const record = read_record(target);
2275
- stamp_file.replace_stamp(target, { ...record, done: [.../* @__PURE__ */ new Set([...record.done, stage])] });
2034
+ function mark_done(target2, stage) {
2035
+ const record2 = read_record(target2);
2036
+ stamp_file.replace_stamp(target2, { ...record2, done: [.../* @__PURE__ */ new Set([...record2.done, stage])] });
2276
2037
  }
2277
- function read_started(target) {
2278
- return read_record(target).started;
2038
+ function read_started(target2) {
2039
+ return read_record(target2).started;
2279
2040
  }
2280
- function mark_started(target, stage) {
2281
- const record = read_record(target);
2282
- stamp_file.replace_stamp(target, { ...record, started: [.../* @__PURE__ */ new Set([...record.started, stage])] });
2041
+ function mark_started(target2, stage) {
2042
+ const record2 = read_record(target2);
2043
+ stamp_file.replace_stamp(target2, { ...record2, started: [.../* @__PURE__ */ new Set([...record2.started, stage])] });
2283
2044
  }
2284
- function end_attempt(target) {
2285
- stamp_file.replace_stamp(target, { ...read_record(target), started: [], is_merge_waiting: false });
2045
+ function end_attempt(target2) {
2046
+ stamp_file.replace_stamp(target2, { ...read_record(target2), started: [], is_merge_waiting: false });
2286
2047
  }
2287
- function read_merge_waiting(target) {
2288
- return read_record(target).is_merge_waiting;
2048
+ function read_merge_waiting(target2) {
2049
+ return read_record(target2).is_merge_waiting;
2289
2050
  }
2290
- function mark_merge_waiting(target, is_merge_waiting) {
2291
- stamp_file.replace_stamp(target, { ...read_record(target), is_merge_waiting });
2051
+ function mark_merge_waiting(target2, is_merge_waiting) {
2052
+ stamp_file.replace_stamp(target2, { ...read_record(target2), is_merge_waiting });
2292
2053
  }
2293
- function read_place_waiting(target) {
2294
- return read_record(target).is_place_waiting;
2054
+ function read_place_waiting(target2) {
2055
+ return read_record(target2).is_place_waiting;
2295
2056
  }
2296
- function mark_place_waiting(target, is_place_waiting) {
2297
- stamp_file.replace_stamp(target, { ...read_record(target), is_place_waiting });
2057
+ function mark_place_waiting(target2, is_place_waiting) {
2058
+ stamp_file.replace_stamp(target2, { ...read_record(target2), is_place_waiting });
2298
2059
  }
2299
- function clear_waits(target) {
2300
- stamp_file.replace_stamp(target, {
2301
- ...read_record(target),
2060
+ function clear_waits(target2) {
2061
+ stamp_file.replace_stamp(target2, {
2062
+ ...read_record(target2),
2302
2063
  is_merge_waiting: false,
2303
2064
  is_place_waiting: false
2304
2065
  });
2305
2066
  }
2306
- function clear(target) {
2307
- stamp_file.remove_stamp(target);
2067
+ function clear(target2) {
2068
+ stamp_file.remove_stamp(target2);
2308
2069
  }
2309
2070
  function is_shipped(state) {
2310
2071
  return state.is_committed && state.is_pushed;
2311
2072
  }
2312
2073
  var DONE_BY = {
2313
2074
  // The preflight asks what the commit stage would refuse on, so a commit is
2314
- // its output as it is the gate's; a resumed commit stage still asks `git -y`'s own preflight.
2315
- [STAGE.PREFLIGHT]: (_done, state) => state.is_merged || state.is_committed,
2316
- // The `--review` round precedes the commit, so a commit is its output as it
2317
- // is the gate's. A record alone is not honored: before a commit the tree may have been edited since
2318
- // the recorded round, and only a commit pins the tree that round read — unless the issue changed since.
2319
- [STAGE.REVIEW]: (_done, state) => state.is_merged || state.is_committed && state.is_review_stale !== true,
2320
- [STAGE.GATE]: (_done, state) => state.is_merged || state.is_committed,
2321
- // The merge of the default branch before the commit: once committed, a
2322
- // conflicting pull request is the followup's to merge again.
2323
- [STAGE.SYNC]: (_done, state) => state.is_merged || state.is_committed,
2075
+ // its output; a resumed commit stage still asks `git -y`'s own preflight.
2076
+ [STAGE.PREFLIGHT]: (done, state) => state.is_merged || done.has(STAGE.PREFLIGHT) && state.is_committed,
2077
+ // The sync stage commits locally before the review round and the gate, without pushing
2078
+ // (`run-ship-sync.ts`), so a commit is neither's output: a pushed one on a clean tree is, as only the
2079
+ // commit stage after the gate pushes — unless the issue changed since.
2080
+ [STAGE.REVIEW]: (done, state) => state.is_merged || done.has(STAGE.REVIEW) && is_shipped(state) && state.is_review_stale !== true,
2081
+ [STAGE.GATE]: (done, state) => state.is_merged || done.has(STAGE.GATE) && is_shipped(state),
2082
+ // The merge of the default branch before the gate: once pushed, a default branch that
2083
+ // moved is the followup's to merge again.
2084
+ [STAGE.SYNC]: (done, state) => state.is_merged || done.has(STAGE.SYNC) && is_shipped(state),
2324
2085
  [STAGE.COMMIT]: (done, state) => state.is_merged || done.has(STAGE.COMMIT) && is_shipped(state),
2325
2086
  // The round-2 pass reads the pushed fix delta, so its record is honored only
2326
2087
  // while that push still stands — new work pushed on top reruns it.
@@ -2344,8 +2105,22 @@ function event_text(issue2, stage, phase, started = []) {
2344
2105
  const full = started.length > 0 ? [...words, listed] : words;
2345
2106
  return full.join(WORD_SEPARATOR);
2346
2107
  }
2108
+ function with_reason(text2, reason) {
2109
+ return reason === void 0 ? text2 : `${text2}${REASON_SEPARATOR}${reason}`;
2110
+ }
2111
+ function words_part(text2) {
2112
+ return text2.split(REASON_SEPARATOR, 1)[0] ?? "";
2113
+ }
2347
2114
  function started_of(text2) {
2348
- return text2.split(WORD_SEPARATOR, WORD_COUNT)[STARTED_INDEX]?.split(STARTED_SEPARATOR);
2115
+ return words_part(text2).split(WORD_SEPARATOR, WORD_COUNT)[STARTED_INDEX]?.split(STARTED_SEPARATOR);
2116
+ }
2117
+ function words_of(text2) {
2118
+ const [, stage = "", phase = ""] = words_part(text2).split(WORD_SEPARATOR, WORD_COUNT);
2119
+ return { stage, phase };
2120
+ }
2121
+ function reason_of(text2) {
2122
+ const at = text2.indexOf(REASON_SEPARATOR);
2123
+ return at === -1 ? void 0 : text2.slice(at + REASON_SEPARATOR.length);
2349
2124
  }
2350
2125
  var CONFLICT = "conflict";
2351
2126
  function stop_reason(stage, conflicts = []) {
@@ -2361,6 +2136,7 @@ var run_ship_stage = {
2361
2136
  end_attempt,
2362
2137
  event_text,
2363
2138
  is_done,
2139
+ is_shipped,
2364
2140
  mark_done,
2365
2141
  mark_merge_waiting,
2366
2142
  mark_place_waiting,
@@ -2369,19 +2145,22 @@ var run_ship_stage = {
2369
2145
  read_merge_waiting,
2370
2146
  read_place_waiting,
2371
2147
  read_started,
2148
+ reason_of,
2372
2149
  record_path,
2373
2150
  started_of,
2151
+ with_reason,
2152
+ words_of,
2374
2153
  stop_reason
2375
2154
  };
2376
2155
 
2377
2156
  // scripts/git/repository-lock.ts
2378
2157
  import { randomUUID as randomUUID2 } from "node:crypto";
2379
- import { linkSync, renameSync, rmSync as rmSync2 } from "node:fs";
2158
+ import { linkSync, renameSync, rmSync as rmSync3 } from "node:fs";
2380
2159
  import { setTimeout as sleep } from "node:timers/promises";
2381
2160
 
2382
2161
  // scripts/josh/process-owner.ts
2383
- import { z as z4 } from "zod";
2384
- var process_owner_schema = z4.object({ pid: z4.number(), process_start: z4.string().optional() });
2162
+ import { z as z6 } from "zod";
2163
+ var process_owner_schema = z6.object({ pid: z6.number(), process_start: z6.string().optional() });
2385
2164
 
2386
2165
  // scripts/git/repository-lock.ts
2387
2166
  var POLL_INTERVAL_MS = 200;
@@ -2395,53 +2174,53 @@ function parse_owner(raw) {
2395
2174
  const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw));
2396
2175
  return parsed.success ? parsed.data : void 0;
2397
2176
  }
2398
- function read_owner(target) {
2399
- return parse_owner(stamp_file.read_stamp_text(target));
2177
+ function read_owner(target2) {
2178
+ return parse_owner(stamp_file.read_stamp_text(target2));
2400
2179
  }
2401
2180
  function is_owner_gone(owner) {
2402
2181
  return process_identity.is_same_process(owner.pid, owner.process_start) === false;
2403
2182
  }
2404
- function restore(aside, target) {
2183
+ function restore(aside, target2) {
2405
2184
  try {
2406
- linkSync(aside, target);
2185
+ linkSync(aside, target2);
2407
2186
  } catch {
2408
2187
  }
2409
2188
  }
2410
- function stale_record(target, is_gone) {
2411
- const raw = stamp_file.read_stamp_text(target);
2189
+ function stale_record(target2, is_gone) {
2190
+ const raw = stamp_file.read_stamp_text(target2);
2412
2191
  const owner = parse_owner(raw);
2413
2192
  return owner !== void 0 && is_gone(owner) ? raw : void 0;
2414
2193
  }
2415
- function move_aside(target) {
2416
- const aside = `${target}.${String(process.pid)}.${randomUUID2()}`;
2194
+ function move_aside(target2) {
2195
+ const aside = `${target2}.${String(process.pid)}.${randomUUID2()}`;
2417
2196
  try {
2418
- renameSync(target, aside);
2197
+ renameSync(target2, aside);
2419
2198
  return aside;
2420
2199
  } catch {
2421
2200
  return void 0;
2422
2201
  }
2423
2202
  }
2424
- function clear_stale(target, is_gone = is_owner_gone) {
2425
- const raw = stale_record(target, is_gone);
2203
+ function clear_stale(target2, is_gone = is_owner_gone) {
2204
+ const raw = stale_record(target2, is_gone);
2426
2205
  if (raw === void 0) return;
2427
- const aside = move_aside(target);
2206
+ const aside = move_aside(target2);
2428
2207
  if (aside === void 0) return;
2429
- if (stamp_file.read_stamp_text(aside) !== raw) restore(aside, target);
2430
- rmSync2(aside, { force: true });
2208
+ if (stamp_file.read_stamp_text(aside) !== raw) restore(aside, target2);
2209
+ rmSync3(aside, { force: true });
2431
2210
  }
2432
- function claim(target) {
2433
- clear_stale(target);
2434
- return stamp_file.create_stamp(target, process_identity.own_fields());
2211
+ function claim(target2) {
2212
+ clear_stale(target2);
2213
+ return stamp_file.create_stamp(target2, process_identity.own_fields());
2435
2214
  }
2436
- function release(target) {
2437
- const owner = read_owner(target);
2215
+ function release(target2) {
2216
+ const owner = read_owner(target2);
2438
2217
  if (owner !== void 0 && process_identity.is_own_process(owner.pid, owner.process_start)) {
2439
- stamp_file.remove_stamp(target);
2218
+ stamp_file.remove_stamp(target2);
2440
2219
  }
2441
2220
  }
2442
- async function acquire(target, max_wait_ms) {
2221
+ async function acquire(target2, max_wait_ms) {
2443
2222
  const deadline = Date.now() + max_wait_ms;
2444
- while (!claim(target)) {
2223
+ while (!claim(target2)) {
2445
2224
  if (Date.now() >= deadline) return false;
2446
2225
  await sleep(POLL_INTERVAL_MS);
2447
2226
  }
@@ -2450,40 +2229,40 @@ async function acquire(target, max_wait_ms) {
2450
2229
  function sleep_sync(ms) {
2451
2230
  Atomics.wait(SLEEP_CELL, 0, 0, ms);
2452
2231
  }
2453
- function acquire_sync(target, max_wait_ms) {
2232
+ function acquire_sync(target2, max_wait_ms) {
2454
2233
  const deadline = Date.now() + max_wait_ms;
2455
- while (!claim(target)) {
2234
+ while (!claim(target2)) {
2456
2235
  if (Date.now() >= deadline) return false;
2457
2236
  sleep_sync(SYNC_POLL_INTERVAL_MS);
2458
2237
  }
2459
2238
  return true;
2460
2239
  }
2461
- async function with_lock(work, target, max_wait_ms) {
2462
- if (!await acquire(target, max_wait_ms)) return void 0;
2240
+ async function with_lock(work, target2, max_wait_ms) {
2241
+ if (!await acquire(target2, max_wait_ms)) return void 0;
2463
2242
  try {
2464
2243
  return await work();
2465
2244
  } finally {
2466
- release(target);
2245
+ release(target2);
2467
2246
  }
2468
2247
  }
2469
- function with_lock_sync(work, target, max_wait_ms) {
2470
- if (!acquire_sync(target, max_wait_ms)) return void 0;
2248
+ function with_lock_sync(work, target2, max_wait_ms) {
2249
+ if (!acquire_sync(target2, max_wait_ms)) return void 0;
2471
2250
  try {
2472
2251
  return work();
2473
2252
  } finally {
2474
- release(target);
2253
+ release(target2);
2475
2254
  }
2476
2255
  }
2477
2256
  var repository_lock = { clear_stale, lock_path, with_lock, with_lock_sync };
2478
2257
 
2479
2258
  // scripts/run/event/run-event-stream.ts
2480
- import { z as z5 } from "zod";
2481
- var EVENT_PREFIX = "josh-run-events-";
2259
+ import { z as z7 } from "zod";
2260
+ var EVENT_PREFIX = durable_state.PREFIX.EVENTS;
2482
2261
  var EVENT_SUFFIX = ".jsonl";
2483
2262
  var EVENT_CAP = 15e3;
2484
2263
  var FIRST_POSITION = 0;
2485
2264
  var POSITION_INCREMENT = 1;
2486
- var LINE_SEPARATOR = "\n";
2265
+ var LINE_SEPARATOR2 = "\n";
2487
2266
  var WORD_SEPARATOR2 = " ";
2488
2267
  var STAGE_PHASE_INDEX = 2;
2489
2268
  var LOCK_SUFFIX = ".lock";
@@ -2495,6 +2274,10 @@ var EVENT_KIND = {
2495
2274
  PARK: "park",
2496
2275
  SPLIT: "split",
2497
2276
  OUTAGE: "outage",
2277
+ // A Claude usage limit stopped a lane child (joshuafolkken/kit#4745). Its text names the reset time,
2278
+ // which `backlog:drive` reads to hold launches until then; it counts against no streak, so it is not an
2279
+ // `OUTAGE`.
2280
+ USAGE_LIMIT: "usage-limit",
2498
2281
  CUT: "cut",
2499
2282
  // A fresh session adopted an implementation cut — `run:cut --resume` answered `resume-impl`. The
2500
2283
  // resume clears the cut record, so without this the `cut` would stay the newest position and
@@ -2555,6 +2338,11 @@ var EVENT_KIND = {
2555
2338
  // The position that hands control back: `run:step` prints the command that
2556
2339
  // shows the stopped report, so the agent fixes it and relaunches rather than rebuilding the context.
2557
2340
  SHIP_STOP: "ship-stop",
2341
+ // The relaunch meant to answer a `SHIP_STOP` started nothing — the broker refused it, or the direct
2342
+ // spawn failed (joshuafolkken/kit#4765). `run:merge` reads it, not the transcript's mtime, to tell the
2343
+ // stop went unanswered, and a re-dispatch cap's park names its reason. A trace: the stop stays the
2344
+ // position `run:step` answers.
2345
+ RELAUNCH_FAILED: "relaunch-failed",
2558
2346
  // An Issue the run filed on its way, written by `issue:file`, so a run started from the command line
2559
2347
  // still surfaces what it found — `run:board`'s findings section reads it.
2560
2348
  FILED: "filed",
@@ -2595,7 +2383,15 @@ var EVENT_KIND = {
2595
2383
  // `backlog:drive` found nothing of the run in flight and only paused lanes left, paused past the
2596
2384
  // silent window (joshuafolkken/kit#4270). Emitted once per pause episode (`emit_once_since_with`,
2597
2385
  // reset by `LANE_STATE`), it is the dedup marker for the one paused-lane Telegram. A trace.
2598
- PAUSED_NOTICE: "paused-notice"
2386
+ PAUSED_NOTICE: "paused-notice",
2387
+ // `backlog:drive` ran a due issue's measurement declaration itself, found it within its bound and
2388
+ // closed the issue through `issue:measured` — no lane was launched for it (joshuafolkken/kit#4621).
2389
+ // `run:board` draws it merged. A trace: the parent's position is the drive's, not this close.
2390
+ MEASURED: "measured",
2391
+ // The host slept while `backlog:drive` sampled its load (joshuafolkken/kit#5032): the sampler's timer
2392
+ // ran late by more than a few intervals. `at` is the wake and `elapsed_ms` how long the sleep
2393
+ // lasted; every lane's net time takes it out (`lane-sleep.ts`). A trace.
2394
+ SLEEP: "sleep"
2599
2395
  };
2600
2396
  var EVENT_KINDS = Object.values(EVENT_KIND);
2601
2397
  var TRACE_KINDS = /* @__PURE__ */ new Set([
@@ -2610,7 +2406,10 @@ var TRACE_KINDS = /* @__PURE__ */ new Set([
2610
2406
  EVENT_KIND.PR_CHECKS,
2611
2407
  EVENT_KIND.IDLE_NOTICE,
2612
2408
  EVENT_KIND.LANE_STATE,
2613
- EVENT_KIND.PAUSED_NOTICE
2409
+ EVENT_KIND.PAUSED_NOTICE,
2410
+ EVENT_KIND.MEASURED,
2411
+ EVENT_KIND.RELAUNCH_FAILED,
2412
+ EVENT_KIND.SLEEP
2614
2413
  ]);
2615
2414
  var DISPOSABLE_KINDS = /* @__PURE__ */ new Set([
2616
2415
  EVENT_KIND.SHIP_STAGE,
@@ -2618,20 +2417,21 @@ var DISPOSABLE_KINDS = /* @__PURE__ */ new Set([
2618
2417
  EVENT_KIND.SETUP,
2619
2418
  EVENT_KIND.PR_CHECKS
2620
2419
  ]);
2621
- var event_schema = z5.object({
2622
- pos: z5.number(),
2623
- at: z5.string(),
2624
- kind: z5.string(),
2625
- text: z5.string(),
2420
+ var event_schema = z7.object({
2421
+ pos: z7.number(),
2422
+ at: z7.string(),
2423
+ kind: z7.string(),
2424
+ text: z7.string(),
2626
2425
  // The child's time on a lane, recorded once by the writer of an ending (joshuafolkken/kit#4481), so a
2627
- // reader never has to find its launch again. An event written before it has none.
2628
- elapsed_ms: z5.number().optional()
2426
+ // reader never has to find its launch again. An event written before it has none. A `sleep` event
2427
+ // carries the sleep's length here.
2428
+ elapsed_ms: z7.number().optional()
2629
2429
  });
2630
2430
  function is_event_kind(value) {
2631
2431
  return EVENT_KINDS.includes(value);
2632
2432
  }
2633
- function target_of(repository2) {
2634
- return stamp_file.stamp_path(EVENT_PREFIX, repository2, EVENT_SUFFIX);
2433
+ function target_of2(repository) {
2434
+ return durable_state.path(EVENT_PREFIX, repository, EVENT_SUFFIX);
2635
2435
  }
2636
2436
  function is_present(event) {
2637
2437
  return event !== void 0;
@@ -2639,13 +2439,13 @@ function is_present(event) {
2639
2439
  function parse_line2(line) {
2640
2440
  return event_schema.safeParse(json_value.parse_or_undefined(line)).data;
2641
2441
  }
2642
- function read_lines(target) {
2643
- const raw = stamp_file.read_stamp_text(target);
2442
+ function read_lines(target2) {
2443
+ const raw = stamp_file.read_stamp_text(target2);
2644
2444
  if (raw === void 0) return [];
2645
- return raw.split(LINE_SEPARATOR).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parse_line2(line)).filter(is_present);
2445
+ return raw.split(LINE_SEPARATOR2).map((line) => line.trim()).filter((line) => line.length > 0).map((line) => parse_line2(line)).filter(is_present);
2646
2446
  }
2647
- function read_events(target) {
2648
- return read_lines(target).filter((event) => is_event_kind(event.kind));
2447
+ function read_events(target2) {
2448
+ return read_lines(target2).filter((event) => is_event_kind(event.kind));
2649
2449
  }
2650
2450
  function last_position(events) {
2651
2451
  return events[events.length - POSITION_INCREMENT]?.pos ?? FIRST_POSITION;
@@ -2687,19 +2487,19 @@ function bounded(events) {
2687
2487
  return events.filter((event) => !dropped.has(event)).slice(-EVENT_CAP);
2688
2488
  }
2689
2489
  function serialize(events) {
2690
- return `${events.map((event) => JSON.stringify(event)).join(LINE_SEPARATOR)}${LINE_SEPARATOR}`;
2490
+ return `${events.map((event) => JSON.stringify(event)).join(LINE_SEPARATOR2)}${LINE_SEPARATOR2}`;
2691
2491
  }
2692
- function append_held(target, event) {
2693
- const position = last_position(read_lines(target)) + POSITION_INCREMENT;
2694
- const events = bounded([...read_events(target), { pos: position, ...event }]);
2695
- stamp_file.replace_text_stamp(target, serialize(events));
2492
+ function append_held(target2, event) {
2493
+ const position = last_position(read_lines(target2)) + POSITION_INCREMENT;
2494
+ const events = bounded([...read_events(target2), { pos: position, ...event }]);
2495
+ stamp_file.replace_text_stamp(target2, serialize(events));
2696
2496
  return position;
2697
2497
  }
2698
- function append_event(target, event) {
2498
+ function append_event(target2, event) {
2699
2499
  if (!is_event_kind(event.kind)) return { appended: false, position: FIRST_POSITION };
2700
- const lock = `${target}${LOCK_SUFFIX}`;
2500
+ const lock = `${target2}${LOCK_SUFFIX}`;
2701
2501
  const position = repository_lock.with_lock_sync(
2702
- () => append_held(target, event),
2502
+ () => append_held(target2, event),
2703
2503
  lock,
2704
2504
  LOCK_WAIT_MS
2705
2505
  );
@@ -2711,18 +2511,18 @@ function append_event(target, event) {
2711
2511
  }
2712
2512
  return { appended: true, position };
2713
2513
  }
2714
- function append(target, kind, text2, at) {
2715
- return append_event(target, { at, kind, text: text2 });
2514
+ function append2(target2, kind, text2, at) {
2515
+ return append_event(target2, { at, kind, text: text2 });
2716
2516
  }
2717
- function read_from(target, position) {
2718
- const events = read_events(target);
2517
+ function read_from(target2, position) {
2518
+ const events = read_events(target2);
2719
2519
  return {
2720
2520
  events: events.filter((event) => event.pos > position),
2721
2521
  next_position: last_position(events)
2722
2522
  };
2723
2523
  }
2724
- function read_last(target) {
2725
- return read_events(target).findLast((event) => !TRACE_KINDS.has(event.kind));
2524
+ function read_last(target2) {
2525
+ return read_events(target2).findLast((event) => !TRACE_KINDS.has(event.kind));
2726
2526
  }
2727
2527
  function has_since(events, kind, reset_kind) {
2728
2528
  const reset_at = events.findLastIndex((event) => event.kind === reset_kind);
@@ -2737,7 +2537,7 @@ var run_event_stream = {
2737
2537
  EVENT_KIND,
2738
2538
  EVENT_KINDS,
2739
2539
  TRACE_KINDS,
2740
- append,
2540
+ append: append2,
2741
2541
  append_event,
2742
2542
  format_event,
2743
2543
  has_since,
@@ -2745,280 +2545,7 @@ var run_event_stream = {
2745
2545
  read_events,
2746
2546
  read_from,
2747
2547
  read_last,
2748
- target_of
2749
- };
2750
-
2751
- // scripts/discovery/repo-origin.ts
2752
- var GITHUB_HOST = "github.com";
2753
- var SSH_ALIAS_PATTERN = /^github(?:-\w+)*$/u;
2754
- var GIT_SUFFIX = ".git";
2755
- var PATH_SEPARATOR2 = "/";
2756
- var USER_SEPARATOR = "@";
2757
- var HOST_SEPARATOR = ":";
2758
- var OWNER_INDEX = 0;
2759
- var REPO_INDEX = 1;
2760
- var REPO_PATH_SEGMENTS = 2;
2761
- var NOT_FOUND4 = -1;
2762
- var SECTION_PREFIX = "[";
2763
- var ORIGIN_SECTION = /^\[remote\s+"origin"\]$/u;
2764
- var REMOTE_SECTION = /^\[remote\s+"[^"]+"\]$/u;
2765
- var URL_KEY = "url";
2766
- function is_github_hostname(host) {
2767
- return host.toLowerCase() === GITHUB_HOST;
2768
- }
2769
- function is_github_ssh_host(host) {
2770
- const normalized = host.toLowerCase();
2771
- return is_github_hostname(normalized) || SSH_ALIAS_PATTERN.test(normalized);
2772
- }
2773
- function strip_git_suffix(name) {
2774
- return name.endsWith(GIT_SUFFIX) ? name.slice(0, -GIT_SUFFIX.length) : name;
2775
- }
2776
- function to_identity(repository_path) {
2777
- const segments = repository_path.split(PATH_SEPARATOR2).filter((segment) => segment !== "");
2778
- if (segments.length !== REPO_PATH_SEGMENTS) return void 0;
2779
- const owner = segments[OWNER_INDEX] ?? "";
2780
- const repo = strip_git_suffix(segments[REPO_INDEX] ?? "");
2781
- return repo === "" ? void 0 : { owner, repo };
2782
- }
2783
- function parse_scp_like(url) {
2784
- const user_end = url.indexOf(USER_SEPARATOR);
2785
- const authority = user_end === NOT_FOUND4 ? url : url.slice(user_end + 1);
2786
- const host_end = authority.indexOf(HOST_SEPARATOR);
2787
- if (host_end === NOT_FOUND4 || !is_github_ssh_host(authority.slice(0, host_end))) return void 0;
2788
- return to_identity(authority.slice(host_end + 1));
2789
- }
2790
- function parse_url_like(url) {
2791
- try {
2792
- const parsed = new URL(url);
2793
- return is_github_hostname(parsed.hostname) ? to_identity(parsed.pathname) : void 0;
2794
- } catch {
2795
- return void 0;
2796
- }
2797
- }
2798
- function parse_origin_url(url) {
2799
- const trimmed = url.trim();
2800
- if (trimmed === "") return void 0;
2801
- return parse_url_like(trimmed) ?? parse_scp_like(trimmed);
2802
- }
2803
- function is_section_header(line) {
2804
- return line.startsWith(SECTION_PREFIX);
2805
- }
2806
- function origin_section_lines(lines) {
2807
- const start = lines.findIndex((line) => ORIGIN_SECTION.test(line));
2808
- if (start === NOT_FOUND4) return [];
2809
- const rest = lines.slice(start + 1);
2810
- const end = rest.findIndex((line) => is_section_header(line));
2811
- return end === NOT_FOUND4 ? rest : rest.slice(0, end);
2812
- }
2813
- function url_value(line) {
2814
- const separator = line.indexOf("=");
2815
- if (separator === NOT_FOUND4 || line.slice(0, separator).trim() !== URL_KEY) return void 0;
2816
- return line.slice(separator + 1).trim();
2817
- }
2818
- function parse_origin_from_config(content) {
2819
- const lines = content.split("\n").map((line) => line.trim());
2820
- return origin_section_lines(lines).map((line) => url_value(line)).find((url) => url !== void 0);
2821
- }
2822
- function section_groups(lines) {
2823
- const groups = [];
2824
- for (const line of lines) {
2825
- if (is_section_header(line)) groups.push([line]);
2826
- else groups.at(-1)?.push(line);
2827
- }
2828
- return groups;
2829
- }
2830
- function parse_remote_urls_from_config(content) {
2831
- const lines = content.split("\n").map((line) => line.trim());
2832
- return section_groups(lines).filter((group) => REMOTE_SECTION.test(group[0] ?? "")).flatMap((group) => group.map((line) => url_value(line))).filter((url) => url !== void 0);
2833
- }
2834
- function format_identity(identity) {
2835
- return `${identity.owner}${PATH_SEPARATOR2}${identity.repo}`.toLowerCase();
2836
- }
2837
- var repo_origin = {
2838
- GITHUB_HOST,
2839
- is_github_hostname,
2840
- is_github_ssh_host,
2841
- parse_origin_from_config,
2842
- parse_origin_url,
2843
- parse_remote_urls_from_config,
2844
- format_identity
2845
- };
2846
-
2847
- // scripts/discovery/repo-discovery.ts
2848
- import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync4, statSync as statSync3 } from "node:fs";
2849
- import path7 from "node:path";
2850
-
2851
- // scripts/lib/stamped-memo.ts
2852
- import { lstatSync } from "node:fs";
2853
- var NO_STAMP = "";
2854
- var STAMP_SEPARATOR = ":";
2855
- function create() {
2856
- const answers2 = /* @__PURE__ */ new Map();
2857
- return {
2858
- of(key, stamp, compute) {
2859
- const known = answers2.get(key);
2860
- if (known?.stamp === stamp) return known.value;
2861
- const value = compute();
2862
- answers2.set(key, { stamp, value });
2863
- return value;
2864
- },
2865
- keep(keys) {
2866
- for (const key of answers2.keys()) if (!keys.has(key)) answers2.delete(key);
2867
- }
2868
- };
2869
- }
2870
- function file_stamp(file) {
2871
- try {
2872
- const status2 = lstatSync(file);
2873
- return [status2.ino, status2.mtimeMs, status2.ctimeMs, status2.size].join(STAMP_SEPARATOR);
2874
- } catch {
2875
- return NO_STAMP;
2876
- }
2877
- }
2878
- var stamped_memo = { NO_STAMP, create, file_stamp };
2879
-
2880
- // scripts/discovery/repo-map-logic.ts
2881
- var OVERRIDE_ENTRY_SEPARATOR = ",";
2882
- var OVERRIDE_PAIR_SEPARATOR = "=";
2883
- var OVERRIDE_PAIR_PARTS = 2;
2884
- var KEY_INDEX = 0;
2885
- var PATH_INDEX = 1;
2886
- function is_same_owner(identity, current_owner) {
2887
- return identity.owner.toLowerCase() === current_owner.toLowerCase();
2888
- }
2889
- function add_entry(target, origin_url2, repository_path, current_owner) {
2890
- if (origin_url2 === void 0) return;
2891
- const identity = repo_origin.parse_origin_url(origin_url2);
2892
- if (identity === void 0 || !is_same_owner(identity, current_owner)) return;
2893
- target.set(repo_origin.format_identity(identity), repository_path);
2894
- }
2895
- function parse_override_entry(entry) {
2896
- const parts = entry.split(OVERRIDE_PAIR_SEPARATOR).map((part) => part.trim());
2897
- if (parts.length !== OVERRIDE_PAIR_PARTS) return void 0;
2898
- const key = parts[KEY_INDEX] ?? "";
2899
- const repository_path = parts[PATH_INDEX] ?? "";
2900
- if (repository_path === "") return void 0;
2901
- return { path: repository_path, origin_url: `https://${repo_origin.GITHUB_HOST}/${key}` };
2902
- }
2903
- function parse_overrides(raw) {
2904
- if (raw === void 0) return [];
2905
- return raw.split(OVERRIDE_ENTRY_SEPARATOR).map((entry) => parse_override_entry(entry)).filter((entry) => entry !== void 0);
2906
- }
2907
- function build_repository_map(discovered, current_owner, override_value) {
2908
- const result = /* @__PURE__ */ new Map();
2909
- for (const entry of discovered) add_entry(result, entry.origin_url, entry.path, current_owner);
2910
- for (const entry of parse_overrides(override_value)) {
2911
- add_entry(result, entry.origin_url, entry.path, current_owner);
2912
- }
2913
- return result;
2914
- }
2915
- var repo_map_logic = {
2916
- is_same_owner,
2917
- build_repository_map
2918
- };
2919
-
2920
- // scripts/discovery/repo-discovery.ts
2921
- var GIT_DIRECTORY = ".git";
2922
- var GIT_CONFIG = "config";
2923
- var GITDIR_PREFIX2 = "gitdir:";
2924
- var COMMON_DIRECTORY_FILE = "commondir";
2925
- var OVERRIDE_ENV_KEY = "JOSH_REPO_PATHS";
2926
- function resolve_common_directory(git_directory) {
2927
- const pointer = path7.join(git_directory, COMMON_DIRECTORY_FILE);
2928
- if (!existsSync3(pointer)) return git_directory;
2929
- try {
2930
- return path7.resolve(git_directory, readFileSync4(pointer, "utf8").trim());
2931
- } catch {
2932
- return git_directory;
2933
- }
2934
- }
2935
- function follow_git_file(repository_path, git_file) {
2936
- const pointer = readFileSync4(git_file, "utf8").trim();
2937
- if (!pointer.startsWith(GITDIR_PREFIX2)) return void 0;
2938
- return path7.resolve(repository_path, pointer.slice(GITDIR_PREFIX2.length).trim());
2939
- }
2940
- function resolve_git_directory(repository_path) {
2941
- const candidate = path7.join(repository_path, GIT_DIRECTORY);
2942
- if (!existsSync3(candidate)) return void 0;
2943
- try {
2944
- if (statSync3(candidate).isDirectory()) return candidate;
2945
- const linked = follow_git_file(repository_path, candidate);
2946
- return linked === void 0 ? void 0 : resolve_common_directory(linked);
2947
- } catch {
2948
- return void 0;
2949
- }
2950
- }
2951
- function read_text(file) {
2952
- try {
2953
- return readFileSync4(file, "utf8");
2954
- } catch {
2955
- return void 0;
2956
- }
2957
- }
2958
- var git_directories2 = stamped_memo.create();
2959
- var configs = stamped_memo.create();
2960
- function read_config(repository_path) {
2961
- const git_entry = path7.join(repository_path, GIT_DIRECTORY);
2962
- const git_directory = git_directories2.of(
2963
- repository_path,
2964
- stamped_memo.file_stamp(git_entry),
2965
- () => resolve_git_directory(repository_path)
2966
- );
2967
- if (git_directory === void 0) return void 0;
2968
- const config = path7.join(git_directory, GIT_CONFIG);
2969
- return configs.of(config, stamped_memo.file_stamp(config), () => read_text(config));
2970
- }
2971
- function read_origin_url(repository_path) {
2972
- const config = read_config(repository_path);
2973
- return config === void 0 ? void 0 : repo_origin.parse_origin_from_config(config);
2974
- }
2975
- function read_remote_urls(repository_path) {
2976
- const config = read_config(repository_path);
2977
- return config === void 0 ? [] : repo_origin.parse_remote_urls_from_config(config);
2978
- }
2979
- function sibling_directories(parent) {
2980
- try {
2981
- return readdirSync2(parent, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path7.join(parent, entry.name)).toSorted((left, right) => left.localeCompare(right));
2982
- } catch {
2983
- return [];
2984
- }
2985
- }
2986
- function scan_siblings(parent) {
2987
- return sibling_directories(parent).map((repository_path) => ({
2988
- path: repository_path,
2989
- origin_url: read_origin_url(repository_path)
2990
- }));
2991
- }
2992
- function resolve_current_owner(repository_path) {
2993
- const origin_url2 = read_origin_url(repository_path);
2994
- if (origin_url2 === void 0) return void 0;
2995
- return repo_origin.parse_origin_url(origin_url2)?.owner;
2996
- }
2997
- function main_worktree(repository_path) {
2998
- const git_directory = resolve_git_directory(repository_path);
2999
- if (git_directory === void 0 || path7.basename(git_directory) !== GIT_DIRECTORY) {
3000
- return repository_path;
3001
- }
3002
- return path7.dirname(git_directory);
3003
- }
3004
- function discover_repositories(repository_path, environment = process.env) {
3005
- const main = main_worktree(repository_path);
3006
- const current_owner = resolve_current_owner(main);
3007
- if (current_owner === void 0) return /* @__PURE__ */ new Map();
3008
- return repo_map_logic.build_repository_map(
3009
- scan_siblings(path7.dirname(main)),
3010
- current_owner,
3011
- environment[OVERRIDE_ENV_KEY]
3012
- );
3013
- }
3014
- var repo_discovery = {
3015
- OVERRIDE_ENV_KEY,
3016
- main_worktree,
3017
- read_origin_url,
3018
- read_remote_urls,
3019
- resolve_current_owner,
3020
- scan_siblings,
3021
- discover_repositories
2548
+ target_of: target_of2
3022
2549
  };
3023
2550
 
3024
2551
  // scripts/rules/issue-citation.ts
@@ -3093,26 +2620,9 @@ function bare_references(message) {
3093
2620
  for (const line of prose_lines(message)) collect_line_references(line, found);
3094
2621
  return [...new Set(found)];
3095
2622
  }
3096
- function prompt_references(prompt) {
3097
- const found = /* @__PURE__ */ new Set();
3098
- for (const match of prompt.matchAll(ISSUE_NUMBER)) {
3099
- found.add(repo_prefix(prompt, match.index) + match[0]);
3100
- }
3101
- return found;
3102
- }
3103
- function unquoted_references(message, prompt) {
3104
- const quoted = prompt_references(prompt);
3105
- return bare_references(message).filter((reference2) => !quoted.has(reference2));
3106
- }
3107
2623
  function has_bare_reference(message) {
3108
2624
  return bare_references(message).length > 0;
3109
2625
  }
3110
- function cite_argument(reference2) {
3111
- return reference2.startsWith("#") ? reference2.slice(1) : reference2;
3112
- }
3113
- function cite_arguments(references) {
3114
- return references.map((reference2) => cite_argument(reference2));
3115
- }
3116
2626
  function reference_link(reference2, default_slug) {
3117
2627
  const slug = reference2.prefix === "" ? default_slug : reference2.prefix;
3118
2628
  const number = reference2.text.slice(1);
@@ -3143,11 +2653,9 @@ function linkify(message, slug) {
3143
2653
  }
3144
2654
  var issue_citation = {
3145
2655
  bare_references,
3146
- cite_arguments,
3147
2656
  has_bare_reference,
3148
2657
  linkify,
3149
- prose_lines,
3150
- unquoted_references
2658
+ prose_lines
3151
2659
  };
3152
2660
 
3153
2661
  // scripts/issue/session-cite.ts
@@ -3171,7 +2679,7 @@ var session_cite = {
3171
2679
 
3172
2680
  // scripts/lane/lane-state.ts
3173
2681
  import { readdirSync as readdirSync3 } from "node:fs";
3174
- import path8 from "node:path";
2682
+ import path7 from "node:path";
3175
2683
 
3176
2684
  // scripts/lib/figure-format.ts
3177
2685
  var USD_DECIMALS = 4;
@@ -3215,23 +2723,23 @@ var figure_format = {
3215
2723
  };
3216
2724
 
3217
2725
  // scripts/lane/lane-state.ts
3218
- import { z as z6 } from "zod";
3219
- var STATE_PREFIX = "josh-lane-state-";
2726
+ import { z as z8 } from "zod";
2727
+ var STATE_PREFIX = durable_state.PREFIX.LANE_STATE;
3220
2728
  var STATE_SUFFIX = ".json";
3221
2729
  var LOCK_SUFFIX2 = ".lock";
3222
2730
  var LOCK_WAIT_MS2 = 5e3;
3223
2731
  var LANE_STATES = ["open", "running", "paused", "ended"];
3224
2732
  var NO_STATE_HINT = "no lane state \u2014 counted in use";
3225
- var lane_run_schema = z6.object({ started_at: z6.string(), owner_pid: z6.number().optional() });
3226
- var stuck_schema = z6.object({ pid: z6.number(), reason: z6.string() });
3227
- var lane_state_schema = z6.object({
3228
- issue: z6.string(),
2733
+ var lane_run_schema = z8.object({ started_at: z8.string(), owner_pid: z8.number().optional() });
2734
+ var stuck_schema = z8.object({ pid: z8.number(), reason: z8.string() });
2735
+ var lane_state_schema2 = z8.object({
2736
+ issue: z8.string(),
3229
2737
  run: lane_run_schema.optional(),
3230
- state: z6.enum(LANE_STATES),
3231
- launched_at: z6.string().optional(),
3232
- changed_at: z6.string(),
3233
- changed_by: z6.string(),
3234
- stuck: z6.array(stuck_schema).optional()
2738
+ state: z8.enum(LANE_STATES),
2739
+ launched_at: z8.string().optional(),
2740
+ changed_at: z8.string(),
2741
+ changed_by: z8.string(),
2742
+ stuck: z8.array(stuck_schema).optional()
3235
2743
  });
3236
2744
  var TRANSITIONS = {
3237
2745
  open: ["open", "running", "ended"],
@@ -3240,17 +2748,17 @@ var TRANSITIONS = {
3240
2748
  ended: ["ended", "open"]
3241
2749
  };
3242
2750
  function state_path(directory, issue2) {
3243
- return stamp_file.stamp_path(STATE_PREFIX, directory, `-${issue2}${STATE_SUFFIX}`);
2751
+ return durable_state.path(STATE_PREFIX, directory, `-${issue2}${STATE_SUFFIX}`);
3244
2752
  }
3245
2753
  function is_allowed(from, to) {
3246
2754
  return from === void 0 || TRANSITIONS[from].includes(to);
3247
2755
  }
3248
2756
  function read_record2(directory, issue2) {
3249
2757
  const raw = stamp_file.read_stamp_text(state_path(directory, issue2));
3250
- return raw === void 0 ? void 0 : json_value.parse_with(raw, lane_state_schema);
2758
+ return raw === void 0 ? void 0 : json_value.parse_with(raw, lane_state_schema2);
3251
2759
  }
3252
- function write_record(directory, record) {
3253
- stamp_file.replace_stamp(state_path(directory, record.issue), record);
2760
+ function write_record(directory, record2) {
2761
+ stamp_file.replace_stamp(state_path(directory, record2.issue), record2);
3254
2762
  }
3255
2763
  function current_run(directory) {
3256
2764
  const carried = run_carry.read_carry(run_carry.carry_path(directory));
@@ -3277,9 +2785,9 @@ function apply_held(change, directory, now) {
3277
2785
  if (!is_allowed(previous?.state, change.state)) {
3278
2786
  return { kind: "skipped", reason: `no ${previous?.state ?? ""} \u2192 ${change.state} transition` };
3279
2787
  }
3280
- const record = next_record(change, previous, directory, now);
3281
- write_record(directory, record);
3282
- return { kind: "written", record };
2788
+ const record2 = next_record(change, previous, directory, now);
2789
+ write_record(directory, record2);
2790
+ return { kind: "written", record: record2 };
3283
2791
  }
3284
2792
  var NO_DIRECTORY = { kind: "skipped", reason: "no git directory" };
3285
2793
  function locked(directory, issue2, held) {
@@ -3303,60 +2811,75 @@ async function outcome_of(change, options) {
3303
2811
  if (directory === void 0) return NO_DIRECTORY;
3304
2812
  return apply(change, directory, options.now ?? /* @__PURE__ */ new Date());
3305
2813
  }
3306
- async function settled_outcome(change, options) {
2814
+ async function settled(write) {
3307
2815
  try {
3308
- return await outcome_of(change, options);
2816
+ return await write();
3309
2817
  } catch (error) {
3310
2818
  return { kind: "skipped", reason: error instanceof Error ? error.message : String(error) };
3311
2819
  }
3312
2820
  }
3313
2821
  async function record_change(change, options = {}) {
3314
- const outcome = await settled_outcome(change, options);
2822
+ const outcome = await settled(async () => await outcome_of(change, options));
3315
2823
  if (outcome.kind === "skipped") warn(change, outcome.reason);
3316
2824
  return outcome;
3317
2825
  }
3318
2826
  async function read_state(issue2, directory) {
3319
- const root = await resolve_directory(directory);
3320
- return root === void 0 ? void 0 : read_record2(root, issue2);
2827
+ const root2 = await resolve_directory(directory);
2828
+ return root2 === void 0 ? void 0 : read_record2(root2, issue2);
3321
2829
  }
3322
2830
  function recorded_issues(directory) {
3323
2831
  const empty = state_path(directory, "");
3324
- const head = path8.basename(empty).slice(0, -STATE_SUFFIX.length);
3325
- return readdirSync3(path8.dirname(empty)).filter((name) => name.startsWith(head) && name.endsWith(STATE_SUFFIX)).map((name) => name.slice(head.length, -STATE_SUFFIX.length)).filter((issue2) => issue2.length > 0);
2832
+ const head = path7.basename(empty).slice(0, -STATE_SUFFIX.length);
2833
+ return readdirSync3(path7.dirname(empty)).filter((name) => name.startsWith(head) && name.endsWith(STATE_SUFFIX)).map((name) => name.slice(head.length, -STATE_SUFFIX.length)).filter((issue2) => issue2.length > 0);
3326
2834
  }
3327
2835
  async function read_records(directory) {
3328
- const root = await resolve_directory(directory);
3329
- if (root === void 0) return [];
3330
- const records = recorded_issues(root).map((issue2) => read_record2(root, issue2));
3331
- return records.filter((record) => record !== void 0);
2836
+ const root2 = await resolve_directory(directory);
2837
+ if (root2 === void 0) return [];
2838
+ const records = recorded_issues(root2).map((issue2) => read_record2(root2, issue2));
2839
+ return records.filter((record2) => record2 !== void 0);
3332
2840
  }
3333
2841
  function stuck_held(issue2, stuck, directory) {
3334
2842
  const previous = read_record2(directory, issue2);
3335
2843
  if (previous === void 0) return { kind: "skipped", reason: "no record" };
3336
- const record = { ...previous, stuck };
3337
- write_record(directory, record);
3338
- return { kind: "written", record };
2844
+ const record2 = { ...previous, stuck };
2845
+ write_record(directory, record2);
2846
+ return { kind: "written", record: record2 };
3339
2847
  }
3340
2848
  async function record_stuck(issue2, stuck, directory) {
3341
- const root = await resolve_directory(directory);
3342
- if (root === void 0) return NO_DIRECTORY;
3343
- return locked(root, issue2, () => stuck_held(issue2, stuck, root));
2849
+ const root2 = await resolve_directory(directory);
2850
+ if (root2 === void 0) return NO_DIRECTORY;
2851
+ return locked(root2, issue2, () => stuck_held(issue2, stuck, root2));
2852
+ }
2853
+ function adopted_held(change, directory, now) {
2854
+ if (read_record2(directory, change.issue) !== void 0) {
2855
+ return { kind: "skipped", reason: "a record exists" };
2856
+ }
2857
+ return apply_held(change, directory, now);
2858
+ }
2859
+ async function adopted_outcome(change, options) {
2860
+ const directory = await resolve_directory(options.directory);
2861
+ if (directory === void 0) return NO_DIRECTORY;
2862
+ const now = options.now ?? /* @__PURE__ */ new Date();
2863
+ return locked(directory, change.issue, () => adopted_held(change, directory, now));
2864
+ }
2865
+ async function record_adopted(change, options = {}) {
2866
+ return await settled(async () => await adopted_outcome(change, options));
3344
2867
  }
3345
2868
  async function read_states(issues, directory) {
3346
- const root = await resolve_directory(directory);
3347
- if (root === void 0) return /* @__PURE__ */ new Map();
3348
- const read3 = issues.map((issue2) => [
2869
+ const root2 = await resolve_directory(directory);
2870
+ if (root2 === void 0) return /* @__PURE__ */ new Map();
2871
+ const read = issues.map((issue2) => [
3349
2872
  issue2,
3350
- read_record2(root, issue2)
2873
+ read_record2(root2, issue2)
3351
2874
  ]);
3352
- return new Map(read3.filter((entry) => entry[1] !== void 0));
2875
+ return new Map(read.filter((entry) => entry[1] !== void 0));
3353
2876
  }
3354
2877
  function paused_text(since_ms, changed_by) {
3355
2878
  return `paused since ${figure_format.minute_of(since_ms)} by ${changed_by}`;
3356
2879
  }
3357
- function paused_note(record) {
3358
- if (record?.state !== "paused") return void 0;
3359
- return paused_text(Date.parse(record.changed_at), record.changed_by);
2880
+ function paused_note(record2) {
2881
+ if (record2?.state !== "paused") return void 0;
2882
+ return paused_text(Date.parse(record2.changed_at), record2.changed_by);
3360
2883
  }
3361
2884
  var lane_state = {
3362
2885
  LANE_STATES,
@@ -3367,6 +2890,7 @@ var lane_state = {
3367
2890
  read_records,
3368
2891
  read_state,
3369
2892
  read_states,
2893
+ record_adopted,
3370
2894
  record_change,
3371
2895
  record_stuck,
3372
2896
  state_path
@@ -3390,9 +2914,9 @@ function scoped_events(events, scope) {
3390
2914
  if (floor === void 0) return void 0;
3391
2915
  return events.filter((event) => is_within(event, floor));
3392
2916
  }
3393
- function scope_of(read3) {
3394
- if (read3.kind !== "carried") return UNKNOWN_EVENT_SCOPE;
3395
- return { kind: SINCE_SCOPE, started_at: read3.carry.started_at };
2917
+ function scope_of(read) {
2918
+ if (read.kind !== "carried") return UNKNOWN_EVENT_SCOPE;
2919
+ return { kind: SINCE_SCOPE, started_at: read.carry.started_at };
3396
2920
  }
3397
2921
  function last_scoped_event(events, scope) {
3398
2922
  return scoped_events(events, scope)?.findLast(
@@ -3403,15 +2927,15 @@ var SHIP_POSITION_KINDS = /* @__PURE__ */ new Set([
3403
2927
  run_event_stream.EVENT_KIND.SHIP_LAUNCH,
3404
2928
  run_event_stream.EVENT_KIND.SHIP_STOP
3405
2929
  ]);
3406
- var KIND = run_event_stream.EVENT_KIND;
2930
+ var KIND5 = run_event_stream.EVENT_KIND;
3407
2931
  var BATCH_RECORD_KINDS = /* @__PURE__ */ new Set([
3408
- KIND.CHILD_LAUNCH,
3409
- KIND.RESTART,
3410
- KIND.WITHDRAW,
3411
- KIND.PARK,
3412
- KIND.SPLIT,
3413
- KIND.RETROSPECTIVE,
3414
- KIND.STRANDED
2932
+ KIND5.CHILD_LAUNCH,
2933
+ KIND5.RESTART,
2934
+ KIND5.WITHDRAW,
2935
+ KIND5.PARK,
2936
+ KIND5.SPLIT,
2937
+ KIND5.RETROSPECTIVE,
2938
+ KIND5.STRANDED
3415
2939
  ]);
3416
2940
  var ISSUE_REFERENCE = /#(\d+)/u;
3417
2941
  function is_foreign_ship_event(event, issue2) {
@@ -3431,7 +2955,7 @@ function is_lane_position(event, issue2) {
3431
2955
  }
3432
2956
  function since_own_launch(events, issue2) {
3433
2957
  const launch = events.findLastIndex(
3434
- (event) => event.kind === KIND.CHILD_LAUNCH && names_issue(event, issue2)
2958
+ (event) => event.kind === KIND5.CHILD_LAUNCH && names_issue(event, issue2)
3435
2959
  );
3436
2960
  return events.slice(launch + 1);
3437
2961
  }
@@ -3441,30 +2965,30 @@ function is_foreign_event(event, issue2, is_lane_child) {
3441
2965
  }
3442
2966
  function last_issue_event(events, scope, issue2, is_lane_child) {
3443
2967
  const attempt = is_lane_child ? since_own_launch(events, issue2) : events;
3444
- const own2 = attempt.filter((event) => !is_foreign_event(event, issue2, is_lane_child));
3445
- if (scope.kind === SINCE_SCOPE) return last_scoped_event(own2, scope);
3446
- return own2.findLast((event) => is_own_ship_event(event, issue2));
2968
+ const own = attempt.filter((event) => !is_foreign_event(event, issue2, is_lane_child));
2969
+ if (scope.kind === SINCE_SCOPE) return last_scoped_event(own, scope);
2970
+ return own.findLast((event) => is_own_ship_event(event, issue2));
3447
2971
  }
3448
2972
  var LAUNCH_OR_SETTLE_KINDS = /* @__PURE__ */ new Set([
3449
- KIND.CHILD_LAUNCH,
3450
- KIND.MERGE,
3451
- KIND.PARK,
3452
- KIND.SPLIT,
3453
- KIND.WITHDRAW
2973
+ KIND5.CHILD_LAUNCH,
2974
+ KIND5.MERGE,
2975
+ KIND5.PARK,
2976
+ KIND5.SPLIT,
2977
+ KIND5.WITHDRAW
3454
2978
  ]);
3455
2979
  function is_merge_owed(events, scope, issue2) {
3456
2980
  const newest = (scoped_events(events, scope) ?? []).findLast(
3457
2981
  (event) => LAUNCH_OR_SETTLE_KINDS.has(event.kind) && names_issue(event, issue2)
3458
2982
  );
3459
- return newest?.kind === KIND.CHILD_LAUNCH;
2983
+ return newest?.kind === KIND5.CHILD_LAUNCH;
3460
2984
  }
3461
2985
  function is_launch_or_withdrawal(event, issue2) {
3462
- const is_kind = event.kind === KIND.CHILD_LAUNCH || event.kind === KIND.WITHDRAW;
2986
+ const is_kind = event.kind === KIND5.CHILD_LAUNCH || event.kind === KIND5.WITHDRAW;
3463
2987
  return is_kind && names_issue(event, issue2);
3464
2988
  }
3465
2989
  function is_withdrawn(events, issue2) {
3466
2990
  const newest = events.findLast((event) => is_launch_or_withdrawal(event, issue2));
3467
- return newest?.kind === KIND.WITHDRAW;
2991
+ return newest?.kind === KIND5.WITHDRAW;
3468
2992
  }
3469
2993
  var run_event_scope = {
3470
2994
  UNKNOWN_EVENT_SCOPE,
@@ -3498,15 +3022,16 @@ function issue_spans(pair) {
3498
3022
  var lane_spans = { issue_spans };
3499
3023
 
3500
3024
  // scripts/run/board/run-board-lane-time.ts
3501
- var KIND2 = run_event_stream.EVENT_KIND;
3502
- var LAUNCH_KINDS = /* @__PURE__ */ new Set([KIND2.CHILD_LAUNCH, KIND2.RESTART]);
3025
+ var KIND6 = run_event_stream.EVENT_KIND;
3026
+ var LAUNCH_KINDS = /* @__PURE__ */ new Set([KIND6.CHILD_LAUNCH, KIND6.RESTART]);
3503
3027
  var OFF_LANE_KINDS = /* @__PURE__ */ new Set([
3504
- KIND2.MERGE,
3505
- KIND2.PARK,
3506
- KIND2.WITHDRAW,
3507
- KIND2.OUTAGE,
3508
- KIND2.SPLIT,
3509
- KIND2.STOP
3028
+ KIND6.MERGE,
3029
+ KIND6.PARK,
3030
+ KIND6.WITHDRAW,
3031
+ KIND6.OUTAGE,
3032
+ KIND6.USAGE_LIMIT,
3033
+ KIND6.SPLIT,
3034
+ KIND6.STOP
3510
3035
  ]);
3511
3036
  function moments_of(events, kinds) {
3512
3037
  return events.filter((event) => kinds.has(event.kind)).map((event) => ({
@@ -3537,24 +3062,24 @@ function in_lane_ms(spans, end_ms) {
3537
3062
  function elapsed_of(spans, started_ms, ended_ms) {
3538
3063
  return spans.length === 0 ? ended_ms - started_ms : in_lane_ms(spans, ended_ms);
3539
3064
  }
3540
- function launched_ms(record) {
3541
- const launched_at = record?.launched_at;
3065
+ function launched_ms(record2) {
3066
+ const launched_at = record2?.launched_at;
3542
3067
  return launched_at === void 0 ? void 0 : Date.parse(launched_at);
3543
3068
  }
3544
- function counted_from(run3, started_ms) {
3545
- return run3 === void 0 ? started_ms : Date.parse(run3.started_at);
3069
+ function counted_from(run, started_ms) {
3070
+ return run === void 0 ? started_ms : Date.parse(run.started_at);
3546
3071
  }
3547
3072
  function is_ended(spans) {
3548
3073
  return spans.at(-1)?.end_ms !== void 0;
3549
3074
  }
3550
- function ending_elapsed(read3) {
3551
- const started_ms = launched_ms(read3.record);
3075
+ function ending_elapsed(read) {
3076
+ const started_ms = launched_ms(read.record);
3552
3077
  if (started_ms === void 0) return void 0;
3553
- const from_ms = counted_from(read3.record?.run, started_ms);
3554
- const spans = (spans_of(read3.events).get(read3.issue) ?? []).filter(
3078
+ const from_ms = counted_from(read.record?.run, started_ms);
3079
+ const spans = (spans_of(read.events).get(read.issue) ?? []).filter(
3555
3080
  (span) => span.from_ms >= from_ms
3556
3081
  );
3557
- return is_ended(spans) ? void 0 : elapsed_of(spans, started_ms, read3.ended_ms);
3082
+ return is_ended(spans) ? void 0 : elapsed_of(spans, started_ms, read.ended_ms);
3558
3083
  }
3559
3084
  var run_board_lane_time = {
3560
3085
  LAUNCH_KINDS,
@@ -3566,12 +3091,12 @@ var run_board_lane_time = {
3566
3091
  };
3567
3092
 
3568
3093
  // scripts/run/event/run-event-stream-emit.ts
3569
- function now_iso() {
3094
+ function now_iso2() {
3570
3095
  return (/* @__PURE__ */ new Date()).toISOString();
3571
3096
  }
3572
3097
  async function stream_target() {
3573
- const repository2 = await run_carry.repository_directory();
3574
- return repository2 === void 0 ? void 0 : run_event_stream.target_of(repository2);
3098
+ const repository = await run_carry.repository_directory();
3099
+ return repository === void 0 ? void 0 : run_event_stream.target_of(repository);
3575
3100
  }
3576
3101
  async function lane_record(issue2) {
3577
3102
  try {
@@ -3581,57 +3106,57 @@ async function lane_record(issue2) {
3581
3106
  return void 0;
3582
3107
  }
3583
3108
  }
3584
- async function ending_fields(target, event) {
3109
+ async function ending_fields(target2, event) {
3585
3110
  const issue2 = run_event_scope.issue_named(event);
3586
3111
  if (issue2 === void 0 || !run_board_lane_time.OFF_LANE_KINDS.has(event.kind)) return {};
3587
3112
  const elapsed_ms = run_board_lane_time.ending_elapsed({
3588
- events: run_event_stream.read_events(target),
3113
+ events: run_event_stream.read_events(target2),
3589
3114
  issue: Number(issue2),
3590
3115
  record: await lane_record(issue2),
3591
3116
  ended_ms: Date.parse(event.at)
3592
3117
  });
3593
3118
  return elapsed_ms === void 0 ? {} : { elapsed_ms };
3594
3119
  }
3595
- async function append_at(target, kind, text2, at) {
3120
+ async function append_at(target2, kind, text2, at) {
3596
3121
  const event = { kind, text: text2, at: at.toISOString() };
3597
- return run_event_stream.append_event(target, {
3122
+ return run_event_stream.append_event(target2, {
3598
3123
  ...event,
3599
- ...await ending_fields(target, event)
3124
+ ...await ending_fields(target2, event)
3600
3125
  });
3601
3126
  }
3602
3127
  async function emit(kind, text2, at = /* @__PURE__ */ new Date()) {
3603
3128
  try {
3604
- const target = await stream_target();
3605
- if (target === void 0) return;
3606
- await append_at(target, kind, text2, at);
3129
+ const target2 = await stream_target();
3130
+ if (target2 === void 0) return;
3131
+ await append_at(target2, kind, text2, at);
3607
3132
  } catch {
3608
3133
  }
3609
3134
  }
3610
3135
  async function emit_once(kind, text2) {
3611
3136
  try {
3612
- const target = await stream_target();
3613
- if (target === void 0 || run_event_stream.read_last(target)?.kind === kind) return false;
3614
- return run_event_stream.append(target, kind, text2, now_iso()).appended;
3137
+ const target2 = await stream_target();
3138
+ if (target2 === void 0 || run_event_stream.read_last(target2)?.kind === kind) return false;
3139
+ return run_event_stream.append(target2, kind, text2, now_iso2()).appended;
3615
3140
  } catch (error) {
3616
3141
  error_text.trace_swallowed("run_event_stream_emit.emit_once", error);
3617
3142
  return false;
3618
3143
  }
3619
3144
  }
3620
- function invocation_events(repository2, target) {
3621
- const events = run_event_stream.read_events(target);
3622
- const scope = run_event_scope.scope_of(run_carry.read_carry(run_carry.carry_path(repository2)));
3145
+ function invocation_events(repository, target2) {
3146
+ const events = run_event_stream.read_events(target2);
3147
+ const scope = run_event_scope.scope_of(run_carry.read_carry(run_carry.carry_path(repository)));
3623
3148
  return run_event_scope.scoped_events(events, scope) ?? events;
3624
3149
  }
3625
3150
  async function emit_once_since_with(kind, reset_kind, compose) {
3626
3151
  try {
3627
- const repository2 = await run_carry.repository_directory();
3628
- if (repository2 === void 0) return void 0;
3629
- const target = run_event_stream.target_of(repository2);
3630
- if (run_event_stream.has_since(invocation_events(repository2, target), kind, reset_kind)) {
3152
+ const repository = await run_carry.repository_directory();
3153
+ if (repository === void 0) return void 0;
3154
+ const target2 = run_event_stream.target_of(repository);
3155
+ if (run_event_stream.has_since(invocation_events(repository, target2), kind, reset_kind)) {
3631
3156
  return void 0;
3632
3157
  }
3633
3158
  const text2 = await compose();
3634
- return run_event_stream.append(target, kind, text2, now_iso()).appended ? text2 : void 0;
3159
+ return run_event_stream.append(target2, kind, text2, now_iso2()).appended ? text2 : void 0;
3635
3160
  } catch (error) {
3636
3161
  error_text.trace_swallowed("run_event_stream_emit.emit_once_since", error);
3637
3162
  return void 0;
@@ -3646,11 +3171,11 @@ async function emit_heartbeat(line) {
3646
3171
  }
3647
3172
  async function current_events() {
3648
3173
  try {
3649
- const repository2 = await run_carry.repository_directory();
3650
- if (repository2 === void 0) return [];
3651
- const read3 = run_carry.read_carry(run_carry.carry_path(repository2));
3652
- const scope = run_event_scope.scope_of(read3);
3653
- const events = run_event_stream.read_events(run_event_stream.target_of(repository2));
3174
+ const repository = await run_carry.repository_directory();
3175
+ if (repository === void 0) return [];
3176
+ const read = run_carry.read_carry(run_carry.carry_path(repository));
3177
+ const scope = run_event_scope.scope_of(read);
3178
+ const events = run_event_stream.read_events(run_event_stream.target_of(repository));
3654
3179
  return run_event_scope.scoped_events(events, scope) ?? [];
3655
3180
  } catch {
3656
3181
  return [];
@@ -3658,16 +3183,16 @@ async function current_events() {
3658
3183
  }
3659
3184
  async function invocation_or_all_events() {
3660
3185
  try {
3661
- const repository2 = await run_carry.repository_directory();
3662
- return repository2 === void 0 ? [] : invocation_events(repository2, run_event_stream.target_of(repository2));
3186
+ const repository = await run_carry.repository_directory();
3187
+ return repository === void 0 ? [] : invocation_events(repository, run_event_stream.target_of(repository));
3663
3188
  } catch {
3664
3189
  return [];
3665
3190
  }
3666
3191
  }
3667
3192
  async function all_events() {
3668
3193
  try {
3669
- const target = await stream_target();
3670
- return target === void 0 ? [] : run_event_stream.read_events(target);
3194
+ const target2 = await stream_target();
3195
+ return target2 === void 0 ? [] : run_event_stream.read_events(target2);
3671
3196
  } catch {
3672
3197
  return [];
3673
3198
  }
@@ -3685,17 +3210,154 @@ var run_event_stream_emit = {
3685
3210
  stream_target
3686
3211
  };
3687
3212
 
3213
+ // ports/index.js
3214
+ import { existsSync as existsSync2 } from "node:fs";
3215
+ import path8 from "node:path";
3216
+ var PORT_SEED_KEY = "PORT_SEED";
3217
+ var LANE_SEAT_KEY = "JOSH_LANE_SEAT";
3218
+ var ENV_FILE_NAME = ".env";
3219
+ var PACKAGE_FILE_NAME = "package.json";
3220
+ var PROJECT_ENVIRONMENT_KEYS = /* @__PURE__ */ new Set([PORT_SEED_KEY, LANE_SEAT_KEY, "PLAYWRIGHT_REUSE_SERVER"]);
3221
+ var DEV_PORT_BASE = 5173;
3222
+ var PREVIEW_PORT_BASE = 4173;
3223
+ var MIN_SEED = 0;
3224
+ var SEED_LANE_MULTIPLIER = 10;
3225
+ var MAX_LANE = 9;
3226
+ var MAX_SEED = 99;
3227
+ var INTEGER_PATTERN = /^\d+$/u;
3228
+ function fail_invalid(key, raw, max) {
3229
+ throw new Error(
3230
+ `${key} must be an integer between ${MIN_SEED} and ${max}, got ${JSON.stringify(raw)}. Unset it to use the default ports (dev ${DEV_PORT_BASE}, preview ${PREVIEW_PORT_BASE}).`
3231
+ );
3232
+ }
3233
+ function read_trimmed(environment, key) {
3234
+ const raw = environment[key];
3235
+ return raw === void 0 ? "" : raw.trim();
3236
+ }
3237
+ function resolve_bounded(environment, key, max) {
3238
+ const trimmed = read_trimmed(environment, key);
3239
+ if (trimmed.length === 0) return MIN_SEED;
3240
+ if (!INTEGER_PATTERN.test(trimmed)) fail_invalid(key, trimmed, max);
3241
+ const value = Number(trimmed);
3242
+ if (value > max) fail_invalid(key, trimmed, max);
3243
+ return value;
3244
+ }
3245
+ function resolve_seed(environment = process.env) {
3246
+ return resolve_bounded(environment, PORT_SEED_KEY, MAX_SEED);
3247
+ }
3248
+ function resolve_lane(environment = process.env) {
3249
+ return resolve_bounded(environment, LANE_SEAT_KEY, MAX_LANE);
3250
+ }
3251
+ function resolve_offset(environment = process.env) {
3252
+ return resolve_seed(environment) * SEED_LANE_MULTIPLIER + resolve_lane(environment);
3253
+ }
3254
+ function offset_from(base, environment) {
3255
+ return base + resolve_offset(environment);
3256
+ }
3257
+ function resolve_development_port(environment = process.env) {
3258
+ return offset_from(DEV_PORT_BASE, environment);
3259
+ }
3260
+ function resolve_preview_port(environment = process.env) {
3261
+ return offset_from(PREVIEW_PORT_BASE, environment);
3262
+ }
3263
+ function resolve_project_directory(directory) {
3264
+ const start = path8.resolve(directory);
3265
+ let current = start;
3266
+ while (!existsSync2(path8.join(current, PACKAGE_FILE_NAME))) {
3267
+ const parent = path8.dirname(current);
3268
+ if (parent === current) return start;
3269
+ current = parent;
3270
+ }
3271
+ return current;
3272
+ }
3273
+ function discard_loaded_keys(snapshot) {
3274
+ for (const key of Object.keys(process.env)) {
3275
+ if (!PROJECT_ENVIRONMENT_KEYS.has(key) && !Object.hasOwn(snapshot, key)) {
3276
+ Reflect.deleteProperty(process.env, key);
3277
+ }
3278
+ }
3279
+ }
3280
+ function load_environment_file(directory = process.cwd()) {
3281
+ const file = path8.join(resolve_project_directory(directory), ENV_FILE_NAME);
3282
+ if (!existsSync2(file)) return false;
3283
+ const snapshot = { ...process.env };
3284
+ process.loadEnvFile(file);
3285
+ discard_loaded_keys(snapshot);
3286
+ return true;
3287
+ }
3288
+ var ports = {
3289
+ load_environment_file,
3290
+ resolve_project_directory,
3291
+ resolve_seed,
3292
+ resolve_lane,
3293
+ resolve_development_port,
3294
+ resolve_preview_port
3295
+ };
3296
+
3297
+ // scripts/josh/josh-command-types.ts
3298
+ var OPTIONAL_ENV_FILE_FLAGS = [`--env-file-if-exists=${ENV_FILE_NAME}`];
3299
+ var ESLINT_CACHE_FILE = ".eslintcache";
3300
+ var TS_BUILD_INFO_FILE = ".tsbuildinfo";
3301
+ var CSPELL_CACHE_FILE = ".cspellcache";
3302
+ var ESLINT_EDIT_CACHE_FILE = ".eslintcache.edit";
3303
+ var ESLINT_RELATED_CACHE_FILE = ".eslintcache.related";
3304
+ var PRETTIER_CACHE_FILE = ".prettiercache";
3305
+ var PRETTIER_RELATED_CACHE_FILE = ".prettiercache.related";
3306
+ var CSPELL_COMMIT_CACHE_FILE = ".cspellcache.commit";
3307
+ var ESLINT_COMMIT_CACHE_FILE = ".eslintcache.commit";
3308
+ var ROOTED_JSON_PORTABILITY = "rooted-json";
3309
+ var ESLINT_CACHE_SPEC = {
3310
+ cache_file: ESLINT_CACHE_FILE,
3311
+ portability: ROOTED_JSON_PORTABILITY
3312
+ };
3313
+ var TS_CACHE_SPEC = {
3314
+ cache_file: TS_BUILD_INFO_FILE,
3315
+ portability: "raw"
3316
+ };
3317
+ var CSPELL_CACHE_SPEC = {
3318
+ cache_file: CSPELL_CACHE_FILE,
3319
+ portability: "raw"
3320
+ };
3321
+ var GATE_CACHE_SPECS = [
3322
+ ESLINT_CACHE_SPEC,
3323
+ TS_CACHE_SPEC,
3324
+ CSPELL_CACHE_SPEC
3325
+ ];
3326
+ var GATE_CACHE_FILES = GATE_CACHE_SPECS.map((spec) => spec.cache_file);
3327
+ var IGNORED_CACHE_FILES = [
3328
+ ...GATE_CACHE_FILES,
3329
+ ESLINT_EDIT_CACHE_FILE,
3330
+ ESLINT_RELATED_CACHE_FILE,
3331
+ PRETTIER_CACHE_FILE,
3332
+ PRETTIER_RELATED_CACHE_FILE,
3333
+ CSPELL_COMMIT_CACHE_FILE,
3334
+ ESLINT_COMMIT_CACHE_FILE
3335
+ ];
3336
+ var CONTENT_CACHE_FLAGS = ["--cache", "--cache-strategy", "content"];
3337
+ var CACHE_LOCATION_FLAG = "--cache-location";
3338
+ function content_cache_flags(cache_file) {
3339
+ return [...CONTENT_CACHE_FLAGS, CACHE_LOCATION_FLAG, cache_file];
3340
+ }
3341
+ var ESLINT_CACHE_FLAGS = content_cache_flags(ESLINT_CACHE_FILE);
3342
+ var ESLINT_EDIT_CACHE_FLAGS = content_cache_flags(ESLINT_EDIT_CACHE_FILE);
3343
+ var ESLINT_RELATED_CACHE_FLAGS = content_cache_flags(ESLINT_RELATED_CACHE_FILE);
3344
+ var CSPELL_CACHE_FLAGS = content_cache_flags(CSPELL_CACHE_FILE);
3345
+ var PRETTIER_CACHE_FLAGS = content_cache_flags(PRETTIER_CACHE_FILE);
3346
+ var PRETTIER_RELATED_CACHE_FLAGS = content_cache_flags(PRETTIER_RELATED_CACHE_FILE);
3347
+ var CSPELL_COMMIT_CACHE_FLAGS = content_cache_flags(CSPELL_COMMIT_CACHE_FILE);
3348
+ var ESLINT_COMMIT_CACHE_FLAGS = content_cache_flags(ESLINT_COMMIT_CACHE_FILE);
3349
+
3688
3350
  // scripts/lib/ancestor-directories.ts
3689
3351
  import path9 from "node:path";
3690
3352
  var MAX_DEPTH = 64;
3691
3353
  function list(start_directory) {
3692
- const directories2 = [];
3354
+ const directories = [];
3693
3355
  let current = path9.resolve(start_directory);
3694
- while (directories2.length < MAX_DEPTH && !directories2.includes(current)) {
3695
- directories2.push(current);
3356
+ while (directories.length < MAX_DEPTH && !directories.includes(current)) {
3357
+ directories.push(current);
3696
3358
  current = path9.dirname(current);
3697
3359
  }
3698
- return directories2;
3360
+ return directories;
3699
3361
  }
3700
3362
  function nearest(start_directory, is_match) {
3701
3363
  return list(start_directory).find((directory) => is_match(directory));
@@ -3703,14 +3365,14 @@ function nearest(start_directory, is_match) {
3703
3365
  var ancestor_directories = { list, nearest };
3704
3366
 
3705
3367
  // scripts/lib/package-manifest.ts
3706
- import { readFileSync as readFileSync5 } from "node:fs";
3368
+ import { readFileSync as readFileSync4 } from "node:fs";
3707
3369
  import path10 from "node:path";
3708
3370
  var PACKAGE_JSON = "package.json";
3709
3371
  function manifest_path(directory) {
3710
3372
  return path10.join(directory, PACKAGE_JSON);
3711
3373
  }
3712
3374
  function read_manifest(directory, schema) {
3713
- const text2 = readFileSync5(manifest_path(directory), "utf8");
3375
+ const text2 = readFileSync4(manifest_path(directory), "utf8");
3714
3376
  return schema.parse(JSON.parse(text2));
3715
3377
  }
3716
3378
  function read_manifest_if_valid(directory, schema) {
@@ -3720,135 +3382,210 @@ function read_manifest_if_valid(directory, schema) {
3720
3382
  }
3721
3383
  var package_manifest = { manifest_path, read_manifest, read_manifest_if_valid };
3722
3384
 
3385
+ // scripts/gate/toolchain-inputs.ts
3386
+ import { createHash } from "node:crypto";
3387
+ import { existsSync as existsSync3, readdirSync as readdirSync4, readFileSync as readFileSync5 } from "node:fs";
3388
+ import path11 from "node:path";
3389
+ var PACKAGE_FILES = [
3390
+ "package.json",
3391
+ "pnpm-lock.yaml",
3392
+ "pnpm-workspace.yaml",
3393
+ "package-lock.json",
3394
+ "yarn.lock",
3395
+ "bun.lock",
3396
+ "bun.lockb",
3397
+ ".npmrc",
3398
+ "node_modules/.modules.yaml"
3399
+ ];
3400
+ var CONFIG_ENTRIES = [
3401
+ /^eslint\.config\.[cm]?[jt]s$/u,
3402
+ /^tsconfig(?:\.[\w-]+)?\.json$/u
3403
+ ];
3404
+ var CONFIG_DIRECTORIES = /* @__PURE__ */ new Set(["eslint", "tsconfig"]);
3405
+ var TEST_MARKER = ".test.";
3406
+ var SEPARATOR = "/";
3407
+ var DIGEST_ALGORITHM = "sha256";
3408
+ function by_code_unit(left, right) {
3409
+ if (left === right) return 0;
3410
+ return left < right ? -1 : 1;
3411
+ }
3412
+ function to_posix(relative) {
3413
+ return relative.split(path11.sep).join(SEPARATOR);
3414
+ }
3415
+ function is_config_entry(name) {
3416
+ return CONFIG_ENTRIES.some((entry) => entry.test(name));
3417
+ }
3418
+ function is_config_module(relative) {
3419
+ const [top = ""] = relative.split(SEPARATOR, 1);
3420
+ return CONFIG_DIRECTORIES.has(top) && !path11.basename(relative).includes(TEST_MARKER);
3421
+ }
3422
+ function is_input(relative) {
3423
+ const posix = to_posix(relative);
3424
+ if (PACKAGE_FILES.includes(posix)) return true;
3425
+ return is_config_entry(posix) || is_config_module(posix);
3426
+ }
3427
+ function modules_under(root2, directory) {
3428
+ const absolute = path11.join(root2, directory);
3429
+ if (!existsSync3(absolute)) return [];
3430
+ return readdirSync4(absolute, { recursive: true, withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => to_posix(path11.relative(root2, path11.join(entry.parentPath, entry.name)))).filter((relative) => is_config_module(relative));
3431
+ }
3432
+ function paths(root2) {
3433
+ const present = PACKAGE_FILES.filter((relative) => existsSync3(path11.join(root2, relative)));
3434
+ const entries = readdirSync4(root2).filter((name) => is_config_entry(name));
3435
+ const modules = [...CONFIG_DIRECTORIES].flatMap((directory) => modules_under(root2, directory));
3436
+ return [...present, ...entries, ...modules].toSorted(by_code_unit);
3437
+ }
3438
+ function read_or_empty(file) {
3439
+ try {
3440
+ return readFileSync5(file);
3441
+ } catch {
3442
+ return new Uint8Array();
3443
+ }
3444
+ }
3445
+ function digest(root2) {
3446
+ const hash = createHash(DIGEST_ALGORITHM);
3447
+ for (const relative of paths(root2)) {
3448
+ hash.update(`${relative}\0`).update(read_or_empty(path11.join(root2, relative))).update("\0");
3449
+ }
3450
+ return hash.digest("hex");
3451
+ }
3452
+ var toolchain_inputs = { digest, is_input, PACKAGE_FILES, paths };
3453
+
3723
3454
  // scripts/git/git-schemas.ts
3724
- import { z as z7 } from "zod";
3725
- var package_name_schema = z7.object({ name: z7.string().min(1) });
3726
- var rollup_item_schema = z7.looseObject({
3455
+ import { z as z9 } from "zod";
3456
+ var package_name_schema = z9.object({ name: z9.string().min(1) });
3457
+ var rollup_item_schema = z9.looseObject({
3727
3458
  // eslint-disable-next-line @typescript-eslint/naming-convention -- GraphQL field name from GitHub API
3728
- __typename: z7.string().nullish(),
3729
- state: z7.string().nullish(),
3730
- status: z7.string().nullish(),
3731
- conclusion: z7.string().nullish(),
3732
- name: z7.string().nullish(),
3733
- context: z7.string().nullish(),
3734
- description: z7.string().nullish()
3459
+ __typename: z9.string().nullish(),
3460
+ state: z9.string().nullish(),
3461
+ status: z9.string().nullish(),
3462
+ conclusion: z9.string().nullish(),
3463
+ name: z9.string().nullish(),
3464
+ context: z9.string().nullish(),
3465
+ description: z9.string().nullish()
3735
3466
  });
3736
- var pr_raw_schema = z7.object({
3737
- statusCheckRollup: z7.array(rollup_item_schema).optional(),
3467
+ var pr_raw_schema = z9.object({
3468
+ statusCheckRollup: z9.array(rollup_item_schema).optional(),
3738
3469
  // The base branch's required status check contexts, read from its rules — empty where none are
3739
3470
  // set or they could not be read (`git-gh-branch-rules.ts`).
3740
- requiredContexts: z7.array(z7.string()).optional(),
3741
- mergeStateStatus: z7.string().optional(),
3742
- reviewDecision: z7.string().optional(),
3743
- headRefOid: z7.string().optional()
3471
+ requiredContexts: z9.array(z9.string()).optional(),
3472
+ mergeStateStatus: z9.string().optional(),
3473
+ reviewDecision: z9.string().optional(),
3474
+ headRefOid: z9.string().optional()
3744
3475
  });
3745
- var pull_comment_schema = z7.object({
3746
- body: z7.string().optional(),
3747
- html_url: z7.string().optional(),
3748
- user: z7.object({ login: z7.string().optional() }).optional()
3476
+ var pull_comment_schema = z9.object({
3477
+ body: z9.string().optional(),
3478
+ html_url: z9.string().optional(),
3479
+ user: z9.object({ login: z9.string().optional() }).optional()
3749
3480
  });
3750
- var ai_review_pull_comment_schema = z7.object({
3751
- body: z7.string().optional(),
3752
- url: z7.string().optional(),
3753
- author: z7.object({ login: z7.string().optional() }).optional()
3481
+ var ai_review_pull_comment_schema = z9.object({
3482
+ body: z9.string().optional(),
3483
+ url: z9.string().optional(),
3484
+ author: z9.object({ login: z9.string().optional() }).optional(),
3485
+ updatedAt: z9.string().optional()
3754
3486
  });
3755
- var pr_info_schema = z7.object({
3756
- mergeable: z7.union([z7.boolean(), z7.string()]).nullable().optional(),
3757
- mergeStateStatus: z7.string().nullable().optional(),
3758
- state: z7.string().optional()
3487
+ var pr_info_schema = z9.object({
3488
+ mergeable: z9.union([z9.boolean(), z9.string()]).nullable().optional(),
3489
+ mergeStateStatus: z9.string().nullable().optional(),
3490
+ state: z9.string().optional()
3759
3491
  });
3760
- var epic_issue_schema = z7.object({
3761
- number: z7.number(),
3762
- body: z7.string().optional(),
3492
+ var epic_issue_schema = z9.object({
3493
+ number: z9.number(),
3494
+ body: z9.string().optional(),
3763
3495
  // REST answers null for an issue never closed and `reopened` for one a person reopened.
3764
- stateReason: z7.string().nullish()
3496
+ stateReason: z9.string().nullish()
3765
3497
  });
3766
- var blocking_issue_schema = z7.object({
3767
- number: z7.number(),
3768
- state: z7.string().optional(),
3769
- repository_url: z7.string().optional()
3498
+ var blocking_issue_schema = z9.object({
3499
+ number: z9.number(),
3500
+ state: z9.string().optional(),
3501
+ repository_url: z9.string().optional()
3770
3502
  });
3771
- var blocked_by_schema = z7.object({
3772
- nodes: z7.array(blocking_issue_schema).default([]),
3773
- totalCount: z7.number().optional()
3503
+ var blocked_by_schema = z9.object({
3504
+ nodes: z9.array(blocking_issue_schema).default([]),
3505
+ totalCount: z9.number().optional()
3774
3506
  }).optional();
3775
- var epic_child_schema = z7.object({
3776
- state: z7.string().optional(),
3507
+ var epic_child_schema = z9.object({
3508
+ state: z9.string().optional(),
3777
3509
  blockedBy: blocked_by_schema
3778
3510
  });
3779
- var rest_comment_schema = z7.looseObject({
3780
- body: z7.string().nullish(),
3781
- html_url: z7.string().optional(),
3782
- user: z7.looseObject({ login: z7.string().optional() }).nullish()
3511
+ var rest_comment_schema = z9.looseObject({
3512
+ body: z9.string().nullish(),
3513
+ html_url: z9.string().optional(),
3514
+ user: z9.looseObject({ login: z9.string().optional() }).nullish(),
3515
+ updated_at: z9.string().optional()
3783
3516
  });
3784
- var issue_label_schema = z7.object({ name: z7.string() });
3785
- var epic_subject_schema = z7.object({
3786
- number: z7.number(),
3787
- state: z7.string().optional(),
3788
- labels: z7.array(issue_label_schema).optional(),
3789
- body: z7.string().optional()
3517
+ var issue_label_schema = z9.object({ name: z9.string() });
3518
+ var epic_subject_schema = z9.object({
3519
+ number: z9.number(),
3520
+ state: z9.string().optional(),
3521
+ labels: z9.array(issue_label_schema).optional(),
3522
+ body: z9.string().optional()
3790
3523
  });
3791
- var open_issue_schema = z7.object({
3792
- number: z7.number(),
3793
- title: z7.string(),
3794
- labels: z7.array(issue_label_schema).optional(),
3795
- createdAt: z7.string(),
3524
+ var author_fields_schema = {
3525
+ author_association: z9.string().nullish(),
3526
+ user: z9.looseObject({ login: z9.string() }).nullish()
3527
+ };
3528
+ var open_issue_schema = z9.object({
3529
+ number: z9.number(),
3530
+ title: z9.string(),
3531
+ labels: z9.array(issue_label_schema).optional(),
3532
+ createdAt: z9.string(),
3796
3533
  blockedBy: blocked_by_schema,
3797
3534
  // Present only on the pickup listing, which reads it for the paths each issue declares.
3798
- body: z7.string().optional()
3535
+ body: z9.string().optional(),
3536
+ ...author_fields_schema,
3537
+ // Assembled by the pickup from the author above, never read off the listing: whether the author
3538
+ // has write access. Absent on every other listing.
3539
+ author_trusted: z9.boolean().optional()
3799
3540
  });
3800
3541
 
3801
3542
  export {
3802
3543
  json_value,
3803
3544
  file_reader,
3545
+ figure_format,
3546
+ pr_raw_schema,
3547
+ epic_issue_schema,
3548
+ blocking_issue_schema,
3549
+ blocked_by_schema,
3550
+ rest_comment_schema,
3551
+ issue_label_schema,
3552
+ author_fields_schema,
3553
+ open_issue_schema,
3554
+ durable_state,
3804
3555
  process_identity,
3805
- process_owner_schema,
3806
3556
  issue_number_shape,
3807
- lane_paths,
3808
- stamped_memo,
3809
- PORCELAIN_FLAG,
3810
- UNTRACKED_FILES_FLAG,
3811
- get_exit_code,
3812
- has_timed_out,
3813
- git_spawn,
3814
- git_diff_reads,
3815
- GIT_LOCATION_VARIABLES,
3816
- git_spawn_sync,
3817
- git_command,
3818
3557
  cli_flags,
3819
3558
  run_invocation,
3559
+ lane_paths,
3820
3560
  time_instant,
3821
3561
  cost_usage,
3822
3562
  cost_transcript,
3823
3563
  agent_session_environment,
3824
3564
  own_session,
3825
3565
  run_carry,
3826
- PORT_SEED_KEY,
3827
- LANE_SEAT_KEY,
3828
- ENV_FILE_NAME,
3829
- ports,
3830
- figure_format,
3831
- pr_raw_schema,
3832
- epic_issue_schema,
3833
- blocking_issue_schema,
3834
- blocked_by_schema,
3835
- rest_comment_schema,
3836
- issue_label_schema,
3837
- open_issue_schema,
3566
+ lane_ledger_schema,
3567
+ lane_ledger_write,
3838
3568
  issue_cite,
3839
- git_common_directory,
3569
+ process_owner_schema,
3840
3570
  repository_lock,
3841
3571
  run_ship_stage,
3842
3572
  run_event_stream,
3843
- repo_origin,
3844
- repo_map_logic,
3845
- repo_discovery,
3846
3573
  issue_citation,
3847
3574
  session_cite,
3848
3575
  lane_state,
3849
3576
  run_event_scope,
3850
3577
  run_event_stream_emit,
3578
+ PORT_SEED_KEY,
3579
+ LANE_SEAT_KEY,
3580
+ ENV_FILE_NAME,
3581
+ ports,
3582
+ OPTIONAL_ENV_FILE_FLAGS,
3583
+ ESLINT_RELATED_CACHE_FILE,
3584
+ ESLINT_EDIT_CACHE_FLAGS,
3585
+ ESLINT_RELATED_CACHE_FLAGS,
3586
+ PRETTIER_RELATED_CACHE_FLAGS,
3851
3587
  ancestor_directories,
3852
3588
  PACKAGE_JSON,
3853
- package_manifest
3589
+ package_manifest,
3590
+ toolchain_inputs
3854
3591
  };