pr-shepherd 0.56.6 → 0.57.1

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 (421) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +150 -280
  3. package/bin/api.d.mts +25 -3
  4. package/bin/api.mjs +51 -13
  5. package/bin/checks/classify.d.mts +1 -0
  6. package/bin/checks/classify.mjs +1 -1
  7. package/bin/checks/conclusions.d.mts +5 -1
  8. package/bin/checks/conclusions.mjs +8 -2
  9. package/bin/checks/superseded.d.mts +8 -2
  10. package/bin/checks/superseded.mjs +24 -7
  11. package/bin/classify/loader.d.mts +2 -0
  12. package/bin/classify/loader.mjs +15 -0
  13. package/bin/classify/standard/author.d.mts +3 -0
  14. package/bin/classify/standard/author.mjs +10 -0
  15. package/bin/classify/standard/codecov-report.d.mts +4 -0
  16. package/bin/classify/standard/codecov-report.mjs +10 -0
  17. package/bin/classify/standard/coderabbit-notices.d.mts +8 -0
  18. package/bin/classify/standard/coderabbit-notices.mjs +38 -0
  19. package/bin/classify/standard/codex-notices.d.mts +8 -0
  20. package/bin/classify/standard/codex-notices.mjs +34 -0
  21. package/bin/classify/standard/dependabot-notices.d.mts +4 -0
  22. package/bin/classify/standard/dependabot-notices.mjs +15 -0
  23. package/bin/classify/standard/gemini-notices.d.mts +4 -0
  24. package/bin/classify/standard/gemini-notices.mjs +13 -0
  25. package/bin/classify/standard/index.d.mts +7 -0
  26. package/bin/classify/standard/index.mjs +21 -0
  27. package/bin/classify/standard/kilo-no-issues.d.mts +4 -0
  28. package/bin/classify/standard/kilo-no-issues.mjs +17 -0
  29. package/bin/classify/standard/sourcery-notices.d.mts +8 -0
  30. package/bin/classify/standard/sourcery-notices.mjs +20 -0
  31. package/bin/cli/api-usage-formatter.mjs +6 -1
  32. package/bin/cli/apply-merge-handler.d.mts +3 -0
  33. package/bin/cli/apply-merge-handler.mjs +73 -0
  34. package/bin/cli/arg-flags.d.mts +2 -0
  35. package/bin/cli/arg-flags.mjs +47 -0
  36. package/bin/cli/args.mjs +10 -41
  37. package/bin/cli/clean-handler.d.mts +1 -0
  38. package/bin/cli/clean-handler.mjs +71 -0
  39. package/bin/cli/default-poll.mjs +3 -0
  40. package/bin/cli/event-state-scope.d.mts +19 -0
  41. package/bin/cli/event-state-scope.mjs +60 -0
  42. package/bin/cli/fix-formatter.mjs +5 -11
  43. package/bin/cli/handlers.d.mts +0 -1
  44. package/bin/cli/handlers.mjs +8 -64
  45. package/bin/cli/help-command-pages.d.mts +62 -18
  46. package/bin/cli/help-command-pages.mjs +59 -15
  47. package/bin/cli/help-iterate-poll-pages.d.mts +2 -2
  48. package/bin/cli/help-iterate-poll-pages.mjs +6 -0
  49. package/bin/cli/help-log-file-page.d.mts +1 -1
  50. package/bin/cli/help-log-file-page.mjs +4 -1
  51. package/bin/cli/help-top-page.d.mts +1 -1
  52. package/bin/cli/help-top-page.mjs +5 -0
  53. package/bin/cli/help.d.mts +63 -19
  54. package/bin/cli/help.mjs +2 -0
  55. package/bin/cli/iterate-branch-segment.d.mts +2 -0
  56. package/bin/cli/iterate-branch-segment.mjs +12 -7
  57. package/bin/cli/iterate-flags.d.mts +7 -1
  58. package/bin/cli/iterate-flags.mjs +38 -0
  59. package/bin/cli/iterate-formatter.d.mts +6 -6
  60. package/bin/cli/iterate-formatter.mjs +56 -22
  61. package/bin/cli/iterate-instructions.mjs +45 -15
  62. package/bin/cli/iterate-lean.mjs +39 -14
  63. package/bin/cli/iterate-merge-formatter.d.mts +6 -0
  64. package/bin/cli/iterate-merge-formatter.mjs +24 -14
  65. package/bin/cli/iterate-verbose.mjs +3 -6
  66. package/bin/cli/list-formatters.mjs +3 -1
  67. package/bin/cli/mutate-formatter.mjs +10 -5
  68. package/bin/cli/next-check-format.d.mts +7 -0
  69. package/bin/cli/next-check-format.mjs +10 -0
  70. package/bin/cli/playbook-handler.d.mts +5 -0
  71. package/bin/cli/playbook-handler.mjs +40 -0
  72. package/bin/cli/poll-handler.mjs +7 -6
  73. package/bin/cli/poll-summary-formatter.mjs +11 -2
  74. package/bin/cli/poll-targets.mjs +2 -0
  75. package/bin/cli/resolve-validators.mjs +2 -2
  76. package/bin/cli/runner.mjs +6 -1
  77. package/bin/cli/stack-layer-view.d.mts +33 -0
  78. package/bin/cli/stack-layer-view.mjs +1 -0
  79. package/bin/cli/stack-overview.d.mts +10 -28
  80. package/bin/cli/stack-overview.mjs +39 -14
  81. package/bin/cli/transport-args.d.mts +5 -0
  82. package/bin/cli/transport-args.mjs +23 -0
  83. package/bin/cli/transport-formatter.d.mts +9 -0
  84. package/bin/cli/transport-formatter.mjs +13 -0
  85. package/bin/cli-parser.mjs +62 -7
  86. package/bin/commands/apply-merge-options.d.mts +4 -0
  87. package/bin/commands/apply-merge-options.mjs +34 -0
  88. package/bin/commands/apply-merge-output.d.mts +7 -0
  89. package/bin/commands/apply-merge-output.mjs +20 -0
  90. package/bin/commands/apply-merge-pull.d.mts +20 -0
  91. package/bin/commands/apply-merge-pull.mjs +15 -0
  92. package/bin/commands/apply-merge.d.mts +18 -0
  93. package/bin/commands/apply-merge.mjs +126 -0
  94. package/bin/commands/apply-queue-removal.mjs +7 -0
  95. package/bin/commands/check-annotations.mjs +28 -18
  96. package/bin/commands/check-execution-context.d.mts +5 -0
  97. package/bin/commands/check-execution-context.mjs +16 -1
  98. package/bin/commands/check-fingerprint.d.mts +26 -2
  99. package/bin/commands/check-fingerprint.mjs +64 -28
  100. package/bin/commands/check-terminal-report.mjs +11 -1
  101. package/bin/commands/check-unreported.d.mts +6 -2
  102. package/bin/commands/check-unreported.mjs +32 -12
  103. package/bin/commands/check-wait-detectors.d.mts +35 -0
  104. package/bin/commands/check-wait-detectors.mjs +107 -0
  105. package/bin/commands/check.d.mts +4 -2
  106. package/bin/commands/check.mjs +130 -40
  107. package/bin/commands/event-instructions.d.mts +11 -0
  108. package/bin/commands/event-instructions.mjs +27 -0
  109. package/bin/commands/event-mode.d.mts +14 -0
  110. package/bin/commands/event-mode.mjs +138 -0
  111. package/bin/commands/iterate/api-usage.mjs +4 -2
  112. package/bin/commands/iterate/base.mjs +4 -0
  113. package/bin/commands/iterate/check-blocker-gate.mjs +14 -2
  114. package/bin/commands/iterate/check-instructions.d.mts +9 -10
  115. package/bin/commands/iterate/check-instructions.mjs +23 -22
  116. package/bin/commands/iterate/classify.mjs +19 -5
  117. package/bin/commands/iterate/escalate.mjs +13 -3
  118. package/bin/commands/iterate/fix-code.mjs +26 -9
  119. package/bin/commands/iterate/fix-instruction-threads.d.mts +0 -8
  120. package/bin/commands/iterate/fix-instruction-threads.mjs +0 -16
  121. package/bin/commands/iterate/fix-loop-instruction.d.mts +9 -0
  122. package/bin/commands/iterate/fix-loop-instruction.mjs +35 -0
  123. package/bin/commands/iterate/helpers.mjs +15 -2
  124. package/bin/commands/iterate/index.mjs +57 -16
  125. package/bin/commands/iterate/mark-ready.mjs +50 -10
  126. package/bin/commands/iterate/merge-plan.d.mts +19 -0
  127. package/bin/commands/iterate/merge-plan.mjs +88 -0
  128. package/bin/commands/iterate/merge-state.mjs +3 -0
  129. package/bin/commands/iterate/merge.d.mts +4 -15
  130. package/bin/commands/iterate/merge.mjs +18 -51
  131. package/bin/commands/iterate/merged-base-pull-requests.d.mts +2 -6
  132. package/bin/commands/iterate/merged-base-pull-requests.mjs +15 -11
  133. package/bin/commands/iterate/native-stack-rebase.mjs +11 -0
  134. package/bin/commands/iterate/render.d.mts +8 -2
  135. package/bin/commands/iterate/render.mjs +28 -42
  136. package/bin/commands/iterate/stack-trunk-conflict.mjs +17 -1
  137. package/bin/commands/iterate/stale-ancestry.mjs +4 -1
  138. package/bin/commands/iterate/stall.d.mts +5 -1
  139. package/bin/commands/iterate/stall.mjs +19 -7
  140. package/bin/commands/iterate/thread-mutation-routing.d.mts +1 -0
  141. package/bin/commands/iterate/thread-mutation-routing.mjs +4 -2
  142. package/bin/commands/iterate/unreported-required.mjs +5 -2
  143. package/bin/commands/mark-files-as-viewed.mjs +7 -0
  144. package/bin/commands/next-check.d.mts +31 -0
  145. package/bin/commands/next-check.mjs +46 -0
  146. package/bin/commands/playbook.d.mts +13 -0
  147. package/bin/commands/playbook.mjs +48 -0
  148. package/bin/commands/poll-mode.d.mts +8 -0
  149. package/bin/commands/poll-mode.mjs +14 -0
  150. package/bin/commands/poll-progress.d.mts +1 -0
  151. package/bin/commands/poll-progress.mjs +6 -3
  152. package/bin/commands/poll-quota.d.mts +3 -2
  153. package/bin/commands/poll-quota.mjs +7 -3
  154. package/bin/commands/poll-summary-explicit-instructions.d.mts +2 -0
  155. package/bin/commands/poll-summary-explicit-instructions.mjs +10 -1
  156. package/bin/commands/poll-summary-instructions.mjs +16 -17
  157. package/bin/commands/poll-summary.mjs +42 -17
  158. package/bin/commands/poll.d.mts +0 -1
  159. package/bin/commands/poll.mjs +11 -19
  160. package/bin/commands/quota-selection.d.mts +2 -1
  161. package/bin/commands/quota-selection.mjs +12 -7
  162. package/bin/commands/resolve-mutate.mjs +33 -5
  163. package/bin/commands/rest-stack-merge-readiness.d.mts +4 -0
  164. package/bin/commands/rest-stack-merge-readiness.mjs +74 -0
  165. package/bin/commands/rule-auto-resolve.mjs +9 -3
  166. package/bin/commands/shepherd-journal.d.mts +5 -4
  167. package/bin/commands/shepherd-journal.mjs +9 -8
  168. package/bin/commands/stack-drain.d.mts +1 -9
  169. package/bin/commands/stack-drain.mjs +50 -37
  170. package/bin/commands/stack-handoffs.d.mts +10 -0
  171. package/bin/commands/stack-handoffs.mjs +25 -0
  172. package/bin/commands/stack-stall.d.mts +5 -0
  173. package/bin/commands/stack-stall.mjs +11 -0
  174. package/bin/commands/stack-work.d.mts +5 -0
  175. package/bin/commands/stack-work.mjs +32 -0
  176. package/bin/comments/existing-reply-scan.d.mts +17 -0
  177. package/bin/comments/existing-reply-scan.mjs +41 -0
  178. package/bin/comments/rate-limit.mjs +2 -2
  179. package/bin/comments/resolve.d.mts +7 -1
  180. package/bin/comments/resolve.mjs +108 -18
  181. package/bin/comments/rest-reply.d.mts +9 -0
  182. package/bin/comments/rest-reply.mjs +95 -0
  183. package/bin/comments/rest-review-mutations.d.mts +22 -0
  184. package/bin/comments/rest-review-mutations.mjs +125 -0
  185. package/bin/comments/review-visibility.d.mts +1 -1
  186. package/bin/comments/review-visibility.mjs +3 -2
  187. package/bin/comments/sha-poll.mjs +7 -3
  188. package/bin/comments/thread-visibility.mjs +10 -5
  189. package/bin/comments/uncertain-replies.d.mts +11 -0
  190. package/bin/comments/uncertain-replies.mjs +121 -0
  191. package/bin/comments/uncertain-reply-guards.d.mts +10 -0
  192. package/bin/comments/uncertain-reply-guards.mjs +94 -0
  193. package/bin/comments/visible-comments.d.mts +1 -1
  194. package/bin/comments/visible-comments.mjs +4 -2
  195. package/bin/config/load.d.mts +37 -1
  196. package/bin/config/load.mjs +73 -1
  197. package/bin/config.json +6 -2
  198. package/bin/exit-codes.d.mts +3 -0
  199. package/bin/exit-codes.mjs +8 -0
  200. package/bin/github/api-telemetry-aggregate.d.mts +15 -4
  201. package/bin/github/api-telemetry-aggregate.mjs +57 -18
  202. package/bin/github/api-telemetry.d.mts +4 -0
  203. package/bin/github/api-telemetry.mjs +22 -8
  204. package/bin/github/apply-review-preflight.d.mts +20 -0
  205. package/bin/github/apply-review-preflight.mjs +61 -0
  206. package/bin/github/base-behind-cache.d.mts +15 -0
  207. package/bin/github/base-behind-cache.mjs +18 -0
  208. package/bin/github/batch-parse-suites.d.mts +4 -2
  209. package/bin/github/batch-parse-suites.mjs +6 -1
  210. package/bin/github/batch-parser-helpers.mjs +40 -2
  211. package/bin/github/batch-parsers.mjs +1 -0
  212. package/bin/github/batch-raw-rules.d.mts +26 -0
  213. package/bin/github/batch-raw-types.d.mts +8 -6
  214. package/bin/github/batch-stack-evidence.d.mts +28 -0
  215. package/bin/github/batch-stack-evidence.mjs +62 -0
  216. package/bin/github/batch.d.mts +15 -2
  217. package/bin/github/batch.mjs +34 -17
  218. package/bin/github/captured-proxy-agent.d.mts +3 -0
  219. package/bin/github/captured-proxy-agent.mjs +8 -0
  220. package/bin/github/check-annotations-batch.d.mts +0 -5
  221. package/bin/github/check-annotations-batch.mjs +25 -4
  222. package/bin/github/check-annotations.mjs +3 -1
  223. package/bin/github/client.d.mts +8 -19
  224. package/bin/github/client.mjs +45 -13
  225. package/bin/github/fingerprint-fields.d.mts +8 -0
  226. package/bin/github/fingerprint-fields.mjs +6 -1
  227. package/bin/github/fingerprint.d.mts +4 -2
  228. package/bin/github/fingerprint.mjs +6 -38
  229. package/bin/github/github-fetch.d.mts +2 -0
  230. package/bin/github/github-fetch.mjs +32 -0
  231. package/bin/github/gql/base-behind.gql +3 -0
  232. package/bin/github/gql/batch-pr-page.gql +16 -0
  233. package/bin/github/gql/batch-pr.gql +57 -0
  234. package/bin/github/gql/commit-check-contexts.gql +17 -0
  235. package/bin/github/gql/get-pr-body.gql +1 -0
  236. package/bin/github/gql/poll-stack-summary.gql +1 -0
  237. package/bin/github/gql/poll-summary-check-contexts.gql +5 -0
  238. package/bin/github/gql/poll-summary-fragment.gql +65 -15
  239. package/bin/github/gql/stack-handoff-check-runs.gql +42 -0
  240. package/bin/github/graphql-http.mjs +9 -4
  241. package/bin/github/graphql-internal-retry.d.mts +2 -0
  242. package/bin/github/graphql-internal-retry.mjs +1 -1
  243. package/bin/github/graphql-quota-probe.d.mts +6 -0
  244. package/bin/github/graphql-quota-probe.mjs +56 -0
  245. package/bin/github/graphql-session-refusal.d.mts +8 -0
  246. package/bin/github/graphql-session-refusal.mjs +14 -0
  247. package/bin/github/http-request.d.mts +1 -1
  248. package/bin/github/http-request.mjs +22 -6
  249. package/bin/github/http-utils.mjs +6 -0
  250. package/bin/github/legacy-dispatcher.d.mts +6 -0
  251. package/bin/github/legacy-dispatcher.mjs +44 -0
  252. package/bin/github/merge-target-rules.d.mts +12 -3
  253. package/bin/github/merge-target-rules.mjs +71 -34
  254. package/bin/github/mutation-policy.d.mts +6 -0
  255. package/bin/github/mutation-policy.mjs +21 -0
  256. package/bin/github/poll-summary-annotation-probe.mjs +17 -10
  257. package/bin/github/poll-summary-check-blockers.d.mts +1 -1
  258. package/bin/github/poll-summary-check-blockers.mjs +2 -2
  259. package/bin/github/poll-summary-check-hydration.mjs +25 -10
  260. package/bin/github/poll-summary-checks.d.mts +2 -2
  261. package/bin/github/poll-summary-checks.mjs +9 -6
  262. package/bin/github/poll-summary-command.d.mts +2 -0
  263. package/bin/github/poll-summary-command.mjs +24 -0
  264. package/bin/github/poll-summary-fingerprint.d.mts +1 -1
  265. package/bin/github/poll-summary-fingerprint.mjs +4 -2
  266. package/bin/github/poll-summary-handoff-fields.d.mts +3 -0
  267. package/bin/github/poll-summary-handoff-fields.mjs +73 -0
  268. package/bin/github/poll-summary-projector.d.mts +1 -1
  269. package/bin/github/poll-summary-projector.mjs +17 -24
  270. package/bin/github/poll-summary-raw.d.mts +70 -10
  271. package/bin/github/poll-summary-readiness.d.mts +6 -1
  272. package/bin/github/poll-summary-readiness.mjs +13 -4
  273. package/bin/github/poll-summary-rest-queue.d.mts +3 -0
  274. package/bin/github/poll-summary-rest-queue.mjs +12 -0
  275. package/bin/github/poll-summary-review.d.mts +1 -1
  276. package/bin/github/poll-summary-review.mjs +35 -20
  277. package/bin/github/poll-summary-route.mjs +19 -3
  278. package/bin/github/poll-summary-stack-page.d.mts +11 -0
  279. package/bin/github/poll-summary-stack-page.mjs +27 -0
  280. package/bin/github/poll-summary-unreported.d.mts +3 -1
  281. package/bin/github/poll-summary-unreported.mjs +6 -3
  282. package/bin/github/poll-summary.d.mts +4 -1
  283. package/bin/github/poll-summary.mjs +47 -33
  284. package/bin/github/queries.d.mts +7 -3
  285. package/bin/github/queries.mjs +8 -4
  286. package/bin/github/rate-limit-sample.d.mts +7 -0
  287. package/bin/github/rate-limit-sample.mjs +12 -0
  288. package/bin/github/reply-recovery-read.d.mts +50 -0
  289. package/bin/github/reply-recovery-read.mjs +118 -0
  290. package/bin/github/reply-thread-transcripts.d.mts +0 -1
  291. package/bin/github/reply-thread-transcripts.mjs +24 -1
  292. package/bin/github/rest-annotation-read.d.mts +5 -0
  293. package/bin/github/rest-annotation-read.mjs +44 -0
  294. package/bin/github/rest-batch-read.d.mts +12 -0
  295. package/bin/github/rest-batch-read.mjs +57 -0
  296. package/bin/github/rest-batch-snapshot.d.mts +30 -0
  297. package/bin/github/rest-batch-snapshot.mjs +115 -0
  298. package/bin/github/rest-batch-unavailable.d.mts +5 -0
  299. package/bin/github/rest-batch-unavailable.mjs +16 -0
  300. package/bin/github/rest-check-read.d.mts +34 -0
  301. package/bin/github/rest-check-read.mjs +124 -0
  302. package/bin/github/rest-comment-authorship.d.mts +7 -0
  303. package/bin/github/rest-comment-authorship.mjs +11 -0
  304. package/bin/github/rest-conditional-scope.d.mts +20 -0
  305. package/bin/github/rest-conditional-scope.mjs +44 -0
  306. package/bin/github/rest-explicit-summary-read.d.mts +3 -0
  307. package/bin/github/rest-explicit-summary-read.mjs +8 -0
  308. package/bin/github/rest-feedback-read.d.mts +36 -0
  309. package/bin/github/rest-feedback-read.mjs +147 -0
  310. package/bin/github/rest-feedback-validation.d.mts +5 -0
  311. package/bin/github/rest-feedback-validation.mjs +28 -0
  312. package/bin/github/rest-http.d.mts +12 -0
  313. package/bin/github/rest-http.mjs +108 -23
  314. package/bin/github/rest-identities.d.mts +22 -0
  315. package/bin/github/rest-identities.mjs +134 -0
  316. package/bin/github/rest-merge-stack-guard.d.mts +14 -0
  317. package/bin/github/rest-merge-stack-guard.mjs +41 -0
  318. package/bin/github/rest-merge.d.mts +29 -0
  319. package/bin/github/rest-merge.mjs +56 -0
  320. package/bin/github/rest-merged-base-read.d.mts +9 -0
  321. package/bin/github/rest-merged-base-read.mjs +48 -0
  322. package/bin/github/rest-pr-core.d.mts +52 -0
  323. package/bin/github/rest-pr-core.mjs +60 -0
  324. package/bin/github/rest-reader-core.d.mts +16 -0
  325. package/bin/github/rest-reader-core.mjs +154 -0
  326. package/bin/github/rest-review-read.d.mts +11 -0
  327. package/bin/github/rest-review-read.mjs +47 -0
  328. package/bin/github/rest-rules-read.d.mts +9 -0
  329. package/bin/github/rest-rules-read.mjs +154 -0
  330. package/bin/github/rest-session-refusal.d.mts +5 -0
  331. package/bin/github/rest-session-refusal.mjs +21 -0
  332. package/bin/github/rest-snapshot-context.d.mts +10 -0
  333. package/bin/github/rest-snapshot-context.mjs +1 -0
  334. package/bin/github/rest-stack-read.d.mts +21 -0
  335. package/bin/github/rest-stack-read.mjs +47 -0
  336. package/bin/github/rest-stack-summary.d.mts +8 -0
  337. package/bin/github/rest-stack-summary.mjs +62 -0
  338. package/bin/github/rest-summary-read.d.mts +7 -0
  339. package/bin/github/rest-summary-read.mjs +112 -0
  340. package/bin/github/rest-terminal-batch.d.mts +14 -0
  341. package/bin/github/rest-terminal-batch.mjs +45 -0
  342. package/bin/github/rest-text.mjs +7 -3
  343. package/bin/github/rest-thread-read.d.mts +4 -0
  344. package/bin/github/rest-thread-read.mjs +35 -0
  345. package/bin/github/rest-viewer-read.d.mts +2 -0
  346. package/bin/github/rest-viewer-read.mjs +41 -0
  347. package/bin/github/stack-bottom.d.mts +3 -0
  348. package/bin/github/stack-bottom.mjs +14 -0
  349. package/bin/github/stack-handoff-context.d.mts +25 -0
  350. package/bin/github/stack-handoff-context.mjs +12 -0
  351. package/bin/github/stack-handoff-page.d.mts +17 -0
  352. package/bin/github/stack-handoff-page.mjs +306 -0
  353. package/bin/github/stack-handoff.d.mts +16 -0
  354. package/bin/github/stack-handoff.mjs +115 -0
  355. package/bin/github/stack-order.d.mts +6 -0
  356. package/bin/github/stack-order.mjs +13 -0
  357. package/bin/github/stack-read.d.mts +7 -5
  358. package/bin/github/stack-read.mjs +22 -24
  359. package/bin/github/stack-size-hint.d.mts +3 -0
  360. package/bin/github/stack-size-hint.mjs +14 -0
  361. package/bin/github/suggestion-thread.mjs +27 -1
  362. package/bin/github/thread-comments.mjs +9 -1
  363. package/bin/github/transport-evidence.d.mts +20 -0
  364. package/bin/github/transport-evidence.mjs +26 -0
  365. package/bin/github/transport-mode.d.mts +2 -0
  366. package/bin/github/transport-mode.mjs +5 -0
  367. package/bin/github/transport.d.mts +19 -0
  368. package/bin/github/transport.mjs +126 -0
  369. package/bin/github/unsupported-rest.d.mts +4 -0
  370. package/bin/github/unsupported-rest.mjs +7 -0
  371. package/bin/mcp/server.mjs +52 -3
  372. package/bin/merge-status/derive.d.mts +2 -0
  373. package/bin/merge-status/derive.mjs +17 -13
  374. package/bin/merge-status/required-check-requirements.d.mts +7 -0
  375. package/bin/merge-status/required-check-requirements.mjs +15 -0
  376. package/bin/merge-status/requirements-format.d.mts +5 -0
  377. package/bin/merge-status/requirements-format.mjs +41 -12
  378. package/bin/merge-status/requirements.mjs +18 -7
  379. package/bin/state/base.mjs +41 -0
  380. package/bin/state/durable-state.d.mts +6 -0
  381. package/bin/state/durable-state.mjs +41 -0
  382. package/bin/state/graphql-quota-policy.mjs +23 -16
  383. package/bin/state/merge-request.d.mts +25 -0
  384. package/bin/state/merge-request.mjs +145 -0
  385. package/bin/state/pr-fingerprint.d.mts +15 -0
  386. package/bin/state/pr-fingerprint.mjs +22 -7
  387. package/bin/state/rest-cache.d.mts +3 -0
  388. package/bin/state/rest-cache.mjs +1 -0
  389. package/bin/state/rest-snapshot-report.d.mts +21 -0
  390. package/bin/state/rest-snapshot-report.mjs +52 -0
  391. package/bin/state/seen-comments.d.mts +3 -0
  392. package/bin/state/seen-comments.mjs +18 -0
  393. package/bin/types/api-usage.d.mts +9 -1
  394. package/bin/types/escalate.d.mts +1 -1
  395. package/bin/types/github.d.mts +23 -9
  396. package/bin/types/iterate.d.mts +24 -2
  397. package/bin/types/merge-action.d.mts +1 -1
  398. package/bin/types/merge-requirements.d.mts +7 -7
  399. package/bin/types/next-check.d.mts +12 -0
  400. package/bin/types/next-check.mjs +1 -0
  401. package/bin/types/poll-summary.d.mts +21 -0
  402. package/bin/types/report.d.mts +13 -1
  403. package/bin/types/review-thread.d.mts +1 -1
  404. package/bin/types.d.mts +1 -0
  405. package/bin/types.mjs +1 -0
  406. package/package.json +4 -3
  407. package/plugins/pr-shepherd/.codex-plugin/plugin.json +1 -1
  408. package/plugins/pr-shepherd/.codex.mcp.json +1 -1
  409. package/plugins/pr-shepherd/.mcp.json +1 -1
  410. package/plugins/pr-shepherd/skills/mark-files-as-viewed/SKILL.md +1 -1
  411. package/plugins/pr-shepherd/skills/pr-shepherd/SKILL.md +14 -51
  412. package/plugins/pr-shepherd/skills/pr-shepherd/references/ci-failure-triage.md +12 -16
  413. package/plugins/pr-shepherd/skills/pr-shepherd/references/cloud-event-loop.md +14 -0
  414. package/plugins/pr-shepherd/skills/pr-shepherd/references/create-pr.md +10 -0
  415. package/plugins/pr-shepherd/skills/pr-shepherd/references/fix-code-loop.md +10 -0
  416. package/plugins/pr-shepherd/skills/pr-shepherd/references/mcp-fallback.md +9 -0
  417. package/plugins/pr-shepherd/skills/reduce-pr-noise/references/classifiers.md +3 -1
  418. package/bin/github/gql/pr-fingerprint.gql +0 -75
  419. package/plugins/pr-shepherd/skills/pr-shepherd/references/journal.md +0 -7
  420. package/plugins/pr-shepherd/skills/pr-shepherd/references/review-mutations.md +0 -9
  421. package/plugins/pr-shepherd/skills/pr-shepherd/references/stack-merge.md +0 -7
