@fitlab-ai/agent-infra 0.9.12 → 0.9.14

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 (402) hide show
  1. package/README.md +11 -11
  2. package/README.zh-CN.md +11 -11
  3. package/bin/cli.ts +26 -9
  4. package/dist/bin/cli.js +173 -157
  5. package/dist/bin/internal-cli.js +66 -40
  6. package/dist/lib/agent-client.js +5 -0
  7. package/dist/lib/agent-clients/next-steps.js +6 -1
  8. package/dist/lib/decide.js +3 -3
  9. package/dist/lib/internal/agent-client.js +5 -2
  10. package/dist/lib/internal/cli-route-inventory.js +152 -0
  11. package/dist/lib/internal/codex-lifecycle.js +9 -6
  12. package/dist/lib/internal/codex-sandbox-controller.js +8 -2
  13. package/dist/lib/internal/git-workflow.js +10 -6
  14. package/dist/lib/internal/platform-checks.js +19 -7
  15. package/dist/lib/internal/platform-comment.js +25 -13
  16. package/dist/lib/internal/platform-context.js +6 -3
  17. package/dist/lib/internal/platform-issue.js +20 -13
  18. package/dist/lib/internal/platform-metadata.js +88 -0
  19. package/dist/lib/internal/platform-pr-review.js +26 -13
  20. package/dist/lib/internal/platform-pr.js +84 -31
  21. package/dist/lib/internal/platform-release-notes.js +9 -6
  22. package/dist/lib/internal/platform-security.js +93 -0
  23. package/dist/lib/internal/pr-review-grade.js +25 -12
  24. package/dist/lib/internal/release-workflow.js +23 -9
  25. package/dist/lib/internal/sandbox-control.js +50 -7
  26. package/dist/lib/internal/task-activity.js +16 -7
  27. package/dist/lib/internal/task-artifact.js +235 -24
  28. package/dist/lib/internal/task-context.js +4 -1
  29. package/dist/lib/internal/task-create.js +50 -17
  30. package/dist/lib/internal/task-delivery.js +4 -1
  31. package/dist/lib/internal/task-event.js +10 -4
  32. package/dist/lib/internal/task-finalization.js +6 -3
  33. package/dist/lib/internal/task-invalidation.js +63 -0
  34. package/dist/lib/internal/task-ledger.js +20 -6
  35. package/dist/lib/internal/task-lifecycle.js +6 -3
  36. package/dist/lib/internal/task-operation-registry.js +421 -0
  37. package/dist/lib/internal/task-orchestration.js +12 -0
  38. package/dist/lib/internal/task-override.js +14 -7
  39. package/dist/lib/internal/task-qualification.js +90 -0
  40. package/dist/lib/internal/task-review.js +7 -4
  41. package/dist/lib/internal/task-short-id.js +11 -1
  42. package/dist/lib/internal/task-snapshot.js +4 -1
  43. package/dist/lib/internal/task-validate.js +7 -2
  44. package/dist/lib/internal/task-verify.js +11 -7
  45. package/dist/lib/internal/task-warning.js +11 -4
  46. package/dist/lib/platform/adapters.js +1 -3
  47. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  48. package/dist/lib/platform/comment-safety.js +226 -0
  49. package/dist/lib/platform/completion-backfill.js +6 -5
  50. package/dist/lib/platform/context.js +70 -130
  51. package/dist/lib/platform/github-client.js +1 -1
  52. package/dist/lib/platform/github-provider.js +1130 -0
  53. package/dist/lib/platform/in-label-sync.js +143 -0
  54. package/dist/lib/platform/issue-comments.js +237 -72
  55. package/dist/lib/platform/issues.js +335 -189
  56. package/dist/lib/platform/metadata-labels.js +6 -2
  57. package/dist/lib/platform/none-provider.js +28 -0
  58. package/dist/lib/platform/pr-change-report.js +545 -0
  59. package/dist/lib/platform/pr-checks.js +119 -104
  60. package/dist/lib/platform/pr-review.js +88 -72
  61. package/dist/lib/platform/pr-summary.js +541 -50
  62. package/dist/lib/platform/provider-bridge.js +45 -0
  63. package/dist/lib/platform/provider-contract.d.ts +553 -0
  64. package/dist/lib/platform/provider-contract.js +99 -0
  65. package/dist/lib/platform/provider-loader.js +251 -0
  66. package/dist/lib/platform/provider-validation.js +577 -0
  67. package/dist/lib/platform/pull-request-metadata.js +8 -6
  68. package/dist/lib/platform/pull-requests.js +734 -543
  69. package/dist/lib/platform/release-notes.js +78 -55
  70. package/dist/lib/platform/releases.js +79 -50
  71. package/dist/lib/platform/repository-metadata.js +377 -0
  72. package/dist/lib/platform/resource-identity.d.ts +26 -0
  73. package/dist/lib/platform/resource-identity.js +92 -0
  74. package/dist/lib/platform/security-alerts.js +155 -0
  75. package/dist/lib/platform/task-identities.js +31 -0
  76. package/dist/lib/platform/verification-required.js +11 -12
  77. package/dist/lib/platform/verification-sync.js +129 -248
  78. package/dist/lib/pr-review/evidence-grading.js +19 -6
  79. package/dist/lib/process-data/index.js +7 -0
  80. package/dist/lib/run/index.js +68 -23
  81. package/dist/lib/sandbox/commands/control-status.js +22 -0
  82. package/dist/lib/sandbox/commands/create.js +32 -6
  83. package/dist/lib/sandbox/commands/ls.js +5 -0
  84. package/dist/lib/sandbox/commands/rm.js +827 -120
  85. package/dist/lib/sandbox/commands/show.js +16 -0
  86. package/dist/lib/sandbox/control/client.js +174 -19
  87. package/dist/lib/sandbox/control/completed-reentry.js +85 -0
  88. package/dist/lib/sandbox/control/container-identity.js +28 -31
  89. package/dist/lib/sandbox/control/executor.js +151 -16
  90. package/dist/lib/sandbox/control/lifecycle.js +621 -127
  91. package/dist/lib/sandbox/control/native-file-lock.js +177 -0
  92. package/dist/lib/sandbox/control/protocol.js +77 -0
  93. package/dist/lib/sandbox/control/server.js +677 -34
  94. package/dist/lib/sandbox/control/state.js +209 -4
  95. package/dist/lib/sandbox/control/task-view.js +183 -0
  96. package/dist/lib/sandbox/engines/authority.js +289 -0
  97. package/dist/lib/sandbox/engines/docker-exact-discovery.js +97 -0
  98. package/dist/lib/sandbox/index.js +5 -0
  99. package/dist/lib/sandbox/recovery.js +21 -1
  100. package/dist/lib/sandbox/workspace-view.js +2 -1
  101. package/dist/lib/sandbox/worktree-safety.js +4 -1
  102. package/dist/lib/server/index.js +8 -0
  103. package/dist/lib/server/protocol.js +38 -1
  104. package/dist/lib/task/activity-log.js +8 -1
  105. package/dist/lib/task/artifact-lifecycle.js +75 -18
  106. package/dist/lib/task/artifact-operations.js +520 -0
  107. package/dist/lib/task/artifact-repair-intent.js +59 -0
  108. package/dist/lib/task/artifact-schema.js +135 -0
  109. package/dist/lib/task/capabilities.js +310 -0
  110. package/dist/lib/task/commands/status.js +32 -0
  111. package/dist/lib/task/commit-operation.js +12 -1
  112. package/dist/lib/task/control-authority.js +12 -5
  113. package/dist/lib/task/create-service.js +111 -12
  114. package/dist/lib/task/create.js +25 -0
  115. package/dist/lib/task/current-contract.js +5 -1
  116. package/dist/lib/task/decision-details.js +1 -1
  117. package/dist/lib/task/events.js +416 -17
  118. package/dist/lib/task/finalization.js +37 -13
  119. package/dist/lib/task/human-override.js +58 -36
  120. package/dist/lib/task/index.js +11 -3
  121. package/dist/lib/task/invalidation-command.js +86 -0
  122. package/dist/lib/task/invalidation.js +260 -0
  123. package/dist/lib/task/ledger-intents.js +37 -0
  124. package/dist/lib/task/local-artifact-finalization.js +299 -0
  125. package/dist/lib/task/orchestration.js +240 -144
  126. package/dist/lib/task/pr-delivery-fact.js +102 -101
  127. package/dist/lib/task/qualification-audit.js +490 -0
  128. package/dist/lib/task/qualification-confirmation.js +109 -0
  129. package/dist/lib/task/qualification-intents.js +148 -0
  130. package/dist/lib/task/review-artifacts.js +22 -23
  131. package/dist/lib/task/review-finalization.js +121 -4
  132. package/dist/lib/task/review-fingerprint.js +24 -2
  133. package/dist/lib/task/rework-intent.js +138 -0
  134. package/dist/lib/task/sections.js +6 -4
  135. package/dist/lib/task/skill-scope.js +23 -0
  136. package/dist/lib/task/task-execution-lock.js +27 -17
  137. package/dist/lib/task/verification-config.js +11 -0
  138. package/dist/lib/task/verification-engine.js +93 -16
  139. package/dist/lib/task/verification.js +3 -3
  140. package/dist/lib/task/workflow-warning-intents.js +1 -1
  141. package/dist/lib/task/write.js +11 -0
  142. package/dist/lib/version.js +11 -1
  143. package/dist/lifecycle-build-manifest.json +3 -3
  144. package/lib/agent-client.ts +9 -0
  145. package/lib/agent-clients/next-steps.ts +6 -1
  146. package/lib/decide.ts +3 -3
  147. package/lib/init.ts +1 -1
  148. package/lib/internal/agent-client.ts +4 -2
  149. package/lib/internal/cli-route-inventory.ts +140 -0
  150. package/lib/internal/codex-lifecycle.ts +8 -6
  151. package/lib/internal/codex-sandbox-controller.ts +7 -2
  152. package/lib/internal/git-workflow.ts +9 -6
  153. package/lib/internal/platform-checks.ts +14 -6
  154. package/lib/internal/platform-comment.ts +20 -12
  155. package/lib/internal/platform-context.ts +5 -3
  156. package/lib/internal/platform-issue.ts +17 -11
  157. package/lib/internal/platform-metadata.ts +70 -0
  158. package/lib/internal/platform-pr-review.ts +23 -12
  159. package/lib/internal/platform-pr.ts +65 -27
  160. package/lib/internal/platform-release-notes.ts +8 -6
  161. package/lib/internal/platform-security.ts +83 -0
  162. package/lib/internal/pr-review-grade.ts +20 -11
  163. package/lib/internal/release-workflow.ts +21 -9
  164. package/lib/internal/sandbox-control.ts +44 -6
  165. package/lib/internal/task-activity.ts +15 -7
  166. package/lib/internal/task-artifact.ts +204 -22
  167. package/lib/internal/task-context.ts +3 -1
  168. package/lib/internal/task-create.ts +78 -17
  169. package/lib/internal/task-delivery.ts +3 -1
  170. package/lib/internal/task-event.ts +9 -4
  171. package/lib/internal/task-finalization.ts +6 -4
  172. package/lib/internal/task-invalidation.ts +41 -0
  173. package/lib/internal/task-ledger.ts +21 -8
  174. package/lib/internal/task-lifecycle.ts +5 -3
  175. package/lib/internal/task-operation-registry.ts +482 -0
  176. package/lib/internal/task-orchestration.ts +12 -0
  177. package/lib/internal/task-override.ts +15 -9
  178. package/lib/internal/task-qualification.ts +61 -0
  179. package/lib/internal/task-review.ts +6 -4
  180. package/lib/internal/task-short-id.ts +10 -1
  181. package/lib/internal/task-snapshot.ts +3 -1
  182. package/lib/internal/task-validate.ts +6 -2
  183. package/lib/internal/task-verify.ts +10 -7
  184. package/lib/internal/task-warning.ts +10 -4
  185. package/lib/platform/adapters.ts +3 -2
  186. package/lib/platform/change-request-git-evidence.ts +36 -9
  187. package/lib/platform/comment-safety.ts +250 -0
  188. package/lib/platform/completion-backfill.ts +9 -8
  189. package/lib/platform/context.ts +97 -134
  190. package/lib/platform/github-client.ts +2 -2
  191. package/lib/platform/github-provider.ts +1132 -0
  192. package/lib/platform/in-label-sync.ts +208 -0
  193. package/lib/platform/issue-comments.ts +255 -80
  194. package/lib/platform/issues.ts +344 -174
  195. package/lib/platform/metadata-labels.ts +5 -2
  196. package/lib/platform/none-provider.ts +35 -0
  197. package/lib/platform/pr-change-report.ts +639 -0
  198. package/lib/platform/pr-checks.ts +126 -106
  199. package/lib/platform/pr-review.ts +88 -85
  200. package/lib/platform/pr-summary.ts +581 -53
  201. package/lib/platform/provider-bridge.ts +82 -0
  202. package/lib/platform/provider-contract.ts +611 -0
  203. package/lib/platform/provider-loader.ts +307 -0
  204. package/lib/platform/provider-validation.ts +611 -0
  205. package/lib/platform/pull-request-metadata.ts +10 -7
  206. package/lib/platform/pull-requests.ts +781 -550
  207. package/lib/platform/release-notes.ts +76 -59
  208. package/lib/platform/releases.ts +77 -43
  209. package/lib/platform/repository-metadata.ts +453 -0
  210. package/lib/platform/resource-identity.ts +121 -0
  211. package/lib/platform/security-alerts.ts +191 -0
  212. package/lib/platform/task-identities.ts +40 -0
  213. package/lib/platform/types.ts +4 -2
  214. package/lib/platform/verification-required.ts +11 -13
  215. package/lib/platform/verification-sync.ts +128 -304
  216. package/lib/pr-review/evidence-grading.ts +25 -8
  217. package/lib/process-data/index.ts +7 -0
  218. package/lib/run/index.ts +62 -22
  219. package/lib/sandbox/commands/control-status.ts +26 -0
  220. package/lib/sandbox/commands/create.ts +46 -6
  221. package/lib/sandbox/commands/ls.ts +7 -0
  222. package/lib/sandbox/commands/rm.ts +1000 -87
  223. package/lib/sandbox/commands/show.ts +16 -0
  224. package/lib/sandbox/control/client.ts +203 -19
  225. package/lib/sandbox/control/completed-reentry.ts +98 -0
  226. package/lib/sandbox/control/container-identity.ts +27 -43
  227. package/lib/sandbox/control/executor.ts +180 -15
  228. package/lib/sandbox/control/lifecycle.ts +629 -17
  229. package/lib/sandbox/control/native-file-lock.ts +209 -0
  230. package/lib/sandbox/control/protocol.ts +118 -2
  231. package/lib/sandbox/control/server.ts +724 -34
  232. package/lib/sandbox/control/state.ts +257 -4
  233. package/lib/sandbox/control/task-view.ts +240 -0
  234. package/lib/sandbox/engines/authority.ts +365 -0
  235. package/lib/sandbox/engines/docker-exact-discovery.ts +132 -0
  236. package/lib/sandbox/index.ts +7 -0
  237. package/lib/sandbox/recovery.ts +21 -1
  238. package/lib/sandbox/workspace-view.ts +9 -3
  239. package/lib/sandbox/worktree-safety.ts +4 -1
  240. package/lib/server/index.ts +10 -0
  241. package/lib/server/protocol.ts +36 -1
  242. package/lib/task/activity-log.ts +8 -0
  243. package/lib/task/artifact-lifecycle.ts +70 -22
  244. package/lib/task/artifact-operations.ts +626 -0
  245. package/lib/task/artifact-repair-intent.ts +71 -0
  246. package/lib/task/artifact-schema.ts +192 -0
  247. package/lib/task/capabilities.ts +331 -0
  248. package/lib/task/commands/status.ts +38 -0
  249. package/lib/task/commit-operation.ts +12 -1
  250. package/lib/task/control-authority.ts +22 -9
  251. package/lib/task/create-service.ts +139 -14
  252. package/lib/task/create.ts +27 -0
  253. package/lib/task/current-contract.ts +6 -1
  254. package/lib/task/decision-details.ts +6 -2
  255. package/lib/task/events.ts +392 -16
  256. package/lib/task/finalization.ts +50 -14
  257. package/lib/task/human-override.ts +70 -46
  258. package/lib/task/index.ts +16 -3
  259. package/lib/task/invalidation-command.ts +86 -0
  260. package/lib/task/invalidation.ts +332 -0
  261. package/lib/task/ledger-intents.ts +35 -1
  262. package/lib/task/local-artifact-finalization.ts +432 -0
  263. package/lib/task/orchestration.ts +223 -133
  264. package/lib/task/pr-delivery-fact.ts +131 -148
  265. package/lib/task/qualification-audit.ts +599 -0
  266. package/lib/task/qualification-confirmation.ts +117 -0
  267. package/lib/task/qualification-intents.ts +150 -0
  268. package/lib/task/review-artifacts.ts +21 -22
  269. package/lib/task/review-finalization.ts +133 -4
  270. package/lib/task/review-fingerprint.ts +23 -2
  271. package/lib/task/rework-intent.ts +165 -0
  272. package/lib/task/sections.ts +6 -4
  273. package/lib/task/skill-scope.ts +24 -0
  274. package/lib/task/task-execution-lock.ts +23 -14
  275. package/lib/task/verification-config.ts +12 -0
  276. package/lib/task/verification-engine.ts +103 -17
  277. package/lib/task/verification.ts +4 -4
  278. package/lib/task/workflow-warning-intents.ts +1 -1
  279. package/lib/task/write.ts +19 -0
  280. package/lib/update.ts +1 -1
  281. package/lib/version.ts +15 -1
  282. package/package.json +12 -1
  283. package/templates/.agents/rules/README.en.md +3 -1
  284. package/templates/.agents/rules/README.zh-CN.md +3 -1
  285. package/templates/.agents/rules/decision-qualification.en.md +22 -0
  286. package/templates/.agents/rules/decision-qualification.zh-CN.md +22 -0
  287. package/templates/.agents/rules/evidence-reporting.en.md +28 -0
  288. package/templates/.agents/rules/evidence-reporting.zh-CN.md +28 -0
  289. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  290. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  291. package/templates/.agents/rules/issue-sync.en.md +2 -0
  292. package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
  293. package/templates/.agents/rules/label-milestone-setup.en.md +7 -7
  294. package/templates/.agents/rules/label-milestone-setup.zh-CN.md +7 -7
  295. package/templates/.agents/rules/local-artifact-repair.en.md +13 -2
  296. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +13 -2
  297. package/templates/.agents/rules/pr-sync.en.md +10 -4
  298. package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
  299. package/templates/.agents/rules/security-alerts.en.md +8 -8
  300. package/templates/.agents/rules/security-alerts.zh-CN.md +8 -8
  301. package/templates/.agents/rules/task-short-id.en.md +1 -4
  302. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  303. package/templates/.agents/skills/analyze-task/SKILL.en.md +28 -5
  304. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +29 -5
  305. package/templates/.agents/skills/analyze-task/config/verify.en.json +1 -12
  306. package/templates/.agents/skills/analyze-task/config/verify.zh-CN.json +1 -12
  307. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  308. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  309. package/templates/.agents/skills/close-codescan/SKILL.en.md +2 -2
  310. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +2 -2
  311. package/templates/.agents/skills/close-dependabot/SKILL.en.md +2 -2
  312. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +2 -2
  313. package/templates/.agents/skills/code-task/SKILL.en.md +41 -9
  314. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +43 -11
  315. package/templates/.agents/skills/code-task/config/verify.en.json +6 -14
  316. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +6 -14
  317. package/templates/.agents/skills/code-task/reference/code-rules.en.md +5 -4
  318. package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +5 -4
  319. package/templates/.agents/skills/code-task/reference/dual-mode.en.md +1 -1
  320. package/templates/.agents/skills/code-task/reference/dual-mode.zh-CN.md +1 -1
  321. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +3 -1
  322. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +3 -1
  323. package/templates/.agents/skills/code-task/reference/report-template.en.md +42 -15
  324. package/templates/.agents/skills/code-task/reference/report-template.zh-CN.md +39 -12
  325. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  326. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  327. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
  328. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
  329. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +10 -4
  330. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +10 -4
  331. package/templates/.agents/skills/complete-manual-validation/reference/report-template.en.md +2 -0
  332. package/templates/.agents/skills/complete-manual-validation/reference/report-template.zh-CN.md +2 -0
  333. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
  334. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
  335. package/templates/.agents/skills/complete-task/SKILL.en.md +26 -21
  336. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +25 -21
  337. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
  338. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
  339. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  340. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  341. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  342. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  343. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  344. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  345. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  346. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  347. package/templates/.agents/skills/create-task/SKILL.en.md +8 -0
  348. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +7 -0
  349. package/templates/.agents/skills/import-codescan/SKILL.en.md +1 -1
  350. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +1 -1
  351. package/templates/.agents/skills/import-dependabot/SKILL.en.md +1 -1
  352. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +1 -1
  353. package/templates/.agents/skills/init-labels/SKILL.en.md +8 -8
  354. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +8 -8
  355. package/templates/.agents/skills/init-milestones/SKILL.en.md +9 -11
  356. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +9 -11
  357. package/templates/.agents/skills/plan-task/SKILL.en.md +27 -4
  358. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +26 -4
  359. package/templates/.agents/skills/plan-task/config/verify.en.json +4 -14
  360. package/templates/.agents/skills/plan-task/config/verify.zh-CN.json +4 -14
  361. package/templates/.agents/skills/review-analysis/SKILL.en.md +17 -4
  362. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +17 -4
  363. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -18
  364. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -18
  365. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +50 -23
  366. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +45 -18
  367. package/templates/.agents/skills/review-code/SKILL.en.md +18 -5
  368. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +18 -5
  369. package/templates/.agents/skills/review-code/config/verify.en.json +1 -23
  370. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -23
  371. package/templates/.agents/skills/review-code/reference/report-template.en.md +49 -22
  372. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +45 -18
  373. package/templates/.agents/skills/review-plan/SKILL.en.md +17 -4
  374. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +17 -4
  375. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -18
  376. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -18
  377. package/templates/.agents/skills/review-plan/reference/report-template.en.md +49 -22
  378. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +45 -18
  379. package/templates/.agents/skills/review-pr/SKILL.en.md +5 -1
  380. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +5 -1
  381. package/templates/.agents/skills/review-pr/reference/report-template.en.md +4 -3
  382. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +4 -3
  383. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +9 -3
  384. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +9 -3
  385. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +3 -1
  386. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +3 -1
  387. package/templates/.agents/skills/test/SKILL.en.md +13 -2
  388. package/templates/.agents/skills/test/SKILL.zh-CN.md +13 -2
  389. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +14 -0
  390. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  391. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  392. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  393. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  394. package/templates/.agents/templates/task.en.md +24 -1
  395. package/templates/.agents/templates/task.zh-CN.md +24 -1
  396. package/templates/.github/workflows/pr-label.yml +7 -26
  397. package/templates/.agents/scripts/security-alerts.github.sh +0 -151
  398. package/templates/.agents/scripts/security-alerts.sh +0 -31
  399. package/templates/.agents/skills/init-labels/scripts/init-labels.github.sh +0 -146
  400. package/templates/.agents/skills/init-labels/scripts/init-labels.sh +0 -32
  401. package/templates/.agents/skills/init-milestones/scripts/init-milestones.github.sh +0 -294
  402. package/templates/.agents/skills/init-milestones/scripts/init-milestones.sh +0 -6
