@fitlab-ai/agent-infra 0.9.11 → 0.9.13

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 (356) hide show
  1. package/README.md +13 -13
  2. package/README.zh-CN.md +13 -13
  3. package/dist/bin/internal-cli.js +29 -19
  4. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +71 -10
  5. package/dist/lib/agent-clients/next-steps.js +6 -1
  6. package/dist/lib/decide.js +3 -3
  7. package/dist/lib/defaults.json +4 -0
  8. package/dist/lib/git/workflow.js +43 -1
  9. package/dist/lib/init.js +1 -0
  10. package/dist/lib/internal/git-workflow.js +8 -1
  11. package/dist/lib/internal/platform-checks.js +3 -3
  12. package/dist/lib/internal/platform-comment.js +9 -9
  13. package/dist/lib/internal/platform-context.js +2 -2
  14. package/dist/lib/internal/platform-issue.js +8 -9
  15. package/dist/lib/internal/platform-pr-review.js +10 -10
  16. package/dist/lib/internal/platform-pr.js +68 -23
  17. package/dist/lib/internal/platform-release-notes.js +3 -3
  18. package/dist/lib/internal/pr-review-grade.js +11 -9
  19. package/dist/lib/internal/release-workflow.js +4 -4
  20. package/dist/lib/internal/sandbox-control.js +30 -4
  21. package/dist/lib/internal/task-activity.js +3 -3
  22. package/dist/lib/internal/task-artifact.js +76 -24
  23. package/dist/lib/internal/task-create.js +2 -2
  24. package/dist/lib/internal/task-delivery.js +59 -0
  25. package/dist/lib/internal/task-event.js +6 -3
  26. package/dist/lib/internal/task-finalization.js +2 -2
  27. package/dist/lib/internal/task-invalidation.js +60 -0
  28. package/dist/lib/internal/task-ledger.js +9 -6
  29. package/dist/lib/internal/task-lifecycle.js +2 -2
  30. package/dist/lib/internal/task-override.js +4 -4
  31. package/dist/lib/internal/task-review.js +3 -3
  32. package/dist/lib/internal/task-verify.js +6 -6
  33. package/dist/lib/internal/task-warning.js +3 -3
  34. package/dist/lib/platform/adapters.js +1 -3
  35. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  36. package/dist/lib/platform/completion-backfill.js +6 -5
  37. package/dist/lib/platform/context.js +70 -130
  38. package/dist/lib/platform/github-client.js +8 -2
  39. package/dist/lib/platform/github-provider.js +903 -0
  40. package/dist/lib/platform/in-label-sync.js +143 -0
  41. package/dist/lib/platform/issue-comments.js +94 -41
  42. package/dist/lib/platform/issues.js +335 -189
  43. package/dist/lib/platform/metadata-labels.js +6 -2
  44. package/dist/lib/platform/none-provider.js +28 -0
  45. package/dist/lib/platform/pr-change-report.js +551 -0
  46. package/dist/lib/platform/pr-checks.js +124 -106
  47. package/dist/lib/platform/pr-review.js +88 -72
  48. package/dist/lib/platform/pr-summary.js +523 -49
  49. package/dist/lib/platform/provider-bridge.js +45 -0
  50. package/dist/lib/platform/provider-contract.d.ts +487 -0
  51. package/dist/lib/platform/provider-contract.js +95 -0
  52. package/dist/lib/platform/provider-loader.js +251 -0
  53. package/dist/lib/platform/provider-validation.js +504 -0
  54. package/dist/lib/platform/pull-request-metadata.js +8 -6
  55. package/dist/lib/platform/pull-requests.js +1050 -502
  56. package/dist/lib/platform/release-notes.js +78 -55
  57. package/dist/lib/platform/releases.js +79 -50
  58. package/dist/lib/platform/resource-identity.d.ts +26 -0
  59. package/dist/lib/platform/resource-identity.js +92 -0
  60. package/dist/lib/platform/task-identities.js +31 -0
  61. package/dist/lib/platform/verification-required.js +22 -12
  62. package/dist/lib/platform/verification-sync.js +118 -239
  63. package/dist/lib/pr-review/evidence-grading.js +30 -9
  64. package/dist/lib/run/index.js +63 -23
  65. package/dist/lib/sandbox/config.js +5 -0
  66. package/dist/lib/sandbox/control/client.js +96 -15
  67. package/dist/lib/sandbox/control/executor.js +3 -3
  68. package/dist/lib/sandbox/control/lifecycle.js +29 -7
  69. package/dist/lib/sandbox/control/protocol.js +77 -0
  70. package/dist/lib/sandbox/control/server.js +398 -25
  71. package/dist/lib/sandbox/control/state.js +204 -1
  72. package/dist/lib/server/process-state.js +2 -2
  73. package/dist/lib/server/protocol.js +38 -1
  74. package/dist/lib/task/activity-log.js +8 -1
  75. package/dist/lib/task/artifact-lifecycle.js +35 -7
  76. package/dist/lib/task/capabilities.js +239 -0
  77. package/dist/lib/task/commands/status.js +32 -0
  78. package/dist/lib/task/commit-intent.js +100 -0
  79. package/dist/lib/task/commit-operation.js +207 -102
  80. package/dist/lib/task/control-authority.js +8 -5
  81. package/dist/lib/task/create-service.js +8 -8
  82. package/dist/lib/task/create.js +33 -7
  83. package/dist/lib/task/current-contract.js +5 -1
  84. package/dist/lib/task/decision-details.js +3 -48
  85. package/dist/lib/task/delivery-target.js +97 -0
  86. package/dist/lib/task/delivery.js +153 -0
  87. package/dist/lib/task/events.js +297 -17
  88. package/dist/lib/task/finalization.js +37 -13
  89. package/dist/lib/task/human-override.js +61 -36
  90. package/dist/lib/task/invalidation-command.js +86 -0
  91. package/dist/lib/task/invalidation.js +260 -0
  92. package/dist/lib/task/ledger-intents.js +37 -0
  93. package/dist/lib/task/lifecycle.js +106 -9
  94. package/dist/lib/task/local-artifact-finalization.js +374 -0
  95. package/dist/lib/task/orchestration.js +100 -151
  96. package/dist/lib/task/pr-delivery-fact.js +183 -0
  97. package/dist/lib/task/review-finalization.js +4 -8
  98. package/dist/lib/task/review-fingerprint.js +32 -2
  99. package/dist/lib/task/rework-intent.js +138 -0
  100. package/dist/lib/task/skill-scope.js +23 -0
  101. package/dist/lib/task/task-execution-lock.js +27 -17
  102. package/dist/lib/task/verification-engine.js +89 -38
  103. package/dist/lib/task/verification-review.js +1 -1
  104. package/dist/lib/task/verification.js +3 -3
  105. package/dist/lib/task/workflow-warning-intents.js +1 -1
  106. package/dist/lib/task/write.js +11 -0
  107. package/dist/lib/update.js +9 -0
  108. package/dist/lib/version.js +11 -1
  109. package/dist/lifecycle-build-manifest.json +3 -3
  110. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +105 -10
  111. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +12 -1
  112. package/lib/agent-clients/next-steps.ts +6 -1
  113. package/lib/decide.ts +3 -3
  114. package/lib/defaults.json +4 -0
  115. package/lib/git/workflow.ts +38 -1
  116. package/lib/init.ts +4 -1
  117. package/lib/internal/git-workflow.ts +7 -1
  118. package/lib/internal/platform-checks.ts +3 -3
  119. package/lib/internal/platform-comment.ts +8 -8
  120. package/lib/internal/platform-context.ts +2 -2
  121. package/lib/internal/platform-issue.ts +7 -8
  122. package/lib/internal/platform-pr-review.ts +9 -9
  123. package/lib/internal/platform-pr.ts +53 -21
  124. package/lib/internal/platform-release-notes.ts +3 -3
  125. package/lib/internal/pr-review-grade.ts +10 -8
  126. package/lib/internal/release-workflow.ts +4 -4
  127. package/lib/internal/sandbox-control.ts +27 -3
  128. package/lib/internal/task-activity.ts +3 -3
  129. package/lib/internal/task-artifact.ts +65 -22
  130. package/lib/internal/task-create.ts +2 -2
  131. package/lib/internal/task-delivery.ts +53 -0
  132. package/lib/internal/task-event.ts +6 -3
  133. package/lib/internal/task-finalization.ts +3 -3
  134. package/lib/internal/task-invalidation.ts +39 -0
  135. package/lib/internal/task-ledger.ts +11 -8
  136. package/lib/internal/task-lifecycle.ts +2 -2
  137. package/lib/internal/task-override.ts +6 -6
  138. package/lib/internal/task-review.ts +3 -3
  139. package/lib/internal/task-verify.ts +6 -6
  140. package/lib/internal/task-warning.ts +3 -3
  141. package/lib/platform/adapters.ts +3 -2
  142. package/lib/platform/change-request-git-evidence.ts +36 -9
  143. package/lib/platform/completion-backfill.ts +9 -8
  144. package/lib/platform/context.ts +97 -134
  145. package/lib/platform/github-client.ts +10 -3
  146. package/lib/platform/github-provider.ts +910 -0
  147. package/lib/platform/in-label-sync.ts +208 -0
  148. package/lib/platform/issue-comments.ts +97 -47
  149. package/lib/platform/issues.ts +344 -174
  150. package/lib/platform/metadata-labels.ts +5 -2
  151. package/lib/platform/none-provider.ts +35 -0
  152. package/lib/platform/pr-change-report.ts +645 -0
  153. package/lib/platform/pr-checks.ts +129 -107
  154. package/lib/platform/pr-review.ts +88 -85
  155. package/lib/platform/pr-summary.ts +562 -52
  156. package/lib/platform/provider-bridge.ts +82 -0
  157. package/lib/platform/provider-contract.ts +536 -0
  158. package/lib/platform/provider-loader.ts +307 -0
  159. package/lib/platform/provider-validation.ts +529 -0
  160. package/lib/platform/pull-request-metadata.ts +10 -7
  161. package/lib/platform/pull-requests.ts +1126 -505
  162. package/lib/platform/release-notes.ts +76 -59
  163. package/lib/platform/releases.ts +77 -43
  164. package/lib/platform/resource-identity.ts +121 -0
  165. package/lib/platform/task-identities.ts +40 -0
  166. package/lib/platform/types.ts +4 -2
  167. package/lib/platform/verification-required.ts +21 -13
  168. package/lib/platform/verification-sync.ts +118 -293
  169. package/lib/pr-review/evidence-grading.ts +31 -11
  170. package/lib/run/index.ts +57 -22
  171. package/lib/sandbox/config.ts +7 -0
  172. package/lib/sandbox/control/client.ts +105 -15
  173. package/lib/sandbox/control/executor.ts +4 -4
  174. package/lib/sandbox/control/lifecycle.ts +30 -8
  175. package/lib/sandbox/control/protocol.ts +113 -0
  176. package/lib/sandbox/control/server.ts +431 -23
  177. package/lib/sandbox/control/state.ts +251 -1
  178. package/lib/server/process-state.ts +2 -2
  179. package/lib/server/protocol.ts +36 -1
  180. package/lib/task/activity-log.ts +8 -0
  181. package/lib/task/artifact-lifecycle.ts +34 -8
  182. package/lib/task/capabilities.ts +262 -0
  183. package/lib/task/commands/status.ts +38 -0
  184. package/lib/task/commit-intent.ts +137 -0
  185. package/lib/task/commit-operation.ts +186 -88
  186. package/lib/task/control-authority.ts +11 -8
  187. package/lib/task/create-service.ts +8 -8
  188. package/lib/task/create.ts +34 -9
  189. package/lib/task/current-contract.ts +6 -1
  190. package/lib/task/decision-details.ts +8 -64
  191. package/lib/task/delivery-target.ts +130 -0
  192. package/lib/task/delivery.ts +160 -0
  193. package/lib/task/events.ts +296 -16
  194. package/lib/task/finalization.ts +50 -14
  195. package/lib/task/human-override.ts +73 -46
  196. package/lib/task/invalidation-command.ts +86 -0
  197. package/lib/task/invalidation.ts +332 -0
  198. package/lib/task/ledger-intents.ts +35 -1
  199. package/lib/task/lifecycle.ts +93 -4
  200. package/lib/task/local-artifact-finalization.ts +563 -0
  201. package/lib/task/orchestration.ts +110 -146
  202. package/lib/task/pr-delivery-fact.ts +237 -0
  203. package/lib/task/review-finalization.ts +4 -14
  204. package/lib/task/review-fingerprint.ts +33 -2
  205. package/lib/task/rework-intent.ts +165 -0
  206. package/lib/task/skill-scope.ts +24 -0
  207. package/lib/task/task-execution-lock.ts +23 -14
  208. package/lib/task/verification-engine.ts +95 -43
  209. package/lib/task/verification-review.ts +2 -0
  210. package/lib/task/verification.ts +4 -4
  211. package/lib/task/workflow-warning-intents.ts +1 -1
  212. package/lib/task/write.ts +19 -0
  213. package/lib/update.ts +11 -1
  214. package/lib/version.ts +15 -1
  215. package/package.json +7 -1
  216. package/templates/.agents/rules/README.en.md +4 -2
  217. package/templates/.agents/rules/README.zh-CN.md +4 -2
  218. package/templates/.agents/rules/create-issue.en.md +11 -2
  219. package/templates/.agents/rules/create-issue.zh-CN.md +24 -2
  220. package/templates/.agents/rules/issue-pr-commands.en.md +4 -17
  221. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  222. package/templates/.agents/rules/issue-sync.en.md +28 -5
  223. package/templates/.agents/rules/issue-sync.zh-CN.md +64 -5
  224. package/templates/.agents/rules/label-milestone-setup.en.md +15 -2
  225. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +15 -2
  226. package/templates/.agents/rules/local-artifact-repair.en.md +53 -0
  227. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +53 -0
  228. package/templates/.agents/rules/milestone-inference.en.md +12 -2
  229. package/templates/.agents/rules/milestone-inference.zh-CN.md +25 -3
  230. package/templates/.agents/rules/pr-sync.en.md +28 -13
  231. package/templates/.agents/rules/pr-sync.zh-CN.md +39 -5
  232. package/templates/.agents/rules/release-commands.en.md +42 -3
  233. package/templates/.agents/rules/release-commands.zh-CN.md +42 -3
  234. package/templates/.agents/rules/security-alerts.en.md +17 -2
  235. package/templates/.agents/rules/security-alerts.zh-CN.md +17 -2
  236. package/templates/.agents/rules/sync-content-generation.en.md +8 -0
  237. package/templates/.agents/rules/sync-content-generation.zh-CN.md +8 -0
  238. package/templates/.agents/rules/task-management.en.md +1 -1
  239. package/templates/.agents/rules/task-management.zh-CN.md +1 -1
  240. package/templates/.agents/rules/task-short-id.en.md +1 -4
  241. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  242. package/templates/.agents/scripts/security-alerts.github.sh +151 -0
  243. package/templates/.agents/scripts/security-alerts.sh +31 -0
  244. package/templates/.agents/skills/analyze-task/SKILL.en.md +14 -3
  245. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +11 -3
  246. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  247. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  248. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  249. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  250. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  251. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  252. package/templates/.agents/skills/code-task/SKILL.en.md +32 -10
  253. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +35 -13
  254. package/templates/.agents/skills/code-task/config/verify.en.json +1 -0
  255. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -0
  256. package/templates/.agents/skills/commit/SKILL.en.md +3 -3
  257. package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -3
  258. package/templates/.agents/skills/commit/config/verify.json +1 -1
  259. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +3 -3
  260. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +3 -3
  261. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  262. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  263. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +4 -4
  264. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +4 -4
  265. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -2
  266. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -2
  267. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +7 -4
  268. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +7 -4
  269. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  270. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  271. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +5 -4
  272. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +5 -4
  273. package/templates/.agents/skills/complete-task/SKILL.en.md +31 -13
  274. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +30 -13
  275. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +2 -2
  276. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +2 -2
  277. package/templates/.agents/skills/create-pr/SKILL.en.md +11 -10
  278. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +11 -11
  279. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  280. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  281. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  282. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  283. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  284. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  285. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  286. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  287. package/templates/.agents/skills/create-task/SKILL.en.md +1 -0
  288. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -0
  289. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  290. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  291. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  292. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  293. package/templates/.agents/skills/init-labels/SKILL.en.md +9 -10
  294. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +9 -10
  295. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +57 -1
  296. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +27 -1
  297. package/templates/.agents/skills/init-milestones/SKILL.en.md +3 -5
  298. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +3 -5
  299. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -3
  300. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +11 -3
  301. package/templates/.agents/skills/review-analysis/SKILL.en.md +6 -5
  302. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +6 -5
  303. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +18 -0
  304. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +18 -0
  305. package/templates/.agents/skills/review-code/SKILL.en.md +10 -9
  306. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +10 -9
  307. package/templates/.agents/skills/review-code/reference/output-templates.en.md +19 -1
  308. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +19 -1
  309. package/templates/.agents/skills/review-code/reference/report-template.en.md +4 -2
  310. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +4 -2
  311. package/templates/.agents/skills/review-plan/SKILL.en.md +6 -5
  312. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +6 -5
  313. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +18 -0
  314. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +18 -0
  315. package/templates/.agents/skills/review-pr/SKILL.en.md +1 -0
  316. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +1 -0
  317. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +2 -2
  318. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +2 -2
  319. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +5 -2
  320. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +5 -2
  321. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  322. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  323. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +4 -0
  324. package/templates/.agents/skills/watch-pr/SKILL.en.md +6 -6
  325. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +6 -6
  326. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  327. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  328. package/templates/.agents/templates/task.en.md +23 -2
  329. package/templates/.agents/templates/task.zh-CN.md +23 -2
  330. package/templates/.agents/workflows/bug-fix.en.yaml +9 -8
  331. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +9 -8
  332. package/templates/.agents/workflows/feature-development.en.yaml +9 -8
  333. package/templates/.agents/workflows/feature-development.zh-CN.yaml +9 -8
  334. package/templates/.agents/workflows/refactoring.en.yaml +9 -8
  335. package/templates/.agents/workflows/refactoring.zh-CN.yaml +9 -8
  336. package/templates/.github/workflows/pr-label.yml +7 -26
  337. package/templates/.agents/rules/create-issue.github.en.md +0 -14
  338. package/templates/.agents/rules/create-issue.github.zh-CN.md +0 -27
  339. package/templates/.agents/rules/issue-pr-commands.github.en.md +0 -34
  340. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +0 -49
  341. package/templates/.agents/rules/issue-sync.github.en.md +0 -40
  342. package/templates/.agents/rules/issue-sync.github.zh-CN.md +0 -76
  343. package/templates/.agents/rules/label-milestone-setup.github.en.md +0 -60
  344. package/templates/.agents/rules/label-milestone-setup.github.zh-CN.md +0 -60
  345. package/templates/.agents/rules/milestone-inference.github.en.md +0 -15
  346. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +0 -27
  347. package/templates/.agents/rules/pr-checks-commands.github.en.md +0 -18
  348. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +0 -34
  349. package/templates/.agents/rules/pr-sync.github.en.md +0 -43
  350. package/templates/.agents/rules/pr-sync.github.zh-CN.md +0 -69
  351. package/templates/.agents/rules/release-commands.github.en.md +0 -44
  352. package/templates/.agents/rules/release-commands.github.zh-CN.md +0 -44
  353. package/templates/.agents/rules/security-alerts.github.en.md +0 -43
  354. package/templates/.agents/rules/security-alerts.github.zh-CN.md +0 -43
  355. /package/templates/.agents/rules/{issue-fields.github.en.md → issue-fields.en.md} +0 -0
  356. /package/templates/.agents/rules/{issue-fields.github.zh-CN.md → issue-fields.zh-CN.md} +0 -0
