@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 { ISSUE_FIELDS_QUERY, graphState, inspectGitHubIssue, inspectGitHubPullRequest, inspectGitHubIssueClosingChangeRequests, inspectGitHubRequiredChecks, parseRunJobIdentity, fetchCheckLogText } from './github-data.ts';
1
2
  import { execFileSync } from 'node:child_process';
2
3
  import fs from 'node:fs';
3
4
  import os from 'node:os';
@@ -16,8 +17,11 @@ import type {
16
17
  CheckRunSnapshot,
17
18
  GitEvidenceSnapshot,
18
19
  IssueSnapshot,
20
+ LabelReconciliation,
19
21
  MutationReceipt,
22
+ MilestoneInitialization,
20
23
  PlatformContextSnapshot,
24
+ PlatformError,
21
25
  ProviderOperationContext,
22
26
  PlatformProvider,
23
27
  PlatformProviderFactoryInput,
@@ -27,16 +31,17 @@ import type {
27
31
  RepositoryMetadataSnapshot,
28
32
  ReleaseSnapshot,
29
33
  RemoteCommentSnapshot,
30
- RequiredCheckSnapshot,
31
34
  ReviewSnapshot,
35
+ SecurityAlertKind,
36
+ SecurityAlertSnapshot,
32
37
  VerificationRemoteFacts
33
38
  } from './provider-contract.ts';
34
39
  import { resourceIdentityNumber, resourceIdentityString } from './resource-identity.ts';
35
- import { syncLabelDelta } from './in-label-sync.ts';
40
+ import { extractPullRequestFileNames, syncLabelDelta } from './in-label-sync.ts';
36
41
 
37
42
  const CURRENT_USER_QUERY = 'query { viewer { login } }';
38
43
  const ISSUE_TYPES_QUERY = `query($owner:String!){organization(login:$owner){issueTypes(first:20){nodes{id name pinnedFields{__typename ... on IssueFieldSingleSelect{id name options{id name}} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}}}}}`;
39
- const ISSUE_FIELDS_QUERY = `query($owner:String!,$name:String!,$number:Int!){repository(owner:$owner,name:$name){issue(number:$number){id issueType{id name pinnedFields{__typename ... on IssueFieldSingleSelect{id name options{id name}} ... on IssueFieldDate{id name} ... on IssueFieldText{id name} ... on IssueFieldNumber{id name}}} issueFieldValues(first:50){nodes{__typename ... on IssueFieldSingleSelectValue{name optionId field{... on IssueFieldSingleSelect{id name}}} ... on IssueFieldDateValue{value field{... on IssueFieldDate{id name}}} ... on IssueFieldTextValue{value field{... on IssueFieldText{id name}}} ... on IssueFieldNumberValue{value field{... on IssueFieldNumber{id name}}}}}}}}`;
44
+ 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}}}}}';
40
45
 
