@fitlab-ai/agent-infra 0.9.2 → 0.9.3

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 (318) hide show
  1. package/README.md +10 -9
  2. package/README.zh-CN.md +10 -9
  3. package/dist/bin/internal-cli.js +15 -0
  4. package/dist/lib/agent-clients/adapter.js +45 -2
  5. package/dist/lib/agent-clients/adapters/antigravity-cli.js +64 -0
  6. package/dist/lib/agent-clients/adapters/claude-code.js +10 -1
  7. package/dist/lib/agent-clients/adapters/codex.js +9 -0
  8. package/dist/lib/agent-clients/adapters/index.js +2 -2
  9. package/dist/lib/agent-clients/adapters/opencode.js +9 -0
  10. package/dist/lib/agent-clients/config.js +42 -4
  11. package/dist/lib/agent-clients/next-steps.js +11 -2
  12. package/dist/lib/agent-clients/reconcile.js +2 -1
  13. package/dist/lib/agent-clients/registry.js +7 -1
  14. package/dist/lib/agent-clients/schema.js +18 -0
  15. package/dist/lib/agent-clients/tokens.js +49 -0
  16. package/dist/lib/agent-clients/types.js +1 -1
  17. package/dist/lib/defaults.json +1 -1
  18. package/dist/lib/git/workflow.js +54 -1
  19. package/dist/lib/internal/agent-client.js +61 -4
  20. package/dist/lib/internal/git-workflow.js +6 -1
  21. package/dist/lib/internal/platform-checks.js +3 -3
  22. package/dist/lib/internal/platform-comment.js +29 -2
  23. package/dist/lib/internal/platform-issue.js +7 -0
  24. package/dist/lib/internal/platform-pr-review.js +132 -0
  25. package/dist/lib/internal/platform-pr.js +20 -2
  26. package/dist/lib/internal/platform-release-notes.js +52 -16
  27. package/dist/lib/internal/pr-review-grade.js +140 -0
  28. package/dist/lib/internal/release-workflow.js +13 -6
  29. package/dist/lib/internal/task-activity.js +73 -0
  30. package/dist/lib/internal/task-event.js +17 -1
  31. package/dist/lib/internal/task-lifecycle.js +7 -0
  32. package/dist/lib/internal/task-orchestration.js +51 -6
  33. package/dist/lib/internal/task-review.js +8 -3
  34. package/dist/lib/platform/adapters.js +8 -1
  35. package/dist/lib/platform/completion-backfill.js +122 -0
  36. package/dist/lib/platform/issue-comments.js +3 -2
  37. package/dist/lib/platform/merged-pr-equivalence.js +115 -5
  38. package/dist/lib/platform/pr-checks.js +64 -41
  39. package/dist/lib/platform/pr-review.js +166 -0
  40. package/dist/lib/platform/pull-requests.js +324 -3
  41. package/dist/lib/platform/release-notes.js +85 -3
  42. package/dist/lib/pr-review/evidence-grading.js +229 -0
  43. package/dist/lib/run/tui.js +3 -5
  44. package/dist/lib/sandbox/commands/create.js +0 -20
  45. package/dist/lib/sandbox/commands/show.js +1 -1
  46. package/dist/lib/task/activity-intent.js +101 -0
  47. package/dist/lib/task/artifact-lifecycle.js +2 -1
  48. package/dist/lib/task/commands/log.js +15 -14
  49. package/dist/lib/task/delegation-receipts.js +23 -2
  50. package/dist/lib/task/events.js +67 -28
  51. package/dist/lib/task/finalization-artifacts.js +35 -0
  52. package/dist/lib/task/lifecycle-execution.js +46 -0
  53. package/dist/lib/task/orchestration.js +408 -44
  54. package/dist/lib/task/review-finalization.js +29 -9
  55. package/dist/lib/task/task-execution-lock.js +231 -0
  56. package/dist/lib/task/verification-checks.js +1 -1
  57. package/dist/lib/task/verification-engine.js +218 -2
  58. package/dist/lib/task/verification.js +4 -3
  59. package/dist/lib/task/workspace-snapshot.js +17 -5
  60. package/lib/agent-clients/adapter.ts +75 -2
  61. package/lib/agent-clients/adapters/antigravity-cli.ts +65 -0
  62. package/lib/agent-clients/adapters/claude-code.ts +10 -1
  63. package/lib/agent-clients/adapters/codex.ts +9 -0
  64. package/lib/agent-clients/adapters/index.ts +2 -2
  65. package/lib/agent-clients/adapters/opencode.ts +9 -0
  66. package/lib/agent-clients/config.ts +49 -4
  67. package/lib/agent-clients/next-steps.ts +15 -2
  68. package/lib/agent-clients/reconcile.ts +2 -1
  69. package/lib/agent-clients/registry.ts +10 -0
  70. package/lib/agent-clients/schema.ts +18 -0
  71. package/lib/agent-clients/tokens.ts +53 -0
  72. package/lib/agent-clients/types.ts +15 -1
  73. package/lib/defaults.json +1 -1
  74. package/lib/git/workflow.ts +66 -2
  75. package/lib/internal/agent-client.ts +59 -4
  76. package/lib/internal/git-workflow.ts +5 -1
  77. package/lib/internal/platform-checks.ts +4 -4
  78. package/lib/internal/platform-comment.ts +17 -2
  79. package/lib/internal/platform-issue.ts +4 -0
  80. package/lib/internal/platform-pr-review.ts +104 -0
  81. package/lib/internal/platform-pr.ts +14 -1
  82. package/lib/internal/platform-release-notes.ts +59 -16
  83. package/lib/internal/pr-review-grade.ts +130 -0
  84. package/lib/internal/release-workflow.ts +13 -6
  85. package/lib/internal/task-activity.ts +55 -0
  86. package/lib/internal/task-event.ts +9 -1
  87. package/lib/internal/task-lifecycle.ts +4 -0
  88. package/lib/internal/task-orchestration.ts +45 -6
  89. package/lib/internal/task-review.ts +8 -3
  90. package/lib/platform/adapters.ts +29 -2
  91. package/lib/platform/completion-backfill.ts +134 -0
  92. package/lib/platform/issue-comments.ts +3 -2
  93. package/lib/platform/merged-pr-equivalence.ts +127 -5
  94. package/lib/platform/pr-checks.ts +72 -45
  95. package/lib/platform/pr-review.ts +201 -0
  96. package/lib/platform/pull-requests.ts +395 -2
  97. package/lib/platform/release-notes.ts +100 -4
  98. package/lib/pr-review/evidence-grading.ts +318 -0
  99. package/lib/run/tui.ts +3 -4
  100. package/lib/sandbox/commands/create.ts +0 -20
  101. package/lib/sandbox/commands/show.ts +1 -1
  102. package/lib/server/server.schema.json +2 -2
  103. package/lib/task/activity-intent.ts +128 -0
  104. package/lib/task/artifact-lifecycle.ts +2 -1
  105. package/lib/task/commands/log.ts +15 -14
  106. package/lib/task/delegation-receipts.ts +32 -3
  107. package/lib/task/events.ts +75 -30
  108. package/lib/task/finalization-artifacts.ts +58 -0
  109. package/lib/task/lifecycle-execution.ts +106 -0
  110. package/lib/task/orchestration.ts +543 -64
  111. package/lib/task/review-finalization.ts +40 -9
  112. package/lib/task/task-execution-lock.ts +296 -0
  113. package/lib/task/verification-checks.ts +1 -1
  114. package/lib/task/verification-engine.ts +249 -2
  115. package/lib/task/verification.ts +5 -3
  116. package/lib/task/workspace-snapshot.ts +26 -5
  117. package/package.json +3 -3
  118. package/templates/.agents/QUICKSTART.en.md +25 -8
  119. package/templates/.agents/QUICKSTART.zh-CN.md +25 -8
  120. package/templates/.agents/README.en.md +10 -7
  121. package/templates/.agents/README.zh-CN.md +10 -7
  122. package/templates/.agents/hooks/lifecycle-delegation.js +15 -4
  123. package/templates/.agents/rules/create-issue.github.en.md +4 -2
  124. package/templates/.agents/rules/create-issue.github.zh-CN.md +4 -2
  125. package/templates/.agents/rules/issue-fields.github.en.md +3 -1
  126. package/templates/.agents/rules/issue-fields.github.zh-CN.md +3 -1
  127. package/templates/.agents/rules/issue-pr-commands.en.md +5 -3
  128. package/templates/.agents/rules/issue-pr-commands.github.en.md +5 -3
  129. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +5 -3
  130. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +5 -3
  131. package/templates/.agents/rules/issue-sync.github.en.md +7 -3
  132. package/templates/.agents/rules/issue-sync.github.zh-CN.md +8 -4
  133. package/templates/.agents/rules/lifecycle-orchestration.en.md +5 -2
  134. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +5 -2
  135. package/templates/.agents/rules/milestone-inference.github.en.md +4 -2
  136. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +4 -2
  137. package/templates/.agents/rules/next-step-output.en.md +3 -1
  138. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -1
  139. package/templates/.agents/rules/no-mid-flow-questions.en.md +17 -0
  140. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +17 -0
  141. package/templates/.agents/rules/pr-checks-commands.en.md +3 -3
  142. package/templates/.agents/rules/pr-checks-commands.github.en.md +2 -2
  143. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +2 -2
  144. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +3 -3
  145. package/templates/.agents/rules/pr-sync.en.md +3 -1
  146. package/templates/.agents/rules/pr-sync.github.en.md +11 -1
  147. package/templates/.agents/rules/pr-sync.github.zh-CN.md +11 -1
  148. package/templates/.agents/rules/pr-sync.zh-CN.md +3 -1
  149. package/templates/.agents/rules/release-commands.en.md +1 -1
  150. package/templates/.agents/rules/release-commands.github.en.md +12 -2
  151. package/templates/.agents/rules/release-commands.github.zh-CN.md +12 -2
  152. package/templates/.agents/rules/release-commands.zh-CN.md +1 -1
  153. package/templates/.agents/rules/task-management.en.md +11 -0
  154. package/templates/.agents/rules/task-management.zh-CN.md +11 -0
  155. package/templates/.agents/skills/analyze-task/SKILL.en.md +10 -7
  156. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +10 -7
  157. package/templates/.agents/skills/block-task/SKILL.en.md +7 -5
  158. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +7 -5
  159. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -4
  160. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -4
  161. package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -1
  162. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -1
  163. package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -1
  164. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -1
  165. package/templates/.agents/skills/code-task/SKILL.en.md +9 -6
  166. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +11 -8
  167. package/templates/.agents/skills/commit/SKILL.en.md +3 -1
  168. package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -1
  169. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  170. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  171. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
  172. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
  173. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  174. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  175. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +6 -4
  176. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +6 -4
  177. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
  178. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
  179. package/templates/.agents/skills/complete-task/SKILL.en.md +21 -6
  180. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +21 -6
  181. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  182. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  183. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +17 -0
  184. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +17 -0
  185. package/templates/.agents/skills/create-pr/SKILL.en.md +3 -1
  186. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +3 -1
  187. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
  188. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
  189. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -16
  190. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +17 -16
  191. package/templates/.agents/skills/create-task/SKILL.en.md +5 -3
  192. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -3
  193. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -3
  194. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -3
  195. package/templates/.agents/skills/plan-task/SKILL.en.md +8 -5
  196. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +8 -5
  197. package/templates/.agents/skills/post-release/SKILL.en.md +2 -0
  198. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +2 -0
  199. package/templates/.agents/skills/release/SKILL.en.md +16 -10
  200. package/templates/.agents/skills/release/SKILL.zh-CN.md +16 -10
  201. package/templates/.agents/skills/restore-task/SKILL.en.md +4 -1
  202. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +4 -1
  203. package/templates/.agents/skills/review-analysis/SKILL.en.md +7 -4
  204. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +7 -4
  205. package/templates/.agents/skills/review-code/SKILL.en.md +9 -6
  206. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +9 -6
  207. package/templates/.agents/skills/review-plan/SKILL.en.md +7 -4
  208. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +7 -4
  209. package/templates/.agents/skills/review-pr/SKILL.en.md +158 -0
  210. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +158 -0
  211. package/templates/.agents/skills/review-pr/config/verify.en.json +37 -0
  212. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +37 -0
  213. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +65 -0
  214. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +65 -0
  215. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +18 -0
  216. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +18 -0
  217. package/templates/.agents/skills/review-pr/reference/report-template.en.md +85 -0
  218. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +85 -0
  219. package/templates/.agents/skills/run-task/SKILL.en.md +8 -8
  220. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +8 -8
  221. package/templates/.agents/skills/run-task/config/verify.en.json +2 -1
  222. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +2 -1
  223. package/templates/.agents/skills/run-task/reference/host-validation.en.md +20 -0
  224. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +20 -0
  225. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +35 -61
  226. package/templates/.agents/skills/watch-pr/SKILL.en.md +13 -13
  227. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +13 -13
  228. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +27 -6
  229. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +26 -5
  230. package/templates/.agents/templates/task.en.md +1 -1
  231. package/templates/.agents/templates/task.zh-CN.md +1 -1
  232. package/templates/.agents/workflows/bug-fix.en.yaml +3 -3
  233. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +3 -3
  234. package/templates/.agents/workflows/code-review.en.yaml +1 -1
  235. package/templates/.agents/workflows/code-review.zh-CN.yaml +1 -1
  236. package/templates/.agents/workflows/feature-development.en.yaml +4 -4
  237. package/templates/.agents/workflows/feature-development.zh-CN.yaml +4 -4
  238. package/templates/.agents/workflows/refactoring.en.yaml +3 -3
  239. package/templates/.agents/workflows/refactoring.zh-CN.yaml +3 -3
  240. package/templates/.claude/commands/post-release.en.md +1 -0
  241. package/templates/.claude/commands/post-release.zh-CN.md +1 -0
  242. package/templates/.claude/commands/review-pr.en.md +8 -0
  243. package/templates/.claude/commands/review-pr.zh-CN.md +8 -0
  244. package/templates/.gemini/commands/_project_/review-pr.en.toml +10 -0
  245. package/templates/.gemini/commands/_project_/review-pr.zh-CN.toml +10 -0
  246. package/templates/.opencode/commands/post-release.en.md +2 -0
  247. package/templates/.opencode/commands/post-release.zh-CN.md +2 -0
  248. package/templates/.opencode/commands/review-pr.en.md +11 -0
  249. package/templates/.opencode/commands/review-pr.zh-CN.md +11 -0
  250. package/dist/lib/agent-clients/adapters/gemini-cli.js +0 -64
  251. package/lib/agent-clients/adapters/gemini-cli.ts +0 -65
  252. package/templates/.gemini/commands/_project_/analyze-task.en.toml +0 -10
  253. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +0 -10
  254. package/templates/.gemini/commands/_project_/archive-tasks.en.toml +0 -10
  255. package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +0 -10
  256. package/templates/.gemini/commands/_project_/block-task.en.toml +0 -10
  257. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +0 -10
  258. package/templates/.gemini/commands/_project_/cancel-task.en.toml +0 -10
  259. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +0 -10
  260. package/templates/.gemini/commands/_project_/check-task.en.toml +0 -10
  261. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +0 -10
  262. package/templates/.gemini/commands/_project_/close-codescan.en.toml +0 -8
  263. package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +0 -8
  264. package/templates/.gemini/commands/_project_/close-dependabot.en.toml +0 -8
  265. package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +0 -8
  266. package/templates/.gemini/commands/_project_/code-task.en.toml +0 -10
  267. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +0 -10
  268. package/templates/.gemini/commands/_project_/commit.en.toml +0 -10
  269. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +0 -10
  270. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +0 -10
  271. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +0 -10
  272. package/templates/.gemini/commands/_project_/complete-task.en.toml +0 -10
  273. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +0 -10
  274. package/templates/.gemini/commands/_project_/create-pr.en.toml +0 -10
  275. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +0 -10
  276. package/templates/.gemini/commands/_project_/create-release-note.en.toml +0 -8
  277. package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +0 -8
  278. package/templates/.gemini/commands/_project_/create-task.en.toml +0 -8
  279. package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +0 -8
  280. package/templates/.gemini/commands/_project_/import-codescan.en.toml +0 -8
  281. package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +0 -8
  282. package/templates/.gemini/commands/_project_/import-dependabot.en.toml +0 -8
  283. package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +0 -8
  284. package/templates/.gemini/commands/_project_/import-issue.en.toml +0 -8
  285. package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +0 -8
  286. package/templates/.gemini/commands/_project_/init-labels.en.toml +0 -8
  287. package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +0 -8
  288. package/templates/.gemini/commands/_project_/init-milestones.en.toml +0 -10
  289. package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +0 -10
  290. package/templates/.gemini/commands/_project_/plan-task.en.toml +0 -10
  291. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +0 -10
  292. package/templates/.gemini/commands/_project_/post-release.en.toml +0 -6
  293. package/templates/.gemini/commands/_project_/post-release.zh-CN.toml +0 -6
  294. package/templates/.gemini/commands/_project_/refine-title.en.toml +0 -8
  295. package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +0 -8
  296. package/templates/.gemini/commands/_project_/release.en.toml +0 -8
  297. package/templates/.gemini/commands/_project_/release.zh-CN.toml +0 -8
  298. package/templates/.gemini/commands/_project_/restore-task.en.toml +0 -8
  299. package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +0 -8
  300. package/templates/.gemini/commands/_project_/review-analysis.en.toml +0 -10
  301. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +0 -10
  302. package/templates/.gemini/commands/_project_/review-code.en.toml +0 -10
  303. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +0 -10
  304. package/templates/.gemini/commands/_project_/review-plan.en.toml +0 -10
  305. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +0 -10
  306. package/templates/.gemini/commands/_project_/run-task.en.toml +0 -8
  307. package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +0 -8
  308. package/templates/.gemini/commands/_project_/test-integration.en.toml +0 -6
  309. package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +0 -6
  310. package/templates/.gemini/commands/_project_/test.en.toml +0 -6
  311. package/templates/.gemini/commands/_project_/test.zh-CN.toml +0 -6
  312. package/templates/.gemini/commands/_project_/update-agent-infra.en.toml +0 -6
  313. package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +0 -6
  314. package/templates/.gemini/commands/_project_/upgrade-dependency.en.toml +0 -8
  315. package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +0 -8
  316. package/templates/.gemini/commands/_project_/watch-pr.en.toml +0 -10
  317. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +0 -10
  318. package/templates/.gemini/settings.json +0 -3