@@ -1,11 +1,11 @@
1
1
  import fs from 'node:fs';
2
- import { parseTaskFrontmatter } from '../task/frontmatter.js';
2
+ import { parseTypedTaskFrontmatter } from '../task/frontmatter.js';
3
3
  import { resolveTaskRef } from '../task/resolve-ref.js';
4
- import { inspectPlatformRequiredChecks, registerPlatformCapabilities } from './adapters.js';
5
- import { resolvePlatformContext } from './context.js';
6
- import { createGitHubClient } from './github-client.js';
4
+ import { resolvePlatformProviderContext } from './context.js';
7
5
  import { inspectPlatformPullRequest } from './pull-requests.js';
8
6
  import { platformResult } from './types.js';
7
+ import { readPrDeliveryFact } from '../task/pr-delivery-fact.js';
8
+ import { providerError, providerOperationContext, providerStatus, resourceIdentity, resourceIdentityNumber, unsupportedProviderOperation } from './provider-bridge.js';
9
9
  function classifyRequiredChecks(required) {
10
10
  if (required.length === 0)
11
11
  return { state: 'no-required', required };
@@ -55,7 +55,7 @@ function checksResult(status, overrides = {}) {
55
55
  };
56
56
  }
57
57
  function normalizeBucket(value) {
58
- const raw = String(value.bucket || value.conclusion || value.state || '').toLowerCase();
58
+ const raw = String(value.bucket || value.status || value.conclusion || value.state || '').toLowerCase();
59
59
  if (['pass', 'success', 'successful', 'neutral'].includes(raw))
60
60
  return 'pass';
61
61
  if (['fail', 'failure', 'failed', 'error', 'timed_out', 'action_required'].includes(raw))
@@ -81,83 +81,83 @@ function normalizeChecks(value) {
81
81
  }] : [];