41
46
  function parseGitHubRemote(remote: string): string | null {
42
47
  const trimmed = remote.trim().replace(/\.git$/, '');
@@ -340,6 +345,29 @@ function createReceipt(remoteId: string): ProviderResult<MutationReceipt> {
340
345
  return { ok: true, value: { changed: true, remoteId } };
341
346
  }
342
347
 
348
+ function partialFailure<T>(response: { ok: false; error: PlatformError }, value: T): ProviderResult<T> {
349
+ return { ok: false, error: response.error, value };
350
+ }
351
+
352
+ function labelReconciliation(
353
+ created: string[],
354
+ updated: string[],
355
+ removed: string[],
356
+ skipped: string[]
357
+ ): LabelReconciliation {
358
+ return {
359
+ changed: created.length > 0 || updated.length > 0 || removed.length > 0,
360
+ created,
361
+ updated,
362
+ removed,
363
+ skipped
364
+ };
365
+ }
366
+
367
+ function milestoneInitialization(created: string[], skipped: string[]): MilestoneInitialization {
368
+ return { changed: created.length > 0, created, skipped };
369
+ }
370
+
343
371
  function githubResourceToken(identity: ResourceIdentity | null | undefined): string | null {
344
372
  return resourceIdentityString(identity) || (identity?.kind === 'number' ? String(identity.value) : null);
345
373
  }
@@ -371,7 +399,7 @@ function syncLabels(
371
399
  return { status: changed ? 'applied' as const : 'no-op' as const, changed, error: null };
372
400
  }
373
401
 
374
- function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'issues' | 'comments' | 'changeRequests' | 'checks' | 'reviews' | 'releases' | 'verification'> {
402
+ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'issues' | 'comments' | 'changeRequests' | 'checks' | 'reviews' | 'releases' | 'securityAlerts' | 'repositoryMetadata' | 'verification'> {
375
403
  const issues: NonNullable<PlatformProvider['issues']> = {
376
404
  async listLabels({ context }) {
377
405
  const response = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/labels?per_page=100`], { cwd: context.workingDirectory });
@@ -436,13 +464,25 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
436
464
  async inspect({ context, target }) {
437
465
  const number = resourceIdentityNumber(target);
438
466
  if (!number) return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
439
- const module = await import('./issues.ts');
440
- const fetched = module.inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
467
+ const fetched = inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
441
468
  if (!fetched.ok) return fetched;
442
- const graph = module.graphState(client, repository(context), number, context.workingDirectory);
469
+ const graph = graphState(client, repository(context), number, context.workingDirectory);
443
470
  return { ok: true, value: issueSnapshot(fetched.value, graph || undefined) };
444
471
  },
445
472
  async create({ context, desired }) {
473
+ let milestone: number | null = null;
474
+ if (desired.milestone) {
475
+ const milestones = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=open&per_page=100`], { cwd: context.workingDirectory });
476
+ if (!milestones.ok) return milestones;
477
+ const values = Array.isArray(milestones.value)
478
+ ? milestones.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
479
+ : [];
480
+ const selected = values.find((item: any) => item?.title === desired.milestone);
481
+ if (!Number.isSafeInteger(selected?.number) || selected.number <= 0) {
482
+ return invalid('MILESTONE_IDENTITY_INVALID', 'Milestone title does not resolve to a positive number');
483
+ }
484
+ milestone = selected.number;
485
+ }
446
486
  const response = client.json<any>(['api', `repos/${repository(context)}/issues`, '-X', 'POST', '--input', '-'], {
447
487
  cwd: context.workingDirectory,
448
488
  method: 'POST',
@@ -451,7 +491,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
451
491
  body: desired.body,
452
492
  labels: desired.labels,
453
493
  assignees: desired.assignees,
454
- ...(desired.milestone ? { milestone: desired.milestone } : {})
494
+ ...(milestone ? { milestone } : {})
455
495
  })
456
496
  });
457
497
  if (!response.ok) return response;
@@ -606,16 +646,66 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
606
646
  async inspect({ context, target }) {
607
647
  const number = resourceIdentityNumber(target);
608
648
  if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
609
- const module = await import('./pull-requests.ts');
610
- const fetched = module.inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
649
+ const fetched = inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
611
650
  if (!fetched.ok) return fetched;
612
651
  return { ok: true, value: changeRequestSnapshot(fetched.value) };
613
652
  },
653
+ async listFiles({ context, target }) {
654
+ const number = resourceIdentityNumber(target);
655
+ if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
656
+ const response = client.json<unknown>(['api', '--paginate', '--slurp', `repos/${repository(context)}/pulls/${number}/files?per_page=100`], { cwd: context.workingDirectory });
657
+ if (!response.ok) return response;
658
+ const files = extractPullRequestFileNames(response.value);
659
+ return files
660
+ ? { ok: true, value: files }
661
+ : invalid('IN_LABEL_SYNC_FILES_INVALID', 'Pull request files response is incomplete');
662
+ },
663
+ async listClosingIssues({ context, target }) {
664
+ const number = resourceIdentityNumber(target);
665
+ if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
666
+ const [owner, name] = repository(context).split('/');
667
+ if (!owner || !name) return invalid('IN_LABEL_SYNC_REPOSITORY_INVALID', 'Repository identity is invalid');
668
+ const identities: ResourceIdentity[] = [];
669
+ let cursor: string | null = null;
670
+ for (;;) {
671
+ const args = ['api', 'graphql', '-f', `query=${CLOSING_ISSUES_QUERY}`, '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `number=${number}`];
672
+ if (cursor) args.push('-F', `cursor=${cursor}`);
673
+ const response = client.json<unknown>(args, { cwd: context.workingDirectory });
674
+ if (!response.ok) return response;
675
+ const connection = (response.value as {
676
+ data?: { repository?: { pullRequest?: { closingIssuesReferences?: {
677
+ nodes?: unknown[]; pageInfo?: { hasNextPage?: boolean; endCursor?: string | null };
678
+ } } } };
679
+ })?.data?.repository?.pullRequest?.closingIssuesReferences;
680
+ if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo) {
681
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue response is incomplete');
682
+ }
683
+ for (const node of connection.nodes) {
684
+ const issue = Number((node as { number?: unknown })?.number);
685
+ if (!Number.isSafeInteger(issue) || issue <= 0) {
686
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue identity is invalid');
687
+ }
688
+ identities.push({ kind: 'number', value: issue });
689
+ }
690
+ if (!connection.pageInfo.hasNextPage) {
691
+ const seen = new Set<string>();
692
+ return { ok: true, value: identities.filter((identity) => {
693
+ const key = `${identity.kind}:${identity.value}`;
694
+ if (seen.has(key)) return false;
695
+ seen.add(key);
696
+ return true;
697
+ }) };
698
+ }
699
+ if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor) {
700
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue pagination cursor is invalid');
701
+ }
702
+ cursor = connection.pageInfo.endCursor;
703
+ }
704
+ },
614
705
  async listClosing({ context, issue }) {
615
706
  const number = resourceIdentityNumber(issue);
616
707
  if (!number) return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
617
- const module = await import('./pull-requests.ts');
618
- const fetched = module.inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
708
+ const fetched = inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
619
709
  if (!fetched.ok) return fetched;
620
710
  return { ok: true, value: fetched.value.map(changeRequestSnapshot) };
621
711
  },
