@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
@@ -0,0 +1,110 @@
1
+ import { execFileSync, spawnSync } from "node:child_process";
2
+ const SHA_PATTERN = /^[0-9a-f]{40}$/i;
3
+ function git(cwd, args) {
4
+ return execFileSync("git", args, { cwd, encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
5
+ }
6
+ function commitExists(gitRoot, sha) {
7
+ try {
8
+ git(gitRoot, ["cat-file", "-e", `${sha}^{commit}`]);
9
+ return true;
10
+ }
11
+ catch {
12
+ return false;
13
+ }
14
+ }
15
+ function isAncestor(gitRoot, ancestor, descendant) {
16
+ const result = spawnSync("git", ["merge-base", "--is-ancestor", ancestor, descendant], {
17
+ cwd: gitRoot,
18
+ encoding: "utf8"
19
+ });
20
+ if (result.status === 0)
21
+ return true;
22
+ if (result.status === 1)
23
+ return false;
24
+ return null;
25
+ }
26
+ export function resolveLocalReviewedCommitRelation(input) {
27
+ const { gitRoot, localHead, lastReviewedCommit, rewrittenCommit, pathspecs } = input;
28
+ const shas = [localHead, lastReviewedCommit, rewrittenCommit];
29
+ if (shas.some((sha) => !SHA_PATTERN.test(sha) || !commitExists(gitRoot, sha))) {
30
+ return {
31
+ status: "blocked",
32
+ code: "LOCAL_REWRITE_OBJECT_MISSING",
33
+ message: "Required local rewrite Git objects are unavailable"
34
+ };
35
+ }
36
+ const ancestor = isAncestor(gitRoot, rewrittenCommit, localHead);
37
+ if (ancestor === false) {
38
+ return {
39
+ status: "failed",
40
+ code: "LOCAL_REWRITE_TOPOLOGY_INVALID",
41
+ message: "Local rewritten commit is not in the current HEAD history"
42
+ };
43
+ }
44
+ if (ancestor === null) {
45
+ return {
46
+ status: "blocked",
47
+ code: "LOCAL_REWRITE_GIT_EVIDENCE_UNAVAILABLE",
48
+ message: "Unable to verify local rewrite ancestry"
49
+ };
50
+ }
51
+ try {
52
+ const parents = git(gitRoot, ["rev-parse", `${rewrittenCommit}^@`])
53
+ .split(/\r?\n/)
54
+ .filter((line) => line.trim() !== "");
55
+ if (parents.length !== 1) {
56
+ return {
57
+ status: "failed",
58
+ code: "LOCAL_REWRITE_TOPOLOGY_INVALID",
59
+ message: "Local rewritten commit is not a single-parent commit"
60
+ };
61
+ }
62
+ const reviewedTree = git(gitRoot, ["rev-parse", `${lastReviewedCommit}^{tree}`]).trim();
63
+ const rewrittenTree = git(gitRoot, ["rev-parse", `${rewrittenCommit}^{tree}`]).trim();
64
+ if (reviewedTree !== rewrittenTree) {
65
+ const protectedDiff = git(gitRoot, [
66
+ "diff",
67
+ "--no-renames",
68
+ "--binary",
69
+ "--full-index",
70
+ lastReviewedCommit,
71
+ rewrittenCommit,
72
+ "--",
73
+ ...pathspecs
74
+ ]);
75
+ if (protectedDiff !== "") {
76
+ return {
77
+ status: "failed",
78
+ code: "LOCAL_REWRITE_CONTENT_MISMATCH",
79
+ message: "Local rewritten commit differs from the reviewed protected content"
80
+ };
81
+ }
82
+ }
83
+ const postRewrite = git(gitRoot, [
84
+ "rev-list",
85
+ `${rewrittenCommit}..${localHead}`,
86
+ "--",
87
+ ...pathspecs
88
+ ]).trim();
89
+ if (postRewrite) {
90
+ return {
91
+ status: "failed",
92
+ code: "POST_LOCAL_REWRITE_CHANGES",
93
+ message: "Protected paths changed after the equivalent local rewrite"
94
+ };
95
+ }
96
+ }
97
+ catch {
98
+ return {
99
+ status: "blocked",
100
+ code: "LOCAL_REWRITE_GIT_EVIDENCE_UNAVAILABLE",
101
+ message: "Unable to verify local rewrite topology or content"
102
+ };
103
+ }
104
+ return {
105
+ status: "local-equivalent",
106
+ reviewedHead: lastReviewedCommit,
107
+ rewrittenCommit
108
+ };
109
+ }
110
+ //# sourceMappingURL=reviewed-commit-equivalence.js.map
package/dist/lib/init.js CHANGED
@@ -8,30 +8,15 @@ import { resolveTemplateDir } from './paths.js';
8
8
  import { renderFile, copySkillDir, KNOWN_PLATFORMS } from './render.js';
9
9
  import { enginesForPlatform } from './sandbox/engines/index.js';
10
10
  import { VERSION } from './version.js';
11
- import { BUILTIN_TUI_IDS, BUILTIN_TUI_DISPLAY, isPathOwnedByDisabledTUI, resolveEnabledTUIs } from './builtin-tuis.js';
11
+ import { listAgentClientAdapters } from './agent-clients/registry.js';
12
+ import { serializeAgentClients } from './agent-clients/config.js';
13
+ import { applyAgentClientReconciliation, planAgentClientReconciliation } from './agent-clients/reconcile.js';
12
14
  const defaults = JSON.parse(fs.readFileSync(new URL('./defaults.json', import.meta.url), 'utf8'));
13
15
  const PLATFORM_DEFAULT_ENGINES = Object.freeze({
14
16
  linux: 'native',
15
17
  darwin: 'colima',
16
18
  win32: 'wsl2'
17
19
  });
18
- function isPathOwnedByOtherPlatform(relativePath, platformType) {
19
- const top = String(relativePath || '').replace(/\\/g, '/').replace(/^\.\//, '').split('/')[0] ?? '';
20
- if (!top.startsWith('.'))
21
- return false;
22
- const candidate = top.slice(1);
23
- if (!KNOWN_PLATFORMS.has(candidate))
24
- return false;
25
- return candidate !== platformType;
26
- }
27
- function buildDefaultFiles(platformType, enabledTUIs) {
28
- const ownedByDisabled = (entry) => isPathOwnedByDisabledTUI(entry, enabledTUIs);
29
- return {
30
- managed: (defaults.files.managed || []).filter((entry) => !isPathOwnedByOtherPlatform(entry, platformType) && !ownedByDisabled(entry)),
31
- merged: (defaults.files.merged || []).filter((entry) => !isPathOwnedByOtherPlatform(entry, platformType) && !ownedByDisabled(entry)),
32
- ejected: structuredClone(defaults.files.ejected || [])
33
- };
34
- }
35
20
  function detectProjectName() {
36
21
  try {
37
22
  const url = execSync('git remote get-url origin', { stdio: ['pipe', 'pipe', 'pipe'] })
@@ -158,9 +143,10 @@ async function cmdInit() {
158
143
  info(`Custom platform '${platformType}' selected. Built-in templates are only complete for github;`
159
144
  + ` provide matching '.${platformType}.' or generic templates before running update-agent-infra.`);
160
145
  }
161
- let enabledTUIs;
146
+ const adapters = listAgentClientAdapters();
147
+ let enabledClientIds;
162
148
  try {
163
- enabledTUIs = await multiSelect('Built-in TUI command files to install/manage', BUILTIN_TUI_IDS.map((id) => ({ id, label: BUILTIN_TUI_DISPLAY[id] })));
149
+ enabledClientIds = await multiSelect('Agent Client project integrations to enable', adapters.map((adapter) => ({ id: adapter.id, label: adapter.displayName })));
164
150
  }
165
151
  catch (e) {
166
152
  err(e instanceof Error ? e.message : String(e));
@@ -168,53 +154,19 @@ async function cmdInit() {
168
154
  process.exitCode = 1;
169
155
  return;
170
156
  }
171
- const enabledTUISet = resolveEnabledTUIs(enabledTUIs);
157
+ const enabledClientSet = new Set(enabledClientIds);
172
158
  const templateSources = parseLocalSources(await prompt('Template sources (optional, comma-separated local paths, e.g. ~/my-templates; Enter to skip)', ''));
173
159
  const skillSources = parseLocalSources(await prompt('Skill sources (optional, comma-separated local paths, e.g. ~/my-skills; Enter to skip)', ''));
174
160
  closePrompt();
175
161
  const project = projectName;
176
162
  const replacements = { project, org: orgName };
177
- console.log('');
178
- if (orgName) {
179
- info(`Installing update-agent-infra seed command for: ${projectName} (${orgName})`);
180
- }
181
- else {
182
- info(`Installing update-agent-infra seed command for: ${projectName}`);
183
- }
184
- console.log('');
185
- // select language-specific template filenames
186
- let claudeSrc, geminiSrc, opencodeSrc;
187
- if (language === 'zh-CN') {
188
- claudeSrc = 'update-agent-infra.zh-CN.md';
189
- geminiSrc = 'update-agent-infra.zh-CN.toml';
190
- opencodeSrc = 'update-agent-infra.zh-CN.md';
191
- }
192
- else {
193
- claudeSrc = 'update-agent-infra.en.md';
194
- geminiSrc = 'update-agent-infra.en.toml';
195
- opencodeSrc = 'update-agent-infra.en.md';
196
- }
197
- // install skill
198
- copySkillDir(path.join(templateDir, '.agents', 'skills', 'update-agent-infra'), path.join('.agents', 'skills', 'update-agent-infra'), replacements, language, platformType);
199
- ok('Installed .agents/skills/update-agent-infra/');
200
- renderFile(path.join(templateDir, '.agents', 'scripts', 'lib', 'agent-infra-package.js'), path.join('.agents', 'scripts', 'lib', 'agent-infra-package.js'), replacements);
201
- ok('Installed .agents/scripts/lib/agent-infra-package.js');
202
- // install Claude command (only if enabled)
203
- if (enabledTUISet.has('claude-code')) {
204
- renderFile(path.join(templateDir, '.claude', 'commands', claudeSrc), path.join('.claude', 'commands', 'update-agent-infra.md'), replacements);
205
- ok('Installed .claude/commands/update-agent-infra.md');
206
- }
207
- // install Gemini command (only if enabled)
208
- if (enabledTUISet.has('gemini-cli')) {
209
- renderFile(path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc), path.join('.gemini', 'commands', project, 'update-agent-infra.toml'), replacements);
210
- ok(`Installed .gemini/commands/${project}/update-agent-infra.toml`);
211
- }
212
- // install OpenCode command (only if enabled)
213
- if (enabledTUISet.has('opencode')) {
214
- renderFile(path.join(templateDir, '.opencode', 'commands', opencodeSrc), path.join('.opencode', 'commands', 'update-agent-infra.md'), replacements);
215
- ok('Installed .opencode/commands/update-agent-infra.md');
216
- }
217
- // generate .agents/.airc.json
163
+ const defaultState = Object.fromEntries(defaults.agentClients.map((entry) => [
164
+ entry.id,
165
+ {
166
+ enabled: enabledClientSet.has(entry.id),
167
+ installInSandbox: entry.installInSandbox
168
+ }
169
+ ]));
218
170
  const config = {
219
171
  project: projectName,
220
172
  org: orgName,
@@ -224,24 +176,39 @@ async function cmdInit() {
224
176
  sandbox: structuredClone(defaults.sandbox),
225
177
  task: structuredClone(defaults.task),
226
178
  labels: structuredClone(defaults.labels),
227
- files: buildDefaultFiles(platformType, enabledTUISet),
228
- tuis: enabledTUIs
179
+ files: { managed: [], merged: [], ejected: [] },
180
+ agentClients: serializeAgentClients(defaultState)
229
181
  };
230
- if (sandboxEngine) {
182
+ if (sandboxEngine)
231
183
  config.sandbox.engine = sandboxEngine;
184
+ if (templateSources.length > 0)
185
+ config.templates = { sources: templateSources };
186
+ if (skillSources.length > 0)
187
+ config.skills = { sources: skillSources };
188
+ const workflowPlan = planAgentClientReconciliation({
189
+ config: config,
190
+ mutation: { type: 'none' },
191
+ projectRoot: process.cwd(),
192
+ templateRoot: templateDir,
193
+ platformType,
194
+ language
195
+ });
196
+ console.log('');
197
+ if (orgName) {
198
+ info(`Installing update-agent-infra seed command for: ${projectName} (${orgName})`);
232
199
  }
233
- if (templateSources.length > 0) {
234
- config.templates = {
235
- sources: templateSources
236
- };
237
- }
238
- if (skillSources.length > 0) {
239
- config.skills = {
240
- sources: skillSources
241
- };
200
+ else {
201
+ info(`Installing update-agent-infra seed command for: ${projectName}`);
242
202
  }
243
- fs.mkdirSync(path.dirname(configPath), { recursive: true });
244
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
203
+ console.log('');
204
+ // install skill
205
+ copySkillDir(path.join(templateDir, '.agents', 'skills', 'update-agent-infra'), path.join('.agents', 'skills', 'update-agent-infra'), replacements, language, platformType);
206
+ ok('Installed .agents/skills/update-agent-infra/');
207
+ renderFile(path.join(templateDir, '.agents', 'scripts', 'lib', 'agent-infra-package.js'), path.join('.agents', 'scripts', 'lib', 'agent-infra-package.js'), replacements);
208
+ ok('Installed .agents/scripts/lib/agent-infra-package.js');
209
+ const reconcileResult = applyAgentClientReconciliation(workflowPlan);
210
+ for (const target of reconcileResult.applied)
211
+ ok(`Installed ${target}`);
245
212
  ok(`Generated ${configPath}`);
246
213
  // done
247
214
  console.log('');
@@ -250,27 +217,16 @@ async function cmdInit() {
250
217
  console.log(' If this init used npx, install agent-infra persistently before update or validation:');
251
218
  console.log(' npm install -g @fitlab-ai/agent-infra');
252
219
  console.log('');
253
- if (enabledTUISet.size === 0) {
254
- console.log(' No built-in TUI selected.');
220
+ if (workflowPlan.nextSteps.length === 0) {
221
+ console.log(' No Agent Client project integration enabled.');
255
222
  console.log(` Configure "customTUIs" in ${configPath} before running update-agent-infra.`);
256
223
  console.log('');
257
224
  }
258
225
  else {
259
226
  console.log(' Next step: open this project in any AI TUI and run:');
260
227
  console.log('');
261
- const claudeOrOpencode = [];
262
- if (enabledTUISet.has('claude-code'))
263
- claudeOrOpencode.push('Claude Code');
264
- if (enabledTUISet.has('opencode'))
265
- claudeOrOpencode.push('OpenCode');
266
- if (claudeOrOpencode.length > 0) {
267
- console.log(` ${claudeOrOpencode.join(' / ')}: /update-agent-infra`);
268
- }
269
- if (enabledTUISet.has('gemini-cli')) {
270
- console.log(` Gemini CLI: /${project}:update-agent-infra`);
271
- }
272
- if (enabledTUISet.has('codex')) {
273
- console.log(' Codex CLI: $update-agent-infra');
228
+ for (const nextStep of workflowPlan.nextSteps) {
229
+ console.log(` ${nextStep.displayName}: ${nextStep.command}`);
274
230
  }
275
231
  console.log('');
276
232
  console.log(' This will render all templates and set up the full');
@@ -0,0 +1,117 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { AgentClientConfigError, normalizeAgentClients } from '../agent-clients/config.js';
4
+ import { normalizeCustomTUIs } from '../agent-clients/custom-tuis.js';
5
+ import { renderNextStepCommands } from '../agent-clients/next-steps.js';
6
+ const USAGE = 'Usage: agent-infra-internal agent-client next-steps --skill <skill-name> [--task-ref <NN|TASK-id>] [--format text|json]\n';
7
+ function failure(code, message) {
8
+ process.stdout.write(`${JSON.stringify({
9
+ status: 'failed',
10
+ changed: false,
11
+ commands: [],
12
+ diagnostics: [],
13
+ error: { code, message }
14
+ })}\n`);
15
+ process.exitCode = 1;
16
+ }
17
+ function parseArgs(args) {
18
+ if (args[0] === '--help' || args[0] === '-h') {
19
+ process.stdout.write(USAGE);
20
+ return null;
21
+ }
22
+ if (args[0] !== 'next-steps') {
23
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', "operation must be 'next-steps'");
24
+ return null;
25
+ }
26
+ let skillName;
27
+ let taskRef;
28
+ let format = 'text';
29
+ const seen = new Set();
30
+ for (let index = 1; index < args.length; index += 1) {
31
+ const flag = args[index];
32
+ if (!['--skill', '--task-ref', '--format'].includes(flag)) {
33
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', `unknown option '${flag}'`);
34
+ return null;
35
+ }
36
+ if (seen.has(flag)) {
37
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', `duplicate option '${flag}'`);
38
+ return null;
39
+ }
40
+ const value = args[++index];
41
+ if (!value || value.startsWith('--')) {
42
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', `option '${flag}' requires a value`);
43
+ return null;
44
+ }
45
+ seen.add(flag);
46
+ if (flag === '--skill')
47
+ skillName = value;
48
+ if (flag === '--task-ref')
49
+ taskRef = value;
50
+ if (flag === '--format') {
51
+ if (value !== 'text' && value !== 'json') {
52
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', "format must be 'text' or 'json'");
53
+ return null;
54
+ }
55
+ format = value;
56
+ }
57
+ }
58
+ if (!skillName) {
59
+ failure('AGENT_CLIENT_PAYLOAD_INVALID', "option '--skill' is required");
60
+ return null;
61
+ }
62
+ return { skillName, ...(taskRef ? { taskRef } : {}), format };
63
+ }
64
+ function agentClient(args = []) {
65
+ const parsed = parseArgs(args);
66
+ if (!parsed || process.exitCode)
67
+ return;
68
+ let config;
69
+ try {
70
+ const configPath = path.join(process.cwd(), '.agents', '.airc.json');
71
+ const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
72
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
73
+ throw new Error('configuration root must be an object');
74
+ }
75
+ config = raw;
76
+ }
77
+ catch (error) {
78
+ failure('AGENT_CLIENT_CONFIG_INVALID', String(error));
79
+ return;
80
+ }
81
+ try {
82
+ const clients = normalizeAgentClients(config);
83
+ const custom = normalizeCustomTUIs(process.cwd(), config.customTUIs ?? []);
84
+ const commands = renderNextStepCommands({
85
+ projectName: String(config.project ?? ''),
86
+ state: clients.state,
87
+ customTUIs: custom.items,
88
+ skillName: parsed.skillName,
89
+ ...(parsed.taskRef ? { taskRef: parsed.taskRef } : {})
90
+ });
91
+ if (parsed.format === 'json') {
92
+ process.stdout.write(`${JSON.stringify({
93
+ status: 'rendered',
94
+ changed: false,
95
+ commands,
96
+ diagnostics: custom.diagnostics,
97
+ error: null
98
+ })}\n`);
99
+ return;
100
+ }
101
+ for (const command of commands) {
102
+ process.stdout.write(` - ${command.displayName}: ${command.command}\n`);
103
+ }
104
+ for (const diagnostic of custom.diagnostics) {
105
+ process.stderr.write(`${diagnostic.code} at ${diagnostic.path}\n`);
106
+ }
107
+ }
108
+ catch (error) {
109
+ if (error instanceof AgentClientConfigError) {
110
+ failure(error.code, error.message);
111
+ return;
112
+ }
113
+ failure('AGENT_CLIENT_RENDER_INVALID', error instanceof Error ? error.message : String(error));
114
+ }
115
+ }
116
+ export { agentClient };
117
+ //# sourceMappingURL=agent-client.js.map
@@ -29,7 +29,7 @@ function gitWorkflow(args = []) {
29
29
  if (!input)
30
30
  result = { status: 'failed', changed: false, error: { code: 'GIT_INPUT_REQUIRED', message: '--input JSON file is required' } };
31
31
  else if (action === 'snapshot')
32
- result = { status: 'no-op', changed: false, snapshot: snapshotReview({ cwd: cwd ?? process.cwd(), mode: input.mode, baseline: input.baseline, globs: input.globs ?? resolvePostReviewGlobs({}, {}) }), error: null };
32
+ result = { status: 'no-op', changed: false, snapshot: snapshotReview({ cwd: cwd ?? process.cwd(), mode: input.mode, baseline: input.baseline, diffBase: input.diffBase, globs: input.globs ?? resolvePostReviewGlobs({}, {}) }), error: null };
33
33
  else
34
34
  result = { status: 'no-op', changed: false, comparison: compareReviewTrees({ cwd: cwd ?? process.cwd(), expected: input.expected, actual: input.actual }), error: null };
35
35
  }
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { publishReleaseNotes, releaseNoteContext } from '../platform/release-notes.js';
4
+ function option(args, name) {
5
+ const index = args.indexOf(name);
6
+ return index >= 0 && args[index + 1] ? args[index + 1] : null;
7
+ }
8
+ function finish(result) {
9
+ process.stdout.write(`${JSON.stringify(result)}\n`);
10
+ process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
11
+ }
12
+ function platformReleaseNotes(args = []) {
13
+ const [action, ...rest] = args;
14
+ const cwd = path.resolve(option(rest, '--cwd') || process.cwd());
15
+ if (action === 'context') {
16
+ const historyRaw = option(rest, '--history-limit');
17
+ finish(releaseNoteContext({
18
+ fromTag: option(rest, '--from-tag') || '',
19
+ toTag: option(rest, '--to-tag') || '',
20
+ branch: option(rest, '--branch') || '',
21
+ historyLimit: historyRaw === null ? undefined : Number(historyRaw)
22
+ }, { cwd }));
23
+ return;
24
+ }
25
+ if (action === 'publish') {
26
+ const notesPath = option(rest, '--notes-file');
27
+ if (!notesPath) {
28
+ finish({ status: 'failed', changed: false, error: { code: 'RELEASE_NOTES_INPUT_INVALID', message: 'notes-file is required', retryable: false } });
29
+ return;
30
+ }
31
+ let resolvedNotesPath = notesPath;
32
+ if (notesPath === '-') {
33
+ resolvedNotesPath = path.join(process.env.TMPDIR || '/tmp', `agent-infra-release-notes-${process.pid}.md`);
34
+ fs.writeFileSync(resolvedNotesPath, fs.readFileSync(0));
35
+ }
36
+ try {
37
+ finish(publishReleaseNotes({
38
+ tag: option(rest, '--tag') || '',
39
+ title: option(rest, '--title') || option(rest, '--tag') || '',
40
+ notesFile: resolvedNotesPath,
41
+ dryRun: rest.includes('--dry-run')
42
+ }, { cwd }));
43
+ }
44
+ finally {
45
+ if (notesPath === '-')
46
+ fs.rmSync(resolvedNotesPath, { force: true });
47
+ }
48
+ return;
49
+ }
50
+ finish({ status: 'failed', changed: false, error: { code: 'RELEASE_NOTES_INPUT_INVALID', message: 'Usage: platform-release-notes context|publish', retryable: false } });
51
+ }
52
+ export { platformReleaseNotes };
53
+ //# sourceMappingURL=platform-release-notes.js.map