@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,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { COMPLETION_BACKFILL_FAMILIES, inspectCompletionArtifacts } from '../task/finalization-artifacts.js';
4
- import { parseArtifactName } from '../task/artifact-lifecycle.js';
4
+ import { parseArtifactName } from '../task/artifact-name.js';
5
5
  import { parseTaskFrontmatter } from '../task/frontmatter.js';
6
6
  import { resolveTaskRef } from '../task/resolve-ref.js';
7
7
  import { getOpenWorkflowWarnings } from '../task/workflow-warnings.js';
@@ -0,0 +1,241 @@
1
+ import { checkStatusBucket } from './check-status.js';
2
+ 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}}}}}}}}`;
3
+ function normalizeIssue(remote, repository, fallbackNumber) {
4
+ const number = Number.isInteger(remote.number) && Number(remote.number) > 0
5
+ ? Number(remote.number)
6
+ : fallbackNumber;
7
+ if (!number || !Number.isSafeInteger(number) || remote.pull_request)
8
+ return null;
9
+ return {
10
+ repository,
11
+ number,
12
+ databaseId: Number.isInteger(remote.id) ? Number(remote.id) : null,
13
+ nodeId: remote.node_id || `issue-${number}`,
14
+ url: remote.html_url || `https://github.com/${repository}/issues/${number}`,
15
+ state: String(remote.state || '').toLowerCase() === 'closed' ? 'closed' : 'open',
16
+ title: remote.title || '',
17
+ body: remote.body || '',
18
+ labels: (remote.labels || []).map((label) => typeof label === 'string' ? label : label.name || '').filter(Boolean).sort(),
19
+ assignees: (remote.assignees || []).map((assignee) => assignee.login || '').filter(Boolean).sort(),
20
+ milestone: remote.milestone?.title || null,
21
+ issueType: remote.type?.name || null,
22
+ fields: {}
23
+ };
24
+ }
25
+ function fieldKind(value) {
26
+ if (value.__typename === 'IssueFieldSingleSelect' || value.__typename === 'IssueFieldSingleSelectValue')
27
+ return 'single-select';
28
+ if (value.__typename === 'IssueFieldDate' || value.__typename === 'IssueFieldDateValue')
29
+ return 'date';
30
+ if (value.__typename === 'IssueFieldText' || value.__typename === 'IssueFieldTextValue')
31
+ return 'text';
32
+ if (value.__typename === 'IssueFieldNumber' || value.__typename === 'IssueFieldNumberValue')
33
+ return 'number';
34
+ return null;
35
+ }
36
+ function normalizeFieldSchemas(value) {
37
+ if (!Array.isArray(value))
38
+ return [];
39
+ return value.flatMap((raw) => {
40
+ const item = raw;
41
+ const kind = fieldKind(item);
42
+ return item.id && item.name && kind ? [{
43
+ id: item.id,
44
+ name: item.name,
45
+ kind,
46
+ options: (item.options || []).flatMap((option) => option.id && option.name ? [{ id: option.id, name: option.name }] : [])
47
+ }] : [];
48
+ });
49
+ }
50
+ function normalizeCurrentFields(value) {
51
+ const issue = value?.data?.repository?.issue;
52
+ const type = issue?.issueType?.name ? {
53
+ id: issue.issueType.id || issue.issueType.name,
54
+ name: issue.issueType.name,
55
+ fields: normalizeFieldSchemas(issue.issueType.pinnedFields)
56
+ } : null;
57
+ const values = (issue?.issueFieldValues?.nodes || []).flatMap((raw) => {
58
+ const item = raw;
59
+ const kind = fieldKind(item);
60
+ const value = kind === 'single-select' ? item.name : item.value;
61
+ return item.field?.name && kind && value !== undefined
62
+ ? [{ id: item.field.id || item.field.name, name: item.field.name, kind, value: value ?? null }]
63
+ : [];
64
+ });
65
+ return { issueId: issue?.id || null, type, values };
66
+ }
67
+ function graphState(client, repository, issue, cwd) {
68
+ const [owner, name] = repository.split('/');
69
+ if (!owner || !name)
70
+ return null;
71
+ const current = client.json([
72
+ 'api', 'graphql', '-f', `query=${ISSUE_FIELDS_QUERY}`, '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `number=${issue}`
73
+ ], { cwd });
74
+ if (!current.ok)
75
+ return null;
76
+ return normalizeCurrentFields(current.value);
77
+ }
78
+ function fetchIssue(client, repository, issue, cwd) {
79
+ return client.json(['api', `repos/${repository}/issues/${issue}`], { cwd });
80
+ }
81
+ function inspectGitHubIssue(client, repository, issue, cwd) {
82
+ const fetched = fetchIssue(client, repository, issue, cwd);
83
+ if (!fetched.ok)
84
+ return fetched;
85
+ const snapshot = normalizeIssue(fetched.value, repository, issue);
86
+ return snapshot
87
+ ? { ok: true, value: snapshot }
88
+ : { ok: false, error: { code: 'ISSUE_IDENTITY_INVALID', message: 'Remote resource is not a valid Issue', retryable: false } };
89
+ }
90
+ const CLOSING_PULL_REQUESTS_QUERY = `query($owner:String!,$name:String!,$issue:Int!,$cursor:String){repository(owner:$owner,name:$name){issue(number:$issue){closedByPullRequestsReferences(first:100,after:$cursor){nodes{number id url state title body isDraft headRefName headRefOid headRepository{nameWithOwner} baseRefName baseRefOid baseRepository{nameWithOwner} mergedAt mergeCommit{oid} labels(first:100){nodes{name}} assignees(first:100){nodes{login}} milestone{title}} pageInfo{hasNextPage endCursor}}}}}`;
91
+ function normalizePullRequest(remote, repository) {
92
+ const number = Number(remote.number);
93
+ const headRepository = remote.head?.repo?.full_name;
94
+ const baseRepository = remote.base?.repo?.full_name;
95
+ if (!Number.isInteger(number) || number <= 0 || !remote.node_id || !remote.html_url ||
96
+ !remote.head?.ref || !remote.head.sha || !headRepository || !remote.base?.ref || !baseRepository)
97
+ return null;
98
+ const mergeabilityDetail = remote.mergeable_state?.trim().toLowerCase() || null;
99
+ const mergeability = remote.mergeable === false
100
+ ? { state: 'conflicting', detail: mergeabilityDetail }
101
+ : remote.mergeable === true && mergeabilityDetail !== 'dirty'
102
+ ? { state: 'mergeable', detail: mergeabilityDetail }
103
+ : { state: 'unknown', detail: mergeabilityDetail };
104
+ return {
105
+ repository,
106
+ number,
107
+ nodeId: remote.node_id,
108
+ url: remote.html_url,
109
+ state: remote.state === 'closed' ? 'closed' : 'open',
110
+ title: remote.title || '',
111
+ body: remote.body || '',
112
+ draft: Boolean(remote.draft),
113
+ head: { repository: headRepository, ref: remote.head.ref, sha: remote.head.sha },
114
+ base: { repository: baseRepository, ref: remote.base.ref, sha: remote.base.sha || '' },
115
+ mergedAt: remote.merged_at || null,
116
+ mergeCommitSha: remote.merge_commit_sha || null,
117
+ labels: (remote.labels || []).map((label) => typeof label === 'string' ? label : label.name || '').filter(Boolean).sort(),
118
+ assignees: (remote.assignees || []).map((assignee) => assignee.login || '').filter(Boolean).sort(),
119
+ milestone: remote.milestone?.title || null,
120
+ mergeability
121
+ };
122
+ }
123
+ function normalizeClosingPullRequest(node, repository) {
124
+ return normalizePullRequest({
125
+ number: node.number,
126
+ node_id: node.id,
127
+ html_url: node.url,
128
+ state: node.state === 'OPEN' ? 'open' : 'closed',
129
+ title: node.title,
130
+ body: node.body,
131
+ draft: node.isDraft,
132
+ head: { ref: node.headRefName, sha: node.headRefOid, repo: node.headRepository ? { full_name: node.headRepository.nameWithOwner } : null },
133
+ base: { ref: node.baseRefName, sha: node.baseRefOid, repo: node.baseRepository ? { full_name: node.baseRepository.nameWithOwner } : null },
134
+ merged_at: node.mergedAt,
135
+ merge_commit_sha: node.mergeCommit?.oid,
136
+ labels: node.labels?.nodes,
137
+ assignees: node.assignees?.nodes,
138
+ milestone: node.milestone
139
+ }, repository);
140
+ }
141
+ function inspectGitHubIssueClosingChangeRequests(client, repository, issueNumber, cwd) {
142
+ const [owner, name] = repository.split('/');
143
+ if (!owner || !name || !Number.isInteger(issueNumber) || issueNumber <= 0)
144
+ return {
145
+ ok: false,
146
+ error: { code: 'PR_IDENTITY_INVALID', message: 'Repository or Issue identity is invalid', retryable: false }
147
+ };
148
+ const candidates = [];
149
+ let cursor = null;
150
+ for (;;) {
151
+ const args = [
152
+ 'api', 'graphql', '-f', `query=${CLOSING_PULL_REQUESTS_QUERY}`,
153
+ '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `issue=${issueNumber}`
154
+ ];
155
+ if (cursor)
156
+ args.push('-F', `cursor=${cursor}`);
157
+ const response = client.json(args, { cwd });
158
+ if (!response.ok)
159
+ return response;
160
+ const connection = response.value?.data?.repository?.issue?.closedByPullRequestsReferences;
161
+ if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo)
162
+ return {
163
+ ok: false,
164
+ error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request response is incomplete', retryable: false }
165
+ };
166
+ for (const node of connection.nodes) {
167
+ const normalized = normalizeClosingPullRequest(node, repository);
168
+ if (!normalized)
169
+ return {
170
+ ok: false,
171
+ error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request identity is incomplete', retryable: false }
172
+ };
173
+ candidates.push(normalized);
174
+ }
175
+ if (!connection.pageInfo.hasNextPage)
176
+ return { ok: true, value: candidates };
177
+ if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor)
178
+ return {
179
+ ok: false,
180
+ error: { code: 'PR_IDENTITY_INVALID', message: 'Closing pull request pagination cursor is invalid', retryable: false }
181
+ };
182
+ cursor = connection.pageInfo.endCursor;
183
+ }
184
+ }
185
+ function inspectGitHubPullRequest(client, repository, number, cwd) {
186
+ const fetched = client.json(['api', `repos/${repository}/pulls/${number}`], { cwd });
187
+ if (!fetched.ok)
188
+ return fetched;
189
+ const pullRequest = normalizePullRequest(fetched.value, repository);
190
+ return pullRequest
191
+ ? { ok: true, value: pullRequest }
192
+ : { ok: false, error: { code: 'PR_IDENTITY_INVALID', message: 'Remote resource is not a valid pull request', retryable: false } };
193
+ }
194
+ function normalizeGitHubChecks(value) {
195
+ if (!Array.isArray(value))
196
+ return [];
197
+ return value.flatMap((raw) => {
198
+ const item = raw;
199
+ const name = String(item.name || item.context || '');
200
+ return name ? [{
201
+ name,
202
+ status: checkStatusBucket(String(item.bucket || item.status || item.conclusion || item.state || '')),
203
+ conclusion: item.conclusion ? String(item.conclusion) : item.state ? String(item.state) : null,
204
+ detailsUrl: item.link ? String(item.link) : item.detailsUrl ? String(item.detailsUrl) : null
205
+ }] : [];
206
+ });
207
+ }
208
+ function inspectGitHubRequiredChecks(client, repository, number, cwd) {
209
+ const inspected = client.json([
210
+ 'pr', 'checks', String(number), '--repo', repository,
211
+ '--json', 'name,state,bucket,link,workflow,startedAt,completedAt'
212
+ ], { cwd });
213
+ return inspected.ok
214
+ ? { ok: true, value: normalizeGitHubChecks(inspected.value) }
215
+ : { ok: false, error: inspected.error };
216
+ }
217
+ function parseRunJobIdentity(detailsUrl) {
218
+ try {
219
+ const url = new URL(detailsUrl);
220
+ if (url.hostname !== 'github.com')
221
+ return null;
222
+ const match = url.pathname.match(/\/actions\/runs\/(\d+)(?:\/job\/(\d+))?/);
223
+ if (!match)
224
+ return null;
225
+ return { runId: Number(match[1]), jobId: match[2] ? Number(match[2]) : null };
226
+ }
227
+ catch {
228
+ return null;
229
+ }
230
+ }
231
+ function fetchCheckLogText(client, args, cwd) {
232
+ if (!client.text)
233
+ return { ok: false, error: { code: 'PLATFORM_CLIENT_TEXT_UNAVAILABLE', message: 'Platform client does not support text responses', retryable: false } };
234
+ const fetched = client.text(args, { cwd });
235
+ if (fetched.ok || args[0] !== 'api' || !/response contains terminal escape sequences/i.test(fetched.error.message)) {
236
+ return fetched;
237
+ }
238
+ return client.text([...args, '--allow-escape-sequences'], { cwd });
239
+ }
240
+ export { ISSUE_FIELDS_QUERY, graphState, inspectGitHubIssue, normalizePullRequest, inspectGitHubIssueClosingChangeRequests, inspectGitHubPullRequest, inspectGitHubRequiredChecks, parseRunJobIdentity, fetchCheckLogText };
241
+ //# sourceMappingURL=github-data.js.map
@@ -1,3 +1,4 @@
1
+ import { ISSUE_FIELDS_QUERY, graphState, inspectGitHubIssue, inspectGitHubPullRequest, inspectGitHubIssueClosingChangeRequests, inspectGitHubRequiredChecks, parseRunJobIdentity, fetchCheckLogText } from './github-data.js';
1
2
  import { execFileSync } from 'node:child_process';