@@ -686,8 +776,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
686
776
  async resolveGitEvidence({ context, target, expected }) {
687
777
  const number = resourceIdentityNumber(target);
688
778
  if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
689
- const module = await import('./github-provider.ts');
690
- return module.resolveGitHubChangeRequestGitEvidence({
779
+ return resolveGitHubChangeRequestGitEvidence({
691
780
  cwd: context.workingDirectory,
692
781
  repository: repository(context),
693
782
  number,
@@ -701,16 +790,12 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
701
790
  async inspectRequired({ context, changeRequest }) {
702
791
  const number = resourceIdentityNumber(changeRequest);
703
792
  if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
704
- const module = await import('./pr-checks.ts');
705
- const fetched = module.inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
706
- if (!fetched.ok) return fetched;
707
- return { ok: true, value: fetched.value.map((check: any): RequiredCheckSnapshot => ({ name: check.name, status: check.bucket, conclusion: check.conclusion, detailsUrl: check.detailsUrl })) };
793
+ return inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
708
794
  },
709
795
  async resolveRun({ context, changeRequest, checkName, detailsUrl }) {
710
796
  const number = resourceIdentityNumber(changeRequest);
711
797
  if (!number) return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
712
- const module = await import('./pr-checks.ts');
713
- const direct = detailsUrl ? module.parseRunJobIdentity(detailsUrl) : null;
798
+ const direct = detailsUrl ? parseRunJobIdentity(detailsUrl) : null;
714
799
  if (direct) {
715
800
  const run = client.json<any>(['api', `repos/${repository(context)}/actions/runs/${direct.runId}`], { cwd: context.workingDirectory });
716
801
  if (!run.ok) return run;
@@ -724,11 +809,10 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
724
809
  : invalid('CHECK_RUN_NOT_FOUND', 'Check run was not found');
725
810
  },
726
811
  async fetchLogs({ context, runId, jobId }) {
727
- const module = await import('./pr-checks.ts');
728
812
  const args = jobId
729
813
  ? ['api', `repos/${repository(context)}/actions/jobs/${jobId}/logs`]
730
814
  : ['run', 'view', runId, '--repo', repository(context), '--log-failed'];
731
- const fetched = module.fetchCheckLogText(client, args, context.workingDirectory);
815
+ const fetched = fetchCheckLogText(client, args, context.workingDirectory);
732
816
  if (!fetched.ok) return fetched;
733
817
  return { ok: true, value: { runId, jobId, text: fetched.value || '' } } as ProviderResult<CheckLogSnapshot>;
734
818
  }
@@ -797,7 +881,12 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
797
881
  }
798
882
  continue;
799
883
  }
800
- const response = client.json(['api', '--method', 'POST', `repos/${repository(context)}/milestones`, '-f', `title=${item.title}`, '-f', `description=${item.description}`], { cwd: context.workingDirectory });
884
+ const response = client.json([
885
+ 'api', '--method', 'POST', `repos/${repository(context)}/milestones`,
886
+ '-f', `title=${item.title}`,
887
+ '-f', `description=${item.description}`,
888
+ '-f', `state=${item.state}`
889
+ ], { cwd: context.workingDirectory });
801
890
  if (!response.ok) return response;
802
891
  created.push(item.title);
803
892
  }
@@ -854,20 +943,148 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
854
943
  }
855
944
  };
856
945
 
946
+ const securityAlerts: NonNullable<PlatformProvider['securityAlerts']> = {
947
+ async inspect({ context, kind, number }): Promise<ProviderResult<SecurityAlertSnapshot>> {
948
+ if (!Number.isSafeInteger(number) || number <= 0) return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
949
+ const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
950
+ if (!suffix) return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
951
+ const response = client.json<any>(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`], { cwd: context.workingDirectory });
952
+ if (!response.ok) return response;
953
+ const data = response.value;
954
+ if (!data || typeof data !== 'object' || Array.isArray(data)) return invalid('SECURITY_RESPONSE_INVALID', 'The platform returned an invalid security alert');
955
+ const value: SecurityAlertSnapshot = {
956
+ kind,
957
+ number,
958
+ state: typeof data.state === 'string' ? data.state : 'invalid',
959
+ data
960
+ };
961
+ return { ok: true, value };
962
+ },
963
+ async dismiss({ context, kind, number, reason, comment }): Promise<ProviderResult<MutationReceipt>> {
964
+ const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
965
+ if (!suffix) return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
966
+ if (!Number.isSafeInteger(number) || number <= 0) return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
967
+ const response = client.json<any>(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`, '-X', 'PATCH', '--input', '-'], {
968
+ cwd: context.workingDirectory,
969
+ method: 'PATCH',
970
+ input: JSON.stringify({ state: 'dismissed', dismissed_reason: reason, dismissed_comment: comment })
971
+ });
972
+ if (!response.ok) return response;
973
+ return createReceipt(String(response.value?.id || `${kind}:${number}`));
974
+ }
975
+ };
976
+
977
+ const repositoryMetadata: NonNullable<PlatformProvider['repositoryMetadata']> = {
978
+ async reconcileLabels({ context, desired, cleanupStaleIn }): Promise<ProviderResult<LabelReconciliation>> {
979
+ const endpoint = `repos/${repository(context)}/labels?per_page=100`;
980
+ const listed = client.json<any>(['api', '--paginate', '--slurp', endpoint], { cwd: context.workingDirectory });
981
+ if (!listed.ok) return listed;
982
+ if (!Array.isArray(listed.value)) return invalid('LABEL_RESPONSE_INVALID', 'The platform returned an invalid label list');
983
+ const values = Array.isArray(listed.value)
984
+ ? listed.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
985
+ : [];
986
+ if (values.some((entry: any) => !entry || typeof entry.name !== 'string' || !entry.name)) {
987
+ return invalid('LABEL_RESPONSE_INVALID', 'The platform returned a label without a valid name');
988
+ }
989
+ const current = new Map<string, any>(values.map((entry: any) => [String(entry.name), entry]));
990
+ const created: string[] = [];
991
+ const updated: string[] = [];
992
+ const skipped: string[] = [];
993
+ const removed: string[] = [];
994
+ for (const label of desired) {
995
+ const existing = current.get(label.name);
996
+ if (!existing) {
997
+ const response = client.json(['api', `repos/${repository(context)}/labels`, '-X', 'POST', '--input', '-'], {
998
+ cwd: context.workingDirectory,
999
+ method: 'POST',
1000
+ input: JSON.stringify({ name: label.name, color: label.color, description: label.description })
1001
+ });
1002
+ if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1003
+ created.push(label.name);
1004
+ continue;
1005
+ }
1006
+ const sameColor = typeof existing.color === 'string' && existing.color.toUpperCase() === label.color.toUpperCase();
1007
+ const sameDescription = String(existing.description || '') === label.description;
1008
+ if (sameColor && sameDescription) {
1009
+ skipped.push(label.name);
1010
+ continue;
1011
+ }
1012
+ const response = client.json(['api', `repos/${repository(context)}/labels/${encodeURIComponent(label.name)}`, '-X', 'PATCH', '--input', '-'], {
1013
+ cwd: context.workingDirectory,
1014
+ method: 'PATCH',
1015
+ input: JSON.stringify({ new_name: label.name, color: label.color, description: label.description })
1016
+ });
1017
+ if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1018
+ updated.push(label.name);
1019
+ }
1020
+ const desiredNames = new Set(desired.map((label) => label.name));
1021
+ if (cleanupStaleIn) {
1022
+ for (const name of current.keys()) {
1023
+ if (!name.startsWith('in:') || desiredNames.has(name)) continue;
1024
+ const response = client.text(['api', `repos/${repository(context)}/labels/${encodeURIComponent(name)}`, '-X', 'DELETE'], {
1025
+ cwd: context.workingDirectory,
1026
+ method: 'DELETE'
1027
+ });
1028
+ if (!response.ok) return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1029
+ removed.push(name);
1030
+ }
1031
+ }
1032
+ return {
1033
+ ok: true,
1034
+ value: {
1035
+ changed: created.length > 0 || updated.length > 0 || removed.length > 0,
1036
+ created,
1037
+ updated,
1038
+ removed,
1039
+ skipped
1040
+ }
1041
+ };
1042
+ },
1043
+ async reconcileMilestones({ context, desired }): Promise<ProviderResult<MilestoneInitialization>> {
1044
+ const listed = client.json<any>(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=all&per_page=100`], { cwd: context.workingDirectory });
1045
+ if (!listed.ok) return listed;
1046
+ if (!Array.isArray(listed.value)) return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned an invalid milestone list');
1047
+ const values = Array.isArray(listed.value)
1048
+ ? listed.value.flatMap((entry: any) => Array.isArray(entry) ? entry : [entry])
1049
+ : [];
1050
+ if (values.some((entry: any) => !entry || typeof entry.title !== 'string' || !entry.title)) {
1051
+ return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned a milestone without a valid title');
1052
+ }
1053
+ const existing = new Set(values.map((entry: any) => String(entry.title)));
1054
+ const created: string[] = [];
1055
+ const skipped: string[] = [];
1056
+ for (const milestone of desired) {
1057
+ if (existing.has(milestone.title)) {
1058
+ skipped.push(milestone.title);
1059
+ continue;
1060
+ }
1061
+ const response = client.json(['api', `repos/${repository(context)}/milestones`, '-X', 'POST', '--input', '-'], {
1062
+ cwd: context.workingDirectory,
1063
+ method: 'POST',
1064
+ input: JSON.stringify({ title: milestone.title, description: milestone.description, state: milestone.state })
1065
+ });
1066
+ if (!response.ok) return partialFailure(response, milestoneInitialization(created, skipped));
1067
+ existing.add(milestone.title);
1068
+ created.push(milestone.title);
1069
+ }
1070
+ return { ok: true, value: { changed: created.length > 0, created, skipped } };
1071
+ }
1072
+ };
1073
+
857
1074
  const verification: NonNullable<PlatformProvider['verification']> = {
858
1075
  async fetchRemoteFacts(input) {
859
1076
  const issue = input.issue && issues.inspect
860
1077
  ? await issues.inspect({ context: input.context, target: input.issue })
861
1078
  : { ok: true as const, value: null };
862
- if (!issue.ok) return issue;
1079
+ if (!issue.ok) return { ok: false, error: issue.error };
863
1080
  const commentFacts = input.includeComments && input.issue && comments.list
864
1081
  ? await comments.list({ context: input.context, parent: input.issue })
865
1082
  : { ok: true as const, value: [] as RemoteCommentSnapshot[] };
866
- if (!commentFacts.ok) return commentFacts;
1083
+ if (!commentFacts.ok) return { ok: false, error: commentFacts.error };
867
1084
  const changeRequest = input.changeRequest && changeRequests.inspect
868
1085
  ? await changeRequests.inspect({ context: input.context, target: input.changeRequest })
869
1086
  : { ok: true as const, value: null };
870
- if (!changeRequest.ok) return changeRequest;
1087
+ if (!changeRequest.ok) return { ok: false, error: changeRequest.error };
871
1088
  return {
872
1089
  ok: true,
873
1090
  value: {
@@ -881,7 +1098,7 @@ function createGitHubOperations(client: GitHubClient): Pick<PlatformProvider, 'i
881
1098
  }
882
1099
  };
883
1100
 
884
- return { issues, comments, changeRequests, checks, reviews, releases, verification };
1101
+ return { issues, comments, changeRequests, checks, reviews, releases, securityAlerts, repositoryMetadata, verification };
885
1102
  }
886
1103
 
887
1104
  function createGitHubProvider(