@fitlab-ai/agent-infra 0.9.9 → 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -3
- package/README.zh-CN.md +13 -3
- package/bin/cli.ts +17 -4
- package/dist/bin/cli.js +19 -4
- package/dist/bin/internal-cli.js +55 -4
- package/dist/lib/agent-client.js +0 -1
- package/dist/lib/agent-clients/adapters/codex-lifecycle/build-identity.js +17 -10
- package/dist/lib/agent-clients/adapters/codex-lifecycle/controller-context.js +11 -31
- package/dist/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.js +15 -33
- package/dist/lib/agent-clients/adapters/codex-sandbox.js +72 -11
- package/dist/lib/agent-clients/adapters/index.js +3 -1
- package/dist/lib/agent-clients/adapters/opencode-sandbox.js +0 -4
- package/dist/lib/agent-clients/adapters/traecli.js +65 -0
- package/dist/lib/agent-clients/config.js +14 -99
- package/dist/lib/agent-clients/reconcile.js +1 -11
- package/dist/lib/agent-clients/schema.js +5 -4
- package/dist/lib/agent-clients/tokens.js +7 -17
- package/dist/lib/agent-clients/types.js +2 -1
- package/dist/lib/decide.js +14 -30
- package/dist/lib/defaults.json +9 -0
- package/dist/lib/init.js +2 -2
- package/dist/lib/internal/codex-lifecycle.js +2 -2
- package/dist/lib/internal/codex-sandbox-controller.js +4 -3
- package/dist/lib/internal/release-workflow.js +0 -1
- package/dist/lib/internal/sandbox-control.js +2 -2
- package/dist/lib/internal/task-finalization.js +19 -9
- package/dist/lib/internal/task-ledger.js +8 -2
- package/dist/lib/internal/task-lifecycle.js +17 -93
- package/dist/lib/internal/task-orchestration.js +30 -216
- package/dist/lib/{task/commands/validate.js → internal/task-validate.js} +77 -43
- package/dist/lib/merge.js +205 -103
- package/dist/lib/process-data/normalize.js +2 -9
- package/dist/lib/run/host.js +46 -16
- package/dist/lib/run/tui.js +5 -2
- package/dist/lib/sandbox/agent-client-reconciler.js +4 -12
- package/dist/lib/sandbox/commands/create.js +3 -3
- package/dist/lib/sandbox/commands/enter.js +18 -4
- package/dist/lib/sandbox/config.js +3 -12
- package/dist/lib/sandbox/control/controller-registration.js +4 -2
- package/dist/lib/sandbox/control/executor.js +135 -40
- package/dist/lib/sandbox/control/lifecycle.js +29 -20
- package/dist/lib/sandbox/control/server.js +18 -16
- package/dist/lib/sandbox/mounts.js +3 -2
- package/dist/lib/sandbox/recovery.js +123 -22
- package/dist/lib/sandbox/workspace-identity.js +14 -0
- package/dist/lib/sandbox/workspace-view.js +8 -9
- package/dist/lib/self-update.js +278 -0
- package/dist/lib/server/protocol.js +5 -5
- package/dist/lib/task/activity-log.js +4 -1
- package/dist/lib/task/artifact-lifecycle.js +4 -2
- package/dist/lib/task/codex-orchestration.js +32 -35
- package/dist/lib/task/command-options.js +1 -3
- package/dist/lib/task/commands/cat.js +0 -5
- package/dist/lib/task/commands/decisions.js +76 -92
- package/dist/lib/task/commands/files.js +6 -6
- package/dist/lib/task/commands/grep.js +25 -61
- package/dist/lib/task/commands/issue-body.js +6 -6
- package/dist/lib/task/commands/log.js +25 -10
- package/dist/lib/task/commands/show.js +5 -6
- package/dist/lib/task/commands/status.js +8 -8
- package/dist/lib/task/commit-operation.js +21 -25
- package/dist/lib/task/commit-policy.js +1 -1
- package/dist/lib/task/control-authority.js +431 -0
- package/dist/lib/task/create.js +6 -1
- package/dist/lib/task/current-contract.js +35 -0
- package/dist/lib/task/decision-details.js +263 -0
- package/dist/lib/task/decision-intents.js +5 -2
- package/dist/lib/task/delegation-receipts.js +8 -7
- package/dist/lib/task/events.js +11 -5
- package/dist/lib/task/finalization.js +72 -46
- package/dist/lib/task/index.js +19 -29
- package/dist/lib/task/ledger-intents.js +8 -9
- package/dist/lib/task/ledger.js +13 -6
- package/dist/lib/task/lifecycle.js +16 -0
- package/dist/lib/task/orchestration.js +51 -14
- package/dist/lib/task/review-artifacts.js +31 -12
- package/dist/lib/task/review-finalization.js +19 -6
- package/dist/lib/task/verification-engine.js +38 -18
- package/dist/lib/task/verification-review.js +1 -1
- package/dist/lib/task/workspace-snapshot.js +5 -11
- package/dist/lib/task/write.js +11 -1
- package/dist/lib/update.js +6 -37
- package/dist/lib/version.js +5 -1
- package/dist/lifecycle-build-manifest.json +3 -3
- package/lib/agent-client.ts +0 -1
- package/lib/agent-clients/adapters/codex-lifecycle/build-identity.ts +25 -10
- package/lib/agent-clients/adapters/codex-lifecycle/controller-context.ts +16 -33
- package/lib/agent-clients/adapters/codex-lifecycle/sandbox-controller.ts +16 -35
- package/lib/agent-clients/adapters/codex-sandbox.ts +89 -14
- package/lib/agent-clients/adapters/index.ts +3 -1
- package/lib/agent-clients/adapters/opencode-sandbox.ts +0 -5
- package/lib/agent-clients/adapters/traecli.ts +66 -0
- package/lib/agent-clients/config.ts +14 -144
- package/lib/agent-clients/reconcile.ts +1 -12
- package/lib/agent-clients/schema.ts +5 -4
- package/lib/agent-clients/tokens.ts +7 -20
- package/lib/agent-clients/types.ts +2 -1
- package/lib/decide.ts +12 -22
- package/lib/defaults.json +9 -0
- package/lib/init.ts +2 -2
- package/lib/internal/codex-lifecycle.ts +2 -2
- package/lib/internal/codex-sandbox-controller.ts +4 -3
- package/lib/internal/release-workflow.ts +0 -1
- package/lib/internal/sandbox-control.ts +2 -2
- package/lib/internal/task-finalization.ts +27 -13
- package/lib/internal/task-ledger.ts +8 -2
- package/lib/internal/task-lifecycle.ts +33 -76
- package/lib/internal/task-orchestration.ts +33 -190
- package/lib/{task/commands/validate.ts → internal/task-validate.ts} +77 -41
- package/lib/merge.ts +236 -120
- package/lib/process-data/normalize.ts +2 -8
- package/lib/run/host.ts +63 -14
- package/lib/run/tui.ts +5 -3
- package/lib/sandbox/agent-client-reconciler.ts +5 -15
- package/lib/sandbox/commands/create.ts +4 -4
- package/lib/sandbox/commands/enter.ts +24 -4
- package/lib/sandbox/config.ts +2 -14
- package/lib/sandbox/control/container-identity.ts +2 -2
- package/lib/sandbox/control/controller-registration.ts +8 -3
- package/lib/sandbox/control/executor.ts +156 -53
- package/lib/sandbox/control/lifecycle.ts +34 -28
- package/lib/sandbox/control/protocol.ts +1 -3
- package/lib/sandbox/control/server.ts +15 -12
- package/lib/sandbox/control/state.ts +7 -7
- package/lib/sandbox/mounts.ts +4 -3
- package/lib/sandbox/recovery.ts +162 -34
- package/lib/sandbox/tools.ts +1 -1
- package/lib/sandbox/workspace-identity.ts +28 -0
- package/lib/sandbox/workspace-view.ts +14 -10
- package/lib/self-update.ts +341 -0
- package/lib/server/protocol.ts +5 -5
- package/lib/task/activity-log.ts +6 -1
- package/lib/task/artifact-lifecycle.ts +5 -3
- package/lib/task/codex-orchestration.ts +40 -45
- package/lib/task/command-options.ts +1 -2
- package/lib/task/commands/cat.ts +0 -4
- package/lib/task/commands/decisions.ts +80 -75
- package/lib/task/commands/files.ts +6 -6
- package/lib/task/commands/grep.ts +23 -51
- package/lib/task/commands/issue-body.ts +6 -6
- package/lib/task/commands/log.ts +22 -10
- package/lib/task/commands/show.ts +5 -6
- package/lib/task/commands/status.ts +8 -8
- package/lib/task/commit-operation.ts +25 -30
- package/lib/task/commit-policy.ts +1 -2
- package/lib/task/control-authority.ts +563 -0
- package/lib/task/create.ts +6 -1
- package/lib/task/current-contract.ts +49 -0
- package/lib/task/decision-details.ts +340 -0
- package/lib/task/decision-intents.ts +7 -2
- package/lib/task/delegation-receipts.ts +8 -6
- package/lib/task/events.ts +10 -5
- package/lib/task/finalization.ts +84 -42
- package/lib/task/index.ts +19 -28
- package/lib/task/ledger-intents.ts +6 -8
- package/lib/task/ledger.ts +17 -7
- package/lib/task/lifecycle.ts +20 -0
- package/lib/task/orchestration.ts +42 -16
- package/lib/task/review-artifacts.ts +53 -15
- package/lib/task/review-finalization.ts +33 -7
- package/lib/task/verification-engine.ts +33 -21
- package/lib/task/verification-review.ts +1 -1
- package/lib/task/workspace-snapshot.ts +4 -13
- package/lib/task/write.ts +20 -1
- package/lib/update.ts +6 -40
- package/lib/version.ts +6 -1
- package/package.json +1 -1
- package/templates/.agents/QUICKSTART.en.md +2 -3
- package/templates/.agents/QUICKSTART.zh-CN.md +2 -3
- package/templates/.agents/README.en.md +5 -3
- package/templates/.agents/README.zh-CN.md +5 -3
- package/templates/.agents/rules/README.en.md +1 -0
- package/templates/.agents/rules/README.zh-CN.md +1 -0
- package/templates/.agents/rules/compatibility-policy.en.md +40 -0
- package/templates/.agents/rules/compatibility-policy.zh-CN.md +40 -0
- package/templates/.agents/rules/create-issue.github.en.md +1 -1
- package/templates/.agents/rules/create-issue.github.zh-CN.md +1 -1
- package/templates/.agents/rules/human-decision-context.en.md +9 -7
- package/templates/.agents/rules/human-decision-context.zh-CN.md +9 -7
- package/templates/.agents/rules/issue-fields.github.en.md +1 -1
- package/templates/.agents/rules/issue-fields.github.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.en.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.github.en.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.github.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-pr-commands.zh-CN.md +1 -1
- package/templates/.agents/rules/issue-sync.github.en.md +1 -1
- package/templates/.agents/rules/issue-sync.github.zh-CN.md +2 -2
- package/templates/.agents/rules/lifecycle-orchestration.en.md +4 -4
- package/templates/.agents/rules/lifecycle-orchestration.zh-CN.md +4 -4
- package/templates/.agents/rules/milestone-inference.github.en.md +1 -1
- package/templates/.agents/rules/milestone-inference.github.zh-CN.md +1 -1
- package/templates/.agents/rules/next-step-output.en.md +3 -3
- package/templates/.agents/rules/next-step-output.zh-CN.md +3 -3
- package/templates/.agents/rules/no-mid-flow-questions.en.md +1 -1
- package/templates/.agents/rules/no-mid-flow-questions.zh-CN.md +1 -1
- package/templates/.agents/rules/pr-sync.en.md +2 -2
- package/templates/.agents/rules/pr-sync.github.en.md +3 -2
- package/templates/.agents/rules/pr-sync.github.zh-CN.md +3 -1
- package/templates/.agents/rules/pr-sync.zh-CN.md +2 -1
- package/templates/.agents/rules/release-commands.github.en.md +6 -0
- package/templates/.agents/rules/release-commands.github.zh-CN.md +6 -0
- package/templates/.agents/rules/review-handshake.en.md +1 -1
- package/templates/.agents/rules/review-handshake.zh-CN.md +1 -1
- package/templates/.agents/rules/review-method.en.md +1 -0
- package/templates/.agents/rules/review-method.zh-CN.md +1 -0
- package/templates/.agents/rules/task-management.en.md +1 -2
- package/templates/.agents/rules/task-management.zh-CN.md +1 -2
- package/templates/.agents/skills/analyze-task/SKILL.en.md +4 -3
- package/templates/.agents/skills/analyze-task/SKILL.zh-CN.md +4 -3
- package/templates/.agents/skills/block-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/block-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/cancel-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/cancel-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/check-task/SKILL.en.md +2 -2
- package/templates/.agents/skills/check-task/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/close-codescan/SKILL.en.md +1 -1
- package/templates/.agents/skills/close-codescan/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/close-dependabot/SKILL.en.md +1 -1
- package/templates/.agents/skills/close-dependabot/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/code-task/SKILL.en.md +4 -3
- package/templates/.agents/skills/code-task/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/commit/SKILL.en.md +27 -7
- package/templates/.agents/skills/commit/SKILL.zh-CN.md +3 -4
- package/templates/.agents/skills/complete-manual-validation/SKILL.en.md +5 -5
- package/templates/.agents/skills/complete-manual-validation/SKILL.zh-CN.md +5 -5
- package/templates/.agents/skills/complete-task/SKILL.en.md +3 -3
- package/templates/.agents/skills/complete-task/SKILL.zh-CN.md +3 -3
- package/templates/.agents/skills/create-pr/SKILL.en.md +15 -11
- package/templates/.agents/skills/create-pr/SKILL.zh-CN.md +15 -11
- package/templates/.agents/skills/create-pr/reference/change-report.en.md +46 -0
- package/templates/.agents/skills/create-pr/reference/change-report.zh-CN.md +46 -0
- package/templates/.agents/skills/create-pr/scripts/change-report.mjs +203 -0
- package/templates/.agents/skills/create-release-note/SKILL.en.md +5 -6
- package/templates/.agents/skills/create-release-note/SKILL.zh-CN.md +5 -6
- package/templates/.agents/skills/create-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/create-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.en.md +1 -1
- package/templates/.agents/skills/import-issue/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/plan-task/SKILL.en.md +5 -4
- package/templates/.agents/skills/plan-task/SKILL.zh-CN.md +5 -4
- package/templates/.agents/skills/restore-task/SKILL.en.md +1 -1
- package/templates/.agents/skills/restore-task/SKILL.zh-CN.md +1 -1
- package/templates/.agents/skills/review-analysis/SKILL.en.md +5 -3
- package/templates/.agents/skills/review-analysis/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/review-analysis/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-analysis/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/review-code/SKILL.en.md +5 -3
- package/templates/.agents/skills/review-code/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/review-code/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-code/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/review-code/reference/migration-risks.en.md +9 -6
- package/templates/.agents/skills/review-code/reference/migration-risks.zh-CN.md +9 -6
- package/templates/.agents/skills/review-plan/SKILL.en.md +5 -3
- package/templates/.agents/skills/review-plan/SKILL.zh-CN.md +5 -3
- package/templates/.agents/skills/review-plan/config/verify.en.json +1 -0
- package/templates/.agents/skills/review-plan/config/verify.zh-CN.json +1 -0
- package/templates/.agents/skills/run-manual-validation/SKILL.en.md +7 -3
- package/templates/.agents/skills/run-manual-validation/SKILL.zh-CN.md +7 -3
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.en.md +1 -1
- package/templates/.agents/skills/run-manual-validation/reference/discovery-and-execution.zh-CN.md +1 -1
- package/templates/.agents/skills/run-manual-validation/reference/report-template.en.md +2 -2
- package/templates/.agents/skills/run-manual-validation/reference/report-template.zh-CN.md +2 -2
- package/templates/.agents/skills/run-task/SKILL.en.md +6 -2
- package/templates/.agents/skills/run-task/SKILL.zh-CN.md +6 -2
- package/templates/.agents/skills/run-task/reference/host-validation.en.md +2 -2
- package/templates/.agents/skills/run-task/reference/host-validation.zh-CN.md +2 -2
- package/templates/.agents/skills/update-agent-infra/SKILL.en.md +2 -2
- package/templates/.agents/skills/update-agent-infra/SKILL.zh-CN.md +2 -2
- package/templates/.agents/skills/update-agent-infra/scripts/sync-templates.js +159 -104
- package/templates/.agents/skills/watch-pr/SKILL.en.md +2 -2
- package/templates/.agents/skills/watch-pr/SKILL.zh-CN.md +2 -2
- package/templates/.agents/templates/task.en.md +1 -1
- package/templates/.agents/templates/task.zh-CN.md +1 -1
- package/templates/.claude/commands/analyze-task.en.md +1 -1
- package/templates/.claude/commands/analyze-task.zh-CN.md +1 -1
- package/templates/.claude/commands/block-task.en.md +1 -1
- package/templates/.claude/commands/block-task.zh-CN.md +1 -1
- package/templates/.claude/commands/cancel-task.en.md +1 -1
- package/templates/.claude/commands/cancel-task.zh-CN.md +1 -1
- package/templates/.claude/commands/check-task.en.md +1 -1
- package/templates/.claude/commands/check-task.zh-CN.md +1 -1
- package/templates/.claude/commands/code-task.en.md +1 -1
- package/templates/.claude/commands/code-task.zh-CN.md +1 -1
- package/templates/.claude/commands/commit.en.md +1 -1
- package/templates/.claude/commands/commit.zh-CN.md +1 -1
- package/templates/.claude/commands/complete-manual-validation.en.md +1 -1
- package/templates/.claude/commands/complete-manual-validation.zh-CN.md +1 -1
- package/templates/.claude/commands/complete-task.en.md +1 -1
- package/templates/.claude/commands/complete-task.zh-CN.md +1 -1
- package/templates/.claude/commands/create-pr.en.md +1 -1
- package/templates/.claude/commands/create-pr.zh-CN.md +1 -1
- package/templates/.claude/commands/plan-task.en.md +1 -1
- package/templates/.claude/commands/plan-task.zh-CN.md +1 -1
- package/templates/.claude/commands/review-analysis.en.md +1 -1
- package/templates/.claude/commands/review-analysis.zh-CN.md +1 -1
- package/templates/.claude/commands/review-code.en.md +1 -1
- package/templates/.claude/commands/review-code.zh-CN.md +1 -1
- package/templates/.claude/commands/review-plan.en.md +1 -1
- package/templates/.claude/commands/review-plan.zh-CN.md +1 -1
- package/templates/.claude/commands/run-manual-validation.en.md +1 -1
- package/templates/.claude/commands/run-manual-validation.zh-CN.md +1 -1
- package/templates/.claude/commands/run-task.en.md +1 -1
- package/templates/.claude/commands/run-task.zh-CN.md +1 -1
- package/templates/.claude/commands/watch-pr.en.md +1 -1
- package/templates/.claude/commands/watch-pr.zh-CN.md +1 -1
- package/templates/.traecli/commands/update-agent-infra.en.md +7 -0
- package/templates/.traecli/commands/update-agent-infra.zh-CN.md +7 -0
- package/dist/lib/builtin-tuis.js +0 -40
- package/lib/builtin-tuis.ts +0 -56
|
@@ -10,20 +10,13 @@ import type {
|
|
|
10
10
|
OrchestrationModelPolicy
|
|
11
11
|
} from './types.ts';
|
|
12
12
|
|
|
13
|
-
type AgentClientConfigInput = Readonly<
|
|
14
|
-
agentClients?: unknown;
|
|
15
|
-
tuis?: unknown;
|
|
16
|
-
sandbox?: unknown;
|
|
17
|
-
customTUIs?: unknown;
|
|
18
|
-
}>;
|
|
13
|
+
type AgentClientConfigInput = Readonly<Record<string, unknown>>;
|
|
19
14
|
|
|
20
15
|
type AgentClientDiagnosticCode =
|
|
21
16
|
| 'INVALID_AGENT_CLIENTS'
|
|
22
17
|
| 'DUPLICATE_AGENT_CLIENT'
|
|
23
18
|
| 'MISSING_AGENT_CLIENT'
|
|
24
|
-
| 'UNKNOWN_AGENT_CLIENT'
|
|
25
|
-
| 'LEGACY_CONFLICT'
|
|
26
|
-
| 'LEGACY_VALUE_IGNORED';
|
|
19
|
+
| 'UNKNOWN_AGENT_CLIENT';
|
|
27
20
|
|
|
28
21
|
type AgentClientDiagnostic = Readonly<{
|
|
29
22
|
code: AgentClientDiagnosticCode;
|
|
@@ -31,13 +24,8 @@ type AgentClientDiagnostic = Readonly<{
|
|
|
31
24
|
}>;
|
|
32
25
|
|
|
33
26
|
type NormalizeAgentClientsResult = Readonly<{
|
|
34
|
-
source: 'canonical' | 'legacy';
|
|
35
27
|
state: AgentClientState;
|
|
36
28
|
canonical: AgentClientsConfig;
|
|
37
|
-
remainingSandboxTools: readonly string[] | undefined;
|
|
38
|
-
removeLegacyTuis: boolean;
|
|
39
|
-
changed: boolean;
|
|
40
|
-
diagnostics: readonly AgentClientDiagnostic[];
|
|
41
29
|
}>;
|
|
42
30
|
|
|
43
31
|
class AgentClientConfigError extends Error {
|
|
@@ -166,147 +154,29 @@ function serializeAgentClients(state: AgentClientState): AgentClientsConfig {
|
|
|
166
154
|
}));
|
|
167
155
|
}
|
|
168
156
|
|
|
169
|
-
function projectLegacyTuis(
|
|
170
|
-
value: unknown,
|
|
171
|
-
diagnostics: AgentClientDiagnostic[]
|
|
172
|
-
): Readonly<Record<AgentClientId, boolean>> {
|
|
173
|
-
if (!Array.isArray(value)) {
|
|
174
|
-
return Object.fromEntries(
|
|
175
|
-
AGENT_CLIENT_IDS.map((id) => [id, true])
|
|
176
|
-
) as Readonly<Record<AgentClientId, boolean>>;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const enabled = new Set<AgentClientId>();
|
|
180
|
-
for (const [index, candidate] of value.entries()) {
|
|
181
|
-
if (isAgentClientId(candidate)) {
|
|
182
|
-
enabled.add(candidate);
|
|
183
|
-
} else {
|
|
184
|
-
diagnostics.push({
|
|
185
|
-
code: 'LEGACY_VALUE_IGNORED',
|
|
186
|
-
path: `tuis[${index}]`
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return Object.fromEntries(
|
|
191
|
-
AGENT_CLIENT_IDS.map((id) => [id, enabled.has(id)])
|
|
192
|
-
) as Readonly<Record<AgentClientId, boolean>>;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
type SandboxProjection = Readonly<{
|
|
196
|
-
installed: Readonly<Record<AgentClientId, boolean>>;
|
|
197
|
-
clientSignals: ReadonlySet<AgentClientId>;
|
|
198
|
-
remainingTools: readonly string[] | undefined;
|
|
199
|
-
}>;
|
|
200
|
-
|
|
201
|
-
function projectLegacySandbox(
|
|
202
|
-
value: unknown,
|
|
203
|
-
diagnostics: AgentClientDiagnostic[]
|
|
204
|
-
): SandboxProjection {
|
|
205
|
-
if (!Array.isArray(value) || value.length === 0) {
|
|
206
|
-
return {
|
|
207
|
-
installed: Object.fromEntries(
|
|
208
|
-
AGENT_CLIENT_IDS.map((id) => [id, true])
|
|
209
|
-
) as Readonly<Record<AgentClientId, boolean>>,
|
|
210
|
-
clientSignals: new Set<AgentClientId>(),
|
|
211
|
-
remainingTools: Array.isArray(value) ? [] : undefined
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
const installed = new Set<AgentClientId>();
|
|
216
|
-
const remainingTools: string[] = [];
|
|
217
|
-
for (const [index, candidate] of value.entries()) {
|
|
218
|
-
if (isAgentClientId(candidate)) {
|
|
219
|
-
installed.add(candidate);
|
|
220
|
-
} else if (typeof candidate === 'string') {
|
|
221
|
-
remainingTools.push(candidate);
|
|
222
|
-
} else {
|
|
223
|
-
diagnostics.push({
|
|
224
|
-
code: 'LEGACY_VALUE_IGNORED',
|
|
225
|
-
path: `sandbox.tools[${index}]`
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
return {
|
|
230
|
-
installed: Object.fromEntries(
|
|
231
|
-
AGENT_CLIENT_IDS.map((id) => [id, installed.has(id)])
|
|
232
|
-
) as Readonly<Record<AgentClientId, boolean>>,
|
|
233
|
-
clientSignals: installed,
|
|
234
|
-
remainingTools
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function stateFromLegacy(
|
|
239
|
-
enabled: Readonly<Record<AgentClientId, boolean>>,
|
|
240
|
-
installed: Readonly<Record<AgentClientId, boolean>>
|
|
241
|
-
): AgentClientState {
|
|
242
|
-
return Object.fromEntries(
|
|
243
|
-
AGENT_CLIENT_IDS.map((id) => [
|
|
244
|
-
id,
|
|
245
|
-
{
|
|
246
|
-
enabled: enabled[id],
|
|
247
|
-
installInSandbox: installed[id]
|
|
248
|
-
}
|
|
249
|
-
])
|
|
250
|
-
) as AgentClientState;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function sameCanonicalOrder(value: unknown): boolean {
|
|
254
|
-
return Array.isArray(value)
|
|
255
|
-
&& value.every((entry, index) => isRecord(entry) && entry.id === AGENT_CLIENT_IDS[index]);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
157
|
function normalizeAgentClients(
|
|
259
158
|
input: AgentClientConfigInput
|
|
260
159
|
): NormalizeAgentClientsResult {
|
|
261
|
-
|
|
262
|
-
const hasCanonical = hasOwn(input, 'agentClients');
|
|
263
|
-
const hasLegacyTuis = hasOwn(input, 'tuis');
|
|
264
|
-
const sandbox = isRecord(input.sandbox) ? input.sandbox : undefined;
|
|
265
|
-
const hasLegacySandboxTools = sandbox !== undefined && hasOwn(sandbox, 'tools');
|
|
266
|
-
const tuiProjection = projectLegacyTuis(input.tuis, diagnostics);
|
|
267
|
-
const sandboxProjection = projectLegacySandbox(sandbox?.tools, diagnostics);
|
|
268
|
-
|
|
269
|
-
if (!hasCanonical) {
|
|
270
|
-
const state = stateFromLegacy(tuiProjection, sandboxProjection.installed);
|
|
271
|
-
return {
|
|
272
|
-
source: 'legacy',
|
|
273
|
-
state,
|
|
274
|
-
canonical: serializeAgentClients(state),
|
|
275
|
-
remainingSandboxTools: sandboxProjection.remainingTools,
|
|
276
|
-
removeLegacyTuis: hasLegacyTuis,
|
|
277
|
-
changed: true,
|
|
278
|
-
diagnostics
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
160
|
+
if (!hasOwn(input, 'agentClients')) fail('MISSING_AGENT_CLIENT', 'agentClients');
|
|
282
161
|
const state = parseCanonical(input.agentClients);
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
}
|
|
162
|
+
for (const [index, id] of AGENT_CLIENT_IDS.entries()) {
|
|
163
|
+
const entry = Array.isArray(input.agentClients) ? input.agentClients[index] : undefined;
|
|
164
|
+
if (!isRecord(entry) || entry.id !== id) {
|
|
165
|
+
fail('INVALID_AGENT_CLIENTS', `agentClients[${index}].id`);
|
|
288
166
|
}
|
|
289
167
|
}
|
|
290
|
-
if (
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
168
|
+
if (hasOwn(input, 'tuis')) fail('INVALID_AGENT_CLIENTS', 'tuis');
|
|
169
|
+
const sandbox = isRecord(input.sandbox) ? input.sandbox : undefined;
|
|
170
|
+
if (Array.isArray(sandbox?.tools)) {
|
|
171
|
+
for (const [index, tool] of sandbox.tools.entries()) {
|
|
172
|
+
if (isAgentClientId(tool)) {
|
|
173
|
+
fail('INVALID_AGENT_CLIENTS', `sandbox.tools[${index}]`);
|
|
294
174
|
}
|
|
295
175
|
}
|
|
296
176
|
}
|
|
297
|
-
|
|
298
177
|
return {
|
|
299
|
-
source: 'canonical',
|
|
300
178
|
state,
|
|
301
|
-
canonical: serializeAgentClients(state)
|
|
302
|
-
remainingSandboxTools: hasLegacySandboxTools
|
|
303
|
-
? sandboxProjection.remainingTools
|
|
304
|
-
: undefined,
|
|
305
|
-
removeLegacyTuis: hasLegacyTuis,
|
|
306
|
-
changed: hasLegacyTuis
|
|
307
|
-
|| sandboxProjection.clientSignals.size > 0
|
|
308
|
-
|| !sameCanonicalOrder(input.agentClients),
|
|
309
|
-
diagnostics
|
|
179
|
+
canonical: serializeAgentClients(state)
|
|
310
180
|
};
|
|
311
181
|
}
|
|
312
182
|
|
|
@@ -32,7 +32,6 @@ type AgentClientSeedOperation = Readonly<{
|
|
|
32
32
|
type WorkflowDiagnostic = AgentClientDiagnostic | Readonly<{ code: string; path: string }>;
|
|
33
33
|
|
|
34
34
|
type AgentClientWorkflowPlan = Readonly<{
|
|
35
|
-
source: 'canonical' | 'legacy';
|
|
36
35
|
before: AgentClientState;
|
|
37
36
|
desired: AgentClientState;
|
|
38
37
|
nextConfig: Record<string, unknown>;
|
|
@@ -149,15 +148,6 @@ function planAgentClientReconciliation(input: Readonly<{
|
|
|
149
148
|
|
|
150
149
|
const nextConfig = structuredClone(input.config);
|
|
151
150
|
nextConfig.agentClients = serializeAgentClients(desired);
|
|
152
|
-
delete nextConfig.tuis;
|
|
153
|
-
if (normalized.remainingSandboxTools !== undefined) {
|
|
154
|
-
const sandbox = isRecord(nextConfig.sandbox) ? { ...nextConfig.sandbox } : {};
|
|
155
|
-
sandbox.tools = [
|
|
156
|
-
'agent-infra',
|
|
157
|
-
...normalized.remainingSandboxTools.filter((tool) => tool !== 'agent-infra')
|
|
158
|
-
];
|
|
159
|
-
nextConfig.sandbox = sandbox;
|
|
160
|
-
}
|
|
161
151
|
const existingFiles = isRecord(nextConfig.files) ? nextConfig.files : {};
|
|
162
152
|
const existingBaselines = isRecord(existingFiles.managedBaselines)
|
|
163
153
|
? existingFiles.managedBaselines
|
|
@@ -240,14 +230,13 @@ function planAgentClientReconciliation(input: Readonly<{
|
|
|
240
230
|
|| actionableSeed;
|
|
241
231
|
|
|
242
232
|
return Object.freeze({
|
|
243
|
-
source: normalized.source,
|
|
244
233
|
before: normalized.state,
|
|
245
234
|
desired,
|
|
246
235
|
nextConfig,
|
|
247
236
|
projectAssets,
|
|
248
237
|
seedOperations: Object.freeze(seedOperations),
|
|
249
238
|
nextSteps,
|
|
250
|
-
diagnostics: Object.freeze([...
|
|
239
|
+
diagnostics: Object.freeze([...custom.diagnostics]),
|
|
251
240
|
changed,
|
|
252
241
|
projectRoot: input.projectRoot,
|
|
253
242
|
configPath: path.join(input.projectRoot, '.agents', '.airc.json')
|
|
@@ -15,14 +15,15 @@ const AGENT_CLIENTS_SCHEMA = {
|
|
|
15
15
|
maxItems: AGENT_CLIENT_IDS.length,
|
|
16
16
|
uniqueItems: true,
|
|
17
17
|
description: 'Canonical Agent Client configuration. Object ID completeness and uniqueness are enforced by the runtime normalizer.',
|
|
18
|
-
|
|
18
|
+
additionalItems: false,
|
|
19
|
+
items: AGENT_CLIENT_IDS.map((id) => ({
|
|
19
20
|
type: 'object',
|
|
20
21
|
additionalProperties: false,
|
|
21
22
|
required: ['id', 'enabled', 'installInSandbox'],
|
|
22
23
|
properties: {
|
|
23
24
|
id: {
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const: id,
|
|
26
|
+
type: 'string'
|
|
26
27
|
},
|
|
27
28
|
enabled: {
|
|
28
29
|
type: 'boolean'
|
|
@@ -40,7 +41,7 @@ const AGENT_CLIENTS_SCHEMA = {
|
|
|
40
41
|
}
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
|
-
}
|
|
44
|
+
}))
|
|
44
45
|
},
|
|
45
46
|
customTUIs: {
|
|
46
47
|
type: 'array',
|
|
@@ -1,33 +1,20 @@
|
|
|
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
|
-
// internal commands and the rendering side share one definition.
|
|
4
|
-
// Gemini tokens remain read-only and are handled by classifyAgent below.
|
|
3
|
+
// internal commands and the rendering side share one definition.
|
|
5
4
|
export const KNOWN_AI_AGENTS: ReadonlySet<string> =
|
|
6
|
-
new Set(['claude', 'codex', 'antigravity', 'opencode', 'cursor']);
|
|
5
|
+
new Set(['claude', 'codex', 'antigravity', 'opencode', 'cursor', 'traecli']);
|
|
7
6
|
|
|
8
|
-
// Long name -> short name mapping
|
|
9
|
-
//
|
|
10
|
-
// client. `gemini-cli` is intentionally not writable.
|
|
7
|
+
// Long name -> short name mapping: `claude-code` reuses the existing
|
|
8
|
+
// orchestration precedent, and `antigravity-cli` is the active client.
|
|
11
9
|
export const AGENT_LONG_NAMES: Readonly<Record<string, string>> = {
|
|
12
10
|
'claude-code': 'claude',
|
|
13
11
|
'antigravity-cli': 'antigravity'
|
|
14
12
|
};
|
|
15
13
|
|
|
16
14
|
export const AGENT_USAGE_HINT =
|
|
17
|
-
"agent must be a short token (claude/codex/antigravity/opencode/cursor), " +
|
|
15
|
+
"agent must be a short token (claude/codex/antigravity/opencode/cursor/traecli), " +
|
|
18
16
|
"a long name (claude-code -> claude, antigravity-cli -> antigravity), or 'human'";
|
|
19
17
|
|
|
20
|
-
// Read-side historical compatibility for activity-log rendering: `gemini` and
|
|
21
|
-
// `gemini-cli` stay recognizable when displaying old logs, but are never
|
|
22
|
-
// accepted by normalizeAgentToken (write side).
|
|
23
|
-
const READ_KNOWN_AI_AGENTS: ReadonlySet<string> =
|
|
24
|
-
new Set([...KNOWN_AI_AGENTS, 'gemini']);
|
|
25
|
-
|
|
26
|
-
const READ_AGENT_LONG_NAMES: Readonly<Record<string, string>> = {
|
|
27
|
-
...AGENT_LONG_NAMES,
|
|
28
|
-
'gemini-cli': 'gemini'
|
|
29
|
-
};
|
|
30
|
-
|
|
31
18
|
// Strict write-side validation: the value must be exactly a short token, a
|
|
32
19
|
// long name, or 'human'; returns the normalized short token, or null when
|
|
33
20
|
// the value is not a recognized agent.
|
|
@@ -47,7 +34,7 @@ export function classifyAgent(raw: string):
|
|
|
47
34
|
const token = raw.trim().split(/\s+/)[0]?.replace(/\(.*$/, '') ?? '';
|
|
48
35
|
if (token === '') return { status: 'unknown', display: 'human' };
|
|
49
36
|
if (token === 'human') return { status: 'human', display: 'human' };
|
|
50
|
-
if (
|
|
51
|
-
const short =
|
|
37
|
+
if (KNOWN_AI_AGENTS.has(token)) return { status: 'ai', display: token };
|
|
38
|
+
const short = AGENT_LONG_NAMES[token];
|
|
52
39
|
return short ? { status: 'ai', display: short } : { status: 'unknown', display: 'human' };
|
|
53
40
|
}
|
package/lib/decide.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { parseTaskScope } from './task/command-options.ts';
|
|
|
3
3
|
import { applyHumanDecision } from './task/decision-intents.ts';
|
|
4
4
|
import { canonicalTimestamp } from './task/write.ts';
|
|
5
5
|
import { consumeHumanOverride, failureId } from './task/human-override.ts';
|
|
6
|
-
import {
|
|
6
|
+
import { resolveTaskContext } from './task/resolve-ref.ts';
|
|
7
7
|
import { TaskExecutionLockError, withTaskExecutionLock } from './task/task-execution-lock.ts';
|
|
8
8
|
|
|
9
9
|
type DecideOptions = {
|
|
@@ -55,44 +55,36 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
|
|
|
55
55
|
item = scope.positionals[++index];
|
|
56
56
|
if (!item) { process.stderr.write(`Error: ${arg} requires a value\n`); return 1; }
|
|
57
57
|
} else if (arg.startsWith('--item=')) {
|
|
58
|
-
|
|
59
|
-
item = arg.slice('--item='.length);
|
|
60
|
-
if (item === '') { process.stderr.write('Error: --item requires a value\n'); return 1; }
|
|
58
|
+
process.stderr.write('Error: --item=... is not supported; use --item <selector> or -i <selector>\n'); return 1;
|
|
61
59
|
} else operands.push(arg);
|
|
62
60
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (item !== undefined) {
|
|
67
|
-
decisionParts = operands;
|
|
68
|
-
} else if (!scope.explicit) {
|
|
69
|
-
[taskRef, selector, ...decisionParts] = operands;
|
|
70
|
-
} else {
|
|
71
|
-
decisionParts = [];
|
|
72
|
-
}
|
|
61
|
+
const taskRef = scope.taskRef;
|
|
62
|
+
const selector = item;
|
|
63
|
+
const decisionParts = operands;
|
|
73
64
|
if (!selector || decisionParts.length === 0) {
|
|
74
|
-
process.stderr.write('Usage: ai decide [--task <ref>] --item <ordinal|ledger-id>
|
|
65
|
+
process.stderr.write('Usage: ai decide [--task <ref> | -t <ref>] (--item <ordinal|ledger-id> | -i <ordinal|ledger-id>) [--needs-implementation true|false] <decision>\n');
|
|
75
66
|
return 1;
|
|
76
67
|
}
|
|
77
68
|
try {
|
|
78
69
|
const parsedDecision = parseDecisionParts(decisionParts);
|
|
79
70
|
const now = (options.now ?? canonicalTimestamp)();
|
|
71
|
+
const resolved = resolveTaskContext(taskRef, { repoRoot: options.repoRoot });
|
|
72
|
+
if (!resolved.ok) throw new Error(resolved.message);
|
|
80
73
|
const request = {
|
|
81
|
-
taskRef, selector, decision: parsedDecision.decision,
|
|
74
|
+
taskRef: resolved.taskId, selector, decision: parsedDecision.decision,
|
|
82
75
|
needsImplementation: parsedDecision.needsImplementation
|
|
83
76
|
};
|
|
84
77
|
const writeOptions = {
|
|
85
|
-
repoRoot:
|
|
78
|
+
repoRoot: resolved.repoRoot,
|
|
86
79
|
metadataProvider: () => ({ timestamp: now, agentInfraVersion: options.version ?? VERSION })
|
|
87
80
|
};
|
|
88
|
-
const resolved = taskRef ? resolveTaskRef(taskRef, { repoRoot: options.repoRoot }) : null;
|
|
89
81
|
let result;
|
|
90
82
|
const execute = () => {
|
|
91
83
|
let current = applyHumanDecision(request, writeOptions);
|
|
92
84
|
if (current.status !== 'failed' || !parsedDecision.overrideTicket) return current;
|
|
93
85
|
if (!parsedDecision.overrideTarget || !parsedDecision.overrideScope) throw new Error('override ticket requires --override-target and --override-scope');
|
|
94
86
|
const consumed = consumeHumanOverride({
|
|
95
|
-
taskRef: resolved
|
|
87
|
+
taskRef: resolved.taskId,
|
|
96
88
|
ticketId: parsedDecision.overrideTicket,
|
|
97
89
|
failureId: failureId('decision-intent', current.error?.code ?? 'TASK_STATE_MISMATCH'),
|
|
98
90
|
target: parsedDecision.overrideTarget,
|
|
@@ -110,9 +102,7 @@ export async function decide(args: string[], options: DecideOptions = {}): Promi
|
|
|
110
102
|
if (consumed.status === 'failed') throw new Error(consumed.error.message);
|
|
111
103
|
return current;
|
|
112
104
|
};
|
|
113
|
-
result = resolved
|
|
114
|
-
? withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute)
|
|
115
|
-
: execute();
|
|
105
|
+
result = withTaskExecutionLock(resolved.repoRoot, resolved.taskId, 'task-decision', execute);
|
|
116
106
|
if (result.error) throw new Error(result.error.message);
|
|
117
107
|
return 0;
|
|
118
108
|
} catch (error) {
|
package/lib/defaults.json
CHANGED
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"id": "opencode",
|
|
23
23
|
"enabled": true,
|
|
24
24
|
"installInSandbox": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "traecli",
|
|
28
|
+
"enabled": true,
|
|
29
|
+
"installInSandbox": true
|
|
25
30
|
}
|
|
26
31
|
],
|
|
27
32
|
"sandbox": {
|
|
@@ -85,6 +90,10 @@
|
|
|
85
90
|
],
|
|
86
91
|
"ejected": [],
|
|
87
92
|
"retiredManaged": [
|
|
93
|
+
{
|
|
94
|
+
"path": ".trae/skills/",
|
|
95
|
+
"templateHashes": []
|
|
96
|
+
},
|
|
88
97
|
{
|
|
89
98
|
"path": ".agents/workspace/README.md",
|
|
90
99
|
"templateHashes": [
|
package/lib/init.ts
CHANGED
|
@@ -117,7 +117,7 @@ async function cmdInit(): Promise<void> {
|
|
|
117
117
|
// check existing config
|
|
118
118
|
if (fs.existsSync(configPath)) {
|
|
119
119
|
err('This project already has agent-infra configuration.');
|
|
120
|
-
err('Use /update-agent-infra in your AI TUI to
|
|
120
|
+
err('Use /update-agent-infra in your AI TUI to sync project files.');
|
|
121
121
|
process.exitCode = 1;
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
@@ -294,7 +294,7 @@ async function cmdInit(): Promise<void> {
|
|
|
294
294
|
console.log('');
|
|
295
295
|
ok('Project initialized successfully!');
|
|
296
296
|
console.log('');
|
|
297
|
-
console.log(' If this init used npx, install agent-infra persistently before update or validation:');
|
|
297
|
+
console.log(' If this init used npx, install agent-infra persistently before ai update or validation:');
|
|
298
298
|
console.log(' npm install -g @fitlab-ai/agent-infra');
|
|
299
299
|
console.log('');
|
|
300
300
|
if (workflowPlan.nextSteps.length === 0) {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { createCodexLifecycleStore } from '../agent-clients/adapters/codex-lifecycle/store.ts';
|
|
12
12
|
import { createCodexCapabilityStore } from '../agent-clients/adapters/codex-lifecycle/capability-store.ts';
|
|
13
13
|
import { computeLifecycleBuildIdentity } from '../agent-clients/adapters/codex-lifecycle/build-identity.ts';
|
|
14
|
-
import {
|
|
14
|
+
import { verifyCodexSandboxControllerContextWithWarnings } from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.ts';
|
|
15
15
|
import type { CodexLifecycleEvent } from '../agent-clients/adapters/codex-lifecycle/evidence.ts';
|
|
16
16
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
17
17
|
import { hasSealableOrchestrationDelegation } from '../task/orchestration.ts';
|
|
@@ -101,7 +101,7 @@ function hookDefinitionHash(): string {
|
|
|
101
101
|
function controllerBinding(taskId: string) {
|
|
102
102
|
const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
|
|
103
103
|
if (!contextPath) return undefined;
|
|
104
|
-
const context =
|
|
104
|
+
const context = verifyCodexSandboxControllerContextWithWarnings(contextPath, { repoRoot: process.cwd() }).context;
|
|
105
105
|
return {
|
|
106
106
|
instanceDigest: context.controllerInstanceDigest,
|
|
107
107
|
controlGeneration: context.controlGeneration
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runCodexSandboxController,
|
|
3
|
-
|
|
3
|
+
verifyCodexSandboxControllerContextWithWarnings
|
|
4
4
|
} from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.ts';
|
|
5
5
|
|
|
6
6
|
const USAGE = 'Usage: agent-infra-internal codex-sandbox-controller <run|verify-context> [options]\n';
|
|
@@ -58,7 +58,8 @@ async function codexSandboxController(args: string[] = []): Promise<void> {
|
|
|
58
58
|
const contextPath = parsed.values['--context']
|
|
59
59
|
?? process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
|
|
60
60
|
if (!contextPath) throw new Error('CODEX_SANDBOX_CONTROLLER_CONTEXT_MISSING');
|
|
61
|
-
const
|
|
61
|
+
const verified = verifyCodexSandboxControllerContextWithWarnings(contextPath);
|
|
62
|
+
const context = verified.context;
|
|
62
63
|
process.stdout.write(`${JSON.stringify({
|
|
63
64
|
status: 'ready',
|
|
64
65
|
changed: false,
|
|
@@ -69,8 +70,8 @@ async function codexSandboxController(args: string[] = []): Promise<void> {
|
|
|
69
70
|
expiresAt: context.expiresAt,
|
|
70
71
|
buildIdentity: context.buildIdentity,
|
|
71
72
|
hookDefinitionHash: context.hookDefinitionHash,
|
|
72
|
-
lifecycleProfilesHash: context.lifecycleProfilesHash
|
|
73
73
|
},
|
|
74
|
+
...(verified.warnings.length > 0 ? { warnings: verified.warnings } : {}),
|
|
74
75
|
error: null
|
|
75
76
|
})}\n`);
|
|
76
77
|
return;
|
|
@@ -9,7 +9,7 @@ import { serveSandboxControl } from '../sandbox/control/server.ts';
|
|
|
9
9
|
import { runSandboxControlExecutor } from '../sandbox/control/executor.ts';
|
|
10
10
|
import {
|
|
11
11
|
controllerProofFromContext,
|
|
12
|
-
|
|
12
|
+
verifyCodexSandboxControllerContextWithWarnings
|
|
13
13
|
} from '../agent-clients/adapters/codex-lifecycle/sandbox-controller.ts';
|
|
14
14
|
|
|
15
15
|
function isCanonicalCodexPrepare(args: readonly string[]): boolean {
|
|
@@ -118,7 +118,7 @@ async function sandboxControl(args: string[]): Promise<void> {
|
|
|
118
118
|
if (family === 'task-orchestration' && isCanonicalCodexPrepare(commandArgs)) {
|
|
119
119
|
const contextPath = process.env.AGENT_INFRA_CODEX_CONTROLLER_CONTEXT;
|
|
120
120
|
const proof = contextPath
|
|
121
|
-
? controllerProofFromContext(
|
|
121
|
+
? controllerProofFromContext(verifyCodexSandboxControllerContextWithWarnings(contextPath).context)
|
|
122
122
|
: null;
|
|
123
123
|
response = requestSandboxTaskControl({ family, args: commandArgs, controllerProof: proof });
|
|
124
124
|
} else {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createDirectHostExecutionContext,
|
|
3
|
+
dispatchTaskControlOperation,
|
|
4
|
+
parseTaskControlOperation
|
|
5
|
+
} from '../task/control-authority.ts';
|
|
2
6
|
import { applyTaskFinalization } from '../task/finalization.ts';
|
|
3
7
|
import { detectRepoRoot, resolveTaskRef } from '../task/resolve-ref.ts';
|
|
4
|
-
import { verifyTaskEvent } from '../task/verification.ts';
|
|
5
8
|
|
|
6
9
|
const USAGE = 'Usage: agent-infra-internal task-finalization <N | TASK-id> complete --agent <agent>\n';
|
|
7
10
|
|
|
@@ -28,17 +31,26 @@ function fail(message: string): void {
|
|
|
28
31
|
process.exitCode = 1;
|
|
29
32
|
}
|
|
30
33
|
|
|
34
|
+
function parseFailure(error: unknown): string {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
return message.replace(/^TASK_CONTROL_OPERATION_INVALID: /u, '');
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
function taskFinalization(args: string[] = []): void {
|
|
32
40
|
if (args[0] === '--help' || args[0] === '-h') { process.stdout.write(USAGE); return; }
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
|
|
42
|
+
let operation;
|
|
43
|
+
try {
|
|
44
|
+
operation = parseTaskControlOperation('task-finalization', args);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
fail(parseFailure(error));
|
|
35
47
|
return;
|
|
36
48
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fail(`invalid --agent: ${AGENT_USAGE_HINT}`);
|
|
49
|
+
if (operation.family !== 'task-finalization') {
|
|
50
|
+
fail('finalization operation is invalid');
|
|
40
51
|
return;
|
|
41
52
|
}
|
|
53
|
+
|
|
42
54
|
let repoRoot: string;
|
|
43
55
|
try {
|
|
44
56
|
repoRoot = detectRepoRoot();
|
|
@@ -48,18 +60,20 @@ function taskFinalization(args: string[] = []): void {
|
|
|
48
60
|
process.exitCode = 1;
|
|
49
61
|
return;
|
|
50
62
|
}
|
|
51
|
-
const resolved = resolveTaskRef(
|
|
63
|
+
const resolved = resolveTaskRef(operation.request.taskRef, { repoRoot });
|
|
52
64
|
if (!resolved.ok) {
|
|
53
65
|
const detail = { code: resolved.code, message: resolved.message, retryable: false };
|
|
54
66
|
process.stdout.write(envelope('failed', false, true, null, detail));
|
|
55
67
|
process.exitCode = 1;
|
|
56
68
|
return;
|
|
57
69
|
}
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
70
|
+
const boundOperation = {
|
|
71
|
+
...operation,
|
|
72
|
+
request: { ...operation.request, taskRef: resolved.taskId }
|
|
73
|
+
};
|
|
74
|
+
const result = dispatchTaskControlOperation(
|
|
75
|
+
createDirectHostExecutionContext({ repoRoot }),
|
|
76
|
+
boundOperation
|
|
63
77
|
);
|
|
64
78
|
process.stdout.write(envelope(result.status, result.changed, true, result, result.error));
|
|
65
79
|
process.exitCode = exitCode(result.status);
|
|
@@ -3,7 +3,7 @@ import fs from 'node:fs';
|
|
|
3
3
|
import { applyLedgerIntent } from '../task/ledger-intents.ts';
|
|
4
4
|
import type { LedgerIntent } from '../task/ledger-intents.ts';
|
|
5
5
|
import { consumeHumanOverride, failureId, overrideDryRunConflict } from '../task/human-override.ts';
|
|
6
|
-
import { isReviewStage,
|
|
6
|
+
import { LEDGER_SECTION_MISSING_CODE, LEDGER_SECTION_MISSING_MESSAGE, isReviewStage, parseLedgerDocument, summarizeLedgerStage, validateLedgerRows } from '../task/ledger.ts';
|
|
7
7
|
import { resolveTaskRef } from '../task/resolve-ref.ts';
|
|
8
8
|
import { TaskExecutionLockError, withTaskExecutionLock } from '../task/task-execution-lock.ts';
|
|
9
9
|
|
|
@@ -81,7 +81,13 @@ function taskLedger(args: string[] = []): void {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
try {
|
|
84
|
-
const
|
|
84
|
+
const ledger = parseLedgerDocument(fs.readFileSync(resolved.taskMdPath, 'utf8'));
|
|
85
|
+
if (!ledger.present) {
|
|
86
|
+
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, taskId: resolved.taskId, error: { code: LEDGER_SECTION_MISSING_CODE, message: LEDGER_SECTION_MISSING_MESSAGE } })}\n`);
|
|
87
|
+
process.exitCode = 1;
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const rows = ledger.rows;
|
|
85
91
|
const invalid = validateLedgerRows(rows);
|
|
86
92
|
if (invalid) {
|
|
87
93
|
process.stdout.write(`${JSON.stringify({ status: 'failed', changed: false, taskId: resolved.taskId, error: invalid })}\n`);
|