82
82
  });
83
83
  }
84
- registerPlatformCapabilities('github', {
85
- inspectRequiredChecks({ client, repository, number, cwd }) {
86
- const github = client || createGitHubClient();
87
- const inspected = github.json([
88
- 'pr', 'checks', String(number), '--repo', repository,
89
- '--json', 'name,state,bucket,link,workflow,startedAt,completedAt'
90
- ], { cwd });
91
- return inspected.ok
92
- ? { ok: true, value: normalizeChecks(inspected.value) }
93
- : { ok: false, error: inspected.error };
94
- }
95
- });
96
- function resolvedTask(taskRef, options) {
84
+ function inspectGitHubRequiredChecks(client, repository, number, cwd) {
85
+ const inspected = client.json([
86
+ 'pr', 'checks', String(number), '--repo', repository,
87
+ '--json', 'name,state,bucket,link,workflow,startedAt,completedAt'
88
+ ], { cwd });
89
+ return inspected.ok
90
+ ? { ok: true, value: normalizeChecks(inspected.value) }
91
+ : { ok: false, error: inspected.error };
92
+ }
93
+ async function resolvedTask(taskRef, options) {
97
94
  const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
98
95
  if (!resolved.ok)
99
96
  return { ok: false, output: checksResult('failed', { error: { code: resolved.code, message: resolved.message, retryable: false } }) };
100
- const frontmatter = parseTaskFrontmatter(fs.readFileSync(resolved.taskMdPath, 'utf8'));
101
- const pr = Number(frontmatter.pr_number);
102
- const prNumber = Number.isInteger(pr) && pr > 0 ? pr : null;
103
- if (!prNumber)
104
- return { ok: false, output: checksResult('failed', { error: { code: 'PR_NOT_LINKED', message: 'Task has no valid pr_number', retryable: false } }) };
105
- const client = options.client || createGitHubClient();
106
- const context = resolvePlatformContext({ cwd: resolved.repoRoot, client });
97
+ const frontmatter = parseTypedTaskFrontmatter(fs.readFileSync(resolved.taskMdPath, 'utf8'));
98
+ const fact = readPrDeliveryFact(frontmatter, options.runtimeVersion);
99
+ if (fact.status === 'invalid')
100
+ return { ok: false, output: checksResult('failed', { error: { code: fact.error.code, message: fact.error.message, retryable: false } }) };
101
+ const prIdentity = fact.status === 'valid' && fact.fact.state === 'bound' ? fact.fact.identity.resource : null;
102
+ const prNumber = resourceIdentityNumber(prIdentity);
103
+ if (!prIdentity)
104
+ return { ok: false, output: checksResult('failed', { error: { code: fact.status === 'missing' ? 'PR_DELIVERY_FACT_MISSING' : 'PR_NOT_LINKED', message: 'Task has no verified bound pull request', retryable: false } }) };
105
+ const loaded = await resolvePlatformProviderContext({ cwd: resolved.repoRoot, client: options.client });
106
+ const context = loaded.ok ? loaded.value.context : loaded.context;
107
107
  if (!context.platform.repository || !['no-op', 'degraded'].includes(context.status))
108
108
  return { ok: false, output: checksResult(context.status, { platform: context.platform, capabilities: context.capabilities, error: context.error }) };
109
- const inspected = inspectPlatformPullRequest(taskRef, { cwd: resolved.repoRoot, client });
109
+ const inspected = await inspectPlatformPullRequest(taskRef, { cwd: resolved.repoRoot, client: options.client });
110
110
  if (!inspected.pullRequest)
111
111
  return { ok: false, output: checksResult(inspected.status, { platform: context.platform, capabilities: context.capabilities, error: inspected.error }) };
112
- return { ok: true, resolved, prNumber, client, context, pullRequest: inspected.pullRequest };
112
+ if (!loaded.ok)
113
+ return { ok: false, output: checksResult('failed', { platform: context.platform, capabilities: context.capabilities, error: context.error }) };
114
+ return { ok: true, resolved, prNumber, prIdentity, client: options.client, context, pullRequest: inspected.pullRequest, provider: loaded.value.provider, loadedContext: loaded.value };
113
115
  }
114
- function inspectRequiredChecks(taskRef, options = {}) {
115
- const base = resolvedTask(taskRef, options);
116
+ async function inspectRequiredChecks(taskRef, options = {}) {
117
+ const base = await resolvedTask(taskRef, options);
116
118
  if (!base.ok)
117
119
  return base.output;
118
120
  return inspectChecksForResolvedTask(base, options);
119
121
  }
120
- function inspectChecksForResolvedTask(base, options) {
122
+ async function inspectChecksForResolvedTask(base, options) {
121
123
  const repository = base.context.platform.repository;
122
- const inspected = inspectPlatformRequiredChecks(base.context.platform.type, {
123
- cwd: base.resolved.repoRoot,
124
- repository,
125
- number: base.prNumber,
126
- headSha: base.pullRequest.head.sha,
127
- client: options.client || base.client
128
- });
129
- if (!inspected.ok || !inspected.value) {
130
- const error = inspected.error || {
131
- code: 'REQUIRED_CHECKS_INSPECTION_INVALID',
132
- message: 'Platform adapter returned no required-checks snapshot',
133
- retryable: false
134
- };
135
- return checksResult(error.retryable ? 'blocked' : 'failed', {
124
+ {
125
+ const inspected = base.provider.checks?.inspectRequired
126
+ ? await base.provider.checks.inspectRequired({
127
+ context: providerOperationContext(base.loadedContext),
128
+ changeRequest: base.prIdentity,
129
+ headSha: base.pullRequest.head.sha
130
+ })
131
+ : unsupportedProviderOperation(base.provider, 'checks.inspectRequired');
132
+ if (!inspected.ok)
133
+ return checksResult(providerStatus(inspected.error), {
134
+ platform: base.context.platform,
135
+ capabilities: base.context.capabilities,
136
+ resource: { kind: 'pull-request', number: base.prNumber },
137
+ pullRequest: base.pullRequest,
138
+ error: providerError(inspected.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
139
+ });
140
+ const required = normalizeChecks(inspected.value);
141
+ const classified = classifyRequiredChecks(required);
142
+ const status = classified.state === 'passed' || classified.state === 'no-required'
143
+ ? 'no-op'
144
+ : classified.state === 'failed' || classified.state === 'cancelled' ? 'failed' : 'blocked';
145
+ return checksResult(status, {
136
146
  platform: base.context.platform, capabilities: base.context.capabilities,
137
- resource: { kind: 'pull-request', number: base.prNumber },
138
- pullRequest: base.pullRequest, error
147
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
148
+ checks: classified,
149
+ error: status === 'no-op' ? null : {
150
+ code: classified.state === 'pending' ? 'REQUIRED_CHECKS_PENDING' : `REQUIRED_CHECKS_${classified.state.toUpperCase()}`,
151
+ message: `Required checks are ${classified.state}`, retryable: classified.state === 'pending'
152
+ }
139
153
  });
140
154
  }
141
- const classified = classifyRequiredChecks(inspected.value);
142
- const status = classified.state === 'passed' || classified.state === 'no-required'
143
- ? 'no-op'
144
- : classified.state === 'failed' || classified.state === 'cancelled' ? 'failed' : 'blocked';
145
- return checksResult(status, {
146
- platform: base.context.platform, capabilities: base.context.capabilities,
147
- resource: { kind: 'pull-request', number: base.prNumber },
148
- pullRequest: base.pullRequest, checks: classified,
149
- error: status === 'no-op' ? null : {
150
- code: classified.state === 'pending' ? 'REQUIRED_CHECKS_PENDING' : `REQUIRED_CHECKS_${classified.state.toUpperCase()}`,
151
- message: `Required checks are ${classified.state}`,
152
- retryable: classified.state === 'pending'
153
- }
154
- });
155
155
  }
156
- function inspectPullRequestReadiness(taskRef, options = {}) {
157
- const base = resolvedTask(taskRef, options);
156
+ async function inspectPullRequestReadiness(taskRef, options = {}) {
157
+ const base = await resolvedTask(taskRef, options);
158
158
  if (!base.ok)
159
159
  return base.output;
160
- const checked = inspectChecksForResolvedTask(base, options);
160
+ const checked = await inspectChecksForResolvedTask(base, options);
161
161
  const classifiedCodes = new Set(['REQUIRED_CHECKS_PENDING', 'REQUIRED_CHECKS_FAILED', 'REQUIRED_CHECKS_CANCELLED']);
162
162
  if (checked.error && !classifiedCodes.has(checked.error.code))
163
163
  return checked;
@@ -194,7 +194,7 @@ async function watchPullRequestReadiness(taskRef, options) {
194
194
  readiness: { state: 'cancelled', headSha: last?.pullRequest?.head.sha ?? '' },
195
195
  error: { code: 'PR_READINESS_CANCELLED', message: 'Pull request readiness watch was cancelled', retryable: false }
196
196
  });
197
- last = inspectPullRequestReadiness(taskRef, options);
197
+ last = await inspectPullRequestReadiness(taskRef, options);
198
198
  if (last.readiness?.state !== 'pending' || last.error?.code !== 'PR_READINESS_PENDING')
199
199
  return last;
200
200
  const elapsed = now() - started;
@@ -208,60 +208,78 @@ async function watchPullRequestReadiness(taskRef, options) {
208
208
  await sleep(Math.min(options.intervalSeconds * 1000, options.deadlineSeconds * 1000 - elapsed));
209
209
  }
210
210
  }
211
- function resolvePlatformCheckRun(taskRef, options) {
212
- const base = resolvedTask(taskRef, options);
211
+ async function resolvePlatformCheckRun(taskRef, options) {
212
+ const base = await resolvedTask(taskRef, options);
213
213
  if (!base.ok)
214
214
  return base.output;
215
- const direct = options.detailsUrl ? parseRunJobIdentity(options.detailsUrl) : null;
216
- if (direct) {
217
- const run = base.client.json(['api', `repos/${base.context.platform.repository}/actions/runs/${direct.runId}`], { cwd: base.resolved.repoRoot });
218
- if (!run.ok)
219
- return checksResult(run.error.retryable ? 'blocked' : 'failed', { platform: base.context.platform, capabilities: base.context.capabilities, pullRequest: base.pullRequest, error: run.error });
220
- if (run.value.head_sha !== base.pullRequest.head.sha)
221
- return checksResult('failed', { error: { code: 'CHECK_RUN_HEAD_MISMATCH', message: 'Resolved run does not belong to the PR head SHA', retryable: false } });
222
- return checksResult('no-op', { platform: base.context.platform, capabilities: base.context.capabilities, resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest, resolution: { status: 'resolved', ...direct }, error: null });
215
+ {
216
+ const resolved = base.provider.checks?.resolveRun
217
+ ? await base.provider.checks.resolveRun({
218
+ context: providerOperationContext(base.loadedContext),
219
+ changeRequest: base.prIdentity,
220
+ checkName: options.checkName,
221
+ ...(options.detailsUrl ? { detailsUrl: options.detailsUrl } : {})
222
+ })
223
+ : unsupportedProviderOperation(base.provider, 'checks.resolveRun');
224
+ if (!resolved.ok)
225
+ return checksResult(providerStatus(resolved.error), {
226
+ platform: base.context.platform, capabilities: base.context.capabilities,
227
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
228
+ error: providerError(resolved.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
229
+ });
230
+ const runId = Number(resolved.value.runId);
231
+ if (!Number.isSafeInteger(runId) || runId <= 0)
232
+ return checksResult('failed', {
233
+ platform: base.context.platform, capabilities: base.context.capabilities,
234
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
235
+ error: { code: 'CHECK_RUN_IDENTITY_INVALID', message: 'Provider returned an invalid check run identity', retryable: false }
236
+ });
237
+ const jobId = resolved.value.jobId ? Number(resolved.value.jobId) : null;
238
+ return checksResult('no-op', {
239
+ platform: base.context.platform, capabilities: base.context.capabilities,
240
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
241
+ resolution: { status: 'resolved', runId, jobId: jobId !== null && Number.isSafeInteger(jobId) && jobId > 0 ? jobId : null }, error: null
242
+ });
223
243
  }
224
- const listed = base.client.json(['api', `repos/${base.context.platform.repository}/commits/${base.pullRequest.head.sha}/check-runs`], { cwd: base.resolved.repoRoot });
225
- if (!listed.ok)
226
- return checksResult(listed.error.retryable ? 'blocked' : 'failed', { error: listed.error });
227
- const candidates = (listed.value.check_runs || []).flatMap((check) => {
228
- if (check.name !== options.checkName || !check.details_url)
229
- return [];
230
- const identity = parseRunJobIdentity(check.details_url);
231
- return identity ? [{ id: identity.runId, jobId: identity.jobId, name: check.name, headSha: base.pullRequest.head.sha }] : [];
232
- });
233
- const resolution = resolveRunCandidate(candidates, base.pullRequest.head.sha, options.checkName);
234
- return checksResult(resolution.status === 'resolved' ? 'no-op' : 'failed', {
235
- platform: base.context.platform, capabilities: base.context.capabilities,
236
- resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
237
- resolution,
238
- error: resolution.status === 'resolved' ? null : { code: resolution.status === 'ambiguous' ? 'CHECK_RUN_AMBIGUOUS' : 'CHECK_RUN_NOT_FOUND', message: `Check run is ${resolution.status}`, retryable: false }
239
- });
240
244
  }
241
245
  function fetchCheckLogText(client, args, cwd) {
246
+ if (!client.text)
247
+ return { ok: false, error: { code: 'PLATFORM_CLIENT_TEXT_UNAVAILABLE', message: 'Platform client does not support text responses', retryable: false } };
242
248
  const fetched = client.text(args, { cwd });
243
249
  if (fetched.ok || args[0] !== 'api' || !/response contains terminal escape sequences/i.test(fetched.error.message)) {
244
250
  return fetched;
245
251
  }
246
252
  return client.text([...args, '--allow-escape-sequences'], { cwd });
247
253
  }
248
- function fetchPlatformCheckLogs(taskRef, options) {
249
- const base = resolvedTask(taskRef, options);
254
+ async function fetchPlatformCheckLogs(taskRef, options) {
255
+ const base = await resolvedTask(taskRef, options);
250
256
  if (!base.ok)
251
257
  return base.output;
252
- const args = options.job
253
- ? ['api', `repos/${base.context.platform.repository}/actions/jobs/${options.job}/logs`]
254
- : ['run', 'view', String(options.run), '--repo', base.context.platform.repository, '--log-failed'];
255
- const fetched = fetchCheckLogText(base.client, args, base.resolved.repoRoot);
256
- if (!fetched.ok)
257
- return checksResult(fetched.error.retryable ? 'blocked' : 'failed', { platform: base.context.platform, capabilities: base.context.capabilities, error: fetched.error });
258
- if (!fetched.value)
259
- return checksResult('failed', { error: { code: 'CHECK_LOGS_MISSING', message: 'No failed logs are available', retryable: false } });
260
- return checksResult('no-op', {
261
- platform: base.context.platform, capabilities: base.context.capabilities,
262
- resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
263
- logs: { runId: options.run, ...(options.job ? { jobId: options.job } : {}), text: fetched.value }, error: null
264
- });
258
+ {
259
+ const fetched = base.provider.checks?.fetchLogs
260
+ ? await base.provider.checks.fetchLogs({
261
+ context: providerOperationContext(base.loadedContext),
262
+ runId: String(options.run),
263
+ ...(options.job ? { jobId: String(options.job) } : {})
264
+ })
265
+ : unsupportedProviderOperation(base.provider, 'checks.fetchLogs');
266
+ if (!fetched.ok)
267
+ return checksResult(providerStatus(fetched.error), {
268
+ platform: base.context.platform, capabilities: base.context.capabilities,
269
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
270
+ error: providerError(fetched.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
271
+ });
272
+ if (!fetched.value.text)
273
+ return checksResult('failed', {
274
+ platform: base.context.platform, capabilities: base.context.capabilities,
275
+ error: { code: 'CHECK_LOGS_MISSING', message: 'No failed logs are available', retryable: false }
276
+ });
277
+ return checksResult('no-op', {
278
+ platform: base.context.platform, capabilities: base.context.capabilities,
279
+ resource: { kind: 'pull-request', number: base.prNumber }, pullRequest: base.pullRequest,
280
+ logs: { runId: options.run, ...(options.job ? { jobId: options.job } : {}), text: fetched.value.text }, error: null
281
+ });
282
+ }
265
283
  }
266
- export { classifyPullRequestReadiness, classifyRequiredChecks, fetchCheckLogText, fetchPlatformCheckLogs, inspectRequiredChecks, inspectPullRequestReadiness, parseRunJobIdentity, resolvePlatformCheckRun, resolveRunCandidate, watchPullRequestReadiness };
284
+ export { classifyPullRequestReadiness, classifyRequiredChecks, fetchCheckLogText, fetchPlatformCheckLogs, inspectGitHubRequiredChecks, inspectRequiredChecks, inspectPullRequestReadiness, parseRunJobIdentity, resolvePlatformCheckRun, resolveRunCandidate, watchPullRequestReadiness };
267
285
  //# sourceMappingURL=pr-checks.js.map
@@ -1,13 +1,17 @@
1
- import { createGitHubClient } from './github-client.js';
2
- import { resolvePlatformContext } from './context.js';
1
+ import { resolvePlatformProviderContext } from './context.js';
3
2
  import { platformResult } from './types.js';
3
+ import { providerError, providerOperationContext, providerStatus, providerResourceToken, unsupportedProviderOperation } from './provider-bridge.js';
4
+ import { isResourceIdentity, resourceIdentityNumber, reviewMarker as resourceReviewMarker } from './resource-identity.js';
4
5
  const REVIEW_EVENTS = ['COMMENT', 'APPROVE', 'REQUEST_CHANGES'];
5
6
  // Marker-safe scope: a task id (`TASK-YYYYMMDD-HHMMSS`) or a bare PR number
6
7
  // (`pr{N}`). Any other value (e.g. one containing `\r\n` or `-->`) would break
7
8
  // the first-line marker idempotency contract of `reviewMarker` (PL-6).
8
9
  const REVIEW_SCOPE_PATTERN = /^(?:pr\d+|TASK-\d{8}-\d{6})$/;
9
10
  export function reviewMarker(identity) {
10
- return `<!-- review-pr:${identity.scope}:r${identity.round} -->`;
11
+ const scope = identity.resource && isResourceIdentity(identity.resource) && identity.resource.kind !== 'number'
12
+ ? resourceReviewMarker(identity.resource)
13
+ : identity.scope;
14
+ return `<!-- review-pr:${scope}:r${identity.round} -->`;
11
15
  }
12
16
  export function reviewedCommitMarker(sha) {
13
17
  return `<!-- reviewed-commit: ${sha} -->`;
@@ -21,81 +25,84 @@ function firstLine(body) {
21
25
  function hasUsableContext(context) {
22
26
  return (context.status === 'no-op' || context.status === 'degraded') && context.platform.repository !== null;
23
27
  }
24
- function invalidPrNumber(prNumber) {
25
- return !Number.isInteger(prNumber) || prNumber <= 0;
26
- }
27
- export function listPrReviews(prNumber, options = {}) {
28
- const client = options.client || createGitHubClient();
29
- const context = resolvePlatformContext({ cwd: options.cwd || process.cwd(), client });
28
+ export async function listPrReviews(prNumber, options = {}) {
29
+ const loaded = await resolvePlatformProviderContext({ cwd: options.cwd || process.cwd(), client: options.client });
30
+ const context = loaded.ok ? loaded.value.context : loaded.context;
30
31
  if (!hasUsableContext(context)) {
31
32
  return { ...platformResult(context.status, { platform: context.platform, capabilities: context.capabilities, error: context.error }), reviews: [] };
32
33
  }
33
- const repository = context.platform.repository;
34
- if (invalidPrNumber(prNumber)) {
34
+ const identity = loaded.ok ? (() => { try {
35
+ return providerResourceToken(loaded.value.provider, 'pull-request', String(prNumber));
36
+ }
37
+ catch {
38
+ return null;
39
+ } })() : null;
40
+ if (!identity) {
35
41
  return {
36
42
  ...platformResult('failed', {
37
43
  platform: context.platform, capabilities: context.capabilities,
38
- error: { code: 'PR_NUMBER_INVALID', message: 'PR number must be positive', retryable: false }
44
+ error: { code: 'PLATFORM_IDENTITY_TOKEN_INVALID', message: 'Pull request token is invalid', retryable: false }
39
45
  }),
40
46
  reviews: []
41
47
  };
42
48
  }
43
- const fetched = client.json(['api', '--paginate', '--slurp', `repos/${repository}/pulls/${prNumber}/reviews?per_page=100`], { cwd: options.cwd || process.cwd() });
44
- if (!fetched.ok) {
49
+ const identityNumber = resourceIdentityNumber(identity);
50
+ if (loaded.ok) {
51
+ const fetched = loaded.value.provider.reviews?.list
52
+ ? await loaded.value.provider.reviews.list({ context: providerOperationContext(loaded.value), changeRequest: identity })
53
+ : unsupportedProviderOperation(loaded.value.provider, 'reviews.list');
54
+ if (!fetched.ok)
55
+ return {
56
+ ...platformResult(providerStatus(fetched.error), {
57
+ platform: context.platform, capabilities: context.capabilities,
58
+ resource: { kind: 'pull-request', number: identityNumber, identity }, error: providerError(fetched.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
59
+ }), reviews: []
60
+ };
45
61
  return {
46
- ...platformResult(fetched.error.retryable ? 'blocked' : 'failed', {
62
+ ...platformResult('no-op', {
47
63
  platform: context.platform, capabilities: context.capabilities,
48
- resource: { kind: 'pull-request', number: prNumber }, error: fetched.error
64
+ resource: { kind: 'pull-request', number: identityNumber, identity }, error: null
49
65
  }),
50
- reviews: []
66
+ reviews: fetched.value.map((review) => ({ id: review.id, commitId: review.commitSha || '', body: review.body, url: review.displayUrl || '' }))
51
67
  };
52
68
  }
53
- const flat = (fetched.value || []).flatMap((entry) => Array.isArray(entry) ? entry : [entry]);
54
- const reviews = flat
55
- .map((review) => ({
56
- id: review.id ?? 0,
57
- commitId: review.commit_id ?? '',
58
- body: review.body ?? '',
59
- url: review.html_url ?? ''
60
- }))
61
- .filter((review) => review.body !== '');
62
- return {
63
- ...platformResult('no-op', {
64
- platform: context.platform, capabilities: context.capabilities,
65
- resource: { kind: 'pull-request', number: prNumber }, error: null
66
- }),
67
- reviews
68
- };
69
+ return { ...platformResult('failed', { platform: context.platform, capabilities: context.capabilities, error: context.error }), reviews: [] };
69
70
  }
70
- export function publishPrReview(options) {
71
- const client = options.client || createGitHubClient();
72
- const context = resolvePlatformContext({ cwd: options.cwd || process.cwd(), client });
71
+ export async function publishPrReview(options) {
72
+ const loaded = await resolvePlatformProviderContext({ cwd: options.cwd || process.cwd(), client: options.client });
73
+ const context = loaded.ok ? loaded.value.context : loaded.context;
73
74
  if (!hasUsableContext(context)) {
74
75
  return platformResult(context.status, { platform: context.platform, capabilities: context.capabilities, error: context.error });
75
76
  }
76
- const repository = context.platform.repository;
77
- if (invalidPrNumber(options.prNumber)) {
77
+ const identity = loaded.ok ? (() => { try {
78
+ return providerResourceToken(loaded.value.provider, 'pull-request', String(options.prNumber));
79
+ }
80
+ catch {
81
+ return null;
82
+ } })() : null;
83
+ if (!identity) {
78
84
  return platformResult('failed', {
79
85
  platform: context.platform, capabilities: context.capabilities,
80
- error: { code: 'PR_NUMBER_INVALID', message: 'PR number must be positive', retryable: false }
86
+ error: { code: 'PLATFORM_IDENTITY_TOKEN_INVALID', message: 'Pull request token is invalid', retryable: false }
81
87
  });
82
88
  }
89
+ const identityNumber = resourceIdentityNumber(identity);
83
90
  if (!REVIEW_EVENTS.includes(options.event)) {
84
91
  return platformResult('failed', {
85
92
  platform: context.platform, capabilities: context.capabilities,
86
- resource: { kind: 'pull-request', number: options.prNumber },
93
+ resource: { kind: 'pull-request', number: identityNumber, identity },
87
94
  error: { code: 'REVIEW_EVENT_INVALID', message: `review event must be one of ${REVIEW_EVENTS.join('|')}`, retryable: false }
88
95
  });
89
96
  }
90
97
  if (!REVIEW_SCOPE_PATTERN.test(options.identity.scope) || !/^[0-9a-f]{7,40}$/i.test(options.identity.commitSha)) {
91
98
  return platformResult('failed', {
92
99
  platform: context.platform, capabilities: context.capabilities,
93
- resource: { kind: 'pull-request', number: options.prNumber },
100
+ resource: { kind: 'pull-request', number: identityNumber, identity },
94
101
  error: { code: 'REVIEW_IDENTITY_INVALID', message: 'review scope must be a task id or pr{N}; commitSha is required', retryable: false }
95
102
  });
96
103
  }
97
- const marker = reviewMarker(options.identity);
98
- const listed = listPrReviews(options.prNumber, { cwd: options.cwd, client });
104
+ const marker = reviewMarker({ ...options.identity, resource: identity });
105
+ const listed = await listPrReviews(options.prNumber, { cwd: options.cwd, client: options.client });
99
106
  if (listed.status === 'failed' || listed.status === 'blocked')
100
107
  return listed;
101
108
  const existing = listed.reviews.find((review) => firstLine(review.body) === marker) ?? null;
@@ -103,13 +110,13 @@ export function publishPrReview(options) {
103
110
  if (existing.commitId === options.identity.commitSha) {
104
111
  return platformResult('no-op', {
105
112
  platform: context.platform, capabilities: context.capabilities,
106
- resource: { kind: 'pull-request', number: options.prNumber },
113
+ resource: { kind: 'pull-request', number: identityNumber, identity },
107
114
  operations: [{ name: 'review:publish', status: 'no-op', reasonCode: null }], error: null
108
115
  });
109
116
  }
110
117
  return platformResult('failed', {
111
118
  platform: context.platform, capabilities: context.capabilities,
112
- resource: { kind: 'pull-request', number: options.prNumber },
119
+ resource: { kind: 'pull-request', number: identityNumber, identity },
113
120
  operations: [{ name: 'review:publish', status: 'failed', reasonCode: 'REVIEW_MARKER_CONFLICT' }],
114
121
  error: { code: 'REVIEW_MARKER_CONFLICT', message: 'A review with the same marker targets a different commit; start a new round', retryable: false }
115
122
  });
@@ -124,43 +131,52 @@ export function publishPrReview(options) {
124
131
  if (options.dryRun) {
125
132
  return platformResult('planned', {
126
133
  platform: context.platform, capabilities: context.capabilities,
127
- resource: { kind: 'pull-request', number: options.prNumber },
134
+ resource: { kind: 'pull-request', number: identityNumber, identity },
128
135
  operations: [{ name: 'review:publish', status: 'planned', reasonCode: null }], error: null
129
136
  });
130
137
  }
131
- const posted = client.json(['api', `repos/${repository}/pulls/${options.prNumber}/reviews`, '-X', 'POST', '--input', '-'], {
132
- cwd: options.cwd || process.cwd(),
133
- method: 'POST',
134
- input: JSON.stringify({ commit_id: options.identity.commitSha, body: wrappedBody, event: options.event })
135
- });
136
- if (!posted.ok) {
137
- if (posted.error.retryable) {
138
- const reconciled = listPrReviews(options.prNumber, { cwd: options.cwd, client });
139
- const found = reconciled.reviews.find((review) => firstLine(review.body) === marker);
140
- if (found) {
141
- return platformResult('applied', {
142
- changed: true, platform: context.platform, capabilities: context.capabilities,
143
- resource: { kind: 'pull-request', number: options.prNumber },
144
- operations: [{ name: 'review:publish', status: 'applied', reasonCode: 'CREATE_RECONCILED' }], error: null
138
+ if (loaded.ok) {
139
+ const published = loaded.value.provider.reviews?.publish
140
+ ? await loaded.value.provider.reviews.publish({
141
+ context: providerOperationContext(loaded.value),
142
+ changeRequest: identity,
143
+ identity: options.identity,
144
+ event: options.event,
145
+ body: wrappedBody,
146
+ mutation: { idempotencyKey: `review:publish:${marker}` }
147
+ })
148
+ : unsupportedProviderOperation(loaded.value.provider, 'reviews.publish');
149
+ if (!published.ok) {
150
+ if (published.error.retryable) {
151
+ const reconciled = await listPrReviews(options.prNumber, { cwd: options.cwd, client: options.client });
152
+ const found = reconciled.reviews.find((review) => firstLine(review.body) === marker);
153
+ if (found)
154
+ return platformResult('applied', {
155
+ changed: true, platform: context.platform, capabilities: context.capabilities,
156
+ resource: { kind: 'pull-request', number: identityNumber, identity },
157
+ operations: [{ name: 'review:publish', status: 'applied', reasonCode: 'CREATE_RECONCILED' }], error: null
158
+ });
159
+ return platformResult('blocked', {
160
+ platform: context.platform, capabilities: context.capabilities,
161
+ resource: { kind: 'pull-request', number: identityNumber, identity },
162
+ operations: [{ name: 'review:publish', status: 'failed', reasonCode: 'REVIEW_CREATE_OUTCOME_UNKNOWN' }],
163
+ error: { code: 'REVIEW_CREATE_OUTCOME_UNKNOWN', message: published.error.message, retryable: true }
145
164
  });
146
165
  }
147
- return platformResult('blocked', {
166
+ return platformResult(providerStatus(published.error), {
148
167
  platform: context.platform, capabilities: context.capabilities,
149
- resource: { kind: 'pull-request', number: options.prNumber },
150
- operations: [{ name: 'review:publish', status: 'failed', reasonCode: 'REVIEW_CREATE_OUTCOME_UNKNOWN' }],
151
- error: { code: 'REVIEW_CREATE_OUTCOME_UNKNOWN', message: posted.error.message, retryable: true }
168
+ resource: { kind: 'pull-request', number: identityNumber, identity },
169
+ operations: [{ name: 'review:publish', status: 'failed', reasonCode: published.error.code }],
170
+ error: providerError(published.error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
152
171
  });
153
172
  }
154
- return platformResult('failed', {
173
+ return platformResult('applied', {
174
+ changed: published.value.changed,
155
175
  platform: context.platform, capabilities: context.capabilities,
156
- resource: { kind: 'pull-request', number: options.prNumber },
157
- operations: [{ name: 'review:publish', status: 'failed', reasonCode: posted.error.code }], error: posted.error
176
+ resource: { kind: 'pull-request', number: identityNumber, identity },
177
+ operations: [{ name: 'review:publish', status: 'applied', reasonCode: null }], error: null
158
178
  });
159
179
  }
160
- return platformResult('applied', {
161
- changed: true, platform: context.platform, capabilities: context.capabilities,
162
- resource: { kind: 'pull-request', number: options.prNumber },
163
- operations: [{ name: 'review:publish', status: 'applied', reasonCode: null }], error: null
164
- });
180
+ return platformResult('failed', { platform: context.platform, capabilities: context.capabilities, error: context.error });
165
181
  }
166
182
  //# sourceMappingURL=pr-review.js.map