@fitlab-ai/agent-infra 0.9.2 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/README.md +12 -9
  2. package/README.zh-CN.md +12 -9
  3. package/bin/cli.ts +12 -0
  4. package/dist/bin/cli.js +14 -0
  5. package/dist/bin/internal-cli.js +134 -108
  6. package/dist/lib/agent-clients/adapter.js +137 -4
  7. package/dist/lib/agent-clients/adapters/antigravity-cli.js +64 -0
  8. package/dist/lib/{sandbox/credentials.js → agent-clients/adapters/claude-code-credentials.js} +4 -14
  9. package/dist/lib/agent-clients/adapters/claude-code-refresh.js +85 -0
  10. package/dist/lib/agent-clients/adapters/claude-code-sandbox.js +247 -0
  11. package/dist/lib/agent-clients/adapters/claude-code.js +27 -4
  12. package/dist/lib/agent-clients/adapters/codex.js +9 -0
  13. package/dist/lib/agent-clients/adapters/index.js +2 -2
  14. package/dist/lib/agent-clients/adapters/opencode-sandbox.js +108 -0
  15. package/dist/lib/agent-clients/adapters/opencode.js +24 -3
  16. package/dist/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
  17. package/dist/lib/agent-clients/config.js +42 -4
  18. package/dist/lib/agent-clients/next-steps.js +11 -2
  19. package/dist/lib/agent-clients/reconcile.js +2 -1
  20. package/dist/lib/agent-clients/registry.js +16 -2
  21. package/dist/lib/agent-clients/schema.js +18 -0
  22. package/dist/lib/agent-clients/tokens.js +49 -0
  23. package/dist/lib/agent-clients/types.js +1 -1
  24. package/dist/lib/defaults.json +1 -1
  25. package/dist/lib/git/workflow.js +54 -1
  26. package/dist/lib/internal/agent-client.js +61 -4
  27. package/dist/lib/internal/git-workflow.js +6 -1
  28. package/dist/lib/internal/platform-checks.js +3 -3
  29. package/dist/lib/internal/platform-comment.js +29 -2
  30. package/dist/lib/internal/platform-issue.js +7 -0
  31. package/dist/lib/internal/platform-pr-review.js +132 -0
  32. package/dist/lib/internal/platform-pr.js +20 -2
  33. package/dist/lib/internal/platform-release-notes.js +52 -16
  34. package/dist/lib/internal/pr-review-grade.js +140 -0
  35. package/dist/lib/internal/release-workflow.js +13 -6
  36. package/dist/lib/internal/sandbox-control.js +24 -0
  37. package/dist/lib/internal/task-activity.js +105 -0
  38. package/dist/lib/internal/task-event.js +17 -1
  39. package/dist/lib/internal/task-ledger.js +12 -3
  40. package/dist/lib/internal/task-lifecycle.js +26 -1
  41. package/dist/lib/internal/task-orchestration.js +167 -18
  42. package/dist/lib/internal/task-review.js +8 -3
  43. package/dist/lib/platform/adapters.js +8 -1
  44. package/dist/lib/platform/completion-backfill.js +122 -0
  45. package/dist/lib/platform/github-client.js +19 -2
  46. package/dist/lib/platform/issue-comments.js +3 -2
  47. package/dist/lib/platform/merged-pr-equivalence.js +115 -5
  48. package/dist/lib/platform/pr-checks.js +65 -42
  49. package/dist/lib/platform/pr-review.js +166 -0
  50. package/dist/lib/platform/pull-requests.js +371 -4
  51. package/dist/lib/platform/release-notes.js +85 -3
  52. package/dist/lib/platform/releases.js +13 -5
  53. package/dist/lib/pr-review/evidence-grading.js +229 -0
  54. package/dist/lib/process-data/index.js +239 -0
  55. package/dist/lib/process-data/normalize.js +198 -0
  56. package/dist/lib/process-data/privacy.js +33 -0
  57. package/dist/lib/process-data/reconcile.js +95 -0
  58. package/dist/lib/process-data/repair.js +58 -0
  59. package/dist/lib/process-data/sources.js +345 -0
  60. package/dist/lib/process-data/store.js +282 -0
  61. package/dist/lib/process-data/types.js +2 -0
  62. package/dist/lib/run/index.js +4 -3
  63. package/dist/lib/run/tui.js +10 -13
  64. package/dist/lib/sandbox/agent-client-reconciler.js +26 -2
  65. package/dist/lib/sandbox/capture.js +7 -2
  66. package/dist/lib/sandbox/commands/create.js +109 -248
  67. package/dist/lib/sandbox/commands/enter.js +15 -47
  68. package/dist/lib/sandbox/commands/list-running.js +16 -6
  69. package/dist/lib/sandbox/commands/ls.js +10 -6
  70. package/dist/lib/sandbox/commands/rebuild.js +4 -3
  71. package/dist/lib/sandbox/commands/refresh.js +4 -84
  72. package/dist/lib/sandbox/commands/rm.js +24 -3
  73. package/dist/lib/sandbox/commands/show.js +13 -4
  74. package/dist/lib/sandbox/commands/start.js +7 -4
  75. package/dist/lib/sandbox/config.js +2 -0
  76. package/dist/lib/sandbox/constants.js +6 -0
  77. package/dist/lib/sandbox/control/client.js +44 -0
  78. package/dist/lib/sandbox/control/protocol.js +35 -0
  79. package/dist/lib/sandbox/control/server.js +109 -0
  80. package/dist/lib/sandbox/dockerfile.js +36 -13
  81. package/dist/lib/sandbox/mounts.js +17 -4
  82. package/dist/lib/sandbox/recovery.js +128 -5
  83. package/dist/lib/sandbox/redaction.js +12 -0
  84. package/dist/lib/sandbox/runtimes/base.dockerfile +24 -74
  85. package/dist/lib/sandbox/workspace-identity.js +95 -0
  86. package/dist/lib/sandbox/workspace-view.js +103 -0
  87. package/dist/lib/task/activity-intent.js +307 -0
  88. package/dist/lib/task/artifact-lifecycle.js +2 -1
  89. package/dist/lib/task/commands/log.js +15 -14
  90. package/dist/lib/task/commit-finalization.js +267 -0
  91. package/dist/lib/task/commit-intent.js +165 -0
  92. package/dist/lib/task/decision-intents.js +31 -17
  93. package/dist/lib/task/delegation-receipts.js +25 -4
  94. package/dist/lib/task/events.js +67 -28
  95. package/dist/lib/task/finalization-artifacts.js +35 -0
  96. package/dist/lib/task/implementation-inputs.js +54 -7
  97. package/dist/lib/task/ledger-intents.js +35 -1
  98. package/dist/lib/task/lifecycle-execution.js +46 -0
  99. package/dist/lib/task/orchestration.js +753 -54
  100. package/dist/lib/task/resolve-ref.js +41 -1
  101. package/dist/lib/task/review-finalization.js +29 -9
  102. package/dist/lib/task/task-execution-lock.js +231 -0
  103. package/dist/lib/task/verification-checks.js +1 -1
  104. package/dist/lib/task/verification-engine.js +218 -2
  105. package/dist/lib/task/verification.js +4 -3
  106. package/dist/lib/task/workspace-snapshot.js +17 -5
  107. package/lib/agent-clients/adapter.ts +201 -4
  108. package/lib/agent-clients/adapters/antigravity-cli.ts +65 -0
  109. package/lib/{sandbox/credentials.ts → agent-clients/adapters/claude-code-credentials.ts} +3 -18
  110. package/lib/agent-clients/adapters/claude-code-refresh.ts +128 -0
  111. package/lib/agent-clients/adapters/claude-code-sandbox.ts +295 -0
  112. package/lib/agent-clients/adapters/claude-code.ts +31 -4
  113. package/lib/agent-clients/adapters/codex.ts +9 -0
  114. package/lib/agent-clients/adapters/index.ts +2 -2
  115. package/lib/agent-clients/adapters/opencode-sandbox.ts +136 -0
  116. package/lib/agent-clients/adapters/opencode.ts +27 -3
  117. package/lib/agent-clients/adapters/runtimes/claude-code.dockerfile +65 -0
  118. package/lib/agent-clients/config.ts +49 -4
  119. package/lib/agent-clients/next-steps.ts +15 -2
  120. package/lib/agent-clients/reconcile.ts +2 -1
  121. package/lib/agent-clients/registry.ts +19 -1
  122. package/lib/agent-clients/schema.ts +18 -0
  123. package/lib/agent-clients/tokens.ts +53 -0
  124. package/lib/agent-clients/types.ts +15 -1
  125. package/lib/defaults.json +1 -1
  126. package/lib/git/workflow.ts +66 -2
  127. package/lib/internal/agent-client.ts +59 -4
  128. package/lib/internal/git-workflow.ts +5 -1
  129. package/lib/internal/platform-checks.ts +4 -4
  130. package/lib/internal/platform-comment.ts +17 -2
  131. package/lib/internal/platform-issue.ts +4 -0
  132. package/lib/internal/platform-pr-review.ts +104 -0
  133. package/lib/internal/platform-pr.ts +14 -1
  134. package/lib/internal/platform-release-notes.ts +59 -16
  135. package/lib/internal/pr-review-grade.ts +130 -0
  136. package/lib/internal/release-workflow.ts +13 -6
  137. package/lib/internal/sandbox-control.ts +24 -0
  138. package/lib/internal/task-activity.ts +91 -0
  139. package/lib/internal/task-event.ts +9 -1
  140. package/lib/internal/task-ledger.ts +12 -3
  141. package/lib/internal/task-lifecycle.ts +26 -1
  142. package/lib/internal/task-orchestration.ts +123 -14
  143. package/lib/internal/task-review.ts +8 -3
  144. package/lib/platform/adapters.ts +29 -2
  145. package/lib/platform/completion-backfill.ts +134 -0
  146. package/lib/platform/github-client.ts +20 -2
  147. package/lib/platform/issue-comments.ts +3 -2
  148. package/lib/platform/merged-pr-equivalence.ts +127 -5
  149. package/lib/platform/pr-checks.ts +73 -46
  150. package/lib/platform/pr-review.ts +201 -0
  151. package/lib/platform/pull-requests.ts +444 -3
  152. package/lib/platform/release-notes.ts +100 -4
  153. package/lib/platform/releases.ts +16 -4
  154. package/lib/pr-review/evidence-grading.ts +318 -0
  155. package/lib/process-data/index.ts +224 -0
  156. package/lib/process-data/normalize.ts +202 -0
  157. package/lib/process-data/privacy.ts +41 -0
  158. package/lib/process-data/reconcile.ts +110 -0
  159. package/lib/process-data/repair.ts +64 -0
  160. package/lib/process-data/sources.ts +354 -0
  161. package/lib/process-data/store.ts +315 -0
  162. package/lib/process-data/types.ts +135 -0
  163. package/lib/run/index.ts +5 -3
  164. package/lib/run/tui.ts +14 -12
  165. package/lib/sandbox/agent-client-reconciler.ts +44 -2
  166. package/lib/sandbox/capture.ts +9 -2
  167. package/lib/sandbox/commands/create.ts +126 -280
  168. package/lib/sandbox/commands/enter.ts +13 -59
  169. package/lib/sandbox/commands/list-running.ts +23 -6
  170. package/lib/sandbox/commands/ls.ts +22 -6
  171. package/lib/sandbox/commands/rebuild.ts +4 -3
  172. package/lib/sandbox/commands/refresh.ts +4 -126
  173. package/lib/sandbox/commands/rm.ts +24 -3
  174. package/lib/sandbox/commands/show.ts +30 -4
  175. package/lib/sandbox/commands/start.ts +6 -4
  176. package/lib/sandbox/config.ts +4 -0
  177. package/lib/sandbox/constants.ts +8 -0
  178. package/lib/sandbox/control/client.ts +55 -0
  179. package/lib/sandbox/control/protocol.ts +75 -0
  180. package/lib/sandbox/control/server.ts +117 -0
  181. package/lib/sandbox/dockerfile.ts +66 -13
  182. package/lib/sandbox/mounts.ts +24 -4
  183. package/lib/sandbox/recovery.ts +163 -6
  184. package/lib/sandbox/redaction.ts +14 -0
  185. package/lib/sandbox/runtimes/base.dockerfile +24 -74
  186. package/lib/sandbox/tool-types.ts +16 -0
  187. package/lib/sandbox/workspace-identity.ts +123 -0
  188. package/lib/sandbox/workspace-view.ts +143 -0
  189. package/lib/server/server.schema.json +2 -2
  190. package/lib/task/activity-intent.ts +417 -0
  191. package/lib/task/artifact-lifecycle.ts +2 -1
  192. package/lib/task/commands/log.ts +15 -14
  193. package/lib/task/commit-finalization.ts +356 -0
  194. package/lib/task/commit-intent.ts +230 -0
  195. package/lib/task/decision-intents.ts +32 -12
  196. package/lib/task/delegation-receipts.ts +34 -5
  197. package/lib/task/events.ts +75 -30
  198. package/lib/task/finalization-artifacts.ts +58 -0
  199. package/lib/task/implementation-inputs.ts +62 -8
  200. package/lib/task/ledger-intents.ts +43 -3
  201. package/lib/task/lifecycle-execution.ts +106 -0
  202. package/lib/task/orchestration.ts +1019 -72
  203. package/lib/task/resolve-ref.ts +46 -1
  204. package/lib/task/review-finalization.ts +40 -9
  205. package/lib/task/task-execution-lock.ts +296 -0
  206. package/lib/task/verification-checks.ts +1 -1
  207. package/lib/task/verification-engine.ts +249 -2
  208. package/lib/task/verification.ts +5 -3
  209. package/lib/task/workspace-snapshot.ts +26 -5
  210. package/package.json +3 -3
  211. package/templates/.agents/QUICKSTART.en.md +25 -8
  212. package/templates/.agents/QUICKSTART.zh-CN.md +25 -8
  213. package/templates/.agents/README.en.md +10 -7
  214. package/templates/.agents/README.zh-CN.md +10 -7
  215. package/templates/.agents/hooks/lifecycle-delegation.js +15 -4
  216. package/templates/.agents/rules/README.en.md +1 -1
  217. package/templates/.agents/rules/README.zh-CN.md +1 -1
  218. package/templates/.agents/rules/create-issue.github.en.md +4 -2
  219. package/templates/.agents/rules/create-issue.github.zh-CN.md +4 -2
  220. package/templates/.agents/rules/human-decision-context.en.md +11 -2
  221. package/templates/.agents/rules/human-decision-context.zh-CN.md +11 -2
  222. package/templates/.agents/rules/issue-fields.github.en.md +3 -1
  223. package/templates/.agents/rules/issue-fields.github.zh-CN.md +3 -1
  224. package/templates/.agents/rules/issue-pr-commands.en.md +5 -3
  225. package/templates/.agents/rules/issue-pr-commands.github.en.md +5 -3
  226. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +5 -3
  227. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +5 -3
  228. package/templates/.agents/rules/issue-sync.github.en.md +7 -3
  229. package/templates/.agents/rules/issue-sync.github.zh-CN.md +8 -4
  230. package/templates/.agents/rules/lifecycle-orchestration.en.md +5 -2
  231. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +5 -2
  232. package/templates/.agents/rules/milestone-inference.github.en.md +4 -2
  233. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +4 -2
  234. package/templates/.agents/rules/next-step-output.en.md +3 -1
  235. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -1
  236. package/templates/.agents/rules/no-mid-flow-questions.en.md +17 -0
  237. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +17 -0
  238. package/templates/.agents/rules/pr-checks-commands.en.md +3 -3
  239. package/templates/.agents/rules/pr-checks-commands.github.en.md +2 -2
  240. package/templates/.agents/rules/pr-checks-commands.github.zh-CN.md +3 -3
  241. package/templates/.agents/rules/pr-checks-commands.zh-CN.md +3 -3
  242. package/templates/.agents/rules/pr-sync.en.md +3 -1
  243. package/templates/.agents/rules/pr-sync.github.en.md +11 -1
  244. package/templates/.agents/rules/pr-sync.github.zh-CN.md +11 -1
  245. package/templates/.agents/rules/pr-sync.zh-CN.md +3 -1
  246. package/templates/.agents/rules/release-commands.en.md +1 -1
  247. package/templates/.agents/rules/release-commands.github.en.md +12 -2
  248. package/templates/.agents/rules/release-commands.github.zh-CN.md +12 -2
  249. package/templates/.agents/rules/release-commands.zh-CN.md +1 -1
  250. package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
  251. package/templates/.agents/rules/task-management.en.md +13 -0
  252. package/templates/.agents/rules/task-management.zh-CN.md +13 -0
  253. package/templates/.agents/skills/analyze-task/SKILL.en.md +10 -7
  254. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +10 -7
  255. package/templates/.agents/skills/block-task/SKILL.en.md +7 -5
  256. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +7 -5
  257. package/templates/.agents/skills/cancel-task/SKILL.en.md +6 -4
  258. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +6 -4
  259. package/templates/.agents/skills/close-codescan/SKILL.en.md +3 -1
  260. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +3 -1
  261. package/templates/.agents/skills/close-dependabot/SKILL.en.md +3 -1
  262. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +3 -1
  263. package/templates/.agents/skills/code-task/SKILL.en.md +10 -7
  264. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +12 -9
  265. package/templates/.agents/skills/commit/SKILL.en.md +23 -11
  266. package/templates/.agents/skills/commit/SKILL.zh-CN.md +29 -11
  267. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  268. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  269. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +49 -0
  270. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +55 -0
  271. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +1 -1
  272. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +1 -1
  273. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  274. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  275. package/templates/.agents/skills/commit/reference/task-status-update.en.md +4 -4
  276. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +4 -4
  277. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +6 -4
  278. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +6 -4
  279. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +1 -1
  280. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +1 -1
  281. package/templates/.agents/skills/complete-task/SKILL.en.md +22 -7
  282. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +22 -7
  283. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  284. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  285. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +17 -0
  286. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +17 -0
  287. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -5
  288. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -5
  289. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +1 -1
  290. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +1 -1
  291. package/templates/.agents/skills/create-release-note/SKILL.en.md +17 -16
  292. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +17 -16
  293. package/templates/.agents/skills/create-task/SKILL.en.md +5 -3
  294. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +5 -3
  295. package/templates/.agents/skills/create-task/reference/context-capture.en.md +34 -0
  296. package/templates/.agents/skills/create-task/reference/context-capture.zh-CN.md +34 -0
  297. package/templates/.agents/skills/import-issue/SKILL.en.md +5 -3
  298. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +5 -3
  299. package/templates/.agents/skills/plan-task/SKILL.en.md +8 -5
  300. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +8 -5
  301. package/templates/.agents/skills/post-release/SKILL.en.md +2 -0
  302. package/templates/.agents/skills/post-release/SKILL.zh-CN.md +2 -0
  303. package/templates/.agents/skills/release/SKILL.en.md +16 -10
  304. package/templates/.agents/skills/release/SKILL.zh-CN.md +16 -10
  305. package/templates/.agents/skills/restore-task/SKILL.en.md +4 -1
  306. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +4 -1
  307. package/templates/.agents/skills/review-analysis/SKILL.en.md +7 -4
  308. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +7 -4
  309. package/templates/.agents/skills/review-code/SKILL.en.md +11 -8
  310. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +11 -8
  311. package/templates/.agents/skills/review-code/reference/output-templates.en.md +1 -1
  312. package/templates/.agents/skills/review-code/reference/output-templates.zh-CN.md +1 -1
  313. package/templates/.agents/skills/review-plan/SKILL.en.md +7 -4
  314. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +7 -4
  315. package/templates/.agents/skills/review-pr/SKILL.en.md +186 -0
  316. package/templates/.agents/skills/review-pr/SKILL.zh-CN.md +186 -0
  317. package/templates/.agents/skills/review-pr/config/verify.en.json +37 -0
  318. package/templates/.agents/skills/review-pr/config/verify.zh-CN.json +37 -0
  319. package/templates/.agents/skills/review-pr/reference/evidence-grading.en.md +65 -0
  320. package/templates/.agents/skills/review-pr/reference/evidence-grading.zh-CN.md +65 -0
  321. package/templates/.agents/skills/review-pr/reference/output-guidance.en.md +18 -0
  322. package/templates/.agents/skills/review-pr/reference/output-guidance.zh-CN.md +18 -0
  323. package/templates/.agents/skills/review-pr/reference/report-template.en.md +85 -0
  324. package/templates/.agents/skills/review-pr/reference/report-template.zh-CN.md +85 -0
  325. package/templates/.agents/skills/run-task/SKILL.en.md +8 -8
  326. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +8 -8
  327. package/templates/.agents/skills/run-task/config/verify.en.json +2 -1
  328. package/templates/.agents/skills/run-task/config/verify.zh-CN.json +2 -1
  329. package/templates/.agents/skills/run-task/reference/host-validation.en.md +20 -0
  330. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +20 -0
  331. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +98 -107
  332. package/templates/.agents/skills/watch-pr/SKILL.en.md +13 -13
  333. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +13 -13
  334. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +27 -6
  335. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +26 -5
  336. package/templates/.agents/templates/task.en.md +2 -2
  337. package/templates/.agents/templates/task.zh-CN.md +2 -2
  338. package/templates/.agents/workflows/bug-fix.en.yaml +3 -3
  339. package/templates/.agents/workflows/bug-fix.zh-CN.yaml +3 -3
  340. package/templates/.agents/workflows/code-review.en.yaml +1 -1
  341. package/templates/.agents/workflows/code-review.zh-CN.yaml +1 -1
  342. package/templates/.agents/workflows/feature-development.en.yaml +4 -4
  343. package/templates/.agents/workflows/feature-development.zh-CN.yaml +4 -4
  344. package/templates/.agents/workflows/refactoring.en.yaml +3 -3
  345. package/templates/.agents/workflows/refactoring.zh-CN.yaml +3 -3
  346. package/templates/.claude/commands/post-release.en.md +1 -0
  347. package/templates/.claude/commands/post-release.zh-CN.md +1 -0
  348. package/templates/.claude/commands/review-pr.en.md +8 -0
  349. package/templates/.claude/commands/review-pr.zh-CN.md +8 -0
  350. package/templates/.claude/commands/watch-pr.en.md +1 -1
  351. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  352. package/templates/.claude/rules/tool-preferences.en.md +20 -0
  353. package/templates/.claude/rules/tool-preferences.zh-CN.md +20 -0
  354. package/templates/.opencode/commands/post-release.en.md +2 -0
  355. package/templates/.opencode/commands/post-release.zh-CN.md +2 -0
  356. package/templates/.opencode/commands/review-pr.en.md +11 -0
  357. package/templates/.opencode/commands/review-pr.zh-CN.md +11 -0
  358. package/templates/.opencode/commands/watch-pr.en.md +1 -1
  359. package/templates/.opencode/commands/watch-pr.zh-CN.md +1 -1
  360. package/dist/lib/agent-clients/adapters/gemini-cli.js +0 -64
  361. package/lib/agent-clients/adapters/gemini-cli.ts +0 -65
  362. package/templates/.gemini/commands/_project_/analyze-task.en.toml +0 -10
  363. package/templates/.gemini/commands/_project_/analyze-task.zh-CN.toml +0 -10
  364. package/templates/.gemini/commands/_project_/archive-tasks.en.toml +0 -10
  365. package/templates/.gemini/commands/_project_/archive-tasks.zh-CN.toml +0 -10
  366. package/templates/.gemini/commands/_project_/block-task.en.toml +0 -10
  367. package/templates/.gemini/commands/_project_/block-task.zh-CN.toml +0 -10
  368. package/templates/.gemini/commands/_project_/cancel-task.en.toml +0 -10
  369. package/templates/.gemini/commands/_project_/cancel-task.zh-CN.toml +0 -10
  370. package/templates/.gemini/commands/_project_/check-task.en.toml +0 -10
  371. package/templates/.gemini/commands/_project_/check-task.zh-CN.toml +0 -10
  372. package/templates/.gemini/commands/_project_/close-codescan.en.toml +0 -8
  373. package/templates/.gemini/commands/_project_/close-codescan.zh-CN.toml +0 -8
  374. package/templates/.gemini/commands/_project_/close-dependabot.en.toml +0 -8
  375. package/templates/.gemini/commands/_project_/close-dependabot.zh-CN.toml +0 -8
  376. package/templates/.gemini/commands/_project_/code-task.en.toml +0 -10
  377. package/templates/.gemini/commands/_project_/code-task.zh-CN.toml +0 -10
  378. package/templates/.gemini/commands/_project_/commit.en.toml +0 -10
  379. package/templates/.gemini/commands/_project_/commit.zh-CN.toml +0 -10
  380. package/templates/.gemini/commands/_project_/complete-manual-validation.en.toml +0 -10
  381. package/templates/.gemini/commands/_project_/complete-manual-validation.zh-CN.toml +0 -10
  382. package/templates/.gemini/commands/_project_/complete-task.en.toml +0 -10
  383. package/templates/.gemini/commands/_project_/complete-task.zh-CN.toml +0 -10
  384. package/templates/.gemini/commands/_project_/create-pr.en.toml +0 -10
  385. package/templates/.gemini/commands/_project_/create-pr.zh-CN.toml +0 -10
  386. package/templates/.gemini/commands/_project_/create-release-note.en.toml +0 -8
  387. package/templates/.gemini/commands/_project_/create-release-note.zh-CN.toml +0 -8
  388. package/templates/.gemini/commands/_project_/create-task.en.toml +0 -8
  389. package/templates/.gemini/commands/_project_/create-task.zh-CN.toml +0 -8
  390. package/templates/.gemini/commands/_project_/import-codescan.en.toml +0 -8
  391. package/templates/.gemini/commands/_project_/import-codescan.zh-CN.toml +0 -8
  392. package/templates/.gemini/commands/_project_/import-dependabot.en.toml +0 -8
  393. package/templates/.gemini/commands/_project_/import-dependabot.zh-CN.toml +0 -8
  394. package/templates/.gemini/commands/_project_/import-issue.en.toml +0 -8
  395. package/templates/.gemini/commands/_project_/import-issue.zh-CN.toml +0 -8
  396. package/templates/.gemini/commands/_project_/init-labels.en.toml +0 -8
  397. package/templates/.gemini/commands/_project_/init-labels.zh-CN.toml +0 -8
  398. package/templates/.gemini/commands/_project_/init-milestones.en.toml +0 -10
  399. package/templates/.gemini/commands/_project_/init-milestones.zh-CN.toml +0 -10
  400. package/templates/.gemini/commands/_project_/plan-task.en.toml +0 -10
  401. package/templates/.gemini/commands/_project_/plan-task.zh-CN.toml +0 -10
  402. package/templates/.gemini/commands/_project_/post-release.en.toml +0 -6
  403. package/templates/.gemini/commands/_project_/post-release.zh-CN.toml +0 -6
  404. package/templates/.gemini/commands/_project_/refine-title.en.toml +0 -8
  405. package/templates/.gemini/commands/_project_/refine-title.zh-CN.toml +0 -8
  406. package/templates/.gemini/commands/_project_/release.en.toml +0 -8
  407. package/templates/.gemini/commands/_project_/release.zh-CN.toml +0 -8
  408. package/templates/.gemini/commands/_project_/restore-task.en.toml +0 -8
  409. package/templates/.gemini/commands/_project_/restore-task.zh-CN.toml +0 -8
  410. package/templates/.gemini/commands/_project_/review-analysis.en.toml +0 -10
  411. package/templates/.gemini/commands/_project_/review-analysis.zh-CN.toml +0 -10
  412. package/templates/.gemini/commands/_project_/review-code.en.toml +0 -10
  413. package/templates/.gemini/commands/_project_/review-code.zh-CN.toml +0 -10
  414. package/templates/.gemini/commands/_project_/review-plan.en.toml +0 -10
  415. package/templates/.gemini/commands/_project_/review-plan.zh-CN.toml +0 -10
  416. package/templates/.gemini/commands/_project_/run-task.en.toml +0 -8
  417. package/templates/.gemini/commands/_project_/run-task.zh-CN.toml +0 -8
  418. package/templates/.gemini/commands/_project_/test-integration.en.toml +0 -6
  419. package/templates/.gemini/commands/_project_/test-integration.zh-CN.toml +0 -6
  420. package/templates/.gemini/commands/_project_/test.en.toml +0 -6
  421. package/templates/.gemini/commands/_project_/test.zh-CN.toml +0 -6
  422. package/templates/.gemini/commands/_project_/update-agent-infra.en.toml +0 -6
  423. package/templates/.gemini/commands/_project_/update-agent-infra.zh-CN.toml +0 -6
  424. package/templates/.gemini/commands/_project_/upgrade-dependency.en.toml +0 -8
  425. package/templates/.gemini/commands/_project_/upgrade-dependency.zh-CN.toml +0 -8
  426. package/templates/.gemini/commands/_project_/watch-pr.en.toml +0 -10
  427. package/templates/.gemini/commands/_project_/watch-pr.zh-CN.toml +0 -10
  428. package/templates/.gemini/settings.json +0 -3
