@fitlab-ai/agent-infra 0.9.13 → 0.9.15

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 (428) hide show
  1. package/README.md +10 -0
  2. package/README.zh-CN.md +10 -0
  3. package/bin/cli.ts +26 -9
  4. package/bin/internal-cli.sh +45 -0
  5. package/dist/bin/cli.js +173 -157
  6. package/dist/bin/internal-cli.js +126 -42
  7. package/dist/lib/agent-client.js +5 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +165 -27
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -2
  10. package/dist/lib/defaults.json +103 -103
  11. package/dist/lib/fs/durable-write.js +37 -0
  12. package/dist/lib/fs/file-lock.js +111 -0
  13. package/dist/lib/host-control/audit.js +19 -0
  14. package/dist/lib/host-control/client.js +142 -0
  15. package/dist/lib/host-control/command.js +49 -0
  16. package/dist/lib/host-control/path.js +160 -0
  17. package/dist/lib/host-control/secure-fs.js +140 -0
  18. package/dist/lib/host-control/server.js +159 -0
  19. package/dist/lib/host-control/service.js +112 -0
  20. package/dist/lib/init.js +11 -2
  21. package/dist/lib/internal/agent-client.js +5 -2
  22. package/dist/lib/internal/cli-route-inventory.js +154 -0
  23. package/dist/lib/internal/codex-lifecycle.js +15 -12
  24. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  25. package/dist/lib/internal/demo-promotion.js +322 -0
  26. package/dist/lib/internal/demo-transcript.js +454 -0
  27. package/dist/lib/internal/git-workflow.js +10 -6
  28. package/dist/lib/internal/host-control.js +28 -0
  29. package/dist/lib/internal/manual-validation.js +322 -0
  30. package/dist/lib/internal/platform-checks.js +16 -4
  31. package/dist/lib/internal/platform-comment.js +16 -4
  32. package/dist/lib/internal/platform-context.js +4 -1
  33. package/dist/lib/internal/platform-issue.js +12 -4
  34. package/dist/lib/internal/platform-metadata.js +88 -0
  35. package/dist/lib/internal/platform-pr-review.js +16 -3
  36. package/dist/lib/internal/platform-pr.js +42 -14
  37. package/dist/lib/internal/platform-release-notes.js +6 -3
  38. package/dist/lib/internal/platform-security.js +93 -0
  39. package/dist/lib/internal/pr-review-grade.js +14 -3
  40. package/dist/lib/internal/release-workflow.js +82 -89
  41. package/dist/lib/internal/sandbox-control.js +171 -7
  42. package/dist/lib/internal/task-activity.js +13 -4
  43. package/dist/lib/internal/task-artifact.js +19 -107
  44. package/dist/lib/internal/task-context.js +4 -1
  45. package/dist/lib/internal/task-create.js +48 -14
  46. package/dist/lib/internal/task-delivery.js +4 -1
  47. package/dist/lib/internal/task-event.js +38 -35
  48. package/dist/lib/internal/task-finalization.js +4 -1
  49. package/dist/lib/internal/task-invalidation.js +4 -1
  50. package/dist/lib/internal/task-ledger.js +12 -1
  51. package/dist/lib/internal/task-lifecycle.js +4 -1
  52. package/dist/lib/internal/task-operation-registry.js +519 -0
  53. package/dist/lib/internal/task-orchestration.js +12 -0
  54. package/dist/lib/internal/task-override.js +10 -3
  55. package/dist/lib/internal/task-qualification.js +90 -0
  56. package/dist/lib/internal/task-review.js +10 -52
  57. package/dist/lib/internal/task-short-id.js +11 -1
  58. package/dist/lib/internal/task-snapshot.js +4 -1
  59. package/dist/lib/internal/task-validate.js +37 -12
  60. package/dist/lib/internal/task-verify.js +5 -1
  61. package/dist/lib/internal/task-warning.js +8 -1
  62. package/dist/lib/owned-path.js +33 -0
  63. package/dist/lib/platform/check-status.js +11 -0
  64. package/dist/lib/platform/comment-safety.js +229 -0
  65. package/dist/lib/platform/completion-backfill.js +1 -1
  66. package/dist/lib/platform/github-data.js +241 -0
  67. package/dist/lib/platform/github-provider.js +248 -26
  68. package/dist/lib/platform/issue-comments.js +146 -34
  69. package/dist/lib/platform/issues.js +1 -179
  70. package/dist/lib/platform/pr-change-report.js +6 -12
  71. package/dist/lib/platform/pr-checks.js +12 -65
  72. package/dist/lib/platform/pr-summary.js +83 -10
  73. package/dist/lib/platform/provider-contract.d.ts +67 -1
  74. package/dist/lib/platform/provider-contract.js +6 -2
  75. package/dist/lib/platform/provider-validation.js +76 -3
  76. package/dist/lib/platform/pull-requests.js +117 -275
  77. package/dist/lib/platform/repository-metadata.js +377 -0
  78. package/dist/lib/platform/security-alerts.js +155 -0
  79. package/dist/lib/platform/snapshots.js +2 -0
  80. package/dist/lib/platform/verification-sync.js +154 -162
  81. package/dist/lib/process-data/index.js +7 -0
  82. package/dist/lib/release/workflow.js +1 -1
  83. package/dist/lib/run/index.js +5 -0
  84. package/dist/lib/sandbox/commands/control-status.js +22 -0
  85. package/dist/lib/sandbox/commands/create.js +39 -8
  86. package/dist/lib/sandbox/commands/ls.js +5 -0
  87. package/dist/lib/sandbox/commands/rm.js +3 -807
  88. package/dist/lib/sandbox/commands/show.js +16 -0
  89. package/dist/lib/sandbox/control/audit.js +203 -0
  90. package/dist/lib/sandbox/control/client.js +125 -12
  91. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  92. package/dist/lib/sandbox/control/container-identity.js +28 -31
  93. package/dist/lib/sandbox/control/executor.js +233 -34
  94. package/dist/lib/sandbox/control/finalization-response.js +27 -0
  95. package/dist/lib/sandbox/control/identity-sentinel.js +107 -0
  96. package/dist/lib/sandbox/control/lifecycle.js +656 -128
  97. package/dist/lib/sandbox/control/native-file-lock.js +85 -0
  98. package/dist/lib/sandbox/control/protocol.js +55 -4
  99. package/dist/lib/sandbox/control/server.js +720 -79
  100. package/dist/lib/sandbox/control/state.js +63 -3
  101. package/dist/lib/sandbox/control/task-view.js +183 -0
  102. package/dist/lib/sandbox/control/task-workflow.js +74 -0
  103. package/dist/lib/sandbox/control/workflow-executor.js +99 -0
  104. package/dist/lib/sandbox/engines/authority.js +289 -0
  105. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  106. package/dist/lib/sandbox/index.js +7 -2
  107. package/dist/lib/sandbox/recovery.js +49 -5
  108. package/dist/lib/sandbox/removal.js +1717 -0
  109. package/dist/lib/sandbox/task-cleanup.js +217 -0
  110. package/dist/lib/sandbox/workspace-view.js +15 -15
  111. package/dist/lib/sandbox/worktree-safety.js +4 -1
  112. package/dist/lib/server/index.js +8 -0
  113. package/dist/lib/task/activity-intent.js +2 -1
  114. package/dist/lib/task/activity-log.js +30 -24
  115. package/dist/lib/task/artifact-command.js +101 -0
  116. package/dist/lib/task/artifact-lifecycle.js +71 -40
  117. package/dist/lib/task/artifact-name.js +36 -0
  118. package/dist/lib/task/artifact-operations.js +474 -0
  119. package/dist/lib/task/artifact-receipts.js +3 -15
  120. package/dist/lib/task/artifact-repair-intent.js +130 -0
  121. package/dist/lib/task/artifact-schema.js +127 -0
  122. package/dist/lib/task/capabilities.js +83 -19
  123. package/dist/lib/task/codex-orchestration.js +71 -25
  124. package/dist/lib/task/commit-identity.js +28 -0
  125. package/dist/lib/task/commit-operation.js +2 -16
  126. package/dist/lib/task/control-authority.js +375 -5
  127. package/dist/lib/task/control-recovery.js +128 -0
  128. package/dist/lib/task/create-service.js +103 -4
  129. package/dist/lib/task/create.js +80 -2
  130. package/dist/lib/task/decision-details.js +2 -46
  131. package/dist/lib/task/events.js +306 -76
  132. package/dist/lib/task/finalization-state.js +9 -0
  133. package/dist/lib/task/human-override.js +3 -6
  134. package/dist/lib/task/implementation-inputs.js +3 -3
  135. package/dist/lib/task/index.js +11 -3
  136. package/dist/lib/task/intermediate-cleanup.js +383 -0
  137. package/dist/lib/task/invalidation.js +18 -65
  138. package/dist/lib/task/ledger-intents.js +7 -22
  139. package/dist/lib/task/ledger.js +1 -3
  140. package/dist/lib/task/lifecycle.js +19 -1
  141. package/dist/lib/task/local-artifact-finalization.js +190 -290
  142. package/dist/lib/task/manual-validation-completion.js +26 -0
  143. package/dist/lib/task/manual-validation-evidence.js +130 -0
  144. package/dist/lib/task/manual-validation-receipt.js +101 -0
  145. package/dist/lib/task/manual-validation-shared.js +40 -0
  146. package/dist/lib/task/manual-validation-transaction.js +243 -0
  147. package/dist/lib/task/markdown.js +47 -0
  148. package/dist/lib/task/orchestration.js +206 -69
  149. package/dist/lib/task/qualification-audit.js +476 -0
  150. package/dist/lib/task/qualification-confirmation.js +109 -0
  151. package/dist/lib/task/qualification-intents.js +148 -0
  152. package/dist/lib/task/review-artifacts.js +23 -40
  153. package/dist/lib/task/review-command.js +25 -0
  154. package/dist/lib/task/review-finalization.js +146 -97
  155. package/dist/lib/task/review-fingerprint.js +2 -2
  156. package/dist/lib/task/sections.js +34 -54
  157. package/dist/lib/task/verification-config.js +11 -0
  158. package/dist/lib/task/verification-engine.js +170 -327
  159. package/dist/lib/task/verification.js +1 -1
  160. package/dist/lib/task/workflow-command.js +17 -0
  161. package/dist/lib/task/workflow-warning-intents.js +0 -16
  162. package/dist/lib/task/workflow-warnings.js +28 -2
  163. package/dist/lib/update.js +2 -0
  164. package/dist/lifecycle-build-manifest.json +3 -3
  165. package/lib/agent-client.ts +9 -0
  166. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +223 -33
  167. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -2
  168. package/lib/fs/durable-write.ts +29 -0
  169. package/lib/fs/file-lock.ts +113 -0
  170. package/lib/host-control/audit.ts +22 -0
  171. package/lib/host-control/client.ts +172 -0
  172. package/lib/host-control/command.ts +60 -0
  173. package/lib/host-control/path.ts +167 -0
  174. package/lib/host-control/secure-fs.ts +135 -0
  175. package/lib/host-control/server.ts +180 -0
  176. package/lib/host-control/service.ts +133 -0
  177. package/lib/init.ts +15 -2
  178. package/lib/internal/agent-client.ts +4 -2
  179. package/lib/internal/cli-route-inventory.ts +142 -0
  180. package/lib/internal/codex-lifecycle.ts +14 -12
  181. package/lib/internal/codex-sandbox-controller.ts +7 -2
  182. package/lib/internal/demo-promotion.ts +354 -0
  183. package/lib/internal/demo-transcript.ts +419 -0
  184. package/lib/internal/git-workflow.ts +9 -6
  185. package/lib/internal/host-control.ts +28 -0
  186. package/lib/internal/manual-validation.ts +306 -0
  187. package/lib/internal/platform-checks.ts +12 -4
  188. package/lib/internal/platform-comment.ts +12 -4
  189. package/lib/internal/platform-context.ts +3 -1
  190. package/lib/internal/platform-issue.ts +11 -4
  191. package/lib/internal/platform-metadata.ts +70 -0
  192. package/lib/internal/platform-pr-review.ts +14 -3
  193. package/lib/internal/platform-pr.ts +38 -14
  194. package/lib/internal/platform-release-notes.ts +5 -3
  195. package/lib/internal/platform-security.ts +83 -0
  196. package/lib/internal/pr-review-grade.ts +10 -3
  197. package/lib/internal/release-workflow.ts +91 -87
  198. package/lib/internal/sandbox-control.ts +181 -6
  199. package/lib/internal/task-activity.ts +12 -4
  200. package/lib/internal/task-artifact.ts +15 -79
  201. package/lib/internal/task-context.ts +3 -1
  202. package/lib/internal/task-create.ts +76 -15
  203. package/lib/internal/task-delivery.ts +3 -1
  204. package/lib/internal/task-event.ts +21 -10
  205. package/lib/internal/task-finalization.ts +3 -1
  206. package/lib/internal/task-invalidation.ts +3 -1
  207. package/lib/internal/task-ledger.ts +11 -1
  208. package/lib/internal/task-lifecycle.ts +3 -1
  209. package/lib/internal/task-operation-registry.ts +590 -0
  210. package/lib/internal/task-orchestration.ts +12 -0
  211. package/lib/internal/task-override.ts +9 -3
  212. package/lib/internal/task-qualification.ts +61 -0
  213. package/lib/internal/task-review.ts +7 -50
  214. package/lib/internal/task-short-id.ts +10 -1
  215. package/lib/internal/task-snapshot.ts +3 -1
  216. package/lib/internal/task-validate.ts +32 -12
  217. package/lib/internal/task-verify.ts +4 -1
  218. package/lib/internal/task-warning.ts +7 -1
  219. package/lib/owned-path.ts +26 -0
  220. package/lib/platform/check-status.ts +9 -0
  221. package/lib/platform/comment-safety.ts +255 -0
  222. package/lib/platform/completion-backfill.ts +1 -1
  223. package/lib/platform/github-data.ts +322 -0
  224. package/lib/platform/github-provider.ts +244 -27
  225. package/lib/platform/issue-comments.ts +159 -35
  226. package/lib/platform/issues.ts +4 -245
  227. package/lib/platform/pr-change-report.ts +6 -12
  228. package/lib/platform/pr-checks.ts +13 -77
  229. package/lib/platform/pr-summary.ts +88 -11
  230. package/lib/platform/provider-contract.ts +78 -3
  231. package/lib/platform/provider-validation.ts +85 -3
  232. package/lib/platform/pull-requests.ts +129 -348
  233. package/lib/platform/repository-metadata.ts +453 -0
  234. package/lib/platform/security-alerts.ts +191 -0
  235. package/lib/platform/snapshots.ts +53 -0
  236. package/lib/platform/verification-sync.ts +171 -177
  237. package/lib/process-data/index.ts +7 -0
  238. package/lib/release/workflow.ts +3 -3
  239. package/lib/run/index.ts +5 -0
  240. package/lib/sandbox/commands/control-status.ts +26 -0
  241. package/lib/sandbox/commands/create.ts +53 -12
  242. package/lib/sandbox/commands/ls.ts +7 -0
  243. package/lib/sandbox/commands/rm.ts +3 -996
  244. package/lib/sandbox/commands/show.ts +16 -0
  245. package/lib/sandbox/control/audit.ts +253 -0
  246. package/lib/sandbox/control/client.ts +150 -13
  247. package/lib/sandbox/control/completed-reentry.ts +98 -0
  248. package/lib/sandbox/control/container-identity.ts +27 -43
  249. package/lib/sandbox/control/executor.ts +262 -37
  250. package/lib/sandbox/control/finalization-response.ts +29 -0
  251. package/lib/sandbox/control/identity-sentinel.ts +137 -0
  252. package/lib/sandbox/control/lifecycle.ts +672 -18
  253. package/lib/sandbox/control/native-file-lock.ts +108 -0
  254. package/lib/sandbox/control/protocol.ts +80 -8
  255. package/lib/sandbox/control/server.ts +779 -82
  256. package/lib/sandbox/control/state.ts +84 -3
  257. package/lib/sandbox/control/task-view.ts +240 -0
  258. package/lib/sandbox/control/task-workflow.ts +95 -0
  259. package/lib/sandbox/control/workflow-executor.ts +102 -0
  260. package/lib/sandbox/engines/authority.ts +365 -0
  261. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  262. package/lib/sandbox/index.ts +9 -2
  263. package/lib/sandbox/recovery.ts +49 -6
  264. package/lib/sandbox/removal.ts +2144 -0
  265. package/lib/sandbox/task-cleanup.ts +209 -0
  266. package/lib/sandbox/workspace-view.ts +26 -18
  267. package/lib/sandbox/worktree-safety.ts +4 -1
  268. package/lib/server/index.ts +10 -0
  269. package/lib/task/activity-intent.ts +2 -2
  270. package/lib/task/activity-log.ts +27 -19
  271. package/lib/task/artifact-command.ts +104 -0
  272. package/lib/task/artifact-lifecycle.ts +66 -39
  273. package/lib/task/artifact-name.ts +55 -0
  274. package/lib/task/artifact-operations.ts +580 -0
  275. package/lib/task/artifact-receipts.ts +3 -14
  276. package/lib/task/artifact-repair-intent.ts +152 -0
  277. package/lib/task/artifact-schema.ts +163 -0
  278. package/lib/task/capabilities.ts +82 -22
  279. package/lib/task/codex-orchestration.ts +85 -24
  280. package/lib/task/commit-identity.ts +31 -0
  281. package/lib/task/commit-operation.ts +2 -16
  282. package/lib/task/control-authority.ts +513 -6
  283. package/lib/task/control-recovery.ts +174 -0
  284. package/lib/task/create-service.ts +131 -6
  285. package/lib/task/create.ts +83 -1
  286. package/lib/task/decision-details.ts +3 -71
  287. package/lib/task/events.ts +292 -75
  288. package/lib/task/finalization-state.ts +11 -0
  289. package/lib/task/human-override.ts +3 -8
  290. package/lib/task/implementation-inputs.ts +3 -3
  291. package/lib/task/index.ts +16 -3
  292. package/lib/task/intermediate-cleanup.ts +455 -0
  293. package/lib/task/invalidation.ts +18 -62
  294. package/lib/task/ledger-intents.ts +7 -24
  295. package/lib/task/ledger.ts +1 -3
  296. package/lib/task/lifecycle.ts +17 -1
  297. package/lib/task/local-artifact-finalization.ts +223 -388
  298. package/lib/task/manual-validation-completion.ts +40 -0
  299. package/lib/task/manual-validation-evidence.ts +209 -0
  300. package/lib/task/manual-validation-receipt.ts +152 -0
  301. package/lib/task/manual-validation-shared.ts +50 -0
  302. package/lib/task/manual-validation-transaction.ts +304 -0
  303. package/lib/task/markdown.ts +70 -0
  304. package/lib/task/orchestration.ts +191 -68
  305. package/lib/task/qualification-audit.ts +588 -0
  306. package/lib/task/qualification-confirmation.ts +117 -0
  307. package/lib/task/qualification-intents.ts +150 -0
  308. package/lib/task/review-artifacts.ts +21 -41
  309. package/lib/task/review-command.ts +23 -0
  310. package/lib/task/review-finalization.ts +154 -153
  311. package/lib/task/review-fingerprint.ts +2 -2
  312. package/lib/task/sections.ts +33 -52
  313. package/lib/task/verification-config.ts +12 -0
  314. package/lib/task/verification-engine.ts +165 -370
  315. package/lib/task/verification-types.ts +17 -0
  316. package/lib/task/verification.ts +1 -1
  317. package/lib/task/workflow-command.ts +18 -0
  318. package/lib/task/workflow-warning-intents.ts +0 -13
  319. package/lib/task/workflow-warnings.ts +21 -2
  320. package/lib/update.ts +6 -0
  321. package/package.json +7 -2
  322. package/templates/.agents/hooks/lifecycle-delegation.js +6 -6
  323. package/templates/.agents/rules/README.en.md +2 -0
  324. package/templates/.agents/rules/README.zh-CN.md +2 -0
  325. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  326. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  327. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  328. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  329. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  330. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  331. package/templates/.agents/rules/local-artifact-repair.en.md +5 -1
  332. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +5 -1
  333. package/templates/.agents/rules/security-alerts.en.md +8 -8
  334. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  335. package/templates/.agents/rules/testing-discipline.en.md +2 -0
  336. package/templates/.agents/rules/testing-discipline.zh-CN.md +2 -0
  337. package/templates/.agents/scripts/package.json +3 -0
  338. package/templates/.agents/skills/analyze-task/SKILL.en.md +15 -2
  339. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +19 -2
  340. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  341. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  342. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  343. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  344. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  345. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  346. package/templates/.agents/skills/code-task/SKILL.en.md +14 -1
  347. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +14 -1
  348. package/templates/.agents/skills/code-task/config/verify.en.json +5 -14
  349. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +5 -14
  350. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  351. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  352. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  353. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  354. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  355. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  356. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  357. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  358. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +37 -21
  359. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +37 -21
  360. package/templates/.agents/skills/complete-manual-validation/config/verify.en.json +1 -1
  361. package/templates/.agents/skills/complete-manual-validation/config/verify.zh-CN.json +1 -1
  362. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +4 -0
  363. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +4 -0
  364. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +16 -7
  365. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +16 -7
  366. package/templates/.agents/skills/complete-task/SKILL.en.md +10 -23
  367. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +10 -23
  368. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  369. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  370. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  371. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  372. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  373. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  374. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  375. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  376. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  377. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  378. package/templates/.agents/skills/plan-task/SKILL.en.md +14 -1
  379. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +16 -1
  380. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  381. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  382. package/templates/.agents/skills/release/SKILL.en.md +7 -3
  383. package/templates/.agents/skills/release/SKILL.zh-CN.md +7 -3
  384. package/templates/.agents/skills/review-analysis/SKILL.en.md +14 -1
  385. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -1
  386. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  387. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  388. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  389. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  390. package/templates/.agents/skills/review-code/SKILL.en.md +14 -1
  391. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +14 -1
  392. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  393. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  394. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  395. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  396. package/templates/.agents/skills/review-plan/SKILL.en.md +14 -1
  397. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -1
  398. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  399. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  400. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  401. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  402. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  403. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  404. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  405. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  406. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +25 -4
  407. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +25 -4
  408. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +4 -1
  409. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +4 -1
  410. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +5 -1
  411. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +5 -1
  412. package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
  413. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
  414. package/templates/.agents/skills/test/SKILL.en.md +29 -7
  415. package/templates/.agents/skills/test/SKILL.zh-CN.md +29 -7
  416. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  417. package/templates/.agents/templates/task.en.md +6 -0
  418. package/templates/.agents/templates/task.zh-CN.md +6 -0
  419. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  420. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  421. package/dist/lib/platform/adapters.js +0 -56
  422. package/lib/platform/adapters.ts +0 -197
  423. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  424. package/templates/.agents/scripts/security-alerts.sh +0 -31
  425. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  426. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  427. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  428. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -1,3 +1,4 @@
