@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
@@ -0,0 +1,229 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { parseTaskFrontmatter } from '../task/frontmatter.js';
4
+ export class HostResolutionError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.name = 'HostResolutionError';
9
+ this.code = code;
10
+ }
11
+ }
12
+ function toPositiveNumber(value) {
13
+ const n = Number(value);
14
+ return Number.isInteger(n) && n > 0 ? n : null;
15
+ }
16
+ /**
17
+ * Parse the PR body for closing-issue references. Handles the conventional
18
+ * `Closes #1` / `Fixes: #2, #3` shapes (case-insensitive, comma/space
19
+ * separated, optional keyword list on the same logical line).
20
+ */
21
+ export function extractClosingIssueNumbers(body) {
22
+ const result = [];
23
+ const seen = new Set();
24
+ const linePattern = /(?:^|\n)[^\n]*\b(?:close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\b[^\n]*/gi;
25
+ let lineMatch;
26
+ while ((lineMatch = linePattern.exec(body)) !== null) {
27
+ const line = lineMatch[0];
28
+ for (const numMatch of line.matchAll(/#(\d+)/g)) {
29
+ const n = Number(numMatch[1]);
30
+ if (Number.isInteger(n) && n > 0 && !seen.has(n)) {
31
+ seen.add(n);
32
+ result.push(n);
33
+ }
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ /**
39
+ * Scan `.agents/workspace/active/{task-id}/task.md` files for tasks bound to the
40
+ * PR number or to one of the PR's closing issues. A task is emitted at most once;
41
+ * a direct `pr_number` hit takes priority over the issue-number reverse lookup.
42
+ */
43
+ export function collectHostCandidates(input) {
44
+ const activeRoot = path.join(input.workspaceRoot, '.agents', 'workspace', 'active');
45
+ const candidates = [];
46
+ let entries;
47
+ try {
48
+ entries = fs.readdirSync(activeRoot, { withFileTypes: true });
49
+ }
50
+ catch {
51
+ return [];
52
+ }
53
+ for (const entry of entries) {
54
+ if (!entry.isDirectory())
55
+ continue;
56
+ const taskDir = path.join(activeRoot, entry.name);
57
+ const taskMdPath = path.join(taskDir, 'task.md');
58
+ let content;
59
+ try {
60
+ content = fs.readFileSync(taskMdPath, 'utf8');
61
+ }
62
+ catch {
63
+ continue;
64
+ }
65
+ const frontmatter = parseTaskFrontmatter(content);
66
+ const issueNumber = toPositiveNumber(frontmatter.issue_number);
67
+ const prNumber = toPositiveNumber(frontmatter.pr_number);
68
+ if (prNumber === input.prNumber) {
69
+ candidates.push({ taskId: entry.name, taskDir, issueNumber, prNumber });
70
+ }
71
+ else if (issueNumber !== null && input.closingIssues.includes(issueNumber)) {
72
+ candidates.push({ taskId: entry.name, taskDir, issueNumber, prNumber });
73
+ }
74
+ }
75
+ return candidates;
76
+ }
77
+ /**
78
+ * Collapse a candidate list into a typed HostResolution. Zero candidates ->
79
+ * none; exactly one -> unique; more than one (no stable selection rule) ->
80
+ * ambiguous (fail closed, AN-6).
81
+ */
82
+ export function resolveHostFromCandidates(candidates) {
83
+ if (candidates.length === 0)
84
+ return { kind: 'none' };
85
+ if (candidates.length === 1) {
86
+ const candidate = candidates[0];
87
+ return {
88
+ kind: 'unique',
89
+ taskId: candidate.taskId,
90
+ taskDir: candidate.taskDir,
91
+ issueNumber: candidate.issueNumber ?? 0,
92
+ prNumber: candidate.prNumber ?? 0
93
+ };
94
+ }
95
+ return {
96
+ kind: 'ambiguous',
97
+ candidates: candidates.map((candidate) => ({ taskId: candidate.taskId, issueNumber: candidate.issueNumber ?? 0 }))
98
+ };
99
+ }
100
+ function hasNoLifecycleArtifacts(presence) {
101
+ return !presence.hasAnalysis && !presence.hasPlan && !presence.hasCode &&
102
+ !presence.hasReviewAnalysis && !presence.hasReviewPlan && !presence.hasReviewCode &&
103
+ !presence.hasPriorPrReview;
104
+ }
105
+ function hasFullArtifacts(presence) {
106
+ return presence.hasAnalysis && presence.hasPlan && presence.hasCode &&
107
+ presence.hasReviewAnalysis && presence.hasReviewPlan && presence.hasReviewCode;
108
+ }
109
+ function isTrusted(head) {
110
+ return head.issueNumberBound && head.taskIssueMatches && (!head.prNumberBound || head.taskPrMatches);
111
+ }
112
+ /**
113
+ * Derive the S1(a) trust factor `taskIssueMatches` (PL-3) mechanically from
114
+ * resolved data: a unique host is trusted on the issue dimension only when the
115
+ * task's bound issue_number is among the PR's closing issues. Ambiguous/none
116
+ * hosts and tasks without a positive issue_number cannot be confirmed -> false
117
+ * (fail closed to S2/audit). `resolve-host` emits this value so the prompt layer
118
+ * does not derive the trust factor ad hoc (CD-2).
119
+ */
120
+ export function deriveTaskIssueMatches(host, closingIssues) {
121
+ return host.kind === 'unique' && host.issueNumber > 0 && closingIssues.includes(host.issueNumber);
122
+ }
123
+ /**
124
+ * S1 -> S2 -> S3 classification (analysis §6.1). The ambiguous host is rejected
125
+ * before classification (AN-6 fail closed). S3(a) is host.kind === 'none';
126
+ * S3(b) is a unique task with no lifecycle artifacts and no prior pr-review
127
+ * (PL-5/PL-9 symmetric: any review-only task falls to S2).
128
+ */
129
+ export function classifyScenario(host, presence, head) {
130
+ if (host.kind === 'ambiguous') {
131
+ throw new HostResolutionError('HOST_AMBIGUOUS', 'multiple candidate hosts; resolve before evidence classification');
132
+ }
133
+ if (host.kind === 'none')
134
+ return 'S3';
135
+ if (hasNoLifecycleArtifacts(presence))
136
+ return 'S3';
137
+ const priorHeadMatches = presence.hasPriorPrReview && head.priorHeadSha !== null && head.priorHeadSha === head.currentHeadSha;
138
+ if (hasFullArtifacts(presence) && priorHeadMatches && isTrusted(head))
139
+ return 'S1';
140
+ return 'S2';
141
+ }
142
+ /**
143
+ * Freshness is benchmarked against the prior `pr-review*` reviewed head SHA
144
+ * (analysis §6.2, AN-7). No prior review -> n/a/n/a (first-review special case).
145
+ */
146
+ export function evaluateHead(head) {
147
+ if (head.priorHeadSha === null)
148
+ return { freshness: 'n/a', alignment: 'n/a' };
149
+ const freshness = head.priorHeadSha === head.currentHeadSha ? 'fresh' : 'stale';
150
+ const aligned = freshness === 'fresh' && isTrusted(head);
151
+ return { freshness, alignment: aligned ? 'aligned' : 'misaligned' };
152
+ }
153
+ /**
154
+ * Pure-evidence risk aggregation (analysis §6.3, AN-5): any priority factor
155
+ * (sensitivity / sourceCredibility) HIGH -> HIGH; otherwise any HIGH -> MEDIUM;
156
+ * all LOW -> LOW. Identity factors are structurally absent from the input type.
157
+ */
158
+ export function gradeRisk(factors) {
159
+ const priority = [factors.sensitivity, factors.sourceCredibility];
160
+ if (priority.includes('HIGH'))
161
+ return 'HIGH';
162
+ const values = Object.values(factors);
163
+ if (values.includes('HIGH'))
164
+ return 'MEDIUM';
165
+ return 'LOW';
166
+ }
167
+ /**
168
+ * verify / audit / reconstruct selection matrix (analysis §6.4). S3 ->
169
+ * reconstruct; S2 -> audit; S1 fresh+aligned -> verify (LOW/MEDIUM risk) or
170
+ * audit (HIGH risk); any other S1 combination falls back to audit.
171
+ */
172
+ export function selectMode(scenario, freshness, alignment, risk) {
173
+ if (scenario === 'S3')
174
+ return 'reconstruct';
175
+ if (scenario === 'S2')
176
+ return 'audit';
177
+ if (freshness === 'fresh' && alignment === 'aligned') {
178
+ return risk === 'HIGH' ? 'audit' : 'verify';
179
+ }
180
+ return 'audit';
181
+ }
182
+ function buildReason(input) {
183
+ const pieces = [];
184
+ if (input.firstReview)
185
+ pieces.push('first review (no prior pr-review head)');
186
+ if (input.hasPriorPrReview)
187
+ pieces.push(`prior head ${input.freshness}`);
188
+ if (input.freshness === 'fresh')
189
+ pieces.push(`alignment ${input.alignment}`);
190
+ pieces.push(`evidence scenario ${input.scenario}`);
191
+ pieces.push(`risk ${input.risk}`);
192
+ pieces.push(`mode ${input.mode}`);
193
+ return pieces.join('; ');
194
+ }
195
+ /**
196
+ * Full decision pipeline: classify -> freshness/alignment -> risk -> mode,
197
+ * producing a traceable DecisionRecord (AC3). Ambiguous hosts are rejected
198
+ * before any classification runs (AN-6).
199
+ */
200
+ export function decide(input) {
201
+ if (input.host.kind === 'ambiguous') {
202
+ throw new HostResolutionError('HOST_AMBIGUOUS', 'ambiguous host; resolve before evidence classification');
203
+ }
204
+ const scenario = classifyScenario(input.host, input.presence, input.head);
205
+ const { freshness, alignment } = evaluateHead(input.head);
206
+ const risk = gradeRisk(input.riskFactors);
207
+ const mode = selectMode(scenario, freshness, alignment, risk);
208
+ const firstReview = !input.presence.hasPriorPrReview;
209
+ return {
210
+ host: input.host,
211
+ scenario,
212
+ freshness,
213
+ alignment,
214
+ risk,
215
+ mode,
216
+ firstReview,
217
+ reason: buildReason({
218
+ scenario,
219
+ freshness,
220
+ alignment,
221
+ risk,
222
+ mode,
223
+ firstReview,
224
+ hasPriorPrReview: input.presence.hasPriorPrReview
225
+ })
226
+ };
227
+ }
228
+ export { hasFullArtifacts, hasNoLifecycleArtifacts, isTrusted };
229
+ //# sourceMappingURL=evidence-grading.js.map
@@ -1,6 +1,6 @@
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
4
  function isTuiName(value) {
5
5
  return typeof value === 'string' && TUI_NAMES.has(value);
6
6
  }
@@ -25,15 +25,13 @@ export function renderPrompt(params) {
25
25
  args: params.args
26
26
  });
27
27
  }
28
- if (params.tui === 'gemini')
29
- return `/agent-infra:${suffix}`;
30
28
  return `/${suffix}`;
31
29
  }
32
30
  export function buildTuiCommand(tui, prompt) {
33
31
  if (tui === 'claude')
34
32
  return ['claude', ['--dangerously-skip-permissions', '--print', prompt]];
35
- if (tui === 'gemini')
36
- return ['gemini', ['--approval-mode', 'yolo', '--prompt', prompt]];
33
+ if (tui === 'antigravity')
34
+ return ['agy', ['--dangerously-skip-permissions', '--print', prompt]];
37
35
  if (tui === 'opencode')
38
36
  return ['opencode', ['run', '--dangerously-skip-permissions', prompt]];
39
37
  return ['codex', ['exec', '--dangerously-bypass-approvals-and-sandbox', prompt]];
@@ -729,22 +729,6 @@ export function ensureOpenCodeModelInheritance(toolDir, hostHomeDir) {
729
729
  fs.writeFileSync(sandboxConfigPath, JSON.stringify(sandboxJson, null, 2), 'utf8');
730
730
  }
731
731
  }
732
- export function ensureGeminiWorkspaceTrust(toolDir) {
733
- const trustPath = path.join(toolDir, 'trustedFolders.json');
734
- let data = {};
735
- if (fs.existsSync(trustPath)) {
736
- try {
737
- data = JSON.parse(fs.readFileSync(trustPath, 'utf8'));
738
- }
739
- catch {
740
- // malformed JSON, start fresh
741
- }
742
- }
743
- if (data['/workspace'] !== 'TRUST_FOLDER') {
744
- data['/workspace'] = 'TRUST_FOLDER';
745
- fs.writeFileSync(trustPath, JSON.stringify(data, null, 2), 'utf8');
746
- }
747
- }
748
732
  export function sandboxAliasesPath(home) {
749
733
  return hostJoin(home, '.agent-infra', 'aliases', 'sandbox.sh');
750
734
  }
@@ -1125,10 +1109,6 @@ export async function create(args) {
1125
1109
  // provider/API settings are enough for Claude Code. If no usable
1126
1110
  // auth was present, the claude-code entry was removed above.
1127
1111
  }
1128
- const geminiEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'gemini-cli');
1129
- if (geminiEntry) {
1130
- ensureGeminiWorkspaceTrust(geminiEntry.dir);
1131
- }
1132
1112
  const opencodeEntry = effectiveResolvedTools.find(({ tool }) => tool.id === 'opencode');
1133
1113
  if (opencodeEntry) {
1134
1114
  // The TUI reads <toolDir>/opencode.json via OPENCODE_CONFIG pinned in tools.js.
@@ -8,7 +8,7 @@ import { resolveTools, toolConfigDirCandidates } from '../tools.js';
8
8
  const USAGE = `Usage: ai sandbox show <branch | TASK-id | N>
9
9
 
10
10
  Shows one sandbox's worktree path and per-tool state paths (Claude Code,
11
- Codex, Gemini CLI, OpenCode). The argument follows the same contract as
11
+ Codex, Antigravity CLI, OpenCode). The argument follows the same contract as
12
12
  'ai sandbox exec' and 'ai sandbox start': N (bare) is the recommended form
13
13
  for task short ids (e.g. 'ai sandbox show 11'); a TASK-id or a plain
14
14
  branch name are also accepted. Use 'ai sandbox ls' for the container list.`;
@@ -0,0 +1,101 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { resolveTaskRef } from './resolve-ref.js';
4
+ import { locateActivityLog, appendActivityEntry } from './activity-log.js';
5
+ import { buildArtifactLinkSection, parseArtifactName } from './artifact-lifecycle.js';
6
+ import { captureTaskWriteMetadata, writeTask } from './write.js';
7
+ function failed(intent, code, message, taskId = null) {
8
+ return {
9
+ status: 'failed', changed: false, intent: 'append', taskId,
10
+ artifact: intent.artifact ?? null, operations: [], error: { code, message }
11
+ };
12
+ }
13
+ function oneLine(value) {
14
+ return value.replace(/\s*\r?\n\s*/g, ' ').trim();
15
+ }
16
+ /**
17
+ * Append an Activity Log entry (and, optionally, a `## 审查反馈` artifact link)
18
+ * to an active task via the atomic `writeTask` path. `current_step` is never
19
+ * touched (PL-2): review-pr does not join the standard stage chain.
20
+ */
21
+ export function applyActivityAppendIntent(intent, options = {}) {
22
+ if (intent.kind !== 'append')
23
+ return failed(intent, 'ACTIVITY_INTENT_INVALID', 'intent kind must be append');
24
+ const resolved = resolveTaskRef(intent.taskRef, { repoRoot: options.repoRoot });
25
+ if (!resolved.ok)
26
+ return failed(intent, resolved.code, resolved.message, resolved.taskId);
27
+ if (resolved.state !== 'active') {
28
+ return failed(intent, 'TASK_STATE_MISMATCH', `task ${resolved.taskId} is ${resolved.state}, expected active`, resolved.taskId);
29
+ }
30
+ const step = oneLine(intent.step);
31
+ const agent = oneLine(intent.agent);
32
+ const note = oneLine(intent.note);
33
+ if (!step || !agent || !note || /[\r\n]/.test(intent.step) || /[\r\n]/.test(intent.agent) || /[\r\n]/.test(intent.note)) {
34
+ return failed(intent, 'ACTIVITY_INTENT_INVALID', 'step, agent and note must be non-empty single-line values', resolved.taskId);
35
+ }
36
+ let artifact = null;
37
+ if (intent.artifact !== undefined) {
38
+ artifact = parseArtifactName(intent.artifact);
39
+ if (!artifact || artifact.family !== 'pr-review') {
40
+ return failed(intent, 'ACTIVITY_ARTIFACT_INVALID', `artifact '${intent.artifact}' is not a canonical pr-review artifact`, resolved.taskId);
41
+ }
42
+ }
43
+ let content;
44
+ try {
45
+ content = fs.readFileSync(resolved.taskMdPath, 'utf8');
46
+ }
47
+ catch (error) {
48
+ return failed(intent, 'TASK_READ_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
49
+ }
50
+ const section = locateActivityLog(content);
51
+ if (!section) {
52
+ return failed(intent, 'ACTIVITY_SECTION_MISSING', 'task has no unique Activity Log section', resolved.taskId);
53
+ }
54
+ let metadata;
55
+ try {
56
+ metadata = (options.metadataProvider ?? captureTaskWriteMetadata)();
57
+ }
58
+ catch (error) {
59
+ return failed(intent, 'METADATA_CAPTURE_FAILED', error instanceof Error ? error.message : String(error), resolved.taskId);
60
+ }
61
+ const mutations = [];
62
+ const activityBody = appendActivityEntry(section, { time: metadata.timestamp, step, agent, note });
63
+ mutations.push({ kind: 'section', aliases: ['活动日志', 'Activity Log'], heading: section.heading, body: activityBody });
64
+ if (artifact) {
65
+ const link = buildArtifactLinkSection(content, {
66
+ ...artifact,
67
+ path: path.join(resolved.taskDir, artifact.name),
68
+ size: 0,
69
+ mtimeMs: 0
70
+ });
71
+ mutations.push({ kind: 'section', aliases: link.aliases, heading: link.heading, body: link.body });
72
+ }
73
+ const writeResult = writeTask({
74
+ taskRef: intent.taskRef,
75
+ expectedState: 'active',
76
+ mutations,
77
+ dryRun: intent.dryRun
78
+ }, {
79
+ ...options,
80
+ taskLocation: {
81
+ repoRoot: resolved.repoRoot,
82
+ taskId: resolved.taskId,
83
+ taskMdPath: resolved.taskMdPath,
84
+ state: resolved.state
85
+ },
86
+ metadataProvider: () => metadata
87
+ });
88
+ if (writeResult.status === 'failed') {
89
+ return failed(intent, writeResult.error.code, writeResult.error.message, writeResult.taskId);
90
+ }
91
+ return {
92
+ status: writeResult.status,
93
+ changed: writeResult.changed,
94
+ intent: 'append',
95
+ taskId: writeResult.taskId,
96
+ artifact: intent.artifact ?? null,
97
+ operations: writeResult.operations,
98
+ error: null
99
+ };
100
+ }
101
+ //# sourceMappingURL=activity-intent.js.map
@@ -12,7 +12,8 @@ const artifactFamilyCatalog = [
12
12
  { family: 'review-plan', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['技术方案审查', 'Plan Review'] },
13
13
  { family: 'code', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['实现报告', 'Implementation Report'] },
14
14
  { family: 'review-code', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['代码审查', 'Code Review'] },
15
- { family: 'manual-validation', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['人工验证', 'Manual Validation'] }
15
+ { family: 'manual-validation', sectionAliases: ['实现备注', 'Implementation Notes'], heading: '实现备注', labels: ['人工验证', 'Manual Validation'] },
16
+ { family: 'pr-review', sectionAliases: ['审查反馈', 'Review Feedback'], heading: '审查反馈', labels: ['PR 审查报告', 'PR Review Report'] }
16
17
  ];
17
18
  const FAMILY_SET = new Set(artifactFamilyCatalog.map((item) => item.family));
18
19
  const BLOCKING_DIAGNOSTICS = new Set([
@@ -1,4 +1,5 @@
1
1
  import fs from 'node:fs';
2
+ import { classifyAgent } from '../../agent-clients/tokens.js';
2
3
  import { formatTable } from '../../table.js';
3
4
  import { parseTaskScope } from '../command-options.js';
4
5
  import { resolveTaskContext } from '../resolve-ref.js';
@@ -30,11 +31,11 @@ const TABLE_HEADERS = ['#', 'STEP', 'AGENT', 'STARTED', 'DONE', 'NOTE'];
30
31
  // with ` [started]`; the matching done entry carries the identical base action
31
32
  // without the suffix. Pairing therefore keys on the base action (including any
32
33
  // `(Round N)`), so every round and every repeated execution pairs on its own.
33
- // Short agent tokens that actually appear in activity logs for AI executors
34
- // (workflow recommended_agents claude/codex/gemini/cursor + enabled TUI opencode;
35
- // note these differ from the `.airc.json` long names claude-code/gemini-cli).
36
- // Any other executor token (a human name, possibly CJK) is treated as human.
37
- const KNOWN_AI_AGENTS = new Set(['claude', 'codex', 'gemini', 'opencode', 'cursor']);
34
+ // Known AI tokens, long-name mapping, and loose rendering classification live
35
+ // in lib/agent-clients/tokens.ts (single source of truth shared with the
36
+ // write-side internal commands). Any other executor token (a human name,
37
+ // possibly CJK, or an unknown value) is rendered as human with a visible
38
+ // `(unknown)` marker.
38
39
  const REVIEW_STAGE_PREFIXES = [
39
40
  { prefix: 'Review Analysis', stage: 'analysis' },
40
41
  { prefix: 'Review Plan', stage: 'plan' },
@@ -83,12 +84,11 @@ function humanValidationCount(note) {
83
84
  function isHumanCountField(field) {
84
85
  return fieldNumber(field, 'manual-validation') !== undefined || fieldNumber(field, 'human-decision') !== undefined;
85
86
  }
86
- // A step is human-executed when its agent token is not a known AI token. Take
87
- // the first whitespace-delimited token and drop any trailing parenthetical
88
- // annotation (e.g. `张三 (executed on host)` -> `张三`) before the lookup.
89
- function isHumanAgent(agent) {
90
- const token = agent.trim().split(/\s+/)[0]?.replace(/\(.*$/, '') ?? '';
91
- return token !== '' && !KNOWN_AI_AGENTS.has(token);
87
+ // A step is human-executed when its agent token is not a known AI token.
88
+ // Known long names (claude-code -> claude, gemini-cli -> gemini) classify as
89
+ // AI; empty or unknown tokens classify as non-AI (human).
90
+ export function isHumanAgent(agent) {
91
+ return classifyAgent(agent).status !== 'ai';
92
92
  }
93
93
  // Fold the two human counts into a review row's verdict NOTE: comma-joined, right
94
94
  // after the blockers/major/minor list and before the ` → artifact` link, mirroring
@@ -148,8 +148,9 @@ function log(args = []) {
148
148
  const note = stage
149
149
  ? foldHumanCounts(s.note, humanDecisionCounts.get(stage) ?? 0, humanValidationCount(s.note))
150
150
  : s.note;
151
- const human = isHumanAgent(s.agent);
152
- const agent = human ? 'human' : s.agent;
151
+ const { status, display } = classifyAgent(s.agent);
152
+ const human = status !== 'ai';
153
+ const agent = status === 'unknown' ? `${display} (unknown)` : display;
153
154
  const started = s.started || (human ? '-' : '');
154
155
  return [String(idx + 1), s.step, agent, started, s.done || (s.started ? '(in progress)' : ''), note];
155
156
  });
@@ -158,5 +159,5 @@ function log(args = []) {
158
159
  }
159
160
  process.stdout.write(`Total: ${steps.length} steps\n`);
160
161
  }
161
- export { log, isHumanAgent };
162
+ export { log };
162
163
  //# sourceMappingURL=log.js.map
@@ -14,7 +14,9 @@ function prepareDelegation(input, options = {}) {
14
14
  ...input,
15
15
  id: (options.id ?? randomUUID)(),
16
16
  actualModel: null,
17
+ actualReasoningEffort: null,
17
18
  modelFallbackReason: null,
19
+ reasoningEffortFallbackReason: null,
18
20
  parentId: null,
19
21
  childId: null,
20
22
  spawnMode: null,
@@ -41,10 +43,27 @@ function activateDelegation(receipt, event, options = {}) {
41
43
  }
42
44
  if (event.spawnMode !== 'fresh')
43
45
  return fail('DELEGATION_FORK_FORBIDDEN', `spawn mode '${event.spawnMode}' is not fresh`);
44
- const actualModel = event.actualModel ?? null;
45
- if (actualModel && receipt.requestedModel && actualModel !== receipt.requestedModel && !event.modelFallbackReason) {
46
+ const actualModel = event.actualModel;
47
+ if (!actualModel || actualModel.trim() !== actualModel) {
48
+ return fail('DELEGATION_MODEL_IDENTITY_MISSING', 'native start event must provide a non-empty actual model identity');
49
+ }
50
+ if (actualModel !== receipt.requestedModel && (!event.modelFallbackReason || event.modelFallbackReason.trim() === '')) {
46
51
  return fail('DELEGATION_MODEL_FALLBACK_UNRECORDED', 'actual model differs from requested model without a fallback reason');
47
52
  }
53
+ const actualReasoningEffort = event.actualReasoningEffort;
54
+ if (!actualReasoningEffort || actualReasoningEffort.trim() !== actualReasoningEffort) {
55
+ return fail('DELEGATION_REASONING_EFFORT_MISSING', 'native start event must provide a non-empty actual reasoning effort');
56
+ }
57
+ if (actualReasoningEffort !== receipt.requestedReasoningEffort
58
+ && (!event.reasoningEffortFallbackReason || event.reasoningEffortFallbackReason.trim() === '')) {
59
+ return fail('DELEGATION_REASONING_EFFORT_FALLBACK_UNRECORDED', 'actual reasoning effort differs from requested effort without a fallback reason');
60
+ }
61
+ if (actualModel === receipt.requestedModel && event.modelFallbackReason) {
62
+ return fail('DELEGATION_MODEL_FALLBACK_INVALID', 'model fallback reason is only valid when actual model differs');
63
+ }
64
+ if (actualReasoningEffort === receipt.requestedReasoningEffort && event.reasoningEffortFallbackReason) {
65
+ return fail('DELEGATION_REASONING_EFFORT_FALLBACK_INVALID', 'reasoning-effort fallback reason is only valid when actual effort differs');
66
+ }
48
67
  return { ok: true, receipt: Object.freeze({
49
68
  ...receipt,
50
69
  status: 'activated',
@@ -52,7 +71,9 @@ function activateDelegation(receipt, event, options = {}) {
52
71
  childId: event.childId,
53
72
  spawnMode: event.spawnMode,
54
73
  actualModel,
74
+ actualReasoningEffort,
55
75
  modelFallbackReason: event.modelFallbackReason ?? null,
76
+ reasoningEffortFallbackReason: event.reasoningEffortFallbackReason ?? null,
56
77
  activatedAt: (options.now ?? (() => new Date().toISOString()))()
57
78
  }) };
58
79
  }