@fitlab-ai/agent-infra 0.9.9 → 0.9.11

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 (309) hide show
  1. package/README.md +13 -3
  2. package/README.zh-CN.md +13 -3
  3. package/bin/cli.ts +17 -4
  4. package/dist/bin/cli.js +19 -4
  5. package/dist/bin/internal-cli.js +55 -4
  6. package/dist/lib/agent-client.js +0 -1
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +17 -10
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-context.js +11 -31
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +15 -33
  10. package/dist/lib/agent-clients/adapters/codex-sandbox.js +72 -11
  11. package/dist/lib/agent-clients/adapters/index.js +3 -1
  12. package/dist/lib/agent-clients/adapters/opencode-sandbox.js +0 -4
  13. package/dist/lib/agent-clients/adapters/traecli.js +65 -0
  14. package/dist/lib/agent-clients/config.js +14 -99
  15. package/dist/lib/agent-clients/reconcile.js +1 -11
  16. package/dist/lib/agent-clients/schema.js +5 -4
  17. package/dist/lib/agent-clients/tokens.js +7 -17
  18. package/dist/lib/agent-clients/types.js +2 -1
  19. package/dist/lib/decide.js +14 -30
  20. package/dist/lib/defaults.json +9 -0
  21. package/dist/lib/init.js +2 -2
  22. package/dist/lib/internal/codex-lifecycle.js +2 -2
  23. package/dist/lib/internal/codex-sandbox-controller.js +4 -3
  24. package/dist/lib/internal/release-workflow.js +0 -1
  25. package/dist/lib/internal/sandbox-control.js +2 -2
  26. package/dist/lib/internal/task-finalization.js +19 -9
  27. package/dist/lib/internal/task-ledger.js +8 -2
  28. package/dist/lib/internal/task-lifecycle.js +17 -93
  29. package/dist/lib/internal/task-orchestration.js +30 -216
  30. package/dist/lib/{task/commands/validate.js → internal/task-validate.js} +77 -43
  31. package/dist/lib/merge.js +205 -103
  32. package/dist/lib/process-data/normalize.js +2 -9
  33. package/dist/lib/run/host.js +46 -16
  34. package/dist/lib/run/tui.js +5 -2
  35. package/dist/lib/sandbox/agent-client-reconciler.js +4 -12
  36. package/dist/lib/sandbox/commands/create.js +3 -3
  37. package/dist/lib/sandbox/commands/enter.js +18 -4
  38. package/dist/lib/sandbox/config.js +3 -12
  39. package/dist/lib/sandbox/control/controller-registration.js +4 -2
  40. package/dist/lib/sandbox/control/executor.js +135 -40
  41. package/dist/lib/sandbox/control/lifecycle.js +29 -20
  42. package/dist/lib/sandbox/control/server.js +18 -16
  43. package/dist/lib/sandbox/mounts.js +3 -2
  44. package/dist/lib/sandbox/recovery.js +123 -22
  45. package/dist/lib/sandbox/workspace-identity.js +14 -0
  46. package/dist/lib/sandbox/workspace-view.js +8 -9
  47. package/dist/lib/self-update.js +278 -0
  48. package/dist/lib/server/protocol.js +5 -5
  49. package/dist/lib/task/activity-log.js +4 -1
  50. package/dist/lib/task/artifact-lifecycle.js +4 -2
  51. package/dist/lib/task/codex-orchestration.js +32 -35
  52. package/dist/lib/task/command-options.js +1 -3
  53. package/dist/lib/task/commands/cat.js +0 -5
  54. package/dist/lib/task/commands/decisions.js +76 -92
  55. package/dist/lib/task/commands/files.js +6 -6
  56. package/dist/lib/task/commands/grep.js +25 -61
  57. package/dist/lib/task/commands/issue-body.js +6 -6
  58. package/dist/lib/task/commands/log.js +25 -10
  59. package/dist/lib/task/commands/show.js +5 -6
  60. package/dist/lib/task/commands/status.js +8 -8
  61. package/dist/lib/task/commit-operation.js +21 -25
  62. package/dist/lib/task/commit-policy.js +1 -1
  63. package/dist/lib/task/control-authority.js +431 -0
  64. package/dist/lib/task/create.js +6 -1
  65. package/dist/lib/task/current-contract.js +35 -0
  66. package/dist/lib/task/decision-details.js +263 -0
  67. package/dist/lib/task/decision-intents.js +5 -2
  68. package/dist/lib/task/delegation-receipts.js +8 -7
  69. package/dist/lib/task/events.js +11 -5
  70. package/dist/lib/task/finalization.js +72 -46
  71. package/dist/lib/task/index.js +19 -29
  72. package/dist/lib/task/ledger-intents.js +8 -9
  73. package/dist/lib/task/ledger.js +13 -6
  74. package/dist/lib/task/lifecycle.js +16 -0
  75. package/dist/lib/task/orchestration.js +51 -14
  76. package/dist/lib/task/review-artifacts.js +31 -12
  77. package/dist/lib/task/review-finalization.js +19 -6
  78. package/dist/lib/task/verification-engine.js +38 -18
  79. package/dist/lib/task/verification-review.js +1 -1
  80. package/dist/lib/task/workspace-snapshot.js +5 -11
  81. package/dist/lib/task/write.js +11 -1
  82. package/dist/lib/update.js +6 -37
  83. package/dist/lib/version.js +5 -1
  84. package/dist/lifecycle-build-manifest.json +3 -3
  85. package/lib/agent-client.ts +0 -1
  86. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +25 -10
  87. package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +16 -33
  88. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +16 -35
  89. package/lib/agent-clients/adapters/codex-sandbox.ts +89 -14
  90. package/lib/agent-clients/adapters/index.ts +3 -1
  91. package/lib/agent-clients/adapters/opencode-sandbox.ts +0 -5
  92. package/lib/agent-clients/adapters/traecli.ts +66 -0
  93. package/lib/agent-clients/config.ts +14 -144
  94. package/lib/agent-clients/reconcile.ts +1 -12
  95. package/lib/agent-clients/schema.ts +5 -4
  96. package/lib/agent-clients/tokens.ts +7 -20
  97. package/lib/agent-clients/types.ts +2 -1
  98. package/lib/decide.ts +12 -22
  99. package/lib/defaults.json +9 -0
  100. package/lib/init.ts +2 -2
  101. package/lib/internal/codex-lifecycle.ts +2 -2
  102. package/lib/internal/codex-sandbox-controller.ts +4 -3
  103. package/lib/internal/release-workflow.ts +0 -1
  104. package/lib/internal/sandbox-control.ts +2 -2
  105. package/lib/internal/task-finalization.ts +27 -13
  106. package/lib/internal/task-ledger.ts +8 -2
  107. package/lib/internal/task-lifecycle.ts +33 -76
  108. package/lib/internal/task-orchestration.ts +33 -190
  109. package/lib/{task/commands/validate.ts → internal/task-validate.ts} +77 -41
  110. package/lib/merge.ts +236 -120
  111. package/lib/process-data/normalize.ts +2 -8
  112. package/lib/run/host.ts +63 -14
  113. package/lib/run/tui.ts +5 -3
  114. package/lib/sandbox/agent-client-reconciler.ts +5 -15
  115. package/lib/sandbox/commands/create.ts +4 -4
  116. package/lib/sandbox/commands/enter.ts +24 -4
  117. package/lib/sandbox/config.ts +2 -14
  118. package/lib/sandbox/control/container-identity.ts +2 -2
  119. package/lib/sandbox/control/controller-registration.ts +8 -3
  120. package/lib/sandbox/control/executor.ts +156 -53
  121. package/lib/sandbox/control/lifecycle.ts +34 -28
  122. package/lib/sandbox/control/protocol.ts +1 -3
  123. package/lib/sandbox/control/server.ts +15 -12
  124. package/lib/sandbox/control/state.ts +7 -7
  125. package/lib/sandbox/mounts.ts +4 -3
  126. package/lib/sandbox/recovery.ts +162 -34
  127. package/lib/sandbox/tools.ts +1 -1
  128. package/lib/sandbox/workspace-identity.ts +28 -0
  129. package/lib/sandbox/workspace-view.ts +14 -10
  130. package/lib/self-update.ts +341 -0
  131. package/lib/server/protocol.ts +5 -5
  132. package/lib/task/activity-log.ts +6 -1
  133. package/lib/task/artifact-lifecycle.ts +5 -3
  134. package/lib/task/codex-orchestration.ts +40 -45
  135. package/lib/task/command-options.ts +1 -2
  136. package/lib/task/commands/cat.ts +0 -4
  137. package/lib/task/commands/decisions.ts +80 -75
  138. package/lib/task/commands/files.ts +6 -6
  139. package/lib/task/commands/grep.ts +23 -51
  140. package/lib/task/commands/issue-body.ts +6 -6
  141. package/lib/task/commands/log.ts +22 -10
  142. package/lib/task/commands/show.ts +5 -6
  143. package/lib/task/commands/status.ts +8 -8
  144. package/lib/task/commit-operation.ts +25 -30
  145. package/lib/task/commit-policy.ts +1 -2
  146. package/lib/task/control-authority.ts +563 -0
  147. package/lib/task/create.ts +6 -1
  148. package/lib/task/current-contract.ts +49 -0
  149. package/lib/task/decision-details.ts +340 -0
  150. package/lib/task/decision-intents.ts +7 -2
  151. package/lib/task/delegation-receipts.ts +8 -6
  152. package/lib/task/events.ts +10 -5
  153. package/lib/task/finalization.ts +84 -42
  154. package/lib/task/index.ts +19 -28
  155. package/lib/task/ledger-intents.ts +6 -8
  156. package/lib/task/ledger.ts +17 -7
  157. package/lib/task/lifecycle.ts +20 -0
  158. package/lib/task/orchestration.ts +42 -16
  159. package/lib/task/review-artifacts.ts +53 -15
  160. package/lib/task/review-finalization.ts +33 -7
  161. package/lib/task/verification-engine.ts +33 -21
  162. package/lib/task/verification-review.ts +1 -1
  163. package/lib/task/workspace-snapshot.ts +4 -13
  164. package/lib/task/write.ts +20 -1
  165. package/lib/update.ts +6 -40
  166. package/lib/version.ts +6 -1
  167. package/package.json +1 -1
  168. package/templates/.agents/QUICKSTART.en.md +2 -3
  169. package/templates/.agents/QUICKSTART.zh-CN.md +2 -3
  170. package/templates/.agents/README.en.md +5 -3
  171. package/templates/.agents/README.zh-CN.md +5 -3
  172. package/templates/.agents/rules/README.en.md +1 -0
  173. package/templates/.agents/rules/README.zh-CN.md +1 -0
  174. package/templates/.agents/rules/compatibility-policy.en.md +40 -0
  175. package/templates/.agents/rules/compatibility-policy.zh-CN.md +40 -0
  176. package/templates/.agents/rules/create-issue.github.en.md +1 -1
  177. package/templates/.agents/rules/create-issue.github.zh-CN.md +1 -1
  178. package/templates/.agents/rules/human-decision-context.en.md +9 -7
  179. package/templates/.agents/rules/human-decision-context.zh-CN.md +9 -7
  180. package/templates/.agents/rules/issue-fields.github.en.md +1 -1
  181. package/templates/.agents/rules/issue-fields.github.zh-CN.md +1 -1
  182. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  183. package/templates/.agents/rules/issue-pr-commands.github.en.md +1 -1
  184. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +1 -1
  185. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  186. package/templates/.agents/rules/issue-sync.github.en.md +1 -1
  187. package/templates/.agents/rules/issue-sync.github.zh-CN.md +2 -2
  188. package/templates/.agents/rules/lifecycle-orchestration.en.md +4 -4
  189. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +4 -4
  190. package/templates/.agents/rules/milestone-inference.github.en.md +1 -1
  191. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +1 -1
  192. package/templates/.agents/rules/next-step-output.en.md +3 -3
  193. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -3
  194. package/templates/.agents/rules/no-mid-flow-questions.en.md +1 -1
  195. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +1 -1
  196. package/templates/.agents/rules/pr-sync.en.md +2 -2
  197. package/templates/.agents/rules/pr-sync.github.en.md +3 -2
  198. package/templates/.agents/rules/pr-sync.github.zh-CN.md +3 -1
  199. package/templates/.agents/rules/pr-sync.zh-CN.md +2 -1
  200. package/templates/.agents/rules/release-commands.github.en.md +6 -0
  201. package/templates/.agents/rules/release-commands.github.zh-CN.md +6 -0
  202. package/templates/.agents/rules/review-handshake.en.md +1 -1
  203. package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
  204. package/templates/.agents/rules/review-method.en.md +1 -0
  205. package/templates/.agents/rules/review-method.zh-CN.md +1 -0
  206. package/templates/.agents/rules/task-management.en.md +1 -2
  207. package/templates/.agents/rules/task-management.zh-CN.md +1 -2
  208. package/templates/.agents/skills/analyze-task/SKILL.en.md +4 -3
  209. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +4 -3
  210. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  211. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  212. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  213. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  214. package/templates/.agents/skills/check-task/SKILL.en.md +2 -2
  215. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +2 -2
  216. package/templates/.agents/skills/close-codescan/SKILL.en.md +1 -1
  217. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +1 -1
  218. package/templates/.agents/skills/close-dependabot/SKILL.en.md +1 -1
  219. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +1 -1
  220. package/templates/.agents/skills/code-task/SKILL.en.md +4 -3
  221. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +5 -3
  222. package/templates/.agents/skills/commit/SKILL.en.md +27 -7
  223. package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -4
  224. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -5
  225. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -5
  226. package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
  227. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
  228. package/templates/.agents/skills/create-pr/SKILL.en.md +15 -11
  229. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +15 -11
  230. package/templates/.agents/skills/create-pr/reference/change-report.en.md +46 -0
  231. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +46 -0
  232. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +203 -0
  233. package/templates/.agents/skills/create-release-note/SKILL.en.md +5 -6
  234. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +5 -6
  235. package/templates/.agents/skills/create-task/SKILL.en.md +1 -1
  236. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -1
  237. package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
  238. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
  239. package/templates/.agents/skills/plan-task/SKILL.en.md +5 -4
  240. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -4
  241. package/templates/.agents/skills/restore-task/SKILL.en.md +1 -1
  242. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +1 -1
  243. package/templates/.agents/skills/review-analysis/SKILL.en.md +5 -3
  244. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +5 -3
  245. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -0
  246. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -0
  247. package/templates/.agents/skills/review-code/SKILL.en.md +5 -3
  248. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -3
  249. package/templates/.agents/skills/review-code/config/verify.en.json +1 -0
  250. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -0
  251. package/templates/.agents/skills/review-code/reference/migration-risks.en.md +9 -6
  252. package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +9 -6
  253. package/templates/.agents/skills/review-plan/SKILL.en.md +5 -3
  254. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +5 -3
  255. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -0
  256. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -0
  257. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +7 -3
  258. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +7 -3
  259. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +1 -1
  260. package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +1 -1
  261. package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -2
  262. package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -2
  263. package/templates/.agents/skills/run-task/SKILL.en.md +6 -2
  264. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +6 -2
  265. package/templates/.agents/skills/run-task/reference/host-validation.en.md +2 -2
  266. package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +2 -2
  267. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -2
  268. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -2
  269. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +159 -104
  270. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  271. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  272. package/templates/.agents/templates/task.en.md +1 -1
  273. package/templates/.agents/templates/task.zh-CN.md +1 -1
  274. package/templates/.claude/commands/analyze-task.en.md +1 -1
  275. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  276. package/templates/.claude/commands/block-task.en.md +1 -1
  277. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  278. package/templates/.claude/commands/cancel-task.en.md +1 -1
  279. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  280. package/templates/.claude/commands/check-task.en.md +1 -1
  281. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  282. package/templates/.claude/commands/code-task.en.md +1 -1
  283. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  284. package/templates/.claude/commands/commit.en.md +1 -1
  285. package/templates/.claude/commands/commit.zh-CN.md +1 -1
  286. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  287. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  288. package/templates/.claude/commands/complete-task.en.md +1 -1
  289. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  290. package/templates/.claude/commands/create-pr.en.md +1 -1
  291. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  292. package/templates/.claude/commands/plan-task.en.md +1 -1
  293. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  294. package/templates/.claude/commands/review-analysis.en.md +1 -1
  295. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  296. package/templates/.claude/commands/review-code.en.md +1 -1
  297. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  298. package/templates/.claude/commands/review-plan.en.md +1 -1
  299. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  300. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  301. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  302. package/templates/.claude/commands/run-task.en.md +1 -1
  303. package/templates/.claude/commands/run-task.zh-CN.md +1 -1
  304. package/templates/.claude/commands/watch-pr.en.md +1 -1
  305. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  306. package/templates/.traecli/commands/update-agent-infra.en.md +7 -0
  307. package/templates/.traecli/commands/update-agent-infra.zh-CN.md +7 -0
  308. package/dist/lib/builtin-tuis.js +0 -40
  309. package/lib/builtin-tuis.ts +0 -56