1
+ import { normalizePullRequest } from './github-data.js';
1
2
  import fs from 'node:fs';
2
3
  import path from 'node:path';
3
4
  import { execFileSync } from 'node:child_process';
@@ -5,12 +6,10 @@ import { parseTypedTaskFrontmatter } from '../task/frontmatter.js';
5
6
  import { resolveTaskRef } from '../task/resolve-ref.js';
6
7
  import { extractSection } from '../task/sections.js';
7
8
  import { captureTaskWriteMetadata, writeTask } from '../task/write.js';
8
- import { parseGitHubRemote, resolvePlatformContext, resolvePlatformProviderContext } from './context.js';
9
- import { createGitHubClient } from './github-client.js';
9
+ import { resolvePlatformProviderContext } from './context.js';
10
10
  import { inspectPlatformIssue } from './issues.js';
11
- import { inspectGitHubIssue } from './issues.js';
12
11
  import { planPullRequestMetadata } from './pull-request-metadata.js';
13
- import { extractPullRequestFileNames, planInLabelUpdate, syncLabelDelta, validateInLabelMapping, validateRepositoryLabelPayload } from './in-label-sync.js';
12
+ import { planInLabelUpdate, validateInLabelMapping } from './in-label-sync.js';
14
13
  import { platformResult } from './types.js';