@@ -20,6 +20,28 @@ import type {
20
20
 
21
21
  type AgentClientCapabilities = AgentClientCapabilityMap;
22
22
 
23
+ type AgentClientModelSelectionContext =
24
+ | Readonly<{
25
+ kind: 'catalog';
26
+ completeness: 'complete' | 'partial';
27
+ source: string;
28
+ models: readonly Readonly<{
29
+ id: string;
30
+ reasoningEfforts?: readonly string[];
31
+ }>[];
32
+ guidance?: string;
33
+ }>
34
+ | Readonly<{
35
+ kind: 'interactive-only';
36
+ command: string;
37
+ guidance: string;
38
+ }>;
39
+
40
+ type AgentClientDelegationEvidence = Readonly<{
41
+ actualModel: 'host-event' | 'unavailable';
42
+ actualReasoningEffort: 'host-event' | 'spawn-ack' | 'unavailable';
43
+ }>;
44
+
23
45
  type AgentClientSeedCommand = Readonly<{
24
46
  templates: Readonly<{
25
47
  en: string;
@@ -41,6 +63,8 @@ type AgentClientAdapter = Readonly<{
41
63
  displayName: string;
42
64
  invocation: string;
43
65
  capabilities: AgentClientCapabilities;
66
+ modelSelection: AgentClientModelSelectionContext;
67
+ delegationEvidence: AgentClientDelegationEvidence;
44
68
  project: AgentClientProjectDescriptor;
45
69
  sandbox: AgentClientSandboxDescriptor;
46
70
  }>;
@@ -211,6 +235,51 @@ function defineAgentClientAdapter(
211
235
  })
212
236
  ) as AgentClientCapabilities;
213
237
 
238
+ const modelSelection = candidate.modelSelection;
239
+ if (!modelSelection || typeof modelSelection !== 'object') {
240
+ throw new Error(`Agent Client '${candidate.id}' has an invalid model-selection context`);
241
+ }
242
+ let frozenModelSelection: AgentClientModelSelectionContext;
243
+ if (modelSelection.kind === 'interactive-only') {
244
+ if (!modelSelection.command?.trim() || !modelSelection.guidance?.trim()) {
245
+ throw new Error(`Agent Client '${candidate.id}' has an invalid model-selection context`);
246
+ }
247
+ frozenModelSelection = Object.freeze({ ...modelSelection });
248
+ } else if (
249
+ modelSelection.kind === 'catalog'
250
+ && ['complete', 'partial'].includes(modelSelection.completeness)
251
+ && typeof modelSelection.source === 'string'
252
+ && modelSelection.source.trim() !== ''
253
+ && Array.isArray(modelSelection.models)
254
+ ) {
255
+ const models = modelSelection.models.map((model) => {
256
+ if (!model?.id?.trim() || (model.reasoningEfforts && !Array.isArray(model.reasoningEfforts))) {
257
+ throw new Error(`Agent Client '${candidate.id}' has an invalid model-selection context`);
258
+ }
259
+ return Object.freeze({
260
+ id: model.id,
261
+ ...(model.reasoningEfforts
262
+ ? { reasoningEfforts: Object.freeze([...model.reasoningEfforts]) }
263
+ : {})
264
+ });
265
+ });
266
+ frozenModelSelection = Object.freeze({
267
+ ...modelSelection,
268
+ models: Object.freeze(models)
269
+ });
270
+ } else {
271
+ throw new Error(`Agent Client '${candidate.id}' has an invalid model-selection context`);
272
+ }
273
+
274
+ const evidence = candidate.delegationEvidence;
275
+ if (
276
+ !evidence
277
+ || !['host-event', 'unavailable'].includes(evidence.actualModel)
278
+ || !['host-event', 'spawn-ack', 'unavailable'].includes(evidence.actualReasoningEffort)
279
+ ) {
280
+ throw new Error(`Agent Client '${candidate.id}' has invalid delegation evidence`);
281
+ }
282
+
214
283
  if (
215
284
  typeof candidate.project !== 'object'
216
285
  || candidate.project === null
@@ -219,8 +288,8 @@ function defineAgentClientAdapter(
219
288
  throw new Error(`Agent Client '${candidate.id}' has an invalid project descriptor`);
220
289
  }
221
290
  const ownedPathPrefixes = candidate.project.ownedPathPrefixes;
222
- if (!Array.isArray(ownedPathPrefixes) || ownedPathPrefixes.length === 0) {
223
- throw new Error(`Agent Client '${candidate.id}' requires owned path prefixes`);
291
+ if (!Array.isArray(ownedPathPrefixes)) {
292
+ throw new Error(`Agent Client '${candidate.id}' has invalid owned path prefixes`);
224
293
  }
225
294
 
226
295
  const paths = ownedPathPrefixes.map((prefix) => {
@@ -441,6 +510,8 @@ function defineAgentClientAdapter(
441
510
  displayName: candidate.displayName,
442
511
  invocation: candidate.invocation,
443
512
  capabilities: Object.freeze(capabilities),
513
+ modelSelection: frozenModelSelection,
514
+ delegationEvidence: Object.freeze({ ...evidence }),
444
515
  project: Object.freeze({
445
516
  ownedPathPrefixes: Object.freeze(paths),
446
517
  ...projectAssets,
@@ -454,7 +525,9 @@ export { defineAgentClientAdapter };
454
525
  export type {
455
526
  AgentClientAdapter,
456
527
  AgentClientCapabilities,
528
+ AgentClientDelegationEvidence,
457
529
  AgentClientManifestEntry,
530
+ AgentClientModelSelectionContext,
458
531
  AgentClientProjectDescriptor,
459
532
  AgentClientSeedCommand,
460
533
  AgentClientRegistry
@@ -0,0 +1,65 @@
1
+ import { defineAgentClientAdapter } from '../adapter.ts';
2
+ import { hostJoin } from '../../sandbox/engines/wsl2-paths.ts';
3
+
4
+ const antigravityCliAdapter = defineAgentClientAdapter({
5
+ id: 'antigravity-cli',
6
+ displayName: 'Antigravity CLI',
7
+ invocation: '/${skillName}',
8
+ capabilities: {
9
+ instructions: { level: 'compatible' },
10
+ skills: { level: 'integrated' },
11
+ commands: { level: 'integrated' },
12
+ hooks: { level: 'compatible' },
13
+ subagents: { level: 'unsupported' },
14
+ orchestration: { level: 'unsupported' },
15
+ sandbox: { level: 'integrated' },
16
+ verification: { level: 'compatible' }
17
+ },
18
+ modelSelection: {
19
+ kind: 'interactive-only',
20
+ command: '/model',
21
+ guidance: 'Use the host model picker for the complete model and reasoning-effort catalog.'
22
+ },
23
+ delegationEvidence: {
24
+ actualModel: 'unavailable',
25
+ actualReasoningEffort: 'unavailable'
26
+ },
27
+ project: {
28
+ ownedPathPrefixes: [],
29
+ managed: [],
30
+ merged: [],
31
+ ejected: [],
32
+ seedCommands: []
33
+ },
34
+ sandbox: {
35
+ createTool: ({ home }) => ({
36
+ id: 'antigravity-cli',
37
+ name: 'Antigravity CLI',
38
+ install: {
39
+ type: 'shell',
40
+ cmd: 'curl -fsSL https://antigravity.google/cli/install.sh | bash -s -- --dir /home/devuser/.npm-global/bin'
41
+ },
42
+ sandboxBase: hostJoin(home, '.agent-infra', 'sandboxes', 'antigravity-cli'),
43
+ containerMount: '/home/devuser/.gemini',
44
+ versionCmd: 'agy --version',
45
+ setupHint: 'Run agy inside the container to finish authentication.',
46
+ hostPreSeedFiles: [
47
+ {
48
+ hostPath: hostJoin(home, '.gemini', 'antigravity-cli', 'keybindings.json'),
49
+ sandboxName: 'antigravity-cli/keybindings.json'
50
+ },
51
+ {
52
+ hostPath: hostJoin(home, '.gemini', 'config', 'mcp_config.json'),
53
+ sandboxName: 'config/mcp_config.json'
54
+ }
55
+ ]
56
+ }),
57
+ aliases: [
58
+ { name: 'antigravity-yolo', command: 'agy --dangerously-skip-permissions; tput ed' },
59
+ { name: 'agy-yolo', command: 'agy --dangerously-skip-permissions; tput ed' }
60
+ ],
61
+ hooks: []
62
+ }
63
+ });
64
+
65
+ export { antigravityCliAdapter };
@@ -11,10 +11,19 @@ const claudeCodeAdapter = defineAgentClientAdapter({
11
11
  commands: { level: 'integrated' },
12
12
  hooks: { level: 'integrated' },
13
13
  subagents: { level: 'experimental' },
14
- orchestration: { level: 'experimental' },
14
+ orchestration: { level: 'unsupported' },
15
15
  sandbox: { level: 'integrated' },
16
16
  verification: { level: 'compatible' }
17
17
  },
18
+ modelSelection: {
19
+ kind: 'interactive-only',
20
+ command: '/model',
21
+ guidance: 'Use the host model picker for the complete model and reasoning-effort catalog.'
22
+ },
23
+ delegationEvidence: {
24
+ actualModel: 'unavailable',
25
+ actualReasoningEffort: 'unavailable'
26
+ },
18
27
  project: {
19
28
  ownedPathPrefixes: ['.claude/'],
20
29
  managed: ['.claude/commands/', '.claude/agents/'],
@@ -19,6 +19,15 @@ const codexAdapter = defineAgentClientAdapter({
19
19
  sandbox: { level: 'integrated' },
20
20
  verification: { level: 'compatible' }
21
21
  },
22
+ modelSelection: {
23
+ kind: 'interactive-only',
24
+ command: '/model',
25
+ guidance: 'Use the host model picker for the complete model and reasoning-effort catalog.'
26
+ },
27
+ delegationEvidence: {
28
+ actualModel: 'unavailable',
29
+ actualReasoningEffort: 'unavailable'
30
+ },
22
31
  project: {
23
32
  ownedPathPrefixes: ['.codex/'],
24
33
  managed: ['.codex/hooks.json', '.codex/agents/'],
@@ -2,14 +2,14 @@ import { AGENT_CLIENT_IDS } from '../types.ts';
2
2
  import type { AgentClientAdapter } from '../adapter.ts';
3
3
  import { claudeCodeAdapter } from './claude-code.ts';
4
4
  import { codexAdapter } from './codex.ts';
5
- import { geminiCliAdapter } from './gemini-cli.ts';
5
+ import { antigravityCliAdapter } from './antigravity-cli.ts';
6
6
  import { opencodeAdapter } from './opencode.ts';
7
7
 
8
8
  const adaptersById = new Map(
9
9
  [
10
10
  claudeCodeAdapter,
11
11
  codexAdapter,
12
- geminiCliAdapter,
12
+ antigravityCliAdapter,
13
13
  opencodeAdapter
14
14
  ].map((adapter) => [adapter.id, adapter])
15
15
  );
@@ -17,6 +17,15 @@ const opencodeAdapter = defineAgentClientAdapter({
17
17
  sandbox: { level: 'integrated' },
18
18
  verification: { level: 'compatible' }
19
19
  },
20
+ modelSelection: {
21
+ kind: 'interactive-only',
22
+ command: '/models',
23
+ guidance: 'Use the host model picker for the complete model and reasoning-effort catalog.'
24
+ },
25
+ delegationEvidence: {
26
+ actualModel: 'unavailable',
27
+ actualReasoningEffort: 'unavailable'
28
+ },
20
29
  project: {
21
30
  ownedPathPrefixes: ['.opencode/'],
22
31
  managed: ['.opencode/commands/'],
@@ -6,7 +6,8 @@ import type {
6
6
  AgentClientConfig,
7
7
  AgentClientId,
8
8
  AgentClientsConfig,
9
- AgentClientState
9
+ AgentClientState,
10
+ OrchestrationModelPolicy
10
11
  } from './types.ts';
11
12
 
12
13
  type AgentClientConfigInput = Readonly<{
@@ -65,12 +66,49 @@ function fail(code: AgentClientDiagnosticCode, path: string): never {
65
66
  throw new AgentClientConfigError({ code, path });
66
67
  }
67
68
 
69
+ function parseExactText(value: unknown, path: string): string {
70
+ if (typeof value !== 'string' || value.length === 0 || value.trim() !== value) {
71
+ fail('INVALID_AGENT_CLIENTS', path);
72
+ }
73
+ return value;
74
+ }
75
+
76
+ function parseOrchestrationPolicy(value: unknown, path: string): OrchestrationModelPolicy {
77
+ if (!isRecord(value)) fail('INVALID_AGENT_CLIENTS', path);
78
+ const keys = Object.keys(value);
79
+ if (
80
+ keys.length !== 2
81
+ || !hasOwn(value, 'executor')
82
+ || !hasOwn(value, 'reviewer')
83
+ ) {
84
+ fail('INVALID_AGENT_CLIENTS', path);
85
+ }
86
+ const parseRole = (candidate: unknown, rolePath: string) => {
87
+ if (
88
+ !isRecord(candidate)
89
+ || Object.keys(candidate).length !== 2
90
+ || !hasOwn(candidate, 'model')
91
+ || !hasOwn(candidate, 'reasoningEffort')
92
+ ) {
93
+ fail('INVALID_AGENT_CLIENTS', rolePath);
94
+ }
95
+ return Object.freeze({
96
+ model: parseExactText(candidate.model, `${rolePath}.model`),
97
+ reasoningEffort: parseExactText(candidate.reasoningEffort, `${rolePath}.reasoningEffort`)
98
+ });
99
+ };
100
+ const executor = parseRole(value.executor, `${path}.executor`);
101
+ const reviewer = parseRole(value.reviewer, `${path}.reviewer`);
102
+ return Object.freeze({ executor, reviewer });
103
+ }
104
+
68
105
  function parseCanonical(value: unknown): AgentClientState {
69
106
  if (!Array.isArray(value)) fail('INVALID_AGENT_CLIENTS', 'agentClients');
70
107
 
71
108
  const entries = new Map<AgentClientId, Readonly<{
72
109
  enabled: boolean;
73
110
  installInSandbox: boolean;
111
+ orchestration?: OrchestrationModelPolicy;
74
112
  }>>();
75
113
 
76
114
  for (const [index, candidate] of value.entries()) {
@@ -79,10 +117,11 @@ function parseCanonical(value: unknown): AgentClientState {
79
117
 
80
118
  const keys = Object.keys(candidate);
81
119
  if (
82
- keys.length !== 3
120
+ (keys.length !== 3 && keys.length !== 4)
83
121
  || !hasOwn(candidate, 'id')
84
122
  || !hasOwn(candidate, 'enabled')
85
123
  || !hasOwn(candidate, 'installInSandbox')
124
+ || (keys.length === 4 && !hasOwn(candidate, 'orchestration'))
86
125
  ) {
87
126
  fail('INVALID_AGENT_CLIENTS', path);
88
127
  }
@@ -100,7 +139,10 @@ function parseCanonical(value: unknown): AgentClientState {
100
139
  }
101
140
  entries.set(candidate.id, {
102
141
  enabled: candidate.enabled,
103
- installInSandbox: candidate.installInSandbox
142
+ installInSandbox: candidate.installInSandbox,
143
+ ...(hasOwn(candidate, 'orchestration')
144
+ ? { orchestration: parseOrchestrationPolicy(candidate.orchestration, `${path}.orchestration`) }
145
+ : {})
104
146
  });
105
147
  }
106
148
 
@@ -117,7 +159,10 @@ function serializeAgentClients(state: AgentClientState): AgentClientsConfig {
117
159
  return AGENT_CLIENT_IDS.map((id): AgentClientConfig => ({
118
160
  id,
119
161
  enabled: state[id].enabled,
120
- installInSandbox: state[id].installInSandbox
162
+ installInSandbox: state[id].installInSandbox,
163
+ ...(state[id].orchestration
164
+ ? { orchestration: structuredClone(state[id].orchestration) }
165
+ : {})
121
166
  }));
122
167
  }
123
168
 
@@ -1,5 +1,6 @@
1
1
  import { listEnabledAgentClientAdapters } from './registry.ts';
2
2
  import { renderAgentClientInvocation } from './invocation.ts';
3
+ import semver from 'semver';
3
4
  import type { CustomTUI } from './custom-tuis.ts';
4
5
  import type { AgentClientId, AgentClientState } from './types.ts';
5
6
 
@@ -16,6 +17,7 @@ type RenderNextStepsInput = Readonly<{
16
17
  customTUIs: readonly CustomTUI[];
17
18
  skillName: string;
18
19
  taskRef?: string;
20
+ version?: string;
19
21
  }>;
20
22
 
21
23
  const SAFE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
@@ -35,6 +37,17 @@ function renderNextStepCommands(
35
37
  if (input.taskRef !== undefined && !SAFE_TASK_REF.test(input.taskRef)) {
36
38
  throw new Error('Invalid task ref');
37
39
  }
40
+ if (
41
+ input.version !== undefined
42
+ && (!/^[0-9]/.test(input.version) || semver.valid(input.version) !== input.version)
43
+ ) {
44
+ throw new Error('Invalid version');
45
+ }
46
+
47
+ const args = [
48
+ ...(input.taskRef === undefined ? [] : [input.taskRef]),
49
+ ...(input.version === undefined ? [] : [input.version])
50
+ ];
38
51
 
39
52
  const builtins = listEnabledAgentClientAdapters(input.state).map(
40
53
  (adapter): NextStepCommand => Object.freeze({
@@ -46,7 +59,7 @@ function renderNextStepCommands(
46
59
  {
47
60
  projectName: input.projectName,
48
61
  skillName: input.skillName,
49
- args: input.taskRef === undefined ? [] : [input.taskRef]
62
+ args
50
63
  }
51
64
  )
52
65
  })
@@ -60,7 +73,7 @@ function renderNextStepCommands(
60
73
  {
61
74
  projectName: input.projectName,
62
75
  skillName: input.skillName,
63
- args: input.taskRef === undefined ? [] : [input.taskRef]
76
+ args
64
77
  }
65
78
  )
66
79
  })
@@ -236,7 +236,8 @@ function planAgentClientReconciliation(input: Readonly<{
236
236
  const actionableSeed = seedOperations.some((operation) =>
237
237
  operation.kind === 'write' || operation.kind === 'remove'
238
238
  );
239
- const changed = JSON.stringify(nextConfig) !== JSON.stringify(input.config) || actionableSeed;
239
+ const changed = JSON.stringify(nextConfig) !== JSON.stringify(input.config)
240
+ || actionableSeed;
240
241
 
241
242
  return Object.freeze({
242
243
  source: normalized.source,
@@ -104,6 +104,14 @@ function getAgentClientCapability(
104
104
  return getAgentClientAdapter(id).capabilities[capability];
105
105
  }
106
106
 
107
+ function getAgentClientModelSelection(id: unknown) {
108
+ return getAgentClientAdapter(id).modelSelection;
109
+ }
110
+
111
+ function getAgentClientDelegationEvidence(id: unknown) {
112
+ return getAgentClientAdapter(id).delegationEvidence;
113
+ }
114
+
107
115
  function listEnabledAgentClientAdaptersByCapability(
108
116
  state: AgentClientState,
109
117
  capability: AgentClientCapabilityId,
@@ -137,6 +145,8 @@ export {
137
145
  createAgentClientManifest,
138
146
  getAgentClientAdapter,
139
147
  getAgentClientCapability,
148
+ getAgentClientDelegationEvidence,
149
+ getAgentClientModelSelection,
140
150
  listAgentClientAdapters,
141
151
  listEnabledAgentClientAdapters,
142
152
  listEnabledAgentClientAdaptersByCapability,
@@ -29,6 +29,15 @@ const AGENT_CLIENTS_SCHEMA = {
29
29
  },
30
30
  installInSandbox: {
31
31
  type: 'boolean'
32
+ },
33
+ orchestration: {
34
+ type: 'object',
35
+ additionalProperties: false,
36
+ required: ['executor', 'reviewer'],
37
+ properties: {
38
+ executor: { $ref: '#/definitions/orchestrationRolePolicy' },
39
+ reviewer: { $ref: '#/definitions/orchestrationRolePolicy' }
40
+ }
32
41
  }
33
42
  }
34
43
  }
@@ -48,6 +57,15 @@ const AGENT_CLIENTS_SCHEMA = {
48
57
  }
49
58
  },
50
59
  definitions: {
60
+ orchestrationRolePolicy: {
61
+ type: 'object',
62
+ additionalProperties: false,
63
+ required: ['model', 'reasoningEffort'],
64
+ properties: {
65
+ model: { type: 'string', minLength: 1 },
66
+ reasoningEffort: { type: 'string', minLength: 1 }
67
+ }
68
+ },
51
69
  agentClientCapabilityId: {
52
70
  type: 'string',
53
71
  enum: [...AGENT_CLIENT_CAPABILITY_IDS]
@@ -0,0 +1,53 @@
1
+ // Active AI collaborator short tokens — the write-side whitelist for the
2
+ // activity log. Migrated from lib/task/commands/log.ts so that the write-side
3
+ // internal commands and the rendering side share one definition. Historical
4
+ // Gemini tokens remain read-only and are handled by classifyAgent below.
5
+ export const KNOWN_AI_AGENTS: ReadonlySet<string> =
6
+ new Set(['claude', 'codex', 'antigravity', 'opencode', 'cursor']);
7
+
8
+ // Long name -> short name mapping (HD-4, decision A): `claude-code` reuses the
9
+ // existing orchestration precedent, and `antigravity-cli` is the active
10
+ // client. `gemini-cli` is intentionally not writable.
11
+ export const AGENT_LONG_NAMES: Readonly<Record<string, string>> = {
12
+ 'claude-code': 'claude',
13
+ 'antigravity-cli': 'antigravity'
14
+ };
15
+
16
+ export const AGENT_USAGE_HINT =
17
+ "agent must be a short token (claude/codex/antigravity/opencode/cursor), " +
18
+ "a long name (claude-code -> claude, antigravity-cli -> antigravity), or 'human'";
19
+
20
+ // Read-side historical compatibility for activity-log rendering: `gemini` and
21
+ // `gemini-cli` stay recognizable when displaying old logs, but are never
22
+ // accepted by normalizeAgentToken (write side).
23
+ const READ_KNOWN_AI_AGENTS: ReadonlySet<string> =
24
+ new Set([...KNOWN_AI_AGENTS, 'gemini']);
25
+
26
+ const READ_AGENT_LONG_NAMES: Readonly<Record<string, string>> = {
27
+ ...AGENT_LONG_NAMES,
28
+ 'gemini-cli': 'gemini'
29
+ };
30
+
31
+ // Strict write-side validation: the value must be exactly a short token, a
32
+ // long name, or 'human'; returns the normalized short token, or null when
33
+ // the value is not a recognized agent.
34
+ export function normalizeAgentToken(value: string): string | null {
35
+ const trimmed = value.trim();
36
+ if (trimmed === 'human') return 'human';
37
+ if (KNOWN_AI_AGENTS.has(trimmed)) return trimmed;
38
+ const short = AGENT_LONG_NAMES[trimmed];
39
+ return short ?? null;
40
+ }
41
+
42
+ // Loose rendering-side classification: tolerates historical parenthetical
43
+ // annotations; unknown tokens keep the `human` grouping but get a visible
44
+ // signal. The "known AI token" test is `classifyAgent(value).status === 'ai'`.
45
+ export function classifyAgent(raw: string):
46
+ { status: 'ai' | 'human' | 'unknown'; display: string } {
47
+ const token = raw.trim().split(/\s+/)[0]?.replace(/\(.*$/, '') ?? '';
48
+ if (token === '') return { status: 'unknown', display: 'human' };
49
+ if (token === 'human') return { status: 'human', display: 'human' };
50
+ if (READ_KNOWN_AI_AGENTS.has(token)) return { status: 'ai', display: token };
51
+ const short = READ_AGENT_LONG_NAMES[token];
52
+ return short ? { status: 'ai', display: short } : { status: 'unknown', display: 'human' };
53
+ }
@@ -1,16 +1,27 @@
1
1
  const AGENT_CLIENT_IDS = [
2
2
  'claude-code',
3
3
  'codex',
4
- 'gemini-cli',
4
+ 'antigravity-cli',
5
5
  'opencode'
6
6
  ] as const;
7
7
 
8
8
  type AgentClientId = (typeof AGENT_CLIENT_IDS)[number];
9
9
 
10
+ type OrchestrationRolePolicy = Readonly<{
11
+ model: string;
12
+ reasoningEffort: string;
13
+ }>;
14
+
15
+ type OrchestrationModelPolicy = Readonly<{
16
+ executor: OrchestrationRolePolicy;
17
+ reviewer: OrchestrationRolePolicy;
18
+ }>;
19
+
10
20
  type AgentClientConfig = Readonly<{
11
21
  id: AgentClientId;
12
22
  enabled: boolean;
13
23
  installInSandbox: boolean;
24
+ orchestration?: OrchestrationModelPolicy;
14
25
  }>;
15
26
 
16
27
  type AgentClientsConfig = readonly AgentClientConfig[];
@@ -21,6 +32,7 @@ type AgentClientState = Readonly<
21
32
  Readonly<{
22
33
  enabled: boolean;
23
34
  installInSandbox: boolean;
35
+ orchestration?: OrchestrationModelPolicy;
24
36
  }>
25
37
  >
26
38
  >;
@@ -68,6 +80,8 @@ export {
68
80
  };
69
81
  export type {
70
82
  AgentClientId,
83
+ OrchestrationRolePolicy,
84
+ OrchestrationModelPolicy,
71
85
  AgentClientConfig,
72
86
  AgentClientsConfig,
73
87
  AgentClientState,
package/lib/defaults.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "installInSandbox": true
15
15
  },
16
16
  {
17
- "id": "gemini-cli",
17
+ "id": "antigravity-cli",
18
18
  "enabled": true,
19
19
  "installInSandbox": true
20
20
  },
@@ -1,4 +1,6 @@
1
1
  import { spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
2
4
 
3
5
  type CommandResult = { status: number | null; stdout: string; stderr: string };
4
6
  type GitRunner = (args: readonly string[], cwd: string) => CommandResult;
@@ -18,6 +20,10 @@ function value(runner: GitRunner, cwd: string, args: readonly string[], trim = t
18
20
  return result.status === 0 ? (trim ? result.stdout.trim() : result.stdout.replace(/\n$/, '')) : null;
19
21
  }
20
22
 
23
+ function cleanMessage(message: string): string {
24
+ return message.replace(/(https?:\/\/)[^\s/@:]+(?::[^\s/@]*)?@/gi, '$1***@').trim();
25
+ }
26
+
21
27
  function inspectGitWorkflow(cwd: string, runner: GitRunner = defaultRunner, remoteInput?: { remote: string; refs: readonly string[] }) {
22
28
  const head = value(runner, cwd, ['rev-parse', 'HEAD']);
23
29
  const branch = value(runner, cwd, ['branch', '--show-current']);
@@ -97,5 +103,63 @@ function pushGitRefs(input: { cwd: string; remote: string; refs: readonly string
97
103
  return { status: failures === 0 ? 'applied' as const : failures === operations.length ? 'failed' as const : 'degraded' as const, changed: failures < operations.length, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations, error: failures ? { code: 'GIT_PUSH_PARTIAL', message: `${failures} ref push operation(s) failed` } : null };
98
104
  }
99
105
 
100
- export { commitExplicitPaths, inspectGitWorkflow, pushGitRefs };
101
- export type { CommandResult, GitRunner };
106
+ type PushRebasedInput = {
107
+ cwd: string;
108
+ remote: string;
109
+ branch: string;
110
+ expectedOldHead: string;
111
+ newHead: string;
112
+ baseBranch: string;
113
+ expectedBaseHead: string;
114
+ };
115
+
116
+ function pushRebasedBranch(input: PushRebasedInput, runner: GitRunner = defaultRunner) {
117
+ const sha = /^[0-9a-f]{40}$/i;
118
+ const refName = /^(?!-)(?!.*\.\.)(?!.*(?:^|\/)\.)(?!.*[~^:?*\[\\\s])(?:[A-Za-z0-9._-]+\/)*[A-Za-z0-9._-]+$/;
119
+ if (!input.remote || !refName.test(input.remote) || !refName.test(input.branch) || !refName.test(input.baseBranch) ||
120
+ !sha.test(input.expectedOldHead) || !sha.test(input.newHead) || !sha.test(input.expectedBaseHead)) {
121
+ return { status: 'failed' as const, changed: false, snapshot: null, operations: [], error: { code: 'GIT_REBASED_INPUT_INVALID', message: 'Remote, branches, and full 40-character SHAs are required' } };
122
+ }
123
+ const snapshot = inspectGitWorkflow(input.cwd, runner).snapshot;
124
+ if (!snapshot) return { status: 'failed' as const, changed: false, snapshot: null, operations: [], error: { code: 'GIT_INSPECT_FAILED', message: 'Unable to inspect Git repository' } };
125
+ if (snapshot.branch !== input.branch || snapshot.head !== input.newHead) {
126
+ return { status: 'failed' as const, changed: false, snapshot, operations: [], error: { code: 'GIT_LOCAL_IDENTITY_MISMATCH', message: 'Current branch or HEAD does not match the rebased intent' } };
127
+ }
128
+ const rebasePaths = ['rebase-merge', 'rebase-apply']
129
+ .map((name) => value(runner, input.cwd, ['rev-parse', '--git-path', name]))
130
+ .filter((candidate): candidate is string => Boolean(candidate));
131
+ if (snapshot.worktree.length > 0 || snapshot.staged.length > 0 ||
132
+ run(runner, input.cwd, ['rev-parse', '-q', '--verify', 'REBASE_HEAD']).status === 0 ||
133
+ rebasePaths.some((candidate) => fs.existsSync(path.isAbsolute(candidate) ? candidate : path.join(input.cwd, candidate)))) {
134
+ return { status: 'failed' as const, changed: false, snapshot, operations: [], error: { code: 'GIT_LOCAL_STATE_UNSAFE', message: 'Working tree must be clean with no rebase in progress' } };
135
+ }
136
+ const remoteRef = `refs/heads/${input.branch}`;
137
+ const baseRef = `refs/heads/${input.baseBranch}`;
138
+ const remoteHead = value(runner, input.cwd, ['ls-remote', '--exit-code', input.remote, remoteRef])?.split(/\s+/)[0] ?? null;
139
+ if (remoteHead !== input.expectedOldHead) {
140
+ return { status: 'failed' as const, changed: false, snapshot, operations: [], error: { code: 'GIT_REMOTE_HEAD_MISMATCH', message: `Expected remote head ${input.expectedOldHead}, received ${remoteHead ?? 'unavailable'}` } };
141
+ }
142
+ const baseHead = value(runner, input.cwd, ['ls-remote', '--exit-code', input.remote, baseRef])?.split(/\s+/)[0] ?? null;
143
+ if (baseHead !== input.expectedBaseHead) {
144
+ return { status: 'failed' as const, changed: false, snapshot, operations: [], error: { code: 'GIT_REMOTE_BASE_MISMATCH', message: `Expected base head ${input.expectedBaseHead}, received ${baseHead ?? 'unavailable'}` } };
145
+ }
146
+ if (run(runner, input.cwd, ['merge-base', '--is-ancestor', input.expectedBaseHead, input.newHead]).status !== 0) {
147
+ return { status: 'failed' as const, changed: false, snapshot, operations: [], error: { code: 'GIT_REBASED_ANCESTOR_MISMATCH', message: 'Rebased head does not contain the expected base head' } };
148
+ }
149
+ const pushed = run(runner, input.cwd, [
150
+ 'push', `--force-with-lease=${remoteRef}:${input.expectedOldHead}`,
151
+ input.remote, `${input.newHead}:${remoteRef}`
152
+ ]);
153
+ if (pushed.status !== 0) {
154
+ const message = cleanMessage(pushed.stderr) || 'Rebased branch push was rejected';
155
+ return { status: 'failed' as const, changed: false, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'push-rebased', status: 'failed' as const, ref: input.branch, message }], error: { code: 'GIT_REBASED_PUSH_REJECTED', message } };
156
+ }
157
+ const verified = value(runner, input.cwd, ['ls-remote', '--exit-code', input.remote, remoteRef])?.split(/\s+/)[0] ?? null;
158
+ if (verified !== input.newHead) {
159
+ return { status: 'failed' as const, changed: true, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'push-rebased', status: 'failed' as const, ref: input.branch, message: 'Remote ref verification failed' }], error: { code: 'GIT_REBASED_VERIFY_FAILED', message: `Expected pushed head ${input.newHead}, received ${verified ?? 'unavailable'}` } };
160
+ }
161
+ return { status: 'applied' as const, changed: true, snapshot: inspectGitWorkflow(input.cwd, runner).snapshot, operations: [{ name: 'push-rebased', status: 'applied' as const, ref: input.branch }], error: null };
162
+ }
163
+
164
+ export { commitExplicitPaths, inspectGitWorkflow, pushGitRefs, pushRebasedBranch };
165
+ export type { CommandResult, GitRunner, PushRebasedInput };