@joshuafolkken/kit 1.1784.0 → 1.2114.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 +59 -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 +415 -389
  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 +15 -8
  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,5 +1,6 @@
1
1
  import { issue_cite } from '#scripts/issue/issue-cite'
2
2
  import { run_event_filed, type FiledKind } from '#scripts/run/event/run-event-filed'
3
+ import { run_event_overrun } from '#scripts/run/event/run-event-overrun'
3
4
  import { run_event_scope } from '#scripts/run/event/run-event-scope'
4
5
  import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
5
6
  import { run_board_ending_reason } from './run-board-ending-reason'
@@ -84,11 +85,16 @@ function plain_note(event: RunEvent): BoardNote {
84
85
  return { kind: 'note', at_ms: Date.parse(event.at), issue, text }
85
86
  }
86
87
 
88
+ // An overrun note is no finding (joshuafolkken/kit#4818): the merged row says it after its time.
89
+ function is_finding(event: RunEvent): boolean {
90
+ return event.kind === KIND.NOTE && run_event_overrun.parse(event.text) === undefined
91
+ }
92
+
87
93
  function note_of(event: RunEvent, titles: Titles): BoardNote | undefined {
88
94
  if (event.kind === KIND.FILED) return filed_note(event)
89
95
  if (event.kind === KIND.PARK) return park_note(event, titles)
90
96
 
91
- return event.kind === KIND.NOTE ? plain_note(event) : undefined
97
+ return is_finding(event) ? plain_note(event) : undefined
92
98
  }
93
99
 
94
100
  // A park is said only of a child the board still holds parked, so one a person released or closed
@@ -1,4 +1,5 @@
1
1
  import path from 'node:path'
2
+ import { token_shape } from '#scripts/lib/token-shape'
2
3
  import { transcript_record, type TranscriptRecord } from '#scripts/lib/transcript-record'
3
4
  import { z } from 'zod'
4
5
 
@@ -60,12 +61,13 @@ function without_assignments(command: string): string {
60
61
  }
61
62
 
62
63
  // The first line of what the command runs, cut to the limit. A command whose variable cannot be read
63
- // to its end is drawn as nothing: a part of the value would stand where the command should.
64
+ // to its end is drawn as nothing: a part of the value would stand where the command should. A
65
+ // credential later in the line is redacted before the cut, which would leave a head no shape matches.
64
66
  function command_target(command: string): string {
65
67
  const [first = ''] = without_assignments(command.trim()).split(NEWLINE)
66
68
  if (UNREAD_ASSIGNMENT.test(first)) return ''
67
69
 
68
- return cut(ascii_head(first.replaceAll(SPACES, ' ')))
70
+ return cut(ascii_head(token_shape.redact(first).replaceAll(SPACES, ' ')))
69
71
  }
70
72
 
71
73
  // The path from `root` down; a file outside it is drawn by its name alone, never by where it is.
@@ -35,9 +35,6 @@ const KIND = run_event_stream.EVENT_KIND
35
35
  const { STAGE } = run_ship_stage
36
36
  // A launched child is investigating until a later record says otherwise — no event marks the start.
37
37
  const LAUNCHED_PHASE: Phase = 'investigate'
38
- const WORD_SEPARATOR = ' '
39
- const STAGE_INDEX = 1
40
- const PHASE_INDEX = 2
41
38
 
42
39
  // `josh ship`'s stages, each its own phase; the preflight is the ship's own start.