15
14
  import { inspectCompletionArtifacts } from '../task/finalization-artifacts.js';
16
15
  import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.js';
@@ -18,7 +17,7 @@ import { resolveDeliveryTarget } from '../task/delivery-target.js';
18
17
  import { mergeOperationWarnings } from '../task/operation-outcome.js';
19
18
  import { buildBoundFact, buildSkippedFact, factFrontmatterMutation, readPrDeliveryFact } from '../task/pr-delivery-fact.js';
20
19
  import { providerError, providerOperationContext, providerStatus, providerResourceToken, providerResourceIdentity, resourceIdentity, unsupportedProviderOperation } from './provider-bridge.js';
21
- import { isResourceIdentity, resourceIdentityEquals, resourceIdentityNumber } from './resource-identity.js';
20
+ import { isResourceIdentity, resourceIdentityEquals, resourceIdentityNumber, serializeResourceIdentity } from './resource-identity.js';
22
21
  import { taskIssueIdentity, taskIssueIdentityError } from './task-identities.js';
23
22
  function warningResultForPrimary(primaryResult) {
24
23
  if (primaryResult === 'pr_created')
@@ -56,56 +55,6 @@ function withCreation(output, creation) {
56
55
  const PRECONDITION_NOT_CREATED = {
57
56
  kind: 'not-created', reason: 'precondition-failed', createdByCurrentOperation: false
58
57
  };
59
- function normalizePullRequest(remote, repository) {
60
- const number = Number(remote.number);
61
- const headRepository = remote.head?.repo?.full_name;
62
- const baseRepository = remote.base?.repo?.full_name;
63
- if (!Number.isInteger(number) || number <= 0 || !remote.node_id || !remote.html_url ||
64
- !remote.head?.ref || !remote.head.sha || !headRepository || !remote.base?.ref || !baseRepository)
65
- return null;
66
- const mergeabilityDetail = remote.mergeable_state?.trim().toLowerCase() || null;
67
- const mergeability = remote.mergeable === false
68
- ? { state: 'conflicting', detail: mergeabilityDetail }
69
- : remote.mergeable === true && mergeabilityDetail !== 'dirty'
70
- ? { state: 'mergeable', detail: mergeabilityDetail }
71
- : { state: 'unknown', detail: mergeabilityDetail };
72
- return {
73
- repository,
74
- number,
75
- nodeId: remote.node_id,
76
- url: remote.html_url,
77
- state: remote.state === 'closed' ? 'closed' : 'open',
78
- title: remote.title || '',
79
- body: remote.body || '',
80
- draft: Boolean(remote.draft),
81
- head: { repository: headRepository, ref: remote.head.ref, sha: remote.head.sha },
82
- base: { repository: baseRepository, ref: remote.base.ref, sha: remote.base.sha || '' },
83
- mergedAt: remote.merged_at || null,
84
- mergeCommitSha: remote.merge_commit_sha || null,
85
- labels: (remote.labels || []).map((label) => typeof label === 'string' ? label : label.name || '').filter(Boolean).sort(),
86
- assignees: (remote.assignees || []).map((assignee) => assignee.login || '').filter(Boolean).sort(),
87
- milestone: remote.milestone?.title || null,
88
- mergeability
89
- };
90
- }
91
- function normalizeClosingPullRequest(node, repository) {
92
- return normalizePullRequest({
93
- number: node.number,
94
- node_id: node.id,
95
- html_url: node.url,
96
- state: node.state === 'OPEN' ? 'open' : 'closed',
97
- title: node.title,
98
- body: node.body,
99
- draft: node.isDraft,
100
- head: { ref: node.headRefName, sha: node.headRefOid, repo: node.headRepository ? { full_name: node.headRepository.nameWithOwner } : null },
101
- base: { ref: node.baseRefName, sha: node.baseRefOid, repo: node.baseRepository ? { full_name: node.baseRepository.nameWithOwner } : null },
102
- merged_at: node.mergedAt,
103
- merge_commit_sha: node.mergeCommit?.oid,
104
- labels: node.labels?.nodes,
105
- assignees: node.assignees?.nodes,
106
- milestone: node.milestone
107
- }, repository);
108
- }
109
58
  function repositoryKey(repository) {
110
59
  return repository.trim().toLowerCase();
111
60
  }
@@ -185,51 +134,6 @@ function selectExternalPullRequest(candidates, repository, existingPrIdentity, e
185
134
  };
186
135
  return { status: 'selected', source: 'unique', selected: eligible[0], candidates, eligible };
187
136
  }
188
- const CLOSING_PULL_REQUESTS_QUERY = `query($owner:String!,$name:String!,$issue:Int!,$cursor:String){repository(owner:$owner,name:$name){issue(number:$issue){closedByPullRequestsReferences(first:100,after:$cursor){nodes{number id url state title body isDraft headRefName headRefOid headRepository{nameWithOwner} baseRefName baseRefOid baseRepository{nameWithOwner} mergedAt mergeCommit{oid} labels(first:100){nodes{name}} assignees(first:100){nodes{login}} milestone{title}} pageInfo{hasNextPage endCursor}}}}}`;
189
- function inspectGitHubIssueClosingChangeRequests(client, repository, issueNumber, cwd) {
190
- const [owner, name] = repository.split('/');
191
- if (!owner || !name || !Number.isInteger(issueNumber) || issueNumber <= 0)
192
- return {
193
- ok: false,
194
- error: { code: 'PR_IDENTITY_INVALID', message: 'Repository or Issue identity is invalid', retryable: false }
195
- };
196
- const candidates = [];
197
- let cursor = null;
198
- for (;;) {
199
- const args = [
200
- 'api', 'graphql', '-f', `query=${CLOSING_PULL_REQUESTS_QUERY}`,
201
- '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `issue=${issueNumber}`
202
- ];
203
- if (cursor)
204
- args.push('-F', `cursor=${cursor}`);
205
- const response = client.json(args, { cwd });
206
- if (!response.ok)
207
- return response;
208
- const connection = response.value?.data?.repository?.issue?.closedByPullRequestsReferences;
209
- if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo)
210
- return {
211
- ok: false,
212
- error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request response is incomplete', retryable: false }
213
- };
214
- for (const node of connection.nodes) {
215
- const normalized = normalizeClosingPullRequest(node, repository);
216
- if (!normalized)
217
- return {
218
- ok: false,
219
- error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request identity is incomplete', retryable: false }
220
- };
221
- candidates.push(normalized);
222
- }
223
- if (!connection.pageInfo.hasNextPage)
224
- return { ok: true, value: candidates };
225
- if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor)
226
- return {
227
- ok: false,
228
- error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request pagination cursor is invalid', retryable: false }
229
- };
230
- cursor = connection.pageInfo.endCursor;
231
- }
232
- }
233
137
  function expectedHead(repository, head) {
234
138
  const colon = head.indexOf(':');
235
139
  if (colon === -1)
@@ -422,15 +326,6 @@ async function inspectExternalPullRequest(base, prIdentity) {
422
326
  error: null
423
327
  });
