@joshuafolkken/kit 1.1010.0 → 1.1050.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 (350) hide show
  1. package/.claude/settings.json +1 -5
  2. package/.claude/skills/dependency-update/SKILL.md +6 -3
  3. package/.claude/skills/epic-commands/SKILL.md +46 -17
  4. package/.claude/skills/verify-ui/SKILL.md +1 -1
  5. package/.claude/skills/workflow-commands/SKILL.md +10 -25
  6. package/.claude/skills/workflow-commands/background-commands.md +1 -1
  7. package/.claude/skills/workflow-commands/backlogrun-child.md +6 -4
  8. package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
  9. package/.claude/skills/workflow-commands/backlogrun-park.md +6 -0
  10. package/.claude/skills/workflow-commands/backlogrun-progress.md +30 -36
  11. package/.claude/skills/workflow-commands/backlogrun-steps.md +16 -16
  12. package/.claude/skills/workflow-commands/backlogrun.md +3 -12
  13. package/.claude/skills/workflow-commands/chain-rule.md +2 -2
  14. package/.claude/skills/workflow-commands/followup-reference.md +2 -2
  15. package/.claude/skills/workflow-commands/fullrun-steps.md +4 -3
  16. package/.claude/skills/workflow-commands/fullrun.md +1 -1
  17. package/.claude/skills/workflow-commands/halfrun.md +2 -1
  18. package/.claude/skills/workflow-commands/into-target.md +1 -1
  19. package/.claude/skills/workflow-commands/issue-comments.md +1 -1
  20. package/.claude/skills/workflow-commands/observation-filing.md +80 -126
  21. package/.claude/skills/workflow-commands/pre-gate-cut.md +33 -36
  22. package/.claude/skills/workflow-commands/prerequisite.md +1 -1
  23. package/.claude/skills/workflow-commands/working-tree-hold.md +2 -2
  24. package/.codex/hooks.json +1 -5
  25. package/.github/workflows/auto-tag.yml +21 -0
  26. package/.github/workflows/publish.yml +9 -10
  27. package/.github/workflows/sonar-qube.yml +1 -1
  28. package/AGENTS.md +4 -25
  29. package/CLAUDE.md +24 -38
  30. package/GEMINI.md +4 -24
  31. package/README.md +22 -56
  32. package/dist/CLAUDE.md +24 -38
  33. package/dist/hooks/batch-guard.js +4 -4
  34. package/dist/hooks/{chunk-6PSTVOLH.js → chunk-5BK3K7V4.js} +114 -90
  35. package/dist/hooks/{chunk-PAXMLGSS.js → chunk-7VPDUBRN.js} +93 -175
  36. package/dist/hooks/{chunk-KPZN42RT.js → chunk-DMQN45FN.js} +3 -3
  37. package/dist/hooks/{chunk-WMIR5SNX.js → chunk-EJDX2TOB.js} +13 -3
  38. package/dist/hooks/{chunk-A2H5I2VD.js → chunk-GQ7KP45M.js} +2 -2
  39. package/dist/hooks/{chunk-4GDR2YTV.js → chunk-HJIISEAC.js} +4 -4
  40. package/dist/hooks/{chunk-AWTFKKFW.js → chunk-NAS4C7GP.js} +6 -33
  41. package/dist/hooks/{chunk-56LGMJJV.js → chunk-NJQOBE6L.js} +2 -2
  42. package/dist/hooks/{chunk-EZLHXKJ6.js → chunk-RLDX5SOC.js} +1222 -941
  43. package/dist/hooks/{chunk-GBJUERYK.js → chunk-WQ4OSBSS.js} +10 -3
  44. package/dist/hooks/codex-hook-adapter.js +10 -10
  45. package/dist/hooks/duplicate-read-guard.js +5 -5
  46. package/dist/hooks/format-edited.js +15 -34
  47. package/dist/hooks/investigation-guard.js +5 -5
  48. package/dist/hooks/pretool-guard.js +23 -16
  49. package/dist/hooks/stop-guard.js +21 -200
  50. package/dist/josh.js +42 -125
  51. package/dist/version/index.js +466 -42
  52. package/eslint/base.js +2 -11
  53. package/package.json +36 -10
  54. package/prompts/coding-standards.md +15 -290
  55. package/prompts/collaboration-workflow/cross-repo-epic.md +2 -51
  56. package/prompts/collaboration-workflow/epic-audit.md +2 -53
  57. package/prompts/collaboration-workflow/epic-bundle.md +2 -106
  58. package/prompts/collaboration-workflow/file-edits.md +6 -53
  59. package/prompts/collaboration-workflow/issue-template.md +4 -4
  60. package/prompts/collaboration-workflow/operating-rules.md +18 -75
  61. package/prompts/collaboration-workflow/principles.md +74 -0
  62. package/prompts/collaboration-workflow/residency.md +55 -15
  63. package/prompts/collaboration-workflow/rule-delivery.md +5 -46
  64. package/prompts/collaboration-workflow/shell-body.md +7 -9
  65. package/prompts/collaboration-workflow/turn-batching.md +21 -37
  66. package/prompts/collaboration-workflow/upstream-interrupt.md +1 -1
  67. package/prompts/collaboration-workflow/wip-cap.md +15 -18
  68. package/prompts/collaboration-workflow.md +22 -28
  69. package/prompts/sonar-hotspot-handling.md +1 -1
  70. package/scripts/adopt/adopt-logic.ts +2 -2
  71. package/scripts/adopt/adopt-toolkits.ts +3 -1
  72. package/scripts/adopt/adopt.ts +2 -2
  73. package/scripts/agent/agent-event.ts +2 -9
  74. package/scripts/agent/agent-exit-record.ts +2 -9
  75. package/scripts/auto-ok/auto-ok-cli.ts +9 -9
  76. package/scripts/backlog/backlog-budget-cli.ts +2 -6
  77. package/scripts/backlog/backlog-drive-cli.ts +20 -10
  78. package/scripts/backlog/backlog-drive.ts +50 -16
  79. package/scripts/backlog/backlog-next.ts +24 -8
  80. package/scripts/backlog/backlog-offer-cli.ts +6 -5
  81. package/scripts/backlog/backlog-plan-cli.ts +5 -1
  82. package/scripts/backlog/backlog-plan.ts +1 -1
  83. package/scripts/backlog/backlog-pool.ts +31 -11
  84. package/scripts/backlog/backlog-rank.ts +106 -0
  85. package/scripts/backlog/backlog-waves.ts +42 -29
  86. package/scripts/build/build-bin.ts +2 -1
  87. package/scripts/build/build-config-merge.ts +2 -1
  88. package/scripts/build/build-hooks.ts +31 -6
  89. package/scripts/build/build-managed-marker.ts +2 -1
  90. package/scripts/build/build-self-sync-guard.ts +2 -1
  91. package/scripts/build/build-version.ts +2 -1
  92. package/scripts/cases/cases-logic.ts +2 -6
  93. package/scripts/ci/pr-classification.ts +13 -11
  94. package/scripts/cost-runtime/cost-transcript.ts +4 -11
  95. package/scripts/delegation/delegation-policy.ts +11 -0
  96. package/scripts/doctor/doctor-consumer.ts +5 -12
  97. package/scripts/doctor/doctor-ports.ts +2 -2
  98. package/scripts/document/document-byte-budget.ts +13 -21
  99. package/scripts/document/document-section.ts +2 -6
  100. package/scripts/document/entry-read-budget.ts +6 -5
  101. package/scripts/{git/git-epic-add-body.ts → epic/epic-add-body.ts} +23 -23
  102. package/scripts/{git/git-epic-add-plan.ts → epic/epic-add-plan.ts} +23 -26
  103. package/scripts/{git/git-epic-add.ts → epic/epic-add.ts} +17 -17
  104. package/scripts/epic/epic-audit-cli.ts +4 -4
  105. package/scripts/epic/epic-audit-orphans.ts +2 -2
  106. package/scripts/epic/epic-audit-rationale.ts +1 -1
  107. package/scripts/epic/epic-audit.ts +1 -1
  108. package/scripts/{git/git-epic-body.ts → epic/epic-body.ts} +6 -6
  109. package/scripts/epic/epic-bundle-cli.ts +1 -1
  110. package/scripts/epic/epic-bundle.ts +2 -2
  111. package/scripts/epic/epic-candidate-confirm.ts +2 -1
  112. package/scripts/{git/git-epic-chains.ts → epic/epic-chains.ts} +4 -4
  113. package/{scripts-ai → scripts/epic}/epic-check.ts +5 -4
  114. package/{scripts-ai → scripts/epic}/epic-cli.ts +4 -4
  115. package/scripts/{git/git-epic-close-comment.ts → epic/epic-close-comment.ts} +9 -9
  116. package/scripts/{git/git-epic-close.ts → epic/epic-close.ts} +23 -19
  117. package/scripts/epic/epic-cross-repo.ts +21 -38
  118. package/scripts/{git/git-epic-decision.ts → epic/epic-decision.ts} +12 -14
  119. package/scripts/epic/epic-fetch.ts +3 -3
  120. package/scripts/epic/epic-graph.ts +3 -3
  121. package/scripts/epic/epic-index.ts +2 -2
  122. package/scripts/epic/epic-issue.ts +1 -1
  123. package/scripts/epic/epic-lane-offer.ts +11 -22
  124. package/scripts/epic/epic-next.ts +3 -3
  125. package/scripts/{git/git-epic-parse.ts → epic/epic-parse.ts} +3 -3
  126. package/scripts/{git/git-epic-promote.ts → epic/epic-promote.ts} +10 -10
  127. package/scripts/epic/epic-rank.ts +37 -0
  128. package/scripts/{git/git-epic-read.ts → epic/epic-read.ts} +9 -9
  129. package/scripts/{git/git-epic-reconcile.ts → epic/epic-reconcile.ts} +18 -20
  130. package/scripts/{git/git-epic-reference.ts → epic/epic-reference.ts} +4 -23
  131. package/scripts/epic/epic-relation-recheck.ts +4 -3
  132. package/scripts/{git/git-epic-relations.ts → epic/epic-relations.ts} +5 -5
  133. package/scripts/{git/git-epic-remove-plan.ts → epic/epic-remove-plan.ts} +17 -19
  134. package/scripts/{git/git-epic-remove.ts → epic/epic-remove.ts} +13 -13
  135. package/scripts/{git/git-epic-run.ts → epic/epic-run.ts} +27 -27
  136. package/scripts/{git/git-epic-sections.ts → epic/epic-sections.ts} +6 -6
  137. package/scripts/{git/git-epic-shape.ts → epic/epic-shape.ts} +7 -7
  138. package/scripts/epic/epic-solo.ts +29 -28
  139. package/scripts/{git/git-epic-validate.ts → epic/epic-validate.ts} +13 -13
  140. package/{scripts-ai → scripts/epic}/epic.ts +17 -16
  141. package/scripts/gh/fix-gh-packages.ts +2 -1
  142. package/scripts/gh/gh-spawn.ts +12 -10
  143. package/scripts/git/constants.ts +1 -1
  144. package/scripts/git/git-branch.ts +10 -1
  145. package/scripts/git/git-command.ts +2 -2
  146. package/scripts/git/git-error.ts +2 -5
  147. package/scripts/git/git-execa-error.ts +6 -1
  148. package/{scripts-ai → scripts/git}/git-followup-finish.ts +7 -7
  149. package/scripts/git/git-followup-flush.ts +74 -48
  150. package/scripts/git/git-followup-issue-close.ts +2 -2
  151. package/scripts/git/git-followup-label.ts +1 -1
  152. package/scripts/git/git-followup-pending.ts +1 -1
  153. package/{scripts-ai → scripts/git}/git-followup-workflow.ts +23 -11
  154. package/scripts/git/git-gh-exec.ts +85 -26
  155. package/scripts/git/git-gh-issue-read.ts +2 -2
  156. package/scripts/git/git-gh-issue-rest.ts +2 -2
  157. package/scripts/git/git-gh-issue-write.ts +6 -6
  158. package/scripts/git/git-gh-pr-read.ts +0 -21
  159. package/scripts/git/git-gh-pr.ts +2 -23
  160. package/scripts/git/git-next-issues.ts +34 -5
  161. package/scripts/git/git-pr-followup-wrapup.ts +2 -6
  162. package/scripts/git/git-preflight.ts +25 -10
  163. package/scripts/git/git-push-transport.ts +12 -69
  164. package/scripts/git/git-spawn.ts +79 -3
  165. package/scripts/git/git-ssh-keepalive.ts +74 -0
  166. package/scripts/git/git-staging.ts +21 -9
  167. package/{scripts-ai → scripts/git}/git-workflow.ts +11 -11
  168. package/scripts/git/github-issue-url.ts +1 -1
  169. package/scripts/git/gone-branch.ts +3 -2
  170. package/scripts/git/issue-labels.ts +13 -1
  171. package/scripts/git/issue-rank.ts +89 -0
  172. package/scripts/git/issue-reference.ts +19 -0
  173. package/scripts/git/main-merge.ts +2 -1
  174. package/scripts/git/main-sync.ts +3 -2
  175. package/scripts/git/schemas.ts +1 -1
  176. package/scripts/git/stash-pop-args.ts +7 -13
  177. package/scripts/git/stash-pop-cli.ts +2 -1
  178. package/{scripts-ai → scripts/git}/telegram-test-logic.ts +2 -2
  179. package/{scripts-ai → scripts/git}/telegram-test.ts +7 -7
  180. package/scripts/hooks/format-edited-cli.ts +15 -0
  181. package/scripts/hooks/format-edited-file.ts +2 -9
  182. package/scripts/hooks/format-rewrite-notice.ts +2 -8
  183. package/scripts/hooks/pretool-guard-cli.ts +21 -0
  184. package/scripts/hooks/pretool-guard.ts +14 -15
  185. package/scripts/init/init-ai-copy.ts +2 -5
  186. package/scripts/init/init.ts +8 -4
  187. package/scripts/init/start-exec.ts +7 -1
  188. package/scripts/init/start-plan.ts +18 -5
  189. package/scripts/init/start-setup-pr.ts +46 -19
  190. package/scripts/init/start-steps.ts +43 -10
  191. package/scripts/init/start.ts +42 -11
  192. package/scripts/issue/issue-cite.ts +19 -1
  193. package/scripts/issue/issue-comment-cli.ts +2 -1
  194. package/scripts/issue/issue-file-cli.ts +2 -1
  195. package/scripts/issue/issue-fold-cli.ts +9 -16
  196. package/scripts/issue/issue-scout-cli.ts +8 -13
  197. package/scripts/issue/measure-rerun-cli.ts +7 -6
  198. package/scripts/josh/josh-command-map.ts +0 -102
  199. package/scripts/josh/josh-commands-ai.ts +2 -2
  200. package/scripts/josh/josh-commands-backlog.ts +1 -1
  201. package/scripts/josh/josh-commands-development.ts +3 -3
  202. package/scripts/josh/josh-commands-project.ts +1 -1
  203. package/scripts/josh/josh-commands-workflow.ts +4 -4
  204. package/scripts/lane/lane-child-marker.ts +16 -2
  205. package/scripts/lane/lane-cli.ts +34 -15
  206. package/scripts/lane/lane-open.ts +3 -2
  207. package/scripts/lane/lane-registry.ts +3 -6
  208. package/scripts/lane/lane-report.ts +10 -4
  209. package/scripts/lib/cli-flags.ts +20 -2
  210. package/scripts/lib/error-message.ts +9 -0
  211. package/scripts/lib/read-file.ts +26 -2
  212. package/scripts/observations/observation-ledger-home.ts +98 -26
  213. package/scripts/observations/observation-ledger-migrate.ts +26 -21
  214. package/scripts/observations/observation-ledger-prepare.ts +10 -20
  215. package/scripts/observations/observation-ledger.ts +58 -25
  216. package/scripts/observations/observations-flush-cli.ts +6 -23
  217. package/scripts/observations/observations-flush-landing.ts +2 -1
  218. package/scripts/observations/observations-flush.ts +29 -20
  219. package/scripts/package/package-scout-cli.ts +8 -16
  220. package/scripts/ports/port-command.ts +2 -1
  221. package/scripts/propagate/propagate-plan.ts +185 -0
  222. package/scripts/propagate/propagate-publish.ts +6 -7
  223. package/scripts/propagate/propagate-run.ts +5 -1
  224. package/scripts/propagate/propagate-steps.ts +18 -2
  225. package/scripts/propagate/propagate-targets.ts +13 -2
  226. package/scripts/propagate/propagate.ts +63 -44
  227. package/scripts/refactor/import-graph.ts +2 -6
  228. package/scripts/registry-migration/migrate-logic.ts +1 -0
  229. package/scripts/registry-migration/migrate.ts +3 -2
  230. package/scripts/registry-migration/user-npmrc.ts +2 -2
  231. package/scripts/release/github-release.ts +1 -1
  232. package/scripts/release/release-cli.ts +2 -1
  233. package/scripts/repo/repo-setting.ts +10 -8
  234. package/scripts/review/review-attest.ts +44 -0
  235. package/scripts/review/review-brief-cli.ts +49 -2
  236. package/scripts/review/review-brief.ts +46 -1
  237. package/scripts/review/review-finding-ledger.ts +3 -3
  238. package/scripts/review/review-findings-cli.ts +4 -11
  239. package/scripts/review/review-record-cli.ts +14 -11
  240. package/scripts/review/review-record.ts +6 -16
  241. package/scripts/review/review-stamps.ts +7 -0
  242. package/scripts/rules/decision-oracle.ts +2 -2
  243. package/scripts/rules/implementation-cut.ts +1 -1
  244. package/scripts/rules/issue-fold.ts +1 -2
  245. package/scripts/rules/lane-carry-conflict.ts +1 -2
  246. package/scripts/rules/lane-park.ts +1 -2
  247. package/scripts/rules/pre-gate-cut.ts +2 -2
  248. package/scripts/rules/rule-body-guard.ts +2 -2
  249. package/scripts/rules/rule-value-cache.ts +99 -0
  250. package/scripts/rules/rule-value-cli.ts +10 -9
  251. package/scripts/rules/rule-value.ts +1 -1
  252. package/scripts/run/run-carry-args.ts +2 -6
  253. package/scripts/run/run-carry-cli.ts +5 -7
  254. package/scripts/run/run-cut-args.ts +7 -13
  255. package/scripts/run/run-ending-cli.ts +4 -7
  256. package/scripts/run/run-event-stream.ts +2 -5
  257. package/scripts/run/run-headless.ts +22 -6
  258. package/scripts/run/run-liveness-cli.ts +4 -7
  259. package/scripts/run/run-parent-cut-hook.ts +144 -0
  260. package/scripts/run/run-progress-args.ts +2 -6
  261. package/scripts/run/run-progress-cli.ts +2 -1
  262. package/scripts/run/run-progress-read.ts +2 -1
  263. package/scripts/run/run-progress.ts +21 -8
  264. package/scripts/run/run-ship-cli.ts +6 -74
  265. package/scripts/run/run-ship-preflight.ts +87 -0
  266. package/scripts/run/run-ship-review-steps.ts +5 -26
  267. package/scripts/run/run-ship-review.ts +9 -0
  268. package/scripts/run/run-ship-scoped.ts +44 -0
  269. package/scripts/run/run-ship-stage.ts +5 -1
  270. package/scripts/run/run-ship-steps.ts +105 -0
  271. package/scripts/run/run-ship.ts +2 -0
  272. package/scripts/run/run-tail-cli.ts +3 -3
  273. package/scripts/run/run-tidy-stashes.ts +7 -14
  274. package/scripts/run/run-wake-cli.ts +4 -8
  275. package/scripts/run/run-wake-describe.ts +19 -1
  276. package/scripts/run/run-wake-driver.ts +15 -2
  277. package/scripts/run/run-wake-session.ts +14 -4
  278. package/scripts/run/run-watcher-hook.ts +1 -1
  279. package/scripts/safe-chain/project-config.ts +3 -6
  280. package/scripts/security/security-audit-provision.ts +6 -7
  281. package/scripts/sonar/sonar-hotspots-cli.ts +2 -1
  282. package/scripts/sync/directory-copy-guard.ts +2 -1
  283. package/scripts/sync/sync-ai-files.ts +3 -3
  284. package/scripts/sync/template-source-logic.ts +3 -4
  285. package/scripts/test/e2e-retry-check.ts +3 -6
  286. package/scripts/time-runtime/time-bundle-call.ts +2 -2
  287. package/scripts/ui/ui-routes-cli.ts +3 -6
  288. package/scripts/version/bump-version.ts +2 -1
  289. package/scripts/version/npm-registry.ts +97 -0
  290. package/scripts/version/version-commands.ts +5 -4
  291. package/scripts/version/version-remote.ts +38 -33
  292. package/scripts/version/version-targets.ts +3 -3
  293. package/.claude/skills/workflow-commands/rule-residency.md +0 -267
  294. package/evals/scenarios/consult-not-execute.json +0 -20
  295. package/evals/scenarios/no-implicit-workflow.json +0 -26
  296. package/evals/scenarios/overrides-both-locations.json +0 -29
  297. package/evals/scenarios/upstream-interrupt.json +0 -23
  298. package/evals/scenarios/workflow-skill-loaded.json +0 -16
  299. package/prompts/agent-lint-protocol.json +0 -79
  300. package/prompts/agent-rules.md +0 -63
  301. package/prompts/collaboration-workflow/consultation-vs-execution.md +0 -8
  302. package/prompts/collaboration-workflow/distributed-docs.md +0 -7
  303. package/prompts/collaboration-workflow/durable-rules.md +0 -24
  304. package/prompts/collaboration-workflow/latest-first.md +0 -14
  305. package/prompts/collaboration-workflow/no-clones.md +0 -11
  306. package/prompts/collaboration-workflow/simplicity-first.md +0 -9
  307. package/prompts/collaboration-workflow/single-source-rules.md +0 -13
  308. package/scripts/build/shim-shell.ts +0 -25
  309. package/scripts/claude/skill-meta.ts +0 -37
  310. package/scripts/document/document-scan.ts +0 -108
  311. package/scripts/document/generate-catalog.ts +0 -69
  312. package/scripts/document/retired-phrases.ts +0 -143
  313. package/scripts/document/review-agent-type.ts +0 -46
  314. package/scripts/document/single-source.ts +0 -73
  315. package/scripts/git/git-fixture-workspace.ts +0 -88
  316. package/scripts/hooks/format-edited-file-fixtures.ts +0 -109
  317. package/scripts/hooks/prompt-hooks.ts +0 -38
  318. package/scripts/init/hook-command-bootstrap.ts +0 -83
  319. package/scripts/issue/issue-logic.ts +0 -50
  320. package/scripts/josh/__snapshots__/josh-command-map.test.ts.snap +0 -1227
  321. package/scripts/josh/josh-script-reader.ts +0 -11
  322. package/scripts/package/production-dependency-graph.ts +0 -68
  323. package/scripts/retrospective/retrospective-cli.ts +0 -97
  324. package/scripts/retrospective/retrospective.ts +0 -127
  325. package/scripts/rules/delivered-rules-harness.ts +0 -72
  326. package/scripts/rules/top-level-scripts-guard.ts +0 -47
  327. package/scripts/run/run-carry-flush.ts +0 -58
  328. package/scripts/run/run-transcript.golden.txt +0 -57
  329. package/scripts/run/run-wake-work.ts +0 -108
  330. package/scripts/sync/dependabot-pin-logic.ts +0 -135
  331. package/scripts/test/classify-isolation.ts +0 -149
  332. package/scripts/test/http-fault-injection.ts +0 -79
  333. package/scripts/test/josh-harness-environment.ts +0 -260
  334. package/scripts/test/josh-harness.ts +0 -96
  335. package/scripts/test/pilot-files.ts +0 -452
  336. package/scripts/test/pilot-measure.ts +0 -78
  337. package/scripts/test/test-network-guard.ts +0 -453
  338. package/scripts/test/test-repository-guard.ts +0 -317
  339. package/scripts/test/test-state-guard.ts +0 -85
  340. package/scripts/test/test-stdout-guard.ts +0 -54
  341. package/scripts/test/test-telegram-guard.ts +0 -90
  342. package/scripts/test/unit-guard-environment.ts +0 -12
  343. package/scripts/test/unit-projects.ts +0 -139
  344. package/scripts/test/vitest-include-globs.ts +0 -12
  345. package/scripts/time-runtime/time-batch-guard-fixtures.ts +0 -66
  346. package/scripts-ai/completion-gate.ts +0 -13
  347. package/scripts-ai/environment-loader.ts +0 -9
  348. /package/{scripts-ai → scripts/epic}/epic-cli-argv.ts +0 -0
  349. /package/{scripts-ai → scripts/epic}/epic-cli-remove.ts +0 -0
  350. /package/{scripts-ai → scripts/git}/followup-issue-number.ts +0 -0