2
3
  import fs from 'node:fs';
3
4
  import os from 'node:os';
@@ -5,10 +6,10 @@ import path from 'node:path';
5
6
  import semver from 'semver';
6
7
  import { createGitHubClient, MINIMUM_GITHUB_CLI_VERSION } from './github-client.js';
7
8
  import { resourceIdentityNumber, resourceIdentityString } from './resource-identity.js';
8
- import { syncLabelDelta } from './in-label-sync.js';
9
+ import { extractPullRequestFileNames, syncLabelDelta } from './in-label-sync.js';
9
10
  const CURRENT_USER_QUERY = 'query { viewer { login } }';
10
11
  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}}}}}}`;
11
- 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}}}}}}}}`;
12
+ 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}}}}}';
12
13
  function parseGitHubRemote(remote) {
13
14
  const trimmed = remote.trim().replace(/\.git$/, '');
14
15
  const match = trimmed.match(/^(?:https?:\/\/github\.com\/|ssh:\/\/(?:git@)?github\.com\/|git@github\.com:)([^/\s]+\/[^/\s]+)$/i);
@@ -289,6 +290,21 @@ function commentSnapshot(value) {
289
290
  function createReceipt(remoteId) {
290
291
  return { ok: true, value: { changed: true, remoteId } };
291
292
  }
293
+ function partialFailure(response, value) {
294
+ return { ok: false, error: response.error, value };
295
+ }
296
+ function labelReconciliation(created, updated, removed, skipped) {
297
+ return {
298
+ changed: created.length > 0 || updated.length > 0 || removed.length > 0,
299
+ created,
300
+ updated,
301
+ removed,
302
+ skipped
303
+ };
304
+ }
305
+ function milestoneInitialization(created, skipped) {
306
+ return { changed: created.length > 0, created, skipped };
307
+ }
292
308
  function githubResourceToken(identity) {
293
309
  return resourceIdentityString(identity) || (identity?.kind === 'number' ? String(identity.value) : null);
294
310
  }
@@ -383,14 +399,27 @@ function createGitHubOperations(client) {
383
399
  const number = resourceIdentityNumber(target);
384
400
  if (!number)
385
401
  return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
386
- const module = await import('./issues.js');
387
- const fetched = module.inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
402
+ const fetched = inspectGitHubIssue(client, repository(context), number, context.workingDirectory);
388
403
  if (!fetched.ok)
389
404
  return fetched;
390
- const graph = module.graphState(client, repository(context), number, context.workingDirectory);
405
+ const graph = graphState(client, repository(context), number, context.workingDirectory);
391
406
  return { ok: true, value: issueSnapshot(fetched.value, graph || undefined) };
392
407
  },
393
408
  async create({ context, desired }) {
409
+ let milestone = null;
410
+ if (desired.milestone) {
411
+ const milestones = client.json(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=open&per_page=100`], { cwd: context.workingDirectory });
412
+ if (!milestones.ok)
413
+ return milestones;
414
+ const values = Array.isArray(milestones.value)
415
+ ? milestones.value.flatMap((entry) => Array.isArray(entry) ? entry : [entry])
416
+ : [];
417
+ const selected = values.find((item) => item?.title === desired.milestone);
418
+ if (!Number.isSafeInteger(selected?.number) || selected.number <= 0) {
419
+ return invalid('MILESTONE_IDENTITY_INVALID', 'Milestone title does not resolve to a positive number');
420
+ }
421
+ milestone = selected.number;
422
+ }
394
423
  const response = client.json(['api', `repos/${repository(context)}/issues`, '-X', 'POST', '--input', '-'], {
395
424
  cwd: context.workingDirectory,
396
425
  method: 'POST',
@@ -399,7 +428,7 @@ function createGitHubOperations(client) {
399
428
  body: desired.body,
400
429
  labels: desired.labels,
401
430
  assignees: desired.assignees,
402
- ...(desired.milestone ? { milestone: desired.milestone } : {})
431
+ ...(milestone ? { milestone } : {})
403
432
  })
404
433
  });
405
434
  if (!response.ok)
@@ -576,18 +605,71 @@ function createGitHubOperations(client) {
576
605
  const number = resourceIdentityNumber(target);
577
606
  if (!number)
578
607
  return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
579
- const module = await import('./pull-requests.js');
580
- const fetched = module.inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
608
+ const fetched = inspectGitHubPullRequest(client, repository(context), number, context.workingDirectory);
581
609
  if (!fetched.ok)
582
610
  return fetched;
583
611
  return { ok: true, value: changeRequestSnapshot(fetched.value) };
584
612
  },
613
+ async listFiles({ context, target }) {
614
+ const number = resourceIdentityNumber(target);
615
+ if (!number)
616
+ return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
617
+ const response = client.json(['api', '--paginate', '--slurp', `repos/${repository(context)}/pulls/${number}/files?per_page=100`], { cwd: context.workingDirectory });
618
+ if (!response.ok)
619
+ return response;
620
+ const files = extractPullRequestFileNames(response.value);
621
+ return files
622
+ ? { ok: true, value: files }
623
+ : invalid('IN_LABEL_SYNC_FILES_INVALID', 'Pull request files response is incomplete');
624
+ },
625
+ async listClosingIssues({ context, target }) {
626
+ const number = resourceIdentityNumber(target);
627
+ if (!number)
628
+ return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
629
+ const [owner, name] = repository(context).split('/');
630
+ if (!owner || !name)
631
+ return invalid('IN_LABEL_SYNC_REPOSITORY_INVALID', 'Repository identity is invalid');
632
+ const identities = [];
633
+ let cursor = null;
634
+ for (;;) {
635
+ const args = ['api', 'graphql', '-f', `query=${CLOSING_ISSUES_QUERY}`, '-F', `owner=${owner}`, '-F', `name=${name}`, '-F', `number=${number}`];
636
+ if (cursor)
637
+ args.push('-F', `cursor=${cursor}`);
638
+ const response = client.json(args, { cwd: context.workingDirectory });
639
+ if (!response.ok)
640
+ return response;
641
+ const connection = response.value?.data?.repository?.pullRequest?.closingIssuesReferences;
642
+ if (!connection || !Array.isArray(connection.nodes) || !connection.pageInfo) {
643
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue response is incomplete');
644
+ }
645
+ for (const node of connection.nodes) {
646
+ const issue = Number(node?.number);
647
+ if (!Number.isSafeInteger(issue) || issue <= 0) {
648
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue identity is invalid');
649
+ }
650
+ identities.push({ kind: 'number', value: issue });
651
+ }
652
+ if (!connection.pageInfo.hasNextPage) {
653
+ const seen = new Set();
654
+ return { ok: true, value: identities.filter((identity) => {
655
+ const key = `${identity.kind}:${identity.value}`;
656
+ if (seen.has(key))
657
+ return false;
658
+ seen.add(key);
659
+ return true;
660
+ }) };
661
+ }
662
+ if (!connection.pageInfo.endCursor || connection.pageInfo.endCursor === cursor) {
663
+ return invalid('IN_LABEL_SYNC_ASSOCIATION_INVALID', 'Closing Issue pagination cursor is invalid');
664
+ }
665
+ cursor = connection.pageInfo.endCursor;
666
+ }
667
+ },
585
668
  async listClosing({ context, issue }) {
586
669
  const number = resourceIdentityNumber(issue);
587
670
  if (!number)
588
671
  return invalid('ISSUE_NUMBER_INVALID', 'Issue number must be positive');
589
- const module = await import('./pull-requests.js');
590
- const fetched = module.inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
672
+ const fetched = inspectGitHubIssueClosingChangeRequests(client, repository(context), number, context.workingDirectory);
591
673
  if (!fetched.ok)
592
674
  return fetched;
593
675
  return { ok: true, value: fetched.value.map(changeRequestSnapshot) };
@@ -671,8 +753,7 @@ function createGitHubOperations(client) {
671
753
  const number = resourceIdentityNumber(target);
672
754
  if (!number)
673
755
  return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
674
- const module = await import('./github-provider.js');
675
- return module.resolveGitHubChangeRequestGitEvidence({
756
+ return resolveGitHubChangeRequestGitEvidence({
676
757
  cwd: context.workingDirectory,
677
758
  repository: repository(context),
678
759
  number,
@@ -686,18 +767,13 @@ function createGitHubOperations(client) {
686
767
  const number = resourceIdentityNumber(changeRequest);
687
768
  if (!number)
688
769
  return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
689
- const module = await import('./pr-checks.js');
690
- const fetched = module.inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
691
- if (!fetched.ok)
692
- return fetched;
693
- return { ok: true, value: fetched.value.map((check) => ({ name: check.name, status: check.bucket, conclusion: check.conclusion, detailsUrl: check.detailsUrl })) };
770
+ return inspectGitHubRequiredChecks(client, repository(context), number, context.workingDirectory);
694
771
  },
695
772
  async resolveRun({ context, changeRequest, checkName, detailsUrl }) {
696
773
  const number = resourceIdentityNumber(changeRequest);
697
774
  if (!number)
698
775
  return invalid('PR_NUMBER_INVALID', 'Pull request number must be positive');
699
- const module = await import('./pr-checks.js');
700
- const direct = detailsUrl ? module.parseRunJobIdentity(detailsUrl) : null;
776
+ const direct = detailsUrl ? parseRunJobIdentity(detailsUrl) : null;
701
777
  if (direct) {
702
778
  const run = client.json(['api', `repos/${repository(context)}/actions/runs/${direct.runId}`], { cwd: context.workingDirectory });
703
779
  if (!run.ok)
@@ -713,11 +789,10 @@ function createGitHubOperations(client) {
713
789
  : invalid('CHECK_RUN_NOT_FOUND', 'Check run was not found');
714
790
  },
715
791
  async fetchLogs({ context, runId, jobId }) {
716
- const module = await import('./pr-checks.js');
717
792
  const args = jobId
718
793
  ? ['api', `repos/${repository(context)}/actions/jobs/${jobId}/logs`]
719
794
  : ['run', 'view', runId, '--repo', repository(context), '--log-failed'];
720
- const fetched = module.fetchCheckLogText(client, args, context.workingDirectory);
795
+ const fetched = fetchCheckLogText(client, args, context.workingDirectory);
721
796
  if (!fetched.ok)
722
797
  return fetched;
723
798
  return { ok: true, value: { runId, jobId, text: fetched.value || '' } };
@@ -798,7 +873,12 @@ function createGitHubOperations(client) {
798
873
  }
799
874
  continue;
800
875
  }
801
- const response = client.json(['api', '--method', 'POST', `repos/${repository(context)}/milestones`, '-f', `title=${item.title}`, '-f', `description=${item.description}`], { cwd: context.workingDirectory });
876
+ const response = client.json([
877
+ 'api', '--method', 'POST', `repos/${repository(context)}/milestones`,
878
+ '-f', `title=${item.title}`,
879
+ '-f', `description=${item.description}`,
880
+ '-f', `state=${item.state}`
881
+ ], { cwd: context.workingDirectory });
802
882
  if (!response.ok)
803
883
  return response;
804
884
  created.push(item.title);
@@ -855,23 +935,165 @@ function createGitHubOperations(client) {
855
935
  };
856
936
  }
857
937
  };
938
+ const securityAlerts = {
939
+ async inspect({ context, kind, number }) {
940
+ if (!Number.isSafeInteger(number) || number <= 0)
941
+ return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
942
+ const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
943
+ if (!suffix)
944
+ return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
945
+ const response = client.json(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`], { cwd: context.workingDirectory });
946
+ if (!response.ok)
947
+ return response;
948
+ const data = response.value;
949
+ if (!data || typeof data !== 'object' || Array.isArray(data))
950
+ return invalid('SECURITY_RESPONSE_INVALID', 'The platform returned an invalid security alert');
951
+ const value = {
952
+ kind,
953
+ number,
954
+ state: typeof data.state === 'string' ? data.state : 'invalid',
955
+ data
956
+ };
957
+ return { ok: true, value };
958
+ },
959
+ async dismiss({ context, kind, number, reason, comment }) {
960
+ const suffix = kind === 'dependabot' ? 'dependabot' : kind === 'code-scanning' ? 'code-scanning' : null;
961
+ if (!suffix)
962
+ return invalid('SECURITY_KIND_INVALID', 'Alert kind is invalid');
963
+ if (!Number.isSafeInteger(number) || number <= 0)
964
+ return invalid('SECURITY_NUMBER_INVALID', 'Alert number must be a positive integer');
965
+ const response = client.json(['api', `repos/${repository(context)}/${suffix}/alerts/${number}`, '-X', 'PATCH', '--input', '-'], {
966
+ cwd: context.workingDirectory,
967
+ method: 'PATCH',
968
+ input: JSON.stringify({ state: 'dismissed', dismissed_reason: reason, dismissed_comment: comment })
969
+ });
970
+ if (!response.ok)
971
+ return response;
972
+ return createReceipt(String(response.value?.id || `${kind}:${number}`));
973
+ }
974
+ };
975
+ const repositoryMetadata = {
976
+ async reconcileLabels({ context, desired, cleanupStaleIn }) {
977
+ const endpoint = `repos/${repository(context)}/labels?per_page=100`;
978
+ const listed = client.json(['api', '--paginate', '--slurp', endpoint], { cwd: context.workingDirectory });
979
+ if (!listed.ok)
980
+ return listed;
981
+ if (!Array.isArray(listed.value))
982
+ return invalid('LABEL_RESPONSE_INVALID', 'The platform returned an invalid label list');
983
+ const values = Array.isArray(listed.value)
984
+ ? listed.value.flatMap((entry) => Array.isArray(entry) ? entry : [entry])
985
+ : [];
986
+ if (values.some((entry) => !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(values.map((entry) => [String(entry.name), entry]));
990
+ const created = [];
991
+ const updated = [];
992
+ const skipped = [];
993
+ const removed = [];
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)
1003
+ return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1004
+ created.push(label.name);
1005
+ continue;
1006
+ }
1007
+ const sameColor = typeof existing.color === 'string' && existing.color.toUpperCase() === label.color.toUpperCase();
1008
+ const sameDescription = String(existing.description || '') === label.description;
1009
+ if (sameColor && sameDescription) {
1010
+ skipped.push(label.name);
1011
+ continue;
1012
+ }
1013
+ const response = client.json(['api', `repos/${repository(context)}/labels/${encodeURIComponent(label.name)}`, '-X', 'PATCH', '--input', '-'], {
1014
+ cwd: context.workingDirectory,
1015
+ method: 'PATCH',
1016
+ input: JSON.stringify({ new_name: label.name, color: label.color, description: label.description })
1017
+ });
1018
+ if (!response.ok)
1019
+ return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1020
+ updated.push(label.name);
1021
+ }
1022
+ const desiredNames = new Set(desired.map((label) => label.name));
1023
+ if (cleanupStaleIn) {
1024
+ for (const name of current.keys()) {
1025
+ if (!name.startsWith('in:') || desiredNames.has(name))
1026
+ continue;
1027
+ const response = client.text(['api', `repos/${repository(context)}/labels/${encodeURIComponent(name)}`, '-X', 'DELETE'], {
1028
+ cwd: context.workingDirectory,
1029
+ method: 'DELETE'
1030
+ });
1031
+ if (!response.ok)
1032
+ return partialFailure(response, labelReconciliation(created, updated, removed, skipped));
1033
+ removed.push(name);
1034
+ }
1035
+ }
1036
+ return {
1037
+ ok: true,
1038
+ value: {
1039
+ changed: created.length > 0 || updated.length > 0 || removed.length > 0,
1040
+ created,
1041
+ updated,
1042
+ removed,
1043
+ skipped
1044
+ }
1045
+ };
1046
+ },
1047
+ async reconcileMilestones({ context, desired }) {
1048
+ const listed = client.json(['api', '--paginate', '--slurp', `repos/${repository(context)}/milestones?state=all&per_page=100`], { cwd: context.workingDirectory });
1049
+ if (!listed.ok)
1050
+ return listed;
1051
+ if (!Array.isArray(listed.value))
1052
+ return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned an invalid milestone list');
1053
+ const values = Array.isArray(listed.value)
1054
+ ? listed.value.flatMap((entry) => Array.isArray(entry) ? entry : [entry])
1055
+ : [];
1056
+ if (values.some((entry) => !entry || typeof entry.title !== 'string' || !entry.title)) {
1057
+ return invalid('MILESTONE_RESPONSE_INVALID', 'The platform returned a milestone without a valid title');
1058
+ }
1059
+ const existing = new Set(values.map((entry) => String(entry.title)));
1060
+ const created = [];
1061
+ const skipped = [];
1062
+ for (const milestone of desired) {
1063
+ if (existing.has(milestone.title)) {
1064
+ skipped.push(milestone.title);
1065
+ continue;
1066
+ }
1067
+ const response = client.json(['api', `repos/${repository(context)}/milestones`, '-X', 'POST', '--input', '-'], {
1068
+ cwd: context.workingDirectory,
1069
+ method: 'POST',
1070
+ input: JSON.stringify({ title: milestone.title, description: milestone.description, state: milestone.state })
1071
+ });
1072
+ if (!response.ok)
1073
+ return partialFailure(response, milestoneInitialization(created, skipped));
1074
+ existing.add(milestone.title);
1075
+ created.push(milestone.title);
1076
+ }
1077
+ return { ok: true, value: { changed: created.length > 0, created, skipped } };
1078
+ }
1079
+ };
858
1080
  const verification = {
859
1081
  async fetchRemoteFacts(input) {
860
1082
  const issue = input.issue && issues.inspect
861
1083
  ? await issues.inspect({ context: input.context, target: input.issue })
862
1084
  : { ok: true, value: null };
863
1085
  if (!issue.ok)
864
- return issue;
1086
+ return { ok: false, error: issue.error };
865
1087
  const commentFacts = input.includeComments && input.issue && comments.list
866
1088
  ? await comments.list({ context: input.context, parent: input.issue })
867
1089
  : { ok: true, value: [] };
868
1090
  if (!commentFacts.ok)
869
- return commentFacts;
1091
+ return { ok: false, error: commentFacts.error };
870
1092
  const changeRequest = input.changeRequest && changeRequests.inspect
871
1093
  ? await changeRequests.inspect({ context: input.context, target: input.changeRequest })
872
1094
  : { ok: true, value: null };
873
1095
  if (!changeRequest.ok)
874
- return changeRequest;
1096
+ return { ok: false, error: changeRequest.error };
875
1097
  return {
876
1098
  ok: true,
877
1099
  value: {
@@ -884,7 +1106,7 @@ function createGitHubOperations(client) {
884
1106
  };
885
1107
  }
886
1108
  };
887
- return { issues, comments, changeRequests, checks, reviews, releases, verification };
1109
+ return { issues, comments, changeRequests, checks, reviews, releases, securityAlerts, repositoryMetadata, verification };
888
1110
  }
889
1111
  function createGitHubProvider(input, client = createGitHubClient()) {
890
1112
  return {