424
328
  }
425
- function inspectGitHubPullRequest(client, repository, number, cwd) {
426
- const fetched = client.json(['api', `repos/${repository}/pulls/${number}`], { cwd });
427
- if (!fetched.ok)
428
- return fetched;
429
- const pullRequest = normalizePullRequest(fetched.value, repository);
430
- return pullRequest
431
- ? { ok: true, value: pullRequest }
432
- : { ok: false, error: { code: 'PR_IDENTITY_INVALID', message: 'Remote resource is not a valid pull request', retryable: false } };
433
- }
434
329
  async function inspectPlatformPullRequest(taskRef, options = {}) {
435
330
  const base = await resolvedContext(taskRef, options);
436
331
  if (!base.ok)
@@ -487,7 +382,6 @@ async function inspectPlatformPullRequestByNumber(prNumber, options = {}) {
487
382
  error: { code: 'PLATFORM_PROVIDER_LOAD_FAILED', message: 'Selected provider failed to load', retryable: false }
488
383
  });
489
384
  }
490
- const CLOSING_ISSUES_QUERY = 'query($owner:String!,$name:String!,$number:Int!,$cursor:String){repository(owner:$owner,name:$name){pullRequest(number:$number){closingIssuesReferences(first:100,after:$cursor){nodes{number} pageInfo{hasNextPage endCursor}}}}}';
491
385
  function readInLabelMapping(repoRoot) {
492
386
  try {
493
387
  const config = JSON.parse(fs.readFileSync(path.join(repoRoot, '.agents', '.airc.json'), 'utf8'));
@@ -528,105 +422,19 @@ function taskInLabelTarget(repoRoot, frontmatter, currentLabels, repositoryLabel
528
422
  return { ok: false, error: planned.error };
529
423
  return { ok: true, value: planned.target };
530
424
  }
531
- function inspectClosingIssueNumbers(client, repository, pullRequest, cwd) {
532
- const [owner, name] = repository.split('/');
533
- if (!owner || !name)
534
- return {
535
- ok: false,
536
- error: { code: 'IN_LABEL_SYNC_REPOSITORY_INVALID', message: 'Repository identity is invalid', retryable: false }
537
- };
538
- let cursor = null;
539
- const numbers = [];
540
- for (;;) {
541
- const args = ['api', 'graphql', '-f', `query=${CLOSING_ISSUES_QUERY}`, '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `number=${pullRequest}`];
542
- if (cursor)
543
- args.push('-F', `cursor=${cursor}`);
544
- const response = client.json(args, { cwd });
545
- if (!response.ok)
546
- return response;
547
- const connection = response.value?.data?.repository?.pullRequest?.closingIssuesReferences;
548
- if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo)
549
- return {
550
- ok: false,
551
- error: { code: 'IN_LABEL_SYNC_ASSOCIATION_INVALID', message: 'Closing Issue response is incomplete', retryable: false }
552
- };
553
- for (const node of connection.nodes) {
554
- const issue = Number(node?.number);
555
- if (!Number.isSafeInteger(issue) || issue <= 0)
556
- return {
557
- ok: false,
558
- error: { code: 'IN_LABEL_SYNC_ASSOCIATION_INVALID', message: 'Closing Issue identity is invalid', retryable: false }
559
- };
560
- numbers.push(issue);
561
- }
562
- if (!connection.pageInfo.hasNextPage)
563
- return { ok: true, value: [...new Set(numbers)] };
564
- if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor)
565
- return {
566
- ok: false,
567
- error: { code: 'IN_LABEL_SYNC_ASSOCIATION_INVALID', message: 'Closing Issue pagination cursor is invalid', retryable: false }
568
- };
569
- cursor = connection.pageInfo.endCursor;
570
- }
571
- }
572
- function inspectRepositoryLabels(client, repository, cwd) {
573
- const response = client.json(['api', '--paginate', '--slurp', `repos/${repository}/labels?per_page=100`], { cwd });
574
- if (!response.ok)
575
- return response;
576
- const labels = validateRepositoryLabelPayload(response.value);
577
- return labels.ok ? { ok: true, value: new Set(labels.value) } : labels;
425
+ function resourceIdentityLabel(identity) {
426
+ const number = resourceIdentityNumber(identity);
427
+ return number === null ? `${identity.kind} ${identity.value}` : `#${number}`;
578
428
  }
579
- function inspectPullRequestFiles(client, repository, pullRequest, cwd) {
580
- const response = client.json(['api', '--paginate', '--slurp', `repos/${repository}/pulls/${pullRequest}/files?per_page=100`], { cwd });
581
- if (!response.ok)
582
- return response;
583
- const files = extractPullRequestFileNames(response.value);
584
- return files ? { ok: true, value: files } : {
585
- ok: false,
586
- error: { code: 'IN_LABEL_SYNC_FILES_INVALID', message: 'Pull request files response is incomplete', retryable: false }
587
- };
588
- }
589
- function inspectTaskInLabelTarget(repoRoot, frontmatter, pullRequest, repository, client) {
590
- const baseRef = typeof frontmatter.delivery_base_ref === 'string' ? frontmatter.delivery_base_ref.trim() : '';
591
- if (!baseRef)
592
- return {
593
- ok: false,
594
- error: { code: 'IN_LABEL_SYNC_BASE_MISSING', message: 'Task has no delivery_base_ref for in-label evidence', retryable: false }
595
- };
596
- let changedFiles;
597
- try {
598
- changedFiles = execFileSync('git', ['diff', `${baseRef}...HEAD`, '--name-only'], {
599
- cwd: repoRoot, encoding: 'utf8'
600
- }).trim().split(/\r?\n/).filter(Boolean);
601
- }
602
- catch (error) {
603
- return {
604
- ok: false,
605
- error: { code: 'IN_LABEL_SYNC_EVIDENCE_UNAVAILABLE', message: error instanceof Error ? error.message : String(error), retryable: false }
606
- };
607
- }
608
- const mapping = readInLabelMapping(repoRoot);
609
- if (!mapping.ok)
610
- return mapping;
611
- const labels = inspectRepositoryLabels(client, repository, repoRoot);
612
- if (!labels.ok)
613
- return labels;
614
- const planned = planInLabelUpdate({
615
- changedFiles, currentLabels: pullRequest.labels, mapping: mapping.value, repositoryLabels: labels.value
616
- });
617
- if (planned.error)
618
- return { ok: false, error: planned.error };
619
- return { ok: true, value: { changedFiles, target: planned.target } };
620
- }
621
- function inLabelResource(kind, number, before, expected, after, effect) {
622
- return { kind, number, before: [...before].sort(), expected: [...expected].sort(), after: after ? [...after].sort() : null, effect };
429
+ function inLabelResource(kind, identity, before, expected, after, effect) {
430
+ return { kind, number: resourceIdentityNumber(identity), identity, before: [...before].sort(), expected: [...expected].sort(), after: after ? [...after].sort() : null, effect };
623
431
  }
624
432
  async function syncPlatformPullRequestInLabels(prNumber, options = {}) {
625
433
  const cwd = path.resolve(options.cwd || process.cwd());
626
- const client = options.client || createGitHubClient();
627
- const context = await resolvePlatformContext({ cwd, client });
434
+ const loaded = await resolvePlatformProviderContext({ cwd, client: options.client });
435
+ const context = loaded.ok ? loaded.value.context : loaded.context;
628
436
  const usable = (context.status === 'no-op' || context.status === 'degraded') && context.platform.repository;
629
- if (!usable)
437
+ if (!loaded.ok || !usable)
630
438
  return result(context.status, null, null, prNumber, {
631
439
  platform: context.platform, capabilities: context.capabilities, operations: context.operations, error: context.error
632
440
  });
@@ -635,68 +443,79 @@ async function syncPlatformPullRequestInLabels(prNumber, options = {}) {
635
443
  platform: context.platform, capabilities: context.capabilities,
636
444
  error: { code: 'PR_NUMBER_INVALID', message: 'PR number must be positive', retryable: false }
637
445
  });
446
+ const provider = loaded.value.provider;
447
+ const operationContext = providerOperationContext(loaded.value);
638
448
  const repository = context.platform.repository;
639
- const fetched = inspectGitHubPullRequest(client, repository, prNumber, cwd);
640
- if (!fetched.ok)
641
- return result(fetched.error.retryable ? 'blocked' : 'failed', null, null, prNumber, {
642
- platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: fetched.error
643
- });
644
- const files = inspectPullRequestFiles(client, repository, prNumber, cwd);
449
+ const pullRequestIdentity = providerResourceToken(provider, 'pull-request', String(prNumber));
450
+ const providerFailure = (error) => result(error.code === 'PLATFORM_CAPABILITY_UNSUPPORTED' ? 'degraded' : providerStatus(error), null, null, prNumber, {
451
+ platform: context.platform,
452
+ capabilities: context.capabilities,
453
+ resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity },
454
+ error: providerError(error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
455
+ });
456
+ const inspected = provider.changeRequests?.inspect
457
+ ? await provider.changeRequests.inspect({ context: operationContext, target: pullRequestIdentity })
458
+ : unsupportedProviderOperation(provider, 'changeRequests.inspect');
459
+ if (!inspected.ok)
460
+ return providerFailure(inspected.error);
461
+ const fetched = normalizeProviderPullRequest(inspected.value, repository, prNumber);
462
+ const files = provider.changeRequests?.listFiles
463
+ ? await provider.changeRequests.listFiles({ context: operationContext, target: pullRequestIdentity })
464
+ : unsupportedProviderOperation(provider, 'changeRequests.listFiles');
645
465
  if (!files.ok)
646
- return result(files.error.retryable ? 'blocked' : 'failed', null, null, prNumber, {
647
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
648
- resource: { kind: 'pull-request', number: prNumber }, error: files.error
649
- });
466
+ return providerFailure(files.error);
650
467
  const mapping = readInLabelMapping(cwd);
651
468
  if (!mapping.ok)
652
469
  return result('failed', null, null, prNumber, {
653
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
654
- resource: { kind: 'pull-request', number: prNumber }, error: mapping.error
655
- });
656
- const repositoryLabels = inspectRepositoryLabels(client, repository, cwd);
657
- if (!repositoryLabels.ok)
658
- return result(repositoryLabels.error.retryable ? 'blocked' : 'failed', null, null, prNumber, {
659
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
660
- resource: { kind: 'pull-request', number: prNumber }, error: repositoryLabels.error
470
+ platform: context.platform, capabilities: context.capabilities, pullRequest: fetched,
471
+ resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, error: mapping.error
661
472
  });
473
+ let repositoryLabels = new Set();
474
+ if (Object.keys(mapping.value).length > 0) {
475
+ const labels = provider.issues?.listLabels
476
+ ? await provider.issues.listLabels({ context: operationContext })
477
+ : unsupportedProviderOperation(provider, 'issues.listLabels');
478
+ if (!labels.ok)
479
+ return providerFailure(labels.error);
480
+ repositoryLabels = new Set(labels.value);
481
+ }
662
482
  const plannedTarget = planInLabelUpdate({
663
- changedFiles: files.value, currentLabels: fetched.value.labels,
664
- mapping: mapping.value, repositoryLabels: repositoryLabels.value
483
+ changedFiles: files.value, currentLabels: fetched.labels,
484
+ mapping: mapping.value, repositoryLabels
665
485
  });
666
486
  if (plannedTarget.error)
667
487
  return result('failed', null, null, prNumber, {
668
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
669
- resource: { kind: 'pull-request', number: prNumber }, error: plannedTarget.error
488
+ platform: context.platform, capabilities: context.capabilities, pullRequest: fetched,
489
+ resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, error: plannedTarget.error
670
490
  });
671
- const target = plannedTarget.target;
672
- const association = inspectClosingIssueNumbers(client, repository, prNumber, cwd);
491
+ const association = provider.changeRequests?.listClosingIssues
492
+ ? await provider.changeRequests.listClosingIssues({ context: operationContext, target: pullRequestIdentity })
493
+ : unsupportedProviderOperation(provider, 'changeRequests.listClosingIssues');
673
494
  if (!association.ok)
674
- return result(association.error.retryable ? 'blocked' : 'failed', null, null, prNumber, {
675
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
676
- resource: { kind: 'pull-request', number: prNumber }, evidence: { kind: 'pull-request-files', pullRequestFiles: files.value }, error: association.error
677
- });
678
- const issueNumber = association.value.length === 1 ? association.value[0] : null;
495
+ return providerFailure(association.error);
496
+ const issueIdentity = association.value.length === 1 ? association.value[0] : null;
497
+ const issueNumber = issueIdentity ? resourceIdentityNumber(issueIdentity) : null;
498
+ const closingIssueIdentities = association.value;
679
499
  let issue = null;
680
- if (issueNumber) {
681
- const fetchedIssue = inspectGitHubIssue(client, repository, issueNumber, cwd);
500
+ if (issueIdentity) {
501
+ const fetchedIssue = provider.issues?.inspect
502
+ ? await provider.issues.inspect({ context: operationContext, target: issueIdentity })
503
+ : unsupportedProviderOperation(provider, 'issues.inspect');
682
504
  if (!fetchedIssue.ok)
683
- return result(fetchedIssue.error.retryable ? 'blocked' : 'failed', null, issueNumber, prNumber, {
684
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
685
- resource: { kind: 'issue', number: issueNumber }, evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value }, error: fetchedIssue.error
686
- });
505
+ return providerFailure(fetchedIssue.error);
687
506
  issue = fetchedIssue.value;
688
507
  }
689
508
  const resources = issue
690
509
  ? [
691
- { kind: 'issue', number: issue.number, snapshot: issue },
692
- { kind: 'pull-request', number: prNumber, snapshot: fetched.value }
510
+ { kind: 'issue', identity: issueIdentity, number: issueNumber, snapshot: issue },
511
+ { kind: 'pull-request', identity: pullRequestIdentity, number: prNumber, snapshot: fetched }
693
512
  ]
694
- : [{ kind: 'pull-request', number: prNumber, snapshot: fetched.value }];
513
+ : [{ kind: 'pull-request', identity: pullRequestIdentity, number: prNumber, snapshot: fetched }];
695
514
  const plans = resources.map((resource) => ({
696
515
  ...resource,
697
516
  plan: planInLabelUpdate({
698
517
  changedFiles: files.value, currentLabels: resource.snapshot.labels,
699
- mapping: mapping.value, repositoryLabels: repositoryLabels.value
518
+ mapping: mapping.value, repositoryLabels
700
519
  })
701
520
  }));
702
521
  const operations = [
@@ -708,63 +527,86 @@ async function syncPlatformPullRequestInLabels(prNumber, options = {}) {
708
527
  }))
709
528
  ];
710
529
  const willWrite = context.capabilities.triage && !options.dryRun;
711
- const resourcesState = plans.map((item) => inLabelResource(item.kind, item.number, item.snapshot.labels, target, item.plan.changed && willWrite ? null : item.snapshot.labels, item.plan.changed && willWrite ? 'unknown' : 'no-op'));
530
+ const resourcesState = plans.map((item) => inLabelResource(item.kind, item.identity, item.snapshot.labels, item.plan.target, item.plan.changed && willWrite ? null : item.snapshot.labels, item.plan.changed && willWrite ? 'unknown' : 'no-op'));
712
531
  if (options.dryRun || !context.capabilities.triage)
713
532
  return result(!context.capabilities.triage || association.value.length !== 1 ? 'degraded' : plans.some((item) => item.plan.changed) ? 'planned' : 'no-op', null, issueNumber, prNumber, {
714
- platform: context.platform, capabilities: context.capabilities, pullRequest: fetched.value,
715
- resource: { kind: 'pull-request', number: prNumber }, operations, resources: resourcesState,
716
- evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value }, error: null
533
+ platform: context.platform, capabilities: context.capabilities, pullRequest: fetched,
534
+ resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, operations, resources: resourcesState,
535
+ evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: closingIssueIdentities }, error: null
717
536
  });
