@fitlab-ai/agent-infra 0.9.0 → 0.9.2

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 (327) hide show
  1. package/README.md +22 -5
  2. package/README.zh-CN.md +21 -5
  3. package/bin/cli.ts +12 -0
  4. package/dist/bin/cli.js +14 -0
  5. package/dist/bin/internal-cli.js +20 -0
  6. package/dist/lib/agent-client.js +163 -0
  7. package/dist/lib/agent-clients/adapter.js +294 -0
  8. package/dist/lib/agent-clients/adapters/claude-code.js +62 -0
  9. package/dist/lib/agent-clients/adapters/codex-sandbox.js +210 -0
  10. package/dist/lib/agent-clients/adapters/codex.js +54 -0
  11. package/dist/lib/agent-clients/adapters/gemini-cli.js +64 -0
  12. package/dist/lib/agent-clients/adapters/index.js +20 -0
  13. package/dist/lib/agent-clients/adapters/opencode.js +64 -0
  14. package/dist/lib/agent-clients/config.js +177 -0
  15. package/dist/lib/agent-clients/custom-tuis.js +99 -0
  16. package/dist/lib/agent-clients/invocation.js +9 -0
  17. package/dist/lib/agent-clients/next-steps.js +38 -0
  18. package/dist/lib/agent-clients/project-assets.js +45 -0
  19. package/dist/lib/agent-clients/reconcile.js +235 -0
  20. package/dist/lib/agent-clients/registry.js +72 -0
  21. package/dist/lib/agent-clients/schema.js +57 -0
  22. package/dist/lib/agent-clients/types.js +29 -0
  23. package/dist/lib/builtin-tuis.js +9 -14
  24. package/dist/lib/defaults.json +85 -73
  25. package/dist/lib/git/review-snapshot.js +25 -10
  26. package/dist/lib/git/reviewed-commit-equivalence.js +110 -0
  27. package/dist/lib/init.js +47 -91
  28. package/dist/lib/internal/agent-client.js +117 -0
  29. package/dist/lib/internal/git-workflow.js +1 -1
  30. package/dist/lib/internal/platform-release-notes.js +53 -0
  31. package/dist/lib/internal/release-workflow.js +175 -17
  32. package/dist/lib/internal/task-orchestration.js +151 -0
  33. package/dist/lib/internal/task-review.js +65 -0
  34. package/dist/lib/merge.js +2 -1
  35. package/dist/lib/platform/adapters.js +38 -1
  36. package/dist/lib/platform/change-request-git-evidence.js +113 -0
  37. package/dist/lib/platform/github-release-notes.js +96 -0
  38. package/dist/lib/platform/issues.js +4 -2
  39. package/dist/lib/platform/merged-pr-equivalence.js +84 -0
  40. package/dist/lib/platform/pr-checks.js +43 -15
  41. package/dist/lib/platform/pull-requests.js +113 -7
  42. package/dist/lib/platform/release-notes.js +143 -0
  43. package/dist/lib/platform/releases.js +1 -1
  44. package/dist/lib/platform/verification-required.js +31 -9
  45. package/dist/lib/prompt.js +15 -3
  46. package/dist/lib/release/channels.js +4 -1
  47. package/dist/lib/release/workflow.js +4 -2
  48. package/dist/lib/remove-dir.js +25 -0
  49. package/dist/lib/run/tui.js +8 -2
  50. package/dist/lib/sandbox/agent-client-reconciler.js +234 -0
  51. package/dist/lib/sandbox/build-proxy.js +63 -0
  52. package/dist/lib/sandbox/clipboard/linux.js +2 -1
  53. package/dist/lib/sandbox/commands/create.js +133 -189
  54. package/dist/lib/sandbox/commands/enter.js +17 -1
  55. package/dist/lib/sandbox/commands/prune.js +2 -2
  56. package/dist/lib/sandbox/commands/rebuild.js +24 -7
  57. package/dist/lib/sandbox/commands/rm.js +3 -2
  58. package/dist/lib/sandbox/config.js +21 -4
  59. package/dist/lib/sandbox/constants.js +3 -0
  60. package/dist/lib/sandbox/dockerfile.js +2 -1
  61. package/dist/lib/sandbox/image-build.js +2 -1
  62. package/dist/lib/sandbox/managed-fs.js +10 -5
  63. package/dist/lib/sandbox/recovery.js +52 -36
  64. package/dist/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
  65. package/dist/lib/sandbox/runtimes/base.dockerfile +8 -1
  66. package/dist/lib/sandbox/runtimes/java17.dockerfile +8 -1
  67. package/dist/lib/sandbox/runtimes/java21.dockerfile +8 -1
  68. package/dist/lib/sandbox/runtimes/node20.dockerfile +8 -1
  69. package/dist/lib/sandbox/runtimes/node22.dockerfile +8 -1
  70. package/dist/lib/sandbox/runtimes/python3.dockerfile +8 -1
  71. package/dist/lib/sandbox/shell.js +3 -2
  72. package/dist/lib/sandbox/tool-types.js +8 -0
  73. package/dist/lib/sandbox/tools.js +2 -126
  74. package/dist/lib/task/artifact-lifecycle.js +1 -49
  75. package/dist/lib/task/commands/decisions.js +50 -20
  76. package/dist/lib/task/commands/issue-body.js +10 -5
  77. package/dist/lib/task/delegation-receipts.js +107 -0
  78. package/dist/lib/task/events.js +101 -2
  79. package/dist/lib/task/issue-form.js +2 -0
  80. package/dist/lib/task/orchestration.js +420 -0
  81. package/dist/lib/task/review-artifacts.js +143 -59
  82. package/dist/lib/task/review-finalization.js +166 -0
  83. package/dist/lib/task/review-fingerprint.js +13 -0
  84. package/dist/lib/task/verification-checks.js +2 -1
  85. package/dist/lib/task/verification-engine.js +168 -23
  86. package/dist/lib/task/verification-review.js +1 -1
  87. package/dist/lib/task/verification.js +4 -2
  88. package/dist/lib/task/workspace-snapshot.js +34 -0
  89. package/dist/lib/update.js +42 -161
  90. package/lib/agent-client.ts +214 -0
  91. package/lib/agent-clients/adapter.ts +461 -0
  92. package/lib/agent-clients/adapters/claude-code.ts +70 -0
  93. package/lib/agent-clients/adapters/codex-sandbox.ts +245 -0
  94. package/lib/agent-clients/adapters/codex.ts +58 -0
  95. package/lib/agent-clients/adapters/gemini-cli.ts +65 -0
  96. package/lib/agent-clients/adapters/index.ts +27 -0
  97. package/lib/agent-clients/adapters/opencode.ts +66 -0
  98. package/lib/agent-clients/config.ts +278 -0
  99. package/lib/agent-clients/custom-tuis.ts +149 -0
  100. package/lib/agent-clients/invocation.ts +19 -0
  101. package/lib/agent-clients/next-steps.ts +72 -0
  102. package/lib/agent-clients/project-assets.ts +96 -0
  103. package/lib/agent-clients/reconcile.ts +324 -0
  104. package/lib/agent-clients/registry.ts +144 -0
  105. package/lib/agent-clients/schema.ts +62 -0
  106. package/lib/agent-clients/types.ts +78 -0
  107. package/lib/benchmark/schemas/v1.0.0/case-manifest.schema.json +120 -0
  108. package/lib/benchmark/schemas/v1.0.0/common.schema.json +109 -0
  109. package/lib/benchmark/schemas/v1.0.0/grader-result.schema.json +160 -0
  110. package/lib/benchmark/schemas/v1.0.0/run-manifest.schema.json +122 -0
  111. package/lib/benchmark/schemas/v1.0.0/subject.schema.json +227 -0
  112. package/lib/builtin-tuis.ts +16 -15
  113. package/lib/defaults.json +24 -12
  114. package/lib/git/review-snapshot.ts +39 -9
  115. package/lib/git/reviewed-commit-equivalence.ts +135 -0
  116. package/lib/init.ts +53 -121
  117. package/lib/internal/agent-client.ts +131 -0
  118. package/lib/internal/git-workflow.ts +1 -1
  119. package/lib/internal/platform-release-notes.ts +55 -0
  120. package/lib/internal/release-workflow.ts +172 -18
  121. package/lib/internal/task-orchestration.ts +132 -0
  122. package/lib/internal/task-review.ts +65 -0
  123. package/lib/merge.ts +2 -1
  124. package/lib/platform/adapters.ts +142 -3
  125. package/lib/platform/change-request-git-evidence.ts +159 -0
  126. package/lib/platform/github-release-notes.ts +132 -0
  127. package/lib/platform/issues.ts +6 -4
  128. package/lib/platform/merged-pr-equivalence.ts +107 -0
  129. package/lib/platform/pr-checks.ts +57 -28
  130. package/lib/platform/pull-requests.ts +140 -25
  131. package/lib/platform/release-notes.ts +167 -0
  132. package/lib/platform/releases.ts +1 -1
  133. package/lib/platform/verification-required.ts +37 -9
  134. package/lib/prompt.ts +16 -3
  135. package/lib/release/channels.ts +4 -1
  136. package/lib/release/workflow.ts +4 -3
  137. package/lib/remove-dir.ts +28 -0
  138. package/lib/run/tui.ts +9 -1
  139. package/lib/sandbox/agent-client-reconciler.ts +378 -0
  140. package/lib/sandbox/build-proxy.ts +94 -0
  141. package/lib/sandbox/clipboard/linux.ts +2 -1
  142. package/lib/sandbox/commands/create.ts +188 -203
  143. package/lib/sandbox/commands/enter.ts +23 -1
  144. package/lib/sandbox/commands/prune.ts +2 -2
  145. package/lib/sandbox/commands/rebuild.ts +29 -7
  146. package/lib/sandbox/commands/rm.ts +3 -2
  147. package/lib/sandbox/config.ts +31 -4
  148. package/lib/sandbox/constants.ts +6 -0
  149. package/lib/sandbox/dockerfile.ts +2 -1
  150. package/lib/sandbox/image-build.ts +4 -1
  151. package/lib/sandbox/managed-fs.ts +18 -5
  152. package/lib/sandbox/recovery.ts +98 -67
  153. package/lib/sandbox/runtimes/ai-tools.dockerfile +24 -3
  154. package/lib/sandbox/runtimes/base.dockerfile +8 -1
  155. package/lib/sandbox/runtimes/java17.dockerfile +8 -1
  156. package/lib/sandbox/runtimes/java21.dockerfile +8 -1
  157. package/lib/sandbox/runtimes/node20.dockerfile +8 -1
  158. package/lib/sandbox/runtimes/node22.dockerfile +8 -1
  159. package/lib/sandbox/runtimes/python3.dockerfile +8 -1
  160. package/lib/sandbox/shell.ts +4 -2
  161. package/lib/sandbox/tool-types.ts +143 -0
  162. package/lib/sandbox/tools.ts +5 -157
  163. package/lib/task/artifact-lifecycle.ts +1 -38
  164. package/lib/task/commands/decisions.ts +53 -20
  165. package/lib/task/commands/issue-body.ts +10 -5
  166. package/lib/task/delegation-receipts.ts +170 -0
  167. package/lib/task/events.ts +111 -3
  168. package/lib/task/issue-form.ts +4 -0
  169. package/lib/task/orchestration.ts +543 -0
  170. package/lib/task/review-artifacts.ts +201 -69
  171. package/lib/task/review-finalization.ts +275 -0
  172. package/lib/task/review-fingerprint.ts +15 -1
  173. package/lib/task/verification-checks.ts +2 -1
  174. package/lib/task/verification-engine.ts +190 -25
  175. package/lib/task/verification-review.ts +2 -0
  176. package/lib/task/verification.ts +6 -3
  177. package/lib/task/workspace-snapshot.ts +36 -0
  178. package/lib/update.ts +48 -184
  179. package/package.json +2 -2
  180. package/templates/.agents/README.en.md +21 -20
  181. package/templates/.agents/README.zh-CN.md +21 -20
  182. package/templates/.agents/hooks/lifecycle-delegation.js +64 -0
  183. package/templates/.agents/rules/README.en.md +2 -0
  184. package/templates/.agents/rules/README.zh-CN.md +2 -0
  185. package/templates/.agents/rules/commit-and-pr.en.md +1 -0
  186. package/templates/.agents/rules/commit-and-pr.zh-CN.md +1 -0
  187. package/templates/.agents/rules/human-decision-context.en.md +14 -12
  188. package/templates/.agents/rules/human-decision-context.zh-CN.md +14 -12
  189. package/templates/.agents/rules/lifecycle-orchestration.en.md +21 -0
  190. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +21 -0
  191. package/templates/.agents/rules/next-step-output.en.md +16 -0
  192. package/templates/.agents/rules/next-step-output.zh-CN.md +16 -0
  193. package/templates/.agents/rules/no-mid-flow-questions.en.md +2 -0
  194. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +2 -0
  195. package/templates/.agents/rules/release-commands.en.md +2 -2
  196. package/templates/.agents/rules/release-commands.github.en.md +15 -39
  197. package/templates/.agents/rules/release-commands.github.zh-CN.md +14 -38
  198. package/templates/.agents/rules/release-commands.zh-CN.md +2 -2
  199. package/templates/.agents/rules/review-handshake.en.md +4 -3
  200. package/templates/.agents/rules/review-handshake.zh-CN.md +4 -3
  201. package/templates/.agents/rules/review-method.en.md +113 -0
  202. package/templates/.agents/rules/review-method.zh-CN.md +98 -0
  203. package/templates/.agents/rules/testing-discipline.en.md +20 -2
  204. package/templates/.agents/rules/testing-discipline.zh-CN.md +20 -2
  205. package/templates/.agents/skills/analyze-task/SKILL.en.md +9 -6
  206. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +9 -6
  207. package/templates/.agents/skills/block-task/SKILL.en.md +4 -4
  208. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +4 -4
  209. package/templates/.agents/skills/cancel-task/SKILL.en.md +4 -4
  210. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +5 -5
  211. package/templates/.agents/skills/check-task/SKILL.en.md +16 -16
  212. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -16
  213. package/templates/.agents/skills/close-codescan/SKILL.en.md +4 -4
  214. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +4 -4
  215. package/templates/.agents/skills/close-dependabot/SKILL.en.md +4 -4
  216. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +4 -4
  217. package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
  218. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +2 -2
  219. package/templates/.agents/skills/code-task/reference/fix-mode.en.md +14 -16
  220. package/templates/.agents/skills/code-task/reference/fix-mode.zh-CN.md +14 -16
  221. package/templates/.agents/skills/code-task/reference/output-template.en.md +3 -3
  222. package/templates/.agents/skills/code-task/reference/output-template.zh-CN.md +3 -3
  223. package/templates/.agents/skills/commit/SKILL.en.md +11 -1
  224. package/templates/.agents/skills/commit/SKILL.zh-CN.md +11 -1
  225. package/templates/.agents/skills/commit/reference/task-status-update.en.md +24 -28
  226. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +24 -28
  227. package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
  228. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
  229. package/templates/.agents/skills/complete-task/config/verify.en.json +0 -1
  230. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +0 -1
  231. package/templates/.agents/skills/create-pr/SKILL.en.md +10 -10
  232. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +10 -10
  233. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +3 -3
  234. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +3 -3
  235. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -38
  236. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +16 -37
  237. package/templates/.agents/skills/create-task/SKILL.en.md +15 -11
  238. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +15 -11
  239. package/templates/.agents/skills/create-task/reference/context-capture.en.md +29 -0
  240. package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +29 -0
  241. package/templates/.agents/skills/import-codescan/SKILL.en.md +5 -5
  242. package/templates/.agents/skills/import-codescan/SKILL.zh-CN.md +5 -5
  243. package/templates/.agents/skills/import-dependabot/SKILL.en.md +5 -5
  244. package/templates/.agents/skills/import-dependabot/SKILL.zh-CN.md +5 -5
  245. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -5
  246. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -5
  247. package/templates/.agents/skills/init-labels/SKILL.en.md +4 -4
  248. package/templates/.agents/skills/init-labels/SKILL.zh-CN.md +4 -4
  249. package/templates/.agents/skills/init-milestones/SKILL.en.md +4 -4
  250. package/templates/.agents/skills/init-milestones/SKILL.zh-CN.md +4 -4
  251. package/templates/.agents/skills/plan-task/SKILL.en.md +5 -5
  252. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -5
  253. package/templates/.agents/skills/refine-title/SKILL.en.md +1 -1
  254. package/templates/.agents/skills/refine-title/SKILL.zh-CN.md +1 -1
  255. package/templates/.agents/skills/release/SKILL.en.md +1 -1
  256. package/templates/.agents/skills/review-analysis/SKILL.en.md +13 -2
  257. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +14 -3
  258. package/templates/.agents/skills/review-analysis/config/verify.en.json +6 -0
  259. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +6 -0
  260. package/templates/.agents/skills/review-analysis/reference/output-templates.en.md +13 -15
  261. package/templates/.agents/skills/review-analysis/reference/output-templates.zh-CN.md +13 -15
  262. package/templates/.agents/skills/review-analysis/reference/report-template.en.md +51 -5
  263. package/templates/.agents/skills/review-analysis/reference/report-template.zh-CN.md +52 -6
  264. package/templates/.agents/skills/review-analysis/reference/review-criteria.en.md +25 -22
  265. package/templates/.agents/skills/review-analysis/reference/review-criteria.zh-CN.md +25 -22
  266. package/templates/.agents/skills/review-code/SKILL.en.md +28 -8
  267. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +28 -8
  268. package/templates/.agents/skills/review-code/config/verify.en.json +7 -0
  269. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +7 -0
  270. package/templates/.agents/skills/review-code/reference/concurrency-risks.en.md +25 -0
  271. package/templates/.agents/skills/review-code/reference/concurrency-risks.zh-CN.md +25 -0
  272. package/templates/.agents/skills/review-code/reference/cross-platform-risks.en.md +27 -0
  273. package/templates/.agents/skills/review-code/reference/cross-platform-risks.zh-CN.md +27 -0
  274. package/templates/.agents/skills/review-code/reference/documentation-antipatterns.en.md +13 -0
  275. package/templates/.agents/skills/review-code/reference/documentation-antipatterns.zh-CN.md +13 -0
  276. package/templates/.agents/skills/review-code/reference/migration-risks.en.md +25 -0
  277. package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +25 -0
  278. package/templates/.agents/skills/review-code/reference/output-templates.en.md +22 -24
  279. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +22 -24
  280. package/templates/.agents/skills/review-code/reference/report-template.en.md +54 -7
  281. package/templates/.agents/skills/review-code/reference/report-template.zh-CN.md +54 -7
  282. package/templates/.agents/skills/review-code/reference/review-criteria.en.md +29 -24
  283. package/templates/.agents/skills/review-code/reference/review-criteria.zh-CN.md +29 -24
  284. package/templates/.agents/skills/review-code/reference/security-risks.en.md +25 -0
  285. package/templates/.agents/skills/review-code/reference/security-risks.zh-CN.md +25 -0
  286. package/templates/.agents/skills/review-plan/SKILL.en.md +13 -2
  287. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +14 -3
  288. package/templates/.agents/skills/review-plan/config/verify.en.json +6 -0
  289. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +6 -0
  290. package/templates/.agents/skills/review-plan/reference/output-templates.en.md +13 -15
  291. package/templates/.agents/skills/review-plan/reference/output-templates.zh-CN.md +13 -15
  292. package/templates/.agents/skills/review-plan/reference/report-template.en.md +61 -5
  293. package/templates/.agents/skills/review-plan/reference/report-template.zh-CN.md +61 -5
  294. package/templates/.agents/skills/review-plan/reference/review-criteria.en.md +21 -24
  295. package/templates/.agents/skills/review-plan/reference/review-criteria.zh-CN.md +21 -24
  296. package/templates/.agents/skills/run-task/SKILL.en.md +22 -0
  297. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +22 -0
  298. package/templates/.agents/skills/run-task/config/verify.en.json +9 -0
  299. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +9 -0
  300. package/templates/.agents/skills/test/SKILL.en.md +4 -4
  301. package/templates/.agents/skills/test/SKILL.zh-CN.md +4 -4
  302. package/templates/.agents/skills/test-integration/SKILL.en.md +4 -4
  303. package/templates/.agents/skills/test-integration/SKILL.zh-CN.md +4 -4
  304. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +5 -5
  305. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +5 -5
  306. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +647 -203
  307. package/templates/.agents/skills/upgrade-dependency/SKILL.en.md +4 -4
  308. package/templates/.agents/skills/upgrade-dependency/SKILL.zh-CN.md +4 -4
  309. package/templates/.agents/skills/watch-pr/SKILL.en.md +8 -8
  310. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +8 -8
  311. package/templates/.agents/templates/task.en.md +18 -0
  312. package/templates/.agents/templates/task.zh-CN.md +18 -0
  313. package/templates/.claude/agents/agent-infra-lifecycle-executor.en.md +6 -0
  314. package/templates/.claude/agents/agent-infra-lifecycle-executor.zh-CN.md +6 -0
  315. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.en.md +6 -0
  316. package/templates/.claude/agents/agent-infra-lifecycle-reviewer.zh-CN.md +6 -0
  317. package/templates/.claude/commands/run-task.en.md +8 -0
  318. package/templates/.claude/commands/run-task.zh-CN.md +8 -0
  319. package/templates/.claude/settings.json +24 -0
  320. package/templates/.codex/agents/agent-infra-lifecycle-executor.en.toml +3 -0
  321. package/templates/.codex/agents/agent-infra-lifecycle-executor.zh-CN.toml +3 -0
  322. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.en.toml +3 -0
  323. package/templates/.codex/agents/agent-infra-lifecycle-reviewer.zh-CN.toml +3 -0
  324. package/templates/.gemini/commands/_project_/run-task.en.toml +8 -0
  325. package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +8 -0
  326. package/templates/.opencode/commands/run-task.en.md +11 -0
  327. package/templates/.opencode/commands/run-task.zh-CN.md +11 -0