@@ -0,0 +1,282 @@
1
+ import crypto from 'node:crypto';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ function sha256(bytes) {
5
+ return crypto.createHash('sha256').update(bytes).digest('hex');
6
+ }
7
+ function compareCodePoints(left, right) {
8
+ const a = Array.from(left, (char) => char.codePointAt(0));
9
+ const b = Array.from(right, (char) => char.codePointAt(0));
10
+ for (let index = 0; index < Math.min(a.length, b.length); index += 1) {
11
+ if (a[index] !== b[index])
12
+ return a[index] - b[index];
13
+ }
14
+ return a.length - b.length;
15
+ }
16
+ function canonicalString(value, seen) {
17
+ if (value === null || typeof value === 'boolean' || typeof value === 'string') {
18
+ return JSON.stringify(value);
19
+ }
20
+ if (typeof value === 'number') {
21
+ if (!Number.isFinite(value))
22
+ throw new Error('canonical JSON accepts only finite JSON values');
23
+ return JSON.stringify(value);
24
+ }
25
+ if (Array.isArray(value)) {
26
+ if (seen.has(value))
27
+ throw new Error('canonical JSON accepts only acyclic JSON values');
28
+ seen.add(value);
29
+ const output = `[${value.map((entry) => canonicalString(entry, seen)).join(',')}]`;
30
+ seen.delete(value);
31
+ return output;
32
+ }
33
+ if (typeof value === 'object') {
34
+ if (seen.has(value))
35
+ throw new Error('canonical JSON accepts only acyclic JSON values');
36
+ seen.add(value);
37
+ const record = value;
38
+ const fields = Object.keys(record)
39
+ .sort(compareCodePoints)
40
+ .map((key) => `${JSON.stringify(key)}:${canonicalString(record[key], seen)}`);
41
+ seen.delete(value);
42
+ return `{${fields.join(',')}}`;
43
+ }
44
+ throw new Error('canonical JSON accepts only JSON values');
45
+ }
46
+ function canonicalJsonBytes(value) {
47
+ return Buffer.from(canonicalString(value, new Set()), 'utf8');
48
+ }
49
+ function ensurePrivateDirectory(directory) {
50
+ fs.mkdirSync(directory, { recursive: true, mode: 0o700 });
51
+ if (process.platform !== 'win32')
52
+ fs.chmodSync(directory, 0o700);
53
+ }
54
+ function writeExclusive(filePath, bytes) {
55
+ ensurePrivateDirectory(path.dirname(filePath));
56
+ try {
57
+ const fd = fs.openSync(filePath, 'wx', 0o600);
58
+ try {
59
+ fs.writeFileSync(fd, bytes);
60
+ fs.fsyncSync(fd);
61
+ }
62
+ finally {
63
+ fs.closeSync(fd);
64
+ }
65
+ return true;
66
+ }
67
+ catch (error) {
68
+ if (error.code !== 'EEXIST')
69
+ throw error;
70
+ return false;
71
+ }
72
+ }
73
+ function createObjectStore(root) {
74
+ const objectRoot = path.join(root, 'objects', 'sha256');
75
+ ensurePrivateDirectory(objectRoot);
76
+ return {
77
+ pathFor(digest) {
78
+ if (!/^[a-f0-9]{64}$/.test(digest))
79
+ throw new Error(`invalid SHA-256: ${digest}`);
80
+ return path.join(objectRoot, digest.slice(0, 2), digest);
81
+ },
82
+ put(bytes) {
83
+ const digest = sha256(bytes);
84
+ const objectPath = path.join(objectRoot, digest.slice(0, 2), digest);
85
+ const created = writeExclusive(objectPath, bytes);
86
+ const stored = fs.readFileSync(objectPath);
87
+ if (sha256(stored) !== digest)
88
+ throw new Error(`CAS hash mismatch for ${digest}`);
89
+ return { sha256: digest, path: objectPath, created };
90
+ }
91
+ };
92
+ }
93
+ function dispositionCounts(objects) {
94
+ const counts = { included: 0, 'excluded-sensitive': 0, unavailable: 0 };
95
+ for (const object of objects)
96
+ counts[object.disposition?.state ?? 'included'] += 1;
97
+ return counts;
98
+ }
99
+ function jsonLine(value) {
100
+ return `${canonicalJsonBytes(value).toString('utf8')}\n`;
101
+ }
102
+ function writePrivateFile(filePath, content) {
103
+ fs.writeFileSync(filePath, content, { mode: 0o600, flag: 'wx' });
104
+ if (process.platform !== 'win32')
105
+ fs.chmodSync(filePath, 0o600);
106
+ }
107
+ function manifestDigest(manifest) {
108
+ return sha256(canonicalJsonBytes(manifest));
109
+ }
110
+ function publishSnapshot(root, input) {
111
+ ensurePrivateDirectory(root);
112
+ ensurePrivateDirectory(path.join(root, 'repairs'));
113
+ const date = new Date(input.observedTo);
114
+ if (!Number.isFinite(date.getTime()))
115
+ throw new Error('observedTo must be an ISO timestamp');
116
+ const identity = {
117
+ scope: input.scope,
118
+ repository: input.repository,
119
+ observedFrom: input.observedFrom,
120
+ observedTo: input.observedTo,
121
+ objects: input.objects,
122
+ endpoints: input.endpoints,
123
+ excerptsEnabled: input.excerptsEnabled,
124
+ dispositionCounts: dispositionCounts(input.objects),
125
+ recordCount: input.records.length,
126
+ findingCount: input.quality.length,
127
+ repairCount: input.repairs.length
128
+ };
129
+ const identityDigest = sha256(canonicalJsonBytes(identity));
130
+ const stamp = input.observedTo.replace(/[-:]/g, '').replace(/\.\d{3}Z$/, 'Z');
131
+ const snapshotId = `${stamp}-${identityDigest.slice(0, 12)}`;
132
+ const partialManifest = {
133
+ schema: 'raw-manifest/v1',
134
+ snapshotId,
135
+ ...identity,
136
+ privacyPolicyVersion: 'process-data-privacy/v1'
137
+ };
138
+ const manifest = { ...partialManifest, manifestSha256: manifestDigest(partialManifest) };
139
+ const stagingRoot = path.join(root, '.staging');
140
+ ensurePrivateDirectory(stagingRoot);
141
+ const staging = fs.mkdtempSync(path.join(stagingRoot, `${snapshotId}-`));
142
+ if (process.platform !== 'win32')
143
+ fs.chmodSync(staging, 0o700);
144
+ try {
145
+ writePrivateFile(path.join(staging, 'manifest.json'), jsonLine(manifest));
146
+ writePrivateFile(path.join(staging, 'normalized.jsonl'), input.records.map((record) => jsonLine({ schema: 'normalized/v1', ...record })).join(''));
147
+ writePrivateFile(path.join(staging, 'quality.json'), jsonLine({ schema: 'quality/v1', findings: input.quality }));
148
+ writePrivateFile(path.join(staging, 'repair-manifest.jsonl'), input.repairs.map((repair) => jsonLine({ schema: 'repair/v1', ...repair })).join(''));
149
+ const destination = path.join(root, 'snapshots', String(date.getUTCFullYear()), String(date.getUTCMonth() + 1).padStart(2, '0'), String(date.getUTCDate()).padStart(2, '0'), snapshotId);
150
+ ensurePrivateDirectory(path.dirname(destination));
151
+ if (fs.existsSync(destination)) {
152
+ const existing = fs.readFileSync(path.join(destination, 'manifest.json'), 'utf8');
153
+ if (existing !== jsonLine(manifest))
154
+ throw new Error(`snapshot collision: ${snapshotId}`);
155
+ fs.rmSync(staging, { recursive: true, force: true });
156
+ return { snapshotId, path: destination, created: false };
157
+ }
158
+ fs.renameSync(staging, destination);
159
+ return { snapshotId, path: destination, created: true };
160
+ }
161
+ catch (error) {
162
+ fs.rmSync(staging, { recursive: true, force: true });
163
+ throw error;
164
+ }
165
+ }
166
+ function findSnapshot(root, snapshotId) {
167
+ const snapshotRoot = path.join(root, 'snapshots');
168
+ if (!fs.existsSync(snapshotRoot))
169
+ return null;
170
+ const stack = [snapshotRoot];
171
+ while (stack.length > 0) {
172
+ const current = stack.pop();
173
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
174
+ if (!entry.isDirectory())
175
+ continue;
176
+ const candidate = path.join(current, entry.name);
177
+ if (entry.name === snapshotId && fs.existsSync(path.join(candidate, 'manifest.json')))
178
+ return candidate;
179
+ stack.push(candidate);
180
+ }
181
+ }
182
+ return null;
183
+ }
184
+ function verifySnapshot(root, snapshotId) {
185
+ const snapshotPath = findSnapshot(root, snapshotId);
186
+ if (!snapshotPath)
187
+ return { ok: false, snapshotId, snapshotPath: null, errors: ['snapshot not found'] };
188
+ const errors = [];
189
+ const checkMode = (target, expected, label) => {
190
+ if (process.platform === 'win32' || !fs.existsSync(target))
191
+ return;
192
+ const actual = fs.statSync(target).mode & 0o777;
193
+ if (actual !== expected)
194
+ errors.push(`${label} permission mismatch: expected ${expected.toString(8)}, got ${actual.toString(8)}`);
195
+ };
196
+ checkMode(snapshotPath, 0o700, 'snapshot directory');
197
+ for (const file of ['manifest.json', 'normalized.jsonl', 'quality.json', 'repair-manifest.jsonl']) {
198
+ checkMode(path.join(snapshotPath, file), 0o600, file);
199
+ }
200
+ let manifest;
201
+ try {
202
+ manifest = JSON.parse(fs.readFileSync(path.join(snapshotPath, 'manifest.json'), 'utf8'));
203
+ }
204
+ catch {
205
+ return { ok: false, snapshotId, snapshotPath, errors: ['manifest is invalid JSON'] };
206
+ }
207
+ if (manifest.schema !== 'raw-manifest/v1')
208
+ errors.push(`unsupported manifest schema: ${manifest.schema}`);
209
+ if (manifest.snapshotId !== snapshotId)
210
+ errors.push('snapshot identity mismatch');
211
+ if (typeof manifest.excerptsEnabled !== 'boolean')
212
+ errors.push('manifest excerpts opt-in is invalid');
213
+ if (!manifest.dispositionCounts || canonicalJsonBytes(manifest.dispositionCounts).toString('utf8') !== canonicalJsonBytes(dispositionCounts(manifest.objects)).toString('utf8')) {
214
+ errors.push('manifest disposition counts mismatch');
215
+ }
216
+ const { manifestSha256, ...partial } = manifest;
217
+ if (manifestDigest(partial) !== manifestSha256)
218
+ errors.push('manifest hash mismatch');
219
+ const store = createObjectStore(root);
220
+ try {
221
+ const lines = fs.readFileSync(path.join(snapshotPath, 'normalized.jsonl'), 'utf8').split('\n').filter(Boolean);
222
+ const ids = new Set();
223
+ for (const line of lines) {
224
+ const record = JSON.parse(line);
225
+ if (record.schema !== 'normalized/v1' || typeof record.recordId !== 'string') {
226
+ errors.push('normalized record schema is invalid');
227
+ continue;
228
+ }
229
+ if (ids.has(record.recordId))
230
+ errors.push(`duplicate normalized record: ${record.recordId}`);
231
+ ids.add(record.recordId);
232
+ }
233
+ if (lines.length !== manifest.recordCount)
234
+ errors.push('normalized record count mismatch');
235
+ const quality = JSON.parse(fs.readFileSync(path.join(snapshotPath, 'quality.json'), 'utf8'));
236
+ if (quality.schema !== 'quality/v1' || !Array.isArray(quality.findings))
237
+ errors.push('quality schema is invalid');
238
+ else if (quality.findings.length !== manifest.findingCount)
239
+ errors.push('quality finding count mismatch');
240
+ const repairLines = fs.readFileSync(path.join(snapshotPath, 'repair-manifest.jsonl'), 'utf8').split('\n').filter(Boolean);
241
+ for (const line of repairLines) {
242
+ const repair = JSON.parse(line);
243
+ if (repair.schema !== 'repair/v1' || typeof repair.repairId !== 'string')
244
+ errors.push('repair manifest schema is invalid');
245
+ }
246
+ if (repairLines.length !== manifest.repairCount)
247
+ errors.push('repair manifest count mismatch');
248
+ }
249
+ catch {
250
+ errors.push('snapshot derived files are missing or invalid');
251
+ }
252
+ for (const object of manifest.objects) {
253
+ if (object.disposition?.state && object.disposition.state !== 'included')
254
+ continue;
255
+ try {
256
+ const objectPath = store.pathFor(object.sha256);
257
+ checkMode(path.dirname(objectPath), 0o700, `object directory ${object.sha256.slice(0, 2)}`);
258
+ checkMode(objectPath, 0o600, `object ${object.sourceIdentity}`);
259
+ const bytes = fs.readFileSync(objectPath);
260
+ if (sha256(bytes) !== object.sha256)
261
+ errors.push(`object hash mismatch: ${object.sourceIdentity}`);
262
+ if (bytes.length !== object.bytes)
263
+ errors.push(`object byte count mismatch: ${object.sourceIdentity}`);
264
+ }
265
+ catch {
266
+ errors.push(`object missing: ${object.sourceIdentity}`);
267
+ }
268
+ }
269
+ for (const page of manifest.endpoints.flatMap((endpoint) => endpoint.pages)) {
270
+ try {
271
+ if (sha256(fs.readFileSync(store.pathFor(page.canonicalSha256))) !== page.canonicalSha256) {
272
+ errors.push(`page hash mismatch: ${page.index}`);
273
+ }
274
+ }
275
+ catch {
276
+ errors.push(`page object missing: ${page.canonicalSha256}`);
277
+ }
278
+ }
279
+ return { ok: errors.length === 0, snapshotId, snapshotPath, errors, manifest };
280
+ }
281
+ export { canonicalJsonBytes, createObjectStore, findSnapshot, publishSnapshot, sha256, verifySnapshot };
282
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -1,7 +1,7 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { loadServerConfig } from '../server/config.js';
4
- import { resolveTaskBranch } from '../sandbox/task-resolver.js';
4
+ import { resolveSandboxTarget } from '../sandbox/workspace-identity.js';
5
5
  import { createRunId, runInSandbox } from '../sandbox/capture.js';
