@fitlab-ai/agent-infra 0.9.12 → 0.9.13

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 (239) hide show
  1. package/README.md +11 -11
  2. package/README.zh-CN.md +11 -11
  3. package/dist/bin/internal-cli.js +24 -19
  4. package/dist/lib/agent-clients/next-steps.js +6 -1
  5. package/dist/lib/decide.js +3 -3
  6. package/dist/lib/internal/platform-checks.js +3 -3
  7. package/dist/lib/internal/platform-comment.js +9 -9
  8. package/dist/lib/internal/platform-context.js +2 -2
  9. package/dist/lib/internal/platform-issue.js +8 -9
  10. package/dist/lib/internal/platform-pr-review.js +10 -10
  11. package/dist/lib/internal/platform-pr.js +63 -24
  12. package/dist/lib/internal/platform-release-notes.js +3 -3
  13. package/dist/lib/internal/pr-review-grade.js +11 -9
  14. package/dist/lib/internal/release-workflow.js +4 -4
  15. package/dist/lib/internal/sandbox-control.js +30 -4
  16. package/dist/lib/internal/task-activity.js +3 -3
  17. package/dist/lib/internal/task-artifact.js +76 -24
  18. package/dist/lib/internal/task-create.js +2 -2
  19. package/dist/lib/internal/task-event.js +6 -3
  20. package/dist/lib/internal/task-finalization.js +2 -2
  21. package/dist/lib/internal/task-invalidation.js +60 -0
  22. package/dist/lib/internal/task-ledger.js +9 -6
  23. package/dist/lib/internal/task-lifecycle.js +2 -2
  24. package/dist/lib/internal/task-override.js +4 -4
  25. package/dist/lib/internal/task-review.js +3 -3
  26. package/dist/lib/internal/task-verify.js +6 -6
  27. package/dist/lib/internal/task-warning.js +3 -3
  28. package/dist/lib/platform/adapters.js +1 -3
  29. package/dist/lib/platform/change-request-git-evidence.js +27 -7
  30. package/dist/lib/platform/completion-backfill.js +6 -5
  31. package/dist/lib/platform/context.js +70 -130
  32. package/dist/lib/platform/github-client.js +1 -1
  33. package/dist/lib/platform/github-provider.js +903 -0
  34. package/dist/lib/platform/in-label-sync.js +143 -0
  35. package/dist/lib/platform/issue-comments.js +94 -41
  36. package/dist/lib/platform/issues.js +335 -189
  37. package/dist/lib/platform/metadata-labels.js +6 -2
  38. package/dist/lib/platform/none-provider.js +28 -0
  39. package/dist/lib/platform/pr-change-report.js +551 -0
  40. package/dist/lib/platform/pr-checks.js +119 -104
  41. package/dist/lib/platform/pr-review.js +88 -72
  42. package/dist/lib/platform/pr-summary.js +520 -50
  43. package/dist/lib/platform/provider-bridge.js +45 -0
  44. package/dist/lib/platform/provider-contract.d.ts +487 -0
  45. package/dist/lib/platform/provider-contract.js +95 -0
  46. package/dist/lib/platform/provider-loader.js +251 -0
  47. package/dist/lib/platform/provider-validation.js +504 -0
  48. package/dist/lib/platform/pull-request-metadata.js +8 -6
  49. package/dist/lib/platform/pull-requests.js +783 -537
  50. package/dist/lib/platform/release-notes.js +78 -55
  51. package/dist/lib/platform/releases.js +79 -50
  52. package/dist/lib/platform/resource-identity.d.ts +26 -0
  53. package/dist/lib/platform/resource-identity.js +92 -0
  54. package/dist/lib/platform/task-identities.js +31 -0
  55. package/dist/lib/platform/verification-required.js +11 -12
  56. package/dist/lib/platform/verification-sync.js +112 -238
  57. package/dist/lib/pr-review/evidence-grading.js +19 -6
  58. package/dist/lib/run/index.js +63 -23
  59. package/dist/lib/sandbox/control/client.js +96 -15
  60. package/dist/lib/sandbox/control/executor.js +3 -3
  61. package/dist/lib/sandbox/control/protocol.js +77 -0
  62. package/dist/lib/sandbox/control/server.js +398 -25
  63. package/dist/lib/sandbox/control/state.js +204 -1
  64. package/dist/lib/server/protocol.js +38 -1
  65. package/dist/lib/task/activity-log.js +8 -1
  66. package/dist/lib/task/artifact-lifecycle.js +33 -5
  67. package/dist/lib/task/capabilities.js +239 -0
  68. package/dist/lib/task/commands/status.js +32 -0
  69. package/dist/lib/task/commit-operation.js +12 -1
  70. package/dist/lib/task/control-authority.js +8 -5
  71. package/dist/lib/task/create-service.js +8 -8
  72. package/dist/lib/task/current-contract.js +5 -1
  73. package/dist/lib/task/decision-details.js +1 -1
  74. package/dist/lib/task/events.js +297 -17
  75. package/dist/lib/task/finalization.js +37 -13
  76. package/dist/lib/task/human-override.js +58 -36
  77. package/dist/lib/task/invalidation-command.js +86 -0
  78. package/dist/lib/task/invalidation.js +260 -0
  79. package/dist/lib/task/ledger-intents.js +37 -0
  80. package/dist/lib/task/local-artifact-finalization.js +374 -0
  81. package/dist/lib/task/orchestration.js +49 -93
  82. package/dist/lib/task/pr-delivery-fact.js +102 -101
  83. package/dist/lib/task/review-fingerprint.js +24 -2
  84. package/dist/lib/task/rework-intent.js +138 -0
  85. package/dist/lib/task/skill-scope.js +23 -0
  86. package/dist/lib/task/task-execution-lock.js +27 -17
  87. package/dist/lib/task/verification-engine.js +43 -16
  88. package/dist/lib/task/verification.js +3 -3
  89. package/dist/lib/task/workflow-warning-intents.js +1 -1
  90. package/dist/lib/task/write.js +11 -0
  91. package/dist/lib/version.js +11 -1
  92. package/dist/lifecycle-build-manifest.json +3 -3
  93. package/lib/agent-clients/next-steps.ts +6 -1
  94. package/lib/decide.ts +3 -3
  95. package/lib/init.ts +1 -1
  96. package/lib/internal/platform-checks.ts +3 -3
  97. package/lib/internal/platform-comment.ts +8 -8
  98. package/lib/internal/platform-context.ts +2 -2
  99. package/lib/internal/platform-issue.ts +7 -8
  100. package/lib/internal/platform-pr-review.ts +9 -9
  101. package/lib/internal/platform-pr.ts +47 -22
  102. package/lib/internal/platform-release-notes.ts +3 -3
  103. package/lib/internal/pr-review-grade.ts +10 -8
  104. package/lib/internal/release-workflow.ts +4 -4
  105. package/lib/internal/sandbox-control.ts +27 -3
  106. package/lib/internal/task-activity.ts +3 -3
  107. package/lib/internal/task-artifact.ts +65 -22
  108. package/lib/internal/task-create.ts +2 -2
  109. package/lib/internal/task-event.ts +6 -3
  110. package/lib/internal/task-finalization.ts +3 -3
  111. package/lib/internal/task-invalidation.ts +39 -0
  112. package/lib/internal/task-ledger.ts +11 -8
  113. package/lib/internal/task-lifecycle.ts +2 -2
  114. package/lib/internal/task-override.ts +6 -6
  115. package/lib/internal/task-review.ts +3 -3
  116. package/lib/internal/task-verify.ts +6 -6
  117. package/lib/internal/task-warning.ts +3 -3
  118. package/lib/platform/adapters.ts +3 -2
  119. package/lib/platform/change-request-git-evidence.ts +36 -9
  120. package/lib/platform/completion-backfill.ts +9 -8
  121. package/lib/platform/context.ts +97 -134
  122. package/lib/platform/github-client.ts +2 -2
  123. package/lib/platform/github-provider.ts +910 -0
  124. package/lib/platform/in-label-sync.ts +208 -0
  125. package/lib/platform/issue-comments.ts +97 -47
  126. package/lib/platform/issues.ts +344 -174
  127. package/lib/platform/metadata-labels.ts +5 -2
  128. package/lib/platform/none-provider.ts +35 -0
  129. package/lib/platform/pr-change-report.ts +645 -0
  130. package/lib/platform/pr-checks.ts +126 -106
  131. package/lib/platform/pr-review.ts +88 -85
  132. package/lib/platform/pr-summary.ts +560 -53
  133. package/lib/platform/provider-bridge.ts +82 -0
  134. package/lib/platform/provider-contract.ts +536 -0
  135. package/lib/platform/provider-loader.ts +307 -0
  136. package/lib/platform/provider-validation.ts +529 -0
  137. package/lib/platform/pull-request-metadata.ts +10 -7
  138. package/lib/platform/pull-requests.ts +826 -543
  139. package/lib/platform/release-notes.ts +76 -59
  140. package/lib/platform/releases.ts +77 -43
  141. package/lib/platform/resource-identity.ts +121 -0
  142. package/lib/platform/task-identities.ts +40 -0
  143. package/lib/platform/types.ts +4 -2
  144. package/lib/platform/verification-required.ts +11 -13
  145. package/lib/platform/verification-sync.ts +112 -292
  146. package/lib/pr-review/evidence-grading.ts +25 -8
  147. package/lib/run/index.ts +57 -22
  148. package/lib/sandbox/control/client.ts +105 -15
  149. package/lib/sandbox/control/executor.ts +4 -4
  150. package/lib/sandbox/control/protocol.ts +113 -0
  151. package/lib/sandbox/control/server.ts +431 -23
  152. package/lib/sandbox/control/state.ts +251 -1
  153. package/lib/server/protocol.ts +36 -1
  154. package/lib/task/activity-log.ts +8 -0
  155. package/lib/task/artifact-lifecycle.ts +32 -6
  156. package/lib/task/capabilities.ts +262 -0
  157. package/lib/task/commands/status.ts +38 -0
  158. package/lib/task/commit-operation.ts +12 -1
  159. package/lib/task/control-authority.ts +11 -8
  160. package/lib/task/create-service.ts +8 -8
  161. package/lib/task/current-contract.ts +6 -1
  162. package/lib/task/decision-details.ts +6 -2
  163. package/lib/task/events.ts +296 -16
  164. package/lib/task/finalization.ts +50 -14
  165. package/lib/task/human-override.ts +70 -46
  166. package/lib/task/invalidation-command.ts +86 -0
  167. package/lib/task/invalidation.ts +332 -0
  168. package/lib/task/ledger-intents.ts +35 -1
  169. package/lib/task/local-artifact-finalization.ts +563 -0
  170. package/lib/task/orchestration.ts +52 -85
  171. package/lib/task/pr-delivery-fact.ts +131 -148
  172. package/lib/task/review-fingerprint.ts +23 -2
  173. package/lib/task/rework-intent.ts +165 -0
  174. package/lib/task/skill-scope.ts +24 -0
  175. package/lib/task/task-execution-lock.ts +23 -14
  176. package/lib/task/verification-engine.ts +52 -17
  177. package/lib/task/verification.ts +4 -4
  178. package/lib/task/workflow-warning-intents.ts +1 -1
  179. package/lib/task/write.ts +19 -0
  180. package/lib/update.ts +1 -1
  181. package/lib/version.ts +15 -1
  182. package/package.json +7 -1
  183. package/templates/.agents/rules/README.en.md +1 -1
  184. package/templates/.agents/rules/README.zh-CN.md +1 -1
  185. package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
  186. package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
  187. package/templates/.agents/rules/issue-sync.en.md +2 -0
  188. package/templates/.agents/rules/issue-sync.zh-CN.md +2 -0
  189. package/templates/.agents/rules/local-artifact-repair.en.md +9 -2
  190. package/templates/.agents/rules/local-artifact-repair.zh-CN.md +9 -2
  191. package/templates/.agents/rules/pr-sync.en.md +10 -4
  192. package/templates/.agents/rules/pr-sync.zh-CN.md +17 -4
  193. package/templates/.agents/rules/task-short-id.en.md +1 -4
  194. package/templates/.agents/rules/task-short-id.zh-CN.md +1 -3
  195. package/templates/.agents/skills/analyze-task/SKILL.en.md +13 -3
  196. package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +10 -3
  197. package/templates/.agents/skills/check-task/SKILL.en.md +16 -37
  198. package/templates/.agents/skills/check-task/SKILL.zh-CN.md +16 -37
  199. package/templates/.agents/skills/code-task/SKILL.en.md +27 -8
  200. package/templates/.agents/skills/code-task/SKILL.zh-CN.md +29 -10
  201. package/templates/.agents/skills/code-task/config/verify.en.json +1 -0
  202. package/templates/.agents/skills/code-task/config/verify.zh-CN.json +1 -0
  203. package/templates/.agents/skills/commit/reference/issue-metadata-sync.en.md +2 -0
  204. package/templates/.agents/skills/commit/reference/issue-metadata-sync.zh-CN.md +2 -0
  205. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +3 -3
  206. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +3 -3
  207. package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -3
  208. package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -3
  209. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.en.md +4 -3
  210. package/templates/.agents/skills/complete-manual-validation/reference/summary-update.zh-CN.md +4 -3
  211. package/templates/.agents/skills/complete-task/SKILL.en.md +21 -3
  212. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +20 -3
  213. package/templates/.agents/skills/create-pr/SKILL.en.md +7 -6
  214. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +7 -7
  215. package/templates/.agents/skills/create-pr/config/verify.json +1 -0
  216. package/templates/.agents/skills/create-pr/reference/change-report.en.md +16 -4
  217. package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +16 -4
  218. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +5 -3
  219. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +5 -3
  220. package/templates/.agents/skills/create-pr/reference/pr-body-template.en.md +1 -1
  221. package/templates/.agents/skills/create-pr/reference/pr-body-template.zh-CN.md +1 -1
  222. package/templates/.agents/skills/create-pr/scripts/change-report.mjs +3 -0
  223. package/templates/.agents/skills/plan-task/SKILL.en.md +13 -3
  224. package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +10 -3
  225. package/templates/.agents/skills/review-analysis/SKILL.en.md +3 -3
  226. package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +3 -3
  227. package/templates/.agents/skills/review-code/SKILL.en.md +4 -4
  228. package/templates/.agents/skills/review-code/SKILL.zh-CN.md +4 -4
  229. package/templates/.agents/skills/review-plan/SKILL.en.md +3 -3
  230. package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +3 -3
  231. package/templates/.agents/skills/run-manual-validation/SKILL.en.md +4 -2
  232. package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +4 -2
  233. package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
  234. package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
  235. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +6 -0
  236. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +6 -0
  237. package/templates/.agents/templates/task.en.md +18 -1
  238. package/templates/.agents/templates/task.zh-CN.md +18 -1
  239. package/templates/.github/workflows/pr-label.yml +7 -26