@@ -0,0 +1,577 @@
1
+ import { parseResourceIdentity, serializeResourceIdentity } from './resource-identity.js';
2
+ function validationError(providerType, phase, message, code = 'PLATFORM_PROVIDER_RESULT_INVALID') {
3
+ return {
4
+ code,
5
+ message,
6
+ retryable: false,
7
+ providerType,
8
+ phase
9
+ };
10
+ }
11
+ function record(value, label) {
12
+ if (!value || typeof value !== 'object' || Array.isArray(value))
13
+ throw new Error(`${label} must be an object`);
14
+ return value;
15
+ }
16
+ function exactKeys(value, keys, label) {
17
+ const allowed = new Set(keys);
18
+ if (Object.keys(value).some((key) => !allowed.has(key)))
19
+ throw new Error(`${label} contains unknown fields`);
20
+ }
21
+ function jsonValue(value, label) {
22
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
23
+ return value;
24
+ if (typeof value === 'number' && Number.isFinite(value))
25
+ return value;
26
+ if (Array.isArray(value))
27
+ return value.map((entry, index) => jsonValue(entry, `${label}[${index}]`));
28
+ const item = record(value, label);
29
+ return Object.fromEntries(Object.entries(item).map(([key, entry]) => [key, jsonValue(entry, `${label}.${key}`)]));
30
+ }
31
+ function jsonObject(value, label) {
32
+ const item = record(value, label);
33
+ return Object.fromEntries(Object.entries(item).map(([key, entry]) => [key, jsonValue(entry, `${label}.${key}`)]));
34
+ }
35
+ function scalarFields(value, label) {
36
+ const item = record(value, label);
37
+ return Object.fromEntries(Object.entries(item).map(([key, entry]) => {
38
+ if (entry === null || typeof entry === 'string')
39
+ return [key, entry];
40
+ if (typeof entry === 'number' && Number.isFinite(entry))
41
+ return [key, entry];
42
+ throw new Error(`${label}.${key} must be a string, number, or null`);
43
+ }));
44
+ }
45
+ function booleanValue(value, label) {
46
+ if (typeof value !== 'boolean')
47
+ throw new Error(`${label} must be boolean`);
48
+ return value;
49
+ }
50
+ function fieldKind(value, label) {
51
+ if (value !== 'single-select' && value !== 'date' && value !== 'text' && value !== 'number')
52
+ throw new Error(`${label} is invalid`);
53
+ return value;
54
+ }
55
+ function mergeability(value, label) {
56
+ const item = record(value, label);
57
+ exactKeys(item, ['state', 'detail'], label);
58
+ if (item.state !== 'mergeable' && item.state !== 'conflicting' && item.state !== 'unknown')
59
+ throw new Error(`${label}.state is invalid`);
60
+ return { state: item.state, detail: item.detail === null ? null : stringValue(item.detail, `${label}.detail`) };
61
+ }
62
+ function stringValue(value, label, allowEmpty = false) {
63
+ if (typeof value !== 'string' || (!allowEmpty && value.length === 0))
64
+ throw new Error(`${label} must be a string`);
65
+ return value;
66
+ }
67
+ function nullableString(value, label) {
68
+ return value === null ? null : stringValue(value, label);
69
+ }
70
+ function timestamp(value, label) {
71
+ const result = stringValue(value, label);
72
+ if (Number.isNaN(Date.parse(result)))
73
+ throw new Error(`${label} must be a timestamp`);
74
+ return result;
75
+ }
76
+ function arrayValue(value, label) {
77
+ if (!Array.isArray(value))
78
+ throw new Error(`${label} must be an array`);
79
+ return value;
80
+ }
81
+ function stableUnique(values, key, label) {
82
+ const seen = new Set();
83
+ for (const value of values) {
84
+ const identityKey = key(value);
85
+ if (seen.has(identityKey))
86
+ throw new Error(`${label} contains duplicate identities`);
87
+ seen.add(identityKey);
88
+ }
89
+ return [...values].sort((left, right) => key(left).localeCompare(key(right)));
90
+ }
91
+ function declaredIdentityKind(declaration, resourceKind) {
92
+ const kind = declaration?.[resourceKind];
93
+ return kind === 'id' || kind === 'number' || kind === 'key' ? kind : undefined;
94
+ }
95
+ function identity(value, label, expectedKind) {
96
+ const parsed = parseResourceIdentity(value, label);
97
+ if (expectedKind !== undefined && parsed.kind !== expectedKind)
98
+ throw new Error(`${label} kind does not match provider declaration`);
99
+ return parsed;
100
+ }
101
+ function author(value, label) {
102
+ if (value === null)
103
+ return null;
104
+ const item = record(value, label);
105
+ exactKeys(item, ['id', 'name'], label);
106
+ const result = {};
107
+ if (item.id !== undefined)
108
+ result.id = stringValue(item.id, `${label}.id`);
109
+ if (item.name !== undefined)
110
+ result.name = stringValue(item.name, `${label}.name`);
111
+ if (!result.id && !result.name)
112
+ throw new Error(`${label} must identify an author`);
113
+ return result;
114
+ }
115
+ function validateContext(value, expectedProviderType) {
116
+ const item = record(value, 'context');
117
+ exactKeys(item, ['type', 'scope', 'currentUser', 'capabilities', 'authenticated', 'metadata'], 'context');
118
+ const scope = record(item.scope, 'context.scope');
119
+ exactKeys(scope, ['id', 'label'], 'context.scope');
120
+ const capabilities = record(item.capabilities, 'context.capabilities');
121
+ exactKeys(capabilities, ['authenticated', 'comment', 'triage', 'push', 'admin'], 'context.capabilities');
122
+ const capabilityNames = ['authenticated', 'comment', 'triage', 'push', 'admin'];
123
+ if (capabilityNames.some((name) => typeof capabilities[name] !== 'boolean'))
124
+ throw new Error('context.capabilities must contain booleans');
125
+ if (typeof item.authenticated !== 'boolean')
126
+ throw new Error('context.authenticated must be boolean');
127
+ const type = stringValue(item.type, 'context.type');
128
+ if (expectedProviderType !== undefined && type !== expectedProviderType)
129
+ throw new Error('context.type does not match selected provider');
130
+ return {
131
+ type,
132
+ scope: { id: stringValue(scope.id, 'context.scope.id'), ...(scope.label === undefined ? {} : { label: stringValue(scope.label, 'context.scope.label') }) },
133
+ currentUser: author(item.currentUser, 'context.currentUser'),
134
+ capabilities: {
135
+ authenticated: capabilities.authenticated,
136
+ comment: capabilities.comment,
137
+ triage: capabilities.triage,
138
+ push: capabilities.push,
139
+ admin: capabilities.admin
140
+ },
141
+ authenticated: item.authenticated,
142
+ ...(item.metadata === undefined ? {} : { metadata: jsonObject(item.metadata, 'context.metadata') })
143
+ };
144
+ }
145
+ function validateIssue(value, expectedKind, requireIdentity = false) {
146
+ const item = record(value, 'issue');
147
+ exactKeys(item, ['id', 'identity', 'number', 'title', 'body', 'state', 'labels', 'assignees', 'milestone', 'fields', 'issueType', 'author', 'displayUrl'], 'issue');
148
+ const result = {
149
+ id: item.id === undefined ? '' : stringValue(item.id, 'issue.id'),
150
+ ...(item.identity === undefined ? {} : { identity: identity(item.identity, 'issue.identity', expectedKind) }),
151
+ ...(item.number === undefined ? {} : { number: Number.isSafeInteger(item.number) && item.number > 0 ? item.number : (() => { throw new Error('issue.number is invalid'); })() }),
152
+ title: stringValue(item.title, 'issue.title', true),
153
+ body: stringValue(item.body, 'issue.body', true),
154
+ state: item.state === 'closed' ? 'closed' : item.state === 'open' ? 'open' : (() => { throw new Error('issue.state is invalid'); })(),
155
+ labels: arrayValue(item.labels, 'issue.labels').map((entry) => stringValue(entry, 'issue.labels[]')),
156
+ assignees: arrayValue(item.assignees, 'issue.assignees').map((entry) => stringValue(entry, 'issue.assignees[]')),
157
+ milestone: nullableString(item.milestone, 'issue.milestone'),
158
+ fields: scalarFields(item.fields, 'issue.fields'),
159
+ ...(item.issueType === undefined ? {} : { issueType: item.issueType === null ? null : issueType(item.issueType, 'issue.issueType') }),
160
+ ...(item.author === undefined ? {} : { author: author(item.author, 'issue.author') }),
161
+ ...(item.displayUrl === undefined ? {} : { displayUrl: stringValue(item.displayUrl, 'issue.displayUrl') })
162
+ };
163
+ if (!result.id && !result.identity)
164
+ throw new Error('issue must expose id or identity');
165
+ if (requireIdentity && !result.identity)
166
+ throw new Error('issue identity is required');
167
+ if (result.number !== undefined && (!Number.isSafeInteger(result.number) || result.number <= 0))
168
+ throw new Error('issue.number is invalid');
169
+ return result;
170
+ }
171
+ function issueType(value, label) {
172
+ const item = record(value, label);
173
+ exactKeys(item, ['identity', 'name', 'fields'], label);
174
+ const fields = arrayValue(item.fields, `${label}.fields`).map((rawField) => {
175
+ const field = record(rawField, `${label}.field`);
176
+ exactKeys(field, ['identity', 'name', 'kind', 'options'], `${label}.field`);
177
+ return {
178
+ identity: identity(field.identity, `${label}.field.identity`),
179
+ name: stringValue(field.name, `${label}.field.name`),
180
+ kind: fieldKind(field.kind, `${label}.field.kind`),
181
+ options: stableUnique(arrayValue(field.options, `${label}.field.options`).map((rawOption) => {
182
+ const option = record(rawOption, `${label}.field.option`);
183
+ exactKeys(option, ['identity', 'name'], `${label}.field.option`);
184
+ return { identity: identity(option.identity, `${label}.field.option.identity`), name: stringValue(option.name, `${label}.field.option.name`) };
185
+ }), (entry) => serializeResourceIdentity(entry.identity), `${label}.field.options`)
186
+ };
187
+ });
188
+ return { identity: identity(item.identity, `${label}.identity`), name: stringValue(item.name, `${label}.name`), fields: stableUnique(fields, (entry) => serializeResourceIdentity(entry.identity), `${label}.fields`) };
189
+ }
190
+ function validateComment(value) {
191
+ const item = record(value, 'comment');
192
+ exactKeys(item, ['id', 'author', 'body', 'createdAt', 'updatedAt'], 'comment');
193
+ return {
194
+ id: stringValue(item.id, 'comment.id'),
195
+ author: author(item.author, 'comment.author'),
196
+ body: stringValue(item.body, 'comment.body', true),
197
+ createdAt: utcTimestamp(item.createdAt, 'comment.createdAt'),
198
+ updatedAt: utcTimestamp(item.updatedAt, 'comment.updatedAt')
199
+ };
200
+ }
201
+ function validateChangeRequest(value, expectedKind, requireIdentity = false) {
202
+ const item = record(value, 'changeRequest');
203
+ exactKeys(item, ['id', 'identity', 'number', 'state', 'title', 'body', 'baseSha', 'headSha', 'author', 'mergedAt', 'displayUrl', 'draft', 'labels', 'assignees', 'milestone', 'mergeCommitSha', 'mergeability', 'head', 'base'], 'changeRequest');
204
+ const result = {
205
+ id: item.id === undefined ? '' : stringValue(item.id, 'changeRequest.id'),
206
+ ...(item.identity === undefined ? {} : { identity: identity(item.identity, 'changeRequest.identity', expectedKind) }),
207
+ ...(item.number === undefined ? {} : { number: Number.isSafeInteger(item.number) && item.number > 0 ? item.number : (() => { throw new Error('changeRequest.number is invalid'); })() }),
208
+ state: stringValue(item.state, 'changeRequest.state'),
209
+ title: stringValue(item.title, 'changeRequest.title', true),
210
+ body: stringValue(item.body, 'changeRequest.body', true),
211
+ ...(item.baseSha === undefined ? {} : { baseSha: stringValue(item.baseSha, 'changeRequest.baseSha') }),
212
+ ...(item.headSha === undefined ? {} : { headSha: stringValue(item.headSha, 'changeRequest.headSha') }),
213
+ ...(item.author === undefined ? {} : { author: author(item.author, 'changeRequest.author') }),
214
+ ...(item.mergedAt === undefined ? {} : { mergedAt: item.mergedAt === null ? null : utcTimestamp(item.mergedAt, 'changeRequest.mergedAt') }),
215
+ ...(item.displayUrl === undefined ? {} : { displayUrl: stringValue(item.displayUrl, 'changeRequest.displayUrl') }),
216
+ ...(item.draft === undefined ? {} : { draft: booleanValue(item.draft, 'changeRequest.draft') }),
217
+ ...(item.labels === undefined ? {} : { labels: arrayValue(item.labels, 'changeRequest.labels').map((entry) => stringValue(entry, 'changeRequest.labels[]')) }),
218
+ ...(item.assignees === undefined ? {} : { assignees: arrayValue(item.assignees, 'changeRequest.assignees').map((entry) => stringValue(entry, 'changeRequest.assignees[]')) }),
219
+ ...(item.milestone === undefined ? {} : { milestone: nullableString(item.milestone, 'changeRequest.milestone') }),
220
+ ...(item.mergeCommitSha === undefined ? {} : { mergeCommitSha: item.mergeCommitSha === null ? null : stringValue(item.mergeCommitSha, 'changeRequest.mergeCommitSha') }),
221
+ ...(item.mergeability === undefined ? {} : { mergeability: mergeability(item.mergeability, 'changeRequest.mergeability') }),
222
+ ...(item.head === undefined ? {} : { head: validateRef(item.head, 'changeRequest.head') }),
223
+ ...(item.base === undefined ? {} : { base: validateRef(item.base, 'changeRequest.base') })
224
+ };
225
+ if (!result.id && !result.identity)
226
+ throw new Error('changeRequest must expose id or identity');
227
+ if (requireIdentity && !result.identity)
228
+ throw new Error('changeRequest identity is required');
229
+ if (result.number !== undefined && (!Number.isSafeInteger(result.number) || result.number <= 0))
230
+ throw new Error('changeRequest.number is invalid');
231
+ if (result.mergedAt && Number.isNaN(Date.parse(result.mergedAt)))
232
+ throw new Error('changeRequest.mergedAt is invalid');
233
+ return result;
234
+ }
235
+ function validateRef(value, label) {
236
+ const item = record(value, label);
237
+ exactKeys(item, ['repository', 'ref', 'sha'], label);
238
+ return {
239
+ repository: stringValue(item.repository, `${label}.repository`),
240
+ ref: stringValue(item.ref, `${label}.ref`),
241
+ sha: stringValue(item.sha, `${label}.sha`)
242
+ };
243
+ }
244
+ function validateReceipt(value) {
245
+ const item = record(value, 'receipt');
246
+ exactKeys(item, ['remoteId', 'changed', 'operationId'], 'receipt');
247
+ return {
248
+ remoteId: stringValue(item.remoteId, 'receipt.remoteId'),
249
+ changed: typeof item.changed === 'boolean' ? item.changed : (() => { throw new Error('receipt.changed is invalid'); })(),
250
+ ...(item.operationId === undefined ? {} : { operationId: stringValue(item.operationId, 'receipt.operationId') })
251
+ };
252
+ }
253
+ function positiveInteger(value, label) {
254
+ if (!Number.isSafeInteger(value) || value <= 0)
255
+ throw new Error(`${label} must be a positive integer`);
256
+ return value;
257
+ }
258
+ function validateSecurityAlert(value) {
259
+ const item = record(value, 'security alert');
260
+ exactKeys(item, ['kind', 'number', 'state', 'data'], 'security alert');
261
+ if (item.kind !== 'dependabot' && item.kind !== 'code-scanning')
262
+ throw new Error('security alert.kind is invalid');
263
+ return {
264
+ kind: item.kind,
265
+ number: positiveInteger(item.number, 'security alert.number'),
266
+ state: stringValue(item.state, 'security alert.state'),
267
+ data: jsonValue(item.data, 'security alert.data')
268
+ };
269
+ }
270
+ function validateLabelDefinition(value, label) {
271
+ const item = record(value, label);
272
+ exactKeys(item, ['name', 'color', 'description'], label);
273
+ return {
274
+ name: stringValue(item.name, `${label}.name`),
275
+ color: stringValue(item.color, `${label}.color`),
276
+ description: stringValue(item.description, `${label}.description`, true)
277
+ };
278
+ }
279
+ function validateLabelReconciliation(value) {
280
+ const item = record(value, 'label reconciliation');
281
+ exactKeys(item, ['changed', 'created', 'updated', 'removed', 'skipped'], 'label reconciliation');
282
+ const names = (field) => arrayValue(item[field], `label reconciliation.${field}`).map((entry) => stringValue(entry, `${field}[]`));
283
+ return {
284
+ changed: booleanValue(item.changed, 'label reconciliation.changed'),
285
+ created: names('created'),
286
+ updated: names('updated'),
287
+ removed: names('removed'),
288
+ skipped: names('skipped')
289
+ };
290
+ }
291
+ function validateMilestoneDefinition(value, label) {
292
+ const item = record(value, label);
293
+ exactKeys(item, ['title', 'description', 'state'], label);
294
+ if (item.state !== 'open' && item.state !== 'closed')
295
+ throw new Error(`${label}.state is invalid`);
296
+ return {
297
+ title: stringValue(item.title, `${label}.title`),
298
+ description: stringValue(item.description, `${label}.description`, true),
299
+ state: item.state
300
+ };
301
+ }
302
+ function validateMilestoneInitialization(value) {
303
+ const item = record(value, 'milestone initialization');
304
+ exactKeys(item, ['changed', 'created', 'skipped'], 'milestone initialization');
305
+ return {
306
+ changed: booleanValue(item.changed, 'milestone initialization.changed'),
307
+ created: arrayValue(item.created, 'milestone initialization.created').map((entry) => stringValue(entry, 'created[]')),
308
+ skipped: arrayValue(item.skipped, 'milestone initialization.skipped').map((entry) => stringValue(entry, 'skipped[]'))
309
+ };
310
+ }
311
+ function validateMetadata(value) {
312
+ const item = record(value, 'repository metadata');
313
+ exactKeys(item, ['repository', 'labels', 'milestones', 'issueTypes', 'fields'], 'repository metadata');
314
+ const repository = record(item.repository, 'metadata.repository');
315
+ exactKeys(repository, ['identity', 'name', 'url'], 'metadata.repository');
316
+ const mapFields = (raw, label) => arrayValue(raw, label).map((entry) => {
317
+ const field = record(entry, label);
318
+ exactKeys(field, ['identity', 'name', 'kind', 'options'], label);
319
+ return {
320
+ identity: identity(field.identity, `${label}.identity`),
321
+ name: stringValue(field.name, `${label}.name`),
322
+ kind: fieldKind(field.kind, `${label}.kind`),
323
+ options: stableUnique(arrayValue(field.options, `${label}.options`).map((rawOption) => {
324
+ const option = record(rawOption, `${label}.option`);
325
+ exactKeys(option, ['identity', 'name'], `${label}.option`);
326
+ return { identity: identity(option.identity, `${label}.option.identity`), name: stringValue(option.name, `${label}.option.name`) };
327
+ }), (entry) => serializeResourceIdentity(entry.identity), `${label}.options`)
328
+ };
329
+ });
330
+ const fields = stableUnique(mapFields(item.fields, 'metadata.fields'), (entry) => serializeResourceIdentity(entry.identity), 'metadata.fields');
331
+ const issueTypes = stableUnique(arrayValue(item.issueTypes, 'metadata.issueTypes').map((raw, index) => {
332
+ const issueType = record(raw, `metadata.issueTypes[${index}]`);
333
+ exactKeys(issueType, ['identity', 'name', 'fields'], `metadata.issueTypes[${index}]`);
334
+ return { identity: identity(issueType.identity, `metadata.issueTypes[${index}].identity`), name: stringValue(issueType.name, `metadata.issueTypes[${index}].name`), fields: stableUnique(mapFields(issueType.fields, `metadata.issueTypes[${index}].fields`), (entry) => serializeResourceIdentity(entry.identity), `metadata.issueTypes[${index}].fields`) };
335
+ }), (entry) => serializeResourceIdentity(entry.identity), 'metadata.issueTypes');
336
+ return {
337
+ repository: { identity: identity(repository.identity, 'metadata.repository.identity'), name: stringValue(repository.name, 'metadata.repository.name'), url: repository.url === null ? null : stringValue(repository.url, 'metadata.repository.url') },
338
+ labels: stableUnique(arrayValue(item.labels, 'metadata.labels').map((raw) => {
339
+ const label = record(raw, 'metadata.label');
340
+ exactKeys(label, ['identity', 'name'], 'metadata.label');
341
+ return { identity: identity(label.identity, 'metadata.label.identity'), name: stringValue(label.name, 'metadata.label.name') };
342
+ }), (entry) => serializeResourceIdentity(entry.identity), 'metadata.labels'),
343
+ milestones: stableUnique(arrayValue(item.milestones, 'metadata.milestones').map((raw) => {
344
+ const milestone = record(raw, 'metadata.milestone');
345
+ exactKeys(milestone, ['identity', 'title', 'state'], 'metadata.milestone');
346
+ if (milestone.state !== 'open' && milestone.state !== 'closed')
347
+ throw new Error('metadata.milestone.state is invalid');
348
+ return { identity: identity(milestone.identity, 'metadata.milestone.identity'), title: stringValue(milestone.title, 'metadata.milestone.title'), state: milestone.state };
349
+ }), (entry) => serializeResourceIdentity(entry.identity), 'metadata.milestones'),
350
+ issueTypes,
351
+ fields
352
+ };
353
+ }
354
+ function validateReleaseNotes(value, declaration) {
355
+ const item = record(value, 'release notes');
356
+ exactKeys(item, ['history', 'mergedPullRequests', 'closingIssues', 'actors'], 'release notes');
357
+ return {
358
+ history: stableUnique(arrayValue(item.history, 'release notes.history').map((raw) => {
359
+ const entry = record(raw, 'release notes.history[]');
360
+ exactKeys(entry, ['sha', 'message', 'authoredAt', 'author'], 'release notes.history[]');
361
+ return { sha: stringValue(entry.sha, 'history.sha'), message: stringValue(entry.message, 'history.message', true), authoredAt: utcTimestamp(entry.authoredAt, 'history.authoredAt'), author: author(entry.author, 'history.author') };
362
+ }), (entry) => entry.sha, 'release notes.history'),
363
+ mergedPullRequests: stableUnique(arrayValue(item.mergedPullRequests, 'release notes.mergedPullRequests').map((entry) => validateChangeRequest(entry, declaredIdentityKind(declaration, 'pull-request'), true)), (entry) => serializeResourceIdentity(entry.identity), 'release notes.mergedPullRequests'),
364
+ closingIssues: stableUnique(arrayValue(item.closingIssues, 'release notes.closingIssues').map((entry) => validateIssue(entry, declaredIdentityKind(declaration, 'issue'), true)), (entry) => serializeResourceIdentity(entry.identity), 'release notes.closingIssues'),
365
+ actors: stableUnique(arrayValue(item.actors, 'release notes.actors').map((entry) => {
366
+ const actor = author(entry, 'release notes.actor');
367
+ if (!actor)
368
+ throw new Error('release notes.actor must identify an actor');
369
+ return actor;
370
+ }), (entry) => entry.id || entry.name || '', 'release notes.actors')
371
+ };
372
+ }
373
+ function utcTimestamp(value, label) {
374
+ const result = timestamp(value, label);
375
+ if (!result.endsWith('Z'))
376
+ throw new Error(`${label} must be UTC`);
377
+ return new Date(result).toISOString();
378
+ }
379
+ const PROVIDER_ERROR_CATALOG = {
380
+ AUTH_REQUIRED: { message: 'Platform authentication is required', retryable: false },
381
+ PERMISSION_DENIED: { message: 'Platform permission was denied', retryable: false },
382
+ PLATFORM_DEPENDENCY_MISSING: { message: 'A platform dependency is unavailable', retryable: false },
383
+ PLATFORM_OUTPUT_TOO_LARGE: { message: 'Platform output exceeded the configured limit', retryable: false },
384
+ PLATFORM_CAPABILITY_UNSUPPORTED: { message: 'Platform capability is unsupported', retryable: false },
385
+ PLATFORM_UNSUPPORTED: { message: 'The configured platform is unsupported', retryable: false },
386
+ REMOTE_MISSING: { message: 'The platform remote is not configured', retryable: false },
387
+ REMOTE_INVALID: { message: 'The platform remote is invalid', retryable: false },
388
+ UPSTREAM_UNRESOLVED: { message: 'The platform upstream repository could not be resolved', retryable: false },
389
+ RESOURCE_NOT_FOUND: { message: 'The platform resource was not found', retryable: false },
390
+ PR_NOT_FOUND: { message: 'The pull request was not found', retryable: false },
391
+ ISSUE_NOT_FOUND: { message: 'The issue was not found', retryable: false },
392
+ REMOTE_BUSY: { message: 'Platform provider is temporarily busy', retryable: true },
393
+ NETWORK_TRANSIENT: { message: 'The platform request failed temporarily', retryable: true },
394
+ NETWORK_RETRY: { message: 'The platform request failed temporarily', retryable: true },
395
+ NETWORK_RETRY_EXHAUSTED: { message: 'The platform request retries were exhausted', retryable: true },
396
+ NETWORK_ERROR: { message: 'The platform request failed temporarily', retryable: true },
397
+ INVALID_PLATFORM_RESPONSE: { message: 'The platform returned an invalid response', retryable: true },
398
+ PLATFORM_REQUEST_INVALID: { message: 'The platform rejected the request', retryable: false },
399
+ PLATFORM_REQUEST_FAILED: { message: 'The platform request failed', retryable: false },
400
+ GH_CLI_VERSION_INVALID: { message: 'The platform CLI returned an invalid version', retryable: false },
401
+ GH_CLI_VERSION_UNSUPPORTED: { message: 'The installed GitHub CLI version is unsupported', retryable: false },
402
+ PR_HEAD_INVALID: { message: 'The pull request head is invalid', retryable: false },
403
+ PR_REMOTE_BRANCH_MISSING: { message: 'The pull request remote branch is missing', retryable: false },
404
+ PR_REMOTE_BRANCH_UNAVAILABLE: { message: 'The pull request remote branch could not be inspected', retryable: true },
405
+ PR_LOCAL_HEAD_UNAVAILABLE: { message: 'The local pull request head could not be inspected', retryable: false },
406
+ PR_REMOTE_HEAD_MISMATCH: { message: 'The pull request remote head does not match the local head', retryable: false },
407
+ PR_MERGE_EVIDENCE_SOURCE_UNAVAILABLE: { message: 'Pull request merge evidence is unavailable', retryable: false },
408
+ PR_CREATE_RESPONSE_INVALID: { message: 'Pull request creation returned an invalid response', retryable: false },
409
+ PR_NUMBER_INVALID: { message: 'The pull request number is invalid', retryable: false },
410
+ ISSUE_NUMBER_INVALID: { message: 'The issue number is invalid', retryable: false },
411
+ ISSUE_CREATE_RESPONSE_INVALID: { message: 'Issue creation returned an invalid response', retryable: false },
412
+ COMMENT_ID_INVALID: { message: 'The comment identity is invalid', retryable: false },
413
+ SECURITY_KIND_INVALID: { message: 'The security alert kind is invalid', retryable: false },
414
+ SECURITY_NUMBER_INVALID: { message: 'The security alert number is invalid', retryable: false },
415
+ SECURITY_RESPONSE_INVALID: { message: 'The platform returned an invalid security alert', retryable: false },
416
+ LABEL_RESPONSE_INVALID: { message: 'The platform returned an invalid label response', retryable: false },
417
+ MILESTONE_RESPONSE_INVALID: { message: 'The platform returned an invalid milestone response', retryable: false },
418
+ MILESTONE_IDENTITY_INVALID: { message: 'The milestone identity is invalid', retryable: false },
419
+ CHECK_RUN_NOT_FOUND: { message: 'The check run was not found', retryable: false },
420
+ RELEASE_NOTES_AUTHORS_TRUNCATED: { message: 'Release note commit authors exceeded the supported limit', retryable: false },
421
+ RELEASE_NOTES_COLLECTION_FAILED: { message: 'Release notes could not be collected', retryable: false },
422
+ RELEASE_NOTES_PUBLISH_FAILED: { message: 'Release notes could not be published', retryable: false },
423
+ PAGINATION_INVALID: { message: 'Platform pagination is invalid', retryable: false },
424
+ PAGINATION_UNSTABLE: { message: 'Platform pagination is unstable', retryable: true },
425
+ PLATFORM_PROVIDER_OPERATION_FAILED: { message: 'Platform provider operation failed', retryable: false }
426
+ };
427
+ function safeProviderError(providerType, operation, value) {
428
+ const item = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
429
+ const definition = typeof item.code === 'string' ? PROVIDER_ERROR_CATALOG[item.code] : undefined;
430
+ return {
431
+ code: definition ? item.code : 'PLATFORM_PROVIDER_OPERATION_FAILED',
432
+ message: definition?.message || PROVIDER_ERROR_CATALOG.PLATFORM_PROVIDER_OPERATION_FAILED.message,
433
+ retryable: definition?.retryable || false,
434
+ providerType,
435
+ phase: operation
436
+ };
437
+ }
438
+ function validators(providerType, declaration) {
439
+ return {
440
+ 'context.resolve': (value) => validateContext(value, providerType),
441
+ 'issues.listLabels': (value) => arrayValue(value, 'issue labels').map((entry) => stringValue(entry, 'issue labels[]')),
442
+ 'issues.listMilestones': (value) => arrayValue(value, 'issue milestones').map((entry) => stringValue(entry, 'issue milestones[]')),
443
+ 'issues.inspect': (value) => validateIssue(value, declaredIdentityKind(declaration, 'issue'), true),
444
+ 'issues.describeRepository': validateMetadata,
445
+ 'issues.create': validateReceipt,
446
+ 'issues.update': validateReceipt,
447
+ 'comments.list': (value) => arrayValue(value, 'comments').map(validateComment),
448
+ 'comments.write': validateReceipt,
449
+ 'comments.delete': validateReceipt,
450
+ 'changeRequests.verifyHead': (value) => {
451
+ const item = record(value, 'change request head');
452
+ exactKeys(item, ['sha'], 'change request head');
453
+ return { sha: stringValue(item.sha, 'change request head.sha') };
454
+ },
455
+ 'changeRequests.inspect': (value) => validateChangeRequest(value, declaredIdentityKind(declaration, 'pull-request'), true),
456
+ 'changeRequests.listFiles': (value) => arrayValue(value, 'pull request files').map((entry) => stringValue(entry, 'pull request files[]')),
457
+ 'changeRequests.listClosingIssues': (value) => arrayValue(value, 'closing issues').map((entry) => identity(entry, 'closing issues[]', declaredIdentityKind(declaration, 'issue'))),
458
+ 'changeRequests.listClosing': (value) => arrayValue(value, 'changeRequests').map((entry) => validateChangeRequest(entry, declaredIdentityKind(declaration, 'pull-request'), true)),
459
+ 'changeRequests.create': validateReceipt,
460
+ 'changeRequests.update': validateReceipt,
461
+ 'changeRequests.resolveGitEvidence': (value) => {
462
+ const item = record(value, 'git evidence');
463
+ exactKeys(item, ['remoteUrl', 'reviewedHeadRef', 'targetHeadRef'], 'git evidence');
464
+ return { remoteUrl: stringValue(item.remoteUrl, 'git evidence.remoteUrl'), reviewedHeadRef: stringValue(item.reviewedHeadRef, 'git evidence.reviewedHeadRef'), targetHeadRef: stringValue(item.targetHeadRef, 'git evidence.targetHeadRef') };
465
+ },
466
+ 'checks.inspectRequired': (value) => arrayValue(value, 'checks').map((entry) => {
467
+ const item = record(entry, 'check');
468
+ exactKeys(item, ['name', 'status', 'conclusion', 'detailsUrl', 'runId', 'jobId'], 'check');
469
+ return { name: stringValue(item.name, 'check.name'), status: stringValue(item.status, 'check.status'), ...(item.conclusion === undefined ? {} : { conclusion: item.conclusion === null ? null : stringValue(item.conclusion, 'check.conclusion') }), ...(item.detailsUrl === undefined ? {} : { detailsUrl: item.detailsUrl === null ? null : stringValue(item.detailsUrl, 'check.detailsUrl') }), ...(item.runId === undefined ? {} : { runId: stringValue(item.runId, 'check.runId') }), ...(item.jobId === undefined ? {} : { jobId: stringValue(item.jobId, 'check.jobId') }) };
470
+ }),
471
+ 'checks.resolveRun': (value) => {
472
+ const item = record(value, 'check run');
473
+ exactKeys(item, ['name', 'status', 'runId', 'conclusion', 'detailsUrl', 'jobId'], 'check run');
474
+ return { name: stringValue(item.name, 'check run.name', true), status: stringValue(item.status, 'check run.status'), runId: stringValue(item.runId, 'check run.runId'), ...(item.conclusion === undefined ? {} : { conclusion: item.conclusion === null ? null : stringValue(item.conclusion, 'check run.conclusion') }), ...(item.detailsUrl === undefined ? {} : { detailsUrl: item.detailsUrl === null ? null : stringValue(item.detailsUrl, 'check run.detailsUrl') }), ...(item.jobId === undefined ? {} : { jobId: stringValue(item.jobId, 'check run.jobId') }) };
475
+ },
476
+ 'checks.fetchLogs': (value) => {
477
+ const item = record(value, 'check log');
478
+ exactKeys(item, ['runId', 'jobId', 'text'], 'check log');
479
+ return { runId: stringValue(item.runId, 'check log.runId'), ...(item.jobId === undefined ? {} : { jobId: stringValue(item.jobId, 'check log.jobId') }), text: stringValue(item.text, 'check log.text', true) };
480
+ },
481
+ 'reviews.list': (value) => arrayValue(value, 'reviews').map((entry) => {
482
+ const item = record(entry, 'review');
483
+ exactKeys(item, ['id', 'author', 'body', 'state', 'submittedAt', 'commitSha', 'displayUrl'], 'review');
484
+ return { id: stringValue(item.id, 'review.id'), author: author(item.author, 'review.author'), body: stringValue(item.body, 'review.body', true), state: stringValue(item.state, 'review.state'), submittedAt: utcTimestamp(item.submittedAt, 'review.submittedAt'), ...(item.commitSha === undefined ? {} : { commitSha: stringValue(item.commitSha, 'review.commitSha') }), ...(item.displayUrl === undefined ? {} : { displayUrl: stringValue(item.displayUrl, 'review.displayUrl') }) };
485
+ }),
486
+ 'reviews.publish': validateReceipt,
487
+ 'releases.inspect': (value) => {
488
+ const item = record(value, 'release');
489
+ exactKeys(item, ['id', 'tag', 'title', 'body', 'draft', 'prerelease', 'publishedAt', 'milestone', 'displayUrl', 'workflows'], 'release');
490
+ return { id: stringValue(item.id, 'release.id'), tag: stringValue(item.tag, 'release.tag'), title: stringValue(item.title, 'release.title', true), body: stringValue(item.body, 'release.body', true), draft: booleanValue(item.draft, 'release.draft'), prerelease: booleanValue(item.prerelease, 'release.prerelease'), publishedAt: item.publishedAt === null ? null : utcTimestamp(item.publishedAt, 'release.publishedAt'), ...(item.milestone === undefined ? {} : { milestone: nullableString(item.milestone, 'release.milestone') }), ...(item.displayUrl === undefined ? {} : { displayUrl: stringValue(item.displayUrl, 'release.displayUrl') }), ...(item.workflows === undefined ? {} : { workflows: arrayValue(item.workflows, 'release.workflows').map((entry) => jsonObject(entry, 'release.workflow')) }) };
491
+ },
492
+ 'releases.create': validateReceipt,
493
+ 'releases.update': validateReceipt,
494
+ 'releases.reconcileMilestones': (value) => {
495
+ const item = record(value, 'milestone reconciliation');
496
+ exactKeys(item, ['changed', 'created', 'closed'], 'milestone reconciliation');
497
+ return { changed: booleanValue(item.changed, 'milestone reconciliation.changed'), created: arrayValue(item.created, 'created').map((entry) => stringValue(entry, 'created[]')), closed: arrayValue(item.closed, 'closed').map((entry) => stringValue(entry, 'closed[]')) };
498
+ },
499
+ 'releases.publishNotes': validateReceipt,
500
+ 'releases.collectNotes': (value) => validateReleaseNotes(value, declaration),
501
+ 'securityAlerts.inspect': validateSecurityAlert,
502
+ 'securityAlerts.dismiss': validateReceipt,
503
+ 'repositoryMetadata.reconcileLabels': validateLabelReconciliation,
504
+ 'repositoryMetadata.reconcileMilestones': validateMilestoneInitialization,
505
+ 'verification.fetchRemoteFacts': (value) => {
506
+ const item = record(value, 'verification facts');
507
+ exactKeys(item, ['issue', 'comments', 'changeRequest', 'commit', 'fields'], 'verification facts');
508
+ const commit = item.commit === undefined ? undefined : item.commit === null ? null : (() => {
509
+ const value = record(item.commit, 'verification.commit');
510
+ exactKeys(value, ['sha', 'message'], 'verification.commit');
511
+ return { sha: stringValue(value.sha, 'verification.commit.sha'), ...(value.message === undefined ? {} : { message: stringValue(value.message, 'verification.commit.message', true) }) };
512
+ })();
513
+ return { issue: item.issue === undefined ? undefined : item.issue === null ? null : validateIssue(item.issue, declaredIdentityKind(declaration, 'issue'), true), comments: arrayValue(item.comments, 'verification.comments').map(validateComment), changeRequest: item.changeRequest === undefined ? undefined : item.changeRequest === null ? null : validateChangeRequest(item.changeRequest, declaredIdentityKind(declaration, 'pull-request'), true), commit, fields: scalarFields(item.fields, 'verification.fields') };
514
+ }
515
+ };
516
+ }
517
+ async function invokeProviderOperation(providerType, operation, call, validate) {
518
+ try {
519
+ const raw = await call();
520
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
521
+ return { ok: false, error: validationError(providerType, operation, 'Provider operation returned an invalid result envelope') };
522
+ const envelope = raw;
523
+ if (envelope.ok === true) {
524
+ try {
525
+ exactKeys(envelope, ['ok', 'value'], `${operation} result`);
526
+ return { ok: true, value: validate(envelope.value) };
527
+ }
528
+ catch {
529
+ return { ok: false, error: validationError(providerType, operation, 'Provider operation returned an invalid value') };
530
+ }
531
+ }
532
+ if (envelope.ok === false && envelope.error && typeof envelope.error === 'object' && !Array.isArray(envelope.error)) {
533
+ try {
534
+ exactKeys(envelope, Object.hasOwn(envelope, 'value') ? ['ok', 'error', 'value'] : ['ok', 'error'], `${operation} result`);
535
+ const error = envelope.error;
536
+ exactKeys(error, ['code', 'message', 'retryable'], `${operation} error`);
537
+ if (typeof error.code !== 'string' || !error.code || typeof error.message !== 'string' || !error.message || typeof error.retryable !== 'boolean')
538
+ throw new Error('invalid provider error');
539
+ return {
540
+ ok: false,
541
+ error: safeProviderError(providerType, operation, error),
542
+ ...(Object.hasOwn(envelope, 'value') ? { value: validate(envelope.value) } : {})
543
+ };
544
+ }
545
+ catch {
546
+ return { ok: false, error: validationError(providerType, operation, 'Provider operation returned an invalid error') };
547
+ }
548
+ }
549
+ return { ok: false, error: validationError(providerType, operation, 'Provider operation returned an invalid result envelope') };
550
+ }
551
+ catch {
552
+ return { ok: false, error: validationError(providerType, operation, 'Platform provider operation failed', 'PLATFORM_PROVIDER_OPERATION_FAILED') };
553
+ }
554
+ }
555
+ function wrapProviderOperations(provider) {
556
+ const map = validators(provider.type, provider.identity);
557
+ const wrapped = { ...provider, context: { ...provider.context } };
558
+ wrapped.context.resolve = (input) => invokeProviderOperation(provider.type, 'context.resolve', () => provider.context.resolve(input), map['context.resolve']);
559
+ for (const groupName of ['issues', 'comments', 'changeRequests', 'checks', 'reviews', 'releases', 'securityAlerts', 'repositoryMetadata', 'verification']) {
560
+ const group = provider[groupName];
561
+ if (!group)
562
+ continue;
563
+ const target = { ...group };
564
+ for (const method of Object.keys(group)) {
565
+ const operation = `${groupName}.${method}`;
566
+ const validator = map[operation];
567
+ if (!validator)
568
+ throw new Error(`Missing validator for ${operation}`);
569
+ const original = group[method];
570
+ target[method] = (input) => invokeProviderOperation(provider.type, operation, () => original(input), validator);
571
+ }
572
+ wrapped[groupName] = target;
573
+ }
574
+ return wrapped;
575
+ }
576
+ export { invokeProviderOperation, validationError, wrapProviderOperations };
577
+ //# sourceMappingURL=provider-validation.js.map
@@ -8,13 +8,13 @@ function ensureClosingReference(body, issueNumber) {
8
8
  }
