@joshuafolkken/kit 1.1050.0 → 1.1094.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 (581) hide show
  1. package/.claude/settings.json +9 -8
  2. package/.claude/skills/epic-commands/SKILL.md +5 -7
  3. package/.claude/skills/workflow-commands/SKILL.md +19 -11
  4. package/.claude/skills/workflow-commands/background-commands.md +4 -3
  5. package/.claude/skills/workflow-commands/backlogrun-child.md +1 -1
  6. package/.claude/skills/workflow-commands/backlogrun-lanes.md +8 -6
  7. package/.claude/skills/workflow-commands/backlogrun-progress.md +1 -1
  8. package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
  9. package/.claude/skills/workflow-commands/backlogrun.md +2 -2
  10. package/.claude/skills/workflow-commands/chain-rule.md +4 -2
  11. package/.claude/skills/workflow-commands/delegation.md +3 -3
  12. package/.claude/skills/workflow-commands/followup-reference.md +1 -1
  13. package/.claude/skills/workflow-commands/followup.md +7 -3
  14. package/.claude/skills/workflow-commands/fullrun-steps.md +3 -2
  15. package/.claude/skills/workflow-commands/fullrun.md +3 -2
  16. package/.claude/skills/workflow-commands/halfrun.md +16 -19
  17. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  18. package/.claude/skills/workflow-commands/issue-fold-existing.md +10 -10
  19. package/.claude/skills/workflow-commands/issue-scout.md +1 -1
  20. package/.claude/skills/workflow-commands/kickoff.md +9 -4
  21. package/.claude/skills/workflow-commands/latest-gate.md +1 -1
  22. package/.claude/skills/workflow-commands/needs-human-review.md +1 -1
  23. package/.claude/skills/workflow-commands/observation-filing.md +3 -3
  24. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  25. package/.claude/skills/workflow-commands/prrun.md +36 -0
  26. package/.claude/skills/workflow-commands/retrospective.md +1 -1
  27. package/.claude/skills/workflow-commands/working-tree-hold.md +22 -2
  28. package/.codex/hooks.json +16 -20
  29. package/.github/actions/setup-pnpm/action.yml +93 -0
  30. package/.github/dependabot.yml +5 -1
  31. package/.github/workflows/ci.yml +26 -128
  32. package/.github/workflows/pr-classification.yml +5 -41
  33. package/.github/workflows/publish.yml +33 -38
  34. package/.github/workflows/sonar-qube.yml +37 -4
  35. package/AGENTS.md +12 -2
  36. package/CLAUDE.md +15 -16
  37. package/GEMINI.md +14 -2
  38. package/README.md +59 -18
  39. package/SECURITY.md +36 -6
  40. package/cspell/index.yaml +2 -1
  41. package/dist/CLAUDE.md +15 -16
  42. package/dist/config-merge/index.js +15 -3
  43. package/dist/hooks/batch-guard.js +4 -4
  44. package/dist/hooks/{chunk-HJIISEAC.js → chunk-3C4YCCEF.js} +5 -13
  45. package/dist/hooks/{chunk-EJDX2TOB.js → chunk-7ZPFAVR7.js} +7 -88
  46. package/dist/hooks/{chunk-WQ4OSBSS.js → chunk-E54KGFEQ.js} +2 -2
  47. package/dist/hooks/{chunk-GQ7KP45M.js → chunk-IL27YTPH.js} +2 -2
  48. package/dist/hooks/{chunk-DMQN45FN.js → chunk-KHWHKJOM.js} +3 -3
  49. package/dist/hooks/{chunk-5BK3K7V4.js → chunk-M2XDCUKD.js} +997 -478
  50. package/dist/hooks/{chunk-7VPDUBRN.js → chunk-NKOG3XAV.js} +150 -153
  51. package/dist/hooks/{chunk-NJQOBE6L.js → chunk-O4LL4HTI.js} +2 -7
  52. package/dist/hooks/{chunk-NAS4C7GP.js → chunk-OIZUHPJI.js} +2 -2
  53. package/dist/hooks/{chunk-RLDX5SOC.js → chunk-UD24EAIL.js} +2084 -1412
  54. package/dist/hooks/codex-hook-adapter.js +10 -11
  55. package/dist/hooks/duplicate-read-guard.js +5 -5
  56. package/dist/hooks/format-edited.js +2 -2
  57. package/dist/hooks/inputs.json +279 -0
  58. package/dist/hooks/investigation-guard.js +5 -5
  59. package/dist/hooks/pretool-guard.js +9 -9
  60. package/dist/hooks/session-lang.js +0 -1
  61. package/dist/hooks/stop-guard.js +178 -324
  62. package/dist/josh.js +162 -119
  63. package/dist/managed-marker/index.js +2 -1
  64. package/dist/version/index.js +34 -58
  65. package/eslint/rules/promise.js +5 -0
  66. package/package.json +9 -4
  67. package/prompts/collaboration-workflow/issue-citation.md +5 -5
  68. package/prompts/collaboration-workflow/operating-rules.md +4 -4
  69. package/prompts/collaboration-workflow/overview.md +13 -1
  70. package/prompts/collaboration-workflow/report-format.md +1 -1
  71. package/prompts/collaboration-workflow/residency.md +3 -3
  72. package/prompts/collaboration-workflow/rule-delivery.md +1 -1
  73. package/prompts/collaboration-workflow/turn-batching.md +3 -3
  74. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  75. package/prompts/collaboration-workflow/wip-cap.md +25 -22
  76. package/prompts/collaboration-workflow.md +5 -8
  77. package/prompts/review-rubric.md +1 -1
  78. package/prompts/review.md +3 -3
  79. package/prompts/sonar-hotspot-handling.md +11 -3
  80. package/prompts/testing-guide.md +3 -3
  81. package/scripts/adopt/adopt-toolkits.ts +0 -2
  82. package/scripts/adopt/adopt.ts +0 -2
  83. package/scripts/agent/agent-argv.ts +0 -2
  84. package/scripts/agent/agent-diagnostics.ts +1 -1
  85. package/scripts/agent/agent-role-profile.ts +0 -7
  86. package/scripts/agent/claude-agent-argv.ts +0 -2
  87. package/scripts/agent/codex-agent-argv.ts +1 -1
  88. package/scripts/agent/codex-hooks.ts +92 -0
  89. package/scripts/agent/interactive-ask.ts +1 -1
  90. package/scripts/auto-ok/auto-ok-cli.ts +6 -16
  91. package/scripts/backlog/backlog-budget.ts +0 -2
  92. package/scripts/backlog/backlog-defect-priority.ts +2 -2
  93. package/scripts/backlog/backlog-drive-cli.ts +10 -8
  94. package/scripts/backlog/backlog-drive-named-offer.ts +16 -3
  95. package/scripts/backlog/backlog-drive-named.ts +2 -1
  96. package/scripts/backlog/backlog-drive.ts +76 -16
  97. package/scripts/backlog/backlog-named.ts +0 -3
  98. package/scripts/backlog/backlog-next.ts +9 -15
  99. package/scripts/backlog/backlog-offer-cli.ts +0 -5
  100. package/scripts/backlog/backlog-plan-cli.ts +1 -7
  101. package/scripts/backlog/backlog-plan.ts +1 -1
  102. package/scripts/backlog/backlog-pool.ts +3 -6
  103. package/scripts/backlog/backlog-rank.ts +2 -2
  104. package/scripts/backlog/backlog-ready.ts +19 -3
  105. package/scripts/backlog/backlog-scope.ts +1 -3
  106. package/scripts/backlog/backlog-stalled-detect.ts +2 -2
  107. package/scripts/backlog/backlog-stalled.ts +0 -1
  108. package/scripts/backlog/backlog-waves.ts +5 -2
  109. package/scripts/behavior/behavior-cli.ts +1 -1
  110. package/scripts/build/build-codex-hooks.ts +26 -0
  111. package/scripts/build/build-hooks.ts +85 -9
  112. package/scripts/build/hook-bundle-stamp.ts +111 -0
  113. package/scripts/cases/cases-cli.ts +1 -1
  114. package/scripts/cases/cases-logic.ts +1 -1
  115. package/scripts/ci/composite-actions.ts +30 -0
  116. package/scripts/ci/pr-classification.ts +3 -3
  117. package/scripts/claude/workflow-destination.ts +10 -1
  118. package/scripts/clone/clone-fingerprint.ts +0 -1
  119. package/scripts/clone/clone-scan-cli.ts +1 -1
  120. package/scripts/clone/clone-scan.ts +1 -1
  121. package/scripts/config-merge/json-format.ts +0 -1
  122. package/scripts/config-merge/patch-yaml-list.ts +1 -1
  123. package/scripts/cost-runtime/codex-usage.ts +2 -9
  124. package/scripts/cost-runtime/cost-attribute.ts +0 -1
  125. package/scripts/cost-runtime/cost-cli.ts +0 -3
  126. package/scripts/cost-runtime/cost-corpus.ts +0 -2
  127. package/scripts/cost-runtime/cost-format.ts +0 -3
  128. package/scripts/cost-runtime/cost-pricing.ts +0 -1
  129. package/scripts/cost-runtime/cost-tokens.ts +0 -1
  130. package/scripts/delegation/delegation-cli.ts +1 -1
  131. package/scripts/delegation/delegation-policy.ts +0 -1
  132. package/scripts/delegation/duplicate-read-guard.ts +0 -8
  133. package/scripts/delegation/fanout-cli.ts +1 -1
  134. package/scripts/delegation/fanout.ts +0 -2
  135. package/scripts/delegation/investigation-reads.ts +1 -164
  136. package/scripts/discovery/repo-map-logic.ts +0 -1
  137. package/scripts/discovery/repo-party-cli.ts +1 -1
  138. package/scripts/doctor/doctor-consumer.ts +4 -6
  139. package/scripts/doctor/doctor-logic.ts +0 -4
  140. package/scripts/doctor/doctor.ts +14 -9
  141. package/scripts/document/document-byte-budget.ts +4 -5
  142. package/scripts/document/document-byte-check.ts +0 -1
  143. package/scripts/document/document-read-cli.ts +0 -2
  144. package/scripts/document/document-section-cli.ts +1 -1
  145. package/scripts/document/document-section.ts +0 -3
  146. package/scripts/document/edit-files-cli.ts +0 -1
  147. package/scripts/document/entry-read-budget.ts +10 -2
  148. package/scripts/document/lane-child-read-set.ts +1 -6
  149. package/scripts/document/read-files-cli.ts +0 -4
  150. package/scripts/document/read-set-cli.ts +0 -2
  151. package/scripts/document/read-set-point-of-use.ts +1 -0
  152. package/scripts/document/read-set-pricing.ts +0 -1
  153. package/scripts/document/read-set-trim.ts +1 -1
  154. package/scripts/epic/epic-add.ts +1 -1
  155. package/scripts/epic/epic-audit-cli.ts +1 -4
  156. package/scripts/epic/epic-audit-orphans.ts +1 -3
  157. package/scripts/epic/epic-audit-rationale.ts +0 -1
  158. package/scripts/epic/epic-audit-report.ts +0 -2
  159. package/scripts/epic/epic-audit.ts +5 -4
  160. package/scripts/epic/epic-bundle-cli.ts +1 -1
  161. package/scripts/epic/epic-bundle-evidence.ts +0 -1
  162. package/scripts/epic/epic-bundle-referenced.ts +1 -5
  163. package/scripts/epic/epic-bundle.ts +0 -4
  164. package/scripts/epic/epic-busy.ts +4 -5
  165. package/scripts/epic/epic-candidate-confirm.ts +0 -5
  166. package/scripts/epic/epic-classify.ts +2 -2
  167. package/scripts/epic/epic-cli-argv.ts +0 -1
  168. package/scripts/epic/epic-close-comment.ts +1 -1
  169. package/scripts/epic/epic-close.ts +5 -2
  170. package/scripts/epic/epic-cross-repo.ts +2 -4
  171. package/scripts/epic/epic-decision.ts +0 -1
  172. package/scripts/epic/epic-fetch.ts +2 -2
  173. package/scripts/epic/epic-index.ts +2 -3
  174. package/scripts/epic/epic-issue.ts +1 -15
  175. package/scripts/epic/epic-lane-offer.ts +9 -8
  176. package/scripts/epic/epic-nested.ts +1 -1
  177. package/scripts/epic/epic-next-read.ts +1 -3
  178. package/scripts/epic/epic-next-views.ts +0 -1
  179. package/scripts/epic/epic-next.ts +1 -10
  180. package/scripts/epic/epic-parse.ts +0 -1
  181. package/scripts/epic/epic-promote.ts +0 -9
  182. package/scripts/epic/epic-rank.ts +2 -2
  183. package/scripts/epic/epic-read.ts +1 -2
  184. package/scripts/epic/epic-reconcile.ts +1 -1
  185. package/scripts/epic/epic-reference.ts +1 -13
  186. package/scripts/epic/epic-relation-recheck.ts +1 -1
  187. package/scripts/epic/epic-relations.ts +1 -1
  188. package/scripts/epic/epic-remove.ts +1 -1
  189. package/scripts/epic/epic-report.ts +0 -1
  190. package/scripts/epic/epic-run.ts +2 -3
  191. package/scripts/epic/epic-shape.ts +1 -1
  192. package/scripts/epic/epic-solo-stale.ts +107 -0
  193. package/scripts/epic/epic-solo.ts +3 -2
  194. package/scripts/epic/epic-triage.ts +1 -1
  195. package/scripts/epic/epic-validate.ts +1 -1
  196. package/scripts/epic/epic.ts +1 -1
  197. package/scripts/exports/unused-members-cli.ts +53 -0
  198. package/scripts/{git → followup}/followup-issue-number.ts +1 -6
  199. package/scripts/{git → followup}/git-followup-cleanup.ts +2 -1
  200. package/scripts/{git → followup}/git-followup-finish.ts +1 -3
  201. package/scripts/{git → followup}/git-followup-flush.ts +2 -2
  202. package/scripts/{git → followup}/git-followup-issue-close.ts +2 -2
  203. package/scripts/{git → followup}/git-followup-label.ts +4 -4
  204. package/scripts/followup/git-followup-merged.ts +112 -0
  205. package/scripts/{git → followup}/git-followup-pending.ts +1 -1
  206. package/scripts/{git → followup}/git-followup-workflow.ts +19 -11
  207. package/scripts/{git → followup}/git-pr-followup-wrapup.ts +9 -3
  208. package/scripts/{git → followup}/git-pr-followup.ts +53 -16
  209. package/scripts/gate/core-budget.ts +3 -9
  210. package/scripts/gate/gate-plan.ts +7 -4
  211. package/scripts/gate/gate-report.ts +0 -6
  212. package/scripts/gate/gate-tree.ts +1 -1
  213. package/scripts/gate/pre-commit-type-check.ts +0 -6
  214. package/scripts/gate/project-checks.ts +7 -8
  215. package/scripts/gate/scoped-green.ts +0 -1
  216. package/scripts/gate/type-check-step.ts +1 -1
  217. package/scripts/gate/verification-gate.ts +0 -2
  218. package/scripts/gh/fix-gh-packages.ts +15 -12
  219. package/scripts/gh/gh-spawn.ts +2 -2
  220. package/scripts/{git → gh}/git-ai-review-scan.ts +1 -5
  221. package/scripts/{git → gh}/git-gh-check.ts +2 -1
  222. package/scripts/{git → gh}/git-gh-exec.ts +1 -1
  223. package/scripts/{git → gh}/git-gh-failure.ts +1 -1
  224. package/scripts/{git → gh}/git-gh-helpers.ts +0 -1
  225. package/scripts/{git → gh}/git-gh-issue-list.ts +2 -0
  226. package/scripts/{git → gh}/git-gh-issue-read.ts +1 -1
  227. package/scripts/{git → gh}/git-gh-issue-rest.ts +6 -3
  228. package/scripts/{git → gh}/git-gh-pr-read.ts +24 -0
  229. package/scripts/{git → gh}/git-gh-pr-rest.ts +5 -2
  230. package/scripts/{git → gh}/git-gh-pr-review.ts +2 -2
  231. package/scripts/{git → gh}/git-gh-pr-rollup.ts +1 -3
  232. package/scripts/{git → gh}/git-gh-pr.ts +3 -1
  233. package/scripts/{git → gh}/git-pr-ai-review.ts +2 -5
  234. package/scripts/{git → gh}/git-pr-checks-eval.ts +0 -10
  235. package/scripts/{git → gh}/git-pr-checks-parse.ts +4 -20
  236. package/scripts/{git → gh}/git-pr-checks.ts +2 -1
  237. package/scripts/{git → gh}/git-pr-coderabbit.ts +2 -5
  238. package/scripts/{git → gh}/git-pr-confirmation.ts +1 -3
  239. package/scripts/{git → gh}/git-pr-managed-config.ts +2 -3
  240. package/scripts/{git → gh}/git-pr.ts +3 -3
  241. package/scripts/git/changed-file-scope.ts +0 -1
  242. package/scripts/git/git-branch.ts +3 -6
  243. package/scripts/git/git-commit.ts +1 -1
  244. package/scripts/git/git-common-directory.ts +80 -24
  245. package/scripts/git/git-error.ts +66 -9
  246. package/scripts/git/git-issue.ts +1 -1
  247. package/scripts/git/git-preflight.ts +2 -2
  248. package/scripts/git/git-prompt.ts +6 -31
  249. package/scripts/git/git-push.ts +1 -1
  250. package/scripts/git/git-staging.ts +1 -0
  251. package/scripts/git/git-status.ts +1 -1
  252. package/scripts/git/git-workflow.ts +1 -1
  253. package/scripts/git/gone-branch.ts +1 -0
  254. package/scripts/git/listing-cutoff.ts +1 -1
  255. package/scripts/git/main-merge.ts +1 -1
  256. package/scripts/git/main-sync.ts +19 -1
  257. package/scripts/git/parse-json-array.ts +0 -3
  258. package/scripts/git/repository-lock.ts +16 -16
  259. package/scripts/git/{git-stash.ts → stash/git-stash.ts} +1 -1
  260. package/scripts/git/{stash-pop-args.ts → stash/stash-pop-args.ts} +1 -1
  261. package/scripts/git/{stash-pop-cli.ts → stash/stash-pop-cli.ts} +0 -1
  262. package/scripts/git/{stash-sweep-lock.ts → stash/stash-sweep-lock.ts} +3 -3
  263. package/scripts/hooks/codex-hook-adapter.ts +0 -1
  264. package/scripts/hooks/edited-cspell.ts +1 -1
  265. package/scripts/hooks/format-edited-file.ts +2 -0
  266. package/scripts/hooks/pre-push-unit.ts +0 -4
  267. package/scripts/hooks/pretool-guard.ts +22 -4
  268. package/scripts/hooks/reserved-run.ts +1 -1
  269. package/scripts/hooks/step-zero-notice.ts +76 -0
  270. package/scripts/hooks/stop-guard.ts +47 -21
  271. package/scripts/init/claude-plugin-config.ts +4 -5
  272. package/scripts/init/hook-command-rewrite.ts +16 -8
  273. package/scripts/init/hook-launch.ts +41 -15
  274. package/scripts/init/init-basic.ts +2 -5
  275. package/scripts/init/init-logic.ts +7 -0
  276. package/scripts/init/init.ts +0 -3
  277. package/scripts/init/project-profile.ts +6 -11
  278. package/scripts/init/start-exec.ts +1 -1
  279. package/scripts/init/start-setup-pr.ts +6 -6
  280. package/scripts/init/start-steps.ts +1 -0
  281. package/scripts/issue/behavior-change-lint.ts +0 -1
  282. package/scripts/issue/defect-rate-cli.ts +3 -3
  283. package/scripts/issue/defect-rate.ts +1 -2
  284. package/scripts/{git → issue}/git-next-issues.ts +3 -3
  285. package/scripts/issue/issue-backlinks-cli.ts +1 -5
  286. package/scripts/issue/issue-cite-cli.ts +2 -6
  287. package/scripts/issue/issue-cite.ts +0 -2
  288. package/scripts/issue/issue-classification.ts +1 -9
  289. package/scripts/issue/issue-closing-pr.ts +4 -4
  290. package/scripts/issue/issue-comment-cli.ts +2 -2
  291. package/scripts/issue/issue-file-cli.ts +5 -5
  292. package/scripts/issue/issue-file.ts +2 -2
  293. package/scripts/issue/issue-fold-cli.ts +1 -1
  294. package/scripts/issue/issue-fold-existing-cli.ts +1 -1
  295. package/scripts/{git → issue}/issue-labels.ts +8 -0
  296. package/scripts/issue/issue-lint-cli.ts +1 -1
  297. package/scripts/issue/issue-merged.ts +2 -2
  298. package/scripts/{git → issue}/issue-rank.ts +1 -1
  299. package/scripts/issue/issue-read-cli.ts +8 -47
  300. package/scripts/issue/issue-read.ts +0 -2
  301. package/scripts/issue/issue-report-failures.ts +80 -0
  302. package/scripts/issue/issue-scout-cli.ts +1 -7
  303. package/scripts/issue/issue-scout-closed.ts +2 -2
  304. package/scripts/issue/issue-scout.ts +0 -2
  305. package/scripts/issue/issue-state-cli.ts +5 -46
  306. package/scripts/issue/issue-state.ts +1 -5
  307. package/scripts/issue/markdown-section.ts +1 -1
  308. package/scripts/issue/measure-rerun-cli.ts +1 -1
  309. package/scripts/issue/reproduction-measure.ts +1 -1
  310. package/scripts/josh/cli-body.ts +1 -1
  311. package/scripts/josh/file-map-stamp.ts +0 -3
  312. package/scripts/josh/josh-command-map.ts +2 -0
  313. package/scripts/josh/josh-commands-ai.ts +9 -102
  314. package/scripts/josh/josh-commands-backlog.ts +5 -1
  315. package/scripts/josh/josh-commands-development.ts +8 -1
  316. package/scripts/josh/josh-commands-issue.ts +2 -2
  317. package/scripts/josh/josh-commands-maintenance.ts +7 -0
  318. package/scripts/josh/josh-commands-project.ts +6 -0
  319. package/scripts/josh/josh-commands-run.ts +114 -0
  320. package/scripts/josh/josh-commands-versioning.ts +8 -0
  321. package/scripts/josh/josh-commands-workflow.ts +2 -2
  322. package/scripts/josh/path-decision.ts +0 -3
  323. package/scripts/josh/process-owner.ts +16 -0
  324. package/scripts/josh/session-language-cli.ts +0 -1
  325. package/scripts/lane/lane-await.ts +3 -6
  326. package/scripts/lane/lane-capacity.ts +6 -3
  327. package/scripts/lane/lane-child-invocation.ts +20 -7
  328. package/scripts/lane/lane-cli.ts +1 -4
  329. package/scripts/lane/lane-close.ts +1 -3
  330. package/scripts/lane/lane-dispatch.ts +3 -4
  331. package/scripts/lane/lane-environment.ts +0 -9
  332. package/scripts/lane/lane-handoff.ts +38 -0
  333. package/scripts/lane/lane-launch-cli.ts +21 -11
  334. package/scripts/lane/lane-open.ts +0 -3
  335. package/scripts/lane/lane-output.ts +0 -1
  336. package/scripts/lane/lane-registry.ts +9 -0
  337. package/scripts/lane/openai-lane-ship.ts +2 -0
  338. package/scripts/lane/openai-lane-supervisor-decision.ts +2 -1
  339. package/scripts/lane/openai-lane-supervisor.ts +6 -4
  340. package/scripts/lane/openai-review-broker.ts +3 -0
  341. package/scripts/lib/bounded-pool.ts +1 -0
  342. package/scripts/lib/json-value.ts +5 -4
  343. package/scripts/lib/poll.ts +3 -1
  344. package/scripts/lib/timed-fetch.ts +15 -0
  345. package/scripts/lib/timeouts.ts +13 -0
  346. package/scripts/{yaml → lib}/yaml-document.ts +3 -1
  347. package/scripts/{bytes → lines}/bytes-command.ts +0 -2
  348. package/scripts/lines/lines-command.ts +0 -1
  349. package/scripts/lint/lint-related-scope.ts +0 -1
  350. package/scripts/lint/lint-related.ts +1 -1
  351. package/scripts/{git → notify}/telegram-notify.ts +2 -2
  352. package/scripts/{git → notify}/telegram-test.ts +4 -4
  353. package/scripts/observations/observation-ledger-home.ts +0 -1
  354. package/scripts/observations/observation-ledger-line.ts +0 -1
  355. package/scripts/observations/observation-ledger-migrate.ts +1 -1
  356. package/scripts/observations/observations-flush-landing.ts +3 -3
  357. package/scripts/observations/observations-flush.ts +2 -2
  358. package/scripts/overrides/lockfile-overrides.ts +1 -1
  359. package/scripts/overrides/overrides-logic.ts +1 -1
  360. package/scripts/package/package-scout-cli.ts +2 -7
  361. package/scripts/package/package-scout.ts +0 -2
  362. package/scripts/propagate/propagate-git-failure.ts +0 -1
  363. package/scripts/propagate/propagate-git.ts +0 -2
  364. package/scripts/propagate/propagate-publish.ts +2 -3
  365. package/scripts/propagate/propagate-run.ts +0 -2
  366. package/scripts/propagate/propagate-steps.ts +3 -5
  367. package/scripts/propagate/propagate-targets.ts +0 -4
  368. package/scripts/propagate/propagate.ts +0 -4
  369. package/scripts/refactor/import-graph.ts +0 -1
  370. package/scripts/refactor/refactor-lint.ts +0 -2
  371. package/scripts/refactor/refactor-scan.ts +0 -1
  372. package/scripts/refactor/refactor-targets.ts +0 -1
  373. package/scripts/registry-migration/migrate-logic.ts +0 -2
  374. package/scripts/registry-migration/migrate.ts +19 -9
  375. package/scripts/release/github-release-cli.ts +8 -6
  376. package/scripts/release/github-release-environment.ts +46 -0
  377. package/scripts/release/github-release.ts +151 -94
  378. package/scripts/release/release-history.ts +0 -1
  379. package/scripts/release/release-plan.ts +0 -1
  380. package/scripts/release/release-publish.ts +2 -3
  381. package/scripts/release/release-scope-cli.ts +1 -2
  382. package/scripts/release/release-tag.ts +2 -4
  383. package/scripts/repo/auto-merge-setting-logic.ts +1 -4
  384. package/scripts/repo/repo-setting.ts +1 -1
  385. package/scripts/repo/repository-labels.ts +3 -3
  386. package/scripts/repo/required-checks-logic.ts +206 -0
  387. package/scripts/repo/required-checks-report.ts +71 -0
  388. package/scripts/repo/ruleset-check-cli.ts +53 -0
  389. package/scripts/repo/ruleset-check.ts +147 -0
  390. package/scripts/report/report-lint-cli.ts +0 -4
  391. package/scripts/review/disposition-cli.ts +1 -1
  392. package/scripts/review/live-evidence.ts +1 -1
  393. package/scripts/review/review-attest-cli.ts +0 -6
  394. package/scripts/review/review-attest.ts +4 -16
  395. package/scripts/review/review-brief-cli.ts +23 -6
  396. package/scripts/review/review-brief.ts +21 -8
  397. package/scripts/review/review-diff-parts.ts +89 -0
  398. package/scripts/review/review-diff-write.ts +97 -0
  399. package/scripts/review/review-finding-ledger.ts +0 -1
  400. package/scripts/review/review-record-cli.ts +1 -1
  401. package/scripts/review/review-record.ts +0 -1
  402. package/scripts/review/review-round2-cli.ts +1 -1
  403. package/scripts/review/review-stamps.ts +0 -3
  404. package/scripts/review/review-tree.ts +14 -2
  405. package/scripts/rules/decision-oracle-stage.ts +18 -0
  406. package/scripts/rules/decision-oracle.ts +10 -7
  407. package/scripts/rules/delivered-rules.ts +9 -1
  408. package/scripts/rules/destructive-command.ts +119 -0
  409. package/scripts/rules/direct-filing.ts +1 -1
  410. package/scripts/rules/file-body.ts +0 -3
  411. package/scripts/rules/filing-cap.ts +0 -2
  412. package/scripts/rules/gh-api.ts +7 -2
  413. package/scripts/rules/git-argv.ts +18 -7
  414. package/scripts/rules/git-force.ts +0 -2
  415. package/scripts/rules/implementation-cut.ts +0 -1
  416. package/scripts/rules/index-guard.ts +71 -0
  417. package/scripts/rules/issue-citation.ts +50 -25
  418. package/scripts/rules/lane-background.ts +15 -7
  419. package/scripts/rules/lane-park.ts +13 -6
  420. package/scripts/rules/last-prompt.ts +1 -0
  421. package/scripts/rules/oracle-consulted.ts +1 -1
  422. package/scripts/rules/oracle-firing.ts +1 -0
  423. package/scripts/rules/oracle-list-cli.ts +0 -3
  424. package/scripts/rules/permission-guards.ts +14 -0
  425. package/scripts/rules/protected-files.ts +74 -0
  426. package/scripts/rules/reply-language.ts +1 -1
  427. package/scripts/rules/rule-body-guard.ts +0 -3
  428. package/scripts/rules/rule-value-cli.ts +0 -1
  429. package/scripts/rules/shell-body-trigger.ts +0 -1
  430. package/scripts/rules/shell-segments.ts +0 -1
  431. package/scripts/rules/stop-rules.ts +13 -5
  432. package/scripts/rules/tail-commands.ts +1 -1
  433. package/scripts/rules/test-declared-commit.ts +1 -1
  434. package/scripts/rules/third-party-write.ts +0 -1
  435. package/scripts/rules/worktree-guard.ts +26 -9
  436. package/scripts/run/run-carry-cli.ts +0 -2
  437. package/scripts/run/run-carry-stash.ts +2 -2
  438. package/scripts/run/run-carry-streak.ts +1 -1
  439. package/scripts/run/run-cut-cli.ts +0 -7
  440. package/scripts/run/run-cut.ts +8 -54
  441. package/scripts/run/run-ending-cli.ts +1 -1
  442. package/scripts/run/run-ending.ts +1 -4
  443. package/scripts/run/run-entry-cli.ts +101 -24
  444. package/scripts/run/run-entry.ts +0 -1
  445. package/scripts/run/run-event-cli.ts +0 -2
  446. package/scripts/run/run-event-follow.ts +1 -0
  447. package/scripts/run/run-event-render.ts +1 -1
  448. package/scripts/run/run-event-scope.ts +53 -4
  449. package/scripts/run/run-event-stream.ts +0 -3
  450. package/scripts/run/run-event-watch.ts +1 -0
  451. package/scripts/run/run-halfrun-resume.ts +20 -7
  452. package/scripts/run/run-headless.ts +2 -2
  453. package/scripts/run/run-hold-cli.ts +33 -10
  454. package/scripts/run/run-hold.ts +25 -5
  455. package/scripts/run/run-issue-number.ts +1 -1
  456. package/scripts/run/run-liveness-cli.ts +1 -1
  457. package/scripts/run/run-liveness.ts +2 -3
  458. package/scripts/run/run-merge-cli.ts +5 -13
  459. package/scripts/run/run-merge-steps.ts +5 -5
  460. package/scripts/run/run-merge.ts +1 -1
  461. package/scripts/run/run-next-cli.ts +1 -1
  462. package/scripts/run/run-parent-cut-hook.ts +0 -1
  463. package/scripts/run/run-preflight.ts +2 -9
  464. package/scripts/run/run-prep-cli.ts +2 -2
  465. package/scripts/run/run-prep-locate.ts +1 -1
  466. package/scripts/run/run-progress-cli.ts +4 -7
  467. package/scripts/run/run-progress-clock.ts +6 -34
  468. package/scripts/run/run-progress-config.ts +0 -4
  469. package/scripts/run/run-progress-read.ts +1 -2
  470. package/scripts/run/run-progress.ts +1 -2
  471. package/scripts/run/run-prrun-resume.ts +117 -0
  472. package/scripts/run/run-report-cli.ts +1 -2
  473. package/scripts/run/run-report.ts +0 -1
  474. package/scripts/run/run-retrospective.ts +1 -1
  475. package/scripts/run/run-review-cli.ts +0 -3
  476. package/scripts/run/run-review-steps.ts +2 -0
  477. package/scripts/run/run-review.ts +0 -2
  478. package/scripts/run/run-ship-cli.ts +21 -3
  479. package/scripts/run/run-ship-detach.ts +1 -0
  480. package/scripts/run/run-ship-next.ts +106 -0
  481. package/scripts/run/run-ship-preflight.ts +1 -1
  482. package/scripts/run/run-ship-return.ts +8 -3
  483. package/scripts/run/run-ship-review-steps.ts +18 -4
  484. package/scripts/run/run-ship-review.ts +11 -0
  485. package/scripts/run/run-ship-scoped.ts +1 -0
  486. package/scripts/run/run-ship-steps.ts +1 -1
  487. package/scripts/run/run-ship.ts +0 -1
  488. package/scripts/run/run-stage-read.ts +62 -0
  489. package/scripts/run/run-stage.ts +160 -0
  490. package/scripts/run/run-status-cli.ts +1 -1
  491. package/scripts/run/run-step-cli.ts +21 -14
  492. package/scripts/run/run-step.ts +1 -1
  493. package/scripts/run/run-stop-notify.ts +1 -3
  494. package/scripts/run/run-stranded-cli.ts +0 -4
  495. package/scripts/run/run-stranded-detect.ts +2 -2
  496. package/scripts/run/run-tail-cli.ts +17 -11
  497. package/scripts/run/run-tail.ts +2 -0
  498. package/scripts/run/run-tidy-lanes.ts +2 -1
  499. package/scripts/run/run-tidy-stashes.ts +12 -12
  500. package/scripts/run/run-wake-cli.ts +2 -3
  501. package/scripts/run/run-wake-loop.ts +2 -2
  502. package/scripts/run/run-wake.ts +2 -4
  503. package/scripts/run/run-watcher-guard-cli.ts +0 -4
  504. package/scripts/run/run-watcher-guard.ts +9 -7
  505. package/scripts/run/run-watcher-hook.ts +1 -1
  506. package/scripts/safe-chain/ci-installer-pin.ts +11 -5
  507. package/scripts/safe-chain/project-config.ts +1 -1
  508. package/scripts/security/security-audit-provision-logic.ts +0 -1
  509. package/scripts/security/security-audit-provision.ts +3 -2
  510. package/scripts/security/security-audit.ts +0 -1
  511. package/scripts/security/security-updates-logic.ts +0 -1
  512. package/scripts/sonar/sonar-hotspots-cli.ts +10 -52
  513. package/scripts/sonar/sonar-hotspots.ts +0 -1
  514. package/scripts/sonar/sonar-new-code-cli.ts +150 -0
  515. package/scripts/sonar/sonar-new-code.ts +79 -0
  516. package/scripts/sonar/sonar-project.ts +97 -0
  517. package/scripts/split/split-assess-cli.ts +1 -1
  518. package/scripts/split/split-assess.ts +2 -5
  519. package/scripts/sync/managed-config-scope-cli.ts +1 -1
  520. package/scripts/sync/skill-migration.ts +0 -1
  521. package/scripts/sync/sync-hook-safety.ts +2 -3
  522. package/scripts/sync/sync.ts +1 -8
  523. package/scripts/sync/template-source-logic.ts +0 -1
  524. package/scripts/sync/workflow-pin-logic.ts +16 -28
  525. package/scripts/test/test-declared-logic.ts +0 -1
  526. package/scripts/test/test-declared.ts +0 -2
  527. package/scripts/test/test-red-commit.ts +2 -2
  528. package/scripts/test/test-red.ts +14 -7
  529. package/scripts/test/test-type-logic.ts +1 -1
  530. package/scripts/test/unit-worker-share.ts +7 -16
  531. package/scripts/time-runtime/time-batch-guard.ts +1 -2
  532. package/scripts/time-runtime/time-bundle-call.ts +0 -1
  533. package/scripts/time-runtime/time-bundles.ts +0 -4
  534. package/scripts/time-runtime/time-density-hook.ts +0 -2
  535. package/scripts/time-runtime/time-followup-stage.ts +1 -1
  536. package/scripts/time-runtime/time-format.ts +0 -73
  537. package/scripts/time-runtime/time-round-trips.ts +0 -4
  538. package/scripts/time-runtime/time-single-check.ts +1 -1
  539. package/scripts/time-runtime/time-spans.ts +1 -1
  540. package/scripts/time-runtime/time-transcript-line.ts +1 -2
  541. package/scripts/ui/ui-routes-cli.ts +0 -5
  542. package/scripts/ui/ui-routes.ts +0 -5
  543. package/scripts/version/effective-upstream.ts +2 -2
  544. package/scripts/version/latest-corepack.ts +7 -9
  545. package/scripts/version/latest-scope-cli.ts +0 -2
  546. package/scripts/version/latest-update.ts +0 -2
  547. package/scripts/version/npm-registry.ts +2 -2
  548. package/scripts/version/publishable-range-check.ts +1 -1
  549. package/scripts/version/release-hold.ts +0 -4
  550. package/scripts/version/running-binary.ts +2 -2
  551. package/scripts/version/version-check-logic.ts +0 -2
  552. package/scripts/version/version-remote.ts +3 -3
  553. package/scripts/version/version-targets.ts +4 -4
  554. package/templates/sonar-project.properties +28 -1
  555. package/templates/workflows/dependabot-auto-merge.yml +5 -3
  556. package/templates/workflows/github-release.yml +81 -0
  557. package/prompts/collaboration-workflow/cross-repo-epic.md +0 -5
  558. package/prompts/collaboration-workflow/epic-audit.md +0 -5
  559. package/prompts/collaboration-workflow/epic-bundle.md +0 -5
  560. package/scripts/init/plugin-install-hint.ts +0 -47
  561. package/scripts/version/parse-json.ts +0 -13
  562. /package/scripts/{git → followup}/git-followup-stages.ts +0 -0
  563. /package/scripts/{git → gh}/git-gh-api-path.ts +0 -0
  564. /package/scripts/{git → gh}/git-gh-command.ts +0 -0
  565. /package/scripts/{git → gh}/git-gh-issue-write.ts +0 -0
  566. /package/scripts/{git → gh}/git-gh-issue.ts +0 -0
  567. /package/scripts/{git → gh}/git-gh-pr-auto-merge.ts +0 -0
  568. /package/scripts/{git → gh}/git-gh-pr-snapshot.ts +0 -0
  569. /package/scripts/{git → gh}/git-gh-reachability.ts +0 -0
  570. /package/scripts/{git → gh}/git-gh-repo.ts +0 -0
  571. /package/scripts/{git → gh}/git-gh-rest-state.ts +0 -0
  572. /package/scripts/{git → gh}/git-pr-checks-watch.ts +0 -0
  573. /package/scripts/{git → gh}/git-pr-error.ts +0 -0
  574. /package/scripts/{git → gh}/git-pr-messages.ts +0 -0
  575. /package/scripts/{git → gh}/github-issue-url.ts +0 -0
  576. /package/scripts/git/{stash-orphans.ts → stash/stash-orphans.ts} +0 -0
  577. /package/scripts/{git → issue}/issue-reference.ts +0 -0
  578. /package/scripts/{git → lib}/animation-helpers.ts +0 -0
  579. /package/scripts/{git → lib}/git-animation.ts +0 -0
  580. /package/scripts/{git → notify}/git-notify.ts +0 -0
  581. /package/scripts/{git → notify}/telegram-test-logic.ts +0 -0