@@ -1,19 +1,21 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
4
- import { bindPlatformPullRequest, createPlatformPullRequest, inspectPlatformPullRequest, resolveExternalPullRequest, skipPlatformPullRequestFact, syncPlatformPullRequest } from '../platform/pull-requests.js';
5
- import { summaryContext, syncPullRequestSummary } from '../platform/pr-summary.js';
4
+ import { bindPlatformPullRequest, createPlatformPullRequest, inspectPlatformPullRequest, resolveExternalPullRequest, skipPlatformPullRequestFact, syncPlatformPullRequest, syncPlatformPullRequestInLabels } from '../platform/pull-requests.js';
5
+ import { reportWrite, summaryContext, syncPullRequestSummary } from '../platform/pr-summary.js';
6
6
  const USAGE = `Usage: agent-infra-internal platform-pr inspect <task-ref> [--cwd <path>]
7
- agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <N>] [--dry-run] [--cwd <path>]
7
+ agent-infra-internal platform-pr resolve-external <task-ref> --agent <agent> [--pr <token>] [--dry-run] [--cwd <path>]
8
8
  agent-infra-internal platform-pr create <task-ref> --agent <agent> --base <branch> --head <branch> --title-file <path|-> --body-file <path|-> [--draft] [--dry-run] [--cwd <path>]
9
- agent-infra-internal platform-pr bind <task-ref> --pr <N> --agent <agent> [--dry-run] [--cwd <path>]
9
+ agent-infra-internal platform-pr bind <task-ref> --pr <token> --agent <agent> [--dry-run] [--cwd <path>]
10
10
  agent-infra-internal platform-pr skip <task-ref> --agent <agent> [--dry-run] [--cwd <path>]
11
11
  agent-infra-internal platform-pr sync <task-ref> --agent <agent> [--metadata] [--closing-issue] --result <pr_created|pr_reused|no_op> [--dry-run] [--cwd <path>]
12
+ agent-infra-internal platform-pr sync-in-labels --pr <N> [--dry-run] [--cwd <path>]
12
13
  agent-infra-internal platform-pr summary-context <task-ref> [--cwd <path>]
13
- agent-infra-internal platform-pr summary-sync <task-ref> --agent <agent> --body-file <path|-> --result <pr_created|pr_reused|no_op> [--dry-run] [--cwd <path>]
14
+ agent-infra-internal platform-pr change-report <task-ref> --agent <agent> --mechanical-file <path> --precheck-file <path> [--dry-run] [--cwd <path>]
15
+ agent-infra-internal platform-pr summary-sync <task-ref> --agent <agent> --body-file <path|-> --change-report-file <path> --result <pr_created|pr_reused|no_op> [--strict] [--dry-run] [--cwd <path>]
14
16
  `;