@@ -1,8 +1,10 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { execFileSync } from "node:child_process";
4
+ import { hasPlatformCapability } from "./adapters.js";
4
5
  import { inspectRequiredChecks } from "./pr-checks.js";
5
6
  import { resolvePlatformContext } from "./context.js";
7
+ import { resolveReviewedHeadRelation } from "./merged-pr-equivalence.js";
6
8
  const CHECK_TYPE = "required-checks";
7
9
  const SHA_PATTERN = /^[0-9a-f]{7,40}$/i;
8
10
  function validPrNumber(value) {
@@ -44,13 +46,27 @@ export function evaluateRequiredChecks(context, shared) {
44
46
  if (inspection.status === "failed") {
45
47
  return shared.failResult(CHECK_TYPE, inspection.error?.message || "Required checks are unavailable", "check_failed");
46
48
  }
47
- const prHead = inspection.pullRequest?.headSha;
48
- if (!prHead || localHead !== reviewedHead || localHead !== prHead) {
49
- return shared.failResult(CHECK_TYPE, "Local HEAD, last reviewed commit, and PR head must match", "check_failed");
49
+ const prHead = inspection.pullRequest?.head?.sha || inspection.pullRequest?.headSha;
50
+ const relation = context.relation || (context.gitRoot && inspection.pullRequest?.head
51
+ ? resolveReviewedHeadRelation({
52
+ gitRoot: context.gitRoot,
53
+ comparisonHead: localHead,
54
+ lastReviewedCommit: reviewedHead,
55
+ pullRequest: inspection.pullRequest
56
+ })
57
+ : localHead === reviewedHead && localHead === prHead
58
+ ? { status: "strict" }
59
+ : { status: "failed" });
60
+ if (relation.status !== "strict" && relation.status !== "merged-equivalent") {
61
+ const message = relation.message || "Local HEAD, last reviewed commit, and PR head must match";
62
+ return relation.status === "blocked"
63
+ ? shared.blockedResult(CHECK_TYPE, message, "dependency_error")
64
+ : shared.failResult(CHECK_TYPE, message, "check_failed");
50
65
  }
51
66
  const state = inspection.checks?.state;
52
67
  if (state === "passed" || state === "no-required") {
53
- return shared.passResult(CHECK_TYPE, `Required checks are ${state} for PR head ${prHead}`);
68
+ const suffix = relation.status === "merged-equivalent" ? " via verified squash merge equivalence" : "";
69
+ return shared.passResult(CHECK_TYPE, `Required checks are ${state} for PR head ${prHead}${suffix}`);
54
70
  }
55
71
  if (state === "pending") {
56
72
  return shared.blockedResult(CHECK_TYPE, inspection.error?.message || "Required checks are pending", "check_pending");
@@ -61,18 +77,24 @@ export function check({ taskDir }, shared) {
61
77
  const task = shared.loadTask(taskDir);
62
78
  if (!task.ok)
63
79
  return shared.failResult(CHECK_TYPE, task.message);
64
- const platform = resolvePlatformContext({ cwd: shared.repoRoot });
65
- if (platform.platform.type !== "github") {
66
- return shared.passResult(CHECK_TYPE, "Skipped: this code platform does not provide required checks");
67
- }
68
80
  const prFlow = readPrFlow(shared.repoRoot);
69
81
  if (prFlow === "disabled" || task.metadata.pr_status === "skipped" || !validPrNumber(task.metadata.pr_number)) {
70
82
  return evaluateRequiredChecks({ metadata: task.metadata, localHead: null, inspection: null, prFlow }, shared);
71
83
  }
84
+ const platform = resolvePlatformContext({ cwd: shared.repoRoot });
85
+ if (!hasPlatformCapability(platform.platform.type, "required-checks")) {
86
+ return shared.blockedResult(CHECK_TYPE, `Platform '${platform.platform.type || "none"}' does not provide required-checks inspection`, "dependency_error");
87
+ }
72
88
  const localHead = readHead(shared.repoRoot);
73
89
  if (!localHead)
74
90
  return evaluateRequiredChecks({ metadata: task.metadata, localHead, inspection: null, prFlow }, shared);
75
91
  const inspection = inspectRequiredChecks(task.metadata.id, { cwd: shared.repoRoot });
76
- return evaluateRequiredChecks({ metadata: task.metadata, localHead, inspection, prFlow }, shared);
92
+ return evaluateRequiredChecks({
93
+ metadata: task.metadata,
94
+ localHead,
95
+ inspection,
96
+ prFlow,
97
+ gitRoot: shared.repoRoot
98
+ }, shared);
77
99
  }
78
100
  //# sourceMappingURL=verification-required.js.map
@@ -74,18 +74,30 @@ async function select(question, choices, defaultValue) {
74
74
  }
75
75
  return trimmed;
76
76
  }
77
- async function multiSelect(question, choices) {
77
+ async function multiSelect(question, choices, defaultIds = choices.map((choice) => choice.id)) {
78
+ const choiceIds = new Set(choices.map((choice) => choice.id));
79
+ if (defaultIds.some((id) => !choiceIds.has(id))) {
80
+ throw new Error('Default selection contains an unknown id');
81
+ }
82
+ const normalizedDefaults = choices
83
+ .map((choice) => choice.id)
84
+ .filter((id) => defaultIds.includes(id));
78
85
  process.stdout.write(` ${question}:\n`);
79
86
  const idWidth = Math.max(...choices.map((c) => c.id.length));
80
87
  choices.forEach((c, i) => {
81
88
  process.stdout.write(` ${i + 1}) ${c.id.padEnd(idWidth)} (${c.label})\n`);
82
89
  });
83
- ask('Enter comma-separated numbers or ids to keep, or "none" to select nothing [default: all]: ');
90
+ const defaultLabel = normalizedDefaults.length === choices.length
91
+ ? 'all'
92
+ : normalizedDefaults.length === 0
93
+ ? 'none'
94
+ : normalizedDefaults.join(',');
95
+ ask(`Enter comma-separated numbers or ids to keep, or "none" to select nothing [default: ${defaultLabel}]: `);
84
96
  setupInterface();
85
97
  const line = await nextLine();
86
98
  // Strictly distinguish bare Enter (null/empty string) from whitespace input.
87
99
  if (line === null || line === '')
88
- return choices.map((c) => c.id);
100
+ return normalizedDefaults;
89
101
  // Explicit empty selection: "none" means deliberately zero built-in choices.
90
102
  if (line.trim().toLowerCase() === 'none')
91
103
  return [];
@@ -21,7 +21,10 @@ async function inspectHomebrewChannel(url, version, fetcher = fetch) {
21
21
  return { status: 'blocked', published: null, version, error: { code: 'HOMEBREW_UNAVAILABLE', message: `formula endpoint returned ${response.status}` } };
22
22
  const formula = await response.text();
23
23
  const escaped = version.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24
- return { status: 'no-op', published: new RegExp(`(?:version\\s+["']${escaped}["']|/v?${escaped}\\.)`).test(formula), version, error: null };
24
+ const formulaUrl = /^\s*url\s+["']([^"']+)["']\s*$/m.exec(formula)?.[1] ?? '';
25
+ const npmTarball = new RegExp(`^https://registry\\.npmjs\\.org/.+/-/[^/]+-${escaped}\\.tgz$`).test(formulaUrl);
26
+ const bottle = /^\s*bottle do\s*$/m.test(formula);
27
+ return { status: 'no-op', published: npmTarball && bottle, version, error: null };
25
28
  }
26
29
  catch (error) {
27
30
  return { status: 'blocked', published: null, version, error: { code: 'HOMEBREW_UNAVAILABLE', message: error instanceof Error ? error.message : String(error) } };
@@ -1,5 +1,5 @@
1
1
  function deriveReleasePhase(facts) {
2
- if (!facts.localTag)
2
+ if (!facts.localTag && !facts.localTagAncestor)
3
3
  return 'unprepared';
4
4
  if (!facts.remoteBranch && !facts.remoteTag)
5
5
  return 'prepared';
@@ -18,8 +18,10 @@ async function runReleaseAction(input) {
18
18
  const before = releaseSnapshot(input.version, await input.inspect());
19
19
  if (input.action === 'inspect')
20
20
  return { status: 'no-op', changed: false, before, snapshot: before, error: null };
21
+ if (before.facts.localTagConflict)
22
+ return { status: 'failed', changed: false, before, snapshot: before, error: { code: 'GIT_TAG_CONFLICT', message: `Tag ${before.tag} is not reachable from HEAD` } };
21
23
  const allowed = input.action === 'prepare' ? before.phase === 'unprepared'
22
- : input.action === 'publish' ? ['prepared', 'partially-published'].includes(before.phase)
24
+ : input.action === 'publish' ? before.facts.localTag && ['prepared', 'partially-published'].includes(before.phase)
23
25
  : ['published', 'post-pending'].includes(before.phase);
24
26
  if (!allowed)
25
27
  return { status: before.phase === 'complete' ? 'no-op' : 'failed', changed: false, before, snapshot: before, error: before.phase === 'complete' ? null : { code: 'RELEASE_PHASE_INVALID', message: `Cannot ${input.action} from ${before.phase}` } };
@@ -0,0 +1,25 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ export function removeDirRecursive(dir) {
4
+ if (!fs.existsSync(dir)) {
5
+ return;
6
+ }
7
+ const pending = [dir];
8
+ const directories = [];
9
+ while (pending.length > 0) {
10
+ const current = pending.pop();
11
+ const stat = fs.lstatSync(current);
12
+ if (!stat.isDirectory() || stat.isSymbolicLink()) {
13
+ fs.unlinkSync(current);
14
+ continue;
15
+ }
16
+ directories.push(current);
17
+ for (const entry of fs.readdirSync(current)) {
18
+ pending.push(path.join(current, entry));
19
+ }
20
+ }
21
+ for (const directory of directories.reverse()) {
22
+ fs.rmdirSync(directory);
23
+ }
24
+ }
25
+ //# sourceMappingURL=remove-dir.js.map
@@ -1,3 +1,5 @@
1
+ import { renderAgentClientInvocation } from '../agent-clients/invocation.js';
2
+ import { getAgentClientAdapter } from '../agent-clients/registry.js';
1
3
  const TUI_NAMES = new Set(['claude', 'codex', 'gemini', 'opencode']);
2
4
  function isTuiName(value) {
3
5
  return typeof value === 'string' && TUI_NAMES.has(value);
@@ -17,8 +19,12 @@ export function selectTui(skill, options) {
17
19
  }
18
20
  export function renderPrompt(params) {
19
21
  const suffix = [params.skill, ...params.args].join(' ').trim();
20
- if (params.tui === 'codex')
21
- return `$${suffix}`;
22
+ if (params.tui === 'codex') {
23
+ return renderAgentClientInvocation(getAgentClientAdapter('codex').invocation, {
24
+ skillName: params.skill,
25
+ args: params.args
26
+ });
27
+ }
22
28
  if (params.tui === 'gemini')
23
29
  return `/agent-infra:${suffix}`;
24
30
  return `/${suffix}`;
@@ -0,0 +1,234 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { execFile } from 'node:child_process';
3
+ import { isAgentClientId } from '../agent-clients/types.js';
4
+ import { listAgentClientAdapters, listInstalledAgentClientAdapters } from '../agent-clients/registry.js';
5
+ import { hostJoin } from './engines/wsl2-paths.js';
6
+ const DEFAULT_SANDBOX_HOOK_TIMEOUT_MS = 30_000;
7
+ function agentInfraTool(home) {
8
+ return {
9
+ id: 'agent-infra',
10
+ name: 'agent-infra CLI',
11
+ install: { type: 'npm', cmd: '@fitlab-ai/agent-infra@latest' },
12
+ sandboxBase: hostJoin(home, '.agent-infra', 'sandboxes', 'agent-infra'),
13
+ containerMount: '/home/devuser/.agent-infra-cli',
14
+ versionCmd: 'ai version --raw',
15
+ setupHint: 'Provides the ai and agent-infra CLI commands inside the sandbox.'
16
+ };
17
+ }
18
+ function compatAgentClientState(tools) {
19
+ return Object.fromEntries(listAgentClientAdapters().map((adapter) => [
20
+ adapter.id,
21
+ {
22
+ enabled: true,
23
+ installInSandbox: tools.includes(adapter.id)
24
+ }
25
+ ]));
26
+ }
27
+ function stableValue(value) {
28
+ if (Array.isArray(value)) {
29
+ return value.map(stableValue);
30
+ }
31
+ if (value && typeof value === 'object') {
32
+ return Object.fromEntries(Object.entries(value)
33
+ .sort(([left], [right]) => left.localeCompare(right))
34
+ .map(([key, nested]) => [key, stableValue(nested)]));
35
+ }
36
+ return value;
37
+ }
38
+ function runtimeToolProjection(tool) {
39
+ return stableValue({
40
+ id: tool.id,
41
+ install: tool.install,
42
+ containerMount: tool.containerMount,
43
+ versionCmd: tool.versionCmd,
44
+ envVars: tool.envVars ?? {},
45
+ hostPreSeedFiles: (tool.hostPreSeedFiles ?? []).map(({ sandboxName }) => ({ sandboxName })),
46
+ hostPreSeedDirs: (tool.hostPreSeedDirs ?? []).map(({ sandboxSubdir }) => ({ sandboxSubdir })),
47
+ pathRewriteFiles: tool.pathRewriteFiles ?? [],
48
+ hostLiveMounts: (tool.hostLiveMounts ?? []).map(({ containerSubpath }) => ({ containerSubpath })),
49
+ postSetupCmds: tool.postSetupCmds ?? [],
50
+ tmpfs: tool.tmpfs ?? null
51
+ });
52
+ }
53
+ function hash(value) {
54
+ return createHash('sha256').update(JSON.stringify(stableValue(value))).digest('hex');
55
+ }
56
+ function assertUniqueTools(tools) {
57
+ const seen = new Set();
58
+ for (const tool of tools) {
59
+ if (seen.has(tool.id)) {
60
+ throw new Error(`Duplicate sandbox tool id "${tool.id}"`);
61
+ }
62
+ seen.add(tool.id);
63
+ }
64
+ }
65
+ function hooksByPhase(adapters) {
66
+ const phases = [
67
+ 'prepare',
68
+ 'before-container-create',
69
+ 'after-container-start',
70
+ 'before-enter'
71
+ ];
72
+ return Object.freeze(Object.fromEntries(phases.map((phase) => [
73
+ phase,
74
+ Object.freeze(adapters.flatMap((adapter) => adapter.sandbox.hooks.filter((hook) => hook.phase === phase)))
75
+ ])));
76
+ }
77
+ function createSandboxCapabilityPlan(config) {
78
+ const state = config.agentClientState ?? compatAgentClientState(config.tools);
79
+ const selectedAgentClients = listInstalledAgentClientAdapters(state);
80
+ const context = { home: config.home, project: config.project };
81
+ const selectedTools = selectedAgentClients.map((adapter) => adapter.sandbox.createTool(context));
82
+ const allClientTools = listAgentClientAdapters().map((adapter) => adapter.sandbox.createTool(context));
83
+ const customById = new Map((config.customTools ?? []).map((tool) => [tool.id, tool]));
84
+ if (customById.size !== (config.customTools ?? []).length) {
85
+ throw new Error('Duplicate sandbox tool id in customTools');
86
+ }
87
+ for (const id of customById.keys()) {
88
+ if (id === 'agent-infra' || isAgentClientId(id)) {
89
+ throw new Error(`Custom sandbox tool id "${id}" collides with a built-in tool`);
90
+ }
91
+ }
92
+ const nonClientTools = [];
93
+ const selectedCustomTools = [];
94
+ for (const id of config.tools) {
95
+ if (isAgentClientId(id))
96
+ continue;
97
+ if (id === 'agent-infra') {
98
+ if (!nonClientTools.some((tool) => tool.id === id)) {
99
+ nonClientTools.push(agentInfraTool(config.home));
100
+ }
101
+ continue;
102
+ }
103
+ const custom = customById.get(id);
104
+ if (!custom) {
105
+ throw new Error(`Unknown sandbox tool: ${id}`);
106
+ }
107
+ selectedCustomTools.push(custom);
108
+ }
109
+ const tools = Object.freeze([...nonClientTools, ...selectedTools, ...selectedCustomTools]);
110
+ assertUniqueTools(tools);
111
+ const phaseHooks = hooksByPhase(selectedAgentClients);
112
+ const hookProjection = selectedAgentClients.flatMap((adapter) => adapter.sandbox.hooks.map((hook) => ({
113
+ adapterId: adapter.id,
114
+ id: hook.id,
115
+ phase: hook.phase,
116
+ timeoutMs: hook.timeoutMs ?? DEFAULT_SANDBOX_HOOK_TIMEOUT_MS
117
+ })));
118
+ const recoveryChecks = Object.freeze(selectedAgentClients.flatMap((adapter) => (adapter.sandbox.recoveryChecks ?? []).map((check) => Object.freeze({
119
+ adapterId: adapter.id,
120
+ check
121
+ }))));
122
+ const recoveryCheckProjection = Object.freeze(recoveryChecks.map(({ adapterId, check }) => Object.freeze({
123
+ adapterId,
124
+ id: check.id,
125
+ ...(check.when === undefined ? {} : { when: check.when }),
126
+ probe: check.probe,
127
+ finding: Object.freeze({
128
+ repairKind: check.finding.repairKind,
129
+ ...(check.finding.path === undefined ? {} : { path: check.finding.path })
130
+ }),
131
+ ...(check.repair === undefined ? {} : { repair: check.repair })
132
+ })));
133
+ const runtimeProjection = Object.freeze({
134
+ tools: Object.freeze(tools.map(runtimeToolProjection)),
135
+ selectedAgentClients: Object.freeze(selectedAgentClients.map((adapter) => adapter.id)),
136
+ hooks: Object.freeze(hookProjection),
137
+ recoveryChecks: recoveryCheckProjection
138
+ });
139
+ const cleanupInventory = Object.freeze([
140
+ agentInfraTool(config.home),
141
+ ...allClientTools,
142
+ ...customById.values()
143
+ ]);
144
+ assertUniqueTools(cleanupInventory);
145
+ return Object.freeze({
146
+ tools,
147
+ selectedAgentClients,
148
+ hooksByPhase: phaseHooks,
149
+ recoveryChecks,
150
+ aliases: Object.freeze(listAgentClientAdapters().flatMap((adapter) => adapter.sandbox.aliases)),
151
+ imageSignature: hash(tools.map(({ id, install }) => ({ id, install }))),
152
+ runtimeSignature: hash(runtimeProjection),
153
+ runtimeProjection,
154
+ cleanupInventory
155
+ });
156
+ }
157
+ function timeoutStatus(phase) {
158
+ if (phase === 'before-enter')
159
+ return 'warning';
160
+ return 'fatal';
161
+ }
162
+ async function runSandboxHooks({ hooks, phase, context, runCommand = async () => {
163
+ throw new Error('Sandbox hook command runner is unavailable');
164
+ }, scheduleTimeout = (callback, timeoutMs) => setTimeout(callback, timeoutMs), clearScheduledTimeout = (handle) => clearTimeout(handle) }) {
165
+ const results = [];
166
+ for (const hook of hooks) {
167
+ if (hook.phase !== phase)
168
+ continue;
169
+ const timeoutMs = hook.timeoutMs ?? DEFAULT_SANDBOX_HOOK_TIMEOUT_MS;
170
+ const controller = new AbortController();
171
+ let timedOut = false;
172
+ let timer;
173
+ const timeout = new Promise((resolve) => {
174
+ timer = scheduleTimeout(() => {
175
+ timedOut = true;
176
+ controller.abort();
177
+ resolve({
178
+ status: timeoutStatus(phase),
179
+ message: `Sandbox hook '${hook.id}' timed out after ${timeoutMs}ms.`
180
+ });
181
+ }, timeoutMs);
182
+ });
183
+ let result;
184
+ try {
185
+ const execution = Promise.resolve().then(() => hook.run({
186
+ ...context,
187
+ signal: controller.signal,
188
+ runCommand: (command) => runCommand(command, {
189
+ signal: controller.signal,
190
+ timeoutMs
191
+ })
192
+ }));
193
+ result = await Promise.race([execution, timeout]);
194
+ }
195
+ catch (error) {
196
+ result = {
197
+ status: timeoutStatus(phase),
198
+ message: error instanceof Error ? error.message : String(error)
199
+ };
200
+ }
201
+ finally {
202
+ clearScheduledTimeout(timer);
203
+ }
204
+ results.push({
205
+ hookId: hook.id,
206
+ phase,
207
+ status: result.status,
208
+ ...(result.message ? { message: result.message } : {})
209
+ });
210
+ if (timedOut || result.status === 'fatal' || result.status === 'hard-failure') {
211
+ break;
212
+ }
213
+ }
214
+ return results;
215
+ }
216
+ function runBoundedSandboxHookCommand(command, options) {
217
+ return new Promise((resolve, reject) => {
218
+ execFile(command.command, [...(command.args ?? [])], {
219
+ cwd: command.cwd,
220
+ env: command.env,
221
+ encoding: 'utf8',
222
+ signal: options.signal,
223
+ timeout: options.timeoutMs
224
+ }, (error, stdout) => {
225
+ if (error) {
226
+ reject(error);
227
+ return;
228
+ }
229
+ resolve({ stdout: stdout.trim() });
230
+ });
231
+ });
232
+ }
233
+ export { DEFAULT_SANDBOX_HOOK_TIMEOUT_MS, createSandboxCapabilityPlan, runBoundedSandboxHookCommand, runSandboxHooks };
234
+ //# sourceMappingURL=agent-client-reconciler.js.map
@@ -0,0 +1,63 @@
1
+ import semver from 'semver';
2
+ import { engineDisplayName } from './engine.js';
3
+ import { runSafeEngine } from './shell.js';
4
+ export const BUILD_PROXY_ENV_KEYS = ['HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY'];
5
+ export const MIN_BUILD_PROXY_DOCKER_VERSION = '20.10.0';
6
+ export const MIN_BUILD_PROXY_BUILDKIT_VERSION = '0.9.0';
7
+ export function prepareBuildProxy(enabled, hostEnv, engine) {
8
+ const env = { ...hostEnv };
9
+ if (!enabled) {
10
+ return { args: [], env, redactionValues: [] };
11
+ }
12
+ const entries = BUILD_PROXY_ENV_KEYS.flatMap((key) => {
13
+ const value = hostEnv[key]?.trim();
14
+ return value ? [[key, value]] : [];
15
+ });
16
+ if (entries.length === 0) {
17
+ throw new Error(`No non-empty build proxy variables are set. Configure one of: ${BUILD_PROXY_ENV_KEYS.join(', ')}.`);
18
+ }
19
+ for (const [key, value] of entries)
20
+ env[key] = value;
21
+ if (engine === 'wsl2') {
22
+ const existing = (env.WSLENV ?? '').split(':').filter(Boolean);
23
+ env.WSLENV = [...new Set([...existing, ...entries.map(([key]) => key)])].join(':');
24
+ }
25
+ return {
26
+ args: entries.flatMap(([key]) => ['--secret', `id=${key},env=${key}`]),
27
+ env,
28
+ redactionValues: entries.map(([, value]) => value)
29
+ };
30
+ }
31
+ function parsedVersion(raw) {
32
+ return semver.coerce(raw.trim())?.version ?? null;
33
+ }
34
+ export function assertBuildProxyCompatibility(engine, runSafeEngineFn = runSafeEngine) {
35
+ const dockerRaw = runSafeEngineFn(engine, 'docker', ['version', '--format', '{{.Server.Version}}']);
36
+ const dockerVersion = parsedVersion(dockerRaw);
37
+ if (!dockerVersion || !semver.gte(dockerVersion, MIN_BUILD_PROXY_DOCKER_VERSION)) {
38
+ throw new Error(`Build proxy requires Docker Engine ${MIN_BUILD_PROXY_DOCKER_VERSION} or newer; `
39
+ + `observed ${dockerVersion ?? 'an unparseable version'}.`);
40
+ }
41
+ const buildxRaw = runSafeEngineFn(engine, 'docker', ['buildx', 'inspect', '--bootstrap']);
42
+ const versions = [...buildxRaw.matchAll(/BuildKit(?:\s+version)?:\s*v?(\d+\.\d+\.\d+(?:[-+][^\s]+)?)/gi)]
43
+ .map((match) => parsedVersion(match[1] ?? ''))
44
+ .filter((version) => version !== null);
45
+ if (versions.length === 0) {
46
+ throw new Error(`Build proxy requires BuildKit ${MIN_BUILD_PROXY_BUILDKIT_VERSION} or newer, `
47
+ + 'but the active builder version could not be determined.');
48
+ }
49
+ const oldVersion = versions.find((version) => !semver.gte(version, MIN_BUILD_PROXY_BUILDKIT_VERSION));
50
+ if (oldVersion) {
51
+ throw new Error(`Build proxy observed BuildKit ${oldVersion}; version ${MIN_BUILD_PROXY_BUILDKIT_VERSION} or newer is required.`);
52
+ }
53
+ }
54
+ export function redactBuildProxyValues(text, values) {
55
+ return [...new Set(values.filter(Boolean))]
56
+ .sort((left, right) => right.length - left.length)
57
+ .reduce((result, value) => result.replaceAll(value, '[REDACTED_BUILD_PROXY]'), text);
58
+ }
59
+ export function buildProxyFailureHint(engine) {
60
+ return `Build-step proxy inheritance is enabled for ${engineDisplayName(engine)}. `
61
+ + 'Image pulls and Dockerfile FROM resolution use the Docker daemon or builder proxy configuration.';
62
+ }
63
+ //# sourceMappingURL=build-proxy.js.map
@@ -2,10 +2,11 @@ import { execFileSync } from 'node:child_process';
2
2
  import fs from 'node:fs';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
+ import { removeDirRecursive } from '../../remove-dir.js';
5
6
  const PROBE_TIMEOUT_MS = 2_000;
6
7
  const READ_IMAGE_TIMEOUT_MS = 5_000;
7
8
  const PNG_MAGIC = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
8
- export function createLinuxClipboardAdapter({ env = process.env, execFn = execFileSync, execToFileFn = execToFile, mkdtempFn = fs.mkdtempSync, readFileFn = fs.readFileSync, rmFn = fs.rmSync } = {}) {
9
+ export function createLinuxClipboardAdapter({ env = process.env, execFn = execFileSync, execToFileFn = execToFile, mkdtempFn = fs.mkdtempSync, readFileFn = fs.readFileSync, rmFn = removeDirRecursive } = {}) {
9
10
  return {
10
11
  available() {
11
12
  const backend = selectBackend(env);