@@ -1,9 +1,9 @@
1
1
  import { preflightCodexLifecycleEvidence, resolveCodexSpawnedChild, resolveCodexTerminal, resolveCodexThread } from '../agent-clients/adapters/codex-lifecycle/app-server.js';
2
2
  import { createCodexLifecycleStore } from '../agent-clients/adapters/codex-lifecycle/store.js';
3
3
  import { createCodexCapabilityStore, isCodexCapabilityProvenanceDetail } from '../agent-clients/adapters/codex-lifecycle/capability-store.js';
4
- import { computeLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.js';
5
- import { verifyCodexSandboxControllerContext } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.js';
6
- import { verifyCodexSandboxControllerContext as verifyControllerContextFile } from '../agent-clients/adapters/codex-lifecycle/controller-context.js';
4
+ import { computeLifecycleBuildIdentity, verifyLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.js';
5
+ import { verifyCodexSandboxControllerContextWithWarnings as verifySandboxControllerWithWarnings } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.js';
6
+ import { verifyCodexSandboxControllerContextWithWarnings as verifyControllerContextFileWithWarnings } from '../agent-clients/adapters/codex-lifecycle/controller-context.js';
7
7
  import { resolveTaskRef } from './resolve-ref.js';
8
8
  import { activateMatchingOrchestrationDelegation, hasActivatableOrchestrationDelegation, hasSealableOrchestrationDelegation, OrchestrationStateError, pauseMatchingOrchestrationDelegation, prepareOrchestrationDelegation, reconcileMatchingOrchestrationDelegation, sealMatchingOrchestrationDelegationWithHostEvidence } from './orchestration.js';
9
9
  function coreOptions(options) {
@@ -42,29 +42,6 @@ function requiredStore(options) {
42
42
  throw new Error('Codex lifecycle store is required for orchestration bridge events');
43
43
  return options.store;
44
44
  }
45
- function controllerContext(repoRoot, brokerController) {
46
- const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
47
- if (!contextPath)
48
- return null;
49
- if (brokerController) {
50
- return verifyControllerContextFile(contextPath, {
51
- repoRoot,
52
- generation: process.env.AGENT_INFRA_CONTROL_GENERATION ?? brokerController.controlGeneration
53
- });
54
- }
55
- return verifyCodexSandboxControllerContext(contextPath, { repoRoot });
56
- }
57
- function brokerBindingConflictsWithContext(repoRoot, brokerController) {
58
- const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
59
- if (!contextPath || !brokerController)
60
- return false;
61
- const context = verifyControllerContextFile(contextPath, {
62
- repoRoot,
63
- generation: process.env.AGENT_INFRA_CONTROL_GENERATION ?? brokerController.controlGeneration
64
- });
65
- return context.controllerInstanceDigest !== brokerController.instanceDigest
66
- || context.controlGeneration !== brokerController.controlGeneration;
67
- }
68
45
  function brokerControllerBinding() {
69
46
  const raw = process.env.AGENT_INFRA_CONTROL_CONTROLLER_BINDING;
70
47
  if (!raw)
@@ -100,11 +77,18 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
100
77
  return bridgeFailure('ORCHESTRATION_CODEX_CAPABILITY_REQUIRED', 'Codex prepare requires a current-session capability token');
101
78
  }
102
79
  const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
103
- const brokerController = brokerControllerBinding();
104
- if (brokerBindingConflictsWithContext(repoRoot, brokerController)) {
105
- return bridgeFailure('CODEX_SANDBOX_CONTROLLER_BINDING_MISMATCH', 'broker and local controller bindings do not match');
106
- }
107
- const localController = controllerContext(repoRoot, brokerController);
80
+ const brokerController = options.controllerBinding ?? brokerControllerBinding();
81
+ const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
82
+ const contextVerification = contextPath
83
+ ? (brokerController
84
+ ? verifyControllerContextFileWithWarnings(contextPath, {
85
+ repoRoot,
86
+ generation: process.env.AGENT_INFRA_CONTROL_GENERATION ?? brokerController.controlGeneration
87
+ })
88
+ : verifySandboxControllerWithWarnings(contextPath, { repoRoot }))
89
+ : null;
90
+ const identityWarnings = [...(contextVerification?.warnings ?? [])];
91
+ const localController = contextVerification?.context ?? null;
108
92
  if (localController && brokerController
109
93
  && (localController.controllerInstanceDigest !== brokerController.instanceDigest
110
94
  || localController.controlGeneration !== brokerController.controlGeneration)) {
@@ -116,6 +100,11 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
116
100
  } : null);
117
101
  const capabilityStore = options.capabilityStore ?? createCodexCapabilityStore();
118
102
  const attested = capabilityStore.inspect(input.capabilityToken);
103
+ const capabilityIdentity = verifyLifecycleBuildIdentity(attested.buildIdentity, buildIdentity);
104
+ if (!capabilityIdentity.ok) {
105
+ return bridgeFailure(capabilityIdentity.code, capabilityIdentity.message);
106
+ }
107
+ identityWarnings.push(...capabilityIdentity.warnings);
119
108
  const lifecycleProvenance = {
120
109
  ...attested.buildIdentity,
121
110
  hookDefinitionHash: preflight.hookDefinitionHash,
@@ -135,7 +124,7 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
135
124
  controlGeneration: controller.controlGeneration
136
125
  } } : {})