@@ -12,15 +12,22 @@ import { start_exec } from './start-exec'
12
12
  const SETUP_TITLE = `Set up ${KIT_PACKAGE_NAME}`
13
13
  const SETUP_BODY = [
14
14
  `Adds the files \`josh start\` wrote while setting up ${KIT_PACKAGE_NAME}, so main carries the`,
15
- 'rules, settings and workflows every later Issue is run with. Only the files kit wrote are in the',
16
- 'pull request; anything else in the working tree is left as it was.',
15
+ 'rules, settings and workflows every later Issue is run with. Only the files the setup wrote are in',
16
+ 'the pull request; anything else in the working tree is left as it was.',
17
17
  ].join('\n')
18
+ const NAME_ONLY = '--name-only'
18
19
  const NOTHING_TO_COMMIT = 'The kit setup has no changes to commit, so no pull request was opened.'
19
20
  const OPEN_SETUP_ISSUES_QUERY = `?state=open&labels=${IGNORE_FOR_RELEASE_LABEL}&per_page=100`
20
21
  const FIRST_SETUP_ISSUE_FILTER = `[.[] | select(.title == "${SETUP_TITLE}") | .number][0] // empty`
21
22
 
22
- function lines_of(output: string | undefined): Array<string> {
23
- return (output ?? '').split('\n').filter((line) => line.length > 0)
23
+ // Listings are read NUL-separated (`-z`), so a path is never quoted — a name a caller's initialize
24
+ // command wrote need not be ASCII the way kit's own are (#2872).
25
+ function paths_of(output: string | undefined): Array<string> {
26
+ return (output ?? '').split('\0').filter((listed) => listed.length > 0)
27
+ }
28
+
29
+ function listing(args: ReadonlyArray<string>, root: string): Array<string> {
30
+ return paths_of(start_exec.read_output('git', [...args, '-z'], root))
24
31
  }
25
32
 
26
33
  function setup_issue(issue_number: string): IssueInfo {
@@ -42,17 +49,18 @@ function is_setup_branch(branch: string | undefined): boolean {
42
49
  }
43
50
 
44
51
  // Untracked files the ignore rules let through, plus tracked files the setup changed — two plain
45
- // listings, so nothing has to be parsed out of `git status`. Every kit path is ASCII, so git's
46
- // quoting of other names never hides one.
52
+ // listings, so nothing has to be parsed out of `git status`.
47
53
  function changed_paths(root: string): Array<string> {
48
- const untracked = start_exec.read_output(
49
- 'git',
50
- ['ls-files', '--others', '--exclude-standard'],
51
- root,
52
- )
53
- const modified = start_exec.read_output('git', ['diff', '--name-only', 'HEAD'], root)
54
-
55
- return [...lines_of(untracked), ...lines_of(modified)]
54
+ const untracked = listing(['ls-files', '--others', '--exclude-standard'], root)
55
+ const modified = listing(['diff', NAME_ONLY, 'HEAD'], root)
56
+
57
+ return [...untracked, ...modified]
58
+ }
59
+
60
+ // On the setup branch a failed commit left, that run's `git add` already staged its files, so they
61
+ // read as changed before this run's command ran — the staged ones count as setup output (#2872).
62
+ function carried_paths(root: string, current: string | undefined): Array<string> {
63
+ return is_setup_branch(current) ? listing(['diff', NAME_ONLY, '--cached'], root) : []
56
64
  }
57
65
 
58
66
  // The Issue carries the release classification the pull request is opened with, so the PR step finds
@@ -113,10 +121,30 @@ function commit_kit_paths(paths: ReadonlyArray<string>, issue: IssueInfo, root:
113
121
  start_exec.run('git', ['commit', '--message', issue.commit_message, '--', ...paths], root)
114
122
  }
115
123
 
116
- // Issue → branch → only kit's files committed → push → pull request. The merge is left to a person:
117
- // it is the one step that changes main.
118
- async function open(root: string): Promise<void> {
119
- const paths = kit_written_paths.select(changed_paths(root))
124
+ // A caller's initialize command writes files kit cannot name, so with a `baseline` — what was already
125
+ // changed before that command ran — everything changed since joins kit's own files, while a change
126
+ // the user had made before the run still stays out (#2872).
127
+ function setup_paths(
128
+ root: string,
129
+ baseline: ReadonlyArray<string> | undefined,
130
+ current: string | undefined,
131
+ ): Array<string> {
132
+ const changed = changed_paths(root)
133
+ const kit_paths = kit_written_paths.select(changed)
134
+
135
+ if (baseline === undefined) return kit_paths
136
+
137
+ const carried = carried_paths(root, current)
138
+ const written = changed.filter((path) => !baseline.includes(path) || carried.includes(path))
139
+
140
+ return [...new Set([...kit_paths, ...written])]
141
+ }
142
+
143
+ // Issue → branch → only the setup's files committed → push → pull request. The merge is left to a
144
+ // person: it is the one step that changes main.
145
+ async function open(root: string, baseline?: ReadonlyArray<string>): Promise<void> {
146
+ const current = start_exec.read_output('git', ['symbolic-ref', '--short', 'HEAD'], root)
147
+ const paths = setup_paths(root, baseline, current)
120
148
 
121
149
  if (paths.length === 0) {
122
150
  console.info(NOTHING_TO_COMMIT)
@@ -124,7 +152,6 @@ async function open(root: string): Promise<void> {
124
152
  return
125
153
  }
126
154
 
127
- const current = start_exec.read_output('git', ['symbolic-ref', '--short', 'HEAD'], root)
128
155
  const issue = resolve_issue(current)
129
156
 
130
157
  switch_to(issue.branch_name, current, root)
@@ -1,6 +1,8 @@
1
1
  import path from 'node:path'
2
+ import { error_text } from '#scripts/lib/error-message'
2
3
  import { repository_labels } from '#scripts/repo/repository-labels'
3
4
  import { self_sync_guard } from '#scripts/self-sync-guard/self-sync-guard-logic'
5
+ import { parseCommandString } from 'execa'
4
6
  import { main as init_main } from './init'
5
7
  import { PACKAGE_DIR } from './init-paths'
6
8
  import { kit_setup_state } from './kit-setup-state'
@@ -13,6 +15,11 @@ interface StepContext {
13
15
  root: string
14
16
  profile: ProjectProfile
15
17
  visibility: Visibility
18
+ init_command: string | undefined
19
+ }
20
+
21
+ interface RunContext extends StepContext {
22
+ baseline: ReadonlyArray<string> | undefined
16
23
  }
17
24
 
18
25
  const DEFAULT_BRANCH = 'main'
@@ -21,7 +28,7 @@ const GH_INSTALL_HINT =
21
28
  const GH_AUTH_HINT =
22
29
  'GitHub CLI is not signed in. Run gh auth login, then run josh start again. Nothing was changed.'
23
30
 
24
- const { succeeds, read_output, run } = start_exec
31
+ const { succeeds, read_output, run, run_local } = start_exec
25
32
 
26
33
  function read_git_state(root: string, shape: ProjectShape): GitState {
27
34
  const { has_git, has_github } = shape
@@ -66,8 +73,19 @@ function create_git_repository(context: StepContext): void {
66
73
  }
67
74
 
68
75
  // The same setup `josh init` runs, called rather than copied, with the profile the user confirmed.
76
+ // A toolkit that layers its files over kit's (`josh-app init`) names its own setup instead, so every
77
+ // other step and guard stays here rather than in a copy of this command (#2872). That command runs
78
+ // without a shell, is given the same profile, and a non-zero exit stops the run before the commit.
69
79
  function initialize(context: StepContext): void {
70
- init_main(['--profile', context.profile])
80
+ if (context.init_command === undefined) {
81
+ init_main(['--profile', context.profile])
82
+
83
+ return
84
+ }
85
+
86
+ const [command = '', ...args] = parseCommandString(context.init_command)
87
+
88
+ run_local(command, [...args, '--profile', context.profile], context.root)
71
89
  }
72
90
 
73
91
  function commit_all(context: StepContext): void {
@@ -96,11 +114,22 @@ function add_missing_labels(): void {
96
114
 
97
115
  // Main already has a history here, so the setup reaches it the way every other change does: through
98
116
  // an Issue and a pull request a person merges (joshuafolkken/kit#2816).
99
- async function open_setup_pull_request(context: StepContext): Promise<void> {
100
- await start_setup_pr.open(context.root)
117
+ async function open_setup_pull_request(context: RunContext): Promise<void> {
118
+ await start_setup_pr.open(context.root, context.baseline)
101
119
  }
102
120
 
103
- type StepAction = (context: StepContext) => void | Promise<void>
121
+ // What was already changed before a caller's initialize command ran, read only when the setup pull
122
+ // request will need to tell that command's files from the user's own (#2872).
123
+ function baseline_of(
124
+ steps: ReadonlyArray<StartStep>,
125
+ context: StepContext,
126
+ ): ReadonlyArray<string> | undefined {
127
+ if (context.init_command === undefined || !steps.includes('setup_pr')) return undefined
128
+
129
+ return start_setup_pr.changed_paths(context.root)
130
+ }
131
+
132
+ type StepAction = (context: RunContext) => void | Promise<void>
104
133
 
105
134
  const STEP_ACTIONS: Readonly<Record<StartStep, StepAction>> = {
106
135
  git_init: create_git_repository,
@@ -113,24 +142,28 @@ const STEP_ACTIONS: Readonly<Record<StartStep, StepAction>> = {
113
142
 
114
143
  async function run_step(
115
144
  step: StartStep,
116
- context: StepContext,
145
+ context: RunContext,
117
146
  completed: ReadonlyArray<StartStep>,
118
147
  ): Promise<void> {
119
148
  try {
120
149
  await STEP_ACTIONS[step](context)
121
150
  } catch (error) {
122
- const cause = error instanceof Error ? error.message : String(error)
151
+ const cause = error_text.message_of(error)
152
+ const labels = start_plan.step_labels(context.init_command)
123
153
 
124
- throw new Error(start_plan.progress_report(step, completed, cause), { cause: error })
154
+ throw new Error(start_plan.progress_report(step, completed, cause, labels), { cause: error })
125
155
  }
126
156
  }
127
157
 
128
158
  async function run_steps(steps: ReadonlyArray<StartStep>, context: StepContext): Promise<void> {
159
+ const labels = start_plan.step_labels(context.init_command)
160
+ const run_context: RunContext = { ...context, baseline: baseline_of(steps, context) }
161
+
129
162
  for (const [index, step] of steps.entries()) {
130
163
  const position = `${String(index + 1)}/${String(steps.length)}`
131
164
 
132
- console.info(`\n[${position}] ${start_plan.STEP_LABELS[step]}`)
133
- await run_step(step, context, steps.slice(0, index))
165
+ console.info(`\n[${position}] ${labels[step]}`)
166
+ await run_step(step, run_context, steps.slice(0, index))
134
167
  }
135
168
  }
136
169
 
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
+ import { error_text } from '#scripts/lib/error-message'
3
4
  import { project_profile, type ProjectProfile } from './project-profile'
4
5
  import {
5
6
  start_plan,
@@ -13,7 +14,9 @@ import { start_steps } from './start-steps'
13
14
 
14
15
  const ARGUMENT_START_INDEX = 2
15
16
  const READY_MESSAGE = 'GitHub workflow ready. Use kickoff new in your assistant to plan an Issue.'
16
- const START_USAGE = 'josh start [--profile basic|full] [--yes] [--github] [--public]'
17
+ const START_USAGE =
18
+ 'josh start [--profile basic|full] [--yes] [--github] [--public] [--init-command <command>]'
19
+ const INIT_COMMAND_FLAG = '--init-command'
17
20
  const YES_FLAG = '--yes'
18
21
  const GITHUB_FLAG = '--github'
19
22
  const PUBLIC_FLAG = '--public'
@@ -25,16 +28,42 @@ interface Prepared {
25
28
  choices: Choices
26
29
  }
27
30
 
28
- // The switches are peeled off first, so what remains is exactly the `--profile` pair `josh init`
29
- // accepts — one parser for the profile in both commands.
31
+ interface InitCommandSplit {
32
+ init_command: string | undefined
33
+ rest: ReadonlyArray<string>
34
+ }
35
+
36
+ // A value that is blank or another flag means the command itself was left out, which would otherwise
37
+ // swallow the next switch or hand the initialize step nothing to run.
38
+ function is_command_value(value: string | undefined): value is string {
39
+ return value !== undefined && value.trim() !== '' && !value.startsWith('-')
40
+ }
41
+
42
+ // The command arrives as the one argument after its flag and is removed together with it.
43
+ function split_init_command(args: ReadonlyArray<string>): InitCommandSplit {
44
+ const index = args.indexOf(INIT_COMMAND_FLAG)
45
+
46
+ if (index === -1) return { init_command: undefined, rest: args }
47
+
48
+ const value = args[index + 1]
49
+
50
+ if (!is_command_value(value)) throw new Error(`Usage: ${START_USAGE}`)
51
+
52
+ return { init_command: value, rest: args.filter((_, at) => at !== index && at !== index + 1) }
53
+ }
54
+
55
+ // The switches and the initialize command are peeled off first, so what remains is exactly the
56
+ // `--profile` pair `josh init` accepts — one parser for the profile in both commands.
30
57
  function parse_start_options(args: ReadonlyArray<string>): StartOptions {
31
- const profile_args = args.filter((argument) => !SWITCHES.has(argument))
58
+ const { init_command, rest } = split_init_command(args)
59
+ const profile_args = rest.filter((argument) => !SWITCHES.has(argument))
32
60
 
33
61
  return {
34
62
  profile: project_profile.requested_profile(profile_args, START_USAGE),
35
- is_yes: args.includes(YES_FLAG),
36
- is_github: args.includes(GITHUB_FLAG),
37
- visibility: args.includes(PUBLIC_FLAG) ? 'public' : 'private',
63
+ is_yes: rest.includes(YES_FLAG),
64
+ is_github: rest.includes(GITHUB_FLAG),
65
+ visibility: rest.includes(PUBLIC_FLAG) ? 'public' : 'private',
66
+ init_command,
38
67
  }
39
68
  }
40
69
 
@@ -82,11 +111,13 @@ function prepare(args: ReadonlyArray<string>, is_tty: boolean, root: string): Pr
82
111
  async function main(args: ReadonlyArray<string>, is_tty: boolean): Promise<void> {
83
112
  const { steps, interaction, choices } = prepare(args, is_tty, process.cwd())
84
113
 
85
- console.info(start_plan.plan_summary(steps))
86
- const profile = await resolve_profile(choices, interaction)
87
114
  const { root, options } = choices
115
+ const { visibility, init_command } = options
116
+
117
+ console.info(start_plan.plan_summary(steps, start_plan.step_labels(init_command)))
118
+ const profile = await resolve_profile(choices, interaction)
88
119
 
89
- await start_steps.run_steps(steps, { root, profile, visibility: options.visibility })
120
+ await start_steps.run_steps(steps, { root, profile, visibility, init_command })
90
121
  console.info(`\n${READY_MESSAGE}`)
91
122
  }
92
123
 
@@ -96,7 +127,7 @@ async function run(args: ReadonlyArray<string>, is_tty: boolean): Promise<number
96
127
 
97
128
  return 0
98
129
  } catch (error) {
99
- console.error(error instanceof Error ? error.message : String(error))
130
+ console.error(error_text.message_of(error))
100
131
 
101
132
  return 1
102
133
  }
@@ -40,6 +40,23 @@ function citation_line(slug: string, number: string, summary: string): string {
40
40
  return `[#${number}](${issue_url(slug, number)})${SUMMARY_SEPARATOR}${summary}`
41
41
  }
42
42
 
43
+ // How a listing names one issue, given what it already holds (joshuafolkken/kit#2943). A progress
44
+ // command's output is copied into a report verbatim, so the line it prints is the citation the report
45
+ // carries: the full form when the title is in hand, the bare number-link when only the repository is,
46
+ // and the plain `#N` only when the repository could not be read at all.
47
+ type IssueCiter = (number: string) => string
48
+
49
+ function citer(slug: string | undefined, titles: ReadonlyMap<string, string>): IssueCiter {
50
+ return function cite(number: string): string {
51
+ if (slug === undefined) return `#${number}`
52
+ const title = titles.get(number)
53
+
54
+ return title === undefined
55
+ ? `[#${number}](${issue_url(slug, number)})`
56
+ : citation_line(slug, number, title)
57
+ }
58
+ }
59
+
43
60
  function qualified_target(token: string): CiteTarget | undefined {
44
61
  const match = REPO_QUALIFIED.exec(token)
45
62
  if (match === null) return undefined
@@ -90,6 +107,7 @@ function no_repo_line(target: CiteTarget): string {
90
107
  const issue_cite = {
91
108
  SUMMARY_SEPARATOR,
92
109
  citation_line,
110
+ citer,
93
111
  issue_url,
94
112
  label,
95
113
  missing_line,
@@ -98,5 +116,5 @@ const issue_cite = {
98
116
  unreadable_line,
99
117
  }
100
118
 
101
- export type { CiteTarget }
119
+ export type { CiteTarget, IssueCiter }
102
120
  export { issue_cite }
@@ -2,6 +2,7 @@
2
2
  import { fileURLToPath } from 'node:url'
3
3
  import { git_gh_command } from '#scripts/git/git-gh-command'
4
4
  import { cli_body } from '#scripts/josh/cli-body'
5
+ import { error_text } from '#scripts/lib/error-message'
5
6
 
6
7
  // `josh issue:comment <N> --body <text> | --body-file <path>` — post one comment to an issue (a PR
7
8
  // comment is an issue comment over REST) and print the comment URL (joshuafolkken/kit#2304).
@@ -66,7 +67,7 @@ function resolve_request(argv: ReadonlyArray<string>): CommentRequest | undefine
66
67
 
67
68
  return request
68
69
  } catch (error) {
69
- console.error(error instanceof Error ? error.message : String(error))
70
+ console.error(error_text.message_of(error))
70
71
 
71
72
  return undefined
72
73
  }
@@ -7,6 +7,7 @@ import { git_gh_command } from '#scripts/git/git-gh-command'
7
7
  import { git_gh_exec } from '#scripts/git/git-gh-exec'
8
8
  import { git_gh_issue_write } from '#scripts/git/git-gh-issue-write'
9
9
  import { github_issue_url } from '#scripts/git/github-issue-url'
10
+ import { error_text } from '#scripts/lib/error-message'
10
11
  import { issue_file, type FileArguments } from './issue-file'
11
12
  import { issue_lint_cli } from './issue-lint-cli'
12
13
  import { issue_scout_cli } from './issue-scout-cli'
@@ -105,7 +106,7 @@ async function create(filing: Filing): Promise<string | undefined> {
105
106
  try {
106
107
  return await git_gh_exec.exec_gh_api(request)
107
108
  } catch (error) {
108
- const reason = error instanceof Error ? error.message : String(error)
109
+ const reason = error_text.message_of(error)
109
110
 
110
111
  console.error(`✖ the create call failed: ${reason}`)
111
112
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { fileURLToPath } from 'node:url'
3
- import { parseArgs } from 'node:util'
4
3
  import { git_command } from '#scripts/git/git-command'
5
4
  import { path_decision } from '#scripts/josh/path-decision'
5
+ import { cli_flags } from '#scripts/lib/cli-flags'
6
6
  import { split_assess, type SplitVerdict } from '#scripts/split/split-assess'
7
7
  import { issue_fold, type FoldVerdict } from './issue-fold'
8
8
 
@@ -33,27 +33,20 @@ interface FoldArguments {
33
33
  is_json: boolean
34
34
  }
35
35
 
36
- function parse_arguments(argv: ReadonlyArray<string>): FoldArguments {
37
- const { values, positionals } = parseArgs({
36
+ // An unknown flag is `undefined` rather than a throw, so the answer is the usage line rather than a
37
+ // stack trace, on a command whose output a workflow reads.
38
+ function read_arguments(argv: ReadonlyArray<string>): FoldArguments | undefined {
39
+ const parsed = cli_flags.parse_or_undefined({
38
40
  args: [...argv],
39
41
  options: { json: { type: 'boolean' }, 'not-separable': { type: 'boolean' } },
40
42
  allowPositionals: true,
41
43
  })
44
+ if (parsed === undefined) return undefined
42
45
 
43
46
  return {
44
- titles: positionals,
45
- is_separable: values['not-separable'] !== true,
46
- is_json: values.json === true,
47
- }
48
- }
49
-
50
- // An unknown flag makes `parseArgs` throw. Caught so the answer is the usage line rather than a stack
51
- // trace, on a command whose output a workflow reads.
52
- function read_arguments(argv: ReadonlyArray<string>): FoldArguments | undefined {
53
- try {
54
- return parse_arguments(argv)
55
- } catch {
56
- return undefined
47
+ titles: parsed.positionals,
48
+ is_separable: parsed.values['not-separable'] !== true,
49
+ is_json: parsed.values.json === true,
57
50
  }
58
51
  }
59
52
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env tsx
2
2
  import { readFile } from 'node:fs/promises'
3
3
  import { fileURLToPath } from 'node:url'
4
- import { parseArgs } from 'node:util'
5
4
  import { epic_audit_logic } from '#scripts/epic/epic-audit'
6
5
  import { epic_bundle, type BacklogIssue, type BundleDecision } from '#scripts/epic/epic-bundle'
7
6
  import { epic_bundle_cli } from '#scripts/epic/epic-bundle-cli'
8
7
  import { epic_bundle_gaps } from '#scripts/epic/epic-bundle-gaps'
9
8
  import { git_gh_command } from '#scripts/git/git-gh-command'
9
+ import { cli_flags } from '#scripts/lib/cli-flags'
10
10
  import { issue_citation } from '#scripts/rules/issue-citation'
11
11
  import {
12
12
  issue_scout,
@@ -59,12 +59,17 @@ function has_invalid_arguments(
59
59
  )
60
60
  }
61
61
 
62
- function parse_arguments(argv: ReadonlyArray<string>): ScoutArguments | undefined {
63
- const { values, positionals } = parseArgs({
62
+ // An unknown flag is `undefined` rather than a throw, so the answer is the usage line rather than a
63
+ // stack trace, on a command whose output a workflow reads.
64
+ function read_arguments(argv: ReadonlyArray<string>): ScoutArguments | undefined {
65
+ const parsed = cli_flags.parse_or_undefined({
64
66
  args: [...argv],
65
67
  options: { body: { type: 'string' }, 'body-file': { type: 'string' } },
66
68
  allowPositionals: true,
67
69
  })
70
+ if (parsed === undefined) return undefined
71
+
72
+ const { values, positionals } = parsed
68
73
  const [title] = positionals
69
74
 
70
75
  if (has_invalid_arguments(title, values.body, values['body-file'])) return undefined
@@ -83,16 +88,6 @@ async function with_draft_body(args: ScoutArguments): Promise<ScoutArguments | u
83
88
  }
84
89
  }
85
90
 
86
- // An unknown flag makes `parseArgs` throw. Caught so the answer is the usage line rather than a stack
87
- // trace, on a command whose output a workflow reads.
88
- function read_arguments(argv: ReadonlyArray<string>): ScoutArguments | undefined {
89
- try {
90
- return parse_arguments(argv)
91
- } catch {
92
- return undefined
93
- }
94
- }
95
-
96
91
  // The issue as it would be filed. The summary is carried as the body because that is what the epic
97
92
  // half reads: the issue numbers its prose names are the references `decide_bundle` decides from.
98
93
  function draft_of(args: ScoutArguments, repo: string): BacklogIssue {
@@ -2,6 +2,7 @@
2
2
  import { execSync } from 'node:child_process'
3
3
  import { readFile } from 'node:fs/promises'
4
4
  import { fileURLToPath } from 'node:url'
5
+ import { error_text } from '#scripts/lib/error-message'
5
6
  import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
6
7
  import { baseline_measure, type Baseline } from './baseline-measure'
7
8
 
@@ -21,7 +22,7 @@ function measure(command: string): string {
21
22
  try {
22
23
  return execSync(command, { encoding: 'utf8' }).trim()
23
24
  } catch (error) {
24
- return `(command failed: ${error instanceof Error ? error.message : String(error)})`
25
+ return `(command failed: ${error_text.message_of(error)})`
25
26
  }
26
27
  }
27
28
 
@@ -40,12 +41,12 @@ function rerun_one(baseline: Baseline, date: string): Outcome {
40
41
  }
41
42
  }
42
43
 
43
- async function append_ledger(lines: ReadonlyArray<string>): Promise<void> {
44
+ async function append_ledger(lines: ReadonlyArray<string>, now: Date): Promise<void> {
44
45
  if (lines.length === 0) return
45
46
 
46
- // The primary checkout's ledger even inside a lane, whose own copy never reaches the default branch
47
- // (joshuafolkken/kit#2419).
48
- const ledger_path = observation_ledger_home.ledger_path()
47
+ // The running work tree's file for the checked-out issue, a lane's inside a lane — the run's own
48
+ // commit carries it (joshuafolkken/kit#2919).
49
+ const ledger_path = await observation_ledger_home.writer_path(now)
49
50
 
50
51
  await observation_ledger_home.append(ledger_path, lines)
51
52
  console.info(`Recorded ${String(lines.length)} refuted premise(s) in ${ledger_path}.`)
@@ -70,7 +71,7 @@ async function rerun(body_path: string, now: Date): Promise<number> {
70
71
  .filter((line): line is string => line !== undefined)
71
72
 
72
73
  console.info(outcomes.map((outcome) => outcome.pair).join('\n\n'))
73
- await append_ledger(ledger_lines)
74
+ await append_ledger(ledger_lines, now)
74
75
 
75
76
  return 0
76
77
  }
@@ -38,8 +38,6 @@ const ALIASES: Record<string, string> = {
38
38
  ln: 'lines',
39
39
  by: 'bytes',
40
40
  f: 'format',
41
- fd: 'format:edited',
42
- bg: 'batch:guard',
43
41
  sd: 'cspell:dot',
44
42
  bh: 'behavior',
45
43
  t: 'test',
@@ -48,8 +46,6 @@ const ALIASES: Record<string, string> = {
48
46
  td: 'test:declared',
49
47
  trd: 'test:red',
50
48
  te: 'test:e2e',
51
- er: 'e2e:retry-check',
52
- sl: 'session:lang',
53
49
  c: 'check',
54
50
  pt: 'port',
55
51
  i: 'init',
@@ -57,19 +53,12 @@ const ALIASES: Record<string, string> = {
57
53
  st: 'start',
58
54
  sy: 'sync',
59
55
  rmi: 'registry:migrate',
60
- sys: 'sync:scope',
61
56
  g: 'git',
62
57
  gp: 'pr',
63
- prc: 'pr:classification',
64
- fu: 'followup',
65
- nf: 'notify',
66
- obf: 'observations:flush',
67
- mrr: 'measure:rerun',
68
58
  ms: 'main:sync',
69
59
  mm: 'main:merge',
70
60
  bp: 'bump',
71
61
  re: 'release',
72
- res: 'release:scope',
73
62
  v: 'version',
74
63
  r: 'ranges',
75
64
  dr: 'doctor',
@@ -77,107 +66,16 @@ const ALIASES: Record<string, string> = {
77
66
  ad: 'adopt',
78
67
  ov: 'overrides',
79
68
  a: 'audit',
80
- ap: 'audit:provision',
81
69
  rt: 'reconcile-templates',
82
70
  u: 'latest',
83
- lg: 'latest:guard',
84
71
  lc: 'latest:corepack',
85
72
  lu: 'latest:update',
86
- ls: 'latest:scope',
87
- pm: 'prevent-main-commit',
88
- cm: 'check-commit-message',
89
- ss: 'secretlint-scan',
90
- ppu: 'pre-push-unit',
91
- rer: 'reserved-run',
92
- ptc: 'pre-commit-type-check',
93
- ird: 'issue:read',
94
- ist: 'issue:state',
95
- isc: 'issue:scout',
96
- ifl: 'issue:file',
97
- isf: 'issue:fold',
98
- isfe: 'issue:fold-existing',
99
- dfr: 'defect:rate',
100
- ici: 'issue:cite',
101
- icm: 'issue:comment',
102
- pks: 'pkg:scout',
103
- iln: 'issue:lint',
104
- ibl: 'issue:backlinks',
105
- rl: 'report:lint',
106
- ep: 'epic',
107
- ec: 'epic:check',
108
- en: 'epic:next',
109
- ea: 'epic:audit',
110
- eb: 'epic:bundle',
111
- ao: 'auto-ok:next',
112
- bl: 'backlog:next',
113
- blo: 'backlog:offer',
114
- bld: 'backlog:drive',
115
- blp: 'backlog:plan',
116
- bls: 'backlog:stalled',
117
- bb: 'backlog:budget',
118
- co: 'cost',
119
- ds: 'doc:section',
120
- rs: 'read:set',
121
- dcr: 'doc:read',
122
- rf: 'read:files',
123
- ef: 'edit:files',
124
- rfs: 'refactor:scan',
125
73
  tm: 'time',
126
74
  tmd: 'time:density',
127
75
  rtr: 'retrospective',
128
- rb: 'review:brief',
129
- r2: 'review:round2',
130
- ra: 'review:attest',
131
- rvr: 'review:record',
132
76
  rvf: 'review:findings',
133
- dp: 'disposition',
134
- dg: 'delegate',
135
- fo: 'fanout',
136
- rh: 'run:hold',
137
- rr: 'run:release',
138
- rc: 'run:carry',
139
- rtd: 'run:tidy',
140
- rw: 'run:wake',
141
- rct: 'run:cut',
142
- rv: 'run:liveness',
143
- red: 'run:ending',
144
- rg: 'run:progress',
145
- rp: 'run:prep',
146
- ren: 'run:entry',
147
- rtl: 'run:tail',
148
- shp: 'ship',
149
- rst: 'run:status',
150
- rn: 'run:next',
151
- rsp: 'run:step',
152
- rpy: 'repo:party',
153
- rmg: 'run:merge',
154
- rrp: 'run:report',
155
- rrv: 'run:review',
156
- rev: 'run:event',
157
- sp: 'stash:pop',
158
- lno: 'lane:open',
159
- lnc: 'lane:close',
160
- lnl: 'lane:list',
161
- lnp: 'lane:prune',
162
- lnv: 'lane:output',
163
- lnd: 'lane:dispatch',
164
- lna: 'lane:await',
165
- lnla: 'lane:launch',
166
- rwg: 'run:watcher:guard',
167
- rsd: 'run:stranded',
168
- ig: 'investigation:guard',
169
- drg: 'duplicate-read:guard',
170
- rug: 'rule:guard',
171
77
  ruv: 'rule:value',
172
- ptg: 'pretool:guard',
173
- sg: 'stop:guard',
174
78
  ev: 'eval',
175
- ol: 'oracle:list',
176
- sa: 'split:assess',
177
- shs: 'sonar:hotspots',
178
- uir: 'ui:routes',
179
- cs: 'clone:scan',
180
- ca: 'cases',
181
79
  }
182
80
 
183
81
  // The canonical name of a `josh` subcommand: an alias expands, and anything else passes through