9
9
  function planPullRequestMetadata(input) {
10
10
  const typeLabel = taskTypeLabel(input.taskType);
11
- const copiedLabels = input.issue.labels.filter((label) => label.startsWith('in:'));
11
+ const targetInLabels = input.inLabels || input.pullRequest.labels.filter((label) => label.startsWith('in:'));
12
12
  const desiredLabels = [...new Set([
13
13
  ...input.pullRequest.labels.filter((label) => !label.startsWith('type:') && !label.startsWith('in:')),
14
14
  ...(typeLabel ? [typeLabel] : []),
15
- ...copiedLabels
15
+ ...targetInLabels.filter((label) => label.startsWith('in:'))
16
16
  ])].sort();
17
- const body = ensureClosingReference(input.pullRequest.body, input.issueNumber);
17
+ const body = input.issueNumber === null ? input.pullRequest.body : ensureClosingReference(input.pullRequest.body, input.issueNumber);
18
18
  return { operations: [
19
19
  input.capabilities.triage
20
20
  ? equalStrings(input.pullRequest.labels, desiredLabels)
@@ -29,9 +29,11 @@ function planPullRequestMetadata(input) {
29
29
  ? { name: 'milestone', status: 'no-op', reasonCode: null }
30
30
  : { name: 'milestone', status: 'planned', reasonCode: null, value: input.issue.milestone }
31
31
  : { name: 'milestone', status: 'skipped', reasonCode: 'TRIAGE_REQUIRED' },
32
- body === input.pullRequest.body
33
- ? { name: 'closing-issue', status: 'no-op', reasonCode: null }
34
- : { name: 'closing-issue', status: 'planned', reasonCode: null, value: body }
32
+ input.issueNumber === null
33
+ ? { name: 'closing-issue', status: 'skipped', reasonCode: 'ISSUE_REFERENCE_UNSUPPORTED' }
34
+ : body === input.pullRequest.body
35
+ ? { name: 'closing-issue', status: 'no-op', reasonCode: null }
36
+ : { name: 'closing-issue', status: 'planned', reasonCode: null, value: body }
35
37
  ] };
36
38
  }
37
39
  export { ensureClosingReference, planPullRequestMetadata };