15
- const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue']);
16
- const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--pr', '--result']);
17
+ const BOOLEAN_FLAGS = new Set(['--draft', '--dry-run', '--metadata', '--closing-issue', '--strict']);
18
+ const VALUE_FLAGS = new Set(['--cwd', '--agent', '--base', '--head', '--title-file', '--body-file', '--change-report-file', '--mechanical-file', '--precheck-file', '--pr', '--result']);
17
19
  function key(flag) {
18
20
  return flag.slice(2).replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
19
21
  }
@@ -53,16 +55,37 @@ function parse(args, start) {
53
55
  function readFile(value, cwd) {
54
56
  return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
55
57
  }
56
- function platformPr(args = []) {
58
+ async function platformPr(args = []) {
57
59
  if (args[0] === '--help' || args[0] === '-h') {
58
60
  process.stdout.write(USAGE);
59
61
  return;
60
62
  }
61
63
  const operation = args[0];
62
- if (!operation || !['inspect', 'resolve-external', 'create', 'bind', 'skip', 'sync', 'summary-context', 'summary-sync'].includes(operation)) {
64
+ if (!operation || !['inspect', 'resolve-external', 'create', 'bind', 'skip', 'sync', 'sync-in-labels', 'summary-context', 'change-report', 'summary-sync'].includes(operation)) {
63
65
  fail('a valid operation is required');
64
66
  return;
65
67
  }
68
+ if (operation === 'sync-in-labels') {
69
+ const parsed = parse(args, 1);
70
+ if (parsed.error) {
71
+ fail(parsed.error);
72
+ return;
73
+ }
74
+ const values = parsed.values;
75
+ const unexpected = Object.keys(values).find((name) => !['cwd', 'pr', 'dryRun'].includes(name));
76
+ if (unexpected) {
77
+ fail(`sync-in-labels does not accept --${unexpected}`);
78
+ return;
79
+ }
80
+ const pr = Number(values.pr);
81
+ if (!Number.isInteger(pr) || pr <= 0) {
82
+ fail('sync-in-labels requires a positive --pr');
83
+ return;
84
+ }
85
+ const cwd = path.resolve(typeof values.cwd === 'string' ? values.cwd : process.cwd());
86
+ finish(await syncPlatformPullRequestInLabels(pr, { cwd, dryRun: values.dryRun === true }));
87
+ return;
88
+ }
66
89
  const taskRef = args[1];
67
90
  if (!taskRef || taskRef.startsWith('--')) {
68
91
  fail(`${operation} requires a task ref`);
@@ -82,8 +105,10 @@ function platformPr(args = []) {
82
105
  bind: ['cwd', 'agent', 'pr', 'dryRun'],
83
106
  skip: ['cwd', 'agent', 'dryRun'],
84
107
  sync: ['cwd', 'agent', 'metadata', 'closingIssue', 'result', 'dryRun'],
108
+ 'sync-in-labels': ['cwd', 'pr', 'dryRun'],
85
109
  'summary-context': ['cwd'],
86
- 'summary-sync': ['cwd', 'agent', 'bodyFile', 'result', 'dryRun']
110
+ 'change-report': ['cwd', 'agent', 'mechanicalFile', 'precheckFile', 'dryRun'],
111
+ 'summary-sync': ['cwd', 'agent', 'bodyFile', 'changeReportFile', 'result', 'dryRun', 'strict']
87
112
  };
88
113
  const unexpected = Object.keys(values).find((name) => !allowed[operation].includes(name));
89
114
  if (unexpected) {
@@ -91,11 +116,11 @@ function platformPr(args = []) {
91
116
  return;
92
117
  }
93
118
  if (operation === 'inspect') {
94
- finish(inspectPlatformPullRequest(taskRef, { cwd }));
119
+ finish(await inspectPlatformPullRequest(taskRef, { cwd }));
95
120
  return;
96
121
  }
97
122
  if (operation === 'summary-context') {
98
- finish(summaryContext(taskRef, { cwd }));
123
+ finish(await summaryContext(taskRef, { cwd }));
99
124
  return;
100
125
  }
101
126
  if (typeof values.agent !== 'string' || !values.agent) {
@@ -108,8 +133,18 @@ function platformPr(args = []) {
108
133
  return;
109
134
  }
110
135
  values.agent = agent;
136
+ if (operation === 'change-report') {
137
+ if (typeof values.mechanicalFile !== 'string' || typeof values.precheckFile !== 'string') {
138
+ fail('change-report requires --mechanical-file and --precheck-file');
139
+ return;
140
+ }
141
+ finish(await reportWrite(taskRef, {
142
+ cwd, agent: values.agent, mechanicalFile: values.mechanicalFile, precheckFile: values.precheckFile, dryRun: values.dryRun === true
143
+ }));
144
+ return;
145
+ }
111
146
  if (operation === 'skip') {
112
- finish(skipPlatformPullRequestFact(taskRef, { cwd, agent, dryRun: values.dryRun === true }));
147
+ finish(await skipPlatformPullRequestFact(taskRef, { cwd, agent, dryRun: values.dryRun === true }));
113
148
  return;
114
149
  }
115
150
  const primaryResult = values.result === undefined ? undefined : values.result;
@@ -118,21 +153,21 @@ function platformPr(args = []) {
118
153
  return;
119
154
  }
120
155
  if (operation === 'resolve-external') {
121
- const pr = values.pr === undefined ? undefined : Number(values.pr);
122
- if (pr !== undefined && (!Number.isInteger(pr) || pr <= 0)) {
123
- fail('resolve-external requires a positive --pr');
156
+ const pr = values.pr === undefined ? undefined : values.pr;
157
+ if (pr !== undefined && (typeof pr !== 'string' || !pr)) {
158
+ fail('resolve-external requires --pr <token>');
124
159
  return;
125
160
  }
126
- finish(resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
161
+ finish(await resolveExternalPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
127
162
  return;
128
163
  }
129
164
  if (operation === 'bind') {
130
- const pr = Number(values.pr);
131
- if (!Number.isInteger(pr) || pr <= 0) {
132
- fail('bind requires a positive --pr');
165
+ const pr = values.pr;
166
+ if (typeof pr !== 'string' || !pr) {
167
+ fail('bind requires --pr <token>');
133
168
  return;
134
169
  }
135
- finish(bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
170
+ finish(await bindPlatformPullRequest(taskRef, { cwd, agent: values.agent, pr, dryRun: values.dryRun === true }));
136
171
  return;
137
172
  }
138
173
  if (operation === 'sync') {
@@ -144,7 +179,7 @@ function platformPr(args = []) {
144
179
  fail('sync requires --result pr_created, pr_reused, or no_op');
145
180
  return;
146
181
  }
147
- finish(syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult, dryRun: values.dryRun === true }));
182
+ finish(await syncPlatformPullRequest(taskRef, { cwd, agent: values.agent, metadata: values.metadata === true, closingIssue: values.closingIssue === true, primaryResult: primaryResult, dryRun: values.dryRun === true }));
148
183
  return;
149
184
  }
150
185
  if (operation === 'summary-sync') {
@@ -152,12 +187,16 @@ function platformPr(args = []) {
152
187
  fail('summary-sync requires --body-file');
153
188
  return;
154
189
  }
190
+ if (typeof values.changeReportFile !== 'string') {
191
+ fail('summary-sync requires --change-report-file');
192
+ return;
193
+ }
155
194
  if (!primaryResult) {
156
195
  fail('summary-sync requires --result pr_created, pr_reused, or no_op');
157
196
  return;
158
197
  }
159
198
  try {
160
- finish(syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), primaryResult: primaryResult, dryRun: values.dryRun === true }));
199
+ finish(await syncPullRequestSummary(taskRef, { cwd, agent: values.agent, body: readFile(values.bodyFile, cwd), changeReportFile: values.changeReportFile, primaryResult: primaryResult, dryRun: values.dryRun === true, strict: values.strict === true }));
161
200
  }
162
201
  catch (error) {
163
202
  fail(`unable to read body file: ${error instanceof Error ? error.message : String(error)}`);
@@ -169,7 +208,7 @@ function platformPr(args = []) {
169
208
  return;
170
209
  }
171
210
  try {
172
- finish(createPlatformPullRequest(taskRef, {
211
+ finish(await createPlatformPullRequest(taskRef, {
173
212
  cwd, agent: values.agent, base: values.base, head: values.head,
174
213
  title: readFile(values.titleFile, cwd), body: readFile(values.bodyFile, cwd),
175
214
  draft: values.draft === true, dryRun: values.dryRun === true
@@ -28,7 +28,7 @@ function finish(result) {
28
28
  process.stdout.write(`${JSON.stringify(result)}\n`);
29
29
  process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
30
30
  }
31
- function platformReleaseNotes(args = []) {
31
+ async function platformReleaseNotes(args = []) {
32
32
  const [action, ...rest] = args;
33
33
  if (action === 'context') {
34
34
  const parsed = parseOptions(rest, ['--cwd', '--history-limit', '--from-tag', '--to-tag', '--branch']);
@@ -36,7 +36,7 @@ function platformReleaseNotes(args = []) {
36
36
  return finish(invalidInput('invalid context options'));
37
37
  const cwd = path.resolve(parsed.values.get('--cwd') || process.cwd());
38
38
  const historyRaw = parsed.values.get('--history-limit') ?? null;
39
- finish(releaseNoteContext({
39
+ finish(await releaseNoteContext({
40
40
  fromTag: parsed.values.get('--from-tag') || '',
41
41
  toTag: parsed.values.get('--to-tag') || '',
42
42
  branch: parsed.values.get('--branch') || '',
@@ -69,7 +69,7 @@ function platformReleaseNotes(args = []) {
69
69
  fs.writeFileSync(resolvedNotesPath, fs.readFileSync(0));
70
70
  }
71
71
  try {
72
- finish(publishReleaseNotes({
72
+ finish(await publishReleaseNotes({
73
73
  tag: parsed.values.get('--tag') || '',
74
74
  title: parsed.values.get('--title') || parsed.values.get('--tag') || '',
75
75
  notesFile: resolvedNotesPath,
@@ -4,7 +4,7 @@ import { collectHostCandidates, decide, deriveTaskIssueMatches, extractClosingIs
4
4
  import { inspectPlatformPullRequestByNumber } from '../platform/pull-requests.js';
5
5
  import { verifyInProcess } from '../task/verification-engine.js';
6
6
  const USAGE = `Usage: agent-infra-internal pr-review-grade decide --input-file <path|-> [--cwd <path>]
7
- agent-infra-internal pr-review-grade resolve-host --pr <N> [--cwd <path>]
7
+ agent-infra-internal pr-review-grade resolve-host --pr <token> [--cwd <path>]
8
8
  agent-infra-internal pr-review-grade verify-artifact --artifact-file <path> [--cwd <path>]
9
9
  `;
10
10
  function fail(message) {
@@ -38,7 +38,7 @@ function parseFlags(args, start) {
38
38
  function readInput(value, cwd) {
39
39
  return value === '-' ? fs.readFileSync(0, 'utf8') : fs.readFileSync(path.resolve(cwd, value), 'utf8');
40
40
  }
41
- function prReviewGrade(args = []) {
41
+ async function prReviewGrade(args = []) {
42
42
  if (args[0] === '--help' || args[0] === '-h') {
43
43
  process.stdout.write(USAGE);
44
44
  return;
@@ -89,12 +89,12 @@ function prReviewGrade(args = []) {
89
89
  return;
90
90
  }
91
91
  if (operation === 'resolve-host') {
92
- const pr = Number(values.pr);
93
- if (!Number.isInteger(pr) || pr <= 0) {
94
- fail('resolve-host requires a positive --pr');
92
+ const pr = typeof values.pr === 'string' ? values.pr : '';
93
+ if (!pr) {
94
+ fail('resolve-host requires --pr <token>');
95
95
  return;
96
96
  }
97
- const inspected = inspectPlatformPullRequestByNumber(pr, { cwd });
97
+ const inspected = await inspectPlatformPullRequestByNumber(pr, { cwd });
98
98
  if (!inspected.pullRequest) {
99
99
  finish({
100
100
  status: 'failed', changed: false, host: null, candidates: [], closingIssues: [],
@@ -102,12 +102,14 @@ function prReviewGrade(args = []) {
102
102
  }, inspected.status === 'blocked' ? 2 : 1);
103
103
  return;
104
104
  }
105
+ const prNumber = inspected.pullRequest.number;
106
+ const prIdentity = inspected.pullRequest.identity || { kind: 'number', value: prNumber };
105
107
  const closingIssues = extractClosingIssueNumbers(inspected.pullRequest.body);
106
- const candidates = collectHostCandidates({ prNumber: pr, closingIssues, workspaceRoot: cwd });
108
+ const candidates = collectHostCandidates({ prNumber, prIdentity, closingIssues, workspaceRoot: cwd });
107
109
  const host = resolveHostFromCandidates(candidates);
108
110
  finish({
109
111
  status: 'ok', changed: false,
110
- pr: { number: pr, baseSha: inspected.pullRequest.base.sha, headSha: inspected.pullRequest.head.sha, state: inspected.pullRequest.state },
112
+ pr: { number: prNumber, identity: prIdentity, baseSha: inspected.pullRequest.base.sha, headSha: inspected.pullRequest.head.sha, state: inspected.pullRequest.state },
111
113
  closingIssues, candidates, host,
112
114
  taskIssueMatches: deriveTaskIssueMatches(host, closingIssues), error: null
113
115
  });
@@ -120,7 +122,7 @@ function prReviewGrade(args = []) {
120
122
  const artifactPath = path.resolve(cwd, values.artifactFile);
121
123
  let result;
122
124
  try {
123
- result = verifyInProcess({
125
+ result = await verifyInProcess({
124
126
  mode: 'checks',
125
127
  skillName: 'review-pr',
126
128
  taskDir: path.dirname(artifactPath),
@@ -236,7 +236,7 @@ async function inspectFacts(cwd, version) {
236
236
  const local = inspectLocalReleaseFacts(cwd, version);
237
237
  const remoteBranch = branch ? git(cwd, ['ls-remote', '--heads', 'origin', branch]) : null;
238
238
  const remoteTag = git(cwd, ['ls-remote', '--tags', 'origin', `refs/tags/${tag}`]);
239
- const platform = inspectPlatformRelease(tag, { cwd });
239
+ const platform = await inspectPlatformRelease(tag, { cwd });
240
240
  const npm = await inspectNpmChannel(pkg.name, version);
241
241
  const formulaUrl = `https://raw.githubusercontent.com/${config.org}/homebrew-tap/main/Formula/${config.project}.rb`;
242
242
  const homebrew = await inspectHomebrewChannel(formulaUrl, version);
@@ -247,7 +247,7 @@ async function inspectFacts(cwd, version) {
247
247
  localTagAncestor: local.localTagAncestor,
248
248
  localTagConflict: local.localTagConflict,
249
249
  remoteBranch: Boolean(remoteBranch && remoteBranch.split(/\s+/)[0] === head), remoteTag: Boolean(remoteTag),
250
- githubRelease: platform.platform.type !== 'github'
250
+ githubRelease: platform.error?.code === 'PLATFORM_CAPABILITY_UNSUPPORTED'
251
251
  ? true
252
252
  : platform.status === 'blocked' ? null : Boolean(platform.release?.published),
253
253
  npm: npm.published, homebrew: homebrew.published, smoke,
@@ -312,7 +312,7 @@ async function releaseWorkflow(args = []) {
312
312
  }
313
313
  if (action === 'prepare') {
314
314
  if (before.phase !== 'unprepared') {
315
- const milestones = reconcileReleaseMilestones(version, { cwd });
315
+ const milestones = await reconcileReleaseMilestones(version, { cwd });
316
316
  process.stdout.write(`${JSON.stringify({ ...milestones, snapshot: before })}\n`);
317
317
  process.exitCode = milestones.status === 'failed' ? 1 : milestones.status === 'blocked' ? 2 : 0;
318
318
  return;
@@ -354,7 +354,7 @@ async function releaseWorkflow(args = []) {
354
354
  return;
355
355
  }
356
356
  const tagged = command(cwd, 'git', ['tag', '-a', `v${version}`, '-m', `Release v${version}`]);
357
- const milestones = tagged.status === 0 ? reconcileReleaseMilestones(version, { cwd }) : null;
357
+ const milestones = tagged.status === 0 ? await reconcileReleaseMilestones(version, { cwd }) : null;
358
358
  const snapshot = releaseSnapshot(version, await inspectFacts(cwd, version));
359
359
  const failed = tagged.status !== 0 || milestones?.status === 'failed';
360
360
  const blocked = milestones?.status === 'blocked';
@@ -1,4 +1,4 @@
1
- import { requestSandboxControl, requestSandboxTaskFinalization, requestSandboxTaskControl, SandboxControlClientError } from '../sandbox/control/client.js';
1
+ import { recoverSandboxControl, requestSandboxControl, requestSandboxTaskFinalization, requestSandboxTaskControl, SandboxControlClientError } from '../sandbox/control/client.js';
2
2
  import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
3
3
  import { serveSandboxControl } from '../sandbox/control/server.js';
4
4
  import { runSandboxControlExecutor } from '../sandbox/control/executor.js';
@@ -23,6 +23,11 @@ function finalizationErrorStatus(error) {
23
23
  return 'unknown';
24
24
  return error.retryable ? 'blocked' : 'failed';
25
25
  }
26
+ function writeClientError(error) {
27
+ process.stderr.write(`${error.detail.message}\n`);
28
+ if (error.requestId)
29
+ process.stderr.write(`SANDBOX_CONTROL_REQUEST_ID: ${error.requestId}\n`);
30
+ }
26
31
  function sandboxFinalizationClient(args) {
27
32
  if (args.length !== 4 || !args[0] || args[1] !== 'complete' || args[2] !== '--agent' || !args[3]) {
28
33
  const error = { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'task ref, complete intent, and --agent are required', retryable: false };
@@ -46,7 +51,7 @@ function sandboxFinalizationClient(args) {
46
51
  if (!(error instanceof SandboxControlClientError))
47
52
  throw error;
48
53
  writeFinalizationEnvelope(finalizationErrorStatus(error.detail), error.accepted, error.detail);
49
- process.stderr.write(`${error.detail.message}\n`);
54
+ writeClientError(error);
50
55
  process.exitCode = error.detail.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN' ? 1 : error.detail.retryable ? 2 : 1;
51
56
  return;
52
57
  }
@@ -95,6 +100,27 @@ async function sandboxControl(args) {
95
100
  await runSandboxControlExecutor(request, nonce);
96
101
  return;
97
102
  }
103
+ if (operation === 'recover') {
104
+ if (rest.length !== 1 || !rest[0])
105
+ throw new Error('sandbox-control recover requires <request-id>');
106
+ let response;
107
+ try {
108
+ response = recoverSandboxControl(rest[0]);
109
+ }
110
+ catch (error) {
111
+ if (!(error instanceof SandboxControlClientError))
112
+ throw error;
113
+ writeClientError(error);
114
+ process.exitCode = error.detail.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN' ? 1 : error.detail.retryable ? 75 : 1;
115
+ return;
116
+ }
117
+ process.stdout.write(response.stdout);
118
+ process.stderr.write(response.stderr);
119
+ process.exitCode = response.phase === 'rejected'
120
+ ? response.error?.retryable ? 75 : 1
121
+ : response.exitCode ?? 1;
122
+ return;
123
+ }
98
124
  if (operation === 'client') {
99
125
  const [family = '', ...commandArgs] = rest;
100
126
  if (family === 'task-finalization') {
@@ -117,7 +143,7 @@ async function sandboxControl(args) {
117
143
  catch (error) {
118
144
  if (!(error instanceof SandboxControlClientError))
119
145
  throw error;
120
- process.stderr.write(`${error.detail.message}\n`);
146
+ writeClientError(error);
121
147
  process.exitCode = error.detail.retryable ? 75 : 1;
122
148
  return;
123
149
  }
@@ -132,7 +158,7 @@ async function sandboxControl(args) {
132
158
  }
133
159
  return;
134
160
  }
135
- throw new Error('Usage: agent-infra-internal sandbox-control serve --manifest <path> | execute --request <path> --nonce <nonce> | client <family> [args...]');
161
+ throw new Error('Usage: agent-infra-internal sandbox-control serve --manifest <path> | execute --request <path> --nonce <nonce> | client <family> [args...] | recover <request-id>');
136
162
  }
137
163
  export { sandboxControl };
138
164
  //# sourceMappingURL=sandbox-control.js.map
@@ -32,7 +32,7 @@ function usageFailure(message) {
32
32
  process.stderr.write(USAGE);
33
33
  process.exitCode = 1;
34
34
  }
35
- function taskActivity(args = []) {
35
+ async function taskActivity(args = []) {
36
36
  if (args[0] === '--help' || args[0] === '-h') {
37
37
  process.stdout.write(USAGE);
38
38
  return;
@@ -113,7 +113,7 @@ function taskActivity(args = []) {
113
113
  let result;
114
114
  let humanOverride = null;
115
115
  try {
116
- result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, () => {
116
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-activity.${kind}`, async () => {
117
117
  let current = applyPrReviewActivityIntent(values, { lockAlreadyHeld: true });
118
118
  if (current.status !== 'failed' || !values.overrideTicket)
119
119
  return current;
@@ -121,7 +121,7 @@ function taskActivity(args = []) {
121
121
  usageFailure('override ticket requires target and scope');
122
122
  return current;
123
123
  }
124
- const consumed = consumeHumanOverride({
124
+ const consumed = await consumeHumanOverride({
125
125
  taskRef, ticketId: String(values.overrideTicket),
126
126
  failureId: failureId('activity-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
127
127
  target: String(values.overrideTarget), scope: String(values.overrideScope)
@@ -1,5 +1,8 @@
1
1
  import { resolveArtifactContext } from '../task/artifact-lifecycle.js';
2
- const USAGE = `Usage: agent-infra-internal task-artifact <N | TASK-id> inspect --family <family>\n\nInspect one workflow artifact family and print a read-only JSON context.\n`;
2
+ import { finalizeLocalArtifact } from '../task/local-artifact-finalization.js';
3
+ import { resolveTaskRef } from '../task/resolve-ref.js';
4
+ import { loadVerificationConfig } from '../task/verification-config.js';
5
+ const USAGE = `Usage: agent-infra-internal task-artifact <N | TASK-id> inspect --family <family>\n agent-infra-internal task-artifact <N | TASK-id> finalize-local --family <analysis|plan|code> --artifact <artifact>\n\nInspect workflow artifact context or finalize a local analysis/plan/code artifact without changing task state.\n`;
3
6
  function failUsage(message) {
4
7
  process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'ARTIFACT_PAYLOAD_INVALID', message } })}\n`);
5
8
  process.stderr.write(USAGE);
@@ -14,15 +17,17 @@ function taskArtifact(args = []) {
14
17
  failUsage('task ref and operation are required');
15
18
  return;
16
19
  }
17
- if (args[1] !== 'inspect') {
18
- failUsage(`unknown operation '${args[1]}'`);
20
+ const operation = args[1];
21
+ if (operation !== 'inspect' && operation !== 'finalize-local') {
22
+ failUsage(`unknown operation '${operation}'`);
19
23
  return;
20
24
  }
21
25
  let family = '';
26
+ let artifact = '';
22
27
  const seen = new Set();
23
28
  for (let index = 2; index < args.length; index += 1) {
24
29
  const flag = args[index];
25
- if (flag !== '--family') {
30
+ if (flag !== '--family' && flag !== '--artifact') {
26
31
  failUsage(`unknown option '${flag}'`);
27
32
  return;
28
33
  }
@@ -36,32 +41,79 @@ function taskArtifact(args = []) {
36
41
  return;
37
42
  }
38
43
  seen.add(flag);
39
- family = value;
44
+ if (flag === '--family')
45
+ family = value;
46
+ else
47
+ artifact = value;
40
48
  }
41
49
  if (!family) {
42
50
  failUsage("option '--family' is required");
43
51
  return;
44
52
  }
45
- const result = resolveArtifactContext(args[0], family);
46
- const output = family === 'code' && result.codeMode ? {
47
- ...result,
48
- mode: result.codeMode.mode,
49
- code_max: result.codeMode.codeMax,
50
- rev_max: result.codeMode.reviewMax,
51
- verdict: result.codeMode.verdict,
52
- next_round: result.next?.round ?? null,
53
- next_artifact: result.next?.name ?? null,
54
- review_artifact: result.codeMode.reviewArtifact,
55
- implementation_input: result.codeMode.implementationInput,
56
- decision_id: result.codeMode.decisionId,
57
- decision_evidence: result.codeMode.decisionEvidence,
58
- message: result.codeMode.message
59
- } : result;
60
- process.stdout.write(`${JSON.stringify(output)}\n`);
61
- if (result.status === 'refused')
53
+ if (operation === 'inspect') {
54
+ if (artifact) {
55
+ failUsage("option '--artifact' is only valid for finalize-local");
56
+ return;
57
+ }
58
+ const result = resolveArtifactContext(args[0], family);
59
+ const output = family === 'code' && result.codeMode ? {
60
+ ...result,
61
+ mode: result.codeMode.mode,
62
+ code_max: result.codeMode.codeMax,
63
+ rev_max: result.codeMode.reviewMax,
64
+ verdict: result.codeMode.verdict,
65
+ next_round: result.next?.round ?? null,
66
+ next_artifact: result.next?.name ?? null,
67
+ review_artifact: result.codeMode.reviewArtifact,
68
+ implementation_input: result.codeMode.implementationInput,
69
+ decision_id: result.codeMode.decisionId,
70
+ decision_evidence: result.codeMode.decisionEvidence,
71
+ message: result.codeMode.message
72
+ } : result;
73
+ process.stdout.write(`${JSON.stringify(output)}\n`);
74
+ if (result.status === 'refused')
75
+ process.exitCode = 1;
76
+ else if (result.status === 'failed')
77
+ process.exitCode = 2;
78
+ return;
79
+ }
80
+ const resolved = resolveTaskRef(args[0]);
81
+ const repositoryRoot = resolved.ok ? resolved.repoRoot : process.cwd();
82
+ if (!artifact) {
83
+ failUsage("option '--artifact' is required");
84
+ return;
85
+ }
86
+ if (family !== 'analysis' && family !== 'plan' && family !== 'code') {
87
+ failUsage("finalize-local only supports 'analysis', 'plan', and 'code'");
88
+ return;
89
+ }
90
+ const skillName = family === 'analysis' ? 'analyze-task' : family === 'plan' ? 'plan-task' : 'code-task';
91
+ let config = {};
92
+ try {
93
+ const loaded = loadVerificationConfig(repositoryRoot, skillName);
94
+ const artifactConfig = loaded.checks.artifact;
95
+ if (artifactConfig && typeof artifactConfig === 'object' && !Array.isArray(artifactConfig)) {
96
+ const sections = artifactConfig.required_sections;
97
+ const patterns = artifactConfig.required_patterns;
98
+ config = {
99
+ requiredSections: Array.isArray(sections) ? sections.filter((value) => typeof value === 'string') : undefined,
100
+ requiredPatterns: Array.isArray(patterns) ? patterns.filter((value) => typeof value === 'string') : undefined
101
+ };
102
+ }
103
+ }
104
+ catch {
105
+ // Isolated fixture repositories may not contain the project's verification config.
106
+ }
107
+ const result = finalizeLocalArtifact({
108
+ taskRef: args[0],
109
+ family: family,
110
+ artifact,
111
+ repoRoot: repositoryRoot,
112
+ ...config
113
+ });
114
+ process.stdout.write(`${JSON.stringify(result)}\n`);
115
+ if (result.status === 'failed')
62
116
  process.exitCode = 1;
63
- else if (result.status === 'failed')
64
- process.exitCode = 2;
65
117
  }
66
118
  export { taskArtifact };
67
119
  //# sourceMappingURL=task-artifact.js.map
@@ -14,7 +14,7 @@ function output(result) {
14
14
  process.stdout.write(`${JSON.stringify(result)}\n`);
15
15
  process.exitCode = result.status === 'blocked' ? 2 : result.status === 'failed' ? 1 : 0;
16
16
  }
17
- function taskCreate(args) {
17
+ async function taskCreate(args) {
18
18
  const inputIndex = args.indexOf('--input');
19
19
  const input = inputIndex >= 0 ? args[inputIndex + 1] : undefined;
20
20
  if (!input || args.length !== 2 || inputIndex !== 0) {
@@ -40,7 +40,7 @@ function taskCreate(args) {
40
40
  process.exitCode = response.exitCode;
41
41
  return;
42
42
  }
43
- output(createTask(candidate, { repoRoot: process.cwd() }));
43
+ output(await createTask(candidate, { repoRoot: process.cwd() }));
44
44
  }
45
45
  catch (error) {
46
46
  if (error instanceof SandboxControlClientError) {
@@ -10,6 +10,9 @@ Events: ${eventCatalog.join(', ')}
10
10
  `;
11
11
  const FLAGS = {
12
12
  '--agent': 'agent', '--round': 'round', '--question': 'question', '--artifact': 'artifact',
13
+ '--artifact-sha256': 'artifactSha256', '--semantic-digest': 'semanticDigest',
14
+ '--initiator': 'initiator', '--request-id': 'requestId', '--reason-code': 'reasonCode',
15
+ '--source-finding': 'sourceFinding', '--source-artifact': 'sourceArtifact', '--source-sha256': 'sourceSha256',
13
16
  '--fix-for': 'fixFor', '--implementation-input': 'implementationInput',
14
17
  '--verdict': 'verdict', '--blockers': 'blockers', '--major': 'major',
15
18
  '--minor': 'minor', '--manual-validation': 'manualValidation', '--files-modified': 'filesModified',
@@ -22,7 +25,7 @@ function usageFailure(message) {
22
25
  process.stderr.write(USAGE);
23
26
  process.exitCode = 1;
24
27
  }
25
- function taskEvent(args = []) {
28
+ async function taskEvent(args = []) {
26
29
  if (args[0] === '--help' || args[0] === '-h') {
27
30
  process.stdout.write(USAGE);
28
31
  return;
@@ -95,7 +98,7 @@ function taskEvent(args = []) {
95
98
  let result;
96
99
  let humanOverride = null;
97
100
  try {
98
- result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, () => {
101
+ result = await withTaskExecutionLock(resolved.repoRoot, resolved.taskId, `task-event.${request.event}`, async () => {
99
102
  let current = applyTaskEvent(request, { lockAlreadyHeld: true });
100
103
  const values = request;
101
104
  if (current.status !== 'failed' || !values.overrideTicket)
@@ -103,7 +106,7 @@ function taskEvent(args = []) {
103
106
  if (!values.overrideTarget || !values.overrideScope) {
104
107
  return { ...current, humanOverride: { status: 'failed', error: { code: 'OVERRIDE_PAYLOAD_INVALID', message: 'override ticket requires target and scope' } } };
105
108
  }
106
- const consumed = consumeHumanOverride({
109
+ const consumed = await consumeHumanOverride({
107
110
  taskRef: request.taskRef,
108
111
  ticketId: String(values.overrideTicket),
109
112
  failureId: failureId('task-event', current.error?.code ?? 'EVENT_TRANSITION_INVALID'),
@@ -18,7 +18,7 @@ function parseFailure(error) {
18
18
  const message = error instanceof Error ? error.message : String(error);
19
19
  return message.replace(/^TASK_CONTROL_OPERATION_INVALID: /u, '');
20
20
  }
21
- function taskFinalization(args = []) {
21
+ async function taskFinalization(args = []) {
22
22
  if (args[0] === '--help' || args[0] === '-h') {
23
23
  process.stdout.write(USAGE);
24
24
  return;
@@ -56,7 +56,7 @@ function taskFinalization(args = []) {
56
56
  ...operation,
57
57
  request: { ...operation.request, taskRef: resolved.taskId }
58
58
  };
59
- const result = dispatchTaskControlOperation(createDirectHostExecutionContext({ repoRoot }), boundOperation);
59
+ const result = await dispatchTaskControlOperation(createDirectHostExecutionContext({ repoRoot }), boundOperation);
60
60
  process.stdout.write(envelope(result.status, result.changed, true, result, result.error));
61
61
  process.exitCode = exitCode(result.status);
62
62
  }