137
126
  };
138
- return prepareOrchestrationDelegation(taskRef, {
127
+ const prepared = prepareOrchestrationDelegation(taskRef, {
139
128
  ...input,
140
129
  lifecycleProvenance
141
130
  }, {
@@ -175,6 +164,9 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
175
164
  }
176
165
  }
177
166
  });
167
+ return identityWarnings.length > 0 && prepared.status !== 'failed'
168
+ ? { ...prepared, warnings: Object.freeze(identityWarnings) }
169
+ : prepared;
178
170
  }
179
171
  catch (error) {
180
172
  if (error instanceof OrchestrationStateError)
@@ -216,10 +208,11 @@ async function activateCodexOrchestrationDelegation(childThreadId, options = {})
216
208
  });
217
209
  const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
218
210
  const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
219
- const controller = contextPath
220
- ? verifyCodexSandboxControllerContext(contextPath, { repoRoot })
211
+ const contextVerification = contextPath
212
+ ? verifySandboxControllerWithWarnings(contextPath, { repoRoot })
221
213
  : null;
222
- return activateMatchingOrchestrationDelegation('codex', {
214
+ const controller = contextVerification?.context ?? null;
215
+ const activated = activateMatchingOrchestrationDelegation('codex', {
223
216
  nativeAgent: evidence.nativeAgent,
224
217
  childId: evidence.childThreadId,
225
218
  parentId: evidence.parentThreadId,
@@ -244,6 +237,10 @@ async function activateCodexOrchestrationDelegation(childThreadId, options = {})
244
237
  controlGeneration: controller?.controlGeneration ?? null
245
238
  }
246
239
  }, coreOptions(options));
240
+ const warnings = contextVerification?.warnings ?? [];
241
+ return warnings.length > 0 && activated.status !== 'failed'
242
+ ? { ...activated, warnings: Object.freeze(warnings) }
243
+ : activated;
247
244
  }