718
- let currentPullRequest = fetched.value;
537
+ let currentPullRequest = fetched;
719
538
  let successfulWrites = 0;
720
539
  for (const item of plans) {
721
540
  if (!item.plan.changed)
722
541
  continue;
723
- const synced = syncLabelDelta(client, repository, item.number, cwd, item.snapshot.labels, item.plan.target);
724
- if (synced.status === 'failed' || synced.status === 'blocked') {
725
- const state = resourcesState.find((resource) => resource.kind === item.kind && resource.number === item.number);
726
- state.effect = synced.status === 'blocked' ? 'unknown' : 'no-op';
727
- state.after = synced.status === 'blocked' ? null : item.snapshot.labels;
728
- const partial = successfulWrites > 0 || synced.status === 'blocked';
729
- const error = partial && synced.error
542
+ const targetIdentity = item.kind === 'issue' ? issueIdentity : pullRequestIdentity;
543
+ const synced = item.kind === 'issue'
544
+ ? provider.issues?.update
545
+ ? await provider.issues.update({
546
+ context: operationContext,
547
+ target: targetIdentity,
548
+ currentLabels: item.snapshot.labels,
549
+ patch: { labels: item.plan.labels },
550
+ mutation: { idempotencyKey: `issue:update:${serializeResourceIdentity(targetIdentity)}:in-labels`, target: targetIdentity }
551
+ })
552
+ : unsupportedProviderOperation(provider, 'issues.update')
553
+ : provider.changeRequests?.update
554
+ ? await provider.changeRequests.update({
555
+ context: operationContext,
556
+ target: targetIdentity,
557
+ currentLabels: item.snapshot.labels,
558
+ patch: { labels: item.plan.labels },
559
+ mutation: { idempotencyKey: `pull-request:update:${serializeResourceIdentity(targetIdentity)}:in-labels`, target: targetIdentity }
560
+ })
561
+ : unsupportedProviderOperation(provider, 'changeRequests.update');
562
+ if (!synced.ok) {
563
+ const state = resourcesState.find((resource) => resource.kind === item.kind && resourceIdentityEquals(resource.identity, item.identity));
564
+ state.effect = synced.error.retryable ? 'unknown' : 'no-op';
565
+ state.after = state.effect === 'unknown' ? null : item.snapshot.labels;
566
+ const partial = successfulWrites > 0 || synced.error.retryable;
567
+ const error = partial
730
568
  ? { ...synced.error, code: 'IN_LABEL_SYNC_PARTIAL', message: `In-label synchronization is partial or unknown: ${synced.error.message}` }
731
569
  : synced.error;
732
- return result(partial ? 'blocked' : synced.status, null, issueNumber, prNumber, {
733
- changed: successfulWrites > 0 || synced.changed, platform: context.platform, capabilities: context.capabilities,
734
- pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber }, operations, resources: resourcesState,
735
- evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value }, error
570
+ return result(partial ? 'blocked' : providerStatus(synced.error), null, issueNumber, prNumber, {
571
+ changed: successfulWrites > 0, platform: context.platform, capabilities: context.capabilities,
572
+ pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, operations, resources: resourcesState,
573
+ evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: closingIssueIdentities }, error: providerError(error, 'PLATFORM_PROVIDER_OPERATION_FAILED')
736
574
  });
737
575
  }
738
- successfulWrites += synced.changed ? 1 : 0;
576
+ successfulWrites += synced.value.changed ? 1 : 0;
739
577
  const reread = item.kind === 'issue'
740
- ? inspectGitHubIssue(client, repository, item.number, cwd)
741
- : inspectGitHubPullRequest(client, repository, item.number, cwd);
578
+ ? provider.issues?.inspect
579
+ ? await provider.issues.inspect({ context: operationContext, target: targetIdentity })
580
+ : unsupportedProviderOperation(provider, 'issues.inspect')
581
+ : provider.changeRequests?.inspect
582
+ ? await provider.changeRequests.inspect({ context: operationContext, target: targetIdentity })
583
+ : unsupportedProviderOperation(provider, 'changeRequests.inspect');
742
584
  if (!reread.ok)
743
585
  return result('blocked', null, issueNumber, prNumber, {
744
586
  changed: true, platform: context.platform, capabilities: context.capabilities,
745
- pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber }, operations, resources: resourcesState,
746
- evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value },
747
- error: { ...reread.error, code: 'IN_LABEL_SYNC_PARTIAL', message: `In-label synchronization is partial or unknown: ${reread.error.message}` }
587
+ pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, operations, resources: resourcesState,
588
+ evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: closingIssueIdentities },
589
+ error: { ...providerError(reread.error, 'PLATFORM_PROVIDER_OPERATION_FAILED'), code: 'IN_LABEL_SYNC_PARTIAL', message: `In-label synchronization is partial or unknown: ${reread.error.message}` }
748
590
  });
