@fitlab-ai/agent-infra 0.9.10 → 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 (269) 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 +50 -4
  6. package/dist/lib/agent-client.js +0 -1
  7. package/dist/lib/agent-clients/adapters/opencode-sandbox.js +0 -4
  8. package/dist/lib/agent-clients/adapters/traecli.js +7 -8
  9. package/dist/lib/agent-clients/config.js +14 -99
  10. package/dist/lib/agent-clients/reconcile.js +1 -11
  11. package/dist/lib/agent-clients/schema.js +5 -4
  12. package/dist/lib/agent-clients/tokens.js +5 -15
  13. package/dist/lib/decide.js +14 -30
  14. package/dist/lib/defaults.json +4 -0
  15. package/dist/lib/init.js +2 -2
  16. package/dist/lib/internal/release-workflow.js +0 -1
  17. package/dist/lib/internal/task-finalization.js +19 -9
  18. package/dist/lib/internal/task-ledger.js +8 -2
  19. package/dist/lib/internal/task-lifecycle.js +17 -93
  20. package/dist/lib/internal/task-orchestration.js +30 -216
  21. package/dist/lib/internal/task-validate.js +2 -1
  22. package/dist/lib/merge.js +205 -103
  23. package/dist/lib/process-data/normalize.js +2 -9
  24. package/dist/lib/run/host.js +46 -16
  25. package/dist/lib/sandbox/agent-client-reconciler.js +4 -12
  26. package/dist/lib/sandbox/commands/create.js +3 -3
  27. package/dist/lib/sandbox/commands/enter.js +18 -4
  28. package/dist/lib/sandbox/config.js +3 -12
  29. package/dist/lib/sandbox/control/executor.js +131 -39
  30. package/dist/lib/sandbox/control/lifecycle.js +29 -20
  31. package/dist/lib/sandbox/control/server.js +18 -16
  32. package/dist/lib/sandbox/mounts.js +3 -2
  33. package/dist/lib/sandbox/recovery.js +123 -22
  34. package/dist/lib/sandbox/workspace-identity.js +14 -0
  35. package/dist/lib/sandbox/workspace-view.js +8 -9
  36. package/dist/lib/self-update.js +278 -0
  37. package/dist/lib/server/protocol.js +5 -5
  38. package/dist/lib/task/activity-log.js +4 -1
  39. package/dist/lib/task/artifact-lifecycle.js +4 -2
  40. package/dist/lib/task/codex-orchestration.js +1 -1
  41. package/dist/lib/task/command-options.js +1 -3
  42. package/dist/lib/task/commands/cat.js +0 -5
  43. package/dist/lib/task/commands/decisions.js +76 -92
  44. package/dist/lib/task/commands/files.js +6 -6
  45. package/dist/lib/task/commands/grep.js +25 -61
  46. package/dist/lib/task/commands/issue-body.js +6 -6
  47. package/dist/lib/task/commands/log.js +25 -10
  48. package/dist/lib/task/commands/show.js +5 -6
  49. package/dist/lib/task/commands/status.js +8 -8
  50. package/dist/lib/task/commit-operation.js +21 -25
  51. package/dist/lib/task/commit-policy.js +1 -1
  52. package/dist/lib/task/control-authority.js +431 -0
  53. package/dist/lib/task/create.js +6 -1
  54. package/dist/lib/task/current-contract.js +35 -0
  55. package/dist/lib/task/decision-details.js +263 -0
  56. package/dist/lib/task/decision-intents.js +5 -2
  57. package/dist/lib/task/events.js +11 -5
  58. package/dist/lib/task/index.js +19 -20
  59. package/dist/lib/task/ledger-intents.js +8 -9
  60. package/dist/lib/task/ledger.js +13 -6
  61. package/dist/lib/task/lifecycle.js +16 -0
  62. package/dist/lib/task/orchestration.js +50 -13
  63. package/dist/lib/task/review-artifacts.js +31 -12
  64. package/dist/lib/task/review-finalization.js +19 -6
  65. package/dist/lib/task/verification-engine.js +38 -15
  66. package/dist/lib/task/verification-review.js +1 -1
  67. package/dist/lib/task/workspace-snapshot.js +5 -11
  68. package/dist/lib/task/write.js +11 -1
  69. package/dist/lib/update.js +6 -37
  70. package/dist/lib/version.js +5 -1
  71. package/dist/lifecycle-build-manifest.json +3 -3
  72. package/lib/agent-client.ts +0 -1
  73. package/lib/agent-clients/adapters/opencode-sandbox.ts +0 -5
  74. package/lib/agent-clients/adapters/traecli.ts +7 -8
  75. package/lib/agent-clients/config.ts +14 -144
  76. package/lib/agent-clients/reconcile.ts +1 -12
  77. package/lib/agent-clients/schema.ts +5 -4
  78. package/lib/agent-clients/tokens.ts +5 -18
  79. package/lib/decide.ts +12 -22
  80. package/lib/defaults.json +4 -0
  81. package/lib/init.ts +2 -2
  82. package/lib/internal/release-workflow.ts +0 -1
  83. package/lib/internal/task-finalization.ts +27 -13
  84. package/lib/internal/task-ledger.ts +8 -2
  85. package/lib/internal/task-lifecycle.ts +33 -76
  86. package/lib/internal/task-orchestration.ts +33 -190
  87. package/lib/internal/task-validate.ts +3 -2
  88. package/lib/merge.ts +236 -120
  89. package/lib/process-data/normalize.ts +2 -8
  90. package/lib/run/host.ts +63 -14
  91. package/lib/sandbox/agent-client-reconciler.ts +5 -15
  92. package/lib/sandbox/commands/create.ts +4 -4
  93. package/lib/sandbox/commands/enter.ts +24 -4
  94. package/lib/sandbox/config.ts +2 -14
  95. package/lib/sandbox/control/container-identity.ts +2 -2
  96. package/lib/sandbox/control/executor.ts +148 -51
  97. package/lib/sandbox/control/lifecycle.ts +34 -28
  98. package/lib/sandbox/control/protocol.ts +1 -3
  99. package/lib/sandbox/control/server.ts +15 -12
  100. package/lib/sandbox/control/state.ts +7 -7
  101. package/lib/sandbox/mounts.ts +4 -3
  102. package/lib/sandbox/recovery.ts +162 -34
  103. package/lib/sandbox/tools.ts +1 -1
  104. package/lib/sandbox/workspace-identity.ts +28 -0
  105. package/lib/sandbox/workspace-view.ts +14 -10
  106. package/lib/self-update.ts +341 -0
  107. package/lib/server/protocol.ts +5 -5
  108. package/lib/task/activity-log.ts +6 -1
  109. package/lib/task/artifact-lifecycle.ts +5 -3
  110. package/lib/task/codex-orchestration.ts +2 -1
  111. package/lib/task/command-options.ts +1 -2
  112. package/lib/task/commands/cat.ts +0 -4
  113. package/lib/task/commands/decisions.ts +80 -75
  114. package/lib/task/commands/files.ts +6 -6
  115. package/lib/task/commands/grep.ts +23 -51
  116. package/lib/task/commands/issue-body.ts +6 -6
  117. package/lib/task/commands/log.ts +22 -10
  118. package/lib/task/commands/show.ts +5 -6
  119. package/lib/task/commands/status.ts +8 -8
  120. package/lib/task/commit-operation.ts +25 -30
  121. package/lib/task/commit-policy.ts +1 -2
  122. package/lib/task/control-authority.ts +563 -0
  123. package/lib/task/create.ts +6 -1
  124. package/lib/task/current-contract.ts +49 -0
  125. package/lib/task/decision-details.ts +340 -0
  126. package/lib/task/decision-intents.ts +7 -2
  127. package/lib/task/events.ts +10 -5
  128. package/lib/task/index.ts +19 -20
  129. package/lib/task/ledger-intents.ts +6 -8
  130. package/lib/task/ledger.ts +17 -7
  131. package/lib/task/lifecycle.ts +20 -0
  132. package/lib/task/orchestration.ts +40 -15
  133. package/lib/task/review-artifacts.ts +53 -15
  134. package/lib/task/review-finalization.ts +33 -7
  135. package/lib/task/verification-engine.ts +33 -18
  136. package/lib/task/verification-review.ts +1 -1
  137. package/lib/task/workspace-snapshot.ts +4 -13
  138. package/lib/task/write.ts +20 -1
  139. package/lib/update.ts +6 -40
  140. package/lib/version.ts +6 -1
  141. package/package.json +1 -1
  142. package/templates/.agents/README.en.md +5 -3
  143. package/templates/.agents/README.zh-CN.md +5 -3
  144. package/templates/.agents/rules/compatibility-policy.en.md +5 -4
  145. package/templates/.agents/rules/compatibility-policy.zh-CN.md +5 -4
  146. package/templates/.agents/rules/create-issue.github.en.md +1 -1
  147. package/templates/.agents/rules/create-issue.github.zh-CN.md +1 -1
  148. package/templates/.agents/rules/human-decision-context.en.md +9 -7
  149. package/templates/.agents/rules/human-decision-context.zh-CN.md +9 -7
  150. package/templates/.agents/rules/issue-fields.github.en.md +1 -1
  151. package/templates/.agents/rules/issue-fields.github.zh-CN.md +1 -1
  152. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  153. package/templates/.agents/rules/issue-pr-commands.github.en.md +1 -1
  154. package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +1 -1
  155. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  156. package/templates/.agents/rules/issue-sync.github.en.md +1 -1
  157. package/templates/.agents/rules/issue-sync.github.zh-CN.md +2 -2
  158. package/templates/.agents/rules/milestone-inference.github.en.md +1 -1
  159. package/templates/.agents/rules/milestone-inference.github.zh-CN.md +1 -1
  160. package/templates/.agents/rules/next-step-output.en.md +3 -3
  161. package/templates/.agents/rules/next-step-output.zh-CN.md +3 -3
  162. package/templates/.agents/rules/no-mid-flow-questions.en.md +1 -1
  163. package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +1 -1
  164. package/templates/.agents/rules/pr-sync.en.md +1 -1
  165. package/templates/.agents/rules/pr-sync.github.en.md +1 -1
  166. package/templates/.agents/rules/pr-sync.github.zh-CN.md +1 -1
  167. package/templates/.agents/rules/pr-sync.zh-CN.md +1 -1
  168. package/templates/.agents/rules/release-commands.github.en.md +6 -0
  169. package/templates/.agents/rules/release-commands.github.zh-CN.md +6 -0
  170. package/templates/.agents/rules/review-handshake.en.md +1 -1
  171. package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
  172. package/templates/.agents/rules/task-management.en.md +1 -2
  173. package/templates/.agents/rules/task-management.zh-CN.md +1 -2
  174. package/templates/.agents/skills/analyze-task/SKILL.en.md +3 -3
  175. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +3 -3
  176. package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
  177. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
  178. package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
  179. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
  180. package/templates/.agents/skills/check-task/SKILL.en.md +2 -2
  181. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +2 -2
  182. package/templates/.agents/skills/close-codescan/SKILL.en.md +1 -1
  183. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +1 -1
  184. package/templates/.agents/skills/close-dependabot/SKILL.en.md +1 -1
  185. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +1 -1
  186. package/templates/.agents/skills/code-task/SKILL.en.md +3 -3
  187. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +3 -3
  188. package/templates/.agents/skills/commit/SKILL.en.md +27 -7
  189. package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -4
  190. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -5
  191. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -5
  192. package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
  193. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
  194. package/templates/.agents/skills/create-pr/SKILL.en.md +5 -7
  195. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +5 -7
  196. package/templates/.agents/skills/create-pr/reference/change-report.en.md +9 -4
  197. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +9 -4
  198. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +203 -0
  199. package/templates/.agents/skills/create-release-note/SKILL.en.md +5 -6
  200. package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +5 -6
  201. package/templates/.agents/skills/create-task/SKILL.en.md +1 -1
  202. package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -1
  203. package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
  204. package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
  205. package/templates/.agents/skills/plan-task/SKILL.en.md +3 -3
  206. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +3 -3
  207. package/templates/.agents/skills/restore-task/SKILL.en.md +1 -1
  208. package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +1 -1
  209. package/templates/.agents/skills/review-analysis/SKILL.en.md +5 -3
  210. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +5 -3
  211. package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -0
  212. package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -0
  213. package/templates/.agents/skills/review-code/SKILL.en.md +5 -3
  214. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -3
  215. package/templates/.agents/skills/review-code/config/verify.en.json +1 -0
  216. package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -0
  217. package/templates/.agents/skills/review-code/reference/migration-risks.en.md +2 -1
  218. package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +2 -1
  219. package/templates/.agents/skills/review-plan/SKILL.en.md +5 -3
  220. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +5 -3
  221. package/templates/.agents/skills/review-plan/config/verify.en.json +1 -0
  222. package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -0
  223. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +4 -0
  224. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +4 -0
  225. package/templates/.agents/skills/run-task/SKILL.en.md +4 -0
  226. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +4 -0
  227. package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -2
  228. package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -2
  229. package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +140 -109
  230. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  231. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  232. package/templates/.agents/templates/task.en.md +1 -1
  233. package/templates/.agents/templates/task.zh-CN.md +1 -1
  234. package/templates/.claude/commands/analyze-task.en.md +1 -1
  235. package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
  236. package/templates/.claude/commands/block-task.en.md +1 -1
  237. package/templates/.claude/commands/block-task.zh-CN.md +1 -1
  238. package/templates/.claude/commands/cancel-task.en.md +1 -1
  239. package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
  240. package/templates/.claude/commands/check-task.en.md +1 -1
  241. package/templates/.claude/commands/check-task.zh-CN.md +1 -1
  242. package/templates/.claude/commands/code-task.en.md +1 -1
  243. package/templates/.claude/commands/code-task.zh-CN.md +1 -1
  244. package/templates/.claude/commands/commit.en.md +1 -1
  245. package/templates/.claude/commands/commit.zh-CN.md +1 -1
  246. package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
  247. package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
  248. package/templates/.claude/commands/complete-task.en.md +1 -1
  249. package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
  250. package/templates/.claude/commands/create-pr.en.md +1 -1
  251. package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
  252. package/templates/.claude/commands/plan-task.en.md +1 -1
  253. package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
  254. package/templates/.claude/commands/review-analysis.en.md +1 -1
  255. package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
  256. package/templates/.claude/commands/review-code.en.md +1 -1
  257. package/templates/.claude/commands/review-code.zh-CN.md +1 -1
  258. package/templates/.claude/commands/review-plan.en.md +1 -1
  259. package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
  260. package/templates/.claude/commands/run-manual-validation.en.md +1 -1
  261. package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
  262. package/templates/.claude/commands/run-task.en.md +1 -1
  263. package/templates/.claude/commands/run-task.zh-CN.md +1 -1
  264. package/templates/.claude/commands/watch-pr.en.md +1 -1
  265. package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
  266. package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.en.md +0 -1
  267. package/templates/{.trae/skills → .traecli/commands}/update-agent-infra.zh-CN.md +0 -1
  268. package/dist/lib/builtin-tuis.js +0 -40
  269. package/lib/builtin-tuis.ts +0 -56