@@ -1,10 +1,29 @@
1
1
  export declare const USAGE: {
2
2
  readonly default: string;
3
+ readonly "apply merge": `pr-shepherd apply merge
4
+
5
+ Submit one SHA-guarded asynchronous merge or enqueue request with REST.
6
+ Rerun the same command to resume its persisted UUID. Pending and enqueued requests are not merged.
7
+ An enqueued result records that request's outcome; it does not confirm current queue membership.
8
+ An uncertain submission is never repeated automatically.
9
+
10
+ Usage:
11
+ pr-shepherd apply merge [PR] --require-sha SHA --merge-action direct_merge|merge_queue|default
12
+ [--method merge|squash|rebase] [--expected-stack JSON] --transport rest [--format text|json]
13
+
14
+ --require-sha <sha> Full 40-character lowercase PR head SHA.
15
+ --merge-action <action> direct_merge, merge_queue, or default.
16
+ --method <method> Optional merge method, only for direct_merge.
17
+ --expected-stack <json> Bind native stack number, baseRefName, and ordered prefix PRs/refs/head SHAs.
18
+ --transport rest Required REST transport; repository rules are never bypassed.
19
+ --format text|json Output format. Default: text.
20
+ --help, -h Print this help before validation or I/O.`;
3
21
  readonly apply: `pr-shepherd apply
4
22
 
5
23
  Apply review mutations, mark selected changed files as viewed, append a PR journal item, or record an external check blocker.
6
24
 
7
25
  Usage:
26
+ pr-shepherd apply merge [PR] --require-sha SHA --merge-action ACTION --transport rest
8
27
  pr-shepherd apply review [PR] [review-flags]
9
28
  pr-shepherd apply files [PR] [files...] [--tests] [--match REGEX]
10
29
  pr-shepherd apply journal [PR] <item> [--dry-run] [--format text|json]
@@ -13,7 +32,7 @@ Usage:
13
32
  pr-shepherd apply check-blocker [PR] --check <name> --clear
14
33
  pr-shepherd apply queue-removal [PR] --require-sha <head> --queue-commit <commit> --removed-at <unix>
15
34
 
16
- Run 'pr-shepherd apply <review|files|journal|check-blocker|queue-removal> --help' for command-specific details.
35
+ Run 'pr-shepherd apply <merge|review|files|journal|check-blocker|queue-removal> --help' for command-specific details.
17
36
  --help, -h Print this help and exit before GitHub I/O.`;
18
37
  readonly "apply review": `pr-shepherd apply review
19
38
 
@@ -32,7 +51,11 @@ Flags:
32
51
  --minimize-comment-ids <ids> Comma-separated issue/review comment IDs to minimize.
33
52
  --dismiss-review-ids <ids> Comma-separated review IDs to dismiss.
34
53
  --message <text> Reply/dismiss message. Required with reply or dismiss IDs.
35
- --require-sha <sha> Wait for this full 40-character lowercase PR head SHA.
54
+ --require-sha <sha> Wait for this full 40-character lowercase PR head SHA, or HEAD
55
+ for this checkout's commit.
56
+ --adopt-existing-replies Generated durable-state commands only: count a thread whose last
57
+ comment is already this exact Shepherd reply from you as replied
58
+ instead of posting it again. Omit it to forward every reply ID.
36
59
  --format text|json Output format. Default: text.
37
60
 
38
61
  At least one action flag is required.
@@ -143,14 +166,16 @@ Run 'pr-shepherd admin <clean|log-file> --help' for command-specific details.
143
166
  Remove pr-shepherd state files from PR_SHEPHERD_STATE_DIR.
144
167
 
145
168
  Usage:
146
- pr-shepherd admin clean pr [number] [--dry-run] [--format text|json]
147
- pr-shepherd admin clean branch [name] [--dry-run] [--format text|json]
148
- pr-shepherd admin clean current [--dry-run] [--format text|json]
149
- pr-shepherd admin clean repo [--dry-run] [--format text|json]
150
- pr-shepherd admin clean all [--dry-run] [--format text|json]
169
+ pr-shepherd admin clean pr [number] [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
170
+ pr-shepherd admin clean branch [name] [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
171
+ pr-shepherd admin clean current [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
172
+ pr-shepherd admin clean repo [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
173
+ pr-shepherd admin clean all [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
151
174
 
152
175
  Variants remove state for one PR, branch, current branch, repository, or all repositories.
153
176
  Use --dry-run to preview paths without removing them.
177
+ --poll-mode auto|poll|event Clean the state for that poll mode; event mode keeps it in durable
178
+ state under the git common directory. Default: poll.mode (auto).
154
179
  --help, -h Print this help and exit before any cleanup.`;
155
180
  readonly "admin log-file": string;
156
181
  readonly resolve: `pr-shepherd resolve
@@ -172,9 +197,10 @@ Flags:
172
197
  --dismiss-review-ids <ids> Comma-separated review IDs to dismiss.
173
198
  --message <text> Reply/dismiss message. Required with --reply-thread-ids
174
199
  or --dismiss-review-ids.
175
- --require-sha <sha> Wait until GitHub reports this PR head SHA before mutating.
176
- Must be a full 40-character lowercase hex SHA. Local HEAD is valid
177
- only when it equals the current remote PR head.
200
+ --require-sha <sha> Wait until GitHub reports this PR head SHA (or HEAD) before mutating.
201
+ Must be a full 40-character lowercase hex SHA, or HEAD for this
202
+ checkout's commit. Local HEAD is valid only when it equals the
203
+ current remote PR head.
178
204
  --format text|json Output format. Default: text.
179
205
  --help, -h Print this help and exit before GitHub I/O.
180
206
 
@@ -227,18 +253,18 @@ Flags:
227
253
 
228
254
  PR may be a number or GitHub pull request URL. When omitted, the current branch PR is inferred.
229
255
  Exit code: 0 on success; nonzero on failure (sysexits.h — see docs/exit-codes.md).`;
230
- readonly iterate: "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n READY Clean PR is inside the ready-delay. Schedule the rerun for when remainingSeconds elapses. Do not invent unrelated work. Already-owned later work may continue.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling this pull request: merged/closed or ready-delay elapsed. Continue remaining work from the original request.\n ESCALATE Stop polling until a human provides direction.\n MERGE Run the emitted merge/queue command, then continue monitoring.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
231
- readonly poll: "pr-shepherd poll\n\nRun iterate repeatedly for one PR, or read compact summaries for an explicit PR set or native\nGitHub stack. Aggregate mode returns when any row needs work, every row is terminal, or timeout.\nPoll exits as soon as iterate returns READY, MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default:\npoll.debounceSeconds; built-in 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal or --merge, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR ...] [poll-flags] [iterate-flags]\n pr-shepherd poll --stack PR [poll-flags] [iterate-flags]\n\nPoll flags:\n --stack PR Select all entries in PR's native GitHub stack, bottom to top.\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: poll.intervalSeconds (built-in 60s). Stack and multi-PR polls multiply that by poll.stackIntervalFactor (built-in 2) unless this flag is set.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: poll.timeoutSeconds (built-in 4.5m).\n --debounce <duration> Settle window after first FIX_CODE or stack SHEPHERD before returning. Bare number = seconds. Default: poll.debounceSeconds (built-in 60s). 0 disables.\n --quiet-status Print only changed WAIT snapshots. Overrides poll.quietStatus.\n --no-quiet-status Print every WAIT snapshot. Overrides poll.quietStatus.\n --until-terminal Continue through WAIT/MARK_READY until READY/FIX_CODE/MERGE/CANCEL/ESCALATE or stack SHEPHERD.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes a stderr line naming what it is waiting on by default; poll.quietStatus can change that default, --quiet-status/--no-quiet-status override it, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until READY, FIX_CODE, MERGE, CANCEL, or ESCALATE. With --merge, --timeout still bounds WAIT ticks; it only continues through MARK_READY while polling remains within that timeout.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n 16 SHEPHERD (--stack only: run the listed one-PR sessions, then rerun the selector)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
256
+ readonly iterate: "pr-shepherd iterate\n\nRun one iterate tick for a pull request. The no-subcommand form polls; use this subcommand for a single tick.\nThe output contains one action and an action-specific ## Instructions section.\n\nUsage:\n pr-shepherd iterate [PR] [iterate-flags]\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --instructions playbook|inline Render fix_code steps inline every tick (default) or fold the invariant ones into a playbook pointer. Default: iterate.instructions (inline).\n --poll-mode auto|poll|event event runs one tick, never sleeps, and prints nextCheck; auto picks event when CLAUDE_CODE_REMOTE=true. Default: poll.mode (auto).\n --transport auto|graphql|rest Select GitHub transport. Default: github.transport (auto).\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number is minutes; decimals are allowed only with an explicit unit (4.5m).\n\nActions:\n WAIT No immediate action; continue with the next poll.\n MARK_READY Draft PR was marked ready; continue with the next poll.\n READY Clean PR is inside the ready-delay. Schedule the rerun for when remainingSeconds elapses. Do not invent unrelated work. Already-owned later work may continue.\n FIX_CODE Agent action is required; follow the instructions, then continue polling.\n CANCEL Stop polling this pull request: merged/closed or ready-delay elapsed. Continue remaining work from the original request.\n ESCALATE Stop polling until a human provides direction.\n MERGE Run the emitted merge/queue command, then continue monitoring.\n\nExit codes:\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
257
+ readonly poll: "pr-shepherd poll\n\nRun iterate repeatedly for one PR, or read compact summaries for an explicit PR set or native\nGitHub stack. Aggregate mode returns when any row needs work, every row is terminal, or timeout.\nPoll exits as soon as iterate returns READY, MARK_READY, CANCEL, or ESCALATE, or when timeout\nreturns the last WAIT result. FIX_CODE starts a --debounce settle window (default:\npoll.debounceSeconds; built-in 1m): poll keeps\niterating at --interval, then runs one more tick after the window and returns that result.\nWith --until-terminal or --merge, poll also continues through MARK_READY.\n\nUsage:\n pr-shepherd poll [PR ...] [poll-flags] [iterate-flags]\n pr-shepherd poll --stack PR [poll-flags] [iterate-flags]\n\nPoll flags:\n --stack PR Select all entries in PR's native GitHub stack, bottom to top.\n --interval <duration> Sleep between WAIT ticks. Bare number = seconds. Default: poll.intervalSeconds (built-in 60s). Stack and multi-PR polls multiply that by poll.stackIntervalFactor (built-in 2) unless this flag is set.\n --timeout <duration> Maximum wall-clock wait for WAIT ticks. Bare number = seconds. Default: poll.timeoutSeconds (built-in 4.5m).\n --debounce <duration> Settle window after first FIX_CODE or stack SHEPHERD before returning. Bare number = seconds. Default: poll.debounceSeconds (built-in 60s). 0 disables.\n --quiet-status Print only changed WAIT snapshots. Overrides poll.quietStatus.\n --no-quiet-status Print every WAIT snapshot. Overrides poll.quietStatus.\n --until-terminal Continue through WAIT/MARK_READY until READY/FIX_CODE/MERGE/CANCEL/ESCALATE or stack SHEPHERD.\n\nForwarded iterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --instructions playbook|inline Render fix_code steps inline every tick (default) or fold the invariant ones into a playbook pointer. Default: iterate.instructions (inline).\n --poll-mode auto|poll|event event runs one tick, never sleeps, and prints nextCheck; auto picks event when CLAUDE_CODE_REMOTE=true. Default: poll.mode (auto).\n --transport auto|graphql|rest Select GitHub transport. Default: github.transport (auto).\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed per-tick lines.\n --help, -h Print this help and exit before GitHub, git, config, or log I/O.\n\nDurations accept s/m/h suffixes: 30s, 4.5m, 1h. A bare number uses each flag's default unit (seconds\nfor --interval/--timeout/--debounce, minutes for --ready-delay/--stall-timeout); decimals are allowed only with\nan explicit unit (4.5m).\nEach WAIT tick writes a stderr line naming what it is waiting on by default; poll.quietStatus can change that default, --quiet-status/--no-quiet-status override it, and --verbose emits detailed per-tick lines.\nFIX_CODE debounce writes a remaining-seconds line to stderr. --timeout does not cut an in-flight debounce short.\nWith --until-terminal, --timeout is ignored for WAIT ticks and polling continues until READY, FIX_CODE, MERGE, CANCEL, or ESCALATE. With --merge, --timeout still bounds WAIT ticks; it only continues through MARK_READY while polling remains within that timeout.\n\nExit codes: same as iterate (the final tick's action/reason decides the code).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY (including a WAIT returned by --timeout)\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n 16 SHEPHERD (--stack only: run the listed one-PR sessions, then rerun the selector)\n A command/validation/GitHub failure exits with a sysexits.h code instead (see docs/exit-codes.md).";
232
258
  readonly clean: `pr-shepherd clean
233
259
 
234
260
  Remove pr-shepherd state files from PR_SHEPHERD_STATE_DIR.
235
261
 
236
262
  Usage:
237
- pr-shepherd clean pr [number] [--dry-run] [--format text|json]
238
- pr-shepherd clean branch [name] [--dry-run] [--format text|json]
239
- pr-shepherd clean current [--dry-run] [--format text|json]
240
- pr-shepherd clean repo [--dry-run] [--format text|json]
241
- pr-shepherd clean all [--dry-run] [--format text|json]
263
+ pr-shepherd clean pr [number] [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
264
+ pr-shepherd clean branch [name] [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
265
+ pr-shepherd clean current [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
266
+ pr-shepherd clean repo [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
267
+ pr-shepherd clean all [--dry-run] [--format text|json] [--poll-mode auto|poll|event]
242
268
 
243
269
  Variants:
244
270
  pr [number] Remove state for one PR. Defaults to current branch PR.
@@ -251,6 +277,9 @@ Variants:
251
277
  Flags:
252
278
  --dry-run Preview paths without removing them.
253
279
  --format text|json Output format. Default: text.
280
+ --poll-mode auto|poll|event
281
+ Clean the state for that poll mode; event mode keeps it in durable
282
+ state under the git common directory. Default: poll.mode (auto).
254
283
  --help, -h Print this help and exit before any cleanup.
255
284
 
256
285
  Exit code: 0 on success (including a no-op --dry-run on a nonexistent target); nonzero on failure (sysexits.h — see docs/exit-codes.md).`;
@@ -291,8 +320,23 @@ Malformed or unrecognized journal content is returned as {"ok":false,...} with e
291
320
  On POSIX, the final body-file path entry must be a readable regular file in a trusted parent directory;
292
321
  symlinks, FIFOs, devices, and unreadable paths exit 66. Unsupported platforms fail closed with exit 66.
293
322
  --help, -h Print this help and exit before any I/O.`;
294
- readonly "log-file": "pr-shepherd log-file\n\nPrint the per-worktree append-only debug log path for the current repository.\nThe log is created by the first non-help pr-shepherd command that initializes logging.\n\nUsage:\n pr-shepherd log-file [--format text|json]\n\nFlags:\n --format text|json Print a raw path or {\"path\": \"...\"} JSON. Default: text.\n --help, -h Print this help and exit before logging setup.\n\nEnvironment:\n PR_SHEPHERD_LOG_DISABLED=1 disables logging.\n PR_SHEPHERD_STATE_DIR overrides the base state directory.\n\nExit code: 0 on success; 1 if repository identity cannot be resolved.";
295
- readonly top: "pr-shepherd\n\nAutonomous PR CI monitor and review-comment resolver for agentic coding tools.\n\nUsage:\n pr-shepherd --version | -v\n pr-shepherd --help | -h\n pr-shepherd [PR ...] [poll-flags] [iterate-flags]\n pr-shepherd --stack PR [poll-flags] [iterate-flags]\n pr-shepherd iterate [PR] [iterate-flags]\n pr-shepherd apply review [PR] [review-flags]\n pr-shepherd apply files [PR] [files...] [--tests] [--match REGEX]\n pr-shepherd apply journal [PR] <item> [--dry-run] [--format text|json]\n pr-shepherd apply check-blocker [PR] --check <name> (--blocked-by <ref>|--clear)\n pr-shepherd apply queue-removal [PR] --require-sha <head> --queue-commit <commit> --removed-at <unix>\n pr-shepherd journal extract --body-file <path>\n pr-shepherd build-suggestion-patches [PR] --thread-id ID --message MSG [groups...]\n pr-shepherd admin clean <pr|branch|current|repo|all> [value] [flags]\n pr-shepherd admin log-file [--format text|json]\n\nCommands:\n [PR ...] Poll one PR, an explicit same-repository set, or a native stack.\n iterate Run one iterate tick (single-tick alias).\n apply review Apply review-state mutations after fixes.\n apply files Mark selected changed files as viewed.\n apply journal Append a list item to the Shepherd Journal details block of a PR body.\n apply check-blocker Record that a failing check is blocked on an external PR or issue.\n apply queue-removal Acknowledge one current CI-driven native-stack queue removal.\n journal extract Extract a validated Shepherd Journal from a local PR-body file as JSON.\n build-suggestion-patches\n Convert ordered GitHub suggestion threads into patches and commit instructions.\n admin clean Remove pr-shepherd state files.\n admin log-file Print the per-worktree debug log path.\n\nPR argument:\n PR may be a number, owner/repo#number, or a GitHub pull request URL.\n Multiple PRs must name one repository. --stack PR selects every entry in PR's native stack.\n When omitted, pr-shepherd infers the current branch's pull request.\n\nCommon flags:\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed poll-tick lines.\n --help, -h Print help and exit before any GitHub, git, config, or log I/O.\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n\nPolling flags:\n --interval <duration> Delay between WAIT ticks. Bare number = seconds. Default: poll.intervalSeconds (built-in 60s). Stack and multi-PR polls multiply that by poll.stackIntervalFactor (built-in 2) unless this flag is set.\n --timeout <duration> Poll wall-clock cap for WAIT ticks. Bare number = seconds. Default: poll.timeoutSeconds (built-in 4.5m).\n --debounce <duration> Settle window after first FIX_CODE or stack SHEPHERD before returning. Bare number = seconds. Default: poll.debounceSeconds (built-in 60s). 0 disables.\n --quiet-status Print only changed WAIT snapshots. Overrides poll.quietStatus.\n --no-quiet-status Print every WAIT snapshot. Overrides poll.quietStatus.\n --until-terminal Continue through WAIT/MARK_READY until READY/FIX_CODE/MERGE/CANCEL/ESCALATE or stack SHEPHERD.\n\nClean variants:\n pr [number] Remove state for one PR. Defaults to current branch PR.\n branch [name] Remove state for a branch's PR. Defaults to current branch.\n current Alias for branch against the current branch.\n repo Remove all state for the current repository.\n all Remove all pr-shepherd state.\n\nExit codes: 0 done, 10-19 PR state, 64-78 shepherd failed (sysexits.h).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n 16 SHEPHERD (--stack only: run the listed one-PR sessions, then rerun the selector)\nSee docs/exit-codes.md for the full sysexits.h error-code table.\n\nDuration examples: 30s, 4.5m, 1h. A bare number uses each flag's default unit (see above); decimals are allowed with an explicit unit (4.5m).\n\nRun 'pr-shepherd <command> --help' for command-specific details.";
323
+ readonly playbook: `pr-shepherd playbook
324
+
325
+ Print a playbook named by a playbook pointer in the output's ## Instructions. Playbooks ship with the
326
+ package, so this works without the pr-shepherd skill installed. With no name, lists every playbook.
327
+ This command performs no GitHub, git, or log I/O.
328
+
329
+ Usage:
330
+ pr-shepherd playbook [name] [--format text|json]
331
+
332
+ Flags:
333
+ --format text|json Markdown text (default) or one JSON line: {"name","content"} or {"playbooks":[...]}.
334
+
335
+ The name is case-insensitive; spaces and hyphens are equivalent ("Fix-code loop" and fix-code-loop match).
336
+ Unknown names exit 64 and list the available playbooks.
337
+ --help, -h Print this help and exit before any I/O.`;
338
+ readonly "log-file": "pr-shepherd log-file\n\nPrint the per-worktree append-only debug log path for the current repository.\nThe log is created by the first non-help pr-shepherd command that initializes logging.\n\nUsage:\n pr-shepherd log-file [--format text|json] [--poll-mode auto|poll|event]\n\nFlags:\n --format text|json Print a raw path or {\"path\": \"...\"} JSON. Default: text.\n --poll-mode auto|poll|event\n Report the log for that poll mode; event mode keeps it in durable\n state under the git common directory. Default: poll.mode (auto).\n --help, -h Print this help and exit before logging setup.\n\nEnvironment:\n PR_SHEPHERD_LOG_DISABLED=1 disables logging.\n PR_SHEPHERD_STATE_DIR overrides the base state directory.\n\nExit code: 0 on success; 1 if repository identity cannot be resolved.";
339
+ readonly top: "pr-shepherd\n\nAutonomous PR CI monitor and review-comment resolver for agentic coding tools.\n\nUsage:\n pr-shepherd --version | -v\n pr-shepherd --help | -h\n pr-shepherd [PR ...] [poll-flags] [iterate-flags]\n pr-shepherd --stack PR [poll-flags] [iterate-flags]\n pr-shepherd iterate [PR] [iterate-flags]\n pr-shepherd apply merge [PR] --require-sha SHA --merge-action ACTION --transport rest\n pr-shepherd apply review [PR] [review-flags]\n pr-shepherd apply files [PR] [files...] [--tests] [--match REGEX]\n pr-shepherd apply journal [PR] <item> [--dry-run] [--format text|json]\n pr-shepherd apply check-blocker [PR] --check <name> (--blocked-by <ref>|--clear)\n pr-shepherd apply queue-removal [PR] --require-sha <head> --queue-commit <commit> --removed-at <unix>\n pr-shepherd journal extract --body-file <path>\n pr-shepherd build-suggestion-patches [PR] --thread-id ID --message MSG [groups...]\n pr-shepherd admin clean <pr|branch|current|repo|all> [value] [flags]\n pr-shepherd admin log-file [--format text|json]\n\nCommands:\n [PR ...] Poll one PR, an explicit same-repository set, or a native stack.\n iterate Run one iterate tick (single-tick alias).\n apply merge Submit or resume a guarded asynchronous merge or enqueue request.\n apply review Apply review-state mutations after fixes.\n apply files Mark selected changed files as viewed.\n apply journal Append a list item to the Shepherd Journal details block of a PR body.\n apply check-blocker Record that a failing check is blocked on an external PR or issue.\n apply queue-removal Acknowledge one current CI-driven native-stack queue removal.\n journal extract Extract a validated Shepherd Journal from a local PR-body file as JSON.\n build-suggestion-patches\n Convert ordered GitHub suggestion threads into patches and commit instructions.\n playbook Print a playbook named by an instruction pointer.\n admin clean Remove pr-shepherd state files.\n admin log-file Print the per-worktree debug log path.\n\nPR argument:\n PR may be a number, owner/repo#number, or a GitHub pull request URL.\n Multiple PRs must name one repository. --stack PR selects every entry in PR's native stack.\n When omitted, pr-shepherd infers the current branch's pull request.\n\nCommon flags:\n --transport auto|graphql|rest Select GitHub transport. Default: github.transport (auto).\n --format text|json Output Markdown text or JSON. Default: text.\n --verbose Include verbose iterate fields and detailed poll-tick lines.\n --help, -h Print help and exit before any GitHub, git, config, or log I/O.\n\nIterate flags:\n --ready-delay <duration> Settle window before a clean PR cancels. Bare number = minutes. Example: 15m.\n --stall-timeout <duration> Escalate repeated unchanged failures after this duration. Bare number = minutes. 0 disables.\n --no-auto-mark-ready Do not convert draft PRs to ready for review.\n --no-auto-cancel-actionable Legacy no-op; workflow runs are never cancelled.\n --merge Shepherd through readiness, then emit a merge or merge-queue command.\n --instructions playbook|inline Render fix_code steps inline every tick (default) or fold the invariant ones into a playbook pointer. Default: iterate.instructions (inline).\n\nPolling flags:\n --interval <duration> Delay between WAIT ticks. Bare number = seconds. Default: poll.intervalSeconds (built-in 60s). Stack and multi-PR polls multiply that by poll.stackIntervalFactor (built-in 2) unless this flag is set.\n --timeout <duration> Poll wall-clock cap for WAIT ticks. Bare number = seconds. Default: poll.timeoutSeconds (built-in 4.5m).\n --debounce <duration> Settle window after first FIX_CODE or stack SHEPHERD before returning. Bare number = seconds. Default: poll.debounceSeconds (built-in 60s). 0 disables.\n --quiet-status Print only changed WAIT snapshots. Overrides poll.quietStatus.\n --no-quiet-status Print every WAIT snapshot. Overrides poll.quietStatus.\n --until-terminal Continue through WAIT/MARK_READY until READY/FIX_CODE/MERGE/CANCEL/ESCALATE or stack SHEPHERD.\n\nClean variants:\n pr [number] Remove state for one PR. Defaults to current branch PR.\n branch [name] Remove state for a branch's PR. Defaults to current branch.\n current Alias for branch against the current branch.\n repo Remove all state for the current repository.\n all Remove all pr-shepherd state.\n\nExit codes: 0 done, 10-19 PR state, 64-78 shepherd failed (sysexits.h).\n 0 CANCEL (merged or ready-delay elapsed)\n 10 WAIT or READY\n 11 MARK_READY\n 12 FIX_CODE\n 13 ESCALATE\n 14 CANCEL (closed without merging)\n 15 MERGE\n 16 SHEPHERD (--stack only: run the listed one-PR sessions, then rerun the selector)\nSee docs/exit-codes.md for the full sysexits.h error-code table.\n\nDuration examples: 30s, 4.5m, 1h. A bare number uses each flag's default unit (see above); decimals are allowed with an explicit unit (4.5m).\n\nRun 'pr-shepherd <command> --help' for command-specific details.";
296
340
  };
297
341
  /** Resolve help keys for nested public commands before any command I/O. */
298
342
  export declare function helpKeyForArgs(args: string[]): keyof typeof USAGE;
package/bin/cli/help.mjs CHANGED
@@ -7,6 +7,8 @@ export const USAGE = {
7
7
  };
8
8
  /** Resolve help keys for nested public commands before any command I/O. */
9
9
  export function helpKeyForArgs(args) {
10
+ if (args[0] === "apply" && args[1] === "merge")
11
+ return "apply merge";
10
12
  if (args[0] === "apply" && args[1] === "review")
11
13
  return "apply review";
12
14
  if (args[0] === "apply" && args[1] === "files")
@@ -1,3 +1,5 @@
1
1
  import type { IterateResult } from "../types.mts";
2
+ /** True when the summary-line branch phrase names the PR base branch. */
3
+ export declare function branchSegmentShowsBase(result: IterateResult): boolean;
2
4
  /** Summary-line branch phrase. Empty when the PR is not behind or conflicting. */
3
5
  export declare function branchStateSegment(result: IterateResult): string;
@@ -1,13 +1,18 @@
1
+ /** True when the summary-line branch phrase names the PR base branch. */
2
+ export function branchSegmentShowsBase(result) {
3
+ if (!result.baseBranch)
4
+ return false;
5
+ if (result.mergeStatus === "BEHIND")
6
+ return true;
7
+ return result.mergeStatus === "CONFLICTS" && !result.stackTrunkConflict;
8
+ }
1
9
  /** Summary-line branch phrase. Empty when the PR is not behind or conflicting. */
2
10
  export function branchStateSegment(result) {
3
- if (result.mergeStatus === "BEHIND" && result.baseBranch) {
4
- return `**branch** behind PR base \`${result.baseBranch}\``;
5
- }
6
11
  if (result.mergeStatus === "CONFLICTS" && result.stackTrunkConflict) {
7
12
  return `**branch** conflicts with stack trunk \`${result.stackTrunkConflict}\``;
8
13
  }
