@fitlab-ai/agent-infra 0.9.8 → 0.9.9

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 (133) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/bin/internal-cli.js +6 -1
  4. package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +58 -21
  5. package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +8 -1
  6. package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +173 -10
  7. package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-context.js +147 -0
  8. package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +14 -0
  9. package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +56 -67
  10. package/dist/lib/git/workflow.js +10 -1
  11. package/dist/lib/internal/codex-lifecycle.js +19 -5
  12. package/dist/lib/internal/codex-sandbox-controller.js +6 -13
  13. package/dist/lib/internal/git-workflow.js +5 -7
  14. package/dist/lib/internal/platform-pr.js +20 -7
  15. package/dist/lib/internal/release-workflow.js +2 -1
  16. package/dist/lib/internal/sandbox-control.js +79 -2
  17. package/dist/lib/internal/task-finalization.js +54 -0
  18. package/dist/lib/internal/task-orchestration.js +156 -291
  19. package/dist/lib/platform/pr-summary.js +48 -10
  20. package/dist/lib/platform/pull-requests.js +205 -41
  21. package/dist/lib/sandbox/commands/rm.js +316 -55
  22. package/dist/lib/sandbox/control/client.js +190 -6
  23. package/dist/lib/sandbox/control/controller-registration.js +273 -0
  24. package/dist/lib/sandbox/control/executor.js +137 -5
  25. package/dist/lib/sandbox/control/lifecycle.js +3 -1
  26. package/dist/lib/sandbox/control/protocol.js +67 -6
  27. package/dist/lib/sandbox/index.js +5 -3
  28. package/dist/lib/sandbox/managed-fs.js +5 -0
  29. package/dist/lib/sandbox/task-resolver.js +50 -6
  30. package/dist/lib/sandbox/workspace-identity.js +27 -0
  31. package/dist/lib/sandbox/worktree-safety.js +215 -2
  32. package/dist/lib/task/codex-orchestration.js +158 -33
  33. package/dist/lib/task/commands/status.js +59 -1
  34. package/dist/lib/task/commit-operation.js +335 -0
  35. package/dist/lib/task/commit-policy.js +18 -0
  36. package/dist/lib/task/delegation-receipts.js +243 -2
  37. package/dist/lib/task/finalization.js +567 -0
  38. package/dist/lib/task/operation-outcome.js +33 -0
  39. package/dist/lib/task/orchestration.js +187 -761
  40. package/dist/lib/task/short-id.js +59 -1
  41. package/dist/lib/task/task-execution-lock.js +6 -1
  42. package/dist/lib/task/verification-engine.js +113 -60
  43. package/dist/lib/task/verification.js +2 -1
  44. package/dist/lib/task/workflow-warning-intents.js +50 -1
  45. package/dist/lifecycle-build-manifest.json +3 -3
  46. package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +61 -19
  47. package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +12 -0
  48. package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +276 -12
  49. package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +180 -0
  50. package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +19 -0
  51. package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +9 -1
  52. package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +83 -91
  53. package/lib/git/workflow.ts +11 -2
  54. package/lib/internal/codex-lifecycle.ts +18 -5
  55. package/lib/internal/codex-sandbox-controller.ts +6 -12
  56. package/lib/internal/git-workflow.ts +5 -6
  57. package/lib/internal/platform-pr.ts +14 -7
  58. package/lib/internal/release-workflow.ts +2 -1
  59. package/lib/internal/sandbox-control.ts +92 -2
  60. package/lib/internal/task-finalization.ts +68 -0
  61. package/lib/internal/task-orchestration.ts +20 -103
  62. package/lib/platform/pr-summary.ts +55 -11
  63. package/lib/platform/pull-requests.ts +211 -41
  64. package/lib/sandbox/commands/rm.ts +413 -61
  65. package/lib/sandbox/control/client.ts +255 -6
  66. package/lib/sandbox/control/controller-registration.ts +347 -0
  67. package/lib/sandbox/control/executor.ts +163 -5
  68. package/lib/sandbox/control/lifecycle.ts +2 -1
  69. package/lib/sandbox/control/protocol.ts +80 -7
  70. package/lib/sandbox/index.ts +5 -3
  71. package/lib/sandbox/managed-fs.ts +5 -0
  72. package/lib/sandbox/task-resolver.ts +58 -7
  73. package/lib/sandbox/workspace-identity.ts +50 -2
  74. package/lib/sandbox/workspace-view.ts +3 -3
  75. package/lib/sandbox/worktree-safety.ts +236 -2
  76. package/lib/task/codex-orchestration.ts +167 -33
  77. package/lib/task/commands/status.ts +78 -1
  78. package/lib/task/commit-operation.ts +430 -0
  79. package/lib/task/commit-policy.ts +30 -0
  80. package/lib/task/delegation-receipts.ts +258 -1
  81. package/lib/task/finalization.ts +719 -0
  82. package/lib/task/operation-outcome.ts +48 -0
  83. package/lib/task/orchestration.ts +217 -982
  84. package/lib/task/short-id.ts +65 -1
  85. package/lib/task/task-execution-lock.ts +10 -1
  86. package/lib/task/verification-engine.ts +118 -63
  87. package/lib/task/verification.ts +3 -2
  88. package/lib/task/workflow-warning-intents.ts +57 -2
  89. package/package.json +2 -2
  90. package/templates/.agents/QUICKSTART.en.md +2 -2
  91. package/templates/.agents/QUICKSTART.zh-CN.md +2 -2
  92. package/templates/.agents/hooks/lifecycle-delegation.js +1 -21
  93. package/templates/.agents/rules/lifecycle-orchestration.en.md +1 -1
  94. package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +1 -1
  95. package/templates/.agents/rules/task-management.en.md +2 -2
  96. package/templates/.agents/rules/task-management.zh-CN.md +2 -2
  97. package/templates/.agents/skills/block-task/SKILL.en.md +2 -4
  98. package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -4
  99. package/templates/.agents/skills/cancel-task/SKILL.en.md +3 -3
  100. package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +3 -3
  101. package/templates/.agents/skills/close-codescan/SKILL.en.md +6 -2
  102. package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +6 -2
  103. package/templates/.agents/skills/close-dependabot/SKILL.en.md +6 -2
  104. package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +6 -2
  105. package/templates/.agents/skills/commit/SKILL.en.md +41 -125
  106. package/templates/.agents/skills/commit/SKILL.zh-CN.md +52 -123
  107. package/templates/.agents/skills/commit/reference/commit-message.en.md +1 -1
  108. package/templates/.agents/skills/commit/reference/commit-message.zh-CN.md +1 -1
  109. package/templates/.agents/skills/commit/reference/commit-orchestration.en.md +14 -43
  110. package/templates/.agents/skills/commit/reference/commit-orchestration.zh-CN.md +14 -49
  111. package/templates/.agents/skills/commit/reference/pr-summary-sync.en.md +1 -1
  112. package/templates/.agents/skills/commit/reference/pr-summary-sync.zh-CN.md +1 -1
  113. package/templates/.agents/skills/commit/reference/task-status-update.en.md +2 -35
  114. package/templates/.agents/skills/commit/reference/task-status-update.zh-CN.md +2 -35
  115. package/templates/.agents/skills/complete-task/SKILL.en.md +31 -38
  116. package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +31 -38
  117. package/templates/.agents/skills/complete-task/config/verify.en.json +1 -0
  118. package/templates/.agents/skills/complete-task/config/verify.zh-CN.json +1 -0
  119. package/templates/.agents/skills/complete-task/reference/external-delivery.en.md +1 -1
  120. package/templates/.agents/skills/complete-task/reference/external-delivery.zh-CN.md +1 -1
  121. package/templates/.agents/skills/create-pr/SKILL.en.md +6 -4
  122. package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +6 -4
  123. package/templates/.agents/skills/create-pr/reference/comment-publish.en.md +2 -2
  124. package/templates/.agents/skills/create-pr/reference/comment-publish.zh-CN.md +2 -2
  125. package/templates/.agents/skills/run-task/SKILL.en.md +5 -5
  126. package/templates/.agents/skills/run-task/SKILL.zh-CN.md +5 -5
  127. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.en.md +1 -1
  128. package/templates/.agents/skills/watch-pr/reference/monitor-and-heal.zh-CN.md +1 -1
  129. package/templates/.codex/hooks.json +4 -4
  130. package/dist/lib/task/commit-finalization.js +0 -305
  131. package/dist/lib/task/commit-intent.js +0 -165
  132. package/lib/task/commit-finalization.ts +0 -419
  133. package/lib/task/commit-intent.ts +0 -230
