@fitlab-ai/agent-infra 0.11.2 → 0.11.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/internal-cli.js +7 -2
- package/dist/lib/agent-clients/adapter.js +3 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +234 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +8 -35
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +1 -34
- package/dist/lib/agent-clients/adapters/codex.js +10 -0
- package/dist/lib/internal/manual-validation.js +22 -27
- package/dist/lib/internal/sandbox-control.js +1 -43
- package/dist/lib/internal/task-lifecycle.js +1 -1
- package/dist/lib/internal/task-operation-registry.js +6 -2
- package/dist/lib/platform/issue-comments.js +2 -31
- package/dist/lib/platform/pr-summary.js +7 -2
- package/dist/lib/sandbox/control/client.js +3 -44
- package/dist/lib/sandbox/control/executor.js +14 -79
- package/dist/lib/sandbox/control/finalization-response.js +3 -5
- package/dist/lib/sandbox/control/protocol.js +5 -64
- package/dist/lib/sandbox/control/server.js +29 -206
- package/dist/lib/sandbox/control/state.js +1 -7
- package/dist/lib/sandbox/control/task-view.js +1 -2
- package/dist/lib/task/control-authority.js +34 -36
- package/dist/lib/task/control-recovery.js +3 -42
- package/dist/lib/task/delegation-receipts.js +2 -2
- package/dist/lib/task/finalization-artifacts.js +1 -3
- package/dist/lib/task/finalization-state.js +1 -1
- package/dist/lib/task/finalization.js +53 -126
- package/dist/lib/task/lifecycle.js +1 -1
- package/dist/lib/task/manual-validation-receipt.js +8 -3
- package/dist/lib/task/orchestration.js +12 -6
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapter.ts +46 -0
- package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +297 -0
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +13 -33
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +1 -44
- package/lib/agent-clients/adapters/codex.ts +10 -0
- package/lib/internal/manual-validation.ts +22 -26
- package/lib/internal/sandbox-control.ts +0 -42
- package/lib/internal/task-lifecycle.ts +2 -2
- package/lib/internal/task-operation-registry.ts +7 -4
- package/lib/platform/issue-comments.ts +1 -35
- package/lib/platform/pr-summary.ts +10 -2
- package/lib/sandbox/control/client.ts +5 -68
- package/lib/sandbox/control/executor.ts +14 -81
- package/lib/sandbox/control/finalization-response.ts +3 -5
- package/lib/sandbox/control/protocol.ts +7 -83
- package/lib/sandbox/control/server.ts +30 -220
- package/lib/sandbox/control/state.ts +1 -9
- package/lib/sandbox/control/task-view.ts +1 -2
- package/lib/task/control-authority.ts +38 -47
- package/lib/task/control-recovery.ts +3 -43
- package/lib/task/delegation-receipts.ts +2 -2
- package/lib/task/finalization-artifacts.ts +1 -3
- package/lib/task/finalization-state.ts +1 -1
- package/lib/task/finalization.ts +57 -121
- package/lib/task/lifecycle.ts +2 -2
- package/lib/task/manual-validation-receipt.ts +8 -2
- package/lib/task/orchestration.ts +30 -19
- package/package.json +1 -1
- package/templates/.agents/rules/lifecycle-orchestration.en.md +19 -5
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +19 -5
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +2 -2
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/complete-task/SKILL.en.md +6 -7
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +6 -7
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +2 -2
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/run-task/SKILL.en.md +9 -8
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +9 -8
- package/dist/lib/sandbox/control/task-workflow.js +0 -74
- package/dist/lib/sandbox/control/workflow-executor.js +0 -142
- package/dist/lib/task/lifecycle-recovery.js +0 -549
- package/dist/lib/task/recovery-warning.js +0 -19
- package/dist/lib/task/workflow-command.js +0 -21
- package/dist/lib/task/workflow-dispatch.js +0 -213
- package/lib/sandbox/control/task-workflow.ts +0 -95
- package/lib/sandbox/control/workflow-executor.ts +0 -156
- package/lib/task/lifecycle-recovery.ts +0 -691
- package/lib/task/recovery-warning.ts +0 -21
- package/lib/task/workflow-command.ts +0 -22
- package/lib/task/workflow-dispatch.ts +0 -214
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { finalizationTerminalResponse } from './finalization-response.js';
|
|
2
|
-
import { isDeepStrictEqual } from 'node:util';
|
|
3
2
|
import { completedReentryView } from './completed-reentry.js';
|
|
4
3
|
import fs from 'node:fs';
|
|
5
4
|
import path from 'node:path';
|
|
@@ -13,10 +12,6 @@ import { validateSandboxControlRequest } from './protocol.js';
|
|
|
13
12
|
import { requestAuditFields, resultAuditFields, appendCriticalAudit, appendDiagnosticAudit, createSandboxControlAuditContext, writeSandboxControlTransition, readSandboxControlTransition } from './audit.js';
|
|
14
13
|
import { parseTaskControlOperation } from '../../task/control-authority.js';
|
|
15
14
|
import { parseControlOutput, classifySandboxControlRecovery, findSandboxControlRecoveryOperation, operationRecoveryBinding, SANDBOX_CONTROL_REQUIRED_COMPLETION_PHASES } from '../../task/control-recovery.js';
|
|
16
|
-
import { readRun } from '../../task/orchestration.js';
|
|
17
|
-
import { readLifecycleRecoveryDomainEvidence } from '../../task/lifecycle-recovery.js';
|
|
18
|
-
import { captureRepositorySnapshot } from '../../task/workspace-snapshot.js';
|
|
19
|
-
import { parseTypedTaskFrontmatter } from '../../task/frontmatter.js';
|
|
20
15
|
import { readLifecycleJournalEvidence } from '../../task/lifecycle.js';
|
|
21
16
|
import { resolveTaskRef } from '../../task/resolve-ref.js';
|
|
22
17
|
import { loadShortIdByTaskId } from '../../task/short-id.js';
|
|
@@ -28,94 +23,32 @@ import { readCodexControllerRegistration } from './controller-registration.js';
|
|
|
28
23
|
import { validateSandboxControlIdentity } from './identity-sentinel.js';
|
|
29
24
|
import { mergeSandboxTaskView, taskViewAfterFinalization, taskViewForManifest } from './task-view.js';
|
|
30
25
|
import { taskCreateOutputUnavailableResult } from '../../task/create-service.js';
|
|
31
|
-
import { consumeLifecycleRecoveryAttestation, issueLifecycleRecoveryAttestation, recoverLifecycleRecoveryOperation } from '../../task/control-authority.js';
|
|
32
|
-
import { createCodexCapabilityStore } from '../../agent-clients/adapters/codex-lifecycle/capability-store.js';
|
|
33
|
-
import { computeLifecycleBuildIdentity } from '../../agent-clients/adapters/codex-lifecycle/build-identity.js';
|
|
34
|
-
function consumeLifecycleAuthorityForResult(manifest, execution) {
|
|
35
|
-
const authority = execution.lifecycleAuthority?.attestation;
|
|
36
|
-
if (!authority || execution.result?.exitCode !== 0)
|
|
37
|
-
return true;
|
|
38
|
-
try {
|
|
39
|
-
consumeLifecycleRecoveryAttestation(authority);
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
appendBrokerAudit(manifest, 'lifecycle-authority-consume-retry', {
|
|
44
|
-
...requestAuditFields(manifest, execution.request),
|
|
45
|
-
errorCode: error instanceof Error ? error.name : 'LIFECYCLE_AUTHORITY_CONSUME_FAILED'
|
|
46
|
-
});
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function lifecycleAuthorityForRequest(manifest, manifestPath, request) {
|
|
51
|
-
const selector = request.family === 'task-workflow' || request.family === 'task-orchestration'
|
|
52
|
-
? request.authority
|
|
53
|
-
: undefined;
|
|
54
|
-
if (!selector)
|
|
55
|
-
return undefined;
|
|
56
|
-
let controllerBinding = null;
|
|
57
|
-
try {
|
|
58
|
-
const registration = readCodexControllerRegistration(manifestPath);
|
|
59
|
-
controllerBinding = {
|
|
60
|
-
instanceDigest: registration.controllerInstanceDigest,
|
|
61
|
-
controlGeneration: registration.controlGeneration
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
catch {
|
|
65
|
-
// The issuer reports the stable unavailable result; the broker never trusts
|
|
66
|
-
// a controller binding supplied by the request.
|
|
67
|
-
}
|
|
68
|
-
return issueLifecycleRecoveryAttestation(selector, {
|
|
69
|
-
controllerBinding,
|
|
70
|
-
capabilityStore: createCodexCapabilityStore(),
|
|
71
|
-
buildIdentity: computeLifecycleBuildIdentity(manifest.repoRoot)
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
26
|
function appendBrokerAudit(manifest, event, fields = {}) {
|
|
75
27
|
appendDiagnosticAudit(manifest, event, { source: 'broker', ...fields });
|
|
76
28
|
}
|
|
77
|
-
function operationKey(request
|
|
29
|
+
function operationKey(request) {
|
|
78
30
|
if (request.family === 'task-finalization')
|
|
79
31
|
return request.operation;
|
|
80
32
|
if (request.family === 'task-create')
|
|
81
33
|
return 'create';
|
|
82
34
|
if (request.family === 'codex-controller')
|
|
83
35
|
return request.command;
|
|
84
|
-
if (request.family
|
|
85
|
-
return request.workflow.operation;
|
|
86
|
-
if (request.family !== 'task-lifecycle' && request.family !== 'task-orchestration')
|
|
36
|
+
if (request.family !== 'task-lifecycle')
|
|
87
37
|
return null;
|
|
88
|
-
if (request.family === 'task-orchestration' && request.args[1] === 'route') {
|
|
89
|
-
if (!output)
|
|
90
|
-
return 'route';
|
|
91
|
-
const result = parseControlOutput(output);
|
|
92
|
-
return result?.changed === true && result.status === 'completed' ? 'route.clean-completion' : 'route.read';
|
|
93
|
-
}
|
|
94
38
|
try {
|
|
95
39
|
const operation = parseTaskControlOperation(request.family, request.args);
|
|
96
|
-
return operation.family === 'task-
|
|
40
|
+
return operation.family === 'task-lifecycle' ? operation.request.intent : null;
|
|
97
41
|
}
|
|
98
42
|
catch {
|
|
99
43
|
return null;
|
|
100
44
|
}
|
|
101
45
|
}
|
|
102
|
-
function recoveryOperationKey(request
|
|
103
|
-
|
|
104
|
-
if (operation !== 'route')
|
|
105
|
-
return operation;
|
|
106
|
-
const digest = terminalResult?.intentDigest;
|
|
107
|
-
for (const candidate of ['route.read', 'route.clean-completion']) {
|
|
108
|
-
const expected = operationRecoveryBinding(request.id, request.generation, null, request.family, candidate).intentDigest;
|
|
109
|
-
if (digest === expected)
|
|
110
|
-
return candidate;
|
|
111
|
-
}
|
|
112
|
-
return null;
|
|
46
|
+
function recoveryOperationKey(request) {
|
|
47
|
+
return operationKey(request);
|
|
113
48
|
}
|
|
114
49
|
function terminalResultMatchesRequest(request, terminalResult) {
|
|
115
50
|
const operation = operationKey(request);
|
|
116
|
-
const candidates = operation
|
|
117
|
-
? ['route.read', 'route.clean-completion']
|
|
118
|
-
: operation ? [operation] : [];
|
|
51
|
+
const candidates = operation ? [operation] : [];
|
|
119
52
|
return candidates.some((candidate) => createHash('sha256').update(`${request.family}\0${candidate}`, 'utf8').digest('hex') === terminalResult.intentDigest);
|
|
120
53
|
}
|
|
121
54
|
function criticalRequestPhase(manifest, request, phase, outcome, reference) {
|
|
@@ -257,7 +190,7 @@ function outputMatchesEvidence(output, bytes, sha256) {
|
|
|
257
190
|
return Buffer.byteLength(output, 'utf8') === bytes
|
|
258
191
|
&& createHash('sha256').update(output, 'utf8').digest('hex') === sha256;
|
|
259
192
|
}
|
|
260
|
-
export function genericRecoveryResponse(request, exitCode, payload, cause = 'recovery'
|
|
193
|
+
export function genericRecoveryResponse(request, exitCode, payload, cause = 'recovery') {
|
|
261
194
|
const outputUnavailable = request.family === 'task-create' && !payload;
|
|
262
195
|
return {
|
|
263
196
|
version: 2,
|
|
@@ -265,11 +198,9 @@ export function genericRecoveryResponse(request, exitCode, payload, cause = 'rec
|
|
|
265
198
|
phase: 'completed',
|
|
266
199
|
exitCode,
|
|
267
200
|
stdout: outputUnavailable ? `${JSON.stringify(taskCreateOutputUnavailableResult(request.id))}\n` : '',
|
|
268
|
-
stderr: payload ? '' :
|
|
269
|
-
?
|
|
270
|
-
:
|
|
271
|
-
? 'SANDBOX_CONTROL_OUTPUT_UNAVAILABLE: output payload was not retained\n'
|
|
272
|
-
: 'SANDBOX_CONTROL_OUTPUT_UNAVAILABLE: broker restarted after executor completion\n',
|
|
201
|
+
stderr: payload ? '' : cause === 'publish'
|
|
202
|
+
? 'SANDBOX_CONTROL_OUTPUT_UNAVAILABLE: output payload was not retained\n'
|
|
203
|
+
: 'SANDBOX_CONTROL_OUTPUT_UNAVAILABLE: broker restarted after executor completion\n',
|
|
273
204
|
error: null,
|
|
274
205
|
outputState: payload ? 'available' : 'unavailable',
|
|
275
206
|
payload: payload ? payloadReference(payload) : null
|
|
@@ -335,32 +266,10 @@ function controllerDomainEvidence(manifest, manifestPath, request, output) {
|
|
|
335
266
|
&& output?.status === 'closed' && typeof output.changed === 'boolean' };
|
|
336
267
|
}
|
|
337
268
|
}
|
|
338
|
-
function
|
|
339
|
-
if (!operation || !output)
|
|
340
|
-
return { consistent: false };
|
|
341
|
-
const outputRun = output.run && typeof output.run === 'object' && !Array.isArray(output.run)
|
|
342
|
-
? output.run : null;
|
|
343
|
-
const runMatches = outputRun === null ? run === null : run !== null && JSON.stringify(run) === JSON.stringify(outputRun);
|
|
344
|
-
if (operation.class === 'read-only') {
|
|
345
|
-
return {
|
|
346
|
-
consistent: output.status === terminalResult.status && output.changed === terminalResult.changed && runMatches,
|
|
347
|
-
snapshotValid: true,
|
|
348
|
-
status: run?.status ?? terminalResult.status,
|
|
349
|
-
pendingDelegation: run?.pendingDelegation ?? null
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
if (!run || !outputRun)
|
|
353
|
-
return { consistent: false };
|
|
354
|
-
return {
|
|
355
|
-
consistent: output.status === terminalResult.status && output.changed === terminalResult.changed && runMatches,
|
|
356
|
-
status: run.status,
|
|
357
|
-
pendingDelegation: run.pendingDelegation
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
function readRecoveryDomain(manifest, manifestPath, request, operation, terminalResult, payloadOutput) {
|
|
269
|
+
async function readRecoveryDomain(manifest, manifestPath, request, operation, terminalResult, payloadOutput) {
|
|
361
270
|
if (!operation)
|
|
362
271
|
return { domain: null };
|
|
363
|
-
const taskRef = request.family === 'task-finalization'
|
|
272
|
+
const taskRef = request.family === 'task-finalization'
|
|
364
273
|
? manifest.taskId
|
|
365
274
|
: 'args' in request ? request.args[0] ?? null : manifest.taskId;
|
|
366
275
|
const output = parseControlOutput(payloadOutput);
|
|
@@ -369,21 +278,7 @@ function readRecoveryDomain(manifest, manifestPath, request, operation, terminal
|
|
|
369
278
|
}
|
|
370
279
|
if (operation.family === 'task-lifecycle') {
|
|
371
280
|
if (operation.intent === 'recover-started') {
|
|
372
|
-
|
|
373
|
-
if (!('args' in request))
|
|
374
|
-
return { domain: null };
|
|
375
|
-
const parsed = parseTaskControlOperation('task-lifecycle', request.args);
|
|
376
|
-
if (parsed.family !== 'task-lifecycle' || parsed.request.intent !== 'recover-started') {
|
|
377
|
-
return { domain: null };
|
|
378
|
-
}
|
|
379
|
-
return {
|
|
380
|
-
domain: readLifecycleRecoveryDomainEvidence(manifest.repoRoot, parsed.request, terminalResult),
|
|
381
|
-
journal: readLifecycleJournalEvidence(manifest.repoRoot, taskRef)
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
catch {
|
|
385
|
-
return { domain: null };
|
|
386
|
-
}
|
|
281
|
+
return { domain: null };
|
|
387
282
|
}
|
|
388
283
|
if (!taskRef || !terminalResult.targetState)
|
|
389
284
|
return { domain: null };
|
|
@@ -403,51 +298,12 @@ function readRecoveryDomain(manifest, manifestPath, request, operation, terminal
|
|
|
403
298
|
return { domain: { consistent: false }, journal };
|
|
404
299
|
}
|
|
405
300
|
}
|
|
406
|
-
if (operation.family === 'task-orchestration') {
|
|
407
|
-
if (!taskRef)
|
|
408
|
-
return { domain: null };
|
|
409
|
-
try {
|
|
410
|
-
const resolved = resolveTaskRef(taskRef, { repoRoot: manifest.repoRoot });
|
|
411
|
-
if (!resolved.ok)
|
|
412
|
-
return { domain: { consistent: false } };
|
|
413
|
-
const run = readRun(resolved.taskDir);
|
|
414
|
-
if (!run && operation.class !== 'read-only')
|
|
415
|
-
return { domain: { consistent: false } };
|
|
416
|
-
if (operation.class === 'route.clean-completion') {
|
|
417
|
-
const snapshot = captureRepositorySnapshot(manifest.repoRoot);
|
|
418
|
-
const metadata = parseTypedTaskFrontmatter(fs.readFileSync(resolved.taskMdPath, 'utf8'));
|
|
419
|
-
const completion = run?.completionEvidence ?? null;
|
|
420
|
-
const consistent = run !== null && completion !== null
|
|
421
|
-
&& terminalResult.completionEvidence !== null
|
|
422
|
-
&& isDeepStrictEqual(completion, terminalResult.completionEvidence);
|
|
423
|
-
return {
|
|
424
|
-
domain: {
|
|
425
|
-
consistent,
|
|
426
|
-
status: run?.status ?? null,
|
|
427
|
-
pendingDelegation: run?.pendingDelegation ?? null,
|
|
428
|
-
completionEvidence: completion,
|
|
429
|
-
snapshot,
|
|
430
|
-
lastReviewedCommit: metadata.last_reviewed_commit
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
}
|
|
434
|
-
return { domain: orchestrationDomainEvidence(operation, terminalResult, output, run) };
|
|
435
|
-
}
|
|
436
|
-
catch {
|
|
437
|
-
return { domain: { consistent: false } };
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
301
|
if (operation.family === 'task-create') {
|
|
441
302
|
return { domain: taskCreateDomainEvidence(manifest, output) };
|
|
442
303
|
}
|
|
443
304
|
if (operation.family === 'codex-controller') {
|
|
444
305
|
return { domain: controllerDomainEvidence(manifest, manifestPath, request, output) };
|
|
445
306
|
}
|
|
446
|
-
if (operation.family === 'task-workflow') {
|
|
447
|
-
return {
|
|
448
|
-
domain: { consistent: output?.status === terminalResult.status && output.changed === terminalResult.changed, snapshotValid: true }
|
|
449
|
-
};
|
|
450
|
-
}
|
|
451
307
|
return { domain: null };
|
|
452
308
|
}
|
|
453
309
|
function readCommittedCriticalPhases(manifest, requestId) {
|
|
@@ -461,8 +317,8 @@ function readCommittedCriticalPhases(manifest, requestId) {
|
|
|
461
317
|
}
|
|
462
318
|
});
|
|
463
319
|
}
|
|
464
|
-
export function recoveryResponse(manifest, manifestPath, request, evidence, payload, terminalResult) {
|
|
465
|
-
const operationName = recoveryOperationKey(request
|
|
320
|
+
export async function recoveryResponse(manifest, manifestPath, request, evidence, payload, terminalResult) {
|
|
321
|
+
const operationName = recoveryOperationKey(request);
|
|
466
322
|
const operation = operationName ? findSandboxControlRecoveryOperation(request.family, operationName) : null;
|
|
467
323
|
if (!operation)
|
|
468
324
|
return null;
|
|
@@ -476,32 +332,9 @@ export function recoveryResponse(manifest, manifestPath, request, evidence, payl
|
|
|
476
332
|
const finalization = request.family === 'task-finalization' ? finalizationRecoveryResponse(manifest, request.id, 0) : null;
|
|
477
333
|
if (evidence.exitCode === 0 && finalization?.status === 'deferred')
|
|
478
334
|
return null;
|
|
479
|
-
if (evidence.exitCode === 0 && request.family === 'task-workflow' && request.authority?.phase === 'task-event.completed') {
|
|
480
|
-
try {
|
|
481
|
-
const registration = readCodexControllerRegistration(manifestPath);
|
|
482
|
-
const recovered = recoverLifecycleRecoveryOperation(request.authority, {
|
|
483
|
-
repoRoot: manifest.repoRoot,
|
|
484
|
-
capabilityStore: createCodexCapabilityStore(),
|
|
485
|
-
buildIdentity: computeLifecycleBuildIdentity(manifest.repoRoot),
|
|
486
|
-
controllerBinding: {
|
|
487
|
-
instanceDigest: registration.controllerInstanceDigest,
|
|
488
|
-
controlGeneration: registration.controlGeneration
|
|
489
|
-
}
|
|
490
|
-
});
|
|
491
|
-
if (recovered.status !== 'committed')
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
catch (error) {
|
|
495
|
-
appendBrokerAudit(manifest, 'lifecycle-authority-recovery-failed', {
|
|
496
|
-
...requestAuditFields(manifest, request),
|
|
497
|
-
errorCode: error instanceof Error ? error.name : 'LIFECYCLE_AUTHORITY_RECOVERY_FAILED'
|
|
498
|
-
});
|
|
499
|
-
return null;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
335
|
const recovery = finalization
|
|
503
336
|
? { domain: { consistent: finalization.status === 'matched' } }
|
|
504
|
-
: readRecoveryDomain(manifest, manifestPath, request, operation, terminalResult, payload?.stdout ?? null);
|
|
337
|
+
: await readRecoveryDomain(manifest, manifestPath, request, operation, terminalResult, payload?.stdout ?? null);
|
|
505
338
|
const binding = operationRecoveryBinding(request.id, manifest.generation, manifest.taskId, request.family, operationName);
|
|
506
339
|
const decision = classifySandboxControlRecovery({
|
|
507
340
|
operation,
|
|
@@ -523,13 +356,13 @@ export function recoveryResponse(manifest, manifestPath, request, evidence, payl
|
|
|
523
356
|
return null;
|
|
524
357
|
return finalization.response ?? null;
|
|
525
358
|
}
|
|
526
|
-
return genericRecoveryResponse(request, evidence.exitCode, payload
|
|
359
|
+
return genericRecoveryResponse(request, evidence.exitCode, payload);
|
|
527
360
|
}
|
|
528
|
-
function terminalMatchesEvidence(manifest, manifestPath, request, response, evidence, payload, payloadInvalid, terminalResult) {
|
|
361
|
+
async function terminalMatchesEvidence(manifest, manifestPath, request, response, evidence, payload, payloadInvalid, terminalResult) {
|
|
529
362
|
if (request.family === 'task-finalization' && evidence.exitCode === 0) {
|
|
530
363
|
if (!terminalResult)
|
|
531
364
|
return { valid: false, payloadReferenced: false };
|
|
532
|
-
const expected = recoveryResponse(manifest, manifestPath, request, evidence, payload, terminalResult);
|
|
365
|
+
const expected = await recoveryResponse(manifest, manifestPath, request, evidence, payload, terminalResult);
|
|
533
366
|
return {
|
|
534
367
|
valid: expected !== null && JSON.stringify(response) === JSON.stringify(expected),
|
|
535
368
|
payloadReferenced: false
|
|
@@ -558,7 +391,7 @@ function terminalMatchesEvidence(manifest, manifestPath, request, response, evid
|
|
|
558
391
|
if (response.outputState === 'unavailable') {
|
|
559
392
|
const causes = ['recovery', 'publish'];
|
|
560
393
|
const valid = causes.some((cause) => JSON.stringify(response)
|
|
561
|
-
=== JSON.stringify(genericRecoveryResponse(request, evidence.exitCode, null, cause
|
|
394
|
+
=== JSON.stringify(genericRecoveryResponse(request, evidence.exitCode, null, cause)));
|
|
562
395
|
return { valid, payloadReferenced: false };
|
|
563
396
|
}
|
|
564
397
|
return {
|
|
@@ -573,7 +406,7 @@ function publishExecutionResult(manifest, request, result, broker, brokerOwns) {
|
|
|
573
406
|
const terminalResult = writeSandboxControlTerminalResult(manifest, {
|
|
574
407
|
id: request.id,
|
|
575
408
|
family: request.family,
|
|
576
|
-
operation: operationKey(request
|
|
409
|
+
operation: operationKey(request)
|
|
577
410
|
}, normalized.stdout);
|
|
578
411
|
if (fs.existsSync(path.join(manifest.processingDir, request.id, 'transitions'))) {
|
|
579
412
|
criticalRequestPhase(manifest, request, 'completed', normalized.exitCode === 0 ? 'success' : 'failure');
|
|
@@ -610,7 +443,7 @@ function publishExecutionResult(manifest, request, result, broker, brokerOwns) {
|
|
|
610
443
|
catch {
|
|
611
444
|
payload = null;
|
|
612
445
|
}
|
|
613
|
-
terminal = genericRecoveryResponse(request, normalized.exitCode, payload, 'publish'
|
|
446
|
+
terminal = genericRecoveryResponse(request, normalized.exitCode, payload, 'publish');
|
|
614
447
|
}
|
|
615
448
|
}
|
|
616
449
|
if (!brokerOwns())
|
|
@@ -697,7 +530,7 @@ function assertCurrentSandboxControlIdentity(manifest, manifestPath) {
|
|
|
697
530
|
throw new Error(`SANDBOX_CONTROL_IDENTITY_${result.state.replaceAll('-', '_').toUpperCase()}`);
|
|
698
531
|
}
|
|
699
532
|
}
|
|
700
|
-
function recoverProcessing(manifest, manifestPath, broker, brokerOwns) {
|
|
533
|
+
async function recoverProcessing(manifest, manifestPath, broker, brokerOwns) {
|
|
701
534
|
for (const entry of fs.readdirSync(manifest.processingDir, { withFileTypes: true })) {
|
|
702
535
|
if (!entry.isDirectory() || !/^[a-f0-9-]{16,64}$/.test(entry.name))
|
|
703
536
|
continue;
|
|
@@ -819,7 +652,7 @@ function recoverProcessing(manifest, manifestPath, broker, brokerOwns) {
|
|
|
819
652
|
if (terminal && request && resultEvidence) {
|
|
820
653
|
if (!terminalResult && request.family !== 'task-create')
|
|
821
654
|
continue;
|
|
822
|
-
const reconciliation = terminalMatchesEvidence(manifest, manifestPath, request, existingTerminalResponse, resultEvidence, payload, payloadInvalid, terminalResult);
|
|
655
|
+
const reconciliation = await terminalMatchesEvidence(manifest, manifestPath, request, existingTerminalResponse, resultEvidence, payload, payloadInvalid, terminalResult);
|
|
823
656
|
if (!reconciliation.valid)
|
|
824
657
|
continue;
|
|
825
658
|
terminalReconciled = true;
|
|
@@ -852,7 +685,7 @@ function recoverProcessing(manifest, manifestPath, broker, brokerOwns) {
|
|
|
852
685
|
return false;
|
|
853
686
|
if (!resultEvidence || !request || payloadInvalid)
|
|
854
687
|
continue;
|
|
855
|
-
const recovered = recoveryResponse(manifest, manifestPath, request, resultEvidence, payload, terminalResult);
|
|
688
|
+
const recovered = await recoveryResponse(manifest, manifestPath, request, resultEvidence, payload, terminalResult);
|
|
856
689
|
if (!recovered)
|
|
857
690
|
continue;
|
|
858
691
|
if (request.family === 'task-finalization' && resultEvidence.exitCode === 0) {
|
|
@@ -1008,7 +841,7 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
1008
841
|
pid: broker.pid,
|
|
1009
842
|
brokerId: broker.brokerId
|
|
1010
843
|
});
|
|
1011
|
-
if (!recoverProcessing(manifest, manifestPath, broker, brokerOwns))
|
|
844
|
+
if (!await recoverProcessing(manifest, manifestPath, broker, brokerOwns))
|
|
1012
845
|
return;
|
|
1013
846
|
try {
|
|
1014
847
|
const published = readSandboxControlStatus(manifest.publicStatusDir);
|
|
@@ -1150,10 +983,6 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
1150
983
|
break;
|
|
1151
984
|
let terminalCommitted = false;
|
|
1152
985
|
if (settledExecution.result && settledExecution.resultEvidenceWritten) {
|
|
1153
|
-
if (!consumeLifecycleAuthorityForResult(manifest, settledExecution)) {
|
|
1154
|
-
active = settledExecution;
|
|
1155
|
-
continue;
|
|
1156
|
-
}
|
|
1157
986
|
terminalCommitted = publishExecutionResult(manifest, settledExecution.request, settledExecution.result, broker, brokerOwns);
|
|
1158
987
|
if (terminalCommitted && settledExecution.request.family === 'task-finalization') {
|
|
1159
988
|
try {
|
|
@@ -1247,14 +1076,9 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
1247
1076
|
executorCwd: manifest.repoRoot,
|
|
1248
1077
|
executorEntry: options.internalCliPath ?? process.argv[1] ?? null
|
|
1249
1078
|
});
|
|
1250
|
-
const lifecycleAuthority = lifecycleAuthorityForRequest(manifest, manifestPath, request);
|
|
1251
|
-
if (lifecycleAuthority?.status === 'rejected') {
|
|
1252
|
-
throw Object.assign(new Error(lifecycleAuthority.error?.message ?? 'lifecycle authority was rejected'), { code: lifecycleAuthority.error?.code ?? 'LIFECYCLE_AUTHORITY_REJECTED' });
|
|
1253
|
-
}
|
|
1254
1079
|
prepared = await prepareExecution({
|
|
1255
1080
|
manifest, manifestPath, request, requestPath: claimed,
|
|
1256
|
-
internalCliPath: options.internalCliPath ?? process.argv[1]
|
|
1257
|
-
...(lifecycleAuthority ? { lifecycleAuthority } : {})
|
|
1081
|
+
internalCliPath: options.internalCliPath ?? process.argv[1]
|
|
1258
1082
|
});
|
|
1259
1083
|
const preparedExecution = prepared;
|
|
1260
1084
|
if (!preparedExecution)
|
|
@@ -1270,7 +1094,7 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
1270
1094
|
executionPath: executionPath(manifest, request.id)
|
|
1271
1095
|
});
|
|
1272
1096
|
const execution = {
|
|
1273
|
-
request, prepared: preparedExecution,
|
|
1097
|
+
request, prepared: preparedExecution, result: null,
|
|
1274
1098
|
resultEvidenceWritten: false, failure: null, settled: false
|
|
1275
1099
|
};
|
|
1276
1100
|
active = execution;
|
|
@@ -1431,8 +1255,7 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
1431
1255
|
}
|
|
1432
1256
|
}
|
|
1433
1257
|
if (owned && active.result && active.resultEvidenceWritten) {
|
|
1434
|
-
if (
|
|
1435
|
-
&& publishExecutionResult(manifest, active.request, active.result, broker, brokerOwns)) {
|
|
1258
|
+
if (publishExecutionResult(manifest, active.request, active.result, broker, brokerOwns)) {
|
|
1436
1259
|
if (brokerOwns()) {
|
|
1437
1260
|
removeAcceptedResponse(manifest, active.request.id);
|
|
1438
1261
|
fs.rmSync(path.join(manifest.processingDir, active.request.id), { recursive: true, force: true });
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isCompletionEvidence } from '../../task/orchestration.js';
|
|
2
2
|
import { parseControlOutput } from '../../task/control-recovery.js';
|
|
3
|
-
import { isRecoveryWarning } from '../../task/recovery-warning.js';
|
|
4
3
|
import { execFileSync } from 'node:child_process';
|
|
5
4
|
import fs from 'node:fs';
|
|
6
5
|
import path from 'node:path';
|
|
@@ -84,7 +83,6 @@ export function createSandboxControlTerminalResult(manifest, request, output) {
|
|
|
84
83
|
? nested.run : null;
|
|
85
84
|
const rawCompletion = nested.completionEvidence ?? run?.completionEvidence;
|
|
86
85
|
const operation = request.operation ?? (typeof nested.intent === 'string' ? nested.intent : null) ?? '';
|
|
87
|
-
const warning = isRecoveryWarning(nested.warning) ? nested.warning : null;
|
|
88
86
|
return {
|
|
89
87
|
version: 1,
|
|
90
88
|
requestId: request.id,
|
|
@@ -94,8 +92,7 @@ export function createSandboxControlTerminalResult(manifest, request, output) {
|
|
|
94
92
|
targetState: typeof nested.targetState === 'string' ? nested.targetState : null,
|
|
95
93
|
status: typeof nested.status === 'string' ? nested.status : 'completed',
|
|
96
94
|
changed: typeof nested.changed === 'boolean' ? nested.changed : null,
|
|
97
|
-
completionEvidence: isCompletionEvidence(rawCompletion) ? rawCompletion : null
|
|
98
|
-
...(warning ? { warning } : {})
|
|
95
|
+
completionEvidence: isCompletionEvidence(rawCompletion) ? rawCompletion : null
|
|
99
96
|
};
|
|
100
97
|
}
|
|
101
98
|
export function writeSandboxControlTerminalResult(manifest, request, output) {
|
|
@@ -126,9 +123,6 @@ export function readSandboxControlTerminalResult(filePath) {
|
|
|
126
123
|
if (value.completionEvidence !== null && !isCompletionEvidence(value.completionEvidence)) {
|
|
127
124
|
throw new Error('SANDBOX_CONTROL_TERMINAL_RESULT_INVALID');
|
|
128
125
|
}
|
|
129
|
-
if (value.warning !== undefined && value.warning !== null && !isRecoveryWarning(value.warning)) {
|
|
130
|
-
throw new Error('SANDBOX_CONTROL_TERMINAL_RESULT_INVALID');
|
|
131
|
-
}
|
|
132
126
|
if (value.changed === undefined) {
|
|
133
127
|
throw new Error('SANDBOX_CONTROL_TERMINAL_RESULT_INVALID');
|
|
134
128
|
}
|
|
@@ -13,11 +13,10 @@ function receiptIdentity(value, generation, requestId) {
|
|
|
13
13
|
if (!binding || typeof binding !== 'object' || Array.isArray(binding))
|
|
14
14
|
return null;
|
|
15
15
|
const controlBinding = binding;
|
|
16
|
-
if (receipt.version !==
|
|
16
|
+
if (receipt.version !== 4 || typeof receipt.receiptId !== 'string' || receipt.receiptId.length === 0
|
|
17
17
|
|| !Number.isSafeInteger(receipt.revision) || receipt.revision < 0
|
|
18
18
|
|| receipt.lifecycle !== 'done'
|
|
19
19
|
|| !['pending', 'done', 'skipped'].includes(String(receipt.summary))
|
|
20
|
-
|| !['pending', 'done', 'skipped'].includes(String(receipt.postSummaryVerification))
|
|
21
20
|
|| controlBinding.generation !== generation
|
|
22
21
|
|| typeof controlBinding.requestId !== 'string'
|
|
23
22
|
|| !/^[a-f0-9-]{16,64}$/u.test(controlBinding.requestId)
|
|
@@ -3,12 +3,11 @@ import crypto from 'node:crypto';
|
|
|
3
3
|
import fs from 'node:fs';
|
|
4
4
|
import { normalizeAgentToken } from '../agent-clients/tokens.js';
|
|
5
5
|
import { isAgentClientId } from '../agent-clients/types.js';
|
|
6
|
+
import { getAgentClientAdapter } from '../agent-clients/registry.js';
|
|
6
7
|
import { consumeHumanOverride, failureId, overrideDryRunConflict } from './human-override.js';
|
|
7
8
|
import { activateMatchingOrchestrationDelegation, activateOrchestrationDelegation, advanceOrchestration, awaitOrchestrationDelegationActivation, beginOrResumeOrchestration, dispatchOrchestrationDelegation, OrchestrationStateError, pauseOrchestration, prepareOrchestrationDelegation, recoverPreparedOrchestrationDelegation, routeOrchestration, sealMatchingOrchestrationDelegation, sealOrchestrationDelegation, statusOrchestration } from './orchestration.js';
|
|
8
|
-
import { prepareCodexOrchestrationDelegation } from './codex-orchestration.js';
|
|
9
9
|
import { applyTaskFinalization } from './finalization.js';
|
|
10
10
|
import { applyTaskLifecycle, taskLifecycleFailure } from './lifecycle.js';
|
|
11
|
-
import { recoverStartedLifecycleUnderLock, recoveryFailure } from './lifecycle-recovery.js';
|
|
12
11
|
import { locateActivityLog } from './activity-log.js';
|
|
13
12
|
import { resolveTaskRef, TASK_ID_RE } from './resolve-ref.js';
|
|
14
13
|
import { TaskExecutionLockError, withTaskExecutionLock } from './task-execution-lock.js';
|
|
@@ -407,7 +406,6 @@ export function createSandboxExecutorExecutionContext(params) {
|
|
|
407
406
|
generation: params.generation,
|
|
408
407
|
manifestPath: absolute('manifestPath', params.manifestPath),
|
|
409
408
|
requestId: params.requestId,
|
|
410
|
-
...(params.diagnosticLog === undefined ? {} : { diagnosticLog: params.diagnosticLog }),
|
|
411
409
|
...(params.controllerBinding === undefined ? {} : { controllerBinding: binding(params.controllerBinding) }),
|
|
412
410
|
...(params.lifecycleRecoveryAttestation === undefined ? {} : {
|
|
413
411
|
lifecycleRecoveryAttestation: params.lifecycleRecoveryAttestation === null
|
|
@@ -450,11 +448,7 @@ function operationTaskId(context, taskRef) {
|
|
|
450
448
|
function domainOptions(context, options) {
|
|
451
449
|
return {
|
|
452
450
|
...options,
|
|
453
|
-
repoRoot: context.repoRoot
|
|
454
|
-
...(context.source === 'sandbox-executor' && context.diagnosticLog !== undefined
|
|
455
|
-
? { diagnosticLog: context.diagnosticLog }
|
|
456
|
-
: {}),
|
|
457
|
-
...(context.source === 'sandbox-executor' ? { gitWorktreeRoot: context.worktreeRoot } : {})
|
|
451
|
+
repoRoot: context.repoRoot
|
|
458
452
|
};
|
|
459
453
|
}
|
|
460
454
|
function lifecycleTaskId(request, repoRoot) {
|
|
@@ -475,7 +469,17 @@ async function applyLifecycleWithAuthority(context, request) {
|
|
|
475
469
|
}
|
|
476
470
|
const execute = async () => {
|
|
477
471
|
if (request.intent === 'recover-started') {
|
|
478
|
-
|
|
472
|
+
const adapter = isAgentClientId(request.agent)
|
|
473
|
+
? getAgentClientAdapter(request.agent).orchestrationAdapter
|
|
474
|
+
: undefined;
|
|
475
|
+
if (!adapter?.recoverStarted) {
|
|
476
|
+
return {
|
|
477
|
+
status: 'no-op', changed: false, targetState: 'active',
|
|
478
|
+
requestRef: request.taskRef, intent: 'recover-started', taskId: null,
|
|
479
|
+
receiptId: null, childId: null, error: null
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
return adapter.recoverStarted(request, { repoRoot: context.repoRoot });
|
|
479
483
|
}
|
|
480
484
|
const lifecycleResult = applyTaskLifecycle(request, { repoRoot: context.repoRoot });
|
|
481
485
|
if (lifecycleResult.status !== 'failed' || !request.overrideTicket)
|
|
@@ -511,7 +515,12 @@ async function applyLifecycleWithAuthority(context, request) {
|
|
|
511
515
|
if (!(error instanceof TaskExecutionLockError))
|
|
512
516
|
throw error;
|
|
513
517
|
if (request.intent === 'recover-started') {
|
|
514
|
-
return
|
|
518
|
+
return {
|
|
519
|
+
status: 'owner-unknown', changed: false, targetState: 'active',
|
|
520
|
+
requestRef: request.taskRef, intent: 'recover-started', taskId,
|
|
521
|
+
receiptId: null, childId: null,
|
|
522
|
+
error: { code: error.code, message: error.message }
|
|
523
|
+
};
|
|
515
524
|
}
|
|
516
525
|
return taskLifecycleFailure(request, { code: error.code, message: error.message }, taskId);
|
|
517
526
|
}
|
|
@@ -536,8 +545,10 @@ function orchestration(context, operation) {
|
|
|
536
545
|
requestedModel: input.requestedModel,
|
|
537
546
|
requestedReasoningEffort: input.requestedReasoningEffort,
|
|
538
547
|
};
|
|
539
|
-
|
|
540
|
-
|
|
548
|
+
const prepareDelegation = getAgentClientAdapter(prepareInput.client)
|
|
549
|
+
.orchestrationAdapter?.prepareDelegation;
|
|
550
|
+
if (prepareDelegation) {
|
|
551
|
+
return prepareDelegation(operation.taskRef, prepareInput, {
|
|
541
552
|
repoRoot: context.repoRoot,
|
|
542
553
|
orchestrationOptions: options,
|
|
543
554
|
});
|
|
@@ -617,7 +628,7 @@ function operationInvalid(message) {
|
|
|
617
628
|
}
|
|
618
629
|
const LIFECYCLE_FLAGS = new Set([
|
|
619
630
|
'--agent', '--reason', '--unblock-condition', '--note', '--alert-number', '--staging-dir', '--issue-number',
|
|
620
|
-
'--
|
|
631
|
+
'--auto', '--override-ticket', '--override-target', '--override-scope', '--dry-run'
|
|
621
632
|
]);
|
|
622
633
|
const FINALIZATION_FLAGS = new Set(['--agent']);
|
|
623
634
|
const ORCHESTRATION_FLAGS = new Set([
|
|
@@ -626,13 +637,13 @@ const ORCHESTRATION_FLAGS = new Set([
|
|
|
626
637
|
'--parent-id', '--before-fingerprint', '--stage', '--round', '--artifact', '--role',
|
|
627
638
|
'--native-agent', '--child-id', '--spawn-mode', '--actual-model', '--actual-reasoning-effort',
|
|
628
639
|
'--model-fallback-reason', '--reasoning-effort-fallback-reason', '--exit-code', '--after-fingerprint',
|
|
629
|
-
'--changed-paths', '--code', '--message', '--recoverable'
|
|
640
|
+
'--changed-paths', '--code', '--message', '--recoverable'
|
|
630
641
|
]);
|
|
631
642
|
function parseValues(args, start, flags) {
|
|
632
643
|
const values = {};
|
|
633
644
|
for (let index = start; index < args.length; index += 1) {
|
|
634
645
|
const flag = args[index];
|
|
635
|
-
if (flag === '--dry-run') {
|
|
646
|
+
if (flag === '--dry-run' || flag === '--auto') {
|
|
636
647
|
if (!flags.has(flag))
|
|
637
648
|
operationInvalid(`unknown option '${flag}'`);
|
|
638
649
|
if (values[flag] !== undefined)
|
|
@@ -693,31 +704,21 @@ export function parseTaskControlOperation(family, args) {
|
|
|
693
704
|
...(value(values, '--override-scope') ? { overrideScope: value(values, '--override-scope') } : {}),
|
|
694
705
|
...(value(values, '--alert-number') ? { alertNumber: Number(value(values, '--alert-number')) } : {}),
|
|
695
706
|
...(value(values, '--issue-number') ? { issueNumber: Number(value(values, '--issue-number')) } : {}),
|
|
696
|
-
...(
|
|
697
|
-
...(value(values, '--round') ? { round: Number(value(values, '--round')) } : {}),
|
|
698
|
-
...(value(values, '--artifact') ? { artifact: value(values, '--artifact') } : {}),
|
|
707
|
+
...(values['--auto'] === true ? { auto: true } : {}),
|
|
699
708
|
...(values['--dry-run'] === true ? { dryRun: true } : {})
|
|
700
709
|
};
|
|
701
710
|
if (intent === 'recover-started') {
|
|
702
|
-
const recoveryFlags = new Set(['--agent', '--
|
|
711
|
+
const recoveryFlags = new Set(['--agent', '--auto']);
|
|
703
712
|
for (const flag of Object.keys(values)) {
|
|
704
713
|
if (!recoveryFlags.has(flag))
|
|
705
714
|
operationInvalid(`option '${flag}' is not supported for recover-started`);
|
|
706
715
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
operationInvalid('--stage must be a supported lifecycle stage');
|
|
711
|
-
}
|
|
712
|
-
const round = Number(value(values, '--round'));
|
|
713
|
-
if (!Number.isSafeInteger(round) || round < 1)
|
|
714
|
-
operationInvalid('--round must be a positive integer');
|
|
715
|
-
if (value(values, '--reason').includes('\n') || value(values, '--reason').includes('\r')) {
|
|
716
|
-
operationInvalid('--reason must be a single line');
|
|
717
|
-
}
|
|
716
|
+
if (values['--auto'] !== true)
|
|
717
|
+
operationInvalid('--auto is required for recover-started');
|
|
718
|
+
return { family, request: input };
|
|
718
719
|
}
|
|
719
|
-
else if (values['--
|
|
720
|
-
operationInvalid('--
|
|
720
|
+
else if (values['--auto'] !== undefined) {
|
|
721
|
+
operationInvalid('--auto is only supported for recover-started');
|
|
721
722
|
}
|
|
722
723
|
return { family, request: input };
|
|
723
724
|
}
|
|
@@ -820,9 +821,6 @@ export function parseTaskControlOperation(family, args) {
|
|
|
820
821
|
input.message = value(values, '--message');
|
|
821
822
|
input.recoverable = recoverable === 'true';
|
|
822
823
|
}
|
|
823
|
-
|
|
824
|
-
? undefined
|
|
825
|
-
: { gitWorktreeRoot: value(values, '--git-worktree-root') };
|
|
826
|
-
return { family, taskRef, intent: parsedIntent, input, ...(options ? { options } : {}) };
|
|
824
|
+
return { family, taskRef, intent: parsedIntent, input };
|
|
827
825
|
}
|
|
828
826
|
//# sourceMappingURL=control-authority.js.map
|