@fitlab-ai/agent-infra 0.11.11 → 0.11.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.
- package/dist/bin/internal-cli.js +2 -2
- package/dist/lib/agent-clients/adapter.js +7 -1
- package/dist/lib/agent-clients/adapters/claude-code.js +5 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/app-server.js +78 -63
- package/dist/lib/agent-clients/adapters/codex-lifecycle/binding.js +114 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/cli.js +447 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-client.js +130 -0
- package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-operation.js +131 -0
- package/dist/lib/{sandbox/control → agent-clients/adapters/codex-lifecycle}/controller-registration.js +2 -2
- package/dist/lib/agent-clients/adapters/codex-lifecycle/evidence.js +48 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/recovery.js +124 -62
- package/dist/lib/{internal/codex-sandbox-controller.js → agent-clients/adapters/codex-lifecycle/sandbox-controller-cli.js} +3 -3
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +3 -5
- package/dist/lib/agent-clients/adapters/codex-lifecycle/store.js +211 -213
- package/dist/lib/agent-clients/adapters/codex-orchestration.js +468 -0
- package/dist/lib/agent-clients/adapters/codex.js +40 -1
- package/dist/lib/agent-clients/adapters/index.js +2 -10
- package/dist/lib/agent-clients/tokens.js +3 -2
- package/dist/lib/internal/agent-client.js +132 -72
- package/dist/lib/internal/cli-route-inventory.js +2 -2
- package/dist/lib/internal/sandbox-control.js +1 -81
- package/dist/lib/internal/task-finalization.js +26 -19
- package/dist/lib/internal/task-lifecycle.js +1 -1
- package/dist/lib/internal/task-operation-registry.js +1 -1
- package/dist/lib/internal/task-validate.js +1 -1
- package/dist/lib/platform/github-client.js +33 -3
- package/dist/lib/platform/issues.js +18 -6
- package/dist/lib/runtime/agent-runtime.js +6 -29
- package/dist/lib/sandbox/commands/control-status.js +1 -0
- package/dist/lib/sandbox/commands/create.js +7 -2
- package/dist/lib/sandbox/commands/ls.js +4 -5
- package/dist/lib/sandbox/commands/rm.js +1 -1
- package/dist/lib/sandbox/control/agent-operation.js +34 -0
- package/dist/lib/sandbox/control/client.js +14 -201
- package/dist/lib/sandbox/control/executor.js +12 -125
- package/dist/lib/sandbox/control/lifecycle.js +66 -4
- package/dist/lib/sandbox/control/protocol.js +15 -54
- package/dist/lib/sandbox/control/server.js +216 -281
- package/dist/lib/sandbox/control/task-view.js +0 -13
- package/dist/lib/sandbox/mounts.js +9 -1
- package/dist/lib/sandbox/recovery.js +31 -10
- package/dist/lib/sandbox/removal.js +28 -5
- package/dist/lib/sandbox/workspace-identity.js +18 -6
- package/dist/lib/sandbox/workspace-view.js +56 -19
- package/dist/lib/task/commands/ls.js +3 -3
- package/dist/lib/task/control-authority.js +56 -264
- package/dist/lib/task/control-recovery.js +2 -3
- package/dist/lib/task/create.js +2 -2
- package/dist/lib/task/delegation-receipts.js +74 -161
- package/dist/lib/task/events.js +88 -44
- package/dist/lib/task/finalization.js +35 -6
- package/dist/lib/task/lifecycle.js +274 -115
- package/dist/lib/task/orchestration.js +201 -194
- package/dist/lib/task/runtime-paths.js +10 -0
- package/dist/lib/task/short-id.js +37 -27
- package/dist/lib/task/verification-engine.js +32 -26
- package/dist/lib/task/workspace-snapshot.js +1 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-clients/adapter.ts +39 -0
- package/lib/agent-clients/adapters/claude-code.ts +5 -1
- package/lib/agent-clients/adapters/codex-lifecycle/app-server.ts +105 -80
- package/lib/agent-clients/adapters/codex-lifecycle/binding.ts +147 -0
- package/lib/agent-clients/adapters/codex-lifecycle/cli.ts +510 -0
- package/lib/agent-clients/adapters/codex-lifecycle/controller-client.ts +158 -0
- package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +1 -1
- package/lib/agent-clients/adapters/codex-lifecycle/controller-operation.ts +151 -0
- package/lib/{sandbox/control → agent-clients/adapters/codex-lifecycle}/controller-registration.ts +4 -4
- package/lib/agent-clients/adapters/codex-lifecycle/evidence.ts +43 -0
- package/lib/agent-clients/adapters/codex-lifecycle/manifest-files.json +8 -5
- package/lib/agent-clients/adapters/codex-lifecycle/recovery.ts +190 -65
- package/lib/{internal/codex-sandbox-controller.ts → agent-clients/adapters/codex-lifecycle/sandbox-controller-cli.ts} +2 -2
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +3 -5
- package/lib/agent-clients/adapters/codex-lifecycle/store.ts +270 -224
- package/lib/agent-clients/adapters/codex-orchestration.ts +632 -0
- package/lib/agent-clients/adapters/codex.ts +44 -1
- package/lib/agent-clients/adapters/index.ts +7 -20
- package/lib/agent-clients/tokens.ts +4 -3
- package/lib/internal/agent-client.ts +142 -73
- package/lib/internal/cli-route-inventory.ts +2 -2
- package/lib/internal/sandbox-control.ts +0 -97
- package/lib/internal/task-finalization.ts +30 -18
- package/lib/internal/task-lifecycle.ts +1 -1
- package/lib/internal/task-operation-registry.ts +1 -1
- package/lib/internal/task-validate.ts +1 -1
- package/lib/platform/github-client.ts +34 -3
- package/lib/platform/issues.ts +18 -6
- package/lib/runtime/agent-runtime.ts +6 -41
- package/lib/sandbox/commands/control-status.ts +1 -0
- package/lib/sandbox/commands/create.ts +7 -1
- package/lib/sandbox/commands/ls.ts +4 -5
- package/lib/sandbox/commands/rm.ts +1 -1
- package/lib/sandbox/control/agent-operation.ts +49 -0
- package/lib/sandbox/control/client.ts +20 -254
- package/lib/sandbox/control/executor.ts +13 -136
- package/lib/sandbox/control/lifecycle.ts +67 -4
- package/lib/sandbox/control/protocol.ts +22 -66
- package/lib/sandbox/control/server.ts +21 -95
- package/lib/sandbox/control/task-view.ts +0 -19
- package/lib/sandbox/mounts.ts +10 -1
- package/lib/sandbox/recovery.ts +38 -17
- package/lib/sandbox/removal.ts +33 -7
- package/lib/sandbox/workspace-identity.ts +16 -6
- package/lib/sandbox/workspace-view.ts +50 -18
- package/lib/task/commands/ls.ts +3 -3
- package/lib/task/control-authority.ts +66 -378
- package/lib/task/control-recovery.ts +3 -4
- package/lib/task/create.ts +3 -3
- package/lib/task/delegation-receipts.ts +87 -231
- package/lib/task/events.ts +100 -42
- package/lib/task/finalization.ts +37 -7
- package/lib/task/lifecycle.ts +257 -109
- package/lib/task/orchestration.ts +260 -237
- package/lib/task/runtime-paths.ts +12 -0
- package/lib/task/short-id.ts +33 -40
- package/lib/task/verification-engine.ts +30 -25
- package/lib/task/workspace-snapshot.ts +1 -1
- package/package.json +1 -1
- package/templates/.agents/hooks/lifecycle-delegation.js +1 -25
- package/templates/.agents/rules/README.en.md +2 -1
- package/templates/.agents/rules/README.zh-CN.md +2 -1
- package/templates/.agents/rules/next-step-output.en.md +6 -19
- package/templates/.agents/rules/next-step-output.zh-CN.md +6 -19
- package/templates/.agents/rules/strategy-pattern.en.md +25 -0
- package/templates/.agents/rules/strategy-pattern.zh-CN.md +25 -0
- package/templates/.agents/skills/analyze-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/check-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/reference/code-rules.en.md +4 -0
- package/templates/.agents/skills/code-task/reference/code-rules.zh-CN.md +4 -0
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +0 -1
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +0 -1
- package/templates/.agents/skills/complete-task/SKILL.en.md +5 -29
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +5 -26
- package/templates/.agents/skills/plan-task/SKILL.en.md +7 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +7 -4
- package/templates/.agents/skills/review-analysis/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-code/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.en.md +1 -1
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +1 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/capability-store.js +0 -546
- package/dist/lib/internal/codex-lifecycle.js +0 -385
- package/dist/lib/task/codex-orchestration.js +0 -206
- package/lib/agent-clients/adapters/codex-lifecycle/capability-store.ts +0 -776
- package/lib/internal/codex-lifecycle.ts +0 -390
- package/lib/task/codex-orchestration.ts +0 -276
|
@@ -4,6 +4,45 @@ import {
|
|
|
4
4
|
codexBeforeContainerCreateHook,
|
|
5
5
|
codexRecoveryChecks
|
|
6
6
|
} from './codex-sandbox.ts';
|
|
7
|
+
import { parseCodexLifecycleBinding } from './codex-lifecycle/binding.ts';
|
|
8
|
+
import { isCodexDelegationReceiptEvidence, isCodexLifecycleActivationEvidence } from './codex-lifecycle/evidence.ts';
|
|
9
|
+
import { codexControllerOperation } from './codex-lifecycle/controller-operation.ts';
|
|
10
|
+
|
|
11
|
+
function codexCarrierError(code: string): Error {
|
|
12
|
+
const error = new Error(code);
|
|
13
|
+
error.name = code;
|
|
14
|
+
return error;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function codexStageToken(stage: string): string {
|
|
18
|
+
const tokens: Readonly<Record<string, string>> = {
|
|
19
|
+
analysis: 'a',
|
|
20
|
+
plan: 'p',
|
|
21
|
+
code: 'c',
|
|
22
|
+
'review-analysis': 'ra',
|
|
23
|
+
'review-plan': 'rp',
|
|
24
|
+
'review-code': 'rc',
|
|
25
|
+
commit: 'm'
|
|
26
|
+
};
|
|
27
|
+
const token = tokens[stage];
|
|
28
|
+
if (!token) throw codexCarrierError('CODEX_LIFECYCLE_SPAWN_IDENTITY_INVALID');
|
|
29
|
+
return token;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function codexLaunchCarrier(
|
|
33
|
+
adapterContext: string,
|
|
34
|
+
identity: Readonly<{ stage: string; round: number; role: string }>
|
|
35
|
+
): Readonly<Record<string, string>> {
|
|
36
|
+
if (!Number.isSafeInteger(identity.round) || identity.round < 1
|
|
37
|
+
|| !['executor', 'reviewer'].includes(identity.role)) {
|
|
38
|
+
throw codexCarrierError('CODEX_LIFECYCLE_SPAWN_IDENTITY_INVALID');
|
|
39
|
+
}
|
|
40
|
+
const label = `${codexStageToken(identity.stage)}_${identity.role === 'reviewer' ? 'r' : 'e'}_r${identity.round}`;
|
|
41
|
+
const taskName = `${label}${adapterContext}`;
|
|
42
|
+
const parsed = parseCodexLifecycleBinding(taskName);
|
|
43
|
+
if (!parsed) throw codexCarrierError('CODEX_LIFECYCLE_LAUNCH_CONTEXT_INVALID');
|
|
44
|
+
return Object.freeze({ task_name: parsed.taskName });
|
|
45
|
+
}
|
|
7
46
|
|
|
8
47
|
const codexAdapter = defineAgentClientAdapter({
|
|
9
48
|
id: 'codex',
|
|
@@ -29,8 +68,11 @@ const codexAdapter = defineAgentClientAdapter({
|
|
|
29
68
|
actualReasoningEffort: 'app-server'
|
|
30
69
|
},
|
|
31
70
|
orchestrationAdapter: {
|
|
71
|
+
validateActivationEvidence: isCodexLifecycleActivationEvidence,
|
|
72
|
+
validateReceiptEvidence: isCodexDelegationReceiptEvidence,
|
|
73
|
+
createLaunchCarrier: codexLaunchCarrier,
|
|
32
74
|
prepareDelegation: async (...args) => {
|
|
33
|
-
const { prepareCodexOrchestrationDelegation } = await import('
|
|
75
|
+
const { prepareCodexOrchestrationDelegation } = await import('./codex-orchestration.ts');
|
|
34
76
|
return prepareCodexOrchestrationDelegation(...args);
|
|
35
77
|
},
|
|
36
78
|
recoverStarted: async (...args) => {
|
|
@@ -38,6 +80,7 @@ const codexAdapter = defineAgentClientAdapter({
|
|
|
38
80
|
return recoverStartedLifecycleFromAdapter(...args);
|
|
39
81
|
}
|
|
40
82
|
},
|
|
83
|
+
sandboxControlOperation: codexControllerOperation,
|
|
41
84
|
project: {
|
|
42
85
|
ownedPathPrefixes: ['.codex/'],
|
|
43
86
|
managed: ['.codex/hooks.json', '.codex/agents/'],
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { AGENT_CLIENT_IDS } from '../types.ts';
|
|
2
1
|
import type { AgentClientAdapter } from '../adapter.ts';
|
|
3
2
|
import { claudeCodeAdapter } from './claude-code.ts';
|
|
4
3
|
import { codexAdapter } from './codex.ts';
|
|
@@ -6,24 +5,12 @@ import { antigravityCliAdapter } from './antigravity-cli.ts';
|
|
|
6
5
|
import { opencodeAdapter } from './opencode.ts';
|
|
7
6
|
import { traecliAdapter } from './traecli.ts';
|
|
8
7
|
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
].map((adapter) => [adapter.id, adapter])
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
const BUILTIN_AGENT_CLIENT_ADAPTERS: readonly AgentClientAdapter[] = Object.freeze(
|
|
20
|
-
AGENT_CLIENT_IDS.map((id) => {
|
|
21
|
-
const adapter = adaptersById.get(id);
|
|
22
|
-
if (!adapter) {
|
|
23
|
-
throw new Error(`Missing built-in Agent Client adapter '${id}'`);
|
|
24
|
-
}
|
|
25
|
-
return adapter;
|
|
26
|
-
})
|
|
27
|
-
);
|
|
8
|
+
const BUILTIN_AGENT_CLIENT_ADAPTERS: readonly AgentClientAdapter[] = Object.freeze([
|
|
9
|
+
claudeCodeAdapter,
|
|
10
|
+
codexAdapter,
|
|
11
|
+
antigravityCliAdapter,
|
|
12
|
+
opencodeAdapter,
|
|
13
|
+
traecliAdapter
|
|
14
|
+
]);
|
|
28
15
|
|
|
29
16
|
export { BUILTIN_AGENT_CLIENT_ADAPTERS };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Active AI collaborator short tokens — the write-side whitelist for the
|
|
2
2
|
// activity log. Migrated from lib/task/commands/log.ts so that the write-side
|
|
3
3
|
// internal commands and the rendering side share one definition.
|
|
4
|
-
export const
|
|
5
|
-
|
|
4
|
+
export const AGENT_TOKEN_VALUES = ['claude', 'codex', 'antigravity', 'opencode', 'cursor', 'traecli'] as const;
|
|
5
|
+
export type AgentToken = (typeof AGENT_TOKEN_VALUES)[number];
|
|
6
|
+
export const KNOWN_AI_AGENTS: ReadonlySet<string> = new Set(AGENT_TOKEN_VALUES);
|
|
6
7
|
|
|
7
8
|
// Long name -> short name mapping: `claude-code` reuses the existing
|
|
8
9
|
// orchestration precedent, and `antigravity-cli` is the active client.
|
|
@@ -12,7 +13,7 @@ export const AGENT_LONG_NAMES: Readonly<Record<string, string>> = {
|
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export const AGENT_USAGE_HINT =
|
|
15
|
-
|
|
16
|
+
`agent must be a short token (${AGENT_TOKEN_VALUES.join('/')}), ` +
|
|
16
17
|
"a long name (claude-code -> claude, antigravity-cli -> antigravity), or 'human'";
|
|
17
18
|
|
|
18
19
|
// Strict write-side validation: the value must be exactly a short token, a
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
} from '../agent-clients/config.ts';
|
|
8
8
|
import { normalizeCustomToolInvocations } from '../agent-clients/custom-tool-invocations.ts';
|
|
9
9
|
import { renderNextStepCommands } from '../agent-clients/next-steps.ts';
|
|
10
|
-
import { getAgentClientModelSelection } from '../agent-clients/registry.ts';
|
|
10
|
+
import { getAgentClientAdapter, getAgentClientModelSelection } from '../agent-clients/registry.ts';
|
|
11
11
|
import { isAgentClientId } from '../agent-clients/types.ts';
|
|
12
12
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
13
13
|
|
|
14
|
-
const USAGE = 'Usage: agent-infra-internal agent-client <next-steps|model-selection> [options]\n';
|
|
14
|
+
const USAGE = 'Usage: agent-infra-internal agent-client <next-steps|model-selection|launch-carrier> [options]\n';
|
|
15
15
|
|
|
16
16
|
type ParsedArgs = Readonly<{
|
|
17
17
|
skillName: string;
|
|
@@ -20,6 +20,14 @@ type ParsedArgs = Readonly<{
|
|
|
20
20
|
format: 'text' | 'json';
|
|
21
21
|
}>;
|
|
22
22
|
|
|
23
|
+
type LaunchCarrierArgs = Readonly<{
|
|
24
|
+
client: string;
|
|
25
|
+
adapterContext: string;
|
|
26
|
+
stage: string;
|
|
27
|
+
round: number;
|
|
28
|
+
role: string;
|
|
29
|
+
}>;
|
|
30
|
+
|
|
23
31
|
function failure(code: string, message: string): void {
|
|
24
32
|
process.stdout.write(`${JSON.stringify({
|
|
25
33
|
status: 'failed',
|
|
@@ -84,68 +92,112 @@ function parseArgs(args: string[]): ParsedArgs | null {
|
|
|
84
92
|
};
|
|
85
93
|
}
|
|
86
94
|
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
const value = args[++index];
|
|
99
|
-
if (!value || value.startsWith('--')) {
|
|
100
|
-
failure('AGENT_CLIENT_PAYLOAD_INVALID', `option '${flag}' requires a value`);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
seen.add(flag);
|
|
104
|
-
values[flag] = value;
|
|
95
|
+
function parseLaunchCarrierArgs(args: string[]): LaunchCarrierArgs | null {
|
|
96
|
+
const allowed = new Set(['--client', '--adapter-context', '--stage', '--round', '--role', '--format']);
|
|
97
|
+
const values: Record<string, string> = {};
|
|
98
|
+
const seen = new Set<string>();
|
|
99
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
100
|
+
const flag = args[index]!;
|
|
101
|
+
if (!allowed.has(flag) || seen.has(flag)) {
|
|
102
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', `invalid or duplicate option '${flag}'`);
|
|
103
|
+
return null;
|
|
105
104
|
}
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return;
|
|
105
|
+
const value = args[++index];
|
|
106
|
+
if (!value || value.startsWith('--')) {
|
|
107
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', `option '${flag}' requires a value`);
|
|
108
|
+
return null;
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
110
|
+
seen.add(flag);
|
|
111
|
+
values[flag] = value;
|
|
112
|
+
}
|
|
113
|
+
const round = Number(values['--round']);
|
|
114
|
+
if (!isAgentClientId(values['--client']) || !values['--adapter-context'] || !values['--stage'] || !values['--role']
|
|
115
|
+
|| !Number.isSafeInteger(round) || round < 1 || (values['--format'] ?? 'json') !== 'json') {
|
|
116
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', 'launch-carrier requires client, adapter context, stage, positive round, role, and json format');
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
client: values['--client']!,
|
|
121
|
+
adapterContext: values['--adapter-context']!,
|
|
122
|
+
stage: values['--stage']!,
|
|
123
|
+
round,
|
|
124
|
+
role: values['--role']!
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function launchCarrier(args: string[]): void {
|
|
129
|
+
const parsed = parseLaunchCarrierArgs(args);
|
|
130
|
+
if (!parsed) return;
|
|
131
|
+
const createCarrier = getAgentClientAdapter(parsed.client).orchestrationAdapter?.createLaunchCarrier;
|
|
132
|
+
if (!createCarrier) {
|
|
133
|
+
process.stdout.write(`${JSON.stringify({
|
|
134
|
+
status: 'failed', changed: false, client: parsed.client, carrier: null,
|
|
135
|
+
error: { code: 'AGENT_CLIENT_LAUNCH_CARRIER_UNSUPPORTED', message: `Agent Client '${parsed.client}' does not support lifecycle launch carriers` }
|
|
136
|
+
})}\n`);
|
|
137
|
+
process.exitCode = 1;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const carrier = createCarrier(parsed.adapterContext, { stage: parsed.stage, round: parsed.round, role: parsed.role });
|
|
142
|
+
process.stdout.write(`${JSON.stringify({ status: 'ready', changed: false, client: parsed.client, carrier, error: null })}\n`);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
process.stdout.write(`${JSON.stringify({
|
|
145
|
+
status: 'failed', changed: false, client: parsed.client, carrier: null,
|
|
146
|
+
error: { code: error instanceof Error && error.name ? error.name : 'AGENT_CLIENT_LAUNCH_CARRIER_INVALID', message: error instanceof Error ? error.message : String(error) }
|
|
147
|
+
})}\n`);
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function modelSelection(args: string[]): void {
|
|
153
|
+
const values: Record<string, string> = {};
|
|
154
|
+
const seen = new Set<string>();
|
|
155
|
+
for (let index = 1; index < args.length; index += 1) {
|
|
156
|
+
const flag = args[index]!;
|
|
157
|
+
if (!['--client', '--format'].includes(flag) || seen.has(flag)) {
|
|
158
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', `invalid or duplicate option '${flag}'`);
|
|
117
159
|
return;
|
|
118
160
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for (const model of context.models) {
|
|
124
|
-
const efforts = model.reasoningEfforts?.length
|
|
125
|
-
? ` (${model.reasoningEfforts.join(', ')})`
|
|
126
|
-
: '';
|
|
127
|
-
process.stdout.write(`- ${model.id}${efforts}\n`);
|
|
128
|
-
}
|
|
129
|
-
if (context.guidance) process.stdout.write(`${context.guidance}\n`);
|
|
161
|
+
const value = args[++index];
|
|
162
|
+
if (!value || value.startsWith('--')) {
|
|
163
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', `option '${flag}' requires a value`);
|
|
164
|
+
return;
|
|
130
165
|
}
|
|
166
|
+
seen.add(flag);
|
|
167
|
+
values[flag] = value;
|
|
168
|
+
}
|
|
169
|
+
const client = values['--client'];
|
|
170
|
+
const format = values['--format'] ?? 'text';
|
|
171
|
+
if (!isAgentClientId(client) || !['text', 'json'].includes(format)) {
|
|
172
|
+
failure('AGENT_CLIENT_PAYLOAD_INVALID', 'model-selection requires a known --client and text|json format');
|
|
131
173
|
return;
|
|
132
174
|
}
|
|
133
|
-
const
|
|
134
|
-
if (
|
|
175
|
+
const context = getAgentClientModelSelection(client);
|
|
176
|
+
if (format === 'json') {
|
|
177
|
+
process.stdout.write(`${JSON.stringify({ status: 'resolved', changed: false, client, context, error: null })}\n`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
renderModelSelection(context);
|
|
181
|
+
}
|
|
135
182
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const raw = JSON.parse(fs.readFileSync(configPath, 'utf8')) as unknown;
|
|
140
|
-
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {
|
|
141
|
-
throw new Error('configuration root must be an object');
|
|
142
|
-
}
|
|
143
|
-
config = raw as Record<string, unknown>;
|
|
144
|
-
} catch (error) {
|
|
145
|
-
failure('AGENT_CLIENT_CONFIG_INVALID', String(error));
|
|
183
|
+
function renderModelSelection(context: ReturnType<typeof getAgentClientModelSelection>): void {
|
|
184
|
+
if (context.kind === 'interactive-only') {
|
|
185
|
+
process.stdout.write(`Model selection: interactive-only\nCommand: ${context.command}\n${context.guidance}\n`);
|
|
146
186
|
return;
|
|
147
187
|
}
|
|
188
|
+
process.stdout.write(`Model selection: ${context.completeness} catalog\nSource: ${context.source}\n`);
|
|
189
|
+
for (const model of context.models) {
|
|
190
|
+
const efforts = model.reasoningEfforts?.length ? ` (${model.reasoningEfforts.join(', ')})` : '';
|
|
191
|
+
process.stdout.write(`- ${model.id}${efforts}\n`);
|
|
192
|
+
}
|
|
193
|
+
if (context.guidance) process.stdout.write(`${context.guidance}\n`);
|
|
194
|
+
}
|
|
148
195
|
|
|
196
|
+
function renderNextSteps(args: string[]): void {
|
|
197
|
+
const parsed = parseArgs(args);
|
|
198
|
+
if (!parsed || process.exitCode) return;
|
|
199
|
+
const config = readAgentClientConfig();
|
|
200
|
+
if (!config) return;
|
|
149
201
|
try {
|
|
150
202
|
const clients = normalizeAgentClients(config);
|
|
151
203
|
const custom = normalizeCustomToolInvocations(config);
|
|
@@ -157,32 +209,49 @@ function agentClient(args: string[] = []): void {
|
|
|
157
209
|
...(parsed.taskRef ? { taskRef: parsed.taskRef } : {}),
|
|
158
210
|
...(parsed.version ? { version: parsed.version } : {})
|
|
159
211
|
});
|
|
160
|
-
|
|
161
|
-
process.stdout.write(`${JSON.stringify({
|
|
162
|
-
status: 'rendered',
|
|
163
|
-
changed: false,
|
|
164
|
-
commands,
|
|
165
|
-
diagnostics: custom.diagnostics,
|
|
166
|
-
error: null
|
|
167
|
-
})}\n`);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
for (const command of commands) {
|
|
171
|
-
process.stdout.write(` - ${command.displayName}: ${command.command}\n`);
|
|
172
|
-
}
|
|
173
|
-
for (const diagnostic of custom.diagnostics) {
|
|
174
|
-
process.stderr.write(`${diagnostic.code} at ${diagnostic.path}\n`);
|
|
175
|
-
}
|
|
212
|
+
writeNextStepOutput(parsed.format, commands, custom.diagnostics);
|
|
176
213
|
} catch (error) {
|
|
177
214
|
if (error instanceof AgentClientConfigError) {
|
|
178
215
|
failure(error.code, error.message);
|
|
179
216
|
return;
|
|
180
217
|
}
|
|
181
|
-
failure(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
218
|
+
failure('AGENT_CLIENT_RENDER_INVALID', error instanceof Error ? error.message : String(error));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function readAgentClientConfig(): Record<string, unknown> | null {
|
|
223
|
+
try {
|
|
224
|
+
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), '.agents', '.airc.json'), 'utf8')) as unknown;
|
|
225
|
+
if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) throw new Error('configuration root must be an object');
|
|
226
|
+
return raw as Record<string, unknown>;
|
|
227
|
+
} catch (error) {
|
|
228
|
+
failure('AGENT_CLIENT_CONFIG_INVALID', String(error));
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function writeNextStepOutput(
|
|
234
|
+
format: ParsedArgs['format'],
|
|
235
|
+
commands: ReturnType<typeof renderNextStepCommands>,
|
|
236
|
+
diagnostics: ReturnType<typeof normalizeCustomToolInvocations>['diagnostics']
|
|
237
|
+
): void {
|
|
238
|
+
if (format === 'json') {
|
|
239
|
+
process.stdout.write(`${JSON.stringify({ status: 'rendered', changed: false, commands, diagnostics, error: null })}\n`);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
for (const command of commands) process.stdout.write(` - ${command.displayName}: ${command.command}\n`);
|
|
243
|
+
for (const diagnostic of diagnostics) process.stderr.write(`${diagnostic.code} at ${diagnostic.path}\n`);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function agentClient(args: string[] = []): void {
|
|
247
|
+
if (!ensureInternalHandlerRoute('agent-client', args)) return;
|
|
248
|
+
if (internalHandlerRoute('agent-client', 'launch-carrier', args[0] ?? '')) {
|
|
249
|
+
return launchCarrier(args);
|
|
250
|
+
}
|
|
251
|
+
if (internalHandlerRoute('agent-client', 'model-selection', args[0] ?? '')) {
|
|
252
|
+
return modelSelection(args);
|
|
185
253
|
}
|
|
254
|
+
renderNextSteps(args);
|
|
186
255
|
}
|
|
187
256
|
|
|
188
257
|
export { agentClient };
|
|
@@ -36,8 +36,8 @@ export const INTERNAL_HANDLER_ROUTE_SELECTORS = Object.freeze({
|
|
|
36
36
|
'task-create': ['input'],
|
|
37
37
|
'task-qualification': ['proposal', 'confirm', 'supersede', 'revoke'],
|
|
38
38
|
'sandbox-control': ['serve', 'execute', 'recover', 'client'],
|
|
39
|
-
'agent-client': ['next-steps', 'model-selection'],
|
|
40
|
-
'codex-lifecycle': ['preflight', '
|
|
39
|
+
'agent-client': ['next-steps', 'model-selection', 'launch-carrier'],
|
|
40
|
+
'codex-lifecycle': ['preflight', 'hook-event', 'resolve-start', 'resolve-stop', 'consume'],
|
|
41
41
|
'codex-sandbox-controller': ['verify-context', 'run'],
|
|
42
42
|
'git-workflow': ['inspect', 'preview-tree', 'snapshot', 'compare-trees', 'commit', 'push-rebased'],
|
|
43
43
|
'task-delivery': ['deliver'],
|
|
@@ -1,33 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
recoverSandboxControl,
|
|
3
3
|
requestSandboxControl,
|
|
4
|
-
requestSandboxTaskFinalization,
|
|
5
4
|
SandboxControlClientError
|
|
6
5
|
} from '../sandbox/control/client.ts';
|
|
7
|
-
import { normalizeAgentToken, AGENT_USAGE_HINT } from '../agent-clients/tokens.ts';
|
|
8
6
|
import { serveSandboxControl } from '../sandbox/control/server.ts';
|
|
9
7
|
import { runSandboxControlExecutor } from '../sandbox/control/executor.ts';
|
|
10
8
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
11
9
|
import { parseTaskCreateResult, taskCreateExitCode } from '../task/create-service.ts';
|
|
12
|
-
import { serializeTaskFinalizationEnvelope, type TaskFinalizationEnvelope } from '../task/finalization-envelope.ts';
|
|
13
|
-
|
|
14
|
-
type FinalizationStatus = 'completed' | 'failed' | 'blocked' | 'unknown';
|
|
15
|
-
|
|
16
|
-
function writeFinalizationEnvelope(
|
|
17
|
-
status: FinalizationStatus,
|
|
18
|
-
accepted: boolean,
|
|
19
|
-
error: { code: string; message: string; retryable: boolean },
|
|
20
|
-
changed: boolean | null = false,
|
|
21
|
-
result: unknown = null,
|
|
22
|
-
requestId: string | null = null
|
|
23
|
-
): void {
|
|
24
|
-
process.stdout.write(serializeTaskFinalizationEnvelope({ status, changed, accepted, requestId, result, error }));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function finalizationErrorStatus(error: { retryable: boolean; code: string }): FinalizationStatus {
|
|
28
|
-
if (error.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN') return 'unknown';
|
|
29
|
-
return error.retryable ? 'blocked' : 'failed';
|
|
30
|
-
}
|
|
31
10
|
|
|
32
11
|
function writeClientError(error: SandboxControlClientError): void {
|
|
33
12
|
process.stderr.write(`${error.detail.message}\n`);
|
|
@@ -45,78 +24,6 @@ function recoveredExitCode(response: Awaited<ReturnType<typeof recoverSandboxCon
|
|
|
45
24
|
return response.exitCode ?? 1;
|
|
46
25
|
}
|
|
47
26
|
|
|
48
|
-
function finalizationResponseOutput(response: Awaited<ReturnType<typeof requestSandboxTaskFinalization>>): string {
|
|
49
|
-
try {
|
|
50
|
-
const value = JSON.parse(response.stdout) as Partial<TaskFinalizationEnvelope>;
|
|
51
|
-
if (value.version === 2
|
|
52
|
-
&& value.status
|
|
53
|
-
&& ['completed', 'failed', 'blocked', 'unknown'].includes(value.status)
|
|
54
|
-
&& (typeof value.changed === 'boolean' || value.changed === null)) {
|
|
55
|
-
return serializeTaskFinalizationEnvelope({
|
|
56
|
-
status: value.status,
|
|
57
|
-
changed: value.changed,
|
|
58
|
-
accepted: true,
|
|
59
|
-
requestId: response.id,
|
|
60
|
-
result: value.result ?? null,
|
|
61
|
-
error: value.error ?? null
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
} catch {
|
|
65
|
-
// Preserve non-envelope output for diagnostics from the executor.
|
|
66
|
-
}
|
|
67
|
-
return response.stdout;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function sandboxFinalizationClient(args: string[]): void {
|
|
71
|
-
if (args.length !== 4 || !args[0] || args[1] !== 'complete' || args[2] !== '--agent' || !args[3]) {
|
|
72
|
-
const error = { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: 'task ref, complete intent, and --agent are required', retryable: false };
|
|
73
|
-
writeFinalizationEnvelope('failed', false, error);
|
|
74
|
-
process.stderr.write('Usage: agent-infra-internal task-finalization <N | TASK-id> complete --agent <agent>\n');
|
|
75
|
-
process.exitCode = 1;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const agent = normalizeAgentToken(args[3]);
|
|
79
|
-
if (!agent) {
|
|
80
|
-
const error = { code: 'TASK_FINALIZATION_PAYLOAD_INVALID', message: `invalid --agent: ${AGENT_USAGE_HINT}`, retryable: false };
|
|
81
|
-
writeFinalizationEnvelope('failed', false, error);
|
|
82
|
-
process.exitCode = 1;
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
let response;
|
|
86
|
-
try {
|
|
87
|
-
response = requestSandboxTaskFinalization({ agent });
|
|
88
|
-
} catch (error) {
|
|
89
|
-
if (!(error instanceof SandboxControlClientError)) throw error;
|
|
90
|
-
const status = finalizationErrorStatus(error.detail);
|
|
91
|
-
writeFinalizationEnvelope(status, error.accepted, error.detail, status === 'unknown' ? null : false, null, error.requestId);
|
|
92
|
-
writeClientError(error);
|
|
93
|
-
process.exitCode = error.detail.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN' ? 1 : error.detail.retryable ? 2 : 1;
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (response.phase === 'rejected') {
|
|
97
|
-
const error = response.error ?? {
|
|
98
|
-
code: 'SANDBOX_CONTROL_REJECTED',
|
|
99
|
-
message: 'sandbox control rejected the finalization request',
|
|
100
|
-
retryable: false
|
|
101
|
-
};
|
|
102
|
-
const status = finalizationErrorStatus(error);
|
|
103
|
-
writeFinalizationEnvelope(
|
|
104
|
-
status,
|
|
105
|
-
error.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN',
|
|
106
|
-
error,
|
|
107
|
-
status === 'unknown' ? null : false,
|
|
108
|
-
null,
|
|
109
|
-
response.id
|
|
110
|
-
);
|
|
111
|
-
process.stderr.write(`${error.message}\n`);
|
|
112
|
-
process.exitCode = error.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN' ? 1 : error.retryable ? 2 : 1;
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
process.stdout.write(finalizationResponseOutput(response));
|
|
116
|
-
process.stderr.write(response.stderr);
|
|
117
|
-
process.exitCode = response.exitCode ?? 1;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
27
|
async function sandboxControl(args: string[]): Promise<void> {
|
|
121
28
|
if (!ensureInternalHandlerRoute('sandbox-control', args)) return;
|
|
122
29
|
const [operation, ...rest] = args;
|
|
@@ -165,10 +72,6 @@ async function sandboxControl(args: string[]): Promise<void> {
|
|
|
165
72
|
}
|
|
166
73
|
if (internalHandlerRoute('sandbox-control', 'client', operation ?? '')) {
|
|
167
74
|
const [family = '', ...commandArgs] = rest;
|
|
168
|
-
if (family === 'task-finalization') {
|
|
169
|
-
sandboxFinalizationClient(commandArgs);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
75
|
let response;
|
|
173
76
|
try {
|
|
174
77
|
response = requestSandboxControl({ family, args: commandArgs });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
1
2
|
import {
|
|
2
3
|
createDirectHostExecutionContext,
|
|
3
4
|
dispatchTaskControlOperation,
|
|
@@ -6,8 +7,10 @@ import {
|
|
|
6
7
|
import { applyTaskFinalization } from '../task/finalization.ts';
|
|
7
8
|
import { detectRepoRoot, resolveTaskRef } from '../task/resolve-ref.ts';
|
|
8
9
|
import { resolveSandboxControlTransport } from './task-operation-registry.ts';
|
|
9
|
-
import {
|
|
10
|
+
import { quiesceSandboxControlForTaskCompletion } from '../sandbox/control/lifecycle.ts';
|
|
11
|
+
import { resolveTaskRuntimeRoot } from '../task/runtime-paths.ts';
|
|
10
12
|
import { serializeTaskFinalizationEnvelope } from '../task/finalization-envelope.ts';
|
|
13
|
+
import { verifyTaskEvent } from '../task/verification.ts';
|
|
11
14
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
12
15
|
|
|
13
16
|
const USAGE = 'Usage: agent-infra-internal task-finalization <N | TASK-id> complete --agent <agent>\n';
|
|
@@ -79,25 +82,34 @@ async function taskFinalization(args: string[] = []): Promise<void> {
|
|
|
79
82
|
};
|
|
80
83
|
const transport = resolveSandboxControlTransport(process.env, { localWorkflow: true });
|
|
81
84
|
if (transport.kind === 'sandbox-local') {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const detail = clientError
|
|
91
|
-
? clientError.detail
|
|
92
|
-
: { code: 'SANDBOX_CONTROL_CLIENT_FAILED', message: error instanceof Error ? error.message : String(error), retryable: false };
|
|
93
|
-
const status = detail.code === 'SANDBOX_CONTROL_RESULT_UNKNOWN'
|
|
94
|
-
? 'unknown'
|
|
95
|
-
: detail.retryable ? 'blocked' : 'failed';
|
|
96
|
-
const changed = status === 'unknown' ? null : false;
|
|
97
|
-
process.stdout.write(envelope(status, changed, clientError?.accepted ?? false, null, detail, clientError?.requestId ?? null));
|
|
98
|
-
process.exitCode = exitCode(status);
|
|
85
|
+
const statusDir = process.env.AGENT_INFRA_CONTROL_STATUS_DIR;
|
|
86
|
+
const taskId = process.env.AGENT_INFRA_TASK_ID;
|
|
87
|
+
const generation = process.env.AGENT_INFRA_CONTROL_GENERATION;
|
|
88
|
+
const controlRootId = process.env.AGENT_INFRA_CONTROL_ROOT_ID;
|
|
89
|
+
if (!statusDir || !taskId || !generation || !controlRootId || taskId !== resolved.taskId) {
|
|
90
|
+
const detail = { code: 'TASK_CONTROL_TRANSPORT_INVALID', message: 'sandbox task control identity is incomplete', retryable: false };
|
|
91
|
+
process.stdout.write(envelope('failed', false, true, null, detail));
|
|
92
|
+
process.exitCode = 1;
|
|
99
93
|
return;
|
|
100
94
|
}
|
|
95
|
+
const result = await applyTaskFinalization(boundOperation.request, {
|
|
96
|
+
repoRoot,
|
|
97
|
+
beforeLifecycle: async (currentTaskId) => {
|
|
98
|
+
if (currentTaskId !== taskId) throw new Error('SANDBOX_CONTROL_IDENTITY_MISMATCH');
|
|
99
|
+
await quiesceSandboxControlForTaskCompletion(
|
|
100
|
+
path.join(resolveTaskRuntimeRoot(taskId, { repoRoot }), 'sandbox-control'),
|
|
101
|
+
{ taskId, generation, controlRootId, statusDir }
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
preflight: (request, options) => verifyTaskEvent(
|
|
105
|
+
{ ...request, event: 'complete-task.hard-preflight' }, options
|
|
106
|
+
)
|
|
107
|
+
});
|
|
108
|
+
const status = result.status === 'prepared' ? 'failed' : result.status;
|
|
109
|
+
process.stdout.write(envelope(status, result.changed, true, result, result.error
|
|
110
|
+
?? (result.status === 'prepared' ? { code: 'TASK_FINALIZATION_PREPARATION_INCOMPLETE', message: 'finalization did not commit', retryable: true } : null)));
|
|
111
|
+
process.exitCode = exitCode(status);
|
|
112
|
+
return;
|
|
101
113
|
}
|
|
102
114
|
const result = await dispatchTaskControlOperation(
|
|
103
115
|
createDirectHostExecutionContext({ repoRoot }),
|
|
@@ -10,7 +10,7 @@ import type { TaskLifecycleResult } from '../task/lifecycle.ts';
|
|
|
10
10
|
import type { AgentClientLifecycleRecoveryResult as LifecycleRecoveryResult } from '../agent-clients/adapter.ts';
|
|
11
11
|
import { ensureInternalHandlerRoute, internalHandlerRoute } from './cli-route-inventory.ts';
|
|
12
12
|
|
|
13
|
-
const USAGE = `Usage: agent-infra-internal task-lifecycle <N | TASK-id> <intent> --agent <agent> [intent flags] [--dry-run]\n\nIntents: ${lifecycleIntentCatalog.join(', ')}\nrecover-started: --auto\n`;
|
|
13
|
+
const USAGE = `Usage: agent-infra-internal task-lifecycle <N | TASK-id> <intent> --agent <agent> [intent flags] [--dry-run]\n\nIntents: ${lifecycleIntentCatalog.filter((intent) => intent !== 'complete').join(', ')}\nrecover-started: --auto\n`;
|
|
14
14
|
|
|
15
15
|
function usageFailure(message: string): void {
|
|
16
16
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, error: { code: 'LIFECYCLE_PAYLOAD_INVALID', message } })}\n`);
|
|
@@ -54,8 +54,8 @@ function internalTaskRoutes(): TaskOperationDescriptor[] {
|
|
|
54
54
|
descriptor('internal', 'sandbox-control', 'client', 'conditional', 'progress', 'delegated'),
|
|
55
55
|
descriptor('internal', 'agent-client', 'next-steps', 'non-task', 'diagnostic', 'none'),
|
|
56
56
|
descriptor('internal', 'agent-client', 'model-selection', 'non-task', 'diagnostic', 'none'),
|
|
57
|
+
descriptor('internal', 'agent-client', 'launch-carrier', 'non-task', 'diagnostic', 'none'),
|
|
57
58
|
descriptor('internal', 'codex-lifecycle', 'preflight', 'non-task', 'diagnostic', 'none'),
|
|
58
|
-
descriptor('internal', 'codex-lifecycle', 'capability-arm', 'conditional', 'progress'),
|
|
59
59
|
descriptor('internal', 'codex-lifecycle', 'hook-event', 'conditional', 'progress'),
|
|
60
60
|
descriptor('internal', 'codex-lifecycle', 'resolve-start', 'conditional', 'progress'),
|
|
61
61
|
descriptor('internal', 'codex-lifecycle', 'resolve-stop', 'conditional', 'progress'),
|
|
@@ -155,7 +155,7 @@ function inplaceValidation(config: ReturnType<typeof loadConfig>, target: Return
|
|
|
155
155
|
const row = selectSandboxContainer([...running, ...nonRunning], containerNameCandidates(config, target.branch));
|
|
156
156
|
if (!row) throw new Error('SANDBOX_VALIDATION_CONTAINER_NOT_FOUND');
|
|
157
157
|
const control = sandboxControlPaths({
|
|
158
|
-
base: config.controlBase, project: config.project,
|
|
158
|
+
base: config.controlBase, repoRoot: config.repoRoot, project: config.project,
|
|
159
159
|
container: row.name, identity: target.workspace
|
|
160
160
|
});
|
|
161
161
|
const manifest = readSandboxControlManifest(control.manifestPath);
|