@joshuafolkken/kit 1.1240.0 → 1.1373.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 (934) hide show
  1. package/.claude/agents/investigator.md +1 -0
  2. package/.claude/settings.json +4 -0
  3. package/.claude/skills/dependency-update/SKILL.md +5 -3
  4. package/.claude/skills/epic-commands/SKILL.md +82 -113
  5. package/.claude/skills/epic-commands/epic-bundle.md +38 -63
  6. package/.claude/skills/epic-commands/execution-waves.md +30 -51
  7. package/.claude/skills/verify-ui/SKILL.md +13 -20
  8. package/.claude/skills/workflow-commands/SKILL.md +10 -10
  9. package/.claude/skills/workflow-commands/background-commands.md +4 -4
  10. package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
  11. package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
  12. package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
  13. package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
  14. package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
  15. package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
  16. package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
  17. package/.claude/skills/workflow-commands/backlogrun.md +52 -61
  18. package/.claude/skills/workflow-commands/chain-rule.md +36 -40
  19. package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
  20. package/.claude/skills/workflow-commands/followup.md +19 -20
  21. package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
  22. package/.claude/skills/workflow-commands/fullrun.md +10 -10
  23. package/.claude/skills/workflow-commands/halfrun.md +9 -8
  24. package/.claude/skills/workflow-commands/into-target.md +12 -18
  25. package/.claude/skills/workflow-commands/issue-comments.md +11 -26
  26. package/.claude/skills/workflow-commands/kickoff.md +26 -16
  27. package/.claude/skills/workflow-commands/latest-gate.md +17 -28
  28. package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
  29. package/.claude/skills/workflow-commands/observation-filing.md +37 -28
  30. package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
  31. package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
  32. package/.claude/skills/workflow-commands/prerequisite.md +23 -15
  33. package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
  34. package/.claude/skills/workflow-commands/prrun.md +3 -3
  35. package/.claude/skills/workflow-commands/retrospective.md +13 -18
  36. package/.claude/skills/workflow-commands/split-assessment.md +6 -4
  37. package/.claude/skills/workflow-commands/target-repository.md +25 -28
  38. package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
  39. package/.gitattributes +2 -1
  40. package/.github/workflows/ci.yml +14 -0
  41. package/.vscode/tasks.json +14 -0
  42. package/CLAUDE.md +10 -61
  43. package/README.md +23 -66
  44. package/SECURITY.md +1 -1
  45. package/dist/CLAUDE.md +10 -61
  46. package/dist/commands/document-section-cli.js +43 -11
  47. package/dist/config-merge/index.js +11 -2
  48. package/dist/hooks/audit-provision.js +2 -2
  49. package/dist/hooks/batch-guard.js +7 -7
  50. package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-7UBFU3CL.js} +18 -20
  51. package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-7WKYHEGU.js} +8 -44
  52. package/dist/hooks/{chunk-4TZVB44A.js → chunk-AKGCP4LX.js} +285 -363
  53. package/dist/hooks/{chunk-QVSWU24O.js → chunk-BZMPVFDY.js} +7 -5
  54. package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
  55. package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
  56. package/dist/hooks/{chunk-XZYKEM6J.js → chunk-JCRDBQXB.js} +13 -11
  57. package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-JGW24KKM.js} +4 -4
  58. package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
  59. package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
  60. package/dist/hooks/{chunk-WK2XSHSI.js → chunk-SLSFIWTX.js} +550 -875
  61. package/dist/hooks/chunk-UTHMB4O2.js +1590 -0
  62. package/dist/hooks/{chunk-KRBERBBI.js → chunk-V4TKZHER.js} +4 -4
  63. package/dist/hooks/chunk-YLBBSSTF.js +3705 -0
  64. package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
  65. package/dist/hooks/codex-hook-adapter.js +26 -21
  66. package/dist/hooks/duplicate-read-guard.js +8 -8
  67. package/dist/hooks/format-edited.js +4 -4
  68. package/dist/hooks/inputs.json +195 -181
  69. package/dist/hooks/investigation-guard.js +8 -8
  70. package/dist/hooks/pretool-guard.js +15 -15
  71. package/dist/hooks/session-lang.js +406 -8
  72. package/dist/hooks/stop-guard.js +122 -187
  73. package/dist/josh.js +282 -95
  74. package/dist/version/index.js +15 -13
  75. package/eslint/base.js +43 -5
  76. package/eslint/rules/english-only-prose.js +3 -3
  77. package/eslint/rules/import.js +12 -0
  78. package/eslint/rules/namespace-object-export.js +2 -2
  79. package/package.json +17 -11
  80. package/pnpm-workspace.yaml +2 -4
  81. package/prompts/coding-standards.md +14 -48
  82. package/prompts/collaboration-workflow/file-edits.md +1 -1
  83. package/prompts/collaboration-workflow/issue-citation.md +1 -1
  84. package/prompts/collaboration-workflow/issue-template.md +3 -10
  85. package/prompts/collaboration-workflow/operating-rules.md +7 -8
  86. package/prompts/collaboration-workflow/output-bounds.md +1 -1
  87. package/prompts/collaboration-workflow/overview.md +1 -1
  88. package/prompts/collaboration-workflow/plan-comment.md +2 -1
  89. package/prompts/collaboration-workflow/principles.md +21 -3
  90. package/prompts/collaboration-workflow/report-format.md +16 -29
  91. package/prompts/collaboration-workflow/residency.md +1 -1
  92. package/prompts/collaboration-workflow/rule-delivery.md +7 -95
  93. package/prompts/collaboration-workflow/shell-body.md +3 -23
  94. package/prompts/collaboration-workflow/turn-batching.md +4 -13
  95. package/prompts/collaboration-workflow/wip-cap.md +5 -11
  96. package/prompts/refactoring.md +1 -1
  97. package/prompts/review-rubric.md +3 -22
  98. package/prompts/review.md +15 -38
  99. package/prompts/testing-guide.md +2 -4
  100. package/scripts/adopt/adopt-logic.ts +5 -5
  101. package/scripts/adopt/adopt-toolkits.ts +4 -5
  102. package/scripts/adopt/adopt.ts +2 -3
  103. package/scripts/agent/agent-argv.ts +7 -7
  104. package/scripts/agent/agent-diagnostics.ts +2 -2
  105. package/scripts/agent/agent-exit-record.ts +1 -1
  106. package/scripts/agent/agent-headless.ts +1 -1
  107. package/scripts/agent/agent-launch-environment.ts +6 -1
  108. package/scripts/agent/agent-role-profile.ts +49 -22
  109. package/scripts/agent/agent-session-role.ts +32 -0
  110. package/scripts/agent/api-outage.ts +1 -1
  111. package/scripts/agent/claude-agent-argv.ts +4 -4
  112. package/scripts/agent/claude-result-event.ts +4 -4
  113. package/scripts/agent/codex-hooks.ts +2 -2
  114. package/scripts/agent/interactive-ask.ts +3 -6
  115. package/scripts/auto-ok/auto-ok-cli.ts +46 -60
  116. package/scripts/backlog/backlog-arrival-added.ts +34 -0
  117. package/scripts/backlog/backlog-arrival.ts +54 -17
  118. package/scripts/backlog/backlog-budget-cli.ts +34 -6
  119. package/scripts/backlog/backlog-budget.ts +17 -24
  120. package/scripts/backlog/backlog-defect-priority.ts +1 -1
  121. package/scripts/backlog/backlog-drive-args.ts +5 -4
  122. package/scripts/backlog/backlog-drive-cli.ts +14 -10
  123. package/scripts/backlog/backlog-drive-epic.ts +85 -0
  124. package/scripts/backlog/backlog-drive-launch.ts +1 -1
  125. package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
  126. package/scripts/backlog/backlog-drive-named.ts +39 -9
  127. package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
  128. package/scripts/backlog/backlog-drive-restore.ts +1 -1
  129. package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
  130. package/scripts/backlog/backlog-drive.ts +43 -28
  131. package/scripts/backlog/backlog-idle.ts +88 -0
  132. package/scripts/backlog/backlog-named.ts +11 -15
  133. package/scripts/backlog/backlog-next.ts +26 -30
  134. package/scripts/backlog/backlog-offer-cli.ts +28 -23
  135. package/scripts/backlog/backlog-offer.ts +7 -7
  136. package/scripts/backlog/backlog-overlap.ts +178 -0
  137. package/scripts/backlog/backlog-plan-cli.ts +14 -90
  138. package/scripts/backlog/backlog-plan-read.ts +111 -0
  139. package/scripts/backlog/backlog-plan.ts +11 -10
  140. package/scripts/backlog/backlog-pool.ts +13 -14
  141. package/scripts/backlog/backlog-rank.ts +11 -11
  142. package/scripts/backlog/backlog-ready.ts +15 -10
  143. package/scripts/backlog/backlog-scope.ts +14 -15
  144. package/scripts/backlog/backlog-stalled-cli.ts +2 -2
  145. package/scripts/backlog/backlog-stalled-detect.ts +4 -4
  146. package/scripts/backlog/backlog-stalled.ts +5 -6
  147. package/scripts/backlog/backlog-waves.ts +4 -4
  148. package/scripts/backlog/backlogrun-args.ts +74 -0
  149. package/scripts/backlog/backlogrun-cli.ts +113 -0
  150. package/scripts/backlog/backlogrun-launch.ts +178 -0
  151. package/scripts/behavior/behavior-assertion.ts +6 -8
  152. package/scripts/behavior/behavior-cli.ts +1 -1
  153. package/scripts/behavior/behavior-rules.ts +3 -3
  154. package/scripts/build/build-claude-md.ts +4 -4
  155. package/scripts/build/build-codex-hooks.ts +2 -2
  156. package/scripts/build/build-commands.ts +1 -1
  157. package/scripts/build/build-hooks.ts +5 -5
  158. package/scripts/build/build.ts +1 -1
  159. package/scripts/build/hook-bundle-stamp.ts +109 -7
  160. package/scripts/build/local-bin.ts +2 -2
  161. package/scripts/cases/cases-cli.ts +1 -1
  162. package/scripts/cases/cases-logic.ts +2 -2
  163. package/scripts/ci/composite-actions.ts +1 -2
  164. package/scripts/ci/pr-classification.ts +2 -2
  165. package/scripts/claude/workflow-destination.ts +1 -1
  166. package/scripts/clone/clone-aggregate.ts +1 -1
  167. package/scripts/clone/clone-fingerprint.ts +1 -1
  168. package/scripts/clone/clone-scan-cli.ts +1 -1
  169. package/scripts/clone/clone-scan.ts +1 -1
  170. package/scripts/config-merge/index.ts +1 -1
  171. package/scripts/config-merge/json-format.ts +1 -3
  172. package/scripts/config-merge/patch-json-array.ts +90 -0
  173. package/scripts/config-merge/patch-json-key.ts +6 -3
  174. package/scripts/config-merge/patch-json-list.ts +1 -1
  175. package/scripts/cost-runtime/codex-usage.ts +1 -1
  176. package/scripts/cost-runtime/context-cut-payback.ts +4 -5
  177. package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
  178. package/scripts/cost-runtime/cost-attribute.ts +3 -3
  179. package/scripts/cost-runtime/cost-blocks.ts +3 -4
  180. package/scripts/cost-runtime/cost-cli.ts +14 -11
  181. package/scripts/cost-runtime/cost-corpus.ts +11 -11
  182. package/scripts/cost-runtime/cost-pricing.ts +4 -4
  183. package/scripts/cost-runtime/cost-tokens.ts +1 -2
  184. package/scripts/cost-runtime/cost-transcript.ts +29 -29
  185. package/scripts/cost-runtime/cost-usage.ts +6 -7
  186. package/scripts/cost-runtime/cost-verdict.ts +10 -11
  187. package/scripts/cost-runtime/own-session.ts +1 -1
  188. package/scripts/cost-runtime/transcript-cwd.ts +2 -2
  189. package/scripts/delegation/delegation-cli.ts +4 -4
  190. package/scripts/delegation/delegation-policy.ts +13 -15
  191. package/scripts/delegation/duplicate-read-guard.ts +9 -10
  192. package/scripts/delegation/fanout-cli.ts +1 -1
  193. package/scripts/delegation/fanout.ts +1 -1
  194. package/scripts/delegation/investigation-guard.ts +18 -22
  195. package/scripts/delegation/investigation-reads.ts +48 -238
  196. package/scripts/discovery/repo-discovery.ts +1 -1
  197. package/scripts/discovery/repo-map-logic.ts +1 -2
  198. package/scripts/discovery/repo-origin.ts +3 -3
  199. package/scripts/discovery/repo-party-cli.ts +2 -2
  200. package/scripts/discovery/repo-party.ts +2 -2
  201. package/scripts/doctor/doctor-consumer.ts +1 -1
  202. package/scripts/doctor/doctor-io.ts +6 -7
  203. package/scripts/doctor/doctor-logic.ts +1 -1
  204. package/scripts/doctor/doctor-ports.ts +1 -1
  205. package/scripts/doctor/doctor.ts +8 -9
  206. package/scripts/document/backlogrun-parent-read-set.ts +5 -6
  207. package/scripts/document/bash-output-cap.ts +5 -7
  208. package/scripts/document/capped-print-part.ts +1 -1
  209. package/scripts/document/capped-print.ts +1 -1
  210. package/scripts/document/document-byte-budget.ts +33 -64
  211. package/scripts/document/document-byte-check.ts +4 -4
  212. package/scripts/document/document-reachability.ts +7 -8
  213. package/scripts/document/document-read-cli.ts +2 -2
  214. package/scripts/document/document-scan.ts +30 -5
  215. package/scripts/document/document-section-cli.ts +6 -8
  216. package/scripts/document/document-section.ts +8 -12
  217. package/scripts/document/edit-files-cli.ts +3 -4
  218. package/scripts/document/entry-read-budget.ts +8 -70
  219. package/scripts/document/entry-read-set.ts +51 -34
  220. package/scripts/document/lane-child-read-set.ts +9 -9
  221. package/scripts/document/read-files-cli.ts +1 -2
  222. package/scripts/document/read-set-cli.ts +16 -19
  223. package/scripts/document/read-set-cost.ts +4 -4
  224. package/scripts/document/read-set-point-of-use.ts +28 -38
  225. package/scripts/document/read-set-pricing.ts +1 -1
  226. package/scripts/document/read-set-trim.ts +3 -3
  227. package/scripts/document/resident-budget.ts +8 -10
  228. package/scripts/epic/epic-add-body.ts +15 -18
  229. package/scripts/epic/epic-add-plan.ts +26 -28
  230. package/scripts/epic/epic-add.ts +32 -25
  231. package/scripts/epic/epic-audit-checks.ts +27 -37
  232. package/scripts/epic/epic-audit-cli.ts +21 -22
  233. package/scripts/epic/epic-audit-orphans.ts +16 -17
  234. package/scripts/epic/epic-audit-rationale.ts +10 -15
  235. package/scripts/epic/epic-audit-report.ts +2 -5
  236. package/scripts/epic/epic-audit.ts +18 -14
  237. package/scripts/epic/epic-body.ts +10 -10
  238. package/scripts/epic/epic-bundle-cli.ts +36 -34
  239. package/scripts/epic/epic-bundle-evidence.ts +5 -5
  240. package/scripts/epic/epic-bundle-gaps.ts +6 -9
  241. package/scripts/epic/epic-bundle-poll.ts +1 -1
  242. package/scripts/epic/epic-bundle-referenced.ts +11 -14
  243. package/scripts/epic/epic-bundle.ts +19 -20
  244. package/scripts/epic/epic-busy.ts +44 -21
  245. package/scripts/epic/epic-candidate-confirm.ts +15 -18
  246. package/scripts/epic/epic-chains.ts +18 -23
  247. package/scripts/epic/epic-classify.ts +11 -12
  248. package/scripts/epic/epic-cli-argv.ts +5 -6
  249. package/scripts/epic/epic-cli-remove.ts +9 -4
  250. package/scripts/epic/epic-cli.ts +38 -26
  251. package/scripts/epic/epic-close-comment.ts +14 -15
  252. package/scripts/epic/epic-close.ts +25 -29
  253. package/scripts/epic/epic-cross-repo.ts +18 -21
  254. package/scripts/epic/epic-decision.ts +14 -18
  255. package/scripts/epic/epic-fetch.ts +25 -31
  256. package/scripts/epic/epic-graph.ts +15 -17
  257. package/scripts/epic/epic-index.ts +14 -16
  258. package/scripts/epic/epic-issue.ts +9 -11
  259. package/scripts/epic/epic-label-age.ts +74 -0
  260. package/scripts/epic/epic-lane-offer.ts +35 -24
  261. package/scripts/epic/epic-nested.ts +1 -1
  262. package/scripts/epic/epic-next-read.ts +8 -8
  263. package/scripts/epic/epic-next-views.ts +12 -12
  264. package/scripts/epic/epic-next.ts +29 -33
  265. package/scripts/epic/epic-outside-blocker.ts +11 -10
  266. package/scripts/epic/epic-parse.ts +22 -24
  267. package/scripts/epic/epic-promote.ts +3 -2
  268. package/scripts/epic/epic-rank.ts +1 -1
  269. package/scripts/epic/epic-read.ts +10 -8
  270. package/scripts/epic/epic-reconcile.ts +8 -6
  271. package/scripts/epic/epic-reference.ts +5 -4
  272. package/scripts/epic/epic-relation-recheck.ts +10 -11
  273. package/scripts/epic/epic-relations.ts +9 -8
  274. package/scripts/epic/epic-remove-plan.ts +4 -5
  275. package/scripts/epic/epic-remove.ts +7 -5
  276. package/scripts/epic/epic-report.ts +18 -20
  277. package/scripts/epic/epic-run.ts +6 -5
  278. package/scripts/epic/epic-sections.ts +2 -2
  279. package/scripts/epic/epic-shape.ts +3 -3
  280. package/scripts/epic/epic-solo-stale.ts +3 -2
  281. package/scripts/epic/epic-solo.ts +8 -8
  282. package/scripts/epic/epic-triage.ts +5 -4
  283. package/scripts/epic/epic-validate.ts +8 -7
  284. package/scripts/epic/epic.ts +5 -5
  285. package/scripts/exports/unused-members-cli.ts +1 -1
  286. package/scripts/followup/followup-issue-number.ts +1 -2
  287. package/scripts/followup/git-followup-cleanup.ts +6 -7
  288. package/scripts/followup/git-followup-finish.ts +11 -13
  289. package/scripts/followup/git-followup-flush.ts +11 -7
  290. package/scripts/followup/git-followup-issue-close.ts +16 -13
  291. package/scripts/followup/git-followup-label.ts +9 -6
  292. package/scripts/followup/git-followup-merged.ts +1 -1
  293. package/scripts/followup/git-followup-pending.ts +7 -9
  294. package/scripts/followup/git-followup-stages.ts +28 -17
  295. package/scripts/followup/git-followup-workflow.ts +19 -21
  296. package/scripts/followup/git-pr-followup-checks.ts +13 -20
  297. package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
  298. package/scripts/followup/git-pr-followup.ts +18 -17
  299. package/scripts/gate/core-admission.ts +2 -2
  300. package/scripts/gate/core-budget.ts +15 -26
  301. package/scripts/gate/gate-ledger.ts +114 -0
  302. package/scripts/gate/gate-log.ts +7 -9
  303. package/scripts/gate/gate-plan.ts +70 -35
  304. package/scripts/gate/gate-report.ts +14 -15
  305. package/scripts/gate/gate-skip.ts +11 -13
  306. package/scripts/gate/gate-steps.ts +5 -1
  307. package/scripts/gate/gate-tree.ts +3 -4
  308. package/scripts/gate/hook-gate-reuse.ts +9 -9
  309. package/scripts/gate/machine-capacity.ts +168 -30
  310. package/scripts/gate/pre-commit-type-check.ts +4 -4
  311. package/scripts/gate/project-checks.ts +12 -4
  312. package/scripts/gate/scoped-green.ts +11 -18
  313. package/scripts/gate/type-check-command.ts +2 -2
  314. package/scripts/gate/type-check-step.ts +4 -4
  315. package/scripts/gate/verification-gate.ts +53 -51
  316. package/scripts/gh/gh-spawn.ts +2 -2
  317. package/scripts/gh/git-ai-review-scan.ts +3 -2
  318. package/scripts/gh/git-gh-api-path.ts +10 -11
  319. package/scripts/gh/git-gh-exec.ts +43 -48
  320. package/scripts/gh/git-gh-failure.ts +6 -9
  321. package/scripts/gh/git-gh-helpers.ts +1 -1
  322. package/scripts/gh/git-gh-issue-list.ts +15 -19
  323. package/scripts/gh/git-gh-issue-read.ts +43 -60
  324. package/scripts/gh/git-gh-issue-rest.ts +14 -15
  325. package/scripts/gh/git-gh-issue-write.ts +52 -40
  326. package/scripts/gh/git-gh-issue.ts +23 -24
  327. package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
  328. package/scripts/gh/git-gh-pr-read.ts +46 -50
  329. package/scripts/gh/git-gh-pr-rest.ts +23 -26
  330. package/scripts/gh/git-gh-pr-review.ts +2 -2
  331. package/scripts/gh/git-gh-pr-rollup.ts +4 -4
  332. package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
  333. package/scripts/gh/git-gh-pr.ts +16 -16
  334. package/scripts/gh/git-gh-reachability.ts +11 -12
  335. package/scripts/gh/git-gh-repo.ts +2 -3
  336. package/scripts/gh/git-gh-rest-state.ts +1 -1
  337. package/scripts/gh/git-pr-ai-review.ts +6 -5
  338. package/scripts/gh/git-pr-checks-eval.ts +28 -30
  339. package/scripts/gh/git-pr-checks-parse.ts +14 -16
  340. package/scripts/gh/git-pr-checks-watch.ts +17 -17
  341. package/scripts/gh/git-pr-checks.ts +20 -23
  342. package/scripts/gh/git-pr-coderabbit.ts +8 -6
  343. package/scripts/gh/git-pr-confirmation.ts +5 -5
  344. package/scripts/gh/git-pr-managed-config.ts +7 -9
  345. package/scripts/gh/git-pr-messages.ts +1 -1
  346. package/scripts/gh/git-pr.ts +15 -16
  347. package/scripts/gh/github-issue-url.ts +8 -9
  348. package/scripts/git/base-tree.ts +66 -0
  349. package/scripts/git/change-base.ts +42 -2
  350. package/scripts/git/changed-file-scope.ts +5 -5
  351. package/scripts/git/changed-paths.ts +1 -2
  352. package/scripts/git/constants.ts +2 -2
  353. package/scripts/git/git-branch.ts +1 -1
  354. package/scripts/git/git-closes-keyword.ts +3 -3
  355. package/scripts/git/git-command.ts +53 -41
  356. package/scripts/git/git-common-directory.ts +3 -3
  357. package/scripts/git/git-diff-reads.ts +14 -15
  358. package/scripts/git/git-error.ts +1 -1
  359. package/scripts/git/git-execa-error.ts +1 -2
  360. package/scripts/git/git-issue.ts +10 -8
  361. package/scripts/git/git-location-environment.ts +3 -4
  362. package/scripts/git/git-ls-remote.ts +6 -8
  363. package/scripts/git/git-pre-push-hook.ts +11 -10
  364. package/scripts/git/git-preflight.ts +5 -5
  365. package/scripts/git/git-push-transport.ts +2 -2
  366. package/scripts/git/git-remote-branch.ts +1 -2
  367. package/scripts/git/git-schemas.ts +16 -23
  368. package/scripts/git/git-spawn-sync.ts +1 -1
  369. package/scripts/git/git-spawn.ts +37 -14
  370. package/scripts/git/git-ssh-keepalive.ts +12 -5
  371. package/scripts/git/git-staging.ts +7 -8
  372. package/scripts/git/git-workflow.ts +1 -1
  373. package/scripts/git/git-worktree.ts +35 -27
  374. package/scripts/git/gone-branch.ts +2 -2
  375. package/scripts/git/listing-cutoff.ts +1 -2
  376. package/scripts/git/lockfile-sync.ts +65 -0
  377. package/scripts/git/main-merge-guard.ts +1 -2
  378. package/scripts/git/main-merge.ts +7 -7
  379. package/scripts/git/main-sync.ts +23 -8
  380. package/scripts/git/parse-json-array.ts +18 -23
  381. package/scripts/git/repository-lock.ts +34 -2
  382. package/scripts/git/stash/git-stash.ts +4 -5
  383. package/scripts/git/stash/stash-orphans.ts +5 -3
  384. package/scripts/git/stash/stash-pop-args.ts +1 -1
  385. package/scripts/git/stash/stash-pop-cli.ts +3 -3
  386. package/scripts/git/stash/stash-sweep-lock.ts +2 -2
  387. package/scripts/hooks/batch-guard.ts +11 -13
  388. package/scripts/hooks/check-commit-message.ts +12 -9
  389. package/scripts/hooks/codex-hook-adapter.ts +16 -10
  390. package/scripts/hooks/edited-cspell.ts +3 -4
  391. package/scripts/hooks/format-edited-cli.ts +1 -1
  392. package/scripts/hooks/format-edited-file.ts +11 -17
  393. package/scripts/hooks/format-rewrite-notice.ts +19 -17
  394. package/scripts/hooks/pre-push-unit.ts +10 -14
  395. package/scripts/hooks/pretool-guard-cli.ts +4 -4
  396. package/scripts/hooks/pretool-guard.ts +93 -18
  397. package/scripts/hooks/reserved-run.ts +2 -2
  398. package/scripts/hooks/step-zero-notice.ts +1 -1
  399. package/scripts/hooks/stop-guard.ts +21 -10
  400. package/scripts/init/basic-path-migration.ts +2 -2
  401. package/scripts/init/claude-kit-only-settings.ts +2 -2
  402. package/scripts/init/claude-plugin-config.ts +2 -2
  403. package/scripts/init/distributed-paths.ts +4 -4
  404. package/scripts/init/hook-command-rewrite.ts +3 -3
  405. package/scripts/init/hook-launch.ts +5 -5
  406. package/scripts/init/init-actions.ts +13 -0
  407. package/scripts/init/init-ai-copy.ts +11 -11
  408. package/scripts/init/init-bootstrap.ts +3 -3
  409. package/scripts/init/init-copy-content.ts +4 -4
  410. package/scripts/init/init-logic-json-merge.ts +7 -9
  411. package/scripts/init/init-logic-migrate.ts +1 -1
  412. package/scripts/init/init-logic-templates.ts +1 -1
  413. package/scripts/init/init-logic-workspace.ts +4 -4
  414. package/scripts/init/init-logic-yaml-merge.ts +2 -2
  415. package/scripts/init/init-logic.ts +19 -22
  416. package/scripts/init/init.ts +7 -7
  417. package/scripts/init/kit-base-preset.ts +1 -1
  418. package/scripts/init/kit-setup-state.ts +1 -1
  419. package/scripts/init/kit-written-paths.ts +1 -2
  420. package/scripts/init/package-manager-pin.ts +1 -1
  421. package/scripts/init/project-profile-cli.ts +1 -1
  422. package/scripts/init/project-profile.ts +3 -3
  423. package/scripts/init/session-language-environment.ts +1 -1
  424. package/scripts/init/start-exec.ts +3 -4
  425. package/scripts/init/start-plan.ts +2 -2
  426. package/scripts/init/start-setup-pr.ts +3 -2
  427. package/scripts/init/start-steps.ts +2 -2
  428. package/scripts/init/tsconfig-preset-migration.ts +1 -1
  429. package/scripts/init/vscode-tasks.ts +62 -0
  430. package/scripts/issue/baseline-measure.ts +2 -2
  431. package/scripts/issue/behavior-change-lint.ts +2 -2
  432. package/scripts/issue/defect-rate-cli.ts +6 -7
  433. package/scripts/issue/defect-rate.ts +37 -27
  434. package/scripts/issue/git-next-issues.ts +9 -8
  435. package/scripts/issue/issue-auto-ok.ts +24 -11
  436. package/scripts/issue/issue-backlinks-cli.ts +5 -5
  437. package/scripts/issue/issue-backlinks.ts +6 -6
  438. package/scripts/issue/issue-cite-cli.ts +20 -18
  439. package/scripts/issue/issue-cite.ts +18 -8
  440. package/scripts/issue/issue-closing-pr.ts +4 -4
  441. package/scripts/issue/issue-comment-cli.ts +6 -4
  442. package/scripts/issue/issue-file-cli.ts +52 -15
  443. package/scripts/issue/issue-file-fold.ts +155 -0
  444. package/scripts/issue/issue-file.ts +9 -6
  445. package/scripts/issue/issue-fold-cli.ts +14 -9
  446. package/scripts/issue/issue-fold.ts +23 -8
  447. package/scripts/issue/issue-labels.ts +34 -38
  448. package/scripts/issue/issue-lint-cli.ts +2 -2
  449. package/scripts/issue/issue-lint.ts +1 -1
  450. package/scripts/issue/issue-merged.ts +10 -4
  451. package/scripts/issue/issue-number-shape.ts +27 -0
  452. package/scripts/issue/issue-rank.ts +1 -1
  453. package/scripts/issue/issue-read-cli.ts +4 -5
  454. package/scripts/issue/issue-read.ts +4 -5
  455. package/scripts/issue/issue-reference.ts +5 -5
  456. package/scripts/issue/issue-release-cli.ts +17 -7
  457. package/scripts/issue/issue-release.ts +3 -3
  458. package/scripts/issue/issue-report-failures.ts +7 -4
  459. package/scripts/issue/issue-scout-cli.ts +11 -11
  460. package/scripts/issue/issue-scout-closed.ts +4 -4
  461. package/scripts/issue/issue-scout.ts +4 -5
  462. package/scripts/issue/issue-state-cli.ts +17 -10
  463. package/scripts/issue/issue-state.ts +12 -13
  464. package/scripts/issue/issue-wip.ts +7 -7
  465. package/scripts/issue/markdown-section.ts +3 -3
  466. package/scripts/issue/measure-rerun-cli.ts +10 -9
  467. package/scripts/issue/reproduction-measure.ts +3 -3
  468. package/scripts/issue/session-cite.ts +56 -0
  469. package/scripts/josh/agent-session-environment.ts +10 -8
  470. package/scripts/josh/cli-body.ts +2 -2
  471. package/scripts/josh/command-suggest.ts +1 -1
  472. package/scripts/josh/file-map-stamp.ts +20 -23
  473. package/scripts/josh/hook-decision.ts +24 -28
  474. package/scripts/josh/josh-command-map.ts +4 -1
  475. package/scripts/josh/josh-command-types.ts +30 -35
  476. package/scripts/josh/josh-commands-ai.ts +6 -6
  477. package/scripts/josh/josh-commands-backlog.ts +15 -3
  478. package/scripts/josh/josh-commands-clone.ts +1 -1
  479. package/scripts/josh/josh-commands-development.ts +25 -4
  480. package/scripts/josh/josh-commands-document.ts +3 -3
  481. package/scripts/josh/josh-commands-guard.ts +3 -3
  482. package/scripts/josh/josh-commands-issue.ts +4 -5
  483. package/scripts/josh/josh-commands-lane.ts +14 -4
  484. package/scripts/josh/josh-commands-lint.ts +1 -1
  485. package/scripts/josh/josh-commands-run.ts +21 -7
  486. package/scripts/josh/josh-commands-split.ts +1 -2
  487. package/scripts/josh/josh-commands-versioning.ts +5 -5
  488. package/scripts/josh/josh-commands-workflow.ts +30 -22
  489. package/scripts/josh/josh-environment-file.ts +1 -1
  490. package/scripts/josh/josh-in-process.ts +3 -3
  491. package/scripts/josh/josh-logic.ts +6 -7
  492. package/scripts/josh/josh-run.ts +3 -3
  493. package/scripts/josh/josh-verdict.ts +9 -12
  494. package/scripts/josh/josh.ts +3 -3
  495. package/scripts/josh/kit-only.ts +2 -2
  496. package/scripts/josh/path-decision.ts +3 -3
  497. package/scripts/josh/platform-temporary.ts +7 -5
  498. package/scripts/josh/process-identity.ts +24 -6
  499. package/scripts/josh/process-owner.ts +4 -4
  500. package/scripts/josh/session-language-cli.ts +53 -11
  501. package/scripts/josh/session-language.ts +1 -1
  502. package/scripts/josh/stamp-file.ts +48 -29
  503. package/scripts/josh/stamp-record.ts +57 -0
  504. package/scripts/lane/lane-await.ts +35 -11
  505. package/scripts/lane/lane-cache.ts +6 -6
  506. package/scripts/lane/lane-capacity.ts +32 -17
  507. package/scripts/lane/lane-child-invocation.ts +17 -15
  508. package/scripts/lane/lane-child-marker.ts +12 -12
  509. package/scripts/lane/lane-cli.ts +12 -13
  510. package/scripts/lane/lane-close.ts +6 -6
  511. package/scripts/lane/lane-dispatch.ts +61 -72
  512. package/scripts/lane/lane-environment.ts +5 -5
  513. package/scripts/lane/lane-guard-policy.ts +7 -21
  514. package/scripts/lane/lane-handoff.ts +2 -2
  515. package/scripts/lane/lane-install.ts +9 -10
  516. package/scripts/lane/lane-launch-cli.ts +13 -8
  517. package/scripts/lane/lane-ledger.ts +73 -11
  518. package/scripts/lane/lane-leftover.ts +2 -2
  519. package/scripts/lane/lane-limit-cli.ts +160 -0
  520. package/scripts/lane/lane-limit-override.ts +74 -0
  521. package/scripts/lane/lane-load.ts +19 -68
  522. package/scripts/lane/lane-measure-cli.ts +15 -25
  523. package/scripts/lane/lane-occupancy.ts +6 -4
  524. package/scripts/lane/lane-open.ts +20 -19
  525. package/scripts/lane/lane-output.ts +4 -3
  526. package/scripts/lane/lane-paths.ts +12 -11
  527. package/scripts/lane/lane-phase.ts +33 -0
  528. package/scripts/lane/lane-reap.ts +2 -2
  529. package/scripts/lane/lane-registry.ts +16 -15
  530. package/scripts/lane/lane-relaunch.ts +9 -9
  531. package/scripts/lane/lane-report.ts +5 -4
  532. package/scripts/lane/lane-resume.ts +2 -2
  533. package/scripts/lane/lane-sampler.ts +55 -0
  534. package/scripts/lane/lane-seed.ts +7 -7
  535. package/scripts/lane/lane-stage-stats.ts +135 -0
  536. package/scripts/lane/lane-start-point.ts +8 -11
  537. package/scripts/lane/lane-stats.ts +60 -15
  538. package/scripts/lane/lane-stray.ts +1 -1
  539. package/scripts/lane/lane-vacant.ts +1 -1
  540. package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
  541. package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
  542. package/scripts/lane/openai-review-broker.ts +2 -4
  543. package/scripts/lib/ancestor-directories.ts +1 -1
  544. package/scripts/lib/bounded-pool.ts +2 -2
  545. package/scripts/lib/buffered-process.ts +4 -6
  546. package/scripts/lib/caddy-logs.sh +0 -0
  547. package/scripts/lib/cli-flags.ts +39 -6
  548. package/scripts/lib/error-message.ts +1 -1
  549. package/scripts/lib/json-value.ts +17 -3
  550. package/scripts/lib/poll.ts +1 -1
  551. package/scripts/lib/status-icons.ts +3 -3
  552. package/scripts/lib/timed-fetch.ts +1 -1
  553. package/scripts/lib/timeouts.ts +1 -1
  554. package/scripts/lines/bytes-command.ts +3 -4
  555. package/scripts/lines/effective-limit.ts +25 -12
  556. package/scripts/lines/line-budget.ts +47 -55
  557. package/scripts/lines/line-targets.ts +6 -2
  558. package/scripts/lines/lines-command.ts +3 -3
  559. package/scripts/lint/cross-file-recheck.ts +155 -0
  560. package/scripts/lint/cspell-cached.ts +1 -1
  561. package/scripts/lint/format.ts +1 -2
  562. package/scripts/lint/lint-parallel.ts +35 -19
  563. package/scripts/lint/lint-related-scope.ts +25 -15
  564. package/scripts/lint/lint-related.ts +6 -7
  565. package/scripts/managed-marker/index.ts +1 -1
  566. package/scripts/managed-marker/managed-marker-logic.ts +1 -2
  567. package/scripts/notify/git-notify.ts +9 -7
  568. package/scripts/notify/telegram-notify.ts +53 -37
  569. package/scripts/notify/telegram-test-logic.ts +3 -3
  570. package/scripts/notify/telegram-test.ts +45 -30
  571. package/scripts/observations/observation-ledger-home.ts +14 -8
  572. package/scripts/observations/observation-ledger-line.ts +3 -2
  573. package/scripts/observations/observation-ledger-migrate.ts +3 -4
  574. package/scripts/observations/observation-ledger-prepare.ts +4 -4
  575. package/scripts/observations/observation-ledger.ts +14 -15
  576. package/scripts/observations/observation-record-cli.ts +83 -0
  577. package/scripts/observations/observation-record.ts +91 -0
  578. package/scripts/observations/observations-flush-cli.ts +1 -1
  579. package/scripts/observations/observations-flush-landing.ts +7 -6
  580. package/scripts/observations/observations-flush.ts +26 -27
  581. package/scripts/overrides/overrides-check.ts +18 -8
  582. package/scripts/package/package-scout-cli.ts +1 -1
  583. package/scripts/package/package-scout-format.ts +2 -2
  584. package/scripts/package/package-scout.ts +1 -1
  585. package/scripts/propagate/propagate-git-failure.ts +1 -1
  586. package/scripts/propagate/propagate-git.ts +7 -7
  587. package/scripts/propagate/propagate-plan.ts +2 -2
  588. package/scripts/propagate/propagate-publish.ts +2 -3
  589. package/scripts/propagate/propagate-run.ts +5 -7
  590. package/scripts/propagate/propagate-select.ts +1 -1
  591. package/scripts/propagate/propagate-steps.ts +19 -20
  592. package/scripts/propagate/propagate-targets.ts +6 -10
  593. package/scripts/propagate/propagate.ts +5 -5
  594. package/scripts/refactor/import-graph.ts +1 -1
  595. package/scripts/refactor/refactor-lint.ts +4 -10
  596. package/scripts/refactor/refactor-scan-cli.ts +1 -1
  597. package/scripts/refactor/refactor-scan.ts +2 -2
  598. package/scripts/refactor/refactor-targets.ts +1 -1
  599. package/scripts/release/github-release-cli.ts +25 -3
  600. package/scripts/release/github-release-runs.ts +1 -1
  601. package/scripts/release/release-cli.ts +21 -4
  602. package/scripts/release/release-history.ts +6 -10
  603. package/scripts/release/release-plan.ts +3 -3
  604. package/scripts/release/release-progress.ts +3 -4
  605. package/scripts/release/release-publish.ts +8 -9
  606. package/scripts/release/release-scope-cli.ts +8 -10
  607. package/scripts/release/release-tag.ts +6 -8
  608. package/scripts/release/release-worktree.ts +5 -5
  609. package/scripts/repo/auto-merge-setting-logic.ts +7 -9
  610. package/scripts/repo/auto-merge-setting.ts +1 -1
  611. package/scripts/repo/repo-setting.ts +4 -4
  612. package/scripts/repo/repository-labels.ts +1 -1
  613. package/scripts/repo/required-checks-logic.ts +3 -3
  614. package/scripts/repo/required-checks-report.ts +1 -1
  615. package/scripts/repo/ruleset-check-cli.ts +1 -1
  616. package/scripts/repo/ruleset-check.ts +1 -1
  617. package/scripts/report/report-format-reference.ts +26 -0
  618. package/scripts/report/report-lint-cli.ts +2 -2
  619. package/scripts/report/report-lint.ts +16 -2
  620. package/scripts/review/disposition-cli.ts +2 -2
  621. package/scripts/review/disposition-logic.ts +1 -1
  622. package/scripts/review/live-evidence.ts +9 -6
  623. package/scripts/review/review-attest-cli.ts +1 -2
  624. package/scripts/review/review-attest.ts +3 -3
  625. package/scripts/review/review-brief-cli.ts +19 -20
  626. package/scripts/review/review-brief.ts +29 -32
  627. package/scripts/review/review-checkout.ts +2 -2
  628. package/scripts/review/review-diff-parts.ts +3 -5
  629. package/scripts/review/review-diff-write.ts +1 -1
  630. package/scripts/review/review-finding-ledger.ts +7 -4
  631. package/scripts/review/review-findings-cli.ts +2 -2
  632. package/scripts/review/review-level.ts +4 -7
  633. package/scripts/review/review-record-cli.ts +73 -16
  634. package/scripts/review/review-record.ts +5 -4
  635. package/scripts/review/review-round2-cli.ts +2 -3
  636. package/scripts/review/review-round2.ts +13 -21
  637. package/scripts/review/review-stamps.ts +9 -71
  638. package/scripts/review/review-tree.ts +4 -5
  639. package/scripts/rules/bash-triggers.ts +4 -4
  640. package/scripts/rules/decision-oracle-batch.ts +6 -7
  641. package/scripts/rules/decision-oracle-stage.ts +1 -1
  642. package/scripts/rules/decision-oracle-tokens.ts +1 -2
  643. package/scripts/rules/decision-oracle.ts +2 -2
  644. package/scripts/rules/delivered-rules.ts +61 -406
  645. package/scripts/rules/destructive-command.ts +2 -2
  646. package/scripts/rules/direct-filing.ts +4 -4
  647. package/scripts/rules/direct-pr-create.ts +2 -2
  648. package/scripts/rules/early-heartbeat.ts +15 -19
  649. package/scripts/rules/file-body.ts +5 -6
  650. package/scripts/rules/filing-cap.ts +6 -7
  651. package/scripts/rules/filing-offer.ts +1 -1
  652. package/scripts/rules/firing-point.ts +6 -6
  653. package/scripts/rules/gh-api.ts +2 -2
  654. package/scripts/rules/git-argv.ts +3 -3
  655. package/scripts/rules/git-force.ts +2 -2
  656. package/scripts/rules/hook-context-line.ts +31 -0
  657. package/scripts/rules/implementation-cut-verdict.ts +5 -8
  658. package/scripts/rules/implementation-cut.ts +35 -32
  659. package/scripts/rules/index-guard.ts +2 -2
  660. package/scripts/rules/issue-citation.ts +7 -7
  661. package/scripts/rules/issue-comments.ts +21 -13
  662. package/scripts/rules/josh-git-bare.ts +2 -2
  663. package/scripts/rules/lane-background.ts +14 -16
  664. package/scripts/rules/lane-carry-conflict.ts +41 -5
  665. package/scripts/rules/lane-interactive-ask.ts +6 -9
  666. package/scripts/rules/lane-park.ts +12 -16
  667. package/scripts/rules/lane-split-park.ts +1 -2
  668. package/scripts/rules/lane-switch-main.ts +10 -13
  669. package/scripts/rules/last-prompt.ts +1 -1
  670. package/scripts/rules/oracle-consulted.ts +5 -5
  671. package/scripts/rules/oracle-firing.ts +6 -9
  672. package/scripts/rules/oracle-list-cli.ts +2 -2
  673. package/scripts/rules/permission-guards.ts +2 -2
  674. package/scripts/rules/piped-verification.ts +79 -9
  675. package/scripts/rules/poll-loop.ts +9 -11
  676. package/scripts/rules/pre-gate-cut.ts +33 -30
  677. package/scripts/rules/prior-comment-read.ts +3 -3
  678. package/scripts/rules/protected-files.ts +25 -13
  679. package/scripts/rules/raw-field-body.ts +3 -4
  680. package/scripts/rules/reply-language.ts +1 -1
  681. package/scripts/rules/rule-body-guard.ts +10 -12
  682. package/scripts/rules/rule-guard.ts +1 -1
  683. package/scripts/rules/rule-list.ts +51 -0
  684. package/scripts/rules/rule-registry-rows.ts +282 -0
  685. package/scripts/rules/rule-registry.ts +109 -0
  686. package/scripts/rules/rule-value-cache.ts +2 -2
  687. package/scripts/rules/rule-value-cli.ts +6 -4
  688. package/scripts/rules/rule-value.ts +61 -22
  689. package/scripts/rules/run-tail-rule.ts +11 -15
  690. package/scripts/rules/shell-body-trigger.ts +7 -7
  691. package/scripts/rules/shell-segments.ts +2 -4
  692. package/scripts/rules/stop-rules.ts +54 -41
  693. package/scripts/rules/tail-commands.ts +1 -1
  694. package/scripts/rules/test-declared-commit.ts +2 -2
  695. package/scripts/rules/third-party-write.ts +3 -3
  696. package/scripts/rules/worktree-guard.ts +12 -5
  697. package/scripts/run/add/run-add-cli.ts +165 -0
  698. package/scripts/run/add/run-add.ts +124 -0
  699. package/scripts/run/board/run-board-cli.ts +207 -0
  700. package/scripts/run/board/run-board-closed.ts +95 -0
  701. package/scripts/run/board/run-board-every.ts +60 -0
  702. package/scripts/run/board/run-board-fetch.ts +38 -0
  703. package/scripts/run/board/run-board-fit.ts +219 -0
  704. package/scripts/run/board/run-board-github.ts +162 -0
  705. package/scripts/run/board/run-board-header.ts +275 -0
  706. package/scripts/run/board/run-board-kind.ts +35 -0
  707. package/scripts/run/board/run-board-labels.ts +299 -0
  708. package/scripts/run/board/run-board-layout.ts +222 -0
  709. package/scripts/run/board/run-board-link.ts +31 -0
  710. package/scripts/run/board/run-board-machine.ts +198 -0
  711. package/scripts/run/board/run-board-notes.ts +103 -0
  712. package/scripts/run/board/run-board-phase.ts +136 -0
  713. package/scripts/run/board/run-board-plan.ts +129 -0
  714. package/scripts/run/board/run-board-read.ts +62 -0
  715. package/scripts/run/board/run-board-render-legend.ts +82 -0
  716. package/scripts/run/board/run-board-render-notes.ts +77 -0
  717. package/scripts/run/board/run-board-render-slot.ts +50 -0
  718. package/scripts/run/board/run-board-render.ts +407 -0
  719. package/scripts/run/board/run-board-scope.ts +17 -0
  720. package/scripts/run/board/run-board-screen.ts +43 -0
  721. package/scripts/run/board/run-board-span.ts +66 -0
  722. package/scripts/run/board/run-board-spin.ts +115 -0
  723. package/scripts/run/board/run-board-state.ts +113 -0
  724. package/scripts/run/board/run-board-status.ts +279 -0
  725. package/scripts/run/board/run-board-tick.ts +210 -0
  726. package/scripts/run/board/run-board-track.ts +22 -0
  727. package/scripts/run/board/run-board-usage-read.ts +255 -0
  728. package/scripts/run/board/run-board-usage-rusage.ts +124 -0
  729. package/scripts/run/board/run-board-usage-text.ts +80 -0
  730. package/scripts/run/board/run-board-usage.ts +165 -0
  731. package/scripts/run/carry/run-carry-added.ts +62 -0
  732. package/scripts/run/carry/run-carry-args.ts +25 -22
  733. package/scripts/run/carry/run-carry-change.ts +1 -1
  734. package/scripts/run/carry/run-carry-cli.ts +71 -48
  735. package/scripts/run/carry/run-carry-conversation.ts +6 -7
  736. package/scripts/run/carry/run-carry-ended.ts +85 -0
  737. package/scripts/run/carry/run-carry-reclaim.ts +1 -1
  738. package/scripts/run/carry/run-carry-stash.ts +3 -2
  739. package/scripts/run/carry/run-carry-streak.ts +8 -10
  740. package/scripts/run/carry/run-carry.ts +85 -89
  741. package/scripts/run/cut/run-cut-args.ts +7 -7
  742. package/scripts/run/cut/run-cut-cli.ts +54 -36
  743. package/scripts/run/cut/run-cut-handoff.ts +15 -15
  744. package/scripts/run/cut/run-cut-report.ts +37 -16
  745. package/scripts/run/cut/run-cut.ts +63 -77
  746. package/scripts/run/detached-launch.ts +35 -50
  747. package/scripts/run/entry/run-entry-cli.ts +48 -27
  748. package/scripts/run/entry/run-entry-stop.ts +7 -9
  749. package/scripts/run/entry/run-entry.ts +5 -6
  750. package/scripts/run/event/run-event-cli.ts +5 -6
  751. package/scripts/run/event/run-event-filed.ts +69 -0
  752. package/scripts/run/event/run-event-follow.ts +3 -3
  753. package/scripts/run/event/run-event-plan.ts +38 -0
  754. package/scripts/run/event/run-event-render.ts +9 -4
  755. package/scripts/run/event/run-event-scope.ts +47 -18
  756. package/scripts/run/event/run-event-stream-emit.ts +64 -11
  757. package/scripts/run/event/run-event-stream.ts +171 -46
  758. package/scripts/run/event/run-event-watch.ts +4 -6
  759. package/scripts/run/hold/run-hold-cli.ts +65 -62
  760. package/scripts/run/hold/run-hold.ts +88 -46
  761. package/scripts/run/merge/run-merge-cli.ts +116 -77
  762. package/scripts/run/merge/run-merge-collect.ts +107 -0
  763. package/scripts/run/merge/run-merge-steps.ts +112 -65
  764. package/scripts/run/merge/run-merge-token.ts +30 -0
  765. package/scripts/run/merge/run-merge.ts +31 -22
  766. package/scripts/run/progress/run-progress-args.ts +4 -4
  767. package/scripts/run/progress/run-progress-cli.ts +39 -50
  768. package/scripts/run/progress/run-progress-clock.ts +25 -32
  769. package/scripts/run/progress/run-progress-config.ts +6 -9
  770. package/scripts/run/progress/run-progress-read.ts +9 -10
  771. package/scripts/run/progress/run-progress.ts +48 -53
  772. package/scripts/run/review/run-review-cli.ts +6 -6
  773. package/scripts/run/review/run-review-steps.ts +6 -6
  774. package/scripts/run/review/run-review.ts +9 -11
  775. package/scripts/run/run-cli-fault.ts +29 -0
  776. package/scripts/run/run-ending-cli.ts +3 -3
  777. package/scripts/run/run-ending.ts +10 -14
  778. package/scripts/run/run-halfrun-resume.ts +6 -8
  779. package/scripts/run/run-headless.ts +26 -12
  780. package/scripts/run/run-invocation.ts +17 -22
  781. package/scripts/run/run-label.ts +7 -5
  782. package/scripts/run/run-liveness-cli.ts +19 -6
  783. package/scripts/run/run-liveness.ts +27 -38
  784. package/scripts/run/run-next-cli.ts +5 -9
  785. package/scripts/run/run-next.ts +4 -5
  786. package/scripts/run/run-parent-cut-hook.ts +10 -12
  787. package/scripts/run/run-preflight.ts +25 -29
  788. package/scripts/run/run-prep-cli.ts +17 -13
  789. package/scripts/run/run-prep-locate.ts +4 -5
  790. package/scripts/run/run-prep.ts +7 -10
  791. package/scripts/run/run-prrun-resume.ts +2 -2
  792. package/scripts/run/run-report-cli.ts +4 -4
  793. package/scripts/run/run-report.ts +9 -14
  794. package/scripts/run/run-retrospective.ts +3 -3
  795. package/scripts/run/run-section.ts +42 -0
  796. package/scripts/run/run-stage-read.ts +2 -2
  797. package/scripts/run/run-stage.ts +6 -4
  798. package/scripts/run/run-status-cli.ts +7 -5
  799. package/scripts/run/run-status.ts +6 -7
  800. package/scripts/run/run-step-cli.ts +64 -18
  801. package/scripts/run/run-step.ts +107 -51
  802. package/scripts/run/run-stop-notify.ts +7 -8
  803. package/scripts/run/run-stranded-cli.ts +1 -1
  804. package/scripts/run/run-stranded-detect.ts +4 -4
  805. package/scripts/run/run-stranded.ts +11 -13
  806. package/scripts/run/run-tail-cli.ts +15 -16
  807. package/scripts/run/run-tail.ts +14 -33
  808. package/scripts/run/run-watcher-guard-cli.ts +3 -4
  809. package/scripts/run/run-watcher-guard.ts +11 -12
  810. package/scripts/run/run-watcher-hook.ts +6 -12
  811. package/scripts/run/ship/run-ship-cli.ts +67 -33
  812. package/scripts/run/ship/run-ship-detach.ts +15 -13
  813. package/scripts/run/ship/run-ship-lock.ts +1 -1
  814. package/scripts/run/ship/run-ship-next.ts +7 -8
  815. package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
  816. package/scripts/run/ship/run-ship-preflight.ts +10 -11
  817. package/scripts/run/ship/run-ship-probe.ts +4 -4
  818. package/scripts/run/ship/run-ship-return.ts +1 -1
  819. package/scripts/run/ship/run-ship-review-steps.ts +43 -24
  820. package/scripts/run/ship/run-ship-review.ts +12 -14
  821. package/scripts/run/ship/run-ship-scoped.ts +15 -6
  822. package/scripts/run/ship/run-ship-stage.ts +80 -26
  823. package/scripts/run/ship/run-ship-steps.ts +26 -16
  824. package/scripts/run/ship/run-ship-stop-text.ts +4 -2
  825. package/scripts/run/ship/run-ship-sync.ts +9 -8
  826. package/scripts/run/ship/run-ship.ts +17 -32
  827. package/scripts/run/tidy/run-tidy-cli.ts +9 -5
  828. package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
  829. package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
  830. package/scripts/run/tidy/run-tidy.ts +4 -3
  831. package/scripts/run/wake/run-wake-cli.ts +27 -32
  832. package/scripts/run/wake/run-wake-describe.ts +24 -28
  833. package/scripts/run/wake/run-wake-driver.ts +14 -14
  834. package/scripts/run/wake/run-wake-handoff.ts +6 -6
  835. package/scripts/run/wake/run-wake-loop.ts +9 -9
  836. package/scripts/run/wake/run-wake-restart.ts +4 -5
  837. package/scripts/run/wake/run-wake-session.ts +23 -27
  838. package/scripts/run/wake/run-wake.ts +57 -279
  839. package/scripts/safe-chain/ci-installer-pin.ts +3 -3
  840. package/scripts/safe-chain/pack-hook.ts +2 -2
  841. package/scripts/safe-chain/preinstall-command.ts +2 -2
  842. package/scripts/security/security-audit-logic.ts +1 -1
  843. package/scripts/security/security-audit-provision-logic.ts +1 -1
  844. package/scripts/security/security-audit-provision.ts +2 -2
  845. package/scripts/security/security-audit.ts +5 -5
  846. package/scripts/security/security-updates-logic.ts +2 -3
  847. package/scripts/security/security-updates.ts +2 -4
  848. package/scripts/self-sync-guard/index.ts +1 -1
  849. package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
  850. package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
  851. package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
  852. package/scripts/sonar/sonar-hotspots.ts +1 -1
  853. package/scripts/sonar/sonar-new-code-cli.ts +1 -1
  854. package/scripts/sonar/sonar-new-code.ts +1 -1
  855. package/scripts/sonar/sonar-project.ts +1 -1
  856. package/scripts/split/split-assess-cli.ts +1 -1
  857. package/scripts/split/split-assess.ts +3 -3
  858. package/scripts/sync/directory-copy-guard.ts +2 -3
  859. package/scripts/sync/managed-config-scope-cli.ts +1 -2
  860. package/scripts/sync/managed-config-scope.ts +4 -4
  861. package/scripts/sync/plugin-skill-directories.ts +2 -2
  862. package/scripts/sync/reconcile-templates.ts +17 -8
  863. package/scripts/sync/removed-skill-manifest.ts +2 -3
  864. package/scripts/sync/sync-ai-files.ts +7 -7
  865. package/scripts/sync/sync-configs.ts +30 -3
  866. package/scripts/sync/sync-hook-safety.ts +2 -2
  867. package/scripts/sync/sync.ts +23 -10
  868. package/scripts/sync/synced-paths.ts +2 -1
  869. package/scripts/sync/workflow-pin-logic.ts +1 -1
  870. package/scripts/test/test-declared-changed.ts +4 -4
  871. package/scripts/test/test-declared-logic.ts +2 -3
  872. package/scripts/test/test-declared-match.ts +25 -4
  873. package/scripts/test/test-declared.ts +26 -9
  874. package/scripts/test/test-red-commit.ts +3 -2
  875. package/scripts/test/test-red-logic.ts +7 -14
  876. package/scripts/test/test-red.ts +12 -47
  877. package/scripts/test/test-related-scope.ts +2 -3
  878. package/scripts/test/test-related.ts +3 -3
  879. package/scripts/test/test-type-logic.ts +1 -2
  880. package/scripts/test/test-unit-guard.ts +13 -17
  881. package/scripts/test/unit-worker-share.ts +7 -8
  882. package/scripts/time-runtime/time-agent-bundles.ts +2 -4
  883. package/scripts/time-runtime/time-background.ts +17 -21
  884. package/scripts/time-runtime/time-batch-guard.ts +67 -342
  885. package/scripts/time-runtime/time-bundle-call.ts +26 -28
  886. package/scripts/time-runtime/time-bundles.ts +11 -12
  887. package/scripts/time-runtime/time-call-identity.ts +1 -1
  888. package/scripts/time-runtime/time-command-key.ts +2 -2
  889. package/scripts/time-runtime/time-density-hook.ts +8 -11
  890. package/scripts/time-runtime/time-density.ts +5 -5
  891. package/scripts/time-runtime/time-followup-stage.ts +7 -7
  892. package/scripts/time-runtime/time-format.ts +5 -5
  893. package/scripts/time-runtime/time-hook-transcript.ts +3 -3
  894. package/scripts/time-runtime/time-instant.ts +1 -1
  895. package/scripts/time-runtime/time-markers.ts +15 -19
  896. package/scripts/time-runtime/time-phase-names.ts +3 -3
  897. package/scripts/time-runtime/time-reported-failure.ts +15 -19
  898. package/scripts/time-runtime/time-round-trips.ts +20 -23
  899. package/scripts/time-runtime/time-shell.ts +8 -8
  900. package/scripts/time-runtime/time-single-check.ts +1 -2
  901. package/scripts/time-runtime/time-spans.ts +35 -40
  902. package/scripts/time-runtime/time-tool-call.ts +15 -16
  903. package/scripts/time-runtime/time-transcript-line.ts +53 -34
  904. package/scripts/time-runtime/time-writes.ts +5 -5
  905. package/scripts/ui/ui-routes-cli.ts +1 -2
  906. package/scripts/ui/ui-routes.ts +1 -2
  907. package/scripts/version/bump-version.ts +1 -1
  908. package/scripts/version/fresh-metadata-cache.ts +2 -2
  909. package/scripts/version/latest-corepack.ts +26 -26
  910. package/scripts/version/latest-lane-guard.ts +1 -1
  911. package/scripts/version/latest-scope-cli.ts +2 -2
  912. package/scripts/version/latest-stamp.ts +1 -2
  913. package/scripts/version/latest-update.ts +2 -2
  914. package/scripts/version/npm-registry.ts +2 -2
  915. package/scripts/version/package-manager-version.ts +18 -0
  916. package/scripts/version/publishable-range-check.ts +2 -1
  917. package/scripts/version/publishable-range.ts +1 -1
  918. package/scripts/version/release-age.ts +11 -11
  919. package/scripts/version/release-hold.ts +2 -2
  920. package/scripts/version/safe-chain-version-update.ts +3 -3
  921. package/scripts/version/version-check-logic.ts +2 -3
  922. package/scripts/version/version-check.ts +1 -2
  923. package/scripts/version/version-command-config.ts +2 -2
  924. package/scripts/version/version-commands.ts +3 -3
  925. package/scripts/version/version-remote.ts +4 -4
  926. package/scripts/version/version-targets.ts +2 -2
  927. package/templates/gitignore +7 -0
  928. package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
  929. package/dist/hooks/chunk-RKUAD3I6.js +0 -90
  930. package/dist/hooks/chunk-WPALEIRX.js +0 -18
  931. package/scripts/backlog/backlog-restructure.ts +0 -152
  932. package/scripts/rules/issue-fold-rule.ts +0 -72
  933. package/scripts/rules/wip-cap.ts +0 -63
  934. package/scripts/run/run-issue-number.ts +0 -19