@@ -1,46 +1,102 @@
1
1
  import { execFileSync } from 'node:child_process'
2
2
  import { git_utilities } from './constants'
3
3
  import { git_command } from './git-command'
4
+ import { git_location_environment, GIT_LOCATION_VARIABLES } from './git-location-environment'
5
+
6
+ // The one synchronous read of a checkout's two git directories (joshuafolkken/kit#2986) — the same
7
+ // `GIT_DIRECTORY_ARGUMENTS` `git_command.git_directories` asks asynchronously, so the two spellings
8
+ // cannot name different directories. It had been run in three places with three timeouts and no
9
+ // memory of the answer, though a `PreToolUse` hook may ask it several times in one call.
4
10
 
5
11
  const OWN_GIT_DIRECTORY = 0
6
12
  const COMMON_GIT_DIRECTORY = 1
7
- const PROBE_TIMEOUT_MS = 2000
13
+ // The read runs inside `PreToolUse` hooks, which hold the tool call for as long as it takes;
14
+ // `rev-parse` takes no lock, so anything past a few seconds is a fault rather than slow work.
15
+ const PROBE_TIMEOUT_MS = 5000
16
+
17
+ // **Only an answer is remembered, never a failure** — a timeout or a directory that is not yet a
18
+ // repository is asked again next time. The key carries every input git resolves from: the directory
19
+ // asked about and, where the environment is inherited, the git location variables it holds.
20
+ const answers = new Map<string, ReadonlyArray<string>>()
8
21
 
