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
@@ -10,6 +10,7 @@ query GetPrBody($owner: String!, $repo: String!, $pr: Int!) {
10
10
  repository(owner: $owner, name: $repo) {
11
11
  pullRequest(number: $pr) {
12
12
  id
13
+ fullDatabaseId
13
14
  body
14
15
  }
15
16
  }
@@ -17,6 +17,7 @@ query PollStackSummary(
17
17
  login
18
18
  }
19
19
  repository(owner: $owner, name: $repo) {
20
+ viewerPermission
20
21
  viewerCanAdminister
21
22
  mergeCommitAllowed
22
23
  squashMergeAllowed
@@ -16,10 +16,12 @@ fragment PollSummaryCheckContexts on StatusCheckRollupContextConnection {
16
16
  completedAt
17
17
  checkSuite {
18
18
  createdAt
19
+ updatedAt
19
20
  workflowRun {
20
21
  databaseId
21
22
  event
22
23
  createdAt
24
+ updatedAt
23
25
  workflow {
24
26
  databaseId
25
27
  name
@@ -30,6 +32,9 @@ fragment PollSummaryCheckContexts on StatusCheckRollupContextConnection {
30
32
  ... on StatusContext {
31
33
  context
32
34
  state
35
+ createdAt
36
+ targetUrl
37
+ description
33
38
  }
34
39
  }
35
40
  }
@@ -1,4 +1,7 @@
1
1
  fragment PollSummaryPr on PullRequest {
2
+ # Scalars and objects below marked "handoff" add no connection, so the stack
3
+ # summary keeps its price; they let a routed layer's first tick skip BatchPr.
4
+ id
2
5
  number
3
6
  title
4
7
  url
@@ -10,12 +13,33 @@ fragment PollSummaryPr on PullRequest {
10
13
  updatedAt
11
14
  isDraft
12
15
  viewerCanUpdate
16
+ # handoff
17
+ viewerDidAuthor
18
+ viewerCanEnableAutoMerge
19
+ viewerCanEditFiles
20
+ headRepository {
21
+ nameWithOwner
22
+ viewerPermission
23
+ }
24
+ isMergeQueueEnabled
25
+ # Aliased: the summary's own `autoMergeRequest` is the REST-projected status.
26
+ batchAutoMergeRequest: autoMergeRequest {
27
+ enabledAt
28
+ mergeMethod
29
+ enabledBy {
30
+ login
31
+ }
32
+ }
13
33
  headRefName
14
34
  headRefOid
15
35
  baseRefName
16
36
  baseRefOid
17
37
  baseRef {
18
38
  ...RefRules
39
+ # handoff: the live base tip
40
+ target {
41
+ oid
42
+ }
19
43
  }
20
44
  mergeable
21
45
  mergeStateStatus
@@ -53,6 +77,9 @@ fragment PollSummaryPr on PullRequest {
53
77
  ... on Mannequin {
54
78
  login
55
79
  }
80
+ ... on Team {
81
+ name
82
+ }
56
83
  }
57
84
  }
58
85
  }
@@ -127,12 +154,15 @@ fragment PollSummaryPr on PullRequest {
127
154
  id
128
155
  body
129
156
  isMinimized
157
+ viewerCanMinimize
130
158
  url
131
159
  authorAssociation
132
160
  author {
133
161
  __typename
134
162
  login
135
163
  }
164
+ createdAt
165
+ updatedAt
136
166
  }
137
167
  }
138
168
  reviews(last: 100) {
@@ -145,11 +175,18 @@ fragment PollSummaryPr on PullRequest {
145
175
  body
146
176
  state
147
177
  isMinimized
178
+ viewerCanMinimize
148
179
  authorAssociation
149
180
  author {
150
181
  __typename
151
182
  login
152
183
  }
184
+ createdAt
185
+ updatedAt
186
+ url
187
+ commit {
188
+ oid
189
+ }
153
190
  }
154
191
  }
155
192
  reviewThreads(last: 20) {
@@ -161,27 +198,21 @@ fragment PollSummaryPr on PullRequest {
161
198
  id
162
199
  isResolved
163
200
  isOutdated
201
+ viewerCanReply
202
+ viewerCanResolve
164
203
  path
165
- rootComments: comments(first: 1) {
166
- nodes {
167
- id
168
- body
169
- url
170
- viewerDidAuthor
171
- authorAssociation
172
- author {
173
- __typename
174
- login
175
- }
176
- }
177
- }
178
- comments(last: 5) {
204
+ line
205
+ startLine
206
+ # One window from the root: a second nested connection would cost 20 more
207
+ # connection-requests per PR. `hasPreviousPage` marks comments outside it.
208
+ comments(first: 5) {
179
209
  totalCount
180
210
  pageInfo {
181
- hasPreviousPage
211
+ hasPreviousPage: hasNextPage
182
212
  }
183
213
  nodes {
184
214
  id
215
+ isMinimized
185
216
  body
186
217
  url
187
218
  authorAssociation
@@ -190,25 +221,44 @@ fragment PollSummaryPr on PullRequest {
190
221
  __typename
191
222
  login
192
223
  }
224
+ pullRequestReview {
225
+ id
226
+ }
227
+ path
228
+ line
229
+ startLine
230
+ createdAt
231
+ updatedAt
193
232
  }
194
233
  }
195
234
  }
196
235
  }
197
236
  commits(last: 1) {
237
+ totalCount
198
238
  nodes {
199
239
  commit {
200
240
  oid
201
241
  committedDate
202
242
  checkSuites(first: 50) {
243
+ pageInfo {
244
+ hasNextPage
245
+ }
203
246
  nodes {
247
+ id
204
248
  status
205
249
  conclusion
206
250
  workflowRun {
251
+ databaseId
207
252
  event
253
+ url
254
+ workflow {
255
+ name
256
+ }
208
257
  }
209
258
  }
210
259
  }
211
260
  statusCheckRollup {
261
+ state
212
262
  contexts(last: 100) {
213
263
  ...PollSummaryCheckContexts
214
264
  }
@@ -0,0 +1,42 @@
1
+ # The CheckRun fields BatchPr reads that the stack summary does not, for the
2
+ # routed layers' handoffs. One request per run, so 100 runs price at 1 point.
3
+ query StackHandoffCheckRuns($ids: [ID!]!) {
4
+ _shepherdRateLimit: rateLimit {
5
+ cost
6
+ limit
7
+ nodeCount
8
+ remaining
9
+ resetAt
10
+ used
11
+ }
12
+ nodes(ids: $ids) {
13
+ __typename
14
+ ... on CheckRun {
15
+ id
16
+ title
17
+ summary
18
+ annotations(first: 1) {
19
+ totalCount
20
+ nodes {
21
+ fullDatabaseId
22
+ path
23
+ annotationLevel
24
+ title
25
+ message
26
+ rawDetails
27
+ blobUrl
28
+ location {
29
+ start {
30
+ line
31
+ column
32
+ }
33
+ end {
34
+ line
35
+ column
36
+ }
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
@@ -2,8 +2,10 @@
2
2
  import { appendEntry, nextEntry } from "../log/log-file.mjs";
3
3
  import { formatRequestEntry, formatResponseEntry } from "../log/session.mjs";
4
4
  import { GitHubRequestError } from "./errors.mjs";
5
- import { withGraphQlInternalRetry } from "./graphql-internal-retry.mjs";
5
+ import { isGraphQlMutationDocument, withGraphQlInternalRetry } from "./graphql-internal-retry.mjs";
6
+ import { githubFetch } from "./github-fetch.mjs";
6
7
  import { formatGraphQlErrors, parseGraphQlPayload } from "./graphql-response.mjs";
8
+ import { CCR_GRAPHQL_REFUSAL_MESSAGE, isCcrGraphqlRefusal } from "./graphql-session-refusal.mjs";
7
9
  import { makeAuthHeaders } from "./http-auth.mjs";
8
10
  import { requestWithTokenRetry } from "./http-request.mjs";
9
11
  import { parseRateLimit, parseRetryAfter, redactToken, sanitizeBody, } from "./http-utils.mjs";
@@ -27,7 +29,7 @@ async function graphqlInner(query, vars, opts) {
27
29
  const auth = await makeAuthHeaders();
28
30
  authSource = auth.source;
29
31
  credentialFingerprint = auth.fingerprint;
30
- return fetch(url, {
32
+ return githubFetch(url, {
31
33
  method: "POST",
32
34
  headers: auth.headers,
33
35
  body: JSON.stringify({ query, variables: vars }),
@@ -41,7 +43,7 @@ async function graphqlInner(query, vars, opts) {
41
43
  durationMs,
42
44
  authSource,
43
45
  credentialFingerprint,
44
- }));
46
+ }), !isGraphQlMutationDocument(query), true);
45
47
  const durationMs = Math.round(performance.now() - retryT0);
46
48
  const headerRateLimit = parseRateLimit(res.headers);
47
49
  const retryAfterSeconds = parseRetryAfter(res.headers);
@@ -67,11 +69,14 @@ async function graphqlInner(query, vars, opts) {
67
69
  credentialFingerprint,
68
70
  rateLimit: headerRateLimit ?? undefined,
69
71
  });
70
- throw new GitHubRequestError(`GitHub GraphQL request failed: ${res.status} ${sanitizeBody(body)}`, {
72
+ throw new GitHubRequestError(isCcrGraphqlRefusal(res.status, body)
73
+ ? CCR_GRAPHQL_REFUSAL_MESSAGE
74
+ : `GitHub GraphQL request failed: ${res.status} ${sanitizeBody(body)}`, {
71
75
  status: res.status,
72
76
  rateLimit: headerRateLimit ?? undefined,
73
77
  retryAfterSeconds,
74
78
  authSource,
79
+ responseMessage: redactToken(body),
75
80
  });
76
81
  }
77
82
  let parsed;
@@ -1,2 +1,4 @@
1
+ /** True when the root operation is a mutation. Anonymous `{...}` is a query. */
2
+ export declare function isGraphQlMutationDocument(document: string): boolean;
1
3
  /** Retry GitHub GraphQL engine crashes and resource-limit failures on reads. */
2
4
  export declare function withGraphQlInternalRetry<T>(document: string, run: () => Promise<T>): Promise<T>;
@@ -2,7 +2,7 @@ import { sleep } from "../util/sleep.mjs";
2
2
  import { GitHubRequestError, isRetryableGraphQlInternal, isRetryableGraphQlResourceLimit, } from "./errors.mjs";
3
3
  const GRAPHQL_INTERNAL_RETRY_DELAYS = [500, 1500];
4
4
  /** True when the root operation is a mutation. Anonymous `{...}` is a query. */
5
- function isGraphQlMutationDocument(document) {
5
+ export function isGraphQlMutationDocument(document) {
6
6
  let rest = document;
7
7
  for (;;) {
8
8
  rest = rest.replace(/^\s+/, "");
@@ -0,0 +1,6 @@
1
+ import type { GitHubRequestError } from "./errors.mts";
2
+ /** Decide whether a quota-shaped GraphQL error needs proof from REST's resource endpoint. */
3
+ export declare function needsGraphQlQuotaProbe(error: GitHubRequestError): boolean;
4
+ export declare function hasMixedGraphQlQuotaErrors(errors: GitHubRequestError["graphqlErrors"]): boolean;
5
+ /** REST can prove exhaustion when the GraphQL refusal has no usable quota sample. */
6
+ export declare function isPrimaryGraphQlQuotaExhausted(): Promise<boolean>;
@@ -0,0 +1,56 @@
1
+ import { rest } from "./rest-http.mjs";
2
+ /** Decide whether a quota-shaped GraphQL error needs proof from REST's resource endpoint. */
3
+ export function needsGraphQlQuotaProbe(error) {
4
+ const response = error.responseMessage ?? "";
5
+ const messages = [
6
+ response,
7
+ error.message,
8
+ ...(error.graphqlErrors?.map((entry) => entry.message) ?? []),
9
+ ].join(" ");
10
+ if (error.retryAfterSeconds !== undefined ||
11
+ /secondary (?:rate )?limit|abuse detection/i.test(messages))
12
+ return false;
13
+ if (error.rateLimit && (!error.rateLimit.resource || error.rateLimit.resource === "graphql"))
14
+ return false;
15
+ const errors = error.graphqlErrors;
16
+ if (hasMixedGraphQlQuotaErrors(errors))
17
+ return false;
18
+ const quotaRefusal = errors?.length
19
+ ? errors.every(isQuotaError)
20
+ : /api rate limit exceeded/i.test(parseResponseMessage(response) || error.message);
21
+ return quotaRefusal && [200, 403, 429].includes(error.status);
22
+ }
23
+ export function hasMixedGraphQlQuotaErrors(errors) {
24
+ return !!errors?.some(isQuotaError) && !errors.every(isQuotaError);
25
+ }
26
+ function isQuotaError(error) {
27
+ return (error.type?.toUpperCase() === "RATE_LIMITED" || /api rate limit exceeded/i.test(error.message));
28
+ }
29
+ /** REST can prove exhaustion when the GraphQL refusal has no usable quota sample. */
30
+ export async function isPrimaryGraphQlQuotaExhausted() {
31
+ try {
32
+ const value = await rest("GET", "/rate_limit");
33
+ if (!value || typeof value !== "object" || Array.isArray(value))
34
+ return false;
35
+ const resources = value["resources"];
36
+ if (!resources || typeof resources !== "object" || Array.isArray(resources))
37
+ return false;
38
+ const graphql = resources["graphql"];
39
+ if (!graphql || typeof graphql !== "object" || Array.isArray(graphql))
40
+ return false;
41
+ const remaining = graphql["remaining"];
42
+ return typeof remaining === "number" && Number.isFinite(remaining) && remaining <= 0;
43
+ }
44
+ catch {
45
+ return false;
46
+ }
47
+ }
48
+ function parseResponseMessage(response) {
49
+ try {
50
+ const parsed = JSON.parse(response);
51
+ if (typeof parsed.message === "string")
52
+ return parsed.message;
53
+ }
54
+ catch { }
55
+ return response.trim();
56
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Whether a GraphQL response is the Claude Code cloud proxy's blanket refusal. Inspects the raw
3
+ * body, because the proxy appends a long list of REST routes that pushes the refusal past the
4
+ * truncated error message.
5
+ */
6
+ export declare function isCcrGraphqlRefusal(status: number, raw: string): boolean;
7
+ /** Exit-77 message for an explicit `--transport graphql` run inside a Claude Code cloud session. */
8
+ export declare const CCR_GRAPHQL_REFUSAL_MESSAGE: string;
@@ -0,0 +1,14 @@
1
+ /** Text the Claude Code cloud proxy returns, with HTTP 403, for every GraphQL request. */
2
+ const CCR_GRAPHQL_REFUSAL = "GitHub GraphQL is not available from Claude Code sessions";
3
+ /**
4
+ * Whether a GraphQL response is the Claude Code cloud proxy's blanket refusal. Inspects the raw
5
+ * body, because the proxy appends a long list of REST routes that pushes the refusal past the
6
+ * truncated error message.
7
+ */
8
+ export function isCcrGraphqlRefusal(status, raw) {
9
+ return status === 403 && raw.includes(CCR_GRAPHQL_REFUSAL);
10
+ }
11
+ /** Exit-77 message for an explicit `--transport graphql` run inside a Claude Code cloud session. */
12
+ export const CCR_GRAPHQL_REFUSAL_MESSAGE = "GitHub GraphQL is not available from Claude Code sessions (HTTP 403 from the Claude Code proxy). " +
13
+ "Rerun with `--transport rest` or `--transport auto` (the default), or set `github.transport` " +
14
+ "to `rest` or `auto`.";
@@ -1,5 +1,5 @@
1
1
  type RetryLogFn = (response: Response, durationMs: number) => void;
2
- export declare function requestWithTokenRetry(fn: () => Promise<Response>, t0: number, onIntermediate?: RetryLogFn): Promise<{
2
+ export declare function requestWithTokenRetry(fn: () => Promise<Response>, t0: number, onIntermediate?: RetryLogFn, safeRead?: boolean, retryServerErrors?: boolean): Promise<{
3
3
  res: Response;
4
4
  attempt: number;
5
5
  retryT0: number;
@@ -2,14 +2,26 @@ import { clearTokenCache, hasCachedToken } from "./http-auth.mjs";
2
2
  import { isTransportError } from "./http-utils.mjs";
3
3
  import { sleep } from "../util/sleep.mjs";
4
4
  const TRANSPORT_RETRY_DELAYS = [250, 500];
5
- async function fetchWithTransportRetry(fn) {
5
+ async function fetchWithTransportRetry(fn, safeRead, retryServerErrors, onRetry) {
6
6
  let lastErr;
7
7
  for (let attempt = 1; attempt <= TRANSPORT_RETRY_DELAYS.length + 1; attempt++) {
8
8
  try {
9
- return await fn();
9
+ const startedAt = performance.now();
10
+ const response = await fn();
11
+ const delay = TRANSPORT_RETRY_DELAYS[attempt - 1];
12
+ if (safeRead && retryServerErrors && response.status >= 500 && delay !== undefined) {
13
+ onRetry?.(response, Math.round(performance.now() - startedAt));
14
+ try {
15
+ await response.arrayBuffer();
16
+ }
17
+ catch { }
18
+ await sleep(delay);
19
+ continue;
20
+ }
21
+ return response;
10
22
  }
11
23
  catch (err) {
12
- if (!isTransportError(err))
24
+ if (!safeRead || !isTransportError(err))
13
25
  throw err;
14
26
  lastErr = err;
15
27
  const delay = TRANSPORT_RETRY_DELAYS[attempt - 1];
@@ -20,8 +32,8 @@ async function fetchWithTransportRetry(fn) {
20
32
  }
21
33
  throw lastErr;
22
34
  }
23
- export async function requestWithTokenRetry(fn, t0, onIntermediate) {
24
- const res = await fetchWithTransportRetry(fn);
35
+ export async function requestWithTokenRetry(fn, t0, onIntermediate, safeRead = true, retryServerErrors = false) {
36
+ const res = await fetchWithTransportRetry(fn, safeRead, retryServerErrors, onIntermediate);
25
37
  if (res.status === 401 && hasCachedToken()) {
26
38
  onIntermediate?.(res, Math.round(performance.now() - t0));
27
39
  try {
@@ -30,7 +42,11 @@ export async function requestWithTokenRetry(fn, t0, onIntermediate) {
30
42
  catch { }
31
43
  clearTokenCache();
32
44
  const retryT0 = performance.now();
33
- return { res: await fetchWithTransportRetry(fn), attempt: 2, retryT0 };
45
+ return {
46
+ res: await fetchWithTransportRetry(fn, safeRead, retryServerErrors, onIntermediate),
47
+ attempt: 2,
48
+ retryT0,
49
+ };
34
50
  }
35
51
  return { res, attempt: 1, retryT0: t0 };
36
52
  }
@@ -3,7 +3,13 @@ const TRANSPORT_ERROR_CODES = new Set([
3
3
  "ETIMEDOUT",
4
4
  "ECONNREFUSED",
5
5
  "EAI_AGAIN",
6
+ "ENOTFOUND",
7
+ "ENETUNREACH",
8
+ "EHOSTUNREACH",
9
+ "EPIPE",
6
10
  "UND_ERR_CONNECT_TIMEOUT",
11
+ "UND_ERR_HEADERS_TIMEOUT",
12
+ "UND_ERR_BODY_TIMEOUT",
7
13
  "UND_ERR_SOCKET",
8
14
  ]);
9
15
  export function isTransportError(err) {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Load Undici and put the host's legacy dispatcher back when this load replaced
3
+ * it. `load` must be synchronous so a concurrent setGlobalDispatcher() cannot
4
+ * land in the slot and then be overwritten by the restore.
5
+ */
6
+ export declare function loadUndiciKeepingLegacyDispatcher<T>(load: () => T, slot?: symbol): T;
@@ -0,0 +1,44 @@
1
+ const legacyDispatcherSlot = Symbol.for("undici.globalDispatcher.1");
2
+ /**
3
+ * Undici 8's import installs a default agent and copies it onto the legacy
4
+ * dispatcher slot that Node 22 and 24's fetch still reads. Put the host's
5
+ * value back afterwards. The current slot stays writable, so a later
6
+ * setGlobalDispatcher() can replace it and mirror that change onto fetch.
7
+ */
8
+ function restoreLegacyDispatcher(previous, slot) {
9
+ if (previous) {
10
+ Object.defineProperty(globalThis, slot, previous);
11
+ return;
12
+ }
13
+ const installed = Object.getOwnPropertyDescriptor(globalThis, slot);
14
+ // Undici defines this property as non-configurable, so absence can only be
15
+ // represented by clearing the value.
16
+ if (!installed?.writable)
17
+ return;
18
+ Object.defineProperty(globalThis, slot, {
19
+ value: undefined,
20
+ writable: true,
21
+ enumerable: false,
22
+ configurable: false,
23
+ });
24
+ }
25
+ /**
26
+ * Load Undici and put the host's legacy dispatcher back when this load replaced
27
+ * it. `load` must be synchronous so a concurrent setGlobalDispatcher() cannot
28
+ * land in the slot and then be overwritten by the restore.
29
+ */
30
+ export function loadUndiciKeepingLegacyDispatcher(load, slot = legacyDispatcherSlot) {
31
+ const previous = Object.getOwnPropertyDescriptor(globalThis, slot);
32
+ const previousValue = previous?.value;
33
+ try {
34
+ const loaded = load();
35
+ if (Object.getOwnPropertyDescriptor(globalThis, slot)?.value !== previousValue) {
36
+ restoreLegacyDispatcher(previous, slot);
37
+ }
38
+ return loaded;
39
+ }
40
+ catch (error) {
41
+ restoreLegacyDispatcher(previous, slot);
42
+ throw error;
43
+ }
44
+ }
@@ -1,12 +1,19 @@
1
+ import { type BaseBehindCacheOptions } from "./base-behind-cache.mts";
1
2
  import type { CheckExecutionContext } from "../commands/check-execution-context.mts";
2
3
  export interface MergeTargetStatus {
3
4
  contexts: string[];
4
- trunkBehindBy?: number;
5
+ /**
6
+ * Commits on the trunk that the bottom open layer does not contain. Present only for a
7
+ * native stack; callers load it only when a required check is unreported.
8
+ */
9
+ trunkBehindBy?: () => Promise<number>;
5
10
  stackBottomPr?: number;
6
11
  }
7
12
  /**
8
13
  * Required status contexts for the branch GitHub actually merges into.
9
- * A native stack uses the trunk ref, and `behindBy` is that trunk against the bottom open layer.
14
+ * A native stack uses the trunk ref, and `trunkBehindBy` compares that trunk against the bottom
15
+ * open layer. The trunk rules and the stack topology come from this tick's `BatchPr` when the
16
+ * context holds them; otherwise `RefRules` and `PollStackTopology` read them.
10
17
  */
11
18
  export declare function loadMergeTargetStatus(input: {
12
19
  owner: string;
@@ -14,6 +21,8 @@ export declare function loadMergeTargetStatus(input: {
14
21
  pr: number;
15
22
  baseRefName: string;
16
23
  headRefName: string;
24
+ /** Head commit; preferred over the branch name for the trunk compare. */
25
+ headRefOid?: string;
17
26
  localContexts: readonly string[];
18
27
  stack?: {
19
28
  baseRefName: string;
@@ -26,7 +35,7 @@ export declare function loadMergeTargetStatus(input: {
26
35
  * `mergeStateStatus` stays `BLOCKED` when a conversation or an expected check
27
36
  * is also open, so this compare is the behind count that status hides.
28
37
  */
29
- export declare function loadBaseBehindBy(owner: string, name: string, baseRefName: string, headRef: string): Promise<number>;
38
+ export declare function loadBaseBehindBy(owner: string, name: string, baseRefName: string, headRef: string, cache?: BaseBehindCacheOptions): Promise<number>;
30
39
  export declare function loadRefRules(owner: string, name: string, qualifiedName: string, headRef: string): Promise<{
31
40
  contexts: string[];
32
41
  behindBy: number;