43
40
  const SHIP_PHASES: Readonly<Partial<Record<string, Phase>>> = {
@@ -62,12 +59,12 @@ const KIND_PHASES: Readonly<Partial<Record<string, Phase>>> = {
62
59
 
63
60
  // The word after the issue — `#<N> <stage> <phase>` carries the stage second.
64
61
  function stage_word_of(event: RunEvent): string {
65
- return event.text.split(WORD_SEPARATOR)[STAGE_INDEX] ?? ''
62
+ return run_ship_stage.words_of(event.text).stage
66
63
  }
67
64
 
68
65
  // The word after the stage — whether it started, succeeded, failed or was passed over.
69
66
  function phase_word_of(event: RunEvent): string {
70
- return event.text.split(WORD_SEPARATOR)[PHASE_INDEX] ?? ''
67
+ return run_ship_stage.words_of(event.text).phase
71
68
  }
72
69
 
73
70
  // A stage marks its phase when it starts; its `done`, and one a resumed ship passed over, mark none.
@@ -1,5 +1,5 @@
1
1
  import { auto_ok_cli, type OptedInRead } from '#scripts/auto-ok/auto-ok-cli'
2
- import type { OptedIn } from '#scripts/backlog/backlog-next'
2
+ import type { OptedIn } from '#scripts/backlog/backlog-gate-scope'
3
3
  import { backlog_plan, type NamedPlan } from '#scripts/backlog/backlog-plan'
4
4
  import { backlog_plan_read, type OpenListing, type Plan } from '#scripts/backlog/backlog-plan-read'
5
5
  import { backlog_waves } from '#scripts/backlog/backlog-waves'
@@ -10,9 +10,12 @@ import { lane_state } from '#scripts/lane/lane-state'
10
10
  import { stamped_memo } from '#scripts/lib/stamped-memo'
11
11
  import { run_carry, type RunCarry } from '#scripts/run/carry/run-carry'
12
12
  import { run_carry_ended } from '#scripts/run/carry/run-carry-ended'
13
+ import { run_event_scope } from '#scripts/run/event/run-event-scope'
13
14
  import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
15
+ import { run_merge_usage_limit } from '#scripts/run/merge/run-merge-usage-limit'
14
16
  import { run_stranded_detect } from '#scripts/run/run-stranded-detect'
15
17
  import { run_wake } from '#scripts/run/wake/run-wake'
18
+ import { run_board_found, type FoundOf } from './run-board-found'
16
19
  import { run_board_lane_state, type BoardLanes } from './run-board-lane-state'
17
20
  import {
18
21
  run_board_operation_read,
@@ -61,6 +64,9 @@ interface LocalRead {
61
64
  occupied_count?: number | undefined
62
65
  // How long each phase usually takes, from the repository's lane ledger.
63
66
  usual?: UsualTimes | undefined
67
+ // The reset a Claude usage limit holds the running run's launches until (`run-merge-usage-limit.ts`);
68
+ // `undefined` once it has passed, where none was recorded, or where no run is carried.
69
+ usage_reset_ms?: number | undefined
64
70
  // The driver holds its offered issue until the machine has memory for one more lane — the ledger's
65
71
  // open hold is `backlog-drive-memory.ts`'s.
66
72
  is_memory_held?: boolean | undefined
@@ -72,6 +78,9 @@ interface LocalRead {
72
78
  closing?: ReadonlySet<string> | undefined
73
79
  // The run's record, whose declared order holds a queued row (`backlog-drive-named.ts`).
74
80
  carry?: RunCarry | undefined
81
+ // What each done row says after its time, its sessions probed once a read against `table`
82
+ // (`run-board-found.ts`), never per redraw.
83
+ found?: FoundOf | undefined
75
84
  }
76
85
 
77
86
  const NO_SPAN: SpanHere = {
@@ -215,6 +224,42 @@ function ledger_here(repository: string): Pick<LocalRead, 'usual' | 'is_memory_h
215
224
  }
216
225
  }
217
226
 
227
+ // The reset a usage limit holds the running run's launches until, read off the events `backlog:drive`
228
+ // reads it off (`run_event_stream_emit.current_events`): the carried invocation's, so an ended run's
229
+ // stop holds no row the driver would launch.
230
+ function usage_reset_here(
231
+ events: ReadonlyArray<RunEvent>,
232
+ carry: RunCarry | undefined,
233
+ ): number | undefined {
234
+ if (carry === undefined) return undefined
235
+ const scope = run_event_scope.scope_of({ kind: 'carried', carry })
236
+
237
+ return run_merge_usage_limit.held_until(
238
+ run_event_scope.scoped_events(events, scope) ?? [],
239
+ Date.now(),
240
+ )
241
+ }
242
+
243
+ // The run's own events, what its done rows say after their time with each open investigation's
244
+ // session asked of `table`, and the usage limit its record's invocation is held by.
245
+ async function span_events_here(
246
+ events: ReadonlyArray<RunEvent>,
247
+ span: BoardSpan,
248
+ table: TableRead | undefined,
249
+ carry: RunCarry | undefined,
250
+ ): Promise<Pick<LocalRead, 'events' | 'found' | 'usage_reset_ms'>> {
251
+ const spanned = run_board_span.events_of(events, span)
252
+ // An overrun session outlives the run that launched it, so its notes and filings are read past the
253
+ // run's end too (joshuafolkken/kit#4818); the next run starts a span of its own.
254
+ const since = run_board_span.events_of(events, { ...span, ended_ms: undefined })
255
+
256
+ return {
257
+ events: spanned,
258
+ found: run_board_found.found_of(since, await run_board_found.live_in(table)),
259
+ usage_reset_ms: usage_reset_here(events, carry),
260
+ }
261
+ }
262
+
218
263
  // `undefined` when no run has started here. The lane count reads `table`, the redraw's process
219
264
  // snapshot, so it agrees with the usage columns.
220
265
  async function read_local(table?: TableRead): Promise<LocalRead | undefined> {
@@ -232,7 +277,7 @@ async function read_local(table?: TableRead): Promise<LocalRead | undefined> {
232
277
  started_ms: span.started_ms,
233
278
  ended_ms: span.ended_ms,
234
279
  scope: run_board_scope.scope_of(span.invocation),
235
- events: run_board_span.events_of(events, span),
280
+ ...(await span_events_here(events, span, table, carry)),
236
281
  lanes: lanes.map((lane) => lane.issue),
237
282
  lane_states,
238
283
  resume,
@@ -51,6 +51,8 @@ interface ReasonRead extends Overlay {
51
51
  occupied_count?: number | undefined
52
52
  // The limit those lanes fill; `undefined` where it could not be read.
53
53
  lane_limit?: number | undefined
54
+ // The reset a Claude usage limit holds launches until (`run-merge-usage-limit.ts`), if one does.
55
+ usage_reset_ms?: number | undefined
54
56
  // The driver holds its offered issue for memory (`backlog-drive-memory.ts`).
55
57
  is_memory_held?: boolean | undefined
56
58
  // The machine's latest gauges, the figures a memory hold names.
@@ -59,6 +61,8 @@ interface ReasonRead extends Overlay {
59
61
  carry?: RunCarry | undefined
60
62
  // A stopped run opens no lane, so a stage its stream ends on is not one any lane is at.
61
63
  is_stopped: boolean
64
+ // The board's clock, which a declared start time is weighed against.
65
+ now_ms: number
62
66
  }
63
67
 
64
68
  // What every row of one layout is weighed against, read once.
@@ -109,7 +113,7 @@ function running_of(read: ReasonRead): Array<number> {
109
113
  function is_candidate(child: EpicChild, read: ReasonRead): boolean {
110
114
  return (
111
115
  epic_triage.is_triaged(child) &&
112
- issue_not_before.is_due(child.body) &&
116
+ issue_not_before.is_due(child.body, read.now_ms) &&
113
117
  !run_board_layout.is_blocked(child, read)
114
118
  )
115
119
  }
@@ -190,9 +194,16 @@ function no_memory_of(gauges: MachineGauges | undefined): RowReason {
190
194
  }
191
195
  }
192
196
 
193
- // The machine's room: no lane left under the limit, else no memory for one more.
197
+ // `🪫 10-25 16:30`: the reset a usage limit holds every launch until, in the board's local time.
198
+ function usage_limit_of(reset_ms: number): RowReason {
199
+ return { icon: WAIT_ICONS.usage_limit, value: run_board_labels.day_minute_of(reset_ms) }
200
+ }
201
+
202
+ // The machine's room: no lane left under the limit, else a usage limit not yet reset, else no memory
203
+ // for one more — the order `backlog:drive` asks them in.
194
204
  function room_wait(read: ReasonRead): RowReason | undefined {
195
205
  if (read.free_lanes === NO_FREE_LANES) return no_lane_of(read)
206
+ if (read.usage_reset_ms !== undefined) return usage_limit_of(read.usage_reset_ms)
196
207
 
197
208
  return read.is_memory_held === true ? no_memory_of(read.gauges) : undefined
198
209
  }
@@ -247,7 +258,7 @@ function solo_wait(child: EpicChild, pool: Pool): RowReason | undefined {
247
258
  // A candidate nothing blocks, in the order the driver answers: the declared order, then what
248
259
  // `backlog:next` answers — the pool held for a judgment, then a running `run:solo` issue, then a
249
260
  // waiting `run:solo` issue's wait, then a path a running issue declares, then a pool with no lane
250
- // left, then a machine with no memory.
261
+ // left, then a usage limit not yet reset, then a machine with no memory.
251
262
  function offer_wait(child: EpicChild, read: ReasonRead, pool: Pool): RowReason | undefined {
252
263
  return (
253
264
  named_of(child, read, pool) ??
@@ -259,20 +270,21 @@ function offer_wait(child: EpicChild, read: ReasonRead, pool: Pool): RowReason |
259
270
  }
260
271
 
261
272
  // `📅 3/10`: the merges the ledger recorded after the declared pull request merged, of those the body
262
- // waits on; `📅 4313` while that pull request has not merged or its merge is unread.
273
+ // waits on; `📅 4313` while that pull request has not merged or its merge is unread — the cited issue
274
+ // for a condition waiting on the pull request that closes it.
263
275
  function sample_wait_of(child: EpicChild): RowReason | undefined {
264
276
  const wait = issue_sample_gate.wait_of(child.body)
265
277
 
266
278
  if (wait === undefined) return undefined
267
- if (wait.kind !== 'short') return { icon: WAIT_ICONS.not_before, issues: [String(wait.pr)] }
279
+ if (wait.kind !== 'short') return { icon: WAIT_ICONS.not_before, issues: [String(wait.cited)] }
268
280
 
269
281
  return { icon: WAIT_ICONS.not_before, value: `${String(wait.counted)}/${String(wait.needed)}` }
270
282
  }
271
283
 
272
284
  // `📅 10-20 16:30`: the start time the body declares and the clock has not reached, in the board's
273
285
  // local time.
274
- function not_before_of(child: EpicChild): RowReason | undefined {
275
- const ms = issue_not_before.waiting_ms(child.body)
286
+ function not_before_of(child: EpicChild, now_ms: number): RowReason | undefined {
287
+ const ms = issue_not_before.waiting_ms(child.body, now_ms)
276
288
 
277
289
  if (ms === undefined) return sample_wait_of(child)
278
290
 
@@ -303,7 +315,7 @@ function wait_of(
303
315
  if (!epic_triage.is_triaged(child)) return untriaged_of(waits)
304
316
  if (waits.length > 0) return { icon: blocker_icon(child, pool), issues: waits }
305
317
 
306
- return not_before_of(child) ?? offer_wait(child, read, pool)
318
+ return not_before_of(child, read.now_ms) ?? offer_wait(child, read, pool)
307
319
  }
308
320
 
309
321
  // What each waiting row of one layout says, the pool-wide facts read once for all of them.
@@ -42,9 +42,10 @@ function coderabbit_part(state: CodeRabbitState): Array<string> {
42
42
  return mark === undefined ? [] : [tinted(`${CODERABBIT_ICON} ${mark}`, CODERABBIT_COLORS[state])]
43
43
  }
44
44
 
45
- function checks_part(checks: PrChecks): string {
45
+ // `link` makes the number a link to the pull request (joshuafolkken/kit#4625); `PR` stays plain.
46
+ function checks_part(checks: PrChecks, link: (number: number) => string): string {
46
47
  return [
47
- `PR ${String(checks.pr)}`,
48
+ `PR ${link(checks.pr)}`,
48
49
  ...count_part(CHECK_ICONS.pass, checks.pass),
49
50
  ...count_part(CHECK_ICONS.pending, checks.pending),
50
51
  ...count_part(CHECK_ICONS.fail, checks.fail, 'red'),
@@ -2,6 +2,7 @@ import { run_board_header, type BoardHeader } from './run-board-header'
2
2
  import { run_board_labels } from './run-board-labels'
3
3
  import { run_board_layout, type BoardRow } from './run-board-layout'
4
4
  import { run_board_render_checks } from './run-board-render-checks'
5
+ import { run_board_render_found } from './run-board-render-found'
5
6
  import type { LegendDrawn } from './run-board-render-legend'
6
7
  import { run_board_render_tail } from './run-board-render-tail'
7
8
  import { run_board_render_waits } from './run-board-render-waits'
@@ -24,6 +25,14 @@ function has_lanes(header: BoardHeader): boolean {
24
25
  return layout !== undefined && run_board_layout.lanes_drawn(layout).length > 0
25
26
  }
26
27
 
28
+ // A lane row draws 🧍 in its indent (joshuafolkken/kit#4625).
29
+ function has_solo_lane(header: BoardHeader): boolean {
30
+ const { layout } = header
31
+ const lanes = layout === undefined ? [] : run_board_layout.lanes_drawn(layout)
32
+
33
+ return lanes.some((row) => row.is_solo === true)
34
+ }
35
+
27
36
  // The third line's kinds, ⏰ where the lanes rule stands it over the lanes' times, then the estimated
28
37
  // finish.
29
38
  function named_of(header: BoardHeader, icons: ReadonlySet<string>): Array<string> {
@@ -59,6 +68,8 @@ function drawn_of(
59
68
  named: named_of(header, icons),
60
69
  checks: run_board_render_checks.legend_of(checks),
61
70
  held: run_board_render_waits.legend_of(header),
71
+ solo: has_solo_lane(header),
72
+ overrun: rows.some((row) => run_board_render_found.is_still(row, header)),
62
73
  }
63
74
  }
64
75
 
@@ -0,0 +1,157 @@
1
+ import { run_event_overrun, type OverrunNote } from '#scripts/run/event/run-event-overrun'
2
+ import type { Found } from './run-board-found'
3
+ import type { BoardHeader } from './run-board-header'
4
+ import { run_board_labels } from './run-board-labels'
5
+ import type { BoardRow } from './run-board-layout'
6
+ import { run_board_render_title } from './run-board-render-title'
7
+ import type { ItemState } from './run-board-status'
8
+
9
+ // A done row's end after its time (joshuafolkken/kit#4772, joshuafolkken/kit#4818). A merged row says
10
+ // its lane's net minutes — `?′` where there are none — the numbers of the Issues its child filed, then
11
+ // what its overrun investigation came to and the numbers it filed (joshuafolkken/kit#4880), each group
12
+ // two spaces apart: `⏭` and why it was skipped, or 🔍, the lane's longest stage and the numbers it filed
13
+ // (`🔍 implement 51′ · 4983`), `↪N` for each open
14
+ // Issue it appended causes to (joshuafolkken/kit#4858), `∅` and why it did not, `∅ ↻N` for a
15
+ // recurrence commented on, or 💥 for an investigation that failed. While the investigation runs, the spinner stands for 🔍.
16
+ // A row its merge left no note on was never asked. A done row that did not merge, and a merged row
17
+ // while the investigation switch is off, says only what was filed during it.
18
+
19
+ const { OVERRUN_MARK } = run_board_labels
20
+ const DONE_STATES: ReadonlySet<ItemState> = new Set(['merged', 'done'])
21
+ const SEPARATOR = ', '
22
+ const GROUP_SEPARATOR = ' '
23
+ const LONGEST_SEPARATOR = ' · '
24
+ const MINUTES_WIDTH = 3
25
+ const MINUTE_MARK = '′'
26
+ const UNKNOWN_MINUTES = '?'
27
+ const SKIP_MARK = '⏭'
28
+ const NONE_MARK = '∅'
29
+ const RECURRED_MARK = '↻'
30
+ const FOLDED_MARK = '↪'
31
+ const FAILED_TEXT = `${OVERRUN_MARK} 💥`
32
+ const NO_RECORD = 'no record'
33
+ // The investigator writes its reason in about 15 characters; the row keeps no more.
34
+ const REASON_LIMIT = 16
35
+
36
+ function found_of(row: BoardRow, header: BoardHeader): Found | undefined {
37
+ if (!DONE_STATES.has(row.state)) return undefined
38
+
39
+ return header.found?.get(row.number)
40
+ }
41
+
42
+ function links_of(references: ReadonlyArray<string>, header: BoardHeader): string {
43
+ return references.map((reference) => header.link(reference)).join(SEPARATOR)
44
+ }
45
+
46
+ // Every filing, the child's and the investigation's alike: a row that did not merge has no outcome
47
+ // to tell them apart by.
48
+ function numbers_of(found: Found | undefined, header: BoardHeader): string {
49
+ return links_of([...(found?.filed ?? []), ...(found?.overrun_filed ?? [])], header)
50
+ }
51
+
52
+ function minutes_text(found: Found | undefined): string {
53
+ const minutes = found?.minutes === undefined ? UNKNOWN_MINUTES : String(found.minutes)
54
+
55
+ return `${minutes.padStart(MINUTES_WIDTH)}${MINUTE_MARK}`
56
+ }
57
+
58
+ // An investigation that filed nothing: the recurrence it commented on, a link with no `#` and its mark
59
+ // outside it (joshuafolkken/kit#4956), else why it did not.
60
+ function none_text(result: string, header: BoardHeader): string {
61
+ const recurred = run_event_overrun.recurred_of(result)
62
+
63
+ if (recurred !== undefined) return `${NONE_MARK} ${RECURRED_MARK}${header.link(String(recurred))}`
64
+
65
+ const why = run_board_render_title.title_of(run_event_overrun.reason_of(result), REASON_LIMIT)
66
+
67
+ return `${NONE_MARK} ${why}`
68
+ }
69
+
70
+ // The open Issues the investigation appended its causes to, each a link with no `#`.
71
+ function folded_text(issues: ReadonlyArray<number>, header: BoardHeader): string {
72
+ const links = issues.map((issue) => `${FOLDED_MARK}${header.link(String(issue))}`)
73
+
74
+ return `${OVERRUN_MARK} ${links.join(SEPARATOR)}`
75
+ }
76
+
77
+ // The result decides, not whether anything was filed: an event written before the overrun mark reads
78
+ // as the child's.
79
+ function ended_text(result: string, header: BoardHeader): string {
80
+ const folded = run_event_overrun.folded_of(result)
81
+
82
+ if (folded.length > 0) return folded_text(folded, header)
83
+ if (result.startsWith(run_event_overrun.FILED_RESULT)) return OVERRUN_MARK
84
+
85
+ return `${OVERRUN_MARK} ${none_text(result, header)}`
86
+ }
87
+
88
+ // A started session still running turns the spinner, one gone without its end note failed, and one
89
+ // whose start token was never read stands still while its pid lives.
90
+ function started_text(found: Found, header: BoardHeader): string {
91
+ if (found.is_investigating === false) return FAILED_TEXT
92
+ if (found.is_investigating === undefined) return OVERRUN_MARK
93
+
94
+ return header.spinner ?? OVERRUN_MARK
95
+ }
96
+
97
+ // A lane at or under the threshold says nothing past its minutes.
98
+ function outcome_text(found: Found, note: OverrunNote, header: BoardHeader): string {
99
+ if (note.kind === 'within') return ''
100
+ if (note.kind === 'skipped') return `${SKIP_MARK} ${note.reason}`
101
+ if (note.kind === 'ended') return ended_text(note.result, header)
102
+
103
+ return note.kind === 'started' ? started_text(found, header) : FAILED_TEXT
104
+ }
105
+
106
+ function joined(parts: ReadonlyArray<string>, separator: string): string {
107
+ return parts.filter((part) => part !== '').join(separator)
108
+ }
109
+
110
+ // The lane's longest stage its start note carried (joshuafolkken/kit#4995), else nothing.
111
+ function longest_text(found: Found | undefined): string {
112
+ const longest = found?.longest
113
+
114
+ return longest === undefined ? '' : `${longest.name} ${String(longest.minutes)}${MINUTE_MARK}`
115
+ }
116
+
117
+ // What the investigation came to, its lane's longest stage, then the Issues it filed.
118
+ function investigation_text(found: Found | undefined, header: BoardHeader): string {
119
+ const outcome =
120
+ found?.overrun === undefined
121
+ ? `${SKIP_MARK} ${NO_RECORD}`
122
+ : outcome_text(found, found.overrun, header)
123
+
124
+ const filed = links_of(found?.overrun_filed ?? [], header)
125
+
126
+ return joined([outcome, joined([longest_text(found), filed], LONGEST_SEPARATOR)], ' ')
127
+ }
128
+
129
+ // The minutes, the child's own filings, then the investigation, each group apart by two spaces. While
130
+ // the investigation switch is off, every merged row says only what was filed, whatever its note
131
+ // (joshuafolkken/kit#5132, joshuafolkken/kit#5194).
132
+ function merged_text(row: BoardRow, header: BoardHeader): string {
133
+ const found = found_of(row, header)
134
+
135
+ if (!header.is_investigation_on) return numbers_of(found, header)
136
+
137
+ const own = links_of(found?.filed ?? [], header)
138
+
139
+ return joined([minutes_text(found), own, investigation_text(found, header)], GROUP_SEPARATOR)
140
+ }
141
+
142
+ // Empty for an unmerged done row with nothing filed, for every row not done, and on a board that read
143
+ // no stream.
144
+ function found_text(row: BoardRow, header: BoardHeader): string {
145
+ if (row.state === 'merged' && header.found !== undefined) return merged_text(row, header)
146
+
147
+ return numbers_of(found_of(row, header), header)
148
+ }
149
+
150
+ // The row draws 🔍, which the legend names.
151
+ function is_still(row: BoardRow, header: BoardHeader): boolean {
152
+ return row.state === 'merged' && found_text(row, header).includes(OVERRUN_MARK)
153
+ }
154
+
155
+ const run_board_render_found = { found_text, is_still }
156
+
157
+ export { run_board_render_found }
@@ -1,6 +1,7 @@
1
1
  import { run_board_earlier } from './run-board-earlier'
2
2
  import { run_board_fresh } from './run-board-fresh'
3
3
  import type { BoardHeader } from './run-board-header'
4
+ import { run_board_labels } from './run-board-labels'
4
5
  import type { BoardRow } from './run-board-layout'
5
6
  import { run_board_render_icon } from './run-board-render-icon'
6
7
  import { run_board_render_tail } from './run-board-render-tail'
@@ -16,6 +17,7 @@ const { BUDGET_ICON, held_of, held_time } = run_board_render_waits
16
17
  const { phase_time } = run_board_render_tail
17
18
  const { state_icon } = run_board_render_icon
18
19
  const { time_of } = run_board_render_time
20
+ const { WAIT_ICONS } = run_board_labels
19
21
  // The widest span a time column draws: `1°14′58″`.
20
22
  const TIME_WIDTH = 8
21
23
  const LANE_INDENT = ' '
@@ -60,6 +62,12 @@ function whole_of(row: BoardRow, header: BoardHeader): string {
60
62
  return run_board_fresh.padded(time, TIME_WIDTH, fresh)
61
63
  }
62
64
 
65
+ // A lane row's indent: 🧍 on a `run:solo` row (joshuafolkken/kit#4625), as wide as the blanks it
66
+ // replaces, so every column after it stays put.
67
+ function indent_of(row: BoardRow): string {
68
+ return row.is_solo === true ? WAIT_ICONS.solo : LANE_INDENT
69
+ }
70
+
63
71
  // A lane row's lead after its indent, ending where its usage cells start less one blank.
64
72
  function lead_of(row: BoardRow, header: BoardHeader): string {
65
73
  const icon = running_fresh(row, state_icon(row), row.status?.phase_ms, header)
@@ -73,6 +81,7 @@ const run_board_render_lead = {
73
81
  LANE_INDENT,
74
82
  TIME_WIDTH,
75
83
  USAGE_START,
84
+ indent_of,
76
85
  lead_of,
77
86
  running_fresh,
78
87
  }
@@ -20,10 +20,12 @@ const {
20
20
  FILED_KIND_ICONS,
21
21
  FILED_RUN_MARK,
22
22
  KIND_WORDS,
23
+ OVERRUN_MARK,
23
24
  PHASE_ICONS,
24
25
  PHASE_WORDS,
25
26
  STATE_ICONS,
26
27
  WAITS_ICON,
28
+ WAIT_ICONS,
27
29
  WAIT_WORDS,
28
30
  WORDS,
29
31
  } = run_board_labels
@@ -43,6 +45,11 @@ interface LegendDrawn {
43
45
  checks: ReadonlyArray<string>
44
46
  // 🚧 and the reasons a held check is drawn with (joshuafolkken/kit#4052).
45
47
  held: ReadonlyArray<string>
48
+ // A lane row leads with 🧍, its `run:solo` mark (joshuafolkken/kit#4625).
49
+ solo: boolean
50
+ // A merged row ends on 🔍, its overrun investigation running where no spinner turns
51
+ // (joshuafolkken/kit#4772) or its result once it ended (joshuafolkken/kit#4818).
52
+ overrun?: boolean | undefined
46
53
  }
47
54
 
48
55
  type LeadWords = ReadonlyArray<readonly [string, keyof Words]>
@@ -100,6 +107,16 @@ function waits_legend(rows: ReadonlyArray<BoardRow>): Array<string> {
100
107
  )
101
108
  }
102
109
 
110
+ // 🧍 is named only while a lane row draws it, and once where a waiting row leads with it too
111
+ // (joshuafolkken/kit#4625).
112
+ function solo_legend(rows: ReadonlyArray<BoardRow>, drawn: LegendDrawn): Array<string> {
113
+ if (!drawn.solo) return []
114
+
115
+ const is_named = rows.some((row) => wait_icon(row) === WAIT_ICONS.solo)
116
+
117
+ return is_named ? [] : [`${WAIT_ICONS.solo} ${WORDS.solo}`]
118
+ }
119
+
103
120
  // ✚ is named only while a row the run filed draws it (joshuafolkken/kit#4099).
104
121
  function filed_legend(
105
122
  rows: ReadonlyArray<BoardRow>,
@@ -135,7 +152,9 @@ function others_line(
135
152
  return [
136
153
  ...kind_named,
137
154
  ...waits_legend(rows),
155
+ ...solo_legend(rows, drawn),
138
156
  ...filed_legend(rows, notes),
157
+ ...(drawn.overrun === true ? [`${OVERRUN_MARK} ${WORDS.overrun}`] : []),
139
158
  ...drawn.held,
140
159
  ...drawn.checks,
141
160
  ...run_board_render_notes.notes_legend(notes, named, rows),
@@ -173,7 +173,7 @@ function tail_of(row: BoardRow, header: BoardHeader): Array<string> {
173
173
 
174
174
  const checks = checks_of(row, header)
175
175
 
176
- if (checks !== undefined) return [run_board_render_checks.checks_part(checks)]
176
+ if (checks !== undefined) return [run_board_render_checks.checks_part(checks, header.pull_link)]
177
177
 
178
178
  return [activity_part(row, header)]
179
179
  }