9
- if (result.mergeStatus === "CONFLICTS" && result.baseBranch) {
10
- return `**branch** conflicts with PR base \`${result.baseBranch}\``;
11
- }
12
- return "";
14
+ if (!branchSegmentShowsBase(result))
15
+ return "";
16
+ const state = result.mergeStatus === "BEHIND" ? "behind" : "conflicts with";
17
+ return `**branch** ${state} PR base \`${result.baseBranch}\``;
13
18
  }
@@ -1,4 +1,4 @@
1
- import type { loadConfig } from "../config/load.mts";
1
+ import { type loadConfig, type InstructionStyle, type PollMode } from "../config/load.mts";
2
2
  interface IterateFlags {
3
3
  readyDelaySuffix: string | undefined | null;
4
4
  readyDelaySeconds: number;
@@ -7,6 +7,12 @@ interface IterateFlags {
7
7
  noAutoMarkReady: boolean;
8
8
  noAutoCancelActionable: boolean;
9
9
  merge: boolean;
10
+ /** `null` when `--instructions` was invalid (an error was already printed). */
11
+ instructions: InstructionStyle | null | undefined;
12
+ /** `null` when `--poll-mode` was invalid (an error was already printed). */
13
+ pollMode: PollMode | null | undefined;
10
14
  }
15
+ /** True when any flag failed validation; the usage error is already printed. */
16
+ export declare function hasInvalidIterateFlags(flags: IterateFlags): boolean;
11
17
  export declare function parseIterateFlags(extra: string[], cfg: ReturnType<typeof loadConfig>): IterateFlags;
12
18
  export {};
@@ -1,9 +1,18 @@
1
+ import { INSTRUCTION_STYLES, POLL_MODES, isInstructionStyle, isPollMode, } from "../config/load.mjs";
2
+ import { EXIT } from "../exit-codes.mjs";
1
3
  import { getFlag, hasFlag } from "./args.mjs";
2
4
  import { parseDurationToSeconds } from "./duration.mjs";
3
5
  import { validateSecondsDurationFlag } from "./duration-flag.mjs";
4
6
  // --ready-delay and --stall-timeout are minute-family flags: a bare number means minutes, and 0 is a
5
7
  // valid value (it disables the ready-delay settle window / stall-timeout escalation, respectively).
6
8
  const MINUTE_FLAG_OPTS = { defaultUnit: "m", allowZero: true };
9
+ /** True when any flag failed validation; the usage error is already printed. */
10
+ export function hasInvalidIterateFlags(flags) {
11
+ return (flags.readyDelaySuffix === null ||
12
+ flags.stallTimeoutSuffix === null ||
13
+ flags.instructions === null ||
14
+ flags.pollMode === null);
15
+ }
7
16
  export function parseIterateFlags(extra, cfg) {
8
17
  const readyDelayStr = getFlag(extra, "--ready-delay");
9
18
  const readyDelaySuffix = validateSecondsDurationFlag("pr-shepherd", "--ready-delay", readyDelayStr, hasFlag(extra, "--ready-delay"), MINUTE_FLAG_OPTS);
@@ -14,7 +23,10 @@ export function parseIterateFlags(extra, cfg) {
14
23
  const stallTimeoutStr = getFlag(extra, "--stall-timeout");
15
24
  const stallTimeoutSuffix = validateSecondsDurationFlag("pr-shepherd", "--stall-timeout", stallTimeoutStr, hasFlag(extra, "--stall-timeout"), MINUTE_FLAG_OPTS);
16
25
  const stallTimeoutSeconds = parseDurationToSeconds(stallTimeoutSuffix ?? "", cfg.iterate.stallTimeoutMinutes * 60, MINUTE_FLAG_OPTS);
26
+ const instructions = parseInstructionsFlag(extra);
17
27
  return {
28
+ instructions,
29
+ pollMode: parsePollModeFlag(extra),
18
30
  readyDelaySuffix,
19
31
  readyDelaySeconds,
20
32
  stallTimeoutSuffix,
@@ -24,3 +36,29 @@ export function parseIterateFlags(extra, cfg) {
24
36
  merge,
25
37
  };
26
38
  }
39
+ /** Validate `--instructions`. Returns `undefined` when absent, `null` after printing a usage error. */
40
+ function parseInstructionsFlag(extra) {
41
+ const value = getFlag(extra, "--instructions");
42
+ if (!hasInstructionsFlag(extra))
43
+ return undefined;
44
+ if (isInstructionStyle(value))
45
+ return value;
46
+ process.stderr.write(`pr-shepherd: --instructions must be one of ${INSTRUCTION_STYLES.join(", ")}, got ${JSON.stringify(value ?? "")}\n`);
47
+ process.exitCode = EXIT.USAGE;
48
+ return null;
49
+ }
50
+ function hasInstructionsFlag(extra) {
51
+ return extra.some((arg) => arg === "--instructions" || arg.startsWith("--instructions="));
52
+ }
53
+ /** Validate `--poll-mode`. Returns `undefined` when absent, `null` after printing a usage error. */
54
+ function parsePollModeFlag(extra) {
55
+ const value = getFlag(extra, "--poll-mode");
56
+ if (!extra.some((arg) => arg === "--poll-mode" || arg.startsWith("--poll-mode="))) {
57
+ return undefined;
58
+ }
59
+ if (isPollMode(value))
60
+ return value;
61
+ process.stderr.write(`pr-shepherd: --poll-mode must be one of ${POLL_MODES.join(", ")}, got ${JSON.stringify(value ?? "")}\n`);
62
+ process.exitCode = EXIT.USAGE;
63
+ return null;
64
+ }
@@ -6,12 +6,12 @@ import type { IterateResult } from "../types.mts";
6
6
  * 1. The H1 heading on line 1 contains `[<ACTION>]` — the action tag identifies
7
7
  * the output for logging and validation. Behavior is driven by `## Instructions`,
8
8
  * not by dispatching on the tag.
9
- * 2. `[FIX_CODE]` wraps the `resolve` command under `## Post-fix actions` in
10
- * backticks — the skill extracts the backticked content for execution.
11
- * 3. Every action ends with a `## Instructions` section — numbered `1.`, `2.`, … —
12
- * that tells the agent exactly what to do with this output. The section is
13
- * unconditional: every action, every variant, always emits at least one step.
14
- * The skill simply follows those steps; it does not need its own dispatch table.
9
+ * 2. `[FIX_CODE]` prints the `apply review` command inline, in backticks, in its
10
+ * `## Instructions` step; the agent runs that backticked command as printed.
11
+ * 3. Every action except `cancel` ends with a `## Instructions` section — numbered
12
+ * `1.`, `2.`, … — that tells the agent exactly what to do with this output, with at
13
+ * least one step. `cancel` has no section: the `[CANCEL]` tag already means stop this
14
+ * PR's loop. The skill follows those steps; it does not need its own dispatch table.
15
15
  */
16
16
  export declare function formatIterateResult(result: IterateResult, opts?: {
17
17
  verbose?: boolean;
@@ -8,6 +8,9 @@ import { formatApiUsage, formatQuotaWarning } from "./api-usage-formatter.mjs";
8
8
  import { formatActivityLine } from "./iterate-activity-formatter.mjs";
9
9
  import { branchStateSegment } from "./iterate-branch-segment.mjs";
10
10
  import { insertRuleAutoResolveSection } from "../commands/rule-auto-resolve-format.mjs";
11
+ import { formatTransportEvidence } from "./transport-formatter.mjs";
12
+ import { formatNextCheckLines, formatPollModeSegment } from "./next-check-format.mjs";
13
+ import { formatPrUrl } from "../pr-reference.mjs";
11
14
  /**
12
15
  * Format an IterateResult as human-readable Markdown.
13
16
  *
@@ -15,31 +18,51 @@ import { insertRuleAutoResolveSection } from "../commands/rule-auto-resolve-form
15
18
  * 1. The H1 heading on line 1 contains `[<ACTION>]` — the action tag identifies
16
19
  * the output for logging and validation. Behavior is driven by `## Instructions`,
17
20
  * not by dispatching on the tag.
18
- * 2. `[FIX_CODE]` wraps the `resolve` command under `## Post-fix actions` in
19
- * backticks — the skill extracts the backticked content for execution.
20
- * 3. Every action ends with a `## Instructions` section — numbered `1.`, `2.`, … —
21
- * that tells the agent exactly what to do with this output. The section is
22
- * unconditional: every action, every variant, always emits at least one step.
23
- * The skill simply follows those steps; it does not need its own dispatch table.
21
+ * 2. `[FIX_CODE]` prints the `apply review` command inline, in backticks, in its
22
+ * `## Instructions` step; the agent runs that backticked command as printed.
23
+ * 3. Every action except `cancel` ends with a `## Instructions` section — numbered
24
+ * `1.`, `2.`, … — that tells the agent exactly what to do with this output, with at
25
+ * least one step. `cancel` has no section: the `[CANCEL]` tag already means stop this
26
+ * PR's loop. The skill follows those steps; it does not need its own dispatch table.
24
27
  */
25
28
  export function formatIterateResult(result, opts) {
26
29
  const verbose = opts?.verbose ?? false;
27
30
  const readyDelaySuffix = opts?.readyDelaySuffix;
28
- const finish = (text) => insertRuleAutoResolveSection(text, result.ruleAutoResolve);
31
+ const repoSeg = ` · **repo** \`${result.repo}\``;
32
+ // Lean: the repo segment repeats what a generated command's PR URL or `--repo` flag already
33
+ // shows. Only the CLI-generated `## Instructions` section counts: review bodies and logs above
34
+ // it are untrusted and may name any repository.
35
+ const dropRepeatedRepo = (full) => {
36
+ if (verbose)
37
+ return full;
38
+ const instructions = full.slice(full.lastIndexOf("\n## Instructions\n") + 1);
39
+ const generated = instructions.startsWith("## Instructions\n") &&
40
+ (instructions.includes(formatPrUrl(result.repo, result.pr)) ||
41
+ instructions.includes(`--repo ${result.repo} `));
42
+ return generated ? full.replace(repoSeg, "") : full;
43
+ };
44
+ const finish = (text) => dropRepeatedRepo(insertRuleAutoResolveSection(text, result.ruleAutoResolve));
29
45
  const heading = `# PR #${result.pr} [${result.action.toUpperCase()}]`;
30
46
  const reviewDecisionSeg = result.mergeStatus === "BLOCKED" && result.reviewDecision
31
47
  ? ` · **reviewDecision** \`${result.reviewDecision}\``
32
48
  : "";
33
49
  const baseBranchSeg = verbose && result.baseBranch ? ` · **baseBranch** \`${result.baseBranch}\`` : "";
34
- const baseLine = `**status** \`${result.status}\` · **merge** \`${result.mergeStateStatus}\`${reviewDecisionSeg} · **state** \`${result.state}\` · **repo** \`${result.repo}\`${baseBranchSeg}`;
50
+ // A CLEAN merge state and an OPEN PR are the trivial defaults; verbose output keeps them.
51
+ const mergeSeg = verbose || result.mergeStateStatus !== "CLEAN"
52
+ ? ` · **merge** \`${result.mergeStateStatus}\``
53
+ : "";
54
+ const stateSeg = verbose || result.state !== "OPEN" ? ` · **state** \`${result.state}\`` : "";
55
+ const baseLine = `**status** \`${result.status}\`${mergeSeg}${reviewDecisionSeg}${stateSeg}${repoSeg}${baseBranchSeg}${formatPollModeSegment(result)}`;
35
56
  const branchSeg = branchStateSegment(result);
36
57
  let summaryLine;
37
58
  if (verbose) {
38
59
  const verboseBranch = branchSeg ? ` · ${branchSeg}` : "";
39
- summaryLine = `**summary** ${result.summary.passing} passing, ${result.summary.skipped} skipped, ${result.summary.filtered} filtered, ${result.summary.inProgress} inProgress, ${result.summary.superseded} superseded · **remainingSeconds** ${result.remainingSeconds} · **blockingBotReviewInProgress** ${result.blockingBotReviewInProgress} · **isDraft** ${result.isDraft} · **shouldCancel** ${result.shouldCancel}${verboseBranch}`;
60
+ summaryLine = `**summary** ${result.summary.passing} passing, ${result.summary.skipped} skipped, ${result.summary.filtered} filtered, ${result.summary.inProgress} inProgress, ${result.summary.superseded} superseded · **remainingSeconds** ${result.remainingSeconds} · **blockingBotReviewInProgress** ${result.blockingBotReviewInProgress} · **isDraft** ${result.isDraft} · **shouldCancel** ${result.shouldCancel}${verboseBranch}${readyDelaySuffix ? ` · **ready-delay** \`${readyDelaySuffix}\` (override)` : ""}`;
40
61
  }
41
62
  else {
42
- const counts = [`${result.summary.passing} passing`];
63
+ const counts = [];
64
+ if (result.summary.passing > 0)
65
+ counts.push(`${result.summary.passing} passing`);
43
66
  if (result.summary.skipped > 0)
44
67
  counts.push(`${result.summary.skipped} skipped`);
45
68
  if (result.summary.filtered > 0)
@@ -48,7 +71,7 @@ export function formatIterateResult(result, opts) {
48
71
  counts.push(`${result.summary.inProgress} inProgress`);
49
72
  if (result.summary.superseded > 0)
50
73
  counts.push(`${result.summary.superseded} superseded`);
51
- const segs = [`**summary** ${counts.join(", ")}`];
74
+ const segs = counts.length > 0 ? [`**summary** ${counts.join(", ")}`] : [];
52
75
  if (result.status === "READY" && result.remainingSeconds > 0) {
53
76
  segs.push(`**remainingSeconds** ${result.remainingSeconds}`);
54
77
  }
@@ -58,13 +81,13 @@ export function formatIterateResult(result, opts) {
58
81
  segs.push(`**isDraft**`);
59
82
  if (branchSeg)
60
83
  segs.push(branchSeg);
61
- summaryLine = segs.join(" · ");
62
- }
63
- // Surface an explicit `--ready-delay` override (set only when the user passed the flag)
64
- // so the active settle window stays visible on every tick. Replaces the rerun command
65
- if (readyDelaySuffix) {
66
- summaryLine += ` · **ready-delay** \`${readyDelaySuffix}\` (override)`;
84
+ // Surface an explicit `--ready-delay` override (set only when the user passed the flag)
85
+ // so the active settle window stays visible on every tick.
86
+ if (readyDelaySuffix)
87
+ segs.push(`**ready-delay** \`${readyDelaySuffix}\` (override)`);
88
+ summaryLine = segs.length > 0 ? segs.join(" · ") : null;
67
89
  }
90
+ const summaryLines = summaryLine ? [summaryLine] : [];
68
91
  const bp = result.branchProtection;
69
92
  const requiredParts = [];
70
93
  if (bp) {
@@ -84,7 +107,7 @@ export function formatIterateResult(result, opts) {
84
107
  }
85
108
  }
86
109
  const requiredLine = requiredParts.length > 0 ? `**required** ${requiredParts.join(", ")}` : null;
87
- const headerLines = [heading, "", baseLine, summaryLine];
110
+ const headerLines = [heading, "", baseLine, ...summaryLines, ...formatTransportEvidence(result)];
88
111
  if (result.mergeRequirements) {
89
112
  headerLines.push(...formatMergeRequirementLines(result.mergeRequirements));
90
113
  }
@@ -104,6 +127,7 @@ export function formatIterateResult(result, opts) {
104
127
  const activityLine = formatActivityLine(result);
105
128
  if (activityLine)
106
129
  headerLines.push(activityLine);
130
+ headerLines.push(...formatNextCheckLines(result.nextCheck));
107
131
  const header = headerLines.join("\n");
108
132
  const quotaWarning = formatQuotaWarning(result.quotaWarning);
109
133
  const apiUsage = verbose ? formatApiUsage(result.apiUsage) : null;
@@ -111,12 +135,12 @@ export function formatIterateResult(result, opts) {
111
135
  const telemetrySections = [quotaWarning, apiUsage, verboseChecks];
112
136
  switch (result.action) {
113
137
  case "ready":
114
- return joinSections([
138
+ return dropRepeatedRepo(joinSections([
115
139
  header,
116
140
  ...telemetrySections,
117
141
  adaptIterateLog(result.log),
118
142
  `## Instructions\n\n${numberInstructions(buildSimpleIterateInstructions(result))}`,
119
- ]);
143
+ ]));
120
144
  case "wait": {
121
145
  const waitLines = [header, ...telemetrySections, adaptIterateLog(result.log)];
122
146
  if (result.deferredWork)
@@ -134,7 +158,18 @@ export function formatIterateResult(result, opts) {
134
158
  case "merge":
135
159
  return finish(formatMergeAction(joinSections([header, ...telemetrySections]), result));
136
160
  case "cancel": {
137
- const cancelHeaderLines = [`${heading} — ${result.reason}`, "", baseLine, summaryLine];
161
+ // A merged or closed PR needs no more data: the `[CANCEL]` heading is enough. Cancel has no
162
+ // instruction steps; the skill's recurrence rule says what to do after it.
163
+ if (!verbose && (result.reason === "merged" || result.reason === "closed")) {
164
+ return finish(`${heading} — ${result.reason}`);
165
+ }
166
+ const cancelHeaderLines = [
167
+ `${heading} — ${result.reason}`,
168
+ "",
169
+ baseLine,
170
+ ...summaryLines,
171
+ ...formatTransportEvidence(result),
172
+ ];
138
173
  if (result.mergeRequirements) {
139
174
  cancelHeaderLines.push(...formatMergeRequirementLines(result.mergeRequirements));
140
175
  }
@@ -158,7 +193,6 @@ export function formatIterateResult(result, opts) {
158
193
  ...(apiUsage ? [apiUsage] : []),
159
194
  ...(verboseChecks ? [verboseChecks] : []),
160
195
  adaptIterateLog(result.log),
161
- `## Instructions\n\n${numberInstructions(buildSimpleIterateInstructions(result))}`,
162
196
  ]));
163
197
  }
164
198
  case "escalate":