@@ -1,8 +1,7 @@
1
- import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.js';
2
- import { abortCommitIntent, activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, awaitOrchestrationDelegationActivation, beginCommitIntent, beginOrResumeOrchestration, checkpointCommitIntent, completeCommitIntent, dispatchOrchestrationDelegation, pauseOrchestration, recoverCommitIntent, recoverPreparedOrchestrationDelegation, routeOrchestration, sealMatchingOrchestrationDelegation, sealOrchestrationDelegation, startCommitAttempt, statusCommitIntent, statusOrchestration, terminateCommitAttempt } from '../task/orchestration.js';
1
+ import { activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, awaitOrchestrationDelegationActivation, beginOrResumeOrchestration, dispatchOrchestrationDelegation, OrchestrationStateError, pauseOrchestration, recoverPreparedOrchestrationDelegation, routeOrchestration, sealMatchingOrchestrationDelegation, sealOrchestrationDelegation, statusOrchestration } from '../task/orchestration.js';
3
2
  import { prepareCodexOrchestrationDelegation } from '../task/codex-orchestration.js';
4
3
  import { isAgentClientId } from '../agent-clients/types.js';
5
- const USAGE = 'Usage: agent-infra-internal task-orchestration <task-ref|auto> <begin-or-resume|route|prepare|dispatch|await-activation|recover-prepared|hook-start|hook-stop|advance|pause|status|commit-start|commit-begin|commit-checkpoint|commit-complete|commit-recover|commit-abort|commit-terminate|commit-status> [options]\n';
4
+ const USAGE = 'Usage: agent-infra-internal task-orchestration <task-ref|auto> <begin-or-resume|route|prepare|dispatch|await-activation|recover-prepared|hook-start|hook-stop|advance|pause|status> [options]\n';
6
5
  function usageFailure(message) {
7
6
  process.stdout.write(`${JSON.stringify({
8
7
  status: 'failed', changed: false,
@@ -23,26 +22,15 @@ async function taskOrchestration(args = []) {
23
22
  const [taskRef, intent] = args;
24
23
  if (![
25
24
  'begin-or-resume', 'route', 'prepare', 'dispatch', 'await-activation', 'recover-prepared',
26
- 'hook-start', 'hook-stop', 'advance', 'pause', 'status',
27
- 'commit-start', 'commit-begin', 'commit-checkpoint', 'commit-complete', 'commit-recover', 'commit-abort', 'commit-terminate', 'commit-status'
25
+ 'hook-start', 'hook-stop', 'advance', 'pause', 'status'
28
26
  ].includes(intent)) {
29
27
  usageFailure(`unknown intent '${intent}'`);
30
28
  return;
31
29
  }
32
30
  const values = {};
33
31
  const seen = new Set();
34
- let orchestrated = false;
35
32
  for (let index = 2; index < args.length; index += 1) {
36
33
  const flag = args[index];
37
- if (flag === '--orchestrated') {
38
- if (seen.has(flag)) {
39
- usageFailure(`duplicate option '${flag}'`);
40
- return;
41
- }
42
- seen.add(flag);
43
- orchestrated = true;
44
- continue;
45
- }
46
34
  if (![
47
35
  '--max-steps', '--executor-model', '--executor-reasoning-effort',
48
36
  '--reviewer-model', '--reviewer-reasoning-effort',
@@ -52,8 +40,7 @@ async function taskOrchestration(args = []) {
52
40
  '--native-agent', '--child-id', '--spawn-mode', '--actual-model', '--actual-reasoning-effort',
53
41
  '--model-fallback-reason', '--reasoning-effort-fallback-reason',
54
42
  '--exit-code', '--after-fingerprint', '--changed-paths', '--code', '--message', '--recoverable', '--agent',
55
- '--baseline-head', '--token', '--kind', '--head', '--remote', '--ref', '--expected-head',
56
- '--attempt', '--git-worktree-root'
43
+ '--git-worktree-root'
57
44
  ].includes(flag)) {
58
45
  usageFailure(`unknown option '${flag}'`);
59
46
  return;
@@ -70,33 +57,6 @@ async function taskOrchestration(args = []) {
70
57
  }
71
58
  values[flag] = value;
72
59
  }
73
- const commitIntentFlags = {
74
- 'commit-start': ['--agent', '--git-worktree-root'],
75
- 'commit-begin': ['--agent', '--baseline-head', '--attempt', '--orchestrated', '--git-worktree-root'],
76
- 'commit-checkpoint': ['--token', '--kind', '--head', '--remote', '--ref', '--git-worktree-root'],
77
- 'commit-complete': ['--token', '--agent', '--git-worktree-root'],
78
- 'commit-recover': ['--agent', '--git-worktree-root'],
79
- 'commit-abort': ['--token', '--expected-head', '--git-worktree-root'],
80
- 'commit-terminate': ['--attempt', '--agent', '--code', '--git-worktree-root'],
81
- 'commit-status': ['--git-worktree-root']
82
- };
83
- if (intent in commitIntentFlags) {
84
- const allowed = commitIntentFlags[intent];
85
- const invalid = [...seen].find((flag) => !allowed.includes(flag));
86
- if (invalid) {
87
- usageFailure(`intent '${intent}' does not accept '${invalid}'`);
88
- return;
89
- }
90
- }
91
- else {
92
- const commitOnly = [...seen].find((flag) => [
93
- '--orchestrated', '--baseline-head', '--attempt', '--token', '--kind', '--head', '--remote', '--ref', '--expected-head'
94
- ].includes(flag));
95
- if (commitOnly) {
96
- usageFailure(`intent '${intent}' does not accept '${commitOnly}'`);
97
- return;
98
- }
99
- }
100
60
  const requireValues = (flags) => flags.find((flag) => values[flag] === undefined);
101
61
  const coreOptions = values['--git-worktree-root'] === undefined
102
62
  ? {}
@@ -106,273 +66,178 @@ async function taskOrchestration(args = []) {
106
66
  return;
107
67
  }
108
68
  let result;
109
- if (intent === 'commit-start') {
110
- const missing = requireValues(['--agent']);
111
- if (missing) {
112
- usageFailure(`intent 'commit-start' requires '${missing}'`);
113
- return;
114
- }
115
- const agent = normalizeAgentToken(values['--agent']);
116
- if (!agent) {
117
- usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
118
- return;
119
- }
120
- result = startCommitAttempt(taskRef, { agent }, coreOptions);
121
- }
122
- else if (intent === 'commit-begin') {
123
- const missing = requireValues(['--agent', '--baseline-head', '--attempt']);
124
- if (missing) {
125
- usageFailure(`intent 'commit-begin' requires '${missing}'`);
126
- return;
127
- }
128
- const agent = normalizeAgentToken(values['--agent']);
129
- if (!agent) {
130
- usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
131
- return;
132
- }
133
- result = beginCommitIntent(taskRef, {
134
- agent, orchestrated, baselineHead: values['--baseline-head'], attempt: values['--attempt']
135
- }, coreOptions);
136
- }
137
- else if (intent === 'commit-checkpoint') {
138
- const missing = requireValues(['--token', '--kind', '--head']);
139
- if (missing) {
140
- usageFailure(`intent 'commit-checkpoint' requires '${missing}'`);
141
- return;
142
- }
143
- if (!['committed', 'pushed'].includes(values['--kind'])) {
144
- usageFailure('--kind must be committed or pushed');
145
- return;
146
- }
147
- if (values['--kind'] === 'pushed') {
148
- const pushedMissing = requireValues(['--remote', '--ref']);
149
- if (pushedMissing) {
150
- usageFailure(`pushed checkpoint requires '${pushedMissing}'`);
69
+ try {
70
+ if (intent === 'begin-or-resume') {
71
+ const missing = requireValues(['--client']);
72
+ if (missing) {
73
+ usageFailure(`intent 'begin-or-resume' requires '${missing}'`);
151
74
  return;
152
75
  }
76
+ const maxSteps = values['--max-steps'] === undefined ? undefined : Number(values['--max-steps']);
77
+ if (maxSteps !== undefined && (!Number.isInteger(maxSteps) || maxSteps < 1)) {
78
+ usageFailure('--max-steps must be a positive integer');
79
+ return;
80
+ }
81
+ const policyFlags = [
82
+ '--executor-model', '--executor-reasoning-effort',
83
+ '--reviewer-model', '--reviewer-reasoning-effort'
84
+ ];
85
+ const hasAnyPolicy = policyFlags.some((flag) => values[flag] !== undefined);
86
+ if (hasAnyPolicy && policyFlags.some((flag) => values[flag] === undefined)) {
87
+ usageFailure('explicit model policy requires executor/reviewer model and reasoning effort');
88
+ return;
89
+ }
90
+ result = beginOrResumeOrchestration(taskRef, {
91
+ ...coreOptions,
92
+ maxSteps,
93
+ client: values['--client'],
94
+ modelPolicy: hasAnyPolicy ? {
95
+ executor: {
96
+ model: values['--executor-model'],
97
+ reasoningEffort: values['--executor-reasoning-effort']
98
+ },
99
+ reviewer: {
100
+ model: values['--reviewer-model'],
101
+ reasoningEffort: values['--reviewer-reasoning-effort']
102
+ }
103
+ } : undefined
104
+ });
105
+ }
106
+ else if (intent === 'route') {
107
+ result = routeOrchestration(taskRef, coreOptions);
108
+ }
109
+ else if (intent === 'status') {
110
+ result = statusOrchestration(taskRef, coreOptions);
111
+ }
112
+ else if (intent === 'prepare') {
113
+ const missing = requireValues(['--client']);
114
+ if (missing) {
115
+ usageFailure(`intent 'prepare' requires '${missing}'`);
116
+ return;
117
+ }
118
+ result = await prepareCodexOrchestrationDelegation(taskRef, {
119
+ client: values['--client'],
120
+ requestedModel: values['--requested-model'],
121
+ requestedReasoningEffort: values['--requested-reasoning-effort'],
122
+ capabilityToken: values['--capability-token']
123
+ }, { orchestrationOptions: coreOptions });
124
+ }
125
+ else if (intent === 'dispatch') {
126
+ result = dispatchOrchestrationDelegation(taskRef, coreOptions);
127
+ }
128
+ else if (intent === 'await-activation') {
129
+ const missing = requireValues(['--stage', '--round', '--artifact', '--role']);
130
+ if (missing) {
131
+ usageFailure(`intent 'await-activation' requires '${missing}'`);
132
+ return;
133
+ }
134
+ const round = Number(values['--round']);
135
+ if (!Number.isSafeInteger(round) || round < 1) {
136
+ usageFailure('--round must be a positive integer');
137
+ return;
138
+ }
139
+ if (!['executor', 'reviewer'].includes(values['--role'])) {
140
+ usageFailure('--role must be executor or reviewer');
141
+ return;
142
+ }
143
+ result = await awaitOrchestrationDelegationActivation(taskRef, {
144
+ stage: values['--stage'],
145
+ round,
146
+ artifact: values['--artifact'],
147
+ role: values['--role']
148
+ }, coreOptions);
153
149
  }
154
- else if (values['--remote'] !== undefined || values['--ref'] !== undefined) {
155
- usageFailure('committed checkpoint does not accept --remote or --ref');
156
- return;
157
- }
158
- result = checkpointCommitIntent(taskRef, {
159
- token: values['--token'], kind: values['--kind'],
160
- head: values['--head'], remote: values['--remote'], ref: values['--ref']
161
- }, coreOptions);
162
- }
163
- else if (intent === 'commit-complete') {
164
- const missing = requireValues(['--token', '--agent']);
165
- if (missing) {
166
- usageFailure(`intent 'commit-complete' requires '${missing}'`);
167
- return;
168
- }
169
- const agent = normalizeAgentToken(values['--agent']);
170
- if (!agent) {
171
- usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
172
- return;
173
- }
174
- result = completeCommitIntent(taskRef, { token: values['--token'], agent }, coreOptions);
175
- }
176
- else if (intent === 'commit-recover') {
177
- const missing = requireValues(['--agent']);
178
- if (missing) {
179
- usageFailure(`intent 'commit-recover' requires '${missing}'`);
180
- return;
181
- }
182
- const agent = normalizeAgentToken(values['--agent']);
183
- if (!agent) {
184
- usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
185
- return;
186
- }
187
- result = recoverCommitIntent(taskRef, { agent }, coreOptions);
188
- }
189
- else if (intent === 'commit-abort') {
190
- const missing = requireValues(['--token', '--expected-head']);
191
- if (missing) {
192
- usageFailure(`intent 'commit-abort' requires '${missing}'`);
193
- return;
194
- }
195
- result = abortCommitIntent(taskRef, { token: values['--token'], expectedHead: values['--expected-head'] }, coreOptions);
196
- }
197
- else if (intent === 'commit-terminate') {
198
- const missing = requireValues(['--attempt', '--agent', '--code']);
199
- if (missing) {
200
- usageFailure(`intent 'commit-terminate' requires '${missing}'`);
201
- return;
202
- }
203
- const agent = normalizeAgentToken(values['--agent']);
204
- if (!agent) {
205
- usageFailure(`invalid --agent '${values['--agent']}': ${AGENT_USAGE_HINT}`);
206
- return;
207
- }
208
- if (!/^[A-Z][A-Z0-9_]{2,63}$/.test(values['--code'])) {
209
- usageFailure('--code must be a stable uppercase identifier');
210
- return;
211
- }
212
- result = terminateCommitAttempt(taskRef, {
213
- attempt: values['--attempt'], agent, code: values['--code']
214
- }, coreOptions);
215
- }
216
- else if (intent === 'commit-status') {
217
- result = statusCommitIntent(taskRef, coreOptions);
218
- }
219
- else if (intent === 'begin-or-resume') {
220
- const missing = requireValues(['--client']);
221
- if (missing) {
222
- usageFailure(`intent 'begin-or-resume' requires '${missing}'`);
223
- return;
224
- }
225
- const maxSteps = values['--max-steps'] === undefined ? undefined : Number(values['--max-steps']);
226
- if (maxSteps !== undefined && (!Number.isInteger(maxSteps) || maxSteps < 1)) {
227
- usageFailure('--max-steps must be a positive integer');
228
- return;
229
- }
230
- const policyFlags = [
231
- '--executor-model', '--executor-reasoning-effort',
232
- '--reviewer-model', '--reviewer-reasoning-effort'
233
- ];
234
- const hasAnyPolicy = policyFlags.some((flag) => values[flag] !== undefined);
235
- if (hasAnyPolicy && policyFlags.some((flag) => values[flag] === undefined)) {
236
- usageFailure('explicit model policy requires executor/reviewer model and reasoning effort');
237
- return;
238
- }
239
- result = beginOrResumeOrchestration(taskRef, {
240
- ...coreOptions,
241
- maxSteps,
242
- client: values['--client'],
243
- modelPolicy: hasAnyPolicy ? {
244
- executor: {
245
- model: values['--executor-model'],
246
- reasoningEffort: values['--executor-reasoning-effort']
247
- },
248
- reviewer: {
249
- model: values['--reviewer-model'],
250
- reasoningEffort: values['--reviewer-reasoning-effort']
251
- }
252
- } : undefined
253
- });
254
- }
255
- else if (intent === 'route') {
256
- result = routeOrchestration(taskRef, coreOptions);
257
- }
258
- else if (intent === 'status') {
259
- result = statusOrchestration(taskRef, coreOptions);
260
- }
261
- else if (intent === 'prepare') {
262
- const missing = requireValues(['--client']);
263
- if (missing) {
264
- usageFailure(`intent 'prepare' requires '${missing}'`);
265
- return;
266
- }
267
- result = await prepareCodexOrchestrationDelegation(taskRef, {
268
- client: values['--client'],
269
- requestedModel: values['--requested-model'],
270
- requestedReasoningEffort: values['--requested-reasoning-effort'],
271
- capabilityToken: values['--capability-token']
272
- }, { orchestrationOptions: coreOptions });
273
- }
274
- else if (intent === 'dispatch') {
275
- result = dispatchOrchestrationDelegation(taskRef, coreOptions);
276
- }
277
- else if (intent === 'await-activation') {
278
- const missing = requireValues(['--stage', '--round', '--artifact', '--role']);
279
- if (missing) {
280
- usageFailure(`intent 'await-activation' requires '${missing}'`);
281
- return;
282
- }
283
- const round = Number(values['--round']);
284
- if (!Number.isSafeInteger(round) || round < 1) {
285
- usageFailure('--round must be a positive integer');
286
- return;
287
- }
288
- if (!['executor', 'reviewer'].includes(values['--role'])) {
289
- usageFailure('--role must be executor or reviewer');
290
- return;
291
- }
292
- result = await awaitOrchestrationDelegationActivation(taskRef, {
293
- stage: values['--stage'],
294
- round,
295
- artifact: values['--artifact'],
296
- role: values['--role']
297
- }, coreOptions);
298
- }
299
- else if (intent === 'recover-prepared') {
300
- result = recoverPreparedOrchestrationDelegation(taskRef, coreOptions);
301
- }
302
- else if (intent === 'hook-start') {
303
- const missing = requireValues([
304
- ...(taskRef === 'auto' ? ['--client'] : []),
305
- '--native-agent', '--child-id', '--parent-id'
306
- ]);
307
- if (missing) {
308
- usageFailure(`intent 'hook-start' requires '${missing}'`);
309
- return;
150
+ else if (intent === 'recover-prepared') {
151
+ result = recoverPreparedOrchestrationDelegation(taskRef, coreOptions);
310
152
  }
311
- const event = {
312
- nativeAgent: values['--native-agent'], childId: values['--child-id'],
313
- parentId: values['--parent-id'], spawnMode: values['--spawn-mode'],
314
- actualModel: values['--actual-model'],
315
- actualReasoningEffort: values['--actual-reasoning-effort'],
316
- modelFallbackReason: values['--model-fallback-reason'],
317
- reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
318
- };
319
- result = taskRef === 'auto'
320
- ? activateMatchingOrchestrationDelegation(values['--client'], event, coreOptions)
321
- : activateOrchestrationDelegation(taskRef, event, coreOptions);
322
- }
323
- else if (intent === 'hook-stop') {
324
- if (taskRef === 'auto') {
325
- const missing = requireValues(['--client', '--native-agent', '--child-id']);
153
+ else if (intent === 'hook-start') {
154
+ const missing = requireValues([
155
+ ...(taskRef === 'auto' ? ['--client'] : []),
156
+ '--native-agent', '--child-id', '--parent-id'
157
+ ]);
326
158
  if (missing) {
327
- usageFailure(`intent 'hook-stop' requires '${missing}'`);
159
+ usageFailure(`intent 'hook-start' requires '${missing}'`);
328
160
  return;
329
161
  }
330
- result = sealMatchingOrchestrationDelegation(values['--client'], {
162
+ const event = {
331
163
  nativeAgent: values['--native-agent'], childId: values['--child-id'],
164
+ parentId: values['--parent-id'], spawnMode: values['--spawn-mode'],
332
165
  actualModel: values['--actual-model'],
333
166
  actualReasoningEffort: values['--actual-reasoning-effort'],
334
167
  modelFallbackReason: values['--model-fallback-reason'],
335
168
  reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
336
- }, coreOptions);
169
+ };
170
+ result = taskRef === 'auto'
171
+ ? activateMatchingOrchestrationDelegation(values['--client'], event, coreOptions)
172
+ : activateOrchestrationDelegation(taskRef, event, coreOptions);
173
+ }
174
+ else if (intent === 'hook-stop') {
175
+ if (taskRef === 'auto') {
176
+ const missing = requireValues(['--client', '--native-agent', '--child-id']);
177
+ if (missing) {
178
+ usageFailure(`intent 'hook-stop' requires '${missing}'`);
179
+ return;
180
+ }
181
+ result = sealMatchingOrchestrationDelegation(values['--client'], {
182
+ nativeAgent: values['--native-agent'], childId: values['--child-id'],
183
+ actualModel: values['--actual-model'],
184
+ actualReasoningEffort: values['--actual-reasoning-effort'],
185
+ modelFallbackReason: values['--model-fallback-reason'],
186
+ reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
187
+ }, coreOptions);
188
+ }
189
+ else {
190
+ const missing = requireValues(['--child-id', '--exit-code', '--after-fingerprint']);
191
+ if (missing) {
192
+ usageFailure(`intent 'hook-stop' requires '${missing}'`);
193
+ return;
194
+ }
195
+ const exitCode = Number(values['--exit-code']);
196
+ if (!Number.isInteger(exitCode)) {
197
+ usageFailure('--exit-code must be an integer');
198
+ return;
199
+ }
200
+ result = sealOrchestrationDelegation(taskRef, {
201
+ childId: values['--child-id'], exitCode,
202
+ afterFingerprint: values['--after-fingerprint'],
203
+ changedPaths: values['--changed-paths'] ? values['--changed-paths'].split(',').filter(Boolean) : [],
204
+ actualModel: values['--actual-model'],
205
+ actualReasoningEffort: values['--actual-reasoning-effort'],
206
+ modelFallbackReason: values['--model-fallback-reason'],
207
+ reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
208
+ }, coreOptions);
209
+ }
210
+ }
211
+ else if (intent === 'advance') {
212
+ result = advanceOrchestration(taskRef, coreOptions);
337
213
  }
338
214
  else {
339
- const missing = requireValues(['--child-id', '--exit-code', '--after-fingerprint']);
215
+ const missing = requireValues(['--code', '--message', '--recoverable']);
340
216
  if (missing) {
341
- usageFailure(`intent 'hook-stop' requires '${missing}'`);
217
+ usageFailure(`intent 'pause' requires '${missing}'`);
342
218
  return;
343
219
  }
344
- const exitCode = Number(values['--exit-code']);
345
- if (!Number.isInteger(exitCode)) {
346
- usageFailure('--exit-code must be an integer');
220
+ if (!['true', 'false'].includes(values['--recoverable'])) {
221
+ usageFailure('--recoverable must be true or false');
347
222
  return;
348
223
  }
349
- result = sealOrchestrationDelegation(taskRef, {
350
- childId: values['--child-id'], exitCode,
351
- afterFingerprint: values['--after-fingerprint'],
352
- changedPaths: values['--changed-paths'] ? values['--changed-paths'].split(',').filter(Boolean) : [],
353
- actualModel: values['--actual-model'],
354
- actualReasoningEffort: values['--actual-reasoning-effort'],
355
- modelFallbackReason: values['--model-fallback-reason'],
356
- reasoningEffortFallbackReason: values['--reasoning-effort-fallback-reason']
357
- }, coreOptions);
358
- }
359
- }
360
- else if (intent === 'advance') {
361
- result = advanceOrchestration(taskRef, coreOptions);
362
- }
363
- else {
364
- const missing = requireValues(['--code', '--message', '--recoverable']);
365
- if (missing) {
366
- usageFailure(`intent 'pause' requires '${missing}'`);
367
- return;
368
- }
369
- if (!['true', 'false'].includes(values['--recoverable'])) {
370
- usageFailure('--recoverable must be true or false');
371
- return;
372
- }
373
- result = pauseOrchestration(taskRef, values['--code'], values['--message'], values['--recoverable'] === 'true', coreOptions);
224
+ result = pauseOrchestration(taskRef, values['--code'], values['--message'], values['--recoverable'] === 'true', coreOptions);
225
+ }
226
+ }
227
+ catch (error) {
228
+ if (!(error instanceof OrchestrationStateError))
229
+ throw error;
230
+ result = {
231
+ status: 'failed',
232
+ changed: false,
233
+ taskId: error.taskId,
234
+ run: null,
235
+ next: null,
236
+ error: { code: error.code, message: error.message }
237
+ };
374
238
  }
375
- process.stdout.write(`${JSON.stringify(result)}\n`);
239
+ const output = result;
240
+ process.stdout.write(`${JSON.stringify(output)}\n`);
376
241
  if (result.status === 'failed')
377
242
  process.exitCode = 1;
378
243
  }
@@ -8,6 +8,13 @@ import { resolvePlatformContext } from './context.js';
8
8
  import { createGitHubClient } from './github-client.js';
9
9
  import { listRemoteComments, normalizeCommentContent, writeComment } from './issue-comments.js';
10
10
  import { platformResult } from './types.js';
11
+ function warningResultForPrimary(primaryResult) {
12
+ if (primaryResult === 'pr_created')
13
+ return 'pr_created_with_warnings';
14
+ if (primaryResult === 'pr_reused')
15
+ return 'pr_reused_with_warnings';
16
+ return 'no_op_with_warnings';
17
+ }
11
18
  function summaryMarker(taskId) {
12
19
  return `<!-- sync-pr:${taskId}:summary -->`;
13
20
  }
@@ -51,40 +58,71 @@ function summaryContext(taskRef, options = {}) {
51
58
  return { ...platformResult('no-op'), task: { id: resolved.taskId, prNumber }, artifacts: canonicalArtifacts(resolved.taskDir) };
52
59
  }
53
60
  function syncPullRequestSummary(taskRef, options) {
61
+ const warningResult = warningResultForPrimary(options.primaryResult);
62
+ let knownPrNumber = null;
63
+ const softenFailure = (output) => {
64
+ const prNumber = output.resource.kind === 'pull-request' && output.resource.number
65
+ ? output.resource.number
66
+ : knownPrNumber;
67
+ const warning = output.error && prNumber
68
+ && output.error.code !== 'PR_NOT_LINKED'
69
+ ? {
70
+ code: output.error.code,
71
+ message: output.error.message,
72
+ retryable: output.error.retryable,
73
+ step: 'pr-summary',
74
+ target: `pull-request:${prNumber}`,
75
+ severity: 'ACTION_REQUIRED'
76
+ }
77
+ : null;
78
+ return warning
79
+ ? {
80
+ ...output,
81
+ status: 'applied',
82
+ changed: false,
83
+ resource: { kind: 'pull-request', number: prNumber },
84
+ error: null,
85
+ result: warningResult,
86
+ warnings: [warning]
87
+ }
88
+ : { ...output, result: null, warnings: [] };
89
+ };
54
90
  const resolved = resolveTaskRef(taskRef, options.cwd ? { repoRoot: options.cwd } : {});
55
91
  if (!resolved.ok)
56
- return platformResult('failed', { error: { code: resolved.code, message: resolved.message, retryable: false } });
92
+ return softenFailure(platformResult('failed', { error: { code: resolved.code, message: resolved.message, retryable: false } }));
57
93
  const frontmatter = parseTaskFrontmatter(fs.readFileSync(resolved.taskMdPath, 'utf8'));
58
94
  const prNumber = Number(frontmatter.pr_number);
59
95
  if (!Number.isInteger(prNumber) || prNumber <= 0)
60
- return platformResult('failed', { error: { code: 'PR_NOT_LINKED', message: 'Task has no valid pr_number', retryable: false } });
96
+ return softenFailure(platformResult('failed', { error: { code: 'PR_NOT_LINKED', message: 'Task has no valid pr_number', retryable: false } }));
97
+ knownPrNumber = prNumber;
61
98
  const client = options.client || createGitHubClient();
62
99
  const context = resolvePlatformContext({ cwd: resolved.repoRoot, client });
63
100
  if (!context.platform.repository || !['no-op', 'degraded'].includes(context.status))
64
- return context;
101
+ return softenFailure(context);
65
102
  let headSha;
66
103
  try {
67
104
  headSha = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: resolved.repoRoot, encoding: 'utf8' }).trim();
68
105
  }
69
106
  catch (error) {
70
- return platformResult('failed', { platform: context.platform, capabilities: context.capabilities, error: { code: 'GIT_HEAD_UNRESOLVED', message: error instanceof Error ? error.message : String(error), retryable: false } });
107
+ return softenFailure(platformResult('failed', { platform: context.platform, capabilities: context.capabilities, error: { code: 'GIT_HEAD_UNRESOLVED', message: error instanceof Error ? error.message : String(error), retryable: false } }));
71
108
  }
72
109
  const desired = buildPullRequestSummary(resolved.taskId, options.body, headSha, renderHumanOverrideAudit(fs.readFileSync(resolved.taskMdPath, 'utf8')));
73
110
  const listed = listRemoteComments(client, context.platform.repository, prNumber, resolved.repoRoot);
74
111
  if (!listed.ok)
75
- return platformResult(listed.error.retryable ? 'blocked' : 'failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: listed.error });
112
+ return softenFailure(platformResult(listed.error.retryable ? 'blocked' : 'failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: listed.error }));
76
113
  const reconciliation = reconcileSummaryComment(listed.value, resolved.taskId, desired);
77
114
  if (reconciliation.action === 'conflict')
78
- return platformResult('failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: { code: 'PR_SUMMARY_MARKER_AMBIGUOUS', message: 'Multiple PR comments contain the summary marker', retryable: false } });
115
+ return softenFailure(platformResult('failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: { code: 'PR_SUMMARY_MARKER_AMBIGUOUS', message: 'Multiple PR comments contain the summary marker', retryable: false } }));
79
116
  if (reconciliation.action === 'no-op')
80
- return platformResult('no-op', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, comment: { kind: 'summary', marker: summaryMarker(resolved.taskId), ids: [reconciliation.commentId], parts: 1 }, error: null });
117
+ return softenFailure(platformResult('no-op', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, comment: { kind: 'summary', marker: summaryMarker(resolved.taskId), ids: [reconciliation.commentId], parts: 1 }, error: null }));
81
118
  if (options.dryRun)
82
- return platformResult('planned', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, operations: [{ name: `summary:${reconciliation.action}`, status: 'planned', reasonCode: null }], error: null });
119
+ return softenFailure(platformResult('planned', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, operations: [{ name: `summary:${reconciliation.action}`, status: 'planned', reasonCode: null }], error: null }));
83
120
  const written = writeComment(client, context.platform.repository, prNumber, resolved.repoRoot, desired, reconciliation.commentId || undefined);
84
121
  if (!written.ok)
85
- return platformResult(written.error.retryable ? 'blocked' : 'failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: written.error });
122
+ return softenFailure(platformResult(written.error.retryable ? 'blocked' : 'failed', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, error: written.error }));
86
123
  const id = Number(written.value.id || reconciliation.commentId);
87
- return platformResult('applied', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, comment: { kind: 'summary', marker: summaryMarker(resolved.taskId), ids: Number.isInteger(id) ? [id] : [], parts: 1 }, operations: [{ name: `summary:${reconciliation.action}`, status: 'applied', reasonCode: null }], error: null });
124
+ return softenFailure(platformResult('applied', { platform: context.platform, capabilities: context.capabilities, resource: { kind: 'pull-request', number: prNumber }, comment: { kind: 'summary', marker: summaryMarker(resolved.taskId), ids: Number.isInteger(id) ? [id] : [], parts: 1 }, operations: [{ name: `summary:${reconciliation.action}`, status: 'applied', reasonCode: null }], error: null }));
88
125
  }
89
126
  export { buildPullRequestSummary, reconcileSummaryComment, summaryContext, summaryMarker, syncPullRequestSummary };
127
+ export { warningResultForPrimary };
90
128
  //# sourceMappingURL=pr-summary.js.map