9
- function read_directories(cwd: string): Array<string> {
10
- const git = git_utilities.get_git_command_for_spawn()
11
- const output = execFileSync(git, [...git_command.GIT_DIRECTORY_ARGUMENTS], {
12
- cwd,
13
- encoding: 'utf8',
14
- stdio: ['ignore', 'pipe', 'ignore'],
15
- timeout: PROBE_TIMEOUT_MS,
16
- })
22
+ // With an explicit `cwd`, the git location variables are cleared so that directory is what git answers
23
+ // for: a hook exports `GIT_DIR`, which beats `cwd` and would name the hook's checkout instead
24
+ // (joshuafolkken/kit#2515). Without one the environment is kept, so the read resolves the same
25
+ // checkout as the asynchronous `git_directories`.
26
+ function probe_environment(cwd: string | undefined): NodeJS.ProcessEnv {
27
+ if (cwd === undefined) return process.env
17
28
 
18
- return output.trim().split('\n')
29
+ return { ...process.env, ...git_location_environment.location_free_environment() }
19
30
  }
20
31
 
21
- function select_linked(directories: ReadonlyArray<string>): string | undefined {
22
- const own = directories[OWN_GIT_DIRECTORY]
23
- const common = directories[COMMON_GIT_DIRECTORY]
32
+ function cache_key(cwd: string | undefined): string {
33
+ if (cwd !== undefined) return `explicit\0${cwd}`
34
+
35
+ const locations = GIT_LOCATION_VARIABLES.map((name) => process.env[name] ?? '')
24
36
 
25
- return own !== undefined && common !== undefined && own !== common ? common : undefined
37
+ return ['inherited', process.cwd(), ...locations].join('\0')
26
38
  }
27
39
 
28
- function resolve(cwd: string): string | undefined {
40
+ // git's own diagnostics are discarded: a checkout it cannot describe is already the empty answer, and
41
+ // a hook that let `fatal: not a git repository` through would print it in front of a tool call. The
42
+ // binary is resolved through `git_utilities` exactly as `git-spawn.ts` resolves it and run with an
43
+ // argument array and no `shell`; both are internally controlled, never untrusted input.
44
+ function read_directories(cwd: string | undefined): ReadonlyArray<string> {
29
45
  try {
30
- return select_linked(read_directories(cwd))
46
+ const output = execFileSync(
47
+ git_utilities.get_git_command_for_spawn(),
48
+ [...git_command.GIT_DIRECTORY_ARGUMENTS],
49
+ {
50
+ cwd,
51
+ env: probe_environment(cwd),
52
+ encoding: 'utf8',
53
+ stdio: ['ignore', 'pipe', 'ignore'],
54
+ timeout: PROBE_TIMEOUT_MS,
55
+ },
56
+ ) // NOSONAR
57
+
58
+ return output.split('\n').filter((line) => line !== '')
31
59
  } catch {
32
- return undefined
60
+ return []
33
61
  }
34
62
  }
35
63
 
36
- function repository(cwd: string): string | undefined {
37
- try {
38
- return read_directories(cwd)[COMMON_GIT_DIRECTORY]
39
- } catch {
40
- return undefined
41
- }
64
+ // The work tree's own git directory, then the common one every work tree of the repository shares —
65
+ // or nothing, where git cannot describe the checkout.
66
+ function directories(cwd?: string): ReadonlyArray<string> {
67
+ const key = cache_key(cwd)
68
+ const known = answers.get(key)
69
+
70
+ if (known !== undefined) return known
71
+
72
+ const read = read_directories(cwd)
73
+
74
+ if (read.length > 0) answers.set(key, read)
75
+
76
+ return read
77
+ }
78
+
79
+ function own(cwd?: string): string | undefined {
80
+ return directories(cwd)[OWN_GIT_DIRECTORY]
81
+ }
82
+
83
+ function repository(cwd?: string): string | undefined {
84
+ return directories(cwd)[COMMON_GIT_DIRECTORY]
85
+ }
86
+
87
+ function select_linked(found: ReadonlyArray<string>): string | undefined {
88
+ const own_directory = found[OWN_GIT_DIRECTORY]
89
+ const common = found[COMMON_GIT_DIRECTORY]
90
+
91
+ return own_directory !== undefined && common !== undefined && own_directory !== common
92
+ ? common
93
+ : undefined
94
+ }
95
+
96
+ function resolve(cwd: string): string | undefined {
97
+ return select_linked(directories(cwd))
42
98
  }
43
99
 
44
- const git_common_directory = { repository, resolve, select_linked }
100
+ const git_common_directory = { directories, own, repository, resolve, select_linked }
45
101
 
46
102
  export { git_common_directory }
@@ -1,5 +1,5 @@
1
+ import { has_stderr_field } from '#scripts/gh/git-gh-exec'
1
2
  import { error_text } from '#scripts/lib/error-message'
2
- import { has_stderr_field } from './git-gh-exec'
3
3
 
4
4
  function get_stderr_from_error(cause: Error): string | undefined {
5
5
  if (!has_stderr_field(cause)) return undefined
@@ -42,7 +42,41 @@ function display_error_details(cause: unknown): void {
42
42
  console.error('💡 Details:', cause_message)
43
43
  }
44
44
 
45
- function handle(error: unknown): void {
45
+ const FAILURE_EXIT_CODE = 1
46
+ const OPERATION_CANCELLED_MESSAGE = '💡 Operation cancelled.'
47
+
48
+ // **A library refuses by throwing; only the CLI entry decides the exit code** (joshuafolkken/kit#2985).
49
+ // `process.exit()` from an imported module skips every `finally` above it (a lock release included)
50
+ // and truncates a piped stdout, so these modules throw a typed error instead, and `handle` — the catch
51
+ // at each entry — renders it and sets `process.exitCode`.
52
+ interface BranchMismatch {
53
+ current_branch: string
54
+ target_branch_name: string
55
+ }
56
+
57
+ class BranchMismatchError extends Error {
58
+ readonly current_branch: string
59
+ readonly target_branch_name: string
60
+
61
+ constructor(mismatch: BranchMismatch, options?: ErrorOptions) {
62
+ super(
63
+ `Branch mismatch: on ${mismatch.current_branch}, expected ${mismatch.target_branch_name}`,
64
+ options,
65
+ )
66
+ this.name = 'BranchMismatchError'
67
+ this.current_branch = mismatch.current_branch
68
+ this.target_branch_name = mismatch.target_branch_name
69
+ }
70
+ }
71
+
72
+ class OperationCancelledError extends Error {
73
+ constructor() {
74
+ super('Operation cancelled')
75
+ this.name = 'OperationCancelledError'
76
+ }
77
+ }
78
+
79
+ function display_failure(error: unknown): void {
46
80
  const error_message = error_text.message_of(error)
47
81
 
48
82
  console.error('')
@@ -53,23 +87,46 @@ function handle(error: unknown): void {
53
87
  }
54
88
 
55
89
  console.error('')
56
- process.exit(1)
57
90
  }
58
91
 
59
- function display_branch_mismatch_error(current_branch: string, target_branch_name: string): void {
92
+ function display_branch_mismatch(error: BranchMismatchError): void {
60
93
  console.error('')
61
94
  console.error('❌ Branch mismatch detected')
62
95
  console.error('')
63
- console.error(`Current branch: ${current_branch}`)
64
- console.error(`Expected branch: ${target_branch_name}`)
96
+ console.error(`Current branch: ${error.current_branch}`)
97
+ console.error(`Expected branch: ${error.target_branch_name}`)
65
98
  console.error('')
66
99
  console.error('💡 Please update main branch to the latest and try again.')
67
- process.exit(1)
100
+ }
101
+
102
+ function display_cancelled(): void {
103
+ console.info(OPERATION_CANCELLED_MESSAGE)
104
+ console.info('')
105
+ }
106
+
107
+ function display(error: unknown): void {
108
+ if (error instanceof BranchMismatchError) {
109
+ display_branch_mismatch(error)
110
+
111
+ return
112
+ }
113
+
114
+ if (error instanceof OperationCancelledError) {
115
+ display_cancelled()
116
+
117
+ return
118
+ }
119
+
120
+ display_failure(error)
121
+ }
122
+
123
+ function handle(error: unknown): void {
124
+ display(error)
125
+ process.exitCode = FAILURE_EXIT_CODE
68
126
  }
69
127
 
70
128
  const git_error = {
71
129
  handle,
72
- display_branch_mismatch_error,
73
130
  }
74
131
 
75
- export { git_error }
132
+ export { git_error, BranchMismatchError, OperationCancelledError }
@@ -1,6 +1,6 @@
1
+ import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
1
2
  import { lane_paths } from '#scripts/lane/lane-paths'
2
3
  import { SEPARATOR_LINE } from './constants'
3
- import { git_gh_issue_read } from './git-gh-issue-read'
4
4
  import { git_prompt } from './git-prompt'
5
5
 
6
6
  interface IssueInfo {
@@ -1,11 +1,11 @@
1
+ import { git_gh_command } from '#scripts/gh/git-gh-command'
2
+ import { git_pr } from '#scripts/gh/git-pr'
1
3
  import { error_text } from '#scripts/lib/error-message'
2
4
  import { live_evidence } from '#scripts/review/live-evidence'
3
5
  import { changed_paths } from './changed-paths'
4
6
  import { git_branch } from './git-branch'
5
7
  import { git_command } from './git-command'
6
- import { git_gh_command } from './git-gh-command'
7
8
  import { git_issue, type IssueInfo } from './git-issue'
8
- import { git_pr } from './git-pr'
9
9
 
10
10
  // joshuafolkken/kit#2817. A first `josh git -y` was refused once per unmet precondition — the title's
11
11
  // issue number, the branch name, the issue's release classification — each only after the stage
@@ -1,9 +1,8 @@
1
1
  import { stdin as input, stdout as output } from 'node:process'
2
2
  import { createInterface, type Interface } from 'node:readline/promises'
3
+ import { OperationCancelledError } from './git-error'
3
4
  import { git_prompt_display } from './git-prompt-display'
4
5
 
5
- const OPERATION_CANCELLED_MESSAGE = '💡 Operation cancelled.'
6
-
7
6
  const PROMPT_MESSAGES = {
8
7
  unstaged_files: '💬 Unstaged files found. Continue anyway? (y/n): ',
9
8
  package_json_not_staged: '💬 package.json is not staged. Continue anyway? (y/n): ',
@@ -85,16 +84,10 @@ async function with_prompt<T>(callback: PromptCallback<T>, fallback_value?: T):
85
84
  }
86
85
  }
87
86
 
88
- async function confirm_with_exit_on_cancel(should_continue: () => Promise<boolean>): Promise<void> {
87
+ async function confirm_or_cancel(should_continue: () => Promise<boolean>): Promise<void> {
89
88
  const is_confirmed = await should_continue()
90
89
 
91
- if (is_confirmed) {
92
- return
93
- }
94
-
95
- console.info(OPERATION_CANCELLED_MESSAGE)
96
- console.info('')
97
- process.exit(1)
90
+ if (!is_confirmed) throw new OperationCancelledError()
98
91
  }
99
92
 
100
93
  function create_confirm_function(message: string): () => Promise<boolean> {
@@ -112,11 +105,11 @@ async function confirm_without_package_json(): Promise<boolean> {
112
105
  }
113
106
 
114
107
  async function confirm_unstaged_files(): Promise<void> {
115
- await confirm_with_exit_on_cancel(confirm_continue)
108
+ await confirm_or_cancel(confirm_continue)
116
109
  }
117
110
 
118
111
  async function confirm_missing_package_json(): Promise<void> {
119
- await confirm_with_exit_on_cancel(confirm_without_package_json)
112
+ await confirm_or_cancel(confirm_without_package_json)
120
113
  }
121
114
 
122
115
  async function confirm_version_not_updated(): Promise<boolean> {
@@ -124,19 +117,7 @@ async function confirm_version_not_updated(): Promise<boolean> {
124
117
  }
125
118
 
126
119
  async function confirm_without_version_update(): Promise<void> {
127
- await confirm_with_exit_on_cancel(confirm_version_not_updated)
128
- }
129
-
130
- async function confirm_commit(): Promise<boolean> {
131
- return await create_confirm_function(PROMPT_MESSAGES.commit)()
132
- }
133
-
134
- async function confirm_push(): Promise<boolean> {
135
- return await create_confirm_function(PROMPT_MESSAGES.push)()
136
- }
137
-
138
- async function confirm_pr(): Promise<boolean> {
139
- return await create_confirm_function(PROMPT_MESSAGES.pr)()
120
+ await confirm_or_cancel(confirm_version_not_updated)
140
121
  }
141
122
 
142
123
  async function ask_issue_info(prompt: Interface, question: string): Promise<string> {
@@ -190,15 +171,9 @@ async function confirm_workflow_steps(): Promise<WorkflowConfirmations> {
190
171
  }
191
172
 
192
173
  const git_prompt = {
193
- confirm_continue,
194
174
  confirm_unstaged_files,
195
- confirm_without_package_json,
196
175
  confirm_missing_package_json,
197
- confirm_version_not_updated,
198
176
  confirm_without_version_update,
199
- confirm_commit,
200
- confirm_push,
201
- confirm_pr,
202
177
  get_issue_info,
203
178
  confirm_workflow_steps,
204
179
  }
@@ -1,4 +1,4 @@
1
- import { animation_helpers, create_git_operation_config } from './animation-helpers'
1
+ import { animation_helpers, create_git_operation_config } from '#scripts/lib/animation-helpers'
2
2
  import { git_command } from './git-command'
3
3
 
4
4
  async function push(): Promise<void> {
@@ -62,6 +62,7 @@ async function stage_untracked_files(files: ReadonlyArray<string>): Promise<void
62
62
  if (files.length === 0) return
63
63
 
64
64
  for (const file of files) {
65
+ // eslint-disable-next-line no-await-in-loop -- git add holds the index lock, so two at once fail
65
66
  await git_command.add_path(file)
66
67
  }
67
68
 
@@ -1,4 +1,4 @@
1
- import { animation_helpers, type AnimationOptions } from './animation-helpers'
1
+ import { animation_helpers, type AnimationOptions } from '#scripts/lib/animation-helpers'
2
2
  import { REQUIRED_STATUS_LENGTH, STAGED_STATUS_INDEX, UNTRACKED_FILE_PREFIX } from './constants'
3
3
  import { git_command } from './git-command'
4
4
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { parseArgs } from 'node:util'
3
+ import { git_pr } from '#scripts/gh/git-pr'
3
4
  import { cli_body } from '#scripts/josh/cli-body'
4
5
  import { test_red_commit } from '#scripts/test/test-red-commit'
5
6
  import { git_branch } from './git-branch'
6
7
  import { git_commit } from './git-commit'
7
8
  import { git_error } from './git-error'
8
9
  import { git_issue, type IssueInfo } from './git-issue'
9
- import { git_pr } from './git-pr'
10
10
  import { git_preflight } from './git-preflight'
11
11
  import { git_prompt, type WorkflowConfirmations } from './git-prompt'
12
12
  import { git_push } from './git-push'
@@ -89,6 +89,7 @@ async function delete_each(names: ReadonlyArray<string>): Promise<PruneResult> {
89
89
 
90
90
  for (const name of names) {
91
91
  try {
92
+ // eslint-disable-next-line no-await-in-loop -- branch deletions write the same refs, one at a time
92
93
  await git_spawn.read(['branch', '-d', name])
93
94
  result.deleted.push(name)
94
95
  } catch {
@@ -1,4 +1,4 @@
1
- import { MAX_SCANNED } from './git-gh-issue-list'
1
+ import { MAX_SCANNED } from '#scripts/gh/git-gh-issue-list'
2
2
 
3
3
  // Why an open-issue listing stopped short of the end of the backlog, or that it did not
4
4
  // (joshuafolkken/kit#1067).
@@ -114,7 +114,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
114
114
  process.exitCode = await run(argv)
115
115
  }
116
116
 
117
- const main_merge = { COMMAND_NAME, main, run }
117
+ const main_merge = { run }
118
118
 
119
119
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
120
120
 
@@ -70,9 +70,27 @@ async function prune_quietly(default_branch: string): Promise<void> {
70
70
  }
71
71
  }
72
72
 
73
+ // **The local default branch is fast-forwarded before it is checked out** (joshuafolkken/kit#2979).
74
+ // A run's ledger file is committed on its feature branch and merged; a line appended afterwards leaves
75
+ // it dirty, and git refuses to check out a stale default branch that lacks the file — so `run:tail`'s
76
+ // sync failed exactly when the flush after it had work. Once fast-forwarded, the default branch holds
77
+ // the committed file and the checkout carries the dirty lines over (the same step the flush takes,
78
+ // joshuafolkken/kit#2462). Skipped on the default branch, where `fetch` refuses to update the checked-out
79
+ // ref; a refusal elsewhere — a local default ahead of origin — is left to the checkout and pull to judge.
80
+ async function fast_forward_quietly(default_branch: string): Promise<void> {
81
+ if ((await git_command.branch()) === default_branch) return
82
+
83
+ try {
84
+ await git_command.fast_forward_local(default_branch)
85
+ } catch {
86
+ // The checkout and `pull --ff-only` below decide, exactly as before this step existed.
87
+ }
88
+ }
89
+
73
90
  async function synchronize(): Promise<number> {
74
91
  const default_branch = await git_command.get_default_branch()
75
92
 
93
+ await fast_forward_quietly(default_branch)
76
94
  await git_command.checkout(default_branch)
77
95
  await git_command.pull_fast_forward()
78
96
  await prune_quietly(default_branch)
@@ -115,7 +133,7 @@ async function main(argv: ReadonlyArray<string>): Promise<void> {
115
133
  process.exitCode = await run(argv)
116
134
  }
117
135
 
118
- const main_sync = { COMMAND_NAME, LANE_REFUSAL, main, run }
136
+ const main_sync = { run }
119
137
 
120
138
  if (process.argv[1] === fileURLToPath(import.meta.url)) await main(process.argv.slice(ARGV_OFFSET))
121
139
 
@@ -87,10 +87,7 @@ function parse_json_object_safe<T>(raw_json: string, schema: z.ZodType<T>): T |
87
87
  }
88
88
 
89
89
  const parse_json = {
90
- parse_json_array_safe,
91
- parse_json_array_or_undefined,
92
90
  parse_json_object_safe,
93
- read_json_listing,
94
91
  }
95
92
 
96
93
  export {
@@ -2,7 +2,9 @@ import { randomUUID } from 'node:crypto'
2
2
  import { linkSync, renameSync, rmSync } from 'node:fs'
3
3
  import { setTimeout as sleep } from 'node:timers/promises'
4
4
  import { process_identity } from '#scripts/josh/process-identity'
5
+ import { process_owner_schema, type ProcessOwner } from '#scripts/josh/process-owner'
5
6
  import { stamp_file } from '#scripts/josh/stamp-file'
7
+ import { json_value } from '#scripts/lib/json-value'
6
8
  import { git_common_directory } from './git-common-directory'
7
9
 
8
10
  // One holder at a time per repository, for work that every work tree of that repository shares
@@ -14,32 +16,29 @@ import { git_common_directory } from './git-common-directory'
14
16
 
15
17
  const POLL_INTERVAL_MS = 200
16
18
 
17
- interface LockOwner {
18
- pid: number
19
- process_start?: string
20
- }
21
-
22
- type IsGone = (owner: LockOwner) => boolean
19
+ type IsGone = (owner: ProcessOwner) => boolean
23
20
 
24
- function lock_path(prefix: string, cwd: string = process.cwd()): string {
25
- return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd)
21
+ // Without a `cwd` the read keeps the inherited git location variables, as every other git call of the
22
+ // running process does; an explicit `cwd` clears them so that directory is the one answered for.
23
+ function lock_path(prefix: string, cwd?: string): string {
24
+ return stamp_file.stamp_path(prefix, git_common_directory.repository(cwd) ?? cwd ?? process.cwd())
26
25
  }
27
26
 
28
- function parse_owner(raw: string | undefined): LockOwner | undefined {
27
+ // A record that is not JSON, or is JSON of any other shape — `null`, an array, an object with no
28
+ // numeric `pid` — is unreadable rather than an owner, so it is never judged and never cleared.
29
+ function parse_owner(raw: string | undefined): ProcessOwner | undefined {
29
30
  if (raw === undefined) return undefined
30
31
 
31
- try {
32
- return JSON.parse(raw) as LockOwner
33
- } catch {
34
- return undefined
35
- }
32
+ const parsed = process_owner_schema.safeParse(json_value.parse_or_undefined(raw))
33
+
34
+ return parsed.success ? parsed.data : undefined
36
35
  }
37
36
 
38
- function read_owner(target: string): LockOwner | undefined {
37
+ function read_owner(target: string): ProcessOwner | undefined {
39
38
  return parse_owner(stamp_file.read_stamp_text(target))
40
39
  }
41
40
 
42
- function is_owner_gone(owner: LockOwner): boolean {
41
+ function is_owner_gone(owner: ProcessOwner): boolean {
43
42
  return process_identity.is_same_process(owner.pid, owner.process_start) === false
44
43
  }
45
44
 
@@ -111,6 +110,7 @@ async function acquire(target: string, max_wait_ms: number): Promise<boolean> {
111
110
 
112
111
  while (!claim(target)) {
113
112
  if (Date.now() >= deadline) return false
113
+ // eslint-disable-next-line no-await-in-loop -- polling: each read waits on the state the previous one saw
114
114
  await sleep(POLL_INTERVAL_MS)
115
115
  }
116
116
 
@@ -1,4 +1,4 @@
1
- import { git_spawn } from './git-spawn'
1
+ import { git_spawn } from '#scripts/git/git-spawn'
2
2
 
3
3
  // The one place a sanctioned `git stash pop` is targeted by its message rather than its stack
4
4
  // position (joshuafolkken/kit#2050). The stash is a single repository-wide stack shared by every
@@ -47,7 +47,7 @@ function to_request(parsed: ParsedValues): Request | undefined {
47
47
  return { message, dir: parsed.values.dir }
48
48
  }
49
49
 
50
- const stash_pop_args = { USAGE, message_of, read_arguments, to_request }
50
+ const stash_pop_args = { USAGE, read_arguments, to_request }
51
51
 
52
52
  export type { Request }
53
53
  export { stash_pop_args }
@@ -97,7 +97,6 @@ const stash_pop_cli = {
97
97
  CONFLICTED_VERDICT,
98
98
  NO_MATCH_VERDICT,
99
99
  POPPED_VERDICT,
100
- main,
101
100
  run,
102
101
  }
103
102
 
@@ -1,4 +1,4 @@
1
- import { repository_lock } from './repository-lock'
1
+ import { repository_lock } from '#scripts/git/repository-lock'
2
2
 
3
3
  // One stash sweep at a time per repository (joshuafolkken/kit#2701). The stash is a single stack every
4
4
  // work tree shares, and a `backlogrun` runs one sweep per lane seat at once: two sweeps that each
@@ -11,7 +11,7 @@ const LOCK_PREFIX = 'josh-stash-sweep-lock-'
11
11
  // wait; the cap only bounds a holder that hung, and a sweep that gives up keeps its entries.
12
12
  const MAX_WAIT_MS = 30_000
13
13
 
14
- function lock_path(cwd: string = process.cwd()): string {
14
+ function lock_path(cwd?: string): string {
15
15
  return repository_lock.lock_path(LOCK_PREFIX, cwd)
16
16
  }
17
17
 
@@ -25,6 +25,6 @@ async function with_lock<T>(
25
25
  return await repository_lock.with_lock(work, target, max_wait_ms)
26
26
  }
27
27
 
28
- const stash_sweep_lock = { clear_stale: repository_lock.clear_stale, lock_path, with_lock }
28
+ const stash_sweep_lock = { clear_stale: repository_lock.clear_stale, with_lock }
29
29
 
30
30
  export { stash_sweep_lock }
@@ -146,7 +146,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
146
146
 
147
147
  const codex_hook_adapter = {
148
148
  format_posttool_payloads,
149
- patch_paths,
150
149
  posttool_payloads,
151
150
  pretool_outcome,
152
151
  pretool_payload,
@@ -122,7 +122,7 @@ async function spelling_diagnostics(
122
122
  }
123
123
  }
124
124
 
125
- const edited_cspell = { format_unknown_words, is_checkable, spelling_diagnostics }
125
+ const edited_cspell = { format_unknown_words, spelling_diagnostics }
126
126
 
127
127
  export type { CspellRunner }
128
128
  export { edited_cspell, MAX_DIAGNOSTIC_CHARS }
@@ -327,6 +327,7 @@ async function run_command(command: FormatCommand, project_root: string): Promis
327
327
  let outcome: CommandOutcome = { exit_code: 0, stdout: '' }
328
328
 
329
329
  for (const invocation of resolve_invocations(command, project_root)) {
330
+ // eslint-disable-next-line no-await-in-loop -- a fallback route runs only when the previous one failed to start
330
331
  outcome = await spawn_invocation(invocation, project_root)
331
332
  if (!is_start_failure(outcome)) return outcome
332
333
  }
@@ -374,6 +375,7 @@ async function collect_unfixed(
374
375
 
375
376
  for (const command of plan) {
376
377
  try {
378
+ // eslint-disable-next-line no-await-in-loop -- formatters rewrite the same file, in plan order
377
379
  unfixed = eslint_unfixed(command, await runner(command, project_root)) ?? unfixed
378
380
  } catch {
379
381
  // One formatter failing to start is not a reason to skip the next: prettier runs last, and
@@ -136,10 +136,6 @@ if (process.argv[1] === fileURLToPath(import.meta.url)) {
136
136
 
137
137
  const pre_push_unit = {
138
138
  FORCE_ENV,
139
- format_skip,
140
- forwarded_arguments,
141
- read_push_tree,
142
- reusable_green_push,
143
139
  run_pre_push_unit,
144
140
  }
145
141