@@ -79,6 +79,20 @@ export function resolveSandboxTarget(requestedRef, repoRoot) {
79
79
  }
80
80
  return { requestedRef, branch: requestedRef, workspace: { mode: 'branch-only' } };
81
81
  }
82
+ export function resolveSandboxReentryContext(params) {
83
+ if (params.target.workspace.mode !== 'branch-only'
84
+ || params.containerWorkspace.mode !== 'task-bound') {
85
+ return { workspace: params.target.workspace, reentry: 'standard' };
86
+ }
87
+ const task = resolveTaskWorkspace(params.containerWorkspace.taskId, params.repoRoot);
88
+ if (task.state !== 'completed' || task.branch !== params.target.branch) {
89
+ return { workspace: params.target.workspace, reentry: 'standard' };
90
+ }
91
+ return {
92
+ workspace: { mode: 'task-bound', taskId: task.taskId },
93
+ reentry: 'completed'
94
+ };
95
+ }
82
96
  export function resolveSandboxCleanupTarget(requestedRef, repoRoot, options = {}) {
83
97
  if (isRemovedHashShortIdInput(requestedRef)) {
84
98
  throw new Error(`Invalid task short id '${requestedRef}': task short ids must use bare digits`);
@@ -171,14 +171,12 @@ export function materializeSandboxControl(params) {
171
171
  const token = randomBytes(32).toString('hex');
172
172
  const generation = randomBytes(16).toString('hex');
173
173
  const repoRoot = fs.realpathSync.native(params.repoRoot);
174
- const manifest = {
175
- version: 5,
174
+ const manifestDraft = {
176
175
  engine: params.engine ?? 'docker',
177
176
  repoRoot,
178
177
  worktreeRoot: fs.realpathSync.native(params.worktreeRoot),
179
178
  project: params.project,
180
179
  container: params.container,
181
- containerIdentity: { id: '', labels: {} },
182
180
  branch: params.branch,
183
181
  mode: params.identity.mode,
184
182
  taskId: params.identity.mode === 'task-bound' ? params.identity.taskId : null,
@@ -189,16 +187,16 @@ export function materializeSandboxControl(params) {
189
187
  processingDir,
190
188
  runtimeDir
191
189
  };
192
- fs.writeFileSync(manifestPath, `${JSON.stringify(manifest)}\n`, { mode: 0o600 });
193
- return { root, channelDir, statusDir, runtimeDir, manifestPath, token, generation };
190
+ return { root, channelDir, statusDir, runtimeDir, manifestPath, manifestDraft, token, generation };
194
191
  }
195
192
  export function finalizeSandboxControlManifest(setup, identity) {
196
193
  if (!identity.engine || !identity.id)
197
194
  throw new Error('SANDBOX_CONTROL_CONTAINER_ID_INVALID');
198
- const manifest = JSON.parse(fs.readFileSync(setup.manifestPath, 'utf8'));
199
- manifest.version = 5;
200
- manifest.engine = identity.engine;
201
- manifest.containerIdentity = { id: identity.id, labels: { ...identity.labels } };
195
+ const manifest = {
196
+ ...setup.manifestDraft,
197
+ engine: identity.engine,
198
+ containerIdentity: { id: identity.id, labels: { ...identity.labels } }
199
+ };
202
200
  const temporary = `${setup.manifestPath}.${process.pid}.${randomBytes(8).toString('hex')}.tmp`;
203
201
  try {
204
202
  fs.writeFileSync(temporary, `${JSON.stringify(manifest)}\n`, { mode: 0o600, flag: 'wx' });
@@ -207,5 +205,6 @@ export function finalizeSandboxControlManifest(setup, identity) {
207
205
  finally {
208
206
  fs.rmSync(temporary, { force: true });
209
207
  }
208
+ return manifest;
210
209
  }
211
210
  //# sourceMappingURL=workspace-view.js.map
@@ -0,0 +1,278 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { err, info, ok } from './log.js';
5
+ import { needsShell, resolveCommandFromAbsolutePath } from './run/host.js';
6
+ function canonicalPath(target) {
7
+ try {
8
+ return fs.realpathSync.native(target);
9
+ }
10
+ catch {
11
+ return null;
12
+ }
13
+ }
14
+ function comparable(target, platform) {
15
+ const resolved = path.resolve(target).replaceAll('\\', '/');
16
+ return platform === 'win32' ? resolved.toLowerCase() : resolved;
17
+ }
18
+ function samePath(left, right, platform) {
19
+ return comparable(left, platform) === comparable(right, platform);
20
+ }
21
+ function isWithin(root, target, platform) {
22
+ const normalizedRoot = comparable(root, platform).replace(/\/$/, '');
23
+ const normalizedTarget = comparable(target, platform).replace(/\/$/, '');
24
+ return normalizedTarget === normalizedRoot
25
+ || normalizedTarget.startsWith(`${normalizedRoot}/`);
26
+ }
27
+ function packageInfoFromRoot(root) {
28
+ try {
29
+ const packageJson = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
30
+ return typeof packageJson.name === 'string'
31
+ ? { root, name: packageJson.name }
32
+ : null;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ function findPackageInfo(entry, platform) {
39
+ const canonicalEntry = canonicalPath(entry);
40
+ if (!canonicalEntry)
41
+ return null;
42
+ let current = path.dirname(canonicalEntry);
43
+ while (true) {
44
+ const canonicalRoot = canonicalPath(current);
45
+ const info = canonicalRoot ? packageInfoFromRoot(canonicalRoot) : null;
46
+ if (info && isWithin(info.root, canonicalEntry, platform))
47
+ return info;
48
+ const parent = path.dirname(current);
49
+ if (parent === current)
50
+ return null;
51
+ current = parent;
52
+ }
53
+ }
54
+ function packageInfoFromCommand(commandPath, platform) {
55
+ const direct = findPackageInfo(commandPath, platform);
56
+ if (direct)
57
+ return direct;
58
+ if (!/\.(?:cmd|bat)$/i.test(commandPath))
59
+ return null;
60
+ const globalPackageRoot = canonicalPath(path.join(path.dirname(commandPath), 'node_modules', '@fitlab-ai', 'agent-infra'));
61
+ return globalPackageRoot ? packageInfoFromRoot(globalPackageRoot) : null;
62
+ }
63
+ function visibleAliasError(packageRoot, platform, env) {
64
+ for (const alias of ['ai', 'agent-infra']) {
65
+ const absolute = resolveCommandFromAbsolutePath(alias, platform, env);
66
+ if (!absolute)
67
+ continue;
68
+ if (!canonicalPath(absolute))
69
+ continue;
70
+ const info = packageInfoFromCommand(absolute, platform);
71
+ if (info && !samePath(info.root, packageRoot, platform)) {
72
+ return `PATH shadowing detected: ${alias} resolves to ${info.root}, not ${packageRoot}.`;
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+ function resolveManager(name, expectedBasenames, platform, env) {
78
+ const absolute = resolveCommandFromAbsolutePath(name, platform, env);
79
+ if (!absolute) {
80
+ return { error: `${name} manager was not found on PATH.` };
81
+ }
82
+ let stat;
83
+ try {
84
+ stat = fs.statSync(absolute);
85
+ }
86
+ catch {
87
+ return { error: `Cannot inspect manager executable: ${absolute}.` };
88
+ }
89
+ if (!stat.isFile())
90
+ return { error: `Manager executable is not a regular file: ${absolute}.` };
91
+ if (!expectedBasenames.includes(path.basename(absolute).toLowerCase())) {
92
+ return { error: `Unexpected manager executable: ${absolute}.` };
93
+ }
94
+ const canonical = canonicalPath(absolute);
95
+ return canonical ? { path: canonical } : null;
96
+ }
97
+ function defaultRun(command, platform) {
98
+ const [file, ...args] = command;
99
+ if (!file)
100
+ return { status: null, error: new Error('run: missing command') };
101
+ const result = spawnSync(file, args, {
102
+ encoding: 'utf8',
103
+ shell: needsShell(file, platform),
104
+ stdio: ['ignore', 'pipe', 'pipe']
105
+ });
106
+ return {
107
+ status: result.status,
108
+ signal: result.signal,
109
+ stdout: result.stdout || '',
110
+ stderr: result.stderr || '',
111
+ error: result.error
112
+ };
113
+ }
114
+ function runCommand(command, options, platform) {
115
+ return options.run ? options.run(command) : defaultRun(command, platform);
116
+ }
117
+ function probe(command, options, platform, label) {
118
+ const result = runCommand(command, options, platform);
119
+ if (result.error)
120
+ return { error: `${label} failed: ${result.error.message}` };
121
+ if (result.signal)
122
+ return { error: `${label} terminated by ${result.signal}.` };
123
+ if (result.status !== 0) {
124
+ const detail = result.stderr?.trim();
125
+ return { error: `${label} exited with ${result.status ?? 1}${detail ? `: ${detail}` : '.'}` };
126
+ }
127
+ const output = result.stdout?.trim() || '';
128
+ return output ? output : { error: `${label} returned no path.` };
129
+ }
130
+ function npmSource(packageInfo, options, platform, env) {
131
+ const manager = resolveManager('npm', platform === 'win32' ? ['npm.cmd', 'npm.bat'] : ['npm'], platform, env);
132
+ if (!manager)
133
+ return null;
134
+ if ('error' in manager)
135
+ return manager;
136
+ const prefixOutput = probe([manager.path, 'prefix', '--global'], options, platform, 'npm prefix --global');
137
+ if (typeof prefixOutput !== 'string')
138
+ return prefixOutput;
139
+ const rootOutput = probe([manager.path, 'root', '--global'], options, platform, 'npm root --global');
140
+ if (typeof rootOutput !== 'string')
141
+ return rootOutput;
142
+ const prefix = canonicalPath(prefixOutput);
143
+ const globalRoot = canonicalPath(rootOutput);
144
+ if (!prefix || !globalRoot)
145
+ return { error: 'npm global prefix or root is not an existing directory.' };
146
+ if (!isWithin(prefix, globalRoot, platform)) {
147
+ return { error: `npm global root ${globalRoot} is outside prefix ${prefix}.` };
148
+ }
149
+ const expectedPackageRoot = canonicalPath(path.join(globalRoot, '@fitlab-ai', 'agent-infra'));
150
+ if (!expectedPackageRoot || !samePath(expectedPackageRoot, packageInfo.root, platform)) {
151
+ return { error: `Current CLI package is not owned by npm global root ${globalRoot}.` };
152
+ }
153
+ if (packageInfo.name !== '@fitlab-ai/agent-infra') {
154
+ return { error: `Unexpected package name at ${packageInfo.root}: ${packageInfo.name}.` };
155
+ }
156
+ if (platform !== 'win32' && !isWithin(prefix, manager.path, platform)) {
157
+ return { error: `npm manager ${manager.path} is outside global prefix ${prefix}.` };
158
+ }
159
+ return {
160
+ kind: 'npm',
161
+ managerPath: manager.path,
162
+ packageRoot: packageInfo.root,
163
+ updateArgs: ['update', '--global', '@fitlab-ai/agent-infra']
164
+ };
165
+ }
166
+ function brewSource(packageInfo, options, platform, env) {
167
+ const manager = resolveManager('brew', ['brew', 'brew.exe', 'brew.cmd'], platform, env);
168
+ if (!manager)
169
+ return null;
170
+ if ('error' in manager)
171
+ return manager;
172
+ const homebrewOutput = probe([manager.path, '--prefix'], options, platform, 'brew --prefix');
173
+ if (typeof homebrewOutput !== 'string')
174
+ return homebrewOutput;
175
+ const formulaOutput = probe([manager.path, '--prefix', 'agent-infra'], options, platform, 'brew --prefix agent-infra');
176
+ if (typeof formulaOutput !== 'string')
177
+ return formulaOutput;
178
+ const homebrewRoot = canonicalPath(homebrewOutput);
179
+ const formulaRoot = canonicalPath(formulaOutput);
180
+ if (!homebrewRoot || !formulaRoot)
181
+ return { error: 'Homebrew prefix is not an existing directory.' };
182
+ if (!isWithin(homebrewRoot, manager.path, platform)) {
183
+ return { error: `brew manager ${manager.path} is outside Homebrew prefix ${homebrewRoot}.` };
184
+ }
185
+ if (!isWithin(homebrewRoot, formulaRoot, platform)) {
186
+ return { error: `agent-infra formula prefix ${formulaRoot} is outside Homebrew prefix ${homebrewRoot}.` };
187
+ }
188
+ if (!isWithin(formulaRoot, packageInfo.root, platform)) {
189
+ return { error: `Current CLI package is outside agent-infra formula prefix ${formulaRoot}.` };
190
+ }
191
+ if (packageInfo.name !== '@fitlab-ai/agent-infra') {
192
+ return { error: `Unexpected package name at ${packageInfo.root}: ${packageInfo.name}.` };
193
+ }
194
+ return {
195
+ kind: 'brew',
196
+ managerPath: manager.path,
197
+ packageRoot: packageInfo.root,
198
+ updateArgs: ['upgrade', 'agent-infra']
199
+ };
200
+ }
201
+ export function detectUpdateSource(options = {}) {
202
+ const platform = options.platform ?? process.platform;
203
+ const env = options.env ?? process.env;
204
+ const entry = options.argv?.[1] ?? process.argv[1];
205
+ if (!entry)
206
+ return { source: null, error: 'Cannot determine the running CLI entry.' };
207
+ const packageInfo = findPackageInfo(entry, platform);
208
+ if (!packageInfo || packageInfo.name !== '@fitlab-ai/agent-infra') {
209
+ return { source: null, error: 'Running CLI is not a persistent @fitlab-ai/agent-infra package installation.' };
210
+ }
211
+ const aliasError = visibleAliasError(packageInfo.root, platform, env);
212
+ if (aliasError)
213
+ return { source: null, error: aliasError };
214
+ const candidates = [];
215
+ const errors = [];
216
+ for (const candidate of [
217
+ npmSource(packageInfo, options, platform, env),
218
+ brewSource(packageInfo, options, platform, env)
219
+ ]) {
220
+ if (!candidate)
221
+ continue;
222
+ if ('error' in candidate)
223
+ errors.push(candidate.error);
224
+ else
225
+ candidates.push(candidate);
226
+ }
227
+ if (candidates.length === 1) {
228
+ const [source] = candidates;
229
+ if (source)
230
+ return { source };
231
+ }
232
+ if (candidates.length > 1)
233
+ return { source: null, error: 'Multiple package managers claim the running CLI; refusing to choose.' };
234
+ return {
235
+ source: null,
236
+ error: errors.length > 0
237
+ ? errors.join(' ')
238
+ : 'No supported persistent npm or Homebrew installation owns the running CLI.'
239
+ };
240
+ }
241
+ function managerStable(source, platform) {
242
+ const current = canonicalPath(source.managerPath);
243
+ return current !== null && samePath(current, source.managerPath, platform);
244
+ }
245
+ export async function cmdUpdate(options = {}) {
246
+ const platform = options.platform ?? process.platform;
247
+ const detected = detectUpdateSource(options);
248
+ if (!detected.source) {
249
+ err(`Cannot update agent-infra CLI: ${detected.error ?? 'unknown source'}`);
250
+ err('Install persistently with "npm install -g @fitlab-ai/agent-infra" or "brew install fitlab-ai/tap/agent-infra".');
251
+ return 1;
252
+ }
253
+ const source = detected.source;
254
+ if (!managerStable(source, platform)) {
255
+ err(`Cannot update agent-infra CLI: manager path changed: ${source.managerPath}.`);
256
+ return 1;
257
+ }
258
+ info(`Updating agent-infra CLI via ${source.kind}.`);
259
+ const result = runCommand([source.managerPath, ...source.updateArgs], options, platform);
260
+ if (result.error) {
261
+ err(`agent-infra CLI update failed: ${result.error.message}`);
262
+ return 1;
263
+ }
264
+ if (result.signal) {
265
+ err(`agent-infra CLI update terminated by ${result.signal}.`);
266
+ return 1;
267
+ }
268
+ if (result.status !== 0) {
269
+ err(`agent-infra CLI update failed with exit code ${result.status ?? 1}.`);
270
+ const detail = result.stderr?.trim();
271
+ if (detail)
272
+ err(detail);
273
+ return result.status && result.status > 0 ? result.status : 1;
274
+ }
275
+ ok('agent-infra CLI updated successfully!');
276
+ return 0;
277
+ }
278
+ //# sourceMappingURL=self-update.js.map
@@ -20,16 +20,16 @@ export function commandHelp() {
20
20
  '/sandbox ls',
21
21
  '/sandbox show {ref}',
22
22
  '/sandbox vm status',
23
- '/task decisions [--task {ref}] [--item {selector}]',
24
- '/task log [--task {ref}]',
23
+ '/task decisions [--task {ref} | -t {ref}] [--item {selector} | -i {selector}]',
24
+ '/task log [--task {ref} | -t {ref}]',
25
25
  '/task ls',
26
- '/task show [--task {ref}]',
27
- '/task status [--task {ref}]',
26
+ '/task show [--task {ref} | -t {ref}]',
27
+ '/task status [--task {ref} | -t {ref}]',
28
28
  'Write:',
29
29
  '/sandbox create {ref}',
30
30
  '/sandbox start {ref}',
31
31
  'Exec:',
32
- '/decide [--task {ref}] --item {ordinal|ledger-id} [--needs-implementation true|false] {decision}',
32
+ '/decide [--task {ref} | -t {ref}] (--item {ordinal|ledger-id} | -i {ordinal|ledger-id}) [--needs-implementation true|false] {decision}',
33
33
  '/run create-task {description}',
34
34
  '/run {skill} {task-ref}'
35
35
  ].join('\n');
@@ -84,5 +84,8 @@ function pairEntries(entries) {
84
84
  }
85
85
  return rows;
86
86
  }
87
- export { activityAttempt, appendActivityEntry, commitAttemptStartedNote, locateActivityLog, pairEntries, parseActivityLog, parseCommitAttemptStarted };
87
+ function startedBackedRows(rows) {
88
+ return rows.filter((row) => row.started !== '');
89
+ }
90
+ export { activityAttempt, appendActivityEntry, commitAttemptStartedNote, locateActivityLog, pairEntries, parseActivityLog, parseCommitAttemptStarted, startedBackedRows };
88
91
  //# sourceMappingURL=activity-log.js.map
@@ -305,7 +305,7 @@ function resolveCodeContext(inventory, options) {
305
305
  }
306
306
  const verdict = parseVerdict(reviewPlan.latest.path);
307
307
  if (!verdict.ok)
308
- return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', verdict.message, reviewPlan.latest.name);
308
+ return contextFailure(inventory, 'ARTIFACT_VERDICT_INVALID', `${verdict.code}: ${verdict.message}`, reviewPlan.latest.name);
309
309
  if (verdict.verdict !== 'Approved') {
310
310
  return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', `latest ${reviewPlan.latest.name} is not approved`, reviewPlan.latest.name);
311
311
  }
@@ -320,6 +320,8 @@ function resolveCodeContext(inventory, options) {
320
320
  }
321
321
  if (reviewPlan.latest && reviewPlan.reviewedInput?.name === plan.latest.name) {
322
322
  const verdict = parseVerdict(reviewPlan.latest.path);
323
+ if (!verdict.ok)
324
+ return contextFailure(inventory, 'ARTIFACT_VERDICT_INVALID', `${verdict.code}: ${verdict.message}`, reviewPlan.latest.name);
323
325
  const reviewedPlanSha256 = sha256File(reviewPlan.reviewedInput.path);
324
326
  if (verdict.ok && verdict.verdict === 'Approved' && (codePlanInput.input.name !== plan.latest.name || codePlanInput.inputSha256 !== reviewedPlanSha256)) {
325
327
  return withCodeMode(inventory, inputs, 'ready', 'init', codeMax, reviewMax, verdict.verdict, reviewPlan.latest.name, `Latest ${reviewPlan.latest.name} approves plan content not captured by the latest code input receipt. Entering replan-driven init.`);
@@ -334,7 +336,7 @@ function resolveCodeContext(inventory, options) {
334
336
  return contextFailure(inventory, 'ARTIFACT_INPUT_MISSING', 'latest review-code artifact is required');
335
337
  const verdict = parseVerdict(review.path);
336
338
  if (!verdict.ok)
337
- return contextFailure(inventory, 'ARTIFACT_REFERENCE_INVALID', verdict.message);
339
+ return contextFailure(inventory, 'ARTIFACT_VERDICT_INVALID', `${verdict.code}: ${verdict.message}`, review.name);
338
340
  if (verdict.verdict === 'Approved') {
339
341
  const decision = resolveDecisionImplementationInput(inventory, review);
340
342
  if ('error' in decision)
@@ -77,7 +77,7 @@ async function prepareCodexOrchestrationDelegation(taskRef, input, options = {})
77
77
  return bridgeFailure('ORCHESTRATION_CODEX_CAPABILITY_REQUIRED', 'Codex prepare requires a current-session capability token');
78
78
  }
79
79
  const buildIdentity = options.buildIdentity ?? computeLifecycleBuildIdentity(repoRoot);
80
- const brokerController = brokerControllerBinding();
80
+ const brokerController = options.controllerBinding ?? brokerControllerBinding();
81
81
  const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
82
82
  const contextVerification = contextPath
83
83
  ? (brokerController
@@ -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;