6
6
  import { loadShortIdByTaskId, normalizeShortIdInput } from '../task/short-id.js';
7
7
  import { buildTuiCommand, renderPrompt, selectTui } from './tui.js';
@@ -101,7 +101,6 @@ function resolveActiveTaskIdentity(taskRef, repoRoot) {
101
101
  let resolvedTaskRef = taskRef;
102
102
  if (TASK_ID_RE.test(taskRef)) {
103
103
  taskId = taskRef;
104
- resolvedTaskRef = loadShortIdByTaskId(repoRoot).get(taskId) ?? taskRef;
105
104
  }
106
105
  else {
107
106
  const normalized = normalizeShortIdInput(taskRef, { shortIdLength: readShortIdLength(repoRoot) });
@@ -165,7 +164,8 @@ export async function runSkill(args, options = {}) {
165
164
  return result.exitCode ?? (result.signal ? 1 : 0);
166
165
  }
167
166
  const repoRoot = options.repoRoot ?? config?.repoRoot ?? process.cwd();
168
- const branch = resolveTaskBranch(parsed.taskRef, repoRoot);
167
+ const target = resolveSandboxTarget(parsed.taskRef, repoRoot);
168
+ const branch = target.branch;
169
169
  const identity = resolveActiveTaskIdentity(parsed.taskRef, repoRoot);
170
170
  const runId = identity ? createRunId() : undefined;
171
171
  const writeStdout = options.writeStdout ?? ((chunk) => process.stdout.write(chunk));
@@ -175,6 +175,7 @@ export async function runSkill(args, options = {}) {
175
175
  const result = await runSandbox({
176
176
  taskRef: parsed.taskRef,
177
177
  branch,
178
+ workspace: target.workspace,
178
179
  command,
179
180
  runId,
180
181
  recreate: parsed.recreate
@@ -1,6 +1,12 @@
1
1
  import { renderAgentClientInvocation } from '../agent-clients/invocation.js';
2
2
  import { getAgentClientAdapter } from '../agent-clients/registry.js';
3
- const TUI_NAMES = new Set(['claude', 'codex', 'gemini', 'opencode']);
3
+ const TUI_NAMES = new Set(['claude', 'codex', 'antigravity', 'opencode']);
4
+ const TUI_AGENT_CLIENT_IDS = Object.freeze({
5
+ claude: 'claude-code',
6
+ codex: 'codex',
7
+ antigravity: 'antigravity-cli',
8
+ opencode: 'opencode'
9
+ });
4
10
  function isTuiName(value) {
5
11
  return typeof value === 'string' && TUI_NAMES.has(value);
6
12
  }
@@ -18,22 +24,13 @@ export function selectTui(skill, options) {
18
24
  return 'codex';
19
25
  }
20
26
  export function renderPrompt(params) {
21
- const suffix = [params.skill, ...params.args].join(' ').trim();
22
- if (params.tui === 'codex') {
23
- return renderAgentClientInvocation(getAgentClientAdapter('codex').invocation, {
24
- skillName: params.skill,
25
- args: params.args
26
- });
27
- }
28
- if (params.tui === 'gemini')
29
- return `/agent-infra:${suffix}`;
30
- return `/${suffix}`;
27
+ return renderAgentClientInvocation(getAgentClientAdapter(TUI_AGENT_CLIENT_IDS[params.tui]).invocation, { skillName: params.skill, args: params.args });
31
28
  }
32
29
  export function buildTuiCommand(tui, prompt) {
33
30
  if (tui === 'claude')
34
31
  return ['claude', ['--dangerously-skip-permissions', '--print', prompt]];
35
- if (tui === 'gemini')
36
- return ['gemini', ['--approval-mode', 'yolo', '--prompt', prompt]];
32
+ if (tui === 'antigravity')
33
+ return ['agy', ['--dangerously-skip-permissions', '--print', prompt]];
37
34
  if (tui === 'opencode')
38
35
  return ['opencode', ['run', '--dangerously-skip-permissions', prompt]];
39
36
  return ['codex', ['exec', '--dangerously-bypass-approvals-and-sandbox', prompt]];
@@ -62,6 +62,27 @@ function assertUniqueTools(tools) {
62
62
  seen.add(tool.id);
63
63
  }
64
64
  }
65
+ function unique(values) {
66
+ return Object.freeze([...new Set(values)]);
67
+ }
68
+ function sandboxImageContribution(adapters, tools) {
69
+ const homePrefix = '/home/devuser/';
70
+ const derivedExclusions = tools.map((tool) => {
71
+ if (!tool.containerMount.startsWith(homePrefix)) {
72
+ throw new Error(`Agent Client '${tool.id}' container mount must be below ${homePrefix.slice(0, -1)}`);
73
+ }
74
+ return tool.containerMount.slice(homePrefix.length);
75
+ });
76
+ return Object.freeze({
77
+ dockerfileFragments: unique(adapters.flatMap((adapter) => adapter.sandbox.image?.dockerfileFragment
78
+ ? [adapter.sandbox.image.dockerfileFragment]
79
+ : [])),
80
+ dotfilesExclusions: unique([
81
+ ...derivedExclusions,
82
+ ...adapters.flatMap((adapter) => adapter.sandbox.image?.dotfilesExclusions ?? [])
83
+ ])
84
+ });
85
+ }
65
86
  function hooksByPhase(adapters) {
66
87
  const phases = [
67
88
  'prepare',
@@ -108,6 +129,7 @@ function createSandboxCapabilityPlan(config) {
108
129
  }
109
130
  const tools = Object.freeze([...nonClientTools, ...selectedTools, ...selectedCustomTools]);
110
131
  assertUniqueTools(tools);
132
+ const image = sandboxImageContribution(selectedAgentClients, selectedTools);
111
133
  const phaseHooks = hooksByPhase(selectedAgentClients);
112
134
  const hookProjection = selectedAgentClients.flatMap((adapter) => adapter.sandbox.hooks.map((hook) => ({
113
135
  adapterId: adapter.id,
@@ -134,7 +156,8 @@ function createSandboxCapabilityPlan(config) {
134
156
  tools: Object.freeze(tools.map(runtimeToolProjection)),
135
157
  selectedAgentClients: Object.freeze(selectedAgentClients.map((adapter) => adapter.id)),
136
158
  hooks: Object.freeze(hookProjection),
137
- recoveryChecks: recoveryCheckProjection
159
+ recoveryChecks: recoveryCheckProjection,
160
+ image
138
161
  });
139
162
  const cleanupInventory = Object.freeze([
140
163
  agentInfraTool(config.home),
@@ -148,6 +171,7 @@ function createSandboxCapabilityPlan(config) {
148
171
  hooksByPhase: phaseHooks,
149
172
  recoveryChecks,
150
173
  aliases: Object.freeze(listAgentClientAdapters().flatMap((adapter) => adapter.sandbox.aliases)),
174
+ image,
151
175
  imageSignature: hash(tools.map(({ id, install }) => ({ id, install }))),
152
176
  runtimeSignature: hash(runtimeProjection),
153
177
  runtimeProjection,
@@ -230,5 +254,5 @@ function runBoundedSandboxHookCommand(command, options) {
230
254
  });
231
255
  });
232
256
  }
233
- export { DEFAULT_SANDBOX_HOOK_TIMEOUT_MS, createSandboxCapabilityPlan, runBoundedSandboxHookCommand, runSandboxHooks };
257
+ export { DEFAULT_SANDBOX_HOOK_TIMEOUT_MS, createSandboxCapabilityPlan, runBoundedSandboxHookCommand, runSandboxHooks, sandboxImageContribution };
234
258
  //# sourceMappingURL=agent-client-reconciler.js.map
@@ -6,6 +6,7 @@ import { commandForEngine } from './shell.js';
6
6
  import { ensureSandboxReady } from './recovery.js';
7
7
  import { hostTimezoneEnvFlags, terminalEnvFlags } from './commands/enter.js';
8
8
  import { fetchSandboxRows, selectSandboxContainer, startSandboxContainer } from './commands/list-running.js';
9
+ import { resolveSandboxTarget } from './workspace-identity.js';
9
10
  async function spawnCapture(file, args) {
10
11
  return new Promise((resolve, reject) => {
11
12
  const child = spawn(file, args, { stdio: ['ignore', 'pipe', 'pipe'] });
@@ -122,6 +123,8 @@ EOF
122
123
  export async function runInSandbox(request, options = {}) {
123
124
  const config = options.engine ? null : loadConfig();
124
125
  const engine = options.engine ?? detectEngine(config);
126
+ const workspace = request.workspace
127
+ ?? (config ? resolveSandboxTarget(request.taskRef, config.repoRoot).workspace : undefined);
125
128
  const rows = options.rows ??
126
129
  (() => {
127
130
  const fetched = fetchSandboxRows(engine, sandboxLabel(config), sandboxBranchLabel(config));
@@ -136,6 +139,7 @@ export async function runInSandbox(request, options = {}) {
136
139
  if (options.ensureReady) {
137
140
  container = (await options.ensureReady({
138
141
  branch: request.branch,
142
+ workspace,
139
143
  row: found,
140
144
  allowRecreate: request.recreate ?? false
141
145
  })).container;
@@ -145,11 +149,12 @@ export async function runInSandbox(request, options = {}) {
145
149
  config,
146
150
  engine,
147
151
  branch: request.branch,
152
+ workspace,
148
153
  row: found,
149
154
  allowRecreate: request.recreate,
150
- recreate: async (targetBranch) => {
155
+ recreate: async () => {
151
156
  const { create } = await import('./commands/create.js');
152
- await create([targetBranch, '--no-refresh']);
157
+ await create([request.taskRef, '--no-refresh']);
153
158
  }
154
159
  })).container;
155
160
  }