@@ -0,0 +1,219 @@
1
+ import { stripVTControlCharacters } from 'node:util'
2
+ import string_width from 'string-width'
3
+ import { run_board_labels } from './run-board-labels'
4
+
5
+ // A live `run:board` frame kept within the terminal. A frame taller than the pane scrolls the
6
+ // alternate screen as it is written, and the header — the lines that say whether the run moves and
7
+ // how far it is — is what scrolls off. So the parts below it give way instead, least wanted first:
8
+ // the footer, the legend, the finished rows, the notes, the rows not yet started, the parked rows
9
+ // and, last, the running rows — what a person keeps the board open to see. Each stage stops once the
10
+ // frame fits, a cut row is counted on its section's `more N` line, and the order a row is drawn in
11
+ // never changes. A line wider than the pane wraps, so every line is counted by the rows it takes on
12
+ // screen, not as one.
13
+
14
+ const { WORDS } = run_board_labels
15
+ const INDENT = ' '
16
+
17
+ interface TerminalSize {
18
+ rows: number
19
+ columns: number
20
+ }
21
+
22
+ // The stage an issue row gives way in, the earlier first.
23
+ type YieldStage = 'finished' | 'pending' | 'parked' | 'running'
24
+
25
+ // When a row's stage gives it way: the oldest first, a row with no time before every timed one.
26
+ interface RowYield {
27
+ stage: YieldStage
28
+ at_ms: number | undefined
29
+ }
30
+
31
+ // One line of the plan, an issue row with when it gives way; a rule, a blank or an epic's own line none.
32
+ interface PlanLine {
33
+ text: string
34
+ row: RowYield | undefined
35
+ }
36
+
37
+ // A plan section drops its heading once none of its rows is left.
38
+ interface PlanSection {
39
+ head: ReadonlyArray<string>
40
+ lines: ReadonlyArray<PlanLine>
41
+ }
42
+
43
+ // The newest notes shown, and how many older ones are already past the section's limit.
44
+ interface NotesPart {
45
+ head: ReadonlyArray<string>
46
+ lines: ReadonlyArray<string>
47
+ hidden: number
48
+ }
49
+
50
+ // A frame in its parts, top to bottom: the header above stays.
51
+ interface FrameParts {
52
+ above: ReadonlyArray<string>
53
+ plan: ReadonlyArray<PlanSection>
54
+ notes: NotesPart
55
+ legend: ReadonlyArray<string>
56
+ footer: ReadonlyArray<string>
57
+ }
58
+
59
+ // One thing that gives way: a part as a whole, one note (the oldest shown), or one issue row.
60
+ type Yielder = 'footer' | 'legend' | 'note' | PlanLine
61
+
62
+ interface Cut {
63
+ footer: boolean
64
+ legend: boolean
65
+ notes: number
66
+ rows: ReadonlySet<PlanLine>
67
+ }
68
+
69
+ const NO_CUT: Cut = { footer: false, legend: false, notes: 0, rows: new Set() }
70
+
71
+ // The columns a line takes on screen: its color escapes take none, an emoji two.
72
+ function width_of(line: string): number {
73
+ return string_width(stripVTControlCharacters(line))
74
+ }
75
+
76
+ function height_of(line: string, columns: number): number {
77
+ return Math.max(1, Math.ceil(width_of(line) / Math.max(1, columns)))
78
+ }
79
+
80
+ function heights(lines: ReadonlyArray<string>, columns: number): number {
81
+ return lines.reduce((sum, line) => sum + height_of(line, columns), 0)
82
+ }
83
+
84
+ function more_lines(hidden: number): Array<string> {
85
+ return hidden > 0 ? [`${INDENT}${WORDS.more} ${String(hidden)}`] : []
86
+ }
87
+
88
+ // A section that ends on an epic whose children were all cut ends on its last row instead.
89
+ function section_lines(section: PlanSection, cut: ReadonlySet<PlanLine>): Array<string> {
90
+ const kept = section.lines.filter((line) => !cut.has(line))
91
+ const last = kept.findLastIndex((line) => line.row !== undefined)
92
+
93
+ if (last === -1) return []
94
+
95
+ return [...section.head, ...kept.slice(0, last + 1).map((line) => line.text)]
96
+ }
97
+
98
+ // The plan's cut rows are counted on one line at its end, under a blank when no section is left.
99
+ function plan_lines(plan: ReadonlyArray<PlanSection>, cut: ReadonlySet<PlanLine>): Array<string> {
100
+ const drawn = plan.flatMap((section) => section_lines(section, cut))
101
+ const lead = drawn.length === 0 && cut.size > 0 ? [''] : []
102
+
103
+ return [...lead, ...drawn, ...more_lines(cut.size)]
104
+ }
105
+
106
+ // The notes give way from the oldest shown; with none left the section goes, heading and all.
107
+ function notes_lines(notes: NotesPart, cut: number): Array<string> {
108
+ const kept = notes.lines.slice(0, notes.lines.length - cut)
109
+
110
+ if (kept.length === 0) return []
111
+
112
+ return [...notes.head, ...kept, ...more_lines(notes.hidden + cut)]
113
+ }
114
+
115
+ function compose(parts: FrameParts, cut: Cut): Array<string> {
116
+ return [
117
+ ...parts.above,
118
+ ...plan_lines(parts.plan, cut.rows),
119
+ ...notes_lines(parts.notes, cut.notes),
120
+ ...(cut.legend ? [] : parts.legend),
121
+ ...(cut.footer ? [] : parts.footer),
122
+ ]
123
+ }
124
+
125
+ interface Indexed {
126
+ line: PlanLine
127
+ index: number
128
+ }
129
+
130
+ function at_of(entry: Indexed): number {
131
+ return entry.line.row?.at_ms ?? -Infinity
132
+ }
133
+
134
+ // The oldest first; rows with the same time — the rows not yet started have none — from the plan's end.
135
+ function oldest_first(left: Indexed, right: Indexed): number {
136
+ const [left_at, right_at] = [at_of(left), at_of(right)]
137
+
138
+ if (left_at === right_at) return right.index - left.index
139
+
140
+ return left_at < right_at ? -1 : 1
141
+ }
142
+
143
+ function yielding(rows: ReadonlyArray<Indexed>, stage: YieldStage): Array<PlanLine> {
144
+ return rows
145
+ .filter((entry) => entry.line.row?.stage === stage)
146
+ .toSorted(oldest_first)
147
+ .map((entry) => entry.line)
148
+ }
149
+
150
+ // Everything that gives way, in the order it does.
151
+ function order_of(parts: FrameParts): Array<Yielder> {
152
+ const rows = parts.plan
153
+ .flatMap((section) => section.lines)
154
+ .map((line, index) => ({ line, index }))
155
+ .filter((entry) => entry.line.row !== undefined)
156
+ const notes = parts.notes.lines.map((): Yielder => 'note')
157
+
158
+ return [
159
+ 'footer',
160
+ 'legend',
161
+ ...yielding(rows, 'finished'),
162
+ ...notes,
163
+ ...yielding(rows, 'pending'),
164
+ ...yielding(rows, 'parked'),
165
+ ...yielding(rows, 'running'),
166
+ ]
167
+ }
168
+
169
+ function is_line(item: Yielder): item is PlanLine {
170
+ return typeof item !== 'string'
171
+ }
172
+
173
+ // What the first `count` of the order cuts.
174
+ function cut_of(order: ReadonlyArray<Yielder>, count: number): Cut {
175
+ const gone = order.slice(0, count)
176
+
177
+ return {
178
+ footer: gone.includes('footer'),
179
+ legend: gone.includes('legend'),
180
+ notes: gone.filter((item) => item === 'note').length,
181
+ rows: new Set(gone.filter((item) => is_line(item))),
182
+ }
183
+ }
184
+
185
+ // The leading lines that fit, for a pane too short even for the header: the top is what is kept.
186
+ function clamped(lines: ReadonlyArray<string>, size: TerminalSize): Array<string> {
187
+ let used = 0
188
+
189
+ return lines.filter((line) => {
190
+ used += height_of(line, size.columns)
191
+
192
+ return used <= size.rows
193
+ })
194
+ }
195
+
196
+ // A frame drawn whole, where no terminal bounds it.
197
+ function whole(parts: FrameParts): Array<string> {
198
+ return compose(parts, NO_CUT)
199
+ }
200
+
201
+ // The frames each longer cut of the order leaves, the uncut whole first.
202
+ function frames_of(parts: FrameParts): Array<Array<string>> {
203
+ const order = order_of(parts)
204
+ const counts = Array.from({ length: order.length + 1 }, (_, count) => count)
205
+
206
+ return counts.map((count) => compose(parts, cut_of(order, count)))
207
+ }
208
+
209
+ function fit(parts: FrameParts, size: TerminalSize): Array<string> {
210
+ const frames = frames_of(parts)
211
+ const fitting = frames.find((frame) => heights(frame, size.columns) <= size.rows)
212
+
213
+ return clamped(fitting ?? frames.at(-1) ?? [], size)
214
+ }
215
+
216
+ const run_board_fit = { fit, height_of, whole, width_of }
217
+
218
+ export { run_board_fit }
219
+ export type { FrameParts, NotesPart, PlanLine, PlanSection, RowYield, TerminalSize, YieldStage }
@@ -0,0 +1,162 @@
1
+ import { run_progress } from '#scripts/run/progress/run-progress'
2
+ import { run_progress_cli } from '#scripts/run/progress/run-progress-cli'
3
+ import type { ClosedAnswer } from './run-board-closed'
4
+ import { run_board_fetch, type Fetch } from './run-board-fetch'
5
+ import { run_board_layout, type BoardPlan } from './run-board-layout'
6
+ import type { LocalRead } from './run-board-read'
7
+ import { run_board_state, type BoardPorts, type BoardState, type Pace } from './run-board-state'
8
+ import { run_board_status, type ItemStatus } from './run-board-status'
9
+
10
+ // The GitHub reads a `run:board` redraw draws over: the plan, and the run's children that left the
11
+ // open listing. Each is taken no more often than `run:progress` re-reads after a decline. **A live
12
+ // board never waits on them**: each read is launched and folded in on the redraw after it lands, so
13
+ // the clock keeps moving while GitHub answers; one plain frame waits for them. A failed plan read
14
+ // keeps the previous plan on screen and says when it failed. A run that ended keeps its plan as it
15
+ // last read.
16
+
17
+ const PLAN_RETRY_MS = run_progress_cli.DECLINE_RETRY_SECONDS * run_progress.MS_PER_SECOND
18
+ // A rejected closed read answers nothing closed and not whole, so it is asked again.
19
+ const UNANSWERED: ClosedAnswer = { closed: new Map(), is_whole: false }
20
+ const { is_due } = run_board_state
21
+
22
+ // What a step of the GitHub reads works against.
23
+ interface Gather {
24
+ ports: BoardPorts
25
+ local: LocalRead
26
+ now_ms: number
27
+ pace: Pace
28
+ }
29
+
30
+ // A title the board once knew stays known, so an issue that left the open listing keeps its name.
31
+ function with_titles(plan: BoardPlan, previous: BoardPlan | undefined): BoardPlan {
32
+ const titles = new Map([...(previous?.context.titles ?? []), ...plan.context.titles])
33
+
34
+ return { ...plan, context: { ...plan.context, titles } }
35
+ }
36
+
37
+ // An ended run's plan is read until it lands once, then held; a read in flight is not launched again.
38
+ function is_plan_due(state: BoardState, gather: Gather): boolean {
39
+ if (state.plan_fetch !== undefined) return false
40
+ if (gather.local.ended_ms !== undefined && state.fetched_ms !== undefined) return false
41
+
42
+ return is_due(state.attempted_ms, PLAN_RETRY_MS, gather.now_ms)
43
+ }
44
+
45
+ function launch_plan(state: BoardState, gather: Gather): BoardState {
46
+ if (!is_plan_due(state, gather)) return state
47
+
48
+ async function read(): Promise<BoardPlan | undefined> {
49
+ return await gather.ports.read_plan(gather.local.scope)
50
+ }
51
+
52
+ const plan_fetch = run_board_fetch.launch(read, undefined)
53
+
54
+ return { ...state, plan_fetch, attempted_ms: gather.now_ms }
55
+ }
56
+
57
+ // A landed read is folded in as of the moment it was asked; one still in flight leaves the state as is.
58
+ function fold_plan(state: BoardState): BoardState {
59
+ const answer = state.plan_fetch?.answer()
60
+
61
+ if (answer === undefined) return state
62
+
63
+ const settled = { ...state, plan_fetch: undefined }
64
+
65
+ if (answer.value === undefined) return { ...settled, failed_ms: state.attempted_ms }
66
+
67
+ return {
68
+ ...settled,
69
+ plan: with_titles(answer.value, state.plan),
70
+ fetched_ms: state.attempted_ms,
71
+ failed_ms: undefined,
72
+ }
73
+ }
74
+
75
+ function statuses_for(plan: BoardPlan, local: LocalRead): ReadonlyMap<number, ItemStatus> {
76
+ return run_board_status.statuses_of(local.events, local.lanes, run_board_layout.numbers_of(plan))
77
+ }
78
+
79
+ // The children the run touched that the open listing no longer holds and the board has not read yet.
80
+ // A listing cut short proves nothing missing, so it asks about none.
81
+ function unread_closed(state: BoardState, local: LocalRead): Array<number> {
82
+ const open = state.plan?.context.open_numbers
83
+
84
+ if (open === undefined || state.plan === undefined) return []
85
+
86
+ const touched = [...statuses_for(state.plan, local).keys()]
87
+
88
+ return touched.filter((issue) => !open.has(issue) && !state.closed.has(issue))
89
+ }
90
+
91
+ // An ended run asks until one ask after it ended has answered whole, then holds what it has, as its
92
+ // plan is held: the board is left open between runs, so a child that never answers closed would
93
+ // otherwise be asked about every retry interval while no run is going.
94
+ function has_asked_since_end(state: BoardState, local: LocalRead): boolean {
95
+ const { closed_answered_ms } = state
96
+ if (closed_answered_ms === undefined || local.ended_ms === undefined) return false
97
+
98
+ return closed_answered_ms >= local.ended_ms
99
+ }
100
+
101
+ function is_closed_due(state: BoardState, gather: Gather): boolean {
102
+ if (state.closed_fetch !== undefined || has_asked_since_end(state, gather.local)) return false
103
+
104
+ return is_due(state.closed_attempted_ms, PLAN_RETRY_MS, gather.now_ms)
105
+ }
106
+
107
+ // A closed child is read once and its answer kept; one that has not answered closed is asked again no
108
+ // sooner than the plan is, and an ended run's not again once an ask after the end has answered whole.
109
+ function launch_closed(state: BoardState, gather: Gather): BoardState {
110
+ const unread = unread_closed(state, gather.local)
111
+
112
+ if (unread.length === 0 || !is_closed_due(state, gather)) return state
113
+
114
+ async function read(): Promise<ClosedAnswer> {
115
+ return await gather.ports.read_closed(unread)
116
+ }
117
+
118
+ const closed_fetch = run_board_fetch.launch(read, UNANSWERED)
119
+
120
+ return { ...state, closed_fetch, closed_attempted_ms: gather.now_ms }
121
+ }
122
+
123
+ // A whole answer counts as of the moment it was asked.
124
+ function fold_closed(state: BoardState): BoardState {
125
+ const answer = state.closed_fetch?.answer()
126
+
127
+ if (answer === undefined) return state
128
+
129
+ const { closed, is_whole } = answer.value
130
+ const closed_answered_ms = is_whole ? state.closed_attempted_ms : state.closed_answered_ms
131
+
132
+ return {
133
+ ...state,
134
+ closed: new Map([...state.closed, ...closed]),
135
+ closed_fetch: undefined,
136
+ closed_answered_ms,
137
+ }
138
+ }
139
+
140
+ // At the `settled` pace, waits for a read in flight to land.
141
+ async function settle(pending: Fetch<unknown> | undefined, pace: Pace): Promise<void> {
142
+ if (pending !== undefined && pace === 'settled') await pending.landed
143
+ }
144
+
145
+ // Folds what landed and launches what is due — the plan first, since the closed children are read off
146
+ // the plan's listing.
147
+ async function gather_github(state: BoardState, gather: Gather): Promise<BoardState> {
148
+ const planned = launch_plan(fold_plan(state), gather)
149
+
150
+ await settle(planned.plan_fetch, gather.pace)
151
+
152
+ const closing = launch_closed(fold_closed(fold_plan(planned)), gather)
153
+
154
+ await settle(closing.closed_fetch, gather.pace)
155
+
156
+ return fold_closed(closing)
157
+ }
158
+
159
+ const run_board_github = { PLAN_RETRY_MS, gather_github, statuses_for }
160
+
161
+ export { run_board_github }
162
+ export type { Gather }
@@ -0,0 +1,275 @@
1
+ import { styleText } from 'node:util'
2
+ import { backlog_budget } from '#scripts/backlog/backlog-budget'
3
+ import { backlog_idle, type IdleWindow } from '#scripts/backlog/backlog-idle'
4
+ import { run_board_labels } from './run-board-labels'
5
+ import { run_board_layout, type BoardLayout, type BoardRow } from './run-board-layout'
6
+ import { run_board_machine, type MachineGauges } from './run-board-machine'
7
+ import type { RunActivity } from './run-board-status'
8
+ import type { LaneUsages } from './run-board-usage'
9
+
10
+ // The top of `run:board`: whether the run is moving, how long it has run, how long it has left, how
11
+ // fresh its last event is, and how far through the plan it is — and, while it waits on an empty
12
+ // backlog, until when it waits and what ends the wait. Every time comes from a record (the carry's
13
+ // start, the stream's events, the `idle` window); nothing here guesses one. Lines of symbols rather
14
+ // than sentences: the `⏱` that moves every second is the proof the board is live, so no `updated`
15
+ // line is drawn. Beside the time, the machine the run is on, so a slow run reads apart from a stuck
16
+ // one. **Always two lines**: the run's state with its progress, then the time with the machine. A
17
+ // value not read yet is drawn `-`, never `0`, so a header still loading reads as unknown rather than
18
+ // as an empty run.
19
+
20
+ const { HEADER_ICONS, STATE_ICONS, WORDS, bar_of, clock_of, elapsed_of, left_of, minute_of } =
21
+ run_board_labels
22
+ const UNKNOWN = '-'
23
+ const { GAP } = run_board_machine
24
+ // A running run whose newest event is older than this is drawn as stale, so a hang stands out; past
25
+ // twice that it is drawn as alarming.
26
+ const STALE_MINUTES = 15
27
+ const STALE_MS = STALE_MINUTES * backlog_budget.MS_PER_MINUTE
28
+ const ALARM_FACTOR = 2
29
+ const ALARM_MS = STALE_MS * ALARM_FACTOR
30
+ const INDENT = ' '
31
+ const RUN_NAME = 'backlogrun'
32
+
33
+ // Who reads the frame: a person on a screen, or a chat a session answers a progress question in, which
34
+ // draws what the screen does but for the machine, its memory alone — a CPU or swap figure read once
35
+ // means nothing.
36
+ type BoardForm = 'screen' | 'chat'
37
+
38
+ interface BoardHeader {
39
+ now_ms: number
40
+ started_ms: number
41
+ // Set once the run has ended: the title then says when, and how long it took.
42
+ ended_ms: number | undefined
43
+ activity: RunActivity
44
+ layout: BoardLayout | undefined
45
+ // The total the board first saw, so arrivals since then read as `(+N)`.
46
+ baseline_total: number | undefined
47
+ plan_fetched_ms: number | undefined
48
+ plan_failed_ms: number | undefined
49
+ // Whether a plan read is in flight.
50
+ is_plan_loading: boolean
51
+ // The machine's gauges, `undefined` before the first sample.
52
+ machine: MachineGauges | undefined
53
+ // Each running lane's CPU and memory, `undefined` where none could be read.
54
+ usages?: LaneUsages | undefined
55
+ // The spinner's frame a running run and a running row turn, `undefined` where the output is not a
56
+ // terminal and they draw their still icons.
57
+ spinner: string | undefined
58
+ form: BoardForm
59
+ // An issue reference as the board draws it — `3450` or `owner/repo#12` — made a link where the
60
+ // terminal opens one.
61
+ link: (reference: string) => string
62
+ }
63
+
64
+ interface BoardCounts {
65
+ total: number
66
+ settled: number
67
+ parked: number
68
+ running: number
69
+ remaining: number
70
+ }
71
+
72
+ type RunMark = 'running' | 'idle' | 'human' | 'stopped'
73
+
74
+ type TextColor = Parameters<typeof styleText>[0]
75
+
76
+ // The run's state as a colored glyph before its name.
77
+ const RUN_MARKS: Readonly<Record<RunMark, { glyph: string; color: TextColor }>> = {
78
+ running: { glyph: '▶', color: 'green' },
79
+ idle: { glyph: '⏸', color: 'yellow' },
80
+ human: { glyph: '✋', color: 'magenta' },
81
+ stopped: { glyph: '■', color: 'gray' },
82
+ }
83
+
84
+ function count_state(rows: ReadonlyArray<BoardRow>, state: BoardRow['state']): number {
85
+ return rows.filter((row) => row.state === state).length
86
+ }
87
+
88
+ function counts_of(layout: BoardLayout): BoardCounts {
89
+ const total = run_board_layout.rows_of(layout).length
90
+ const parked = count_state(layout.active, 'parked')
91
+ const settled = count_state(layout.active, 'merged') + parked + count_state(layout.active, 'done')
92
+ const running = count_state(layout.active, 'running')
93
+
94
+ return { total, settled, parked, running, remaining: total - settled - running }
95
+ }
96
+
97
+ // Nothing running: the run is waiting on a person when all the plan has left is what
98
+ // `needs-decision` holds, and otherwise idle.
99
+ function quiet_mark(layout: BoardLayout | undefined): RunMark {
100
+ return layout?.waves.length === 0 && layout.people.length > 0 ? 'human' : 'idle'
101
+ }
102
+
103
+ // The run's state, each state overriding the ones below it.
104
+ function mark_of(header: BoardHeader, running: number): RunMark {
105
+ if (header.activity.is_stopped) return 'stopped'
106
+ if (running > 0) return 'running'
107
+
108
+ return header.activity.idle === undefined ? quiet_mark(header.layout) : 'idle'
109
+ }
110
+
111
+ // A running run turns the spinner in place of ▶, both one column wide; every other mark stands still.
112
+ function run_part(mark: RunMark, spinner: string | undefined): string {
113
+ const { glyph, color } = RUN_MARKS[mark]
114
+ const shown = mark === 'running' ? (spinner ?? glyph) : glyph
115
+
116
+ return styleText(color, `${shown} ${RUN_NAME}`)
117
+ }
118
+
119
+ function aged(part: string, age_ms: number): string {
120
+ if (age_ms > ALARM_MS) return styleText('red', part)
121
+
122
+ return age_ms > STALE_MS ? styleText('yellow', part) : part
123
+ }
124
+
125
+ // How long ago the stream last moved; only a running run can be stale, so only it is colored. An ended
126
+ // run has no heartbeat to keep: one counting on would read as a hang.
127
+ function heartbeat_part(header: BoardHeader, mark: RunMark): string | undefined {
128
+ const last = header.activity.last_event_ms
129
+
130
+ if (last === undefined || header.ended_ms !== undefined) return undefined
131
+
132
+ const age = header.now_ms - last
133
+ const part = `💓 ${elapsed_of(age)}`
134
+
135
+ return mark === 'running' ? aged(part, age) : part
136
+ }
137
+
138
+ // A plan fetch is said only when it failed — the board otherwise keeps quiet about a routine read.
139
+ function plan_warning(header: BoardHeader): string | undefined {
140
+ const failed = header.plan_failed_ms
141
+
142
+ if (failed === undefined) return undefined
143
+
144
+ return styleText('yellow', `⚠ ${WORDS.plan} ${minute_of(failed)}`)
145
+ }
146
+
147
+ // A plan read in flight turns the spinner after ⏳ and says nothing more; a
148
+ // frame that is not a terminal's has no spinner, and draws nothing for it.
149
+ function loading_part(header: BoardHeader): string | undefined {
150
+ const { is_plan_loading, spinner } = header
151
+
152
+ return is_plan_loading && spinner !== undefined ? `${HEADER_ICONS.loading} ${spinner}` : undefined
153
+ }
154
+
155
+ // A running run's age and time left before the cut-off, or an ended run's frozen duration and the
156
+ // minute it ended — an ended run has no cut-off left.
157
+ function time_parts(header: BoardHeader): Array<string> {
158
+ const { now_ms, started_ms, ended_ms } = header
159
+
160
+ if (ended_ms !== undefined) {
161
+ return [
162
+ `⏱ ${elapsed_of(ended_ms - started_ms)}`,
163
+ `${HEADER_ICONS.ended} ${minute_of(ended_ms)}`,
164
+ ]
165
+ }
166
+
167
+ const cutoff = started_ms + backlog_budget.WHOLE_RUN_BUDGET_MS
168
+
169
+ return [`⏱ ${elapsed_of(now_ms - started_ms)}`, `⌛ ${left_of(cutoff - now_ms)}`]
170
+ }
171
+
172
+ function layout_of(header: BoardHeader): BoardLayout {
173
+ return header.layout ?? run_board_layout.EMPTY_LAYOUT
174
+ }
175
+
176
+ // Whether the plan has been read: until it has, the board draws the run's own children alone, and the
177
+ // counts only the plan knows — the total and what waits — are unknown.
178
+ function is_plan_read(header: BoardHeader): boolean {
179
+ return header.plan_fetched_ms !== undefined
180
+ }
181
+
182
+ // Arrivals since the board first looked, as `(+N)`.
183
+ function plus_of(counts: BoardCounts, header: BoardHeader): string {
184
+ const added = counts.total - (header.baseline_total ?? counts.total)
185
+
186
+ return added > 0 ? ` (+${String(added)})` : ''
187
+ }
188
+
189
+ // Icon, figure, then bar, as the machine gauges: the settled count is right-aligned to the total's
190
+ // width, so the bar starts in one column as the count grows. Arrivals since the board first looked
191
+ // follow the bar, where they cannot move it.
192
+ function tally_part(counts: BoardCounts, is_read: boolean): string {
193
+ const { settled } = counts
194
+ const total = is_read ? String(counts.total) : UNKNOWN
195
+ const tally = `${String(settled)}/${total}`.padStart(`${total}/${total}`.length)
196
+ const bar = is_read ? bar_of(settled, counts.total) : bar_of(0, 0)
197
+
198
+ return `${STATE_ICONS.merged} ${tally} ${bar}`
199
+ }
200
+
201
+ function progress_parts(counts: BoardCounts, header: BoardHeader): Array<string> {
202
+ const is_read = is_plan_read(header)
203
+
204
+ return [
205
+ `${tally_part(counts, is_read)}${is_read ? plus_of(counts, header) : ''}`,
206
+ `${STATE_ICONS.running} ${String(counts.running)}`,
207
+ `${STATE_ICONS.waiting} ${is_read ? String(counts.remaining) : UNKNOWN}`,
208
+ `${STATE_ICONS.parked} ${String(counts.parked)}`,
209
+ ]
210
+ }
211
+
212
+ // The run's mark and its progress, then how fresh its stream is and what its plan read is doing.
213
+ function state_line(counts: BoardCounts, header: BoardHeader): string {
214
+ const mark = mark_of(header, counts.running)
215
+ const parts = [
216
+ run_part(mark, header.spinner),
217
+ ...progress_parts(counts, header),
218
+ heartbeat_part(header, mark),
219
+ loading_part(header),
220
+ plan_warning(header),
221
+ ]
222
+
223
+ return parts.filter((part) => part !== undefined).join(GAP)
224
+ }
225
+
226
+ function idle_line(idle: IdleWindow, now_ms: number): string {
227
+ const ending = idle.bound === 'idle' ? WORDS.idle_end_idle : WORDS.idle_end_run
228
+ const left = `${elapsed_of(idle.until_ms - now_ms)} ${WORDS.idle_left}`
229
+ const until = `${WORDS.idle_until} ${clock_of(idle.until_ms)} (${left}) → ${ending}`
230
+ const next_check = `${WORDS.next_check} ${clock_of(backlog_idle.next_check_ms(idle))}`
231
+
232
+ return `${INDENT}${RUN_MARKS.idle.glyph} ${until} · ${next_check}`
233
+ }
234
+
235
+ // The wait, under the header's blank line, drawn only while it is what the run is doing: no child
236
+ // running and the run not ended. The children running are the run's own, read
237
+ // locally, so a board still waiting on GitHub never draws a running run as waiting.
238
+ function idle_lines(header: BoardHeader): Array<string> {
239
+ const { idle, is_stopped } = header.activity
240
+
241
+ if (is_stopped || idle === undefined || counts_of(layout_of(header)).running > 0) return []
242
+
243
+ return ['', idle_line(idle, header.now_ms)]
244
+ }
245
+
246
+ // The gauges the machine line draws: every one on a screen, the memory alone in a chat.
247
+ function machine_of(header: BoardHeader): MachineGauges | undefined {
248
+ const { machine } = header
249
+
250
+ if (machine === undefined || header.form === 'screen') return machine
251
+
252
+ return { ...machine, cpu_percent: undefined, swap_mb_per_s: undefined }
253
+ }
254
+
255
+ // The machine before a gauge could be read: each gauge's icon, its figure unknown, apart as the gauges.
256
+ const MACHINE_UNKNOWN = [HEADER_ICONS.cpu, HEADER_ICONS.memory, HEADER_ICONS.swap]
257
+ .map((icon) => `${icon} ${UNKNOWN}`)
258
+ .join(GAP)
259
+
260
+ // The time, then the machine the run is on.
261
+ function clock_line(header: BoardHeader): string {
262
+ const machine = run_board_machine.line_of(machine_of(header)) ?? MACHINE_UNKNOWN
263
+
264
+ return [...time_parts(header), machine].join(GAP)
265
+ }
266
+
267
+ // The run's state with its progress, then the time with the machine, in every state the board can be in.
268
+ function header_lines(header: BoardHeader): Array<string> {
269
+ return [state_line(counts_of(layout_of(header)), header), clock_line(header)]
270
+ }
271
+
272
+ const run_board_header = { counts_of, header_lines, idle_lines, is_plan_read }
273
+
274
+ export { run_board_header }
275
+ export type { BoardCounts, BoardForm, BoardHeader }
@@ -0,0 +1,35 @@
1
+ import {
2
+ BREAKING_CHANGE_LABEL,
3
+ BUG_LABEL,
4
+ BUGFIX_LABEL,
5
+ ENHANCEMENT_LABEL,
6
+ has_label_name,
7
+ } from '#scripts/issue/issue-labels'
8
+ import type { FiledKind } from '#scripts/run/event/run-event-filed'
9
+
10
+ // The release category a row is drawn with (joshuafolkken/kit#3577): the categories
11
+ // `.github/release.yml` sorts a change into, in its order, each with every label that places an issue
12
+ // there. An issue with labels from several takes the first, as the release notes do; one with none is
13
+ // an Other Change and draws no kind.
14
+
15
+ const SEMVER_MAJOR_LABEL = 'Semver-Major'
16
+ const SEMVER_MINOR_LABEL = 'Semver-Minor'
17
+
18
+ const RELEASE_KINDS: ReadonlyArray<readonly [FiledKind, ReadonlyArray<string>]> = [
19
+ ['breaking-change', [BREAKING_CHANGE_LABEL, SEMVER_MAJOR_LABEL]],
20
+ ['enhancement', [ENHANCEMENT_LABEL, SEMVER_MINOR_LABEL]],
21
+ ['bug', [BUGFIX_LABEL, BUG_LABEL]],
22
+ ]
23
+
24
+ // The kinds in the release notes' order — the order a legend names them in.
25
+ const KIND_ORDER: ReadonlyArray<FiledKind> = RELEASE_KINDS.map(([kind]) => kind)
26
+
27
+ function kind_of(labels: ReadonlyArray<string> | undefined): FiledKind | undefined {
28
+ if (labels === undefined) return undefined
29
+
30
+ return RELEASE_KINDS.find(([, names]) => names.some((name) => has_label_name(labels, name)))?.[0]
31
+ }
32
+
33
+ const run_board_kind = { KIND_ORDER, kind_of }
34
+
35
+ export { run_board_kind }