248
245
  catch (error) {
249
246
  if (error instanceof OrchestrationStateError)
@@ -11,9 +11,7 @@ function parseTaskScope(args) {
11
11
  throw new Error(`${arg} requires a value`);
12
12
  }
13
13
  else if (arg.startsWith('--task=')) {
14
- value = arg.slice('--task='.length);
15
- if (value === '')
16
- throw new Error('--task requires a value');
14
+ throw new Error("--task=... is not supported; use --task <ref> or -t <ref>");
17
15
  }
18
16
  else {
19
17
  positionals.push(arg);
@@ -4,11 +4,9 @@ import { resolveTaskContext } from '../resolve-ref.js';
4
4
  import { resolveArtifact } from '../artifacts.js';
5
5
  const USAGE = `Usage: ai task cat <artifact | N>
6
6
  ai task cat (--task <ref> | -t <ref>) <artifact | N>
7
- ai task cat <ref> <artifact | N>
8
7
 
9
8
  Prints a task artifact's raw content to stdout.
10
9
  One positional Uses current task context and treats the operand as the artifact.
11
- <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
10
  <artifact | N> Artifact filename (with or without '.md'), or the number from 'ai task files'.
13
11
  `;
14
12
  function cat(args = []) {
@@ -39,9 +37,6 @@ function cat(args = []) {
39
37
  else if (scope.positionals.length === 1) {
40
38
  artifact = scope.positionals[0];
41
39
  }
42
- else if (scope.positionals.length === 2) {
43
- [taskRef, artifact] = scope.positionals;
44
- }
45
40
  else {
46
41
  process.stdout.write(USAGE);
47
42
  process.exitCode = 1;
@@ -3,19 +3,18 @@ import path from 'node:path';
3
3
  import { formatTable } from '../../table.js';
4
4
  import { parseTaskScope } from '../command-options.js';
5
5
  import { resolveTaskContext } from '../resolve-ref.js';
6
- import { isReviewStage, parseLedger } from '../ledger.js';
6
+ import { isReviewStage, parseLedgerDocument } from '../ledger.js';
7
7
  import { listDecisionItems, selectDecisionItem } from '../decision-items.js';
8
- import { extractSubSection } from '../sections.js';
8
+ import { normalizeDecisionDetailForDisplay, parseDecisionEvidence, resolveDecisionDetail } from '../decision-details.js';
9
9
  const USAGE = `Usage: ai task decisions [--task <ref> | -t <ref>] [--item <selector> | -i <selector>] [options]
10
- ai task decisions <ref> [selector] [options]
11
10
 
12
11
  Shows what still needs a maintainer's decision. Without a selector, it lists
13
12
  the choices. With a selector, it shows the explanation and how to respond.
14
13
  Read-only.
15
14
 
16
- Omit <ref> Resolve the unique active task for the current branch.
17
- <ref> Legacy positional task ref.
18
- [selector] Ordinal (1-based) or ledger id (e.g. 'PL-3') to show one item's detail.
15
+ Omit the scope Resolve the unique active task for the current branch.
16
+ --task/-t <ref> Select a task explicitly.
17
+ --item/-i <s> Ordinal (1-based) or ledger id (e.g. 'PL-3') to show one item's detail.
19
18
 
20
19
  Options:
21
20
  -i, --item <s> Select an item when task scope is implicit or flag-based.
@@ -53,15 +52,8 @@ function parseArgs(args) {
53
52
  i += 1;
54
53
  }
55
54
  else if (a.startsWith('--item=')) {
56
- if (out.item !== undefined) {
57
- fail("duplicate option '--item'");
58
- return null;
59
- }
60
- out.item = a.slice('--item='.length);
61
- if (out.item === '') {
62
- fail('--item requires a value');
63
- return null;
64
- }
55
+ fail("--item=... is not supported; use --item <selector> or -i <selector>");
56
+ return null;
65
57
  }
66
58
  else if (a === '--stage') {
67
59
  const v = args[i + 1];
@@ -97,48 +89,26 @@ function parseArgs(args) {
97
89
  }
98
90
  return out;
99
91
  }
100
- // Parse `<file>.md#anchor` evidence into its filename, when present.
101
- function evidenceFile(evidence) {
102
- const m = /([\w.-]+\.md)#/.exec(evidence);
103
- return m ? m[1] : null;
104
- }
105
- function roundOf(file) {
106
- const m = /-r(\d+)\.md$/.exec(file);
107
- return m ? Number.parseInt(m[1], 10) : 1;
108
- }
109
- // Locate the `### {ledger-id}` detail block for a row. Prefer the artifact named by the
110
- // row's evidence anchor; otherwise scan analysis/plan/code artifacts and return
111
- // the block from the highest-round file that contains it. Returns '' when none
112
- // is found (caller degrades gracefully — plan B3).
113
92
  function findDetailBlock(row, taskDir) {
114
- const hinted = evidenceFile(row.evidence);
115
- if (hinted) {
116
- const p = path.join(taskDir, hinted);
117
- if (fs.existsSync(p)) {
118
- const block = extractSubSection(fs.readFileSync(p, 'utf8'), row.id);
119
- if (block)
120
- return block;
121
- }
122
- }
123
- let best = '';
124
- let bestRound = -1;
125
- let entries;
93
+ const evidence = parseDecisionEvidence(row.evidence);
94
+ if (!evidence.ok)
95
+ return { status: 'invalid', reason: `invalid evidence '${row.evidence}'` };
96
+ const artifactPath = path.join(taskDir, evidence.artifact);
97
+ if (!fs.existsSync(artifactPath))
98
+ return { status: 'missing', reason: `artifact '${evidence.artifact}' is missing` };
99
+ let artifactContent;
126
100
  try {
127
- entries = fs.readdirSync(taskDir);
101
+ artifactContent = fs.readFileSync(artifactPath, 'utf8');
128
102
  }
129
103
  catch {
130
- return '';
104
+ return { status: 'missing', reason: `artifact '${evidence.artifact}' cannot be read` };
131
105
  }
132
- for (const file of entries) {
133
- if (!/^(analysis|plan|code)(-r\d+)?\.md$/.test(file))
134
- continue;
135
- const block = extractSubSection(fs.readFileSync(path.join(taskDir, file), 'utf8'), row.id);
136
- if (block && roundOf(file) > bestRound) {
137
- best = block;
138
- bestRound = roundOf(file);
139
- }
140
- }
141
- return best;
106
+ const resolved = resolveDecisionDetail(artifactContent, row.id, evidence.anchor);
107
+ if (resolved.status === 'found')
108
+ return { status: 'found', content: normalizeDecisionDetailForDisplay(resolved.block) };
109
+ if (resolved.status === 'ambiguous')
110
+ return { status: 'ambiguous', reason: resolved.reason };
111
+ return { status: 'missing', reason: resolved.reason };
142
112
  }
143
113
  // Pull the `## 人工裁决` record lines that mention this ledger id, so a decided item
144
114
  // shows the human's recorded ruling alongside its detail block.
@@ -160,9 +130,9 @@ function findDecisionRecord(id, content) {
160
130
  return out;
161
131
  }
162
132
  function titleOf(row, taskDir) {
163
- const block = findDetailBlock(row, taskDir);
164
- if (block) {
165
- const title = block
133
+ const detail = findDetailBlock(row, taskDir);
134
+ if (detail.status === 'found') {
135
+ const title = detail.content
166
136
  .split('\n')[0]
167
137
  .replace(/^###\s+/, '')
168
138
  .replace(/\s*\[needs-human-decision\]\s*$/, '')
@@ -174,7 +144,7 @@ function titleOf(row, taskDir) {
174
144
  function trackingOf(row) {
175
145
  return `stage=${row.stage} · severity=${row.severity} · status=${row.status} · evidence=${row.evidence}`;
176
146
  }
177
- function renderList(rows, format, taskDir) {
147
+ function renderList(rows, format, taskDir, taskId) {
178
148
  if (rows.length === 0) {
179
149
  process.stdout.write('No pending decisions.\n');
180
150
  return;
@@ -193,10 +163,10 @@ function renderList(rows, format, taskDir) {
193
163
  `| ${sep.join(' | ')} |`,
194
164
  ...data.map((row) => `| ${row.join(' | ')} |`)
195
165
  ];
196
- process.stdout.write(`${md.join('\n')}\n\nView one item: ai task decisions <task-ref> <ordinal|ledger-id>\n`);
166
+ process.stdout.write(`${md.join('\n')}\n\nView one item: ai task decisions --task ${taskId} --item <ordinal|ledger-id>\n`);
197
167
  return;
198
168
  }
199
- process.stdout.write(`${formatTable(headers, data).join('\n')}\n\nView one item: ai task decisions <task-ref> <ordinal|ledger-id>\n`);
169
+ process.stdout.write(`${formatTable(headers, data).join('\n')}\n\nView one item: ai task decisions --task ${taskId} --item <ordinal|ledger-id>\n`);
200
170
  }
201
171
  function renderTracking(row, format) {
202
172
  if (format === 'markdown') {
@@ -216,29 +186,31 @@ function renderTracking(row, format) {
216
186
  `evidence: ${row.evidence}`
217
187
  ];
218
188
  }
219
- function renderDetail(rows, selector, format, taskDir, content) {
189
+ function renderDetail(rows, selector, format, taskDir, content, taskId) {
220
190
  const selected = selectDecisionItem(rows, selector);
221
191
  if (!selected.ok) {
222
192
  fail(selected.message);
223
193
  return;
224
194
  }
225
195
  const r = selected.row;
226
- const block = findDetailBlock(r, taskDir);
227
- const title = titleOf(r, taskDir);
196
+ const detail = findDetailBlock(r, taskDir);
197
+ if (detail.status === 'invalid' || detail.status === 'ambiguous') {
198
+ fail(`cannot resolve ${r.id}: ${detail.reason}`);
199
+ return;
200
+ }
201
+ const block = detail.status === 'found' ? detail.content : '';
202
+ const title = block
203
+ ? block.split('\n')[0].replace(/^###\s+/, '').replace(/\s*\[needs-human-decision\]\s*$/, '').trim()
204
+ .replace(new RegExp(`^${r.id}\\s*[::]\\s*`, 'i'), '').trim()
205
+ : '(explanation unavailable)';
228
206
  const lines = [];
229
207
  const decided = r.status === 'human-decided';
230
208
  if (format === 'markdown') {
231
209
  lines.push(`## ${decided ? 'Decision already recorded' : 'Decision needed'}: ${title}`, '');
232
- if (!decided) {
233
- lines.push('**How to record your choice**', `\`ai decide <task-ref> ${r.id} <your choice and rationale>\``, '');
234
- }
235
210
  lines.push('**Original context**', '');
236
211
  }
237
212
  else {
238
213
  lines.push(`${decided ? 'Decision already recorded' : 'Decision needed'}: ${title}`, '');
239
- if (!decided) {
240
- lines.push('How to record your choice:', `ai decide <task-ref> ${r.id} <your choice and rationale>`, '');
241
- }
242
214
  lines.push('Original context:');
243
215
  }
244
216
  if (block) {
@@ -252,6 +224,15 @@ function renderDetail(rows, selector, format, taskDir, content) {
252
224
  lines.push('', format === 'markdown' ? '**Recorded choice**' : 'Recorded choice:');
253
225
  lines.push(...(record.length ? record : ['No separate ruling record was found.']));
254
226
  }
227
+ if (!decided) {
228
+ lines.push('');
229
+ if (format === 'markdown') {
230
+ lines.push('**How to record your choice**', `\`ai decide --task ${taskId} --item ${r.id} <your choice and rationale>\``);
231
+ }
232
+ else {
233
+ lines.push('How to record your choice:', `ai decide --task ${taskId} --item ${r.id} <your choice and rationale>`);
234
+ }
235
+ }
255
236
  lines.push('', ...renderTracking(r, format));
256
237
  process.stdout.write(`${lines.join('\n')}\n`);
257
238
  }
@@ -279,43 +260,46 @@ function decisions(args = []) {
279
260
  fail(`invalid --format '${parsed.format}' (expected text|markdown)`);
280
261
  return;
281
262
  }
282
- let taskRef = scope.taskRef;
283
- let selector = parsed.item;
284
- if (parsed.item !== undefined) {
285
- if (parsed.positionals.length > 0) {
286
- fail('positional task ref/selector cannot be combined with --item');
287
- return;
288
- }
289
- }
290
- else if (scope.explicit) {
291
- if (parsed.positionals.length > 0) {
292
- fail('positional task ref/selector cannot be combined with --task');
293
- return;
294
- }
295
- }
296
- else {
297
- if (parsed.positionals.length > 2) {
298
- fail('too many positional arguments');
299
- return;
300
- }
301
- taskRef = parsed.positionals[0];
302
- selector = parsed.positionals[1];
263
+ const taskRef = scope.taskRef;
264
+ const selector = parsed.item;
265
+ if (parsed.positionals.length > 0) {
266
+ fail('positional task ref/selector is not supported; use --task <ref> or -t <ref>, and --item <selector> or -i <selector>');
267
+ return;
303
268
  }
304
269
  const resolved = resolveTaskContext(taskRef);
305
270
  if (!resolved.ok) {
306
271
  fail(resolved.message);
307
272
  return;
308
273
  }
309
- const content = fs.readFileSync(resolved.taskMdPath, 'utf8');
310
- const rows = listDecisionItems(parseLedger(content), {
274
+ let content;
275
+ let ledger;
276
+ try {
277
+ content = fs.readFileSync(resolved.taskMdPath, 'utf8');
278
+ ledger = parseLedgerDocument(content);
279
+ }
280
+ catch (error) {
281
+ fail(`ledger unavailable [LEDGER_DOCUMENT_INVALID]: ${error instanceof Error ? error.message : String(error)}`);
282
+ return;
283
+ }
284
+ if (!ledger.present) {
285
+ fail('ledger unavailable [LEDGER_SECTION_MISSING]: review disagreement ledger section is missing');
286
+ return;
287
+ }
288
+ const rows = listDecisionItems(ledger.rows, {
311
289
  includeDecided: parsed.all,
312
290
  stage: parsed.stage
313
291
  });
314
292
  if (selector === undefined) {
315
- renderList(rows, parsed.format, resolved.taskDir);
293
+ renderList(rows, parsed.format, resolved.taskDir, resolved.taskId);
316
294
  }
317
295
  else {
318
- renderDetail(rows, selector, parsed.format, resolved.taskDir, content);
296
+ const selectionRows = /^[A-Za-z]+-\d+$/.test(selector)
297
+ ? listDecisionItems(ledger.rows, {
298
+ includeDecided: true,
299
+ stage: parsed.stage
300
+ })
301
+ : rows;
302
+ renderDetail(selectionRows, selector, parsed.format, resolved.taskDir, content, resolved.taskId);
319
303
  }
320
304
  }
321
305
  export { decisions };
@@ -2,11 +2,11 @@ import { formatTable } from '../../table.js';
2
2
  import { parseTaskScope } from '../command-options.js';
3
3
  import { resolveTaskContext } from '../resolve-ref.js';
4
4
  import { enumerateArtifacts } from '../artifacts.js';
5
- const USAGE = `Usage: ai task files [<N | TASK-id> | --task <ref> | -t <ref>]
5
+ const USAGE = `Usage: ai task files [--task <ref> | -t <ref>]
6
6
 
7
7
  Lists the artifacts in a task directory with stable numbers.
8
- Omit <ref> Resolve the unique active task for the current branch.
9
- <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
8
+ Omit the scope Resolve the unique active task for the current branch.
9
+ --task/-t <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
10
10
 
11
11
  Columns: # (artifact number, usable with 'ai task cat') / NAME / SIZE (bytes) / MTIME
12
12
  `;
@@ -33,12 +33,12 @@ function files(args = []) {
33
33
  process.exitCode = 1;
34
34
  return;
35
35
  }
36
- if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
37
- process.stderr.write('ai task files: task ref must be provided once\n');
36
+ if (scope.positionals.length > 0) {
37
+ process.stderr.write('ai task files: positional task ref is not supported; use --task <ref> or -t <ref>\n');
38
38
  process.exitCode = 1;
39
39
  return;
40
40
  }
41
- const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
41
+ const resolved = resolveTaskContext(scope.taskRef);
42
42
  if (!resolved.ok) {
43
43
  process.stderr.write(`ai task files: ${resolved.message}\n`);
44
44
  process.exitCode = 1;
@@ -1,24 +1,19 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import { resolveTaskContext, resolveTaskRef, detectRepoRoot, enumerateTaskDirs } from '../resolve-ref.js';
3
+ import { resolveTaskContext, resolveTaskRef } from '../resolve-ref.js';
4
4
  import { enumerateArtifacts, resolveArtifact } from '../artifacts.js';
5
5
  import { loadShortIdByTaskId } from '../short-id.js';
6
- const USAGE = `Usage: ai task grep <pattern> [ref] [artifact | N]
7
- ai task grep <pattern> (--current | --task <ref> | -t <ref>) [artifact | N]
6
+ const USAGE = `Usage: ai task grep [--current | --task <ref> | -t <ref>] <pattern> [artifact | N]
8
7
 
9
8
  Literal (non-regex) line search across task artifacts.
10
9
  <pattern> Literal substring to match (NOT a regex). Case-sensitive by default.
11
- [ref] Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
- Omit to scan every task under active / blocked / completed
13
- (archive is skipped). With a ref, narrows to that single task
14
- (a TASK-id ref can also resolve an archived task).
15
- [artifact | N] Only valid with <ref>. Artifact filename (with or without '.md')
10
+ --current Limit search to the unique active task for the current branch.
11
+ -t, --task <ref> Limit search to an explicit task (bare short id or TASK-id).
12
+ [artifact | N] Artifact filename (with or without '.md')
16
13
  or the number from 'ai task files'. Narrows to a single artifact.
17
14
 
18
15
  Options:
19
16
  -i, --ignore-case Case-insensitive matching.
20
- --current Limit search to the current task context.
21
- -t, --task <ref> Limit search to an explicit task.
22
17
  -- Treat the rest as positional (use for patterns starting with '-').
23
18
 
24
19
  Output: '{taskId} [#short] {fileStem}:{line}: {matched-line}' (short id only for active tasks).
@@ -92,17 +87,9 @@ function grep(args = []) {
92
87
  continue;
93
88
  }
94
89
  if (!optsEnded && a.startsWith('--task=')) {
95
- if (taskRef !== undefined) {
96
- process.stderr.write("ai task grep: duplicate option '--task'\n");
97
- process.exitCode = 1;
98
- return;
99
- }
100
- taskRef = a.slice('--task='.length);
101
- if (taskRef === '') {
102
- process.stderr.write('ai task grep: --task requires a value\n');
103
- process.exitCode = 1;
104
- return;
105
- }
90
+ process.stderr.write('ai task grep: --task=... is not supported; use --task <ref> or -t <ref>\n');
91
+ process.exitCode = 1;
92
+ return;
106
93
  continue;
107
94
  }
108
95
  if (!optsEnded && a.startsWith('-') && a !== '-') {
@@ -122,63 +109,40 @@ function grep(args = []) {
122
109
  process.exitCode = 1;
123
110
  return;
124
111
  }
125
- if (positional.length > 3 || ((current || taskRef !== undefined) && positional.length > 2)) {
112
+ if (positional.length > 2) {
126
113
  process.stderr.write('ai task grep: too many arguments\n');
127
114
  process.exitCode = 1;
128
115
  return;
129
116
  }
130
- let [pattern, ref, artifactOrN] = positional;
131
- if (current || taskRef !== undefined) {
132
- artifactOrN = ref;
133
- ref = taskRef;
134
- }
117
+ const [pattern, artifactOrN] = positional;
135
118
  const matcher = makeMatcher(pattern, ignoreCase);
136
119
  const chunks = [];
137
120
  const emit = (line) => chunks.push(line);
138
121
  let total = 0;
139
- if (ref === undefined && !current) {
140
- // No ref: full scan across active / blocked / completed (no archive).
141
- let repoRoot;
122
+ const resolved = current || taskRef === undefined
123
+ ? resolveTaskContext()
124
+ : resolveTaskRef(taskRef);
125
+ if (!resolved.ok) {
126
+ process.stderr.write(`ai task grep: ${resolved.message}\n`);
127
+ process.exitCode = 1;
128
+ return;
129
+ }
130
+ const shortToken = loadShortIdByTaskId(resolved.repoRoot).get(resolved.taskId);
131
+ if (artifactOrN !== undefined) {
132
+ let artifactPath;
142
133
  try {
143
- repoRoot = detectRepoRoot();
134
+ artifactPath = resolveArtifact(resolved.taskDir, artifactOrN);
144
135
  }
145
136
  catch (e) {
146
137
  process.stderr.write(`ai task grep: ${e.message}\n`);
147
138
  process.exitCode = 1;
148
139
  return;
149
140
  }
150
- const shortMap = loadShortIdByTaskId(repoRoot);
151
- for (const { taskId, taskDir } of enumerateTaskDirs(repoRoot)) {
152
- const shortToken = shortMap.get(taskId);
153
- for (const a of enumerateArtifacts(taskDir)) {
154
- total += scanArtifact(taskId, shortToken, a.path, matcher, emit);
155
- }
156
- }
141
+ total += scanArtifact(resolved.taskId, shortToken, artifactPath, matcher, emit);
157
142
  }
158
143
  else {
159
- const resolved = current ? resolveTaskContext() : resolveTaskRef(ref);
160
- if (!resolved.ok) {
161
- process.stderr.write(`ai task grep: ${resolved.message}\n`);
162
- process.exitCode = 1;
163
- return;
164
- }
165
- const shortToken = loadShortIdByTaskId(resolved.repoRoot).get(resolved.taskId);
166
- if (artifactOrN !== undefined) {
167
- let artifactPath;
168
- try {
169
- artifactPath = resolveArtifact(resolved.taskDir, artifactOrN);
170
- }
171
- catch (e) {
172
- process.stderr.write(`ai task grep: ${e.message}\n`);
173
- process.exitCode = 1;
174
- return;
175
- }
176
- total += scanArtifact(resolved.taskId, shortToken, artifactPath, matcher, emit);
177
- }
178
- else {
179
- for (const a of enumerateArtifacts(resolved.taskDir)) {
180
- total += scanArtifact(resolved.taskId, shortToken, a.path, matcher, emit);
181
- }
144
+ for (const a of enumerateArtifacts(resolved.taskDir)) {
145
+ total += scanArtifact(resolved.taskId, shortToken, a.path, matcher, emit);
182
146
  }
183
147
  }
184
148
  if (total === 0) {
@@ -4,11 +4,11 @@ import { resolveTaskContext } from '../resolve-ref.js';
4
4
  import { extractTitle } from '../frontmatter.js';
5
5
  import { extractSection, findSectionHeading } from '../sections.js';
6
6
  import { renderTemplateBody, PLACEHOLDER } from '../issue-form.js';
7
- const USAGE = `Usage: ai task issue-body [<ref> | --task <ref> | -t <ref>] [--template <path>]
7
+ const USAGE = `Usage: ai task issue-body [--task <ref> | -t <ref>] [--template <path>]
8
8
 
9
9
  Print a deterministic Issue body extracted from a task's task.md.
10
- Omit <ref> Resolve the unique active task for the current branch.
11
- <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
10
+ Omit the scope Resolve the unique active task for the current branch.
11
+ --task/-t <ref> Bare numeric short id, or a full TASK-YYYYMMDD-HHMMSS id.
12
12
  --template <path> Render the final body for the given GitHub Issue Form (scenario A);
13
13
  without it, print the default '任务输入 + 描述 + 需求' body (scenario B).
14
14
 
@@ -71,12 +71,12 @@ function issueBody(args = []) {
71
71
  process.exitCode = 1;
72
72
  return;
73
73
  }
74
- if (scope.positionals.length > 1 || (scope.explicit && scope.positionals.length > 0)) {
75
- process.stderr.write('ai task issue-body: task ref must be provided once\n');
74
+ if (scope.positionals.length > 0) {
75
+ process.stderr.write('ai task issue-body: positional task ref is not supported; use --task <ref> or -t <ref>\n');
76
76
  process.exitCode = 1;
77
77
  return;
78
78
  }
79
- const resolved = resolveTaskContext(scope.taskRef ?? scope.positionals[0]);
79
+ const resolved = resolveTaskContext(scope.taskRef);
80
80
  if (!resolved.ok) {
81
81
  process.stderr.write(`ai task issue-body: ${resolved.message}\n`);
82
82
  process.exitCode = 1;