749
- const after = reread.value.labels;
750
- const state = resourcesState.find((resource) => resource.kind === item.kind && resource.number === item.number);
591
+ const after = reread.value.labels || [];
592
+ const state = resourcesState.find((resource) => resource.kind === item.kind && resourceIdentityEquals(resource.identity, item.identity));
751
593
  state.after = after;
752
- state.effect = after.filter((label) => label.startsWith('in:')).sort().join('\0') === target.join('\0') ? 'applied' : 'unknown';
594
+ state.effect = after.filter((label) => label.startsWith('in:')).sort().join('\0') === item.plan.target.join('\0') ? 'applied' : 'unknown';
753
595
  if (state.effect === 'unknown')
754
596
  return result('blocked', null, issueNumber, prNumber, {
755
597
  changed: true, platform: context.platform, capabilities: context.capabilities,
756
- pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber }, operations, resources: resourcesState,
757
- evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value },
758
- error: { code: 'IN_LABEL_SYNC_PARTIAL', message: `${item.kind} #${item.number} did not converge to the expected in: labels`, retryable: true }
598
+ pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity }, operations, resources: resourcesState,
599
+ evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: closingIssueIdentities },
600
+ error: { code: 'IN_LABEL_SYNC_PARTIAL', message: `${item.kind} ${resourceIdentityLabel(item.identity)} did not converge to the expected in: labels`, retryable: true }
759
601
  });
