@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
|
@@ -126,10 +126,12 @@ function defaultProbe(manifest, identity) {
|
|
|
126
126
|
function assertRegistrationBinding(registration, manifest, buildIdentity) {
|
|
127
127
|
if (registration.taskId !== manifest.taskId
|
|
128
128
|
|| registration.controlGeneration !== manifest.generation
|
|
129
|
-
|| registration.containerId !== manifest.containerIdentity.id
|
|
130
|
-
|| JSON.stringify(registration.buildIdentity) !== JSON.stringify(buildIdentity)) {
|
|
129
|
+
|| registration.containerId !== manifest.containerIdentity.id) {
|
|
131
130
|
fail('CODEX_SANDBOX_CONTROLLER_REGISTRATION_INVALID', 'controller registration binding is invalid');
|
|
132
131
|
}
|
|
132
|
+
if (registration.buildIdentity.protocolVersion !== buildIdentity.protocolVersion) {
|
|
133
|
+
fail('CODEX_LIFECYCLE_PROTOCOL_MISMATCH', 'Codex lifecycle protocol version does not match');
|
|
134
|
+
}
|
|
133
135
|
}
|
|
134
136
|
function atomicWrite(file, value) {
|
|
135
137
|
const temporary = path.join(path.dirname(file), `.${path.basename(file)}.${process.pid}.${crypto.randomUUID()}.tmp`);
|
|
@@ -1,15 +1,32 @@
|
|
|
1
|
-
import { spawn
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
5
5
|
import { getProcessStartTime } from '../../server/process-state.js';
|
|
6
6
|
import { createTask } from '../../task/create-service.js';
|
|
7
7
|
import { applyTaskFinalization } from '../../task/finalization.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { bindSandboxControlTask, validateSandboxControlRequest } from './protocol.js';
|
|
9
|
+
import { atomicWriteJson, executionPath, readActiveLease, terminateSandboxControlExecution } from './state.js';
|
|
10
|
+
import { createSandboxExecutorExecutionContext, dispatchTaskControlOperation, parseTaskControlOperation } from '../../task/control-authority.js';
|
|
11
|
+
import { assertSandboxControlBrokerOwner, readSandboxControlManifest } from './lifecycle.js';
|
|
11
12
|
import { computeLifecycleBuildIdentity } from '../../agent-clients/adapters/codex-lifecycle/build-identity.js';
|
|
12
13
|
import { closeCodexControllerRegistration, CodexControllerRegistrationError, openCodexControllerRegistration, resolveCodexControllerBinding } from './controller-registration.js';
|
|
14
|
+
function sameBrokerOwner(left, right) {
|
|
15
|
+
return left.version === right.version
|
|
16
|
+
&& left.pid === right.pid
|
|
17
|
+
&& left.startTime === right.startTime
|
|
18
|
+
&& left.brokerId === right.brokerId
|
|
19
|
+
&& left.token === right.token
|
|
20
|
+
&& left.generation === right.generation;
|
|
21
|
+
}
|
|
22
|
+
export function assertSandboxControlExecutorAuthority(manifest, gateOwner) {
|
|
23
|
+
const owner = assertSandboxControlBrokerOwner(manifest);
|
|
24
|
+
if (gateOwner && !sameBrokerOwner(owner, gateOwner)) {
|
|
25
|
+
throw new Error('SANDBOX_CONTROL_GATE_OWNER_MISMATCH');
|
|
26
|
+
}
|
|
27
|
+
if (readActiveLease(manifest))
|
|
28
|
+
throw new Error('SANDBOX_CONTROL_HANDOFF_ACTIVE');
|
|
29
|
+
}
|
|
13
30
|
function safeEnv(env) {
|
|
14
31
|
return Object.fromEntries(Object.entries(env).filter(([key]) => !key.toUpperCase().startsWith('AGENT_INFRA_CONTROL_')));
|
|
15
32
|
}
|
|
@@ -74,12 +91,15 @@ export async function prepareSandboxControlExecution(params) {
|
|
|
74
91
|
start(canWrite = () => true) {
|
|
75
92
|
if (!child.connected)
|
|
76
93
|
throw new Error('SANDBOX_CONTROL_EXECUTOR_GATE_CLOSED');
|
|
94
|
+
if (!canWrite())
|
|
95
|
+
throw new Error('SANDBOX_CONTROL_OWNER_LOST');
|
|
96
|
+
const gateOwner = assertSandboxControlBrokerOwner(params.manifest);
|
|
77
97
|
if (!canWrite())
|
|
78
98
|
throw new Error('SANDBOX_CONTROL_OWNER_LOST');
|
|
79
99
|
atomicWriteJson(executionPath(params.manifest, params.request.id), { ...execution, phase: 'running', updatedAt: Date.now() });
|
|
80
100
|
if (!canWrite())
|
|
81
101
|
throw new Error('SANDBOX_CONTROL_OWNER_LOST');
|
|
82
|
-
child.send({ version: 1, nonce });
|
|
102
|
+
child.send({ version: 1, nonce, owner: gateOwner });
|
|
83
103
|
},
|
|
84
104
|
completion,
|
|
85
105
|
terminate(updateState = true) {
|
|
@@ -104,11 +124,16 @@ function waitForGate(nonce, timeoutMs = 2_000) {
|
|
|
104
124
|
clearTimeout(timer);
|
|
105
125
|
process.off('disconnect', onDisconnect);
|
|
106
126
|
const value = message;
|
|
107
|
-
|
|
127
|
+
const owner = value?.owner;
|
|
128
|
+
if (!value || value.version !== 1 || value.nonce !== nonce
|
|
129
|
+
|| !owner || owner.version !== 3 || !Number.isSafeInteger(owner.pid) || (owner.pid ?? 0) <= 0
|
|
130
|
+
|| typeof owner.startTime !== 'number' || !Number.isSafeInteger(owner.startTime)
|
|
131
|
+
|| typeof owner.brokerId !== 'string' || owner.brokerId.length === 0
|
|
132
|
+
|| typeof owner.token !== 'string' || typeof owner.generation !== 'string') {
|
|
108
133
|
reject(new Error('SANDBOX_CONTROL_EXECUTOR_GATE_INVALID'));
|
|
109
134
|
return;
|
|
110
135
|
}
|
|
111
|
-
resolve();
|
|
136
|
+
resolve(owner);
|
|
112
137
|
});
|
|
113
138
|
});
|
|
114
139
|
}
|
|
@@ -117,12 +142,15 @@ function controllerFailure(error) {
|
|
|
117
142
|
? error.code
|
|
118
143
|
: /^([A-Z][A-Z0-9_]+)/u.exec(error instanceof Error ? error.message : String(error))?.[1]
|
|
119
144
|
?? 'CODEX_SANDBOX_CONTROLLER_FAILED';
|
|
145
|
+
const message = error instanceof CodexControllerRegistrationError
|
|
146
|
+
? error.message
|
|
147
|
+
: `${code}: controller operation failed; inspect the sandbox controller and rebuild the sandbox if needed`;
|
|
120
148
|
const payload = {
|
|
121
149
|
version: 1,
|
|
122
150
|
status: 'failed',
|
|
123
151
|
changed: false,
|
|
124
152
|
lease: null,
|
|
125
|
-
error: { code, message
|
|
153
|
+
error: { code, message, retryable: false }
|
|
126
154
|
};
|
|
127
155
|
return { exitCode: 1, stdout: `${JSON.stringify(payload)}\n`, stderr: '' };
|
|
128
156
|
}
|
|
@@ -136,6 +164,16 @@ function orchestrationFailure(code, message) {
|
|
|
136
164
|
stderr: ''
|
|
137
165
|
};
|
|
138
166
|
}
|
|
167
|
+
function lifecycleFailure(code, message) {
|
|
168
|
+
return {
|
|
169
|
+
exitCode: 1,
|
|
170
|
+
stdout: `${JSON.stringify({
|
|
171
|
+
status: 'failed', changed: false,
|
|
172
|
+
error: { code, message }
|
|
173
|
+
})}\n`,
|
|
174
|
+
stderr: ''
|
|
175
|
+
};
|
|
176
|
+
}
|
|
139
177
|
function finalizationResult(result) {
|
|
140
178
|
const payload = {
|
|
141
179
|
version: 1,
|
|
@@ -151,19 +189,7 @@ function finalizationResult(result) {
|
|
|
151
189
|
stderr: ''
|
|
152
190
|
};
|
|
153
191
|
}
|
|
154
|
-
function
|
|
155
|
-
if (args[1] !== 'prepare')
|
|
156
|
-
return false;
|
|
157
|
-
const values = [];
|
|
158
|
-
for (let index = 2; index < args.length; index += 1) {
|
|
159
|
-
if (args[index] === '--client')
|
|
160
|
-
values.push(args[index + 1] ?? '');
|
|
161
|
-
else if (args[index]?.startsWith('--client='))
|
|
162
|
-
values.push(args[index].slice('--client='.length));
|
|
163
|
-
}
|
|
164
|
-
return values.length === 1 && values[0] === 'codex';
|
|
165
|
-
}
|
|
166
|
-
export function executeRequest(manifest, manifestPath, request, options = {}) {
|
|
192
|
+
export async function executeRequest(manifest, manifestPath, request, options = {}) {
|
|
167
193
|
if (request.family === 'task-create') {
|
|
168
194
|
const result = createTask(request.candidate, { repoRoot: manifest.repoRoot });
|
|
169
195
|
return {
|
|
@@ -217,12 +243,41 @@ export function executeRequest(manifest, manifestPath, request, options = {}) {
|
|
|
217
243
|
}
|
|
218
244
|
}
|
|
219
245
|
if (request.family === 'task-finalization') {
|
|
220
|
-
|
|
246
|
+
const operation = parseTaskControlOperation('task-finalization', [manifest.taskId, 'complete', '--agent', request.agent]);
|
|
247
|
+
if (operation.family !== 'task-finalization')
|
|
248
|
+
throw new Error('SANDBOX_CONTROL_FINALIZATION_OPERATION_INVALID');
|
|
249
|
+
const result = dispatchTaskControlOperation(createSandboxExecutorExecutionContext({
|
|
250
|
+
repoRoot: manifest.repoRoot,
|
|
251
|
+
worktreeRoot: manifest.worktreeRoot,
|
|
252
|
+
runtimeDir: manifest.runtimeDir,
|
|
253
|
+
taskId: manifest.taskId,
|
|
254
|
+
generation: manifest.generation,
|
|
255
|
+
manifestPath,
|
|
256
|
+
requestId: request.id
|
|
257
|
+
}), operation);
|
|
258
|
+
return finalizationResult(result);
|
|
221
259
|
}
|
|
222
260
|
const boundArgs = bindSandboxControlTask(request, manifest.taskId);
|
|
261
|
+
if (request.family === 'task-orchestration') {
|
|
262
|
+
boundArgs.push('--git-worktree-root', manifest.worktreeRoot);
|
|
263
|
+
}
|
|
264
|
+
let operation;
|
|
265
|
+
try {
|
|
266
|
+
operation = parseTaskControlOperation(request.family, boundArgs);
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
270
|
+
const code = /^([A-Z][A-Z0-9_]+)/u.exec(message)?.[1] ?? 'TASK_CONTROL_OPERATION_INVALID';
|
|
271
|
+
return request.family === 'task-lifecycle'
|
|
272
|
+
? lifecycleFailure('LIFECYCLE_PAYLOAD_INVALID', message)
|
|
273
|
+
: orchestrationFailure(code, message);
|
|
274
|
+
}
|
|
223
275
|
let controllerBinding = null;
|
|
224
276
|
if (request.family === 'task-orchestration') {
|
|
225
|
-
|
|
277
|
+
const codexPrepare = operation.family === 'task-orchestration'
|
|
278
|
+
&& operation.intent === 'prepare'
|
|
279
|
+
&& operation.input.client === 'codex';
|
|
280
|
+
if (codexPrepare) {
|
|
226
281
|
if (!request.controllerProof) {
|
|
227
282
|
return orchestrationFailure('CODEX_SANDBOX_CONTROLLER_PROOF_REQUIRED', 'Codex prepare requires a current controller lease proof');
|
|
228
283
|
}
|
|
@@ -244,33 +299,73 @@ export function executeRequest(manifest, manifestPath, request, options = {}) {
|
|
|
244
299
|
else if (request.controllerProof !== null) {
|
|
245
300
|
return orchestrationFailure('CODEX_SANDBOX_CONTROLLER_PROOF_INVALID', 'Controller proof is only accepted for canonical Codex prepare');
|
|
246
301
|
}
|
|
247
|
-
boundArgs.push('--git-worktree-root', manifest.worktreeRoot);
|
|
248
302
|
}
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
303
|
+
const context = createSandboxExecutorExecutionContext({
|
|
304
|
+
repoRoot: manifest.repoRoot,
|
|
305
|
+
worktreeRoot: manifest.worktreeRoot,
|
|
306
|
+
runtimeDir: manifest.runtimeDir,
|
|
307
|
+
taskId: manifest.taskId,
|
|
308
|
+
generation: manifest.generation,
|
|
309
|
+
manifestPath,
|
|
310
|
+
requestId: request.id,
|
|
311
|
+
...(controllerBinding ? { controllerBinding } : {})
|
|
259
312
|
});
|
|
260
|
-
|
|
313
|
+
const format = (value) => {
|
|
314
|
+
const result = value;
|
|
315
|
+
return {
|
|
316
|
+
exitCode: result.status === 'failed' ? 1 : 0,
|
|
317
|
+
stdout: `${JSON.stringify(value)}\n`,
|
|
318
|
+
stderr: ''
|
|
319
|
+
};
|
|
320
|
+
};
|
|
321
|
+
if (request.family === 'task-orchestration') {
|
|
322
|
+
if (operation.family !== 'task-orchestration')
|
|
323
|
+
throw new Error('SANDBOX_CONTROL_ORCHESTRATION_OPERATION_INVALID');
|
|
324
|
+
return format(await dispatchTaskControlOperation(context, operation));
|
|
325
|
+
}
|
|
326
|
+
if (operation.family !== 'task-lifecycle')
|
|
327
|
+
throw new Error('SANDBOX_CONTROL_LIFECYCLE_OPERATION_INVALID');
|
|
328
|
+
return format(dispatchTaskControlOperation(context, operation));
|
|
261
329
|
}
|
|
262
330
|
export async function runSandboxControlExecutor(requestPath, nonce) {
|
|
263
|
-
await waitForGate(nonce);
|
|
331
|
+
const gateOwner = await waitForGate(nonce);
|
|
264
332
|
process.disconnect?.();
|
|
265
|
-
const root = fs.realpathSync.native(process.cwd());
|
|
266
|
-
const request = JSON.parse(fs.readFileSync(requestPath, 'utf8'));
|
|
267
333
|
const manifestPath = process.env.AGENT_INFRA_EXECUTOR_MANIFEST;
|
|
268
334
|
if (!manifestPath)
|
|
269
335
|
throw new Error('SANDBOX_CONTROL_EXECUTOR_MANIFEST_MISSING');
|
|
270
|
-
const manifest =
|
|
336
|
+
const manifest = readSandboxControlManifest(manifestPath);
|
|
337
|
+
const root = fs.realpathSync.native(process.cwd());
|
|
271
338
|
if (fs.realpathSync.native(manifest.repoRoot) !== root)
|
|
272
339
|
throw new Error('SANDBOX_CONTROL_EXECUTOR_ROOT_INVALID');
|
|
273
|
-
const
|
|
340
|
+
const raw = JSON.parse(fs.readFileSync(requestPath, 'utf8'));
|
|
341
|
+
const request = validateSandboxControlRequest(raw, manifest);
|
|
342
|
+
const requestDirectory = path.resolve(path.dirname(requestPath));
|
|
343
|
+
const processingDirectory = path.resolve(path.join(manifest.processingDir, request.id));
|
|
344
|
+
const channelRequestDirectory = path.resolve(path.join(manifest.channelDir, 'requests'));
|
|
345
|
+
if (requestDirectory !== processingDirectory && requestDirectory !== channelRequestDirectory) {
|
|
346
|
+
throw new Error('SANDBOX_CONTROL_EXECUTOR_REQUEST_INVALID');
|
|
347
|
+
}
|
|
348
|
+
let result;
|
|
349
|
+
try {
|
|
350
|
+
assertSandboxControlExecutorAuthority(manifest, gateOwner);
|
|
351
|
+
result = await executeRequest(manifest, manifestPath, request);
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
355
|
+
const code = /^([A-Z][A-Z0-9_]+)/u.exec(detail)?.[1] ?? 'SANDBOX_CONTROL_EXECUTOR_FAILED';
|
|
356
|
+
result = request.family === 'task-finalization'
|
|
357
|
+
? {
|
|
358
|
+
exitCode: 1,
|
|
359
|
+
stdout: `${JSON.stringify({
|
|
360
|
+
version: 1, status: 'failed', changed: false, accepted: true, result: null,
|
|
361
|
+
error: { code, message: detail, retryable: false }
|
|
362
|
+
})}\n`,
|
|
363
|
+
stderr: ''
|
|
364
|
+
}
|
|
365
|
+
: request.family === 'task-lifecycle'
|
|
366
|
+
? lifecycleFailure(code, detail)
|
|
367
|
+
: orchestrationFailure(code, detail);
|
|
368
|
+
}
|
|
274
369
|
process.stdout.write(result.stdout);
|
|
275
370
|
process.stderr.write(result.stderr);
|
|
276
371
|
process.exitCode = result.exitCode;
|
|
@@ -414,8 +414,6 @@ function readProcessingSnapshot(root) {
|
|
|
414
414
|
export function captureSandboxControlCutoverSnapshot(root) {
|
|
415
415
|
const resolvedRoot = path.resolve(root);
|
|
416
416
|
const manifestPath = path.join(resolvedRoot, 'manifest.json');
|
|
417
|
-
if (fs.existsSync(manifestPath))
|
|
418
|
-
readSandboxControlManifestForTransition(manifestPath);
|
|
419
417
|
return {
|
|
420
418
|
root: resolvedRoot,
|
|
421
419
|
manifestRaw: readOptionalRaw(manifestPath),
|
|
@@ -430,7 +428,7 @@ export function assertSandboxControlCutoverSnapshot(snapshot) {
|
|
|
430
428
|
throw new Error('SANDBOX_CONTROL_OWNER_TRANSITION');
|
|
431
429
|
}
|
|
432
430
|
}
|
|
433
|
-
function readSandboxControlManifestValue(manifestPath
|
|
431
|
+
function readSandboxControlManifestValue(manifestPath) {
|
|
434
432
|
if (!regularFile(manifestPath))
|
|
435
433
|
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
436
434
|
let manifest;
|
|
@@ -445,8 +443,14 @@ function readSandboxControlManifestValue(manifestPath, allowLegacy) {
|
|
|
445
443
|
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
446
444
|
}
|
|
447
445
|
const candidate = manifest;
|
|
448
|
-
|
|
449
|
-
|
|
446
|
+
const expectedKeys = [
|
|
447
|
+
'branch', 'channelDir', 'container', 'containerIdentity', 'engine', 'generation',
|
|
448
|
+
'mode', 'processingDir', 'project', 'publicStatusDir', 'repoRoot', 'runtimeDir',
|
|
449
|
+
'taskId', 'token', 'worktreeRoot'
|
|
450
|
+
];
|
|
451
|
+
if ('version' in candidate || typeof candidate.runtimeDir !== 'string'
|
|
452
|
+
|| Object.keys(manifest).sort().join(',') !== expectedKeys.sort().join(',')) {
|
|
453
|
+
throw new Error('SANDBOX_CONTROL_MANIFEST_REBUILD_REQUIRED: container-only recreation/rebuild is required');
|
|
450
454
|
}
|
|
451
455
|
if (typeof candidate.containerIdentity !== 'object' || candidate.containerIdentity === null
|
|
452
456
|
|| Array.isArray(candidate.containerIdentity))
|
|
@@ -463,7 +467,9 @@ function readSandboxControlManifestValue(manifestPath, allowLegacy) {
|
|
|
463
467
|
|| (candidate.taskId !== null && typeof candidate.taskId !== 'string')
|
|
464
468
|
|| typeof candidate.channelDir !== 'string' || typeof candidate.publicStatusDir !== 'string'
|
|
465
469
|
|| typeof candidate.processingDir !== 'string' || typeof candidate.token !== 'string'
|
|
466
|
-
|| typeof candidate.generation !== 'string'
|
|
470
|
+
|| typeof candidate.generation !== 'string'
|
|
471
|
+
|| (candidate.mode === 'task-bound' && (typeof candidate.taskId !== 'string' || candidate.taskId.length === 0))
|
|
472
|
+
|| (candidate.mode === 'branch-only' && candidate.taskId !== null))
|
|
467
473
|
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
468
474
|
const root = path.dirname(path.resolve(manifestPath));
|
|
469
475
|
if (path.resolve(candidate.channelDir) !== path.join(root, 'channel')
|
|
@@ -471,22 +477,13 @@ function readSandboxControlManifestValue(manifestPath, allowLegacy) {
|
|
|
471
477
|
|| path.resolve(candidate.processingDir) !== path.join(root, 'processing')) {
|
|
472
478
|
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
473
479
|
}
|
|
474
|
-
if (candidate.
|
|
475
|
-
if (!allowLegacy) {
|
|
476
|
-
throw new Error('SANDBOX_CONTROL_MANIFEST_VERSION_INVALID: expected version 5; container-only recreation is required');
|
|
477
|
-
}
|
|
478
|
-
return candidate;
|
|
479
|
-
}
|
|
480
|
-
if (typeof candidate.runtimeDir !== 'string' || path.resolve(candidate.runtimeDir) !== path.join(root, 'runtime')) {
|
|
480
|
+
if (path.resolve(candidate.runtimeDir) !== path.join(root, 'runtime')) {
|
|
481
481
|
throw new Error('SANDBOX_CONTROL_MANIFEST_INVALID');
|
|
482
482
|
}
|
|
483
483
|
return candidate;
|
|
484
484
|
}
|
|
485
485
|
export function readSandboxControlManifest(manifestPath) {
|
|
486
|
-
return readSandboxControlManifestValue(manifestPath
|
|
487
|
-
}
|
|
488
|
-
export function readSandboxControlManifestForTransition(manifestPath) {
|
|
489
|
-
return readSandboxControlManifestValue(manifestPath, true);
|
|
486
|
+
return readSandboxControlManifestValue(manifestPath);
|
|
490
487
|
}
|
|
491
488
|
function readBrokerOwner(filePath) {
|
|
492
489
|
if (!fs.existsSync(filePath))
|
|
@@ -507,6 +504,18 @@ function readBrokerOwner(filePath) {
|
|
|
507
504
|
throw new Error('SANDBOX_CONTROL_OWNER_MISMATCH');
|
|
508
505
|
return owner;
|
|
509
506
|
}
|
|
507
|
+
export function assertSandboxControlBrokerOwner(manifest, options = {}) {
|
|
508
|
+
const root = path.dirname(path.resolve(manifest.publicStatusDir));
|
|
509
|
+
const owner = readBrokerOwner(path.join(root, 'broker.json'));
|
|
510
|
+
if (!owner)
|
|
511
|
+
throw new Error('SANDBOX_CONTROL_OWNER_EVIDENCE_MISSING');
|
|
512
|
+
if (owner.token !== manifest.token || owner.generation !== manifest.generation) {
|
|
513
|
+
throw new Error('SANDBOX_CONTROL_OWNER_MISMATCH');
|
|
514
|
+
}
|
|
515
|
+
if (!ownerLive(owner, options.identityProbe))
|
|
516
|
+
throw new Error('SANDBOX_CONTROL_OWNER_LOST');
|
|
517
|
+
return owner;
|
|
518
|
+
}
|
|
510
519
|
function readStatusOwner(filePath) {
|
|
511
520
|
if (!fs.existsSync(filePath))
|
|
512
521
|
return null;
|
|
@@ -641,7 +650,7 @@ export async function quiesceSandboxControlRoot(root, options = {}) {
|
|
|
641
650
|
markSandboxControlRootQuiescing(resolvedRoot);
|
|
642
651
|
await waitForStartupTransition(resolvedRoot, Math.max(0, forceAt - Date.now()), identityProbe);
|
|
643
652
|
const manifestPath = path.join(resolvedRoot, 'manifest.json');
|
|
644
|
-
const manifest = fs.existsSync(manifestPath) ?
|
|
653
|
+
const manifest = fs.existsSync(manifestPath) ? readSandboxControlManifest(manifestPath) : null;
|
|
645
654
|
const broker = readBrokerOwner(path.join(resolvedRoot, 'broker.json'));
|
|
646
655
|
const status = readStatusOwner(path.join(resolvedRoot, 'public', 'status.json'));
|
|
647
656
|
const statusOwner = status ? status.broker : null;
|
|
@@ -730,7 +739,7 @@ export async function removeSandboxControlRoot(root, options) {
|
|
|
730
739
|
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
731
740
|
throw new Error('SANDBOX_CONTROL_CHANNEL_INVALID');
|
|
732
741
|
const manifestPath = path.join(resolvedRoot, 'manifest.json');
|
|
733
|
-
const manifest =
|
|
742
|
+
const manifest = readSandboxControlManifest(manifestPath);
|
|
734
743
|
const inspectContainer = options.inspectContainer
|
|
735
744
|
?? ((timeoutMs) => inspectSandboxControlContainer(manifest, { timeoutMs }));
|
|
736
745
|
const timeoutMs = options.timeoutMs ?? options.timing?.quiesceDeadlineMs ?? DEFAULT_QUIESCE_TIMEOUT_MS;
|
|
@@ -792,7 +801,7 @@ export async function removeSandboxControlRoot(root, options) {
|
|
|
792
801
|
: 'SANDBOX_CONTROL_CONTAINER_STILL_EXISTS');
|
|
793
802
|
}
|
|
794
803
|
}
|
|
795
|
-
const currentManifest =
|
|
804
|
+
const currentManifest = readSandboxControlManifest(manifestPath);
|
|
796
805
|
if (currentManifest.token !== manifest.token || currentManifest.generation !== manifest.generation
|
|
797
806
|
|| !isSandboxControlRootQuiescing(resolvedRoot)) {
|
|
798
807
|
throw new Error('SANDBOX_CONTROL_OWNER_TRANSITION');
|
|
@@ -197,6 +197,7 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
197
197
|
if (!recoverProcessing(manifest, brokerOwns))
|
|
198
198
|
return;
|
|
199
199
|
while (!signal.aborted) {
|
|
200
|
+
let settledExecution = null;
|
|
200
201
|
if (!brokerOwns())
|
|
201
202
|
break;
|
|
202
203
|
let current;
|
|
@@ -255,22 +256,7 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
255
256
|
if (active?.settled) {
|
|
256
257
|
if (!brokerOwns())
|
|
257
258
|
break;
|
|
258
|
-
|
|
259
|
-
if (!brokerOwns())
|
|
260
|
-
break;
|
|
261
|
-
writeResponse(manifest, {
|
|
262
|
-
version: 2, id: active.request.id, phase: 'completed', exitCode: active.result.exitCode,
|
|
263
|
-
stdout: active.result.stdout, stderr: active.result.stderr, error: null
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
if (!brokerOwns())
|
|
268
|
-
break;
|
|
269
|
-
writeResponse(manifest, unknown(active.request.id));
|
|
270
|
-
}
|
|
271
|
-
if (!brokerOwns())
|
|
272
|
-
break;
|
|
273
|
-
fs.rmSync(path.join(manifest.processingDir, active.request.id), { recursive: true, force: true });
|
|
259
|
+
settledExecution = active;
|
|
274
260
|
active = null;
|
|
275
261
|
}
|
|
276
262
|
let reasonCode = null;
|
|
@@ -313,6 +299,22 @@ export async function serveSandboxControl(manifestPath, signal = new AbortContro
|
|
|
313
299
|
appendSandboxControlAudit(manifest, 'broker-state', { state, reasonCode, requestId: active?.request.id ?? null });
|
|
314
300
|
lastState = stateKey;
|
|
315
301
|
}
|
|
302
|
+
if (settledExecution) {
|
|
303
|
+
if (!brokerOwns())
|
|
304
|
+
break;
|
|
305
|
+
if (settledExecution.result) {
|
|
306
|
+
writeResponse(manifest, {
|
|
307
|
+
version: 2, id: settledExecution.request.id, phase: 'completed', exitCode: settledExecution.result.exitCode,
|
|
308
|
+
stdout: settledExecution.result.stdout, stderr: settledExecution.result.stderr, error: null
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
writeResponse(manifest, unknown(settledExecution.request.id));
|
|
313
|
+
}
|
|
314
|
+
if (!brokerOwns())
|
|
315
|
+
break;
|
|
316
|
+
fs.rmSync(path.join(manifest.processingDir, settledExecution.request.id), { recursive: true, force: true });
|
|
317
|
+
}
|
|
316
318
|
let retiring = false;
|
|
317
319
|
for (const name of fs.readdirSync(requestsDir).sort()) {
|
|
318
320
|
if (!/^[a-f0-9-]{16,64}\.json$/.test(name))
|
|
@@ -2,7 +2,8 @@ import path from 'node:path';
|
|
|
2
2
|
import { shareBranchDir, shareCommonDir, shellConfigDirCandidates, worktreeDirCandidates } from './constants.js';
|
|
3
3
|
import { sandboxWorkspaceViewStatePaths } from './workspace-view.js';
|
|
4
4
|
export function sandboxCoreBindMounts(config, branch, overrides) {
|
|
5
|
-
const
|
|
5
|
+
const taskSources = overrides.taskSources ?? [];
|
|
6
|
+
const taskBound = Boolean(taskSources.length > 0 && overrides.taskId);
|
|
6
7
|
const workspaceMounts = sandboxWorkspaceViewStatePaths(overrides.workspaceViewRoot).map(({ state, hostPath }) => taskBound && state === 'active'
|
|
7
8
|
? {
|
|
8
9
|
hostPaths: [path.join(hostPath, '.short-ids.json')],
|
|
@@ -26,7 +27,7 @@ export function sandboxCoreBindMounts(config, branch, overrides) {
|
|
|
26
27
|
];
|
|
27
28
|
if (taskBound) {
|
|
28
29
|
mounts.push({
|
|
29
|
-
hostPaths:
|
|
30
|
+
hostPaths: taskSources,
|
|
30
31
|
containerPath: path.posix.join('/workspace/.agents/workspace/active', overrides.taskId),
|
|
31
32
|
readOnly: false
|
|
32
33
|
});
|