@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
package/lib/update.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { normalizeAgentClients } from './agent-clients/config.ts';
4
+ import {
5
+ applyAgentClientReconciliation,
6
+ planAgentClientReconciliation
7
+ } from './agent-clients/reconcile.ts';
3
8
  import { info, ok, err } from './log.ts';
4
9
  import { resolveTemplateDir } from './paths.ts';
5
- import { renderFile, copySkillDir, KNOWN_PLATFORMS } from './render.ts';
6
- import { isPathOwnedByDisabledTUI, resolveEnabledTUIs } from './builtin-tuis.ts';
7
- import type { BuiltinTUIId } from './builtin-tuis.ts';
10
+ import { renderFile, copySkillDir } from './render.ts';
8
11
 
9
12
  type FileRegistry = {
10
13
  managed: string[];
@@ -24,6 +27,8 @@ type UpdateConfig = {
24
27
  labels?: Record<string, unknown>;
25
28
  files?: Partial<FileRegistry>;
26
29
  tuis?: unknown;
30
+ agentClients?: unknown;
31
+ customTUIs?: unknown;
27
32
  };
28
33
 
29
34
  type Defaults = {
@@ -40,9 +45,6 @@ const defaults = JSON.parse(
40
45
 
41
46
  const CONFIG_DIR = '.agents';
42
47
  const CONFIG_PATH = path.join(CONFIG_DIR, '.airc.json');
43
- const AGENT_INFRA_SANDBOX_TOOL = 'agent-infra';
44
- const LEGACY_DEFAULT_SANDBOX_TOOLS = ['claude-code', 'codex', 'gemini-cli', 'opencode'];
45
- const DEFAULT_SANDBOX_TOOLS = [AGENT_INFRA_SANDBOX_TOOL, ...LEGACY_DEFAULT_SANDBOX_TOOLS];
46
48
 
47
49
  // One-time migration of the legacy project-level PR switch to the three-state
48
50
  // `prFlow` preference. `true` (the old default / "PR flow on") maps to the
@@ -63,83 +65,6 @@ function migratePrFlow(config: UpdateConfig): 'required' | 'disabled' | null {
63
65
  return null;
64
66
  }
65
67
 
66
- function isLegacyDefaultSandboxTools(value: unknown): value is string[] {
67
- if (!Array.isArray(value) || value.length !== LEGACY_DEFAULT_SANDBOX_TOOLS.length) {
68
- return false;
69
- }
70
- const tools = new Set(value);
71
- return LEGACY_DEFAULT_SANDBOX_TOOLS.every((tool) => tools.has(tool));
72
- }
73
-
74
- function migrateSandboxTools(config: UpdateConfig): boolean {
75
- const tools = config.sandbox?.tools;
76
- if (!isLegacyDefaultSandboxTools(tools)) {
77
- return false;
78
- }
79
- config.sandbox = {
80
- ...config.sandbox,
81
- tools: [...DEFAULT_SANDBOX_TOOLS]
82
- };
83
- return true;
84
- }
85
-
86
- function isPathOwnedByOtherPlatform(relativePath: string, platformType: string): boolean {
87
- const top = String(relativePath || '').replace(/\\/g, '/').replace(/^\.\//, '').split('/')[0] ?? '';
88
- if (!top.startsWith('.')) return false;
89
-
90
- const candidate = top.slice(1);
91
- if (!KNOWN_PLATFORMS.has(candidate)) return false;
92
- return candidate !== platformType;
93
- }
94
-
95
- function syncFileRegistry(config: UpdateConfig, platformType: string, enabledTUIs: Set<BuiltinTUIId>) {
96
- config.files ||= {};
97
- const before = JSON.stringify({
98
- files: {
99
- managed: config.files.managed || [],
100
- merged: config.files.merged || [],
101
- ejected: config.files.ejected || []
102
- }
103
- });
104
- config.files.managed = config.files.managed || [];
105
- config.files.merged = config.files.merged || [];
106
- config.files.ejected = config.files.ejected || [];
107
-
108
- const allExisting = [
109
- ...config.files.managed,
110
- ...config.files.merged,
111
- ...config.files.ejected
112
- ];
113
- const added: Pick<FileRegistry, 'managed' | 'merged'> = { managed: [], merged: [] };
114
-
115
- for (const entry of defaults.files.managed) {
116
- if (isPathOwnedByOtherPlatform(entry, platformType)) continue;
117
- if (isPathOwnedByDisabledTUI(entry, enabledTUIs)) continue;
118
- if (!allExisting.includes(entry)) {
119
- config.files.managed.push(entry);
120
- added.managed.push(entry);
121
- }
122
- }
123
- for (const entry of defaults.files.merged) {
124
- if (isPathOwnedByOtherPlatform(entry, platformType)) continue;
125
- if (isPathOwnedByDisabledTUI(entry, enabledTUIs)) continue;
126
- if (!allExisting.includes(entry)) {
127
- config.files.merged.push(entry);
128
- added.merged.push(entry);
129
- }
130
- }
131
-
132
- const after = JSON.stringify({
133
- files: {
134
- managed: config.files.managed,
135
- merged: config.files.merged,
136
- ejected: config.files.ejected
137
- }
138
- });
139
-
140
- return { added, changed: before !== after };
141
- }
142
-
143
68
  async function cmdUpdate(): Promise<void> {
144
69
  console.log('');
145
70
  console.log(' ai update');
@@ -167,24 +92,36 @@ async function cmdUpdate(): Promise<void> {
167
92
  const config = JSON.parse(fs.readFileSync(CONFIG_PATH, 'utf8')) as UpdateConfig;
168
93
  const { project, org, language } = config;
169
94
  const platformType = config.platform?.type || defaults.platform.type;
170
- const enabledTUIs = resolveEnabledTUIs(config.tuis);
171
95
  const replacements = { project, org };
172
96
 
97
+ const normalizedOriginal = normalizeAgentClients(config);
98
+ const currentRegistry: FileRegistry = {
99
+ managed: config.files?.managed || [],
100
+ merged: config.files?.merged || [],
101
+ ejected: config.files?.ejected || []
102
+ };
103
+ const platformAdded = !config.platform;
104
+ const sandboxAdded = !config.sandbox;
105
+ const taskAdded = !config.task;
106
+ const labelsAdded = !config.labels;
107
+ const prFlowMigrated = migratePrFlow(config);
108
+ if (platformAdded) config.platform = structuredClone(defaults.platform);
109
+ if (sandboxAdded) config.sandbox = structuredClone(defaults.sandbox);
110
+ if (taskAdded) config.task = structuredClone(defaults.task);
111
+ if (labelsAdded) config.labels = structuredClone(defaults.labels);
112
+
113
+ const workflowPlan = planAgentClientReconciliation({
114
+ config: config as unknown as Record<string, unknown>,
115
+ mutation: { type: 'replace-state', state: normalizedOriginal.state },
116
+ projectRoot: process.cwd(),
117
+ templateRoot: templateDir,
118
+ platformType,
119
+ language
120
+ });
121
+
173
122
  info(`Updating seed files for: ${project}`);
174
123
  console.log('');
175
124
 
176
- // select language-specific template filenames
177
- let claudeSrc, geminiSrc, opencodeSrc;
178
- if (language === 'zh-CN') {
179
- claudeSrc = 'update-agent-infra.zh-CN.md';
180
- geminiSrc = 'update-agent-infra.zh-CN.toml';
181
- opencodeSrc = 'update-agent-infra.zh-CN.md';
182
- } else {
183
- claudeSrc = 'update-agent-infra.en.md';
184
- geminiSrc = 'update-agent-infra.en.toml';
185
- opencodeSrc = 'update-agent-infra.en.md';
186
- }
187
-
188
125
  // update skill
189
126
  copySkillDir(
190
127
  path.join(templateDir, '.agents', 'skills', 'update-agent-infra'),
@@ -206,76 +143,19 @@ async function cmdUpdate(): Promise<void> {
206
143
  // Ignore missing legacy script from pre-ESM installs.
207
144
  }
208
145
 
209
- // update Claude command (only if enabled)
210
- if (enabledTUIs.has('claude-code')) {
211
- renderFile(
212
- path.join(templateDir, '.claude', 'commands', claudeSrc),
213
- path.join('.claude', 'commands', 'update-agent-infra.md'),
214
- replacements
215
- );
216
- ok('Updated .claude/commands/update-agent-infra.md');
217
- }
218
-
219
- // update Gemini command (only if enabled)
220
- if (enabledTUIs.has('gemini-cli')) {
221
- renderFile(
222
- path.join(templateDir, '.gemini', 'commands', '_project_', geminiSrc),
223
- path.join('.gemini', 'commands', project, 'update-agent-infra.toml'),
224
- replacements
225
- );
226
- ok(`Updated .gemini/commands/${project}/update-agent-infra.toml`);
227
- }
228
-
229
- // update OpenCode command (only if enabled)
230
- if (enabledTUIs.has('opencode')) {
231
- renderFile(
232
- path.join(templateDir, '.opencode', 'commands', opencodeSrc),
233
- path.join('.opencode', 'commands', 'update-agent-infra.md'),
234
- replacements
235
- );
236
- ok('Updated .opencode/commands/update-agent-infra.md');
237
- }
238
-
239
- // sync file registry
240
- const { added, changed } = syncFileRegistry(config, platformType, enabledTUIs);
146
+ const added = {
147
+ managed: workflowPlan.projectAssets.registry.managed.filter(
148
+ (entry) => !currentRegistry.managed.includes(entry)
149
+ ),
150
+ merged: workflowPlan.projectAssets.registry.merged.filter(
151
+ (entry) => !currentRegistry.merged.includes(entry)
152
+ )
153
+ };
241
154
  const hasNewEntries = added.managed.length > 0 || added.merged.length > 0;
242
- const platformAdded = !config.platform;
243
- const sandboxAdded = !config.sandbox;
244
- const taskAdded = !config.task;
245
- const labelsAdded = !config.labels;
246
- const prFlowMigrated = migratePrFlow(config);
247
- const sandboxToolsMigrated = !sandboxAdded && migrateSandboxTools(config);
248
- let configChanged = changed;
155
+ const reconcileResult = applyAgentClientReconciliation(workflowPlan);
156
+ for (const target of reconcileResult.applied) ok(`Updated ${target}`);
249
157
 
250
- if (platformAdded) {
251
- config.platform = structuredClone(defaults.platform);
252
- configChanged = true;
253
- }
254
-
255
- if (sandboxAdded) {
256
- config.sandbox = structuredClone(defaults.sandbox);
257
- configChanged = true;
258
- }
259
-
260
- if (taskAdded) {
261
- config.task = structuredClone(defaults.task);
262
- configChanged = true;
263
- }
264
-
265
- if (labelsAdded) {
266
- config.labels = structuredClone(defaults.labels);
267
- configChanged = true;
268
- }
269
-
270
- if (prFlowMigrated) {
271
- configChanged = true;
272
- }
273
-
274
- if (sandboxToolsMigrated) {
275
- configChanged = true;
276
- }
277
-
278
- if (configChanged) {
158
+ if (reconcileResult.configUpdated) {
279
159
  console.log('');
280
160
  if (hasNewEntries) {
281
161
  info(`New file entries synced to ${CONFIG_PATH}:`);
@@ -301,9 +181,6 @@ async function cmdUpdate(): Promise<void> {
301
181
  if (prFlowMigrated) {
302
182
  info(`Migrated legacy requiresPullRequest to prFlow="${prFlowMigrated}" in ${CONFIG_PATH}.`);
303
183
  }
304
- if (sandboxToolsMigrated) {
305
- info(`Migrated default sandbox.tools to include ${AGENT_INFRA_SANDBOX_TOOL} in ${CONFIG_PATH}.`);
306
- }
307
184
  } else {
308
185
  info(`File registry changed in ${CONFIG_PATH}.`);
309
186
  }
@@ -322,10 +199,6 @@ async function cmdUpdate(): Promise<void> {
322
199
  if (hasNewEntries && prFlowMigrated) {
323
200
  info(`Migrated legacy requiresPullRequest to prFlow="${prFlowMigrated}" in ${CONFIG_PATH}.`);
324
201
  }
325
- if (hasNewEntries && sandboxToolsMigrated) {
326
- info(`Migrated default sandbox.tools to include ${AGENT_INFRA_SANDBOX_TOOL} in ${CONFIG_PATH}.`);
327
- }
328
- fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2) + '\n', 'utf8');
329
202
  ok(`Updated ${CONFIG_PATH}`);
330
203
  }
331
204
 
@@ -333,24 +206,15 @@ async function cmdUpdate(): Promise<void> {
333
206
  console.log('');
334
207
  ok('Seed files updated successfully!');
335
208
  console.log('');
336
- if (enabledTUIs.size === 0) {
337
- console.log(' No built-in TUI enabled (tuis: []).');
209
+ if (workflowPlan.nextSteps.length === 0) {
210
+ console.log(' No Agent Client project integration enabled.');
338
211
  console.log(` Configure "customTUIs" in ${CONFIG_PATH} if needed.`);
339
212
  console.log('');
340
213
  } else {
341
214
  console.log(' Next step: run the full update in your AI TUI:');
342
215
  console.log('');
343
- const claudeOrOpencode: string[] = [];
344
- if (enabledTUIs.has('claude-code')) claudeOrOpencode.push('Claude Code');
345
- if (enabledTUIs.has('opencode')) claudeOrOpencode.push('OpenCode');
346
- if (claudeOrOpencode.length > 0) {
347
- console.log(` ${claudeOrOpencode.join(' / ')}: /update-agent-infra`);
348
- }
349
- if (enabledTUIs.has('gemini-cli')) {
350
- console.log(` Gemini CLI: /${project}:update-agent-infra`);
351
- }
352
- if (enabledTUIs.has('codex')) {
353
- console.log(' Codex CLI: $update-agent-infra');
216
+ for (const nextStep of workflowPlan.nextSteps) {
217
+ console.log(` ${nextStep.displayName}: ${nextStep.command}`);
354
218
  }
355
219
  console.log('');
356
220
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fitlab-ai/agent-infra",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "Bootstrap tool for AI multi-tool collaboration infrastructure — works with Claude Code, Codex, Gemini CLI, and OpenCode",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -73,7 +73,7 @@
73
73
  "typescript": "~7.0"
74
74
  },
75
75
  "optionalDependencies": {
76
- "@lydell/node-pty": "^1.2.0-beta.12"
76
+ "@lydell/node-pty": "^1.2.0-beta.14"
77
77
  },
78
78
  "overrides": {
79
79
  "axios": "1.18.1"
@@ -218,37 +218,38 @@ Ordinary `managed` files keep their overwrite semantics. A small set of platform
218
218
 
219
219
  `ejected` entries support literal paths or globs, using the same matching rules as `merged`.
220
220
 
221
- ## Built-in TUI Selection
221
+ ## Agent Client Configuration
222
222
 
223
- Use the top-level `.agents/.airc.json` `tuis` array to pick which built-in TUIs (`claude-code`, `codex`, `gemini-cli`, `opencode`) agent-infra should install command files for and keep in sync.
223
+ Use the top-level `.agents/.airc.json` `agentClients` array to configure all four built-in clients (`claude-code`, `codex`, `gemini-cli`, `opencode`). Each canonical entry has three fields:
224
224
 
225
- | Value | Meaning |
225
+ | Field | Meaning |
226
226
  |-------|---------|
227
- | `tuis` missing or `null` | All four built-in TUIs are enabled (backward-compatible default for legacy `.airc.json` predating this field). |
228
- | `tuis: []` | No built-in TUI is managed. Use this when the project only relies on `customTUIs` and does not need any built-in command files installed. |
229
- | `tuis: [<subset>]` | Only the listed TUIs are managed. Unknown ids are ignored. |
227
+ | `id` | Built-in Agent Client id. The canonical array contains exactly one entry for each built-in client. |
228
+ | `enabled` | Whether agent-infra writes and maintains that client's project integration and seed command. |
229
+ | `installInSandbox` | Whether the sandbox image installs that client's CLI. This is independent from `enabled`. |
230
230
 
231
- `ai init` includes an interactive multi-select for this field:
231
+ Manage these settings without hand-editing JSON:
232
232
 
233
- - Press Enter to accept the default (all built-in TUIs enabled).
234
- - Type comma-separated numbers or ids (e.g. `1,3` or `claude-code,opencode`) to keep a subset.
235
- - Type `none` to explicitly disable every built-in TUI (typically combined with a `customTUIs` entry added later).
236
- - Invalid input (duplicate, out-of-range, unknown id, whitespace-only) aborts init with a non-zero exit code.
233
+ ```bash
234
+ ai agent-client list
235
+ ai agent-client status
236
+ ai agent-client enable codex
237
+ ai agent-client disable gemini-cli
238
+ ai agent-client configure
239
+ ```
237
240
 
238
- ### Side effects of disabling a TUI
241
+ `enable` and `disable` only change `enabled`; `configure` edits both dimensions. `ai init` asks which clients to enable and preserves the displayed defaults when you press Enter. All clients default to `installInSandbox: true`.
239
242
 
240
- When you disable a built-in TUI (either via `ai init` or by hand-editing `.airc.json`), the next `ai update` / `update-agent-infra` will:
243
+ Legacy `tuis` and built-in client ids in `sandbox.tools` are migration inputs only. The next config-writing command converts them into the canonical `agentClients` array and removes the legacy fields. If canonical and legacy values conflict, the command stops without modifying files so the conflict can be resolved explicitly.
241
244
 
242
- - skip seed command writes for that TUI (e.g. `.gemini/commands/<project>/update-agent-infra.toml`);
243
- - skip the TUI's owned default entries when backfilling `files.managed` / `files.merged`;
244
- - **clean up existing files** under the TUI's owned path prefix (`.claude/`, `.codex/`, `.gemini/`, `.opencode/`) — these are listed in `report.managed.removed`, mirroring the cleanup behavior when switching `platform`.
245
+ ### Side effects of disabling an Agent Client
245
246
 
246
- To opt a specific file out of this cleanup, list it in `files.ejected`; ejected entries owned by disabled TUIs are preserved as-is and are not re-created by sync.
247
+ When you disable a built-in client, reconciliation stops maintaining its seed command and owned registry entries. An unchanged generated seed may be removed; a locally modified seed is protected and reported instead. Files listed in `files.ejected` remain project-owned and are preserved.
247
248
 
248
249
  ### Relation to other config fields
249
250
 
250
- - `tuis` controls **which TUI command files agent-infra writes and maintains**. It is independent from `sandbox.tools`, which controls **which CLIs the sandbox image installs**. Toggling one does not affect the other; the README for `sandbox.tools` lives in the Sandbox section.
251
- - `tuis` is independent from `customTUIs` (see below). CustomTUI command files are not removed when you disable a built-in TUI, even if the customTUI's `dir` falls under that TUI's owned prefix (e.g. a customTUI configured with `dir: ".codex/commands"` is preserved when `codex` is disabled).
251
+ - `sandbox.tools` now lists non-client tools such as `agent-infra` and custom tools. Built-in client installation belongs in `agentClients[].installInSandbox`.
252
+ - `agentClients` is independent from `customTUIs` (see below). Custom TUI command files are preserved even when their directory is under a disabled built-in client's path prefix.
252
253
 
253
254
  ## Custom TUI Configuration
254
255
 
@@ -300,7 +301,7 @@ Namespaced custom TUI:
300
301
 
301
302
  ## Sandbox Custom Tools
302
303
 
303
- `customTUIs` generates slash-command files but does not change the sandbox image. To install a non-npm CLI or tool (pip / cargo / curl-based / pre-built binary) into the sandbox image and live-mount its credentials, declare it under `sandbox.customTools` in `.agents/.airc.json`. Built-in sandbox tools (`claude-code`, `codex`, `opencode`, `gemini-cli`, `agent-infra`) keep working unchanged; `agent-infra` only provides the in-sandbox `ai` / `agent-infra` CLI and is not part of `tuis` or `customTUIs`.
304
+ `customTUIs` generates slash-command files but does not change the sandbox image. To install a non-npm CLI or tool (pip / cargo / curl-based / pre-built binary) into the sandbox image and live-mount its credentials, declare it under `sandbox.customTools` in `.agents/.airc.json`. Built-in Agent Clients are installed according to `agentClients[].installInSandbox`; `agent-infra` remains a non-client entry in `sandbox.tools` and only provides the in-sandbox `ai` / `agent-infra` CLI.
304
305
 
305
306
  ### Required fields
306
307
 
@@ -218,37 +218,38 @@ disable-model-invocation: true # 可选;由支持该能力的 TUI 适配器
218
218
 
219
219
  `ejected` 条目支持字面路径或 glob,匹配规则与 `merged` 相同。
220
220
 
221
- ## 内建 TUI 选择
221
+ ## Agent Client 配置
222
222
 
223
- `.agents/.airc.json` 顶层 `tuis` 数组用于决定 agent-infra 应当为哪些内建 TUI(`claude-code`、`codex`、`gemini-cli`、`opencode`)安装并维护命令文件。
223
+ `.agents/.airc.json` 顶层 `agentClients` 数组用于配置全部四个内建客户端(`claude-code`、`codex`、`gemini-cli`、`opencode`)。规范化后的每个条目包含三个字段:
224
224
 
225
- | 取值 | 含义 |
225
+ | 字段 | 含义 |
226
226
  |------|------|
227
- | `tuis` 缺失或为 `null` | 启用全部四个内建 TUI(向后兼容默认,适用于本字段引入之前的 `.airc.json`) |
228
- | `tuis: []` | 不维护任何内建 TUI。适用于只依赖 `customTUIs`、不需要安装任何内建命令文件的项目 |
229
- | `tuis: [<子集>]` | 仅维护列出的 TUI;未知 id 会被忽略 |
227
+ | `id` | 内建 Agent Client id。规范数组为每个内建客户端保留且仅保留一个条目。 |
228
+ | `enabled` | agent-infra 是否写入并维护该客户端的项目集成与种子命令。 |
229
+ | `installInSandbox` | 沙箱镜像是否安装该客户端 CLI;此字段与 `enabled` 相互独立。 |
230
230
 
231
- `ai init` 会通过交互式多选询问该字段:
231
+ 无需手工编辑 JSON,可使用:
232
232
 
233
- - 直接回车 = 接受默认值(全部内建 TUI 启用)。
234
- - 输入逗号分隔的编号或 id(如 `1,3` 或 `claude-code,opencode`)= 只保留子集。
235
- - 输入 `none` = 明确不启用任何内建 TUI(通常配合后续在 `customTUIs` 添加条目使用)。
236
- - 非法输入(重复、超界、未知 id、纯空白)会让 init 以非零退出码终止。
233
+ ```bash
234
+ ai agent-client list
235
+ ai agent-client status
236
+ ai agent-client enable codex
237
+ ai agent-client disable gemini-cli
238
+ ai agent-client configure
239
+ ```
237
240
 
238
- ### 取消某个 TUI 的副作用
241
+ `enable` 和 `disable` 只修改 `enabled`;`configure` 同时编辑两个维度。`ai init` 会询问启用哪些客户端,直接回车会保留界面展示的默认值。所有客户端的 `installInSandbox` 默认均为 `true`。
239
242
 
240
- 通过 `ai init` 或手工编辑 `.airc.json` 取消某个内建 TUI 后,下一次 `ai update` / `update-agent-infra` 会:
243
+ 旧 `tuis` 字段和 `sandbox.tools` 中的内建客户端 id 仅作为迁移输入。下一次写配置的命令会将其转换为规范 `agentClients` 数组并移除旧字段。若规范配置与旧配置冲突,命令会在修改文件前停止,要求显式解决冲突。
241
244
 
242
- - 跳过该 TUI 的 seed 命令文件写入(例如 `.gemini/commands/<project>/update-agent-infra.toml`);
243
- - 在回填 `files.managed` / `files.merged` 时跳过该 TUI owned 的默认条目;
244
- - **物理清理**该 TUI owned 路径前缀(`.claude/`、`.codex/`、`.gemini/`、`.opencode/`)下的已有文件——清理列表会出现在 `report.managed.removed`,与切换 `platform` 时的清理行为一致。
245
+ ### 取消 Agent Client 的副作用
245
246
 
246
- 若希望保留某个具体文件,把它加入 `files.ejected`:被 ejected 的、属于已取消 TUI 的条目会保持原状,sync 不会重新创建也不会删除。
247
+ 取消某个内建客户端后,协调流程会停止维护其种子命令和 owned 注册项。未修改的生成种子文件可以被删除;本地修改过的种子文件会受到保护并进入报告。`files.ejected` 中的文件仍由项目所有并会被保留。
247
248
 
248
249
  ### 与其他配置字段的关系
249
250
 
250
- - `tuis` 控制 **agent-infra 写入与维护哪些 TUI 的命令文件**,与 `sandbox.tools`(控制**沙箱镜像里安装哪些 CLI**)相互独立。两者互不影响;`sandbox.tools` 的说明见 Sandbox 一节。
251
- - `tuis` 与 `customTUIs`(见下)相互独立。取消某个内建 TUI 时 customTUI 命令文件不会被清理,即便 customTUI 的 `dir` 落在该 TUI 的 owned 前缀下(例如 `dir: ".codex/commands"` 的 customTUI 在 `codex` 被取消时仍会保留)。
251
+ - `sandbox.tools` 现在只列出 `agent-infra` 和自定义工具等非客户端工具。内建客户端的安装状态由 `agentClients[].installInSandbox` 表达。
252
+ - `agentClients` 与 `customTUIs`(见下)相互独立。即使自定义 TUI 目录落在已取消的内建客户端路径前缀下,其命令文件也会被保留。
252
253
 
253
254
  ## 自定义 TUI 配置
254
255
 
@@ -300,7 +301,7 @@ disable-model-invocation: true # 可选;由支持该能力的 TUI 适配器
300
301
 
301
302
  ## 沙箱自定义工具(Sandbox Custom Tools)
302
303
 
303
- `customTUIs` 只负责生成 slash-command 文件,**不影响沙箱镜像**。如果要把一个非 npm 分发的 CLI 或工具(pip / cargo / curl 脚本 / 裸二进制)装进沙箱镜像、并 live-mount 它的凭证目录,需要在 `.agents/.airc.json` 的 `sandbox.customTools` 中声明。内建 sandbox 工具(`claude-code` / `codex` / `opencode` / `gemini-cli` / `agent-infra`)行为保持不变;其中 `agent-infra` 只提供沙箱内 `ai` / `agent-infra` CLI,不属于 `tuis` 或 `customTUIs` 配置。
304
+ `customTUIs` 只负责生成 slash-command 文件,**不影响沙箱镜像**。如果要把一个非 npm 分发的 CLI 或工具(pip / cargo / curl 脚本 / 裸二进制)装进沙箱镜像、并 live-mount 它的凭证目录,需要在 `.agents/.airc.json` 的 `sandbox.customTools` 中声明。内建 Agent Client 按 `agentClients[].installInSandbox` 安装;`agent-infra` 仍是 `sandbox.tools` 中的非客户端条目,只提供沙箱内的 `ai` / `agent-infra` CLI。
304
305
 
305
306
  ### 必填字段
306
307
 
@@ -0,0 +1,64 @@
1
+ import { execFileSync } from 'node:child_process';
2
+
3
+ const MAX_INPUT_BYTES = 64 * 1024;
4
+ const clientIndex = process.argv.indexOf('--client');
5
+ const client = clientIndex >= 0 ? process.argv[clientIndex + 1] : '';
6
+ if (client !== 'claude-code') {
7
+ process.stderr.write('Lifecycle delegation hook requires a supported --client value\n');
8
+ process.exit(1);
9
+ }
10
+ let input = '';
11
+ process.stdin.setEncoding('utf8');
12
+ process.stdin.on('data', (chunk) => {
13
+ input += chunk;
14
+ if (Buffer.byteLength(input) > MAX_INPUT_BYTES) {
15
+ process.stderr.write('Lifecycle delegation hook input exceeds 64 KiB\n');
16
+ process.exit(1);
17
+ }
18
+ });
19
+ process.stdin.on('end', () => {
20
+ let event;
21
+ try {
22
+ event = JSON.parse(input || '{}');
23
+ } catch {
24
+ process.stderr.write('Lifecycle delegation hook received invalid JSON\n');
25
+ process.exit(1);
26
+ }
27
+ const hook = String(event.hook_event_name || event.event || '').toLowerCase();
28
+ const nativeAgent = event.agent_name || event.agent_type || event.agent?.name;
29
+ if (!String(nativeAgent || '').startsWith('agent-infra-lifecycle-')) process.exit(0);
30
+ const start = hook.includes('start');
31
+ const stop = hook.includes('stop');
32
+ if (!start && !stop) {
33
+ process.stderr.write('Managed lifecycle hook event has an unknown type\n');
34
+ process.exit(1);
35
+ }
36
+ const args = ['task-orchestration', 'auto', start ? 'hook-start' : 'hook-stop', '--client', client];
37
+ if (start) {
38
+ args.push(
39
+ '--native-agent', String(nativeAgent),
40
+ '--child-id', String(event.child_id || event.agent_id || event.thread_id || ''),
41
+ '--parent-id', String(event.parent_id || event.parent_session_id || event.session_id || ''),
42
+ '--spawn-mode', String(event.spawn_mode || 'fresh')
43
+ );
44
+ if (event.model) args.push('--actual-model', String(event.model));
45
+ if (event.model_fallback_reason) args.push('--fallback-reason', String(event.model_fallback_reason));
46
+ } else {
47
+ args.push(
48
+ '--native-agent', String(nativeAgent),
49
+ '--child-id', String(event.child_id || event.agent_id || event.thread_id || '')
50
+ );
51
+ }
52
+ try {
53
+ const output = execFileSync('agent-infra-internal', args, {
54
+ encoding: 'utf8',
55
+ shell: process.platform === 'win32',
56
+ stdio: ['ignore', 'pipe', 'pipe']
57
+ });
58
+ process.stdout.write(output);
59
+ } catch (error) {
60
+ if (error.stdout) process.stdout.write(String(error.stdout));
61
+ if (error.stderr) process.stderr.write(String(error.stderr));
62
+ process.exit(typeof error.status === 'number' ? error.status : 1);
63
+ }
64
+ });
@@ -25,7 +25,9 @@ so you can quickly find "which ones to read" without opening each file.
25
25
  ## Task Workflow
26
26
 
27
27
  - [`task-management.md`](task-management.md) — Task intent detection and workflow-command mapping.
28
+ - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — Fresh executor/reviewer, one-use receipt, pause/recovery, and safe endpoint rules for `run-task`.
28
29
  - [`review-handshake.md`](review-handshake.md) — Three-stage bidirectional review handshake: four-state disposition, symmetric evidence, disagreement ledger, convergence and post-review commit gate.
30
+ - [`review-method.md`](review-method.md) — Shared three-stage review method: multi-pass review, risk lenses, traceability, and finding evidence.
29
31
  - [`human-decision-context.md`](human-decision-context.md) — Self-contained context and canonical structure for new human-decision details.
30
32
  - [`task-short-id.md`](task-short-id.md) — Resolution, allocation and lifecycle of bare-number short ids.
31
33
  - [`milestone-inference.md`](milestone-inference.md) — Milestone inference for create-task / code-task / create-pr.
@@ -24,7 +24,9 @@
24
24
  ## 任务工作流
25
25
 
26
26
  - [`task-management.md`](task-management.md) — 任务语义识别与工作流命令映射。
27
+ - [`lifecycle-orchestration.md`](lifecycle-orchestration.md) — `run-task` 的 fresh executor/reviewer、一次性 receipt、暂停恢复与安全终点规则。
27
28
  - [`review-handshake.md`](review-handshake.md) — 三阶段双向审查握手协议:四态处置、对称证据、分歧账本、收敛与 post-review commit 门禁。
29
+ - [`review-method.md`](review-method.md) — 三阶段共享检视方法:多遍检视、风险镜头、追踪与 finding 证据契约。
28
30
  - [`human-decision-context.md`](human-decision-context.md) — 新建人工裁决详情的自足上下文与规范结构。
29
31
  - [`task-short-id.md`](task-short-id.md) — 裸数字任务短号的解析、分配与生命周期。
30
32
  - [`milestone-inference.md`](milestone-inference.md) — create-task / code-task / create-pr 的 milestone 推断。
@@ -11,6 +11,7 @@
11
11
 
12
12
  - Never run `git commit` or `git add` automatically
13
13
  - Enter the commit workflow only when the user explicitly requests a commit
14
+ - The only exception is a one-use commit authorization issued by an active `run-task` explicitly started by the user. It authorizes this commit round but does not relax staging, sensitive-file, copyright, test, review-snapshot, HEAD/tree, or push gates.
14
15
  - After finishing code changes, remind the user to use the appropriate TUI commit command
15
16
 
16
17
  ## PR Rules
@@ -11,6 +11,7 @@
11
11
 
12
12
  - 绝对不要自动执行 `git commit` 或 `git add`
13
13
  - 仅在用户明确发起提交命令时才进入提交流程
14
+ - 唯一例外:用户显式启动的 active `run-task` 可签发一次性 commit authorization;它等价于本轮提交授权,但不得放宽暂存、敏感文件、版权、测试、审查快照、HEAD/tree 或 push 门禁。
14
15
  - 完成代码修改后,提醒用户使用对应 TUI 的提交命令
15
16
 
16
17
  ## PR 提交规则
@@ -4,32 +4,34 @@ This rule governs every new `[needs-human-decision]` detail block produced by an
4
4
 
5
5
  ## Self-contained Context
6
6
 
7
- A maintainer must be able to decide without asking a model to reconstruct context. Every item must state its background, decision objective, impact scope, risks, recommended option, and recommendation rationale. It must provide at least two options, each with both benefits and costs.
7
+ A maintainer must be able to understand the issue and choose without knowing the internal workflow or asking a model to reconstruct context. Start in plain language: explain why a decision is needed now, what must be chosen, which choice is recommended, and why. Then explain what the choice affects and what could go wrong if the wrong choice is made or no action is taken.
8
+
9
+ Provide at least two options with short names, and state the benefits and trade-offs of each one. Explain internal terms such as stage, severity, and evidence the first time they appear. IDs and evidence are for lookup and troubleshooting; they do not replace the plain-language explanation.
8
10
 
9
11
  ## Canonical Structure
10
12
 
11
13
  ```markdown
12
14
  ### {AN-N|PL-N|CD-N|HD-N}: {Title} [needs-human-decision]
13
15
 
14
- - **Background**: {facts, constraints, and why a decision is needed}
15
- - **Decision Objective**: {the single choice that must be made}
16
- - **Impact Scope**: {affected behavior, files, users, or precedent}
17
- - **Risks**: {risks of the wrong choice, delay, or no decision}
18
- - **Recommended Option**: {Option A/B/...}
19
- - **Recommendation Rationale**: {reason based on benefits, costs, and constraints}
16
+ - **Why a decision is needed now**: {plain-language facts, constraints, and why work cannot simply continue}
17
+ - **What needs a decision**: {the one choice that must be made}
18
+ - **Recommended choice**: {Option A/B/...}
19
+ - **Why this choice**: {reason based on benefits, trade-offs, and current constraints}
20
+ - **What this affects**: {affected behavior, files, users, or future practice}
21
+ - **What could go wrong**: {problems caused by the wrong choice or no action}
20
22
 
21
23
  #### Option A: {Name}
22
24
 
23
- - **Benefits**: {benefits of this option}
24
- - **Costs**: {costs and limitations of this option}
25
+ - **Benefits**: {what this option provides}
26
+ - **Trade-offs**: {what this option costs and where it falls short}
25
27
 
26
28
  #### Option B: {Name}
27
29
 
28
- - **Benefits**: {benefits of this option}
29
- - **Costs**: {costs and limitations of this option}
30
+ - **Benefits**: {what this option provides}
31
+ - **Trade-offs**: {what this option costs and where it falls short}
30
32
  ```
31
33
 
32
- Option C and supporting evidence may be added, but none of the fields above may be omitted or collapsed into an incomparable one-line option list. The heading ID must match the task.md Review Disagreement Ledger row, whose evidence must point to this stable heading anchor.
34
+ Option C and supporting evidence may be added, but none of the information above may be omitted or collapsed into an incomparable one-line option list. The heading ID must match the task.md Review Disagreement Ledger row. Its evidence (the reference used to find the original explanation) must point to this stable heading anchor.
33
35
 
34
36
  ## Decision Closure
35
37