760
602
  if (item.kind === 'pull-request')
761
- currentPullRequest = reread.value;
603
+ currentPullRequest = normalizeProviderPullRequest(reread.value, repository, prNumber, currentPullRequest);
762
604
  }
763
605
  return result(association.value.length !== 1 ? 'degraded' : successfulWrites > 0 ? 'applied' : 'no-op', null, issueNumber, prNumber, {
764
606
  changed: successfulWrites > 0, platform: context.platform, capabilities: context.capabilities,
765
- pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber },
607
+ pullRequest: currentPullRequest, resource: { kind: 'pull-request', number: prNumber, identity: pullRequestIdentity },
766
608
  operations: operations.map((operation) => operation.status === 'planned' ? { ...operation, status: 'applied' } : operation),
767
- resources: resourcesState, evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: association.value }, error: null
609
+ resources: resourcesState, evidence: { kind: 'pull-request-files', pullRequestFiles: files.value, closingIssues: closingIssueIdentities }, error: null
768
610
  });
769
611
  }
770
612
  function appendActivity(content, line) {
@@ -1518,6 +1360,6 @@ async function skipPlatformPullRequestFact(taskRef, options) {
1518
1360
  });
1519
1361
  }
1520
1362
  }
1521
- export { bindPlatformPullRequest, createPlatformPullRequest, inspectGitHubPullRequest, inspectGitHubIssueClosingChangeRequests, inspectPlatformPullRequest, inspectPlatformPullRequestByNumber, normalizePullRequest, resolveExternalPullRequest, skipPlatformPullRequestFact, selectExternalPullRequest, selectPullRequest, syncPlatformPullRequest, syncPlatformPullRequestInLabels };
1363
+ export { bindPlatformPullRequest, createPlatformPullRequest, inspectPlatformPullRequest, inspectPlatformPullRequestByNumber, resolveExternalPullRequest, skipPlatformPullRequestFact, selectExternalPullRequest, selectPullRequest, syncPlatformPullRequest, syncPlatformPullRequestInLabels };
1522
1364
  export { warningResultForPrimary };
1523
1365
  //# sourceMappingURL=pull-requests.js.map