@ornexus/neocortex 4.60.73 → 4.60.74
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/release-source.json +1 -1
- package/dist/sbom.cdx.json +1216 -1210
- package/install.ps1 +1 -1
- package/install.sh +1 -1
- package/package.json +2 -2
- package/packages/client/dist/adapters/adapter-registry.js +1 -108
- package/packages/client/dist/adapters/antigravity-adapter.js +2 -77
- package/packages/client/dist/adapters/claude-code-adapter.js +3 -79
- package/packages/client/dist/adapters/codex-adapter.js +2 -80
- package/packages/client/dist/adapters/cursor-adapter.js +4 -115
- package/packages/client/dist/adapters/gemini-adapter.js +2 -71
- package/packages/client/dist/adapters/grok-adapter.js +2 -42
- package/packages/client/dist/adapters/index.js +1 -22
- package/packages/client/dist/adapters/platform-detector.js +1 -212
- package/packages/client/dist/adapters/target-adapter.js +0 -12
- package/packages/client/dist/adapters/vscode-adapter.js +2 -72
- package/packages/client/dist/agent/refresh-stubs.js +2 -417
- package/packages/client/dist/agent/update-agent-yaml.js +1 -102
- package/packages/client/dist/agent/update-description.js +1 -251
- package/packages/client/dist/cache/crypto-utils.js +1 -78
- package/packages/client/dist/cache/encrypted-cache.js +1 -108
- package/packages/client/dist/cache/in-memory-asset-cache.js +1 -73
- package/packages/client/dist/cache/index.js +1 -13
- package/packages/client/dist/cache/protected-pi-boundary.js +1 -44
- package/packages/client/dist/checkpoint/checkpoint-client-reader.js +2 -127
- package/packages/client/dist/checkpoint/index.js +1 -11
- package/packages/client/dist/checkpoint/shared-checkpoint-types.js +1 -32
- package/packages/client/dist/cli.js +5 -358
- package/packages/client/dist/commands/activate.js +8 -394
- package/packages/client/dist/commands/architecture-answers.js +7 -274
- package/packages/client/dist/commands/architecture-memory-terminal.js +4 -253
- package/packages/client/dist/commands/architecture-non-ui-continuation.js +1 -100
- package/packages/client/dist/commands/architecture-root-binding.js +1 -51
- package/packages/client/dist/commands/cache-status.js +2 -112
- package/packages/client/dist/commands/config.js +1 -88
- package/packages/client/dist/commands/doctor.js +2 -635
- package/packages/client/dist/commands/invoke.js +143 -7200
- package/packages/client/dist/commands/legacy-epic-terminal.js +1 -71
- package/packages/client/dist/commands/legacy-story-branch.js +1 -96
- package/packages/client/dist/commands/legacy-story-pr.js +1 -276
- package/packages/client/dist/commands/mutation-qa-checkpoint.js +5 -285
- package/packages/client/dist/commands/mutation-qa-gate.js +1 -54
- package/packages/client/dist/commands/mutation-qa-git.js +1 -41
- package/packages/client/dist/commands/mutation-qa-policy.js +1 -102
- package/packages/client/dist/commands/mutation-qa-run.js +3 -219
- package/packages/client/dist/commands/mutation-qa-verdict.js +1 -149
- package/packages/client/dist/commands/mutation-qa.js +1 -220
- package/packages/client/dist/commands/native-agent.js +2 -136
- package/packages/client/dist/commands/planning-diagnosis.js +1 -43
- package/packages/client/dist/commands/planning-generation.js +1 -53
- package/packages/client/dist/commands/planning-memory.js +1 -40
- package/packages/client/dist/commands/planning-research.js +1 -42
- package/packages/client/dist/commands/private-session.js +1 -75
- package/packages/client/dist/commands/property-qa.js +1 -139
- package/packages/client/dist/commands/qa-control.js +1 -16
- package/packages/client/dist/commands/qa-scan-browser-launch.js +1 -55
- package/packages/client/dist/commands/qa-scan-browser-route.js +1 -28
- package/packages/client/dist/commands/qa-scan-capture.js +5 -663
- package/packages/client/dist/commands/qa-scan-discovery.js +3 -376
- package/packages/client/dist/commands/qa-scan-review.js +5 -826
- package/packages/client/dist/commands/qa-synthetic-backend-capture.js +1 -266
- package/packages/client/dist/commands/qa-synthetic-backend-review.js +1 -297
- package/packages/client/dist/commands/qa-synthetic-backend.js +2 -340
- package/packages/client/dist/commands/qa-synthetic-broker-port.js +1 -85
- package/packages/client/dist/commands/qa-synthetic-browser.js +1 -39
- package/packages/client/dist/commands/refactor-characterization.js +21 -671
- package/packages/client/dist/commands/refactor-commit.js +13 -399
- package/packages/client/dist/commands/refactor-control.js +3 -142
- package/packages/client/dist/commands/refactor-cpp-assertions.js +3 -93
- package/packages/client/dist/commands/refactor-review.js +5 -283
- package/packages/client/dist/commands/refactor-root.js +7 -588
- package/packages/client/dist/commands/refresh-memory.js +3 -156
- package/packages/client/dist/commands/shared-architecture-non-ui.js +1 -24
- package/packages/client/dist/commands/story-checkpoint.js +1 -171
- package/packages/client/dist/config/profile-directory.js +1 -13
- package/packages/client/dist/config/resolver-selection.js +1 -278
- package/packages/client/dist/config/secure-config.js +12 -281
- package/packages/client/dist/config.js +2 -223
- package/packages/client/dist/constants.js +1 -25
- package/packages/client/dist/context/context-collector.js +2 -222
- package/packages/client/dist/context/context-sanitizer.js +1 -145
- package/packages/client/dist/continuity/autonomous-governance.js +1 -285
- package/packages/client/dist/continuity/continuity-client-state-store.js +1 -1587
- package/packages/client/dist/continuity/invoke-hooks.js +1 -129
- package/packages/client/dist/continuity/migrations/001-initial-schema.js +2 -12
- package/packages/client/dist/continuity/migrations/002-processing-output-summary-indexes.js +2 -12
- package/packages/client/dist/continuity/migrations/003-headless-execution-attempts.js +2 -12
- package/packages/client/dist/continuity/migrations/004-outbox-delivery-state.js +2 -12
- package/packages/client/dist/continuity/migrations/005-bounded-headless-queue.js +2 -12
- package/packages/client/dist/continuity/migrations/006-native-agent-dispatches.js +2 -10
- package/packages/client/dist/continuity/native-agent-store.js +1 -69
- package/packages/client/dist/continuity/native-agent-types.js +1 -90
- package/packages/client/dist/continuity/outbox.js +1 -117
- package/packages/client/dist/continuity/runner-bootstrap-policy.js +1 -172
- package/packages/client/dist/continuity/sqlite-store.js +81 -2612
- package/packages/client/dist/effects/invoke-effect-gateways.js +1 -62
- package/packages/client/dist/errors/error-messages.js +2 -228
- package/packages/client/dist/errors/frontmatter-diagnostics.js +1 -125
- package/packages/client/dist/evidence/collector.js +1 -347
- package/packages/client/dist/evidence/index.js +1 -1
- package/packages/client/dist/evidence/types.js +0 -2
- package/packages/client/dist/fs/atomic-state-replace.js +1 -152
- package/packages/client/dist/generated/command-registry.generated.js +1 -4076
- package/packages/client/dist/generated/public-projections.generated.js +1 -149
- package/packages/client/dist/git/direct-yolo-c01-retry.js +4 -138
- package/packages/client/dist/git/direct-yolo-checkpoint.js +4 -1234
- package/packages/client/dist/git/epic-operational-state.js +2 -672
- package/packages/client/dist/git/git-lifecycle-step-ids.js +1 -14
- package/packages/client/dist/git/git-lifecycle-store.d.ts +23 -0
- package/packages/client/dist/git/git-lifecycle-store.js +10 -1981
- package/packages/client/dist/git/legacy-story-branch-checkpoint.js +9 -259
- package/packages/client/dist/git/legacy-story-branch-setup.js +4 -348
- package/packages/client/dist/git/legacy-story-pr.js +70 -3538
- package/packages/client/dist/git/secure-filesystem-boundary.js +5 -182
- package/packages/client/dist/graph-retrieval/pre-command-hook.js +1 -284
- package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +1 -237
- package/packages/client/dist/i18n/first-run.js +2 -60
- package/packages/client/dist/index.js +1 -47
- package/packages/client/dist/invocation/invoke-input.js +1 -24
- package/packages/client/dist/license/index.js +1 -5
- package/packages/client/dist/license/license-client.js +1 -304
- package/packages/client/dist/machine/fingerprint.js +2 -163
- package/packages/client/dist/machine/index.js +1 -5
- package/packages/client/dist/memory/project-memory-path-scope.js +1 -62
- package/packages/client/dist/memory/project-memory-writer.js +40 -1007
- package/packages/client/dist/memory/shared-project-memory-types.js +2 -253
- package/packages/client/dist/migrations/epic-lifecycle-backfill.js +3 -1060
- package/packages/client/dist/migrations/project-identity-capability.js +1 -50
- package/packages/client/dist/migrations/project-identity.js +7 -493
- package/packages/client/dist/migrations/state-json.js +4 -393
- package/packages/client/dist/policy/architecture-policy.js +2 -184
- package/packages/client/dist/policy/index.js +1 -7
- package/packages/client/dist/policy/shared-policy-types.js +0 -38
- package/packages/client/dist/policy/subagent-approval-policy.js +1 -55
- package/packages/client/dist/private-execution/clean-baseline.js +2 -279
- package/packages/client/dist/private-execution/codex-executor.js +4 -574
- package/packages/client/dist/private-execution/codex-host-runtime.js +1 -137
- package/packages/client/dist/private-execution/codex-lifecycle-guard.js +1 -97
- package/packages/client/dist/private-execution/codex-scoped-permissions.js +1 -128
- package/packages/client/dist/private-execution/delivery.js +13 -410
- package/packages/client/dist/private-execution/diagnosis-root-review.js +2 -294
- package/packages/client/dist/private-execution/frozen-handoff.js +6 -19
- package/packages/client/dist/private-execution/implementation-validation.js +2 -106
- package/packages/client/dist/private-execution/isolated-admission.js +23 -1432
- package/packages/client/dist/private-execution/isolated-session.js +5 -725
- package/packages/client/dist/private-execution/isolated-workspace.js +1 -122
- package/packages/client/dist/private-execution/pact-consumer-runtime.js +3 -409
- package/packages/client/dist/private-execution/pact-test-source.js +1 -258
- package/packages/client/dist/private-execution/pact-toolchain.js +3 -290
- package/packages/client/dist/private-execution/pact-write-set.js +1 -172
- package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +5 -406
- package/packages/client/dist/private-execution/planning-generation-checkpoint.js +5 -462
- package/packages/client/dist/private-execution/planning-memory-checkpoint.js +3 -139
- package/packages/client/dist/private-execution/planning-research-checkpoint.js +4 -325
- package/packages/client/dist/private-execution/private-report-store.js +1 -42
- package/packages/client/dist/private-execution/property-test-candidate.js +1 -103
- package/packages/client/dist/private-execution/property-test-choices.js +3 -147
- package/packages/client/dist/private-execution/property-test-plan.js +7 -271
- package/packages/client/dist/private-execution/property-test-review.js +4 -258
- package/packages/client/dist/private-execution/property-test-runtime.js +9 -372
- package/packages/client/dist/private-execution/property-test-source.js +1 -139
- package/packages/client/dist/private-execution/root-checkpoint.js +1 -80
- package/packages/client/dist/private-execution/root-memory-git-evidence.js +3 -135
- package/packages/client/dist/private-execution/root-memory-recovery.js +1 -93
- package/packages/client/dist/private-execution/root-memory-request.js +1 -29
- package/packages/client/dist/private-execution/root-memory-scope.js +1 -178
- package/packages/client/dist/private-execution/root-memory-writer.js +1 -102
- package/packages/client/dist/private-execution/session-lease.js +1 -63
- package/packages/client/dist/private-execution/shared-private-admission-types.js +1 -50
- package/packages/client/dist/private-execution/shared-project-validation.js +1 -66
- package/packages/client/dist/private-execution/shared-root-memory-types.js +1 -61
- package/packages/client/dist/private-execution/ux-source-validation.js +1 -372
- package/packages/client/dist/private-execution/ux-write-set.js +2 -191
- package/packages/client/dist/registry/registry-reconciliation.js +1 -234
- package/packages/client/dist/resilience/circuit-breaker.js +1 -170
- package/packages/client/dist/resilience/degradation-manager.js +1 -164
- package/packages/client/dist/resilience/freshness-indicator.js +1 -100
- package/packages/client/dist/resilience/index.js +1 -8
- package/packages/client/dist/resilience/recovery-detector.js +1 -74
- package/packages/client/dist/resolvers/asset-resolver.js +0 -13
- package/packages/client/dist/resolvers/local-resolver.js +8 -255
- package/packages/client/dist/resolvers/remote-resolver.js +1 -233
- package/packages/client/dist/runner/binary.js +1 -404
- package/packages/client/dist/runner/cli.js +17 -1571
- package/packages/client/dist/runner/headless/adapters.js +1 -49
- package/packages/client/dist/runner/headless/claude-code-adapter.js +1 -79
- package/packages/client/dist/runner/headless/continuous-story-workspace.js +11 -1628
- package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +1 -69
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.d.ts +1 -1
- package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +2 -110
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.d.ts +2 -0
- package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +10 -1236
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.d.ts +18 -2
- package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +2 -318
- package/packages/client/dist/runner/headless/fake-adapter.js +1 -62
- package/packages/client/dist/runner/headless/managed-profile.js +1 -132
- package/packages/client/dist/runner/headless/opencode-adapter.js +2 -145
- package/packages/client/dist/runner/headless/prepared-story-bundle.js +1 -43
- package/packages/client/dist/runner/headless/resolver.js +1 -231
- package/packages/client/dist/runner/headless/run-yolo.js +1 -885
- package/packages/client/dist/runner/headless/run-yoloop.d.ts +1 -0
- package/packages/client/dist/runner/headless/run-yoloop.js +2 -2574
- package/packages/client/dist/runner/headless/types.js +2 -574
- package/packages/client/dist/runner/local-console.js +13 -396
- package/packages/client/dist/runner/portal-sync-worker.js +1 -1487
- package/packages/client/dist/runner/project-identity.js +1 -106
- package/packages/client/dist/runner/scheduler.js +7 -995
- package/packages/client/dist/runner-cli.js +2 -18
- package/packages/client/dist/state/invocation-shape.js +1 -13
- package/packages/client/dist/state/project-state-snapshot.js +1 -1731
- package/packages/client/dist/state/state-json-repair.js +3 -785
- package/packages/client/dist/state/structural-dag-projection.js +1 -118
- package/packages/client/dist/telemetry/index.js +1 -5
- package/packages/client/dist/telemetry/offline-queue.js +1 -131
- package/packages/client/dist/tier/index.js +1 -5
- package/packages/client/dist/tier/tier-aware-client.js +1 -405
- package/packages/client/dist/types/index.js +1 -38
- package/packages/client/dist/version.js +1 -27
- package/packages/client/dist/yolo/change-evidence-collector.js +1 -126
- package/packages/client/dist/yolo/invoke-envelope-capability.js +1 -62
- package/packages/client/dist/yolo/spec-envelope-collector.js +5 -184
- package/packages/client/dist/yoloop/discovery-hook.js +2 -300
- package/packages/client/dist/yoloop/index.js +1 -8
- package/packages/client/dist/yoloop/invoke-hooks.js +12 -669
- package/packages/client/dist/yoloop/shared-discover-epics.js +1 -1007
- package/packages/client/dist/yoloop/shared-yoloop-types.js +1 -33
- package/packages/client/dist/yoloop/target-normalization.js +1 -180
- package/packages/client/dist/yoloop/yoloop-client-state-store.js +1 -1920
- package/packages/shared/dist/yolo/change-evidence.js +1 -1
- package/packages/shared/dist/yoloop/epic-terminal-git.js +144 -2
- package/targets-stubs/antigravity/gemini.md +1 -1
- package/targets-stubs/antigravity/skill/SKILL.md +1 -1
- package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex-root.md +2 -2
- package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
- package/targets-stubs/claude-code/neocortex.md +2 -2
- package/targets-stubs/codex/AGENTS.md +1 -1
- package/targets-stubs/cursor/agent.md +2 -2
- package/targets-stubs/gemini-cli/agent.md +2 -2
- package/targets-stubs/opencode/neocortex-root.md +1 -1
- package/targets-stubs/vscode/neocortex.agent.md +2 -2
|
@@ -1,137 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
/** Host control state for one subscription execution. Never a QA checkout or image. */
|
|
3
|
-
import { createHash } from 'node:crypto';
|
|
4
|
-
import { closeSync, constants, fstatSync, lstatSync, mkdtempSync, openSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
5
|
-
import { isAbsolute, join, relative } from 'node:path';
|
|
6
|
-
const digest = (bytes) => createHash('sha256').update(bytes).digest('hex');
|
|
7
|
-
const liveRuntimes = new Set();
|
|
8
|
-
let exitCleanupInstalled = false;
|
|
9
|
-
function fail() { throw new Error('private-codex-host-runtime-unverified'); }
|
|
10
|
-
function readFile(path, credential) {
|
|
11
|
-
const fd = openSync(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
12
|
-
try {
|
|
13
|
-
const before = fstatSync(fd);
|
|
14
|
-
if (!before.isFile() || before.uid !== process.getuid?.() || before.nlink !== 1
|
|
15
|
-
|| before.mode & 0o022 || credential && (before.mode & 0o777) !== 0o600
|
|
16
|
-
|| before.size < 1 || before.size > 1048576)
|
|
17
|
-
fail();
|
|
18
|
-
const bytes = readFileSync(fd), after = fstatSync(fd), current = lstatSync(path);
|
|
19
|
-
if (bytes.length !== before.size || [after, current].some(s => s.dev !== before.dev || s.ino !== before.ino
|
|
20
|
-
|| s.size !== before.size || s.mtimeMs !== before.mtimeMs || s.ctimeMs !== before.ctimeMs
|
|
21
|
-
|| s.mode !== before.mode || s.nlink !== 1))
|
|
22
|
-
fail();
|
|
23
|
-
return bytes;
|
|
24
|
-
}
|
|
25
|
-
finally {
|
|
26
|
-
closeSync(fd);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/** The CLI may record project trust in its own configuration. Keep that write in
|
|
30
|
-
* short-lived, owner-private host control storage using the existing account.
|
|
31
|
-
* No credential is placed in, mounted into or passed to the model checkout. */
|
|
32
|
-
export function createPrivateCodexHostRuntime(projectRoot, sourceHome) {
|
|
33
|
-
try {
|
|
34
|
-
const root = realpathSync(projectRoot), source = realpathSync(sourceHome), relation = relative(root, source);
|
|
35
|
-
const parent = lstatSync(source);
|
|
36
|
-
if (!relation || !relation.startsWith('..') && !isAbsolute(relation)
|
|
37
|
-
|| !parent.isDirectory() || parent.uid !== process.getuid?.() || parent.mode & 0o022)
|
|
38
|
-
fail();
|
|
39
|
-
const auth = readFile(join(source, 'auth.json'), true);
|
|
40
|
-
let config;
|
|
41
|
-
try {
|
|
42
|
-
config = readFile(join(source, 'config.toml'), false);
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
if (error.code !== 'ENOENT')
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
const authDigest = digest(auth), configDigest = config ? digest(config) : undefined;
|
|
49
|
-
const home = mkdtempSync(join(source, '.neocortex-executor-')), identity = lstatSync(home);
|
|
50
|
-
const guard = process.platform === 'linux' ? startPrivateCodexHomeGuard(home) : undefined;
|
|
51
|
-
let closed = false;
|
|
52
|
-
const custody = () => {
|
|
53
|
-
const current = lstatSync(home), directory = lstatSync(source);
|
|
54
|
-
if (realpathSync(source) !== source || directory.dev !== parent.dev || directory.ino !== parent.ino
|
|
55
|
-
|| directory.uid !== parent.uid || directory.mode & 0o022 || current.dev !== identity.dev || current.ino !== identity.ino
|
|
56
|
-
|| current.uid !== process.getuid?.() || (current.mode & 0o777) !== 0o700 || !current.isDirectory()
|
|
57
|
-
|| current.isSymbolicLink())
|
|
58
|
-
fail();
|
|
59
|
-
};
|
|
60
|
-
let runtime;
|
|
61
|
-
const close = () => {
|
|
62
|
-
if (closed)
|
|
63
|
-
return;
|
|
64
|
-
try {
|
|
65
|
-
custody();
|
|
66
|
-
rmSync(home, { recursive: true });
|
|
67
|
-
closed = true;
|
|
68
|
-
if (runtime)
|
|
69
|
-
liveRuntimes.delete(runtime);
|
|
70
|
-
if (guard?.connected)
|
|
71
|
-
guard.disconnect();
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
fail();
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
try {
|
|
78
|
-
writeFileSync(join(home, 'auth.json'), auth, { mode: 0o600, flag: 'wx' });
|
|
79
|
-
if (config)
|
|
80
|
-
writeFileSync(join(home, 'config.toml'), config, { mode: 0o600, flag: 'wx' });
|
|
81
|
-
auth.fill(0);
|
|
82
|
-
config?.fill(0);
|
|
83
|
-
const verify = () => {
|
|
84
|
-
try {
|
|
85
|
-
if (closed || guard && (!guard.connected || guard.exitCode !== null || guard.signalCode !== null))
|
|
86
|
-
fail();
|
|
87
|
-
custody();
|
|
88
|
-
if (digest(readFile(join(source, 'auth.json'), true)) !== authDigest)
|
|
89
|
-
fail();
|
|
90
|
-
let current;
|
|
91
|
-
try {
|
|
92
|
-
current = readFile(join(source, 'config.toml'), false);
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
if (error.code !== 'ENOENT')
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
if ((current ? digest(current) : undefined) !== configDigest)
|
|
99
|
-
fail();
|
|
100
|
-
readFile(join(home, 'auth.json'), true);
|
|
101
|
-
try {
|
|
102
|
-
readFile(join(home, 'config.toml'), true);
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
if (error.code !== 'ENOENT')
|
|
106
|
-
throw error;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
fail();
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
verify();
|
|
114
|
-
runtime = Object.freeze({ home, sourceHome: source, verify, close });
|
|
115
|
-
liveRuntimes.add(runtime);
|
|
116
|
-
if (!exitCleanupInstalled) {
|
|
117
|
-
exitCleanupInstalled = true;
|
|
118
|
-
process.once('exit', () => {
|
|
119
|
-
for (const pending of liveRuntimes) {
|
|
120
|
-
try {
|
|
121
|
-
pending.close();
|
|
122
|
-
}
|
|
123
|
-
catch { /* Preserve a directory whose custody became ambiguous. */ }
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
return runtime;
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
close();
|
|
131
|
-
throw error;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
fail();
|
|
136
|
-
}
|
|
137
|
-
}
|
|
1
|
+
import{startPrivateCodexHomeGuard as L}from"./codex-lifecycle-guard.js";import{createHash as k}from"node:crypto";import{closeSync as H,constants as O,fstatSync as z,lstatSync as g,mkdtempSync as M,openSync as R,readFileSync as T,realpathSync as S,rmSync as _,writeFileSync as C}from"node:fs";import{isAbsolute as P,join as c,relative as W}from"node:path";const p=d=>k("sha256").update(d).digest("hex"),w=new Set;let b=!1;function r(){throw new Error("private-codex-host-runtime-unverified")}function a(d,v){const f=R(d,O.O_RDONLY|O.O_NOFOLLOW|O.O_NONBLOCK);try{const e=z(f);(!e.isFile()||e.uid!==process.getuid?.()||e.nlink!==1||e.mode&18||v&&(e.mode&511)!==384||e.size<1||e.size>1048576)&&r();const l=T(f),s=z(f),m=g(d);return(l.length!==e.size||[s,m].some(t=>t.dev!==e.dev||t.ino!==e.ino||t.size!==e.size||t.mtimeMs!==e.mtimeMs||t.ctimeMs!==e.ctimeMs||t.mode!==e.mode||t.nlink!==1))&&r(),l}finally{H(f)}}function K(d,v){try{const f=S(d),e=S(v),l=W(f,e),s=g(e);(!l||!l.startsWith("..")&&!P(l)||!s.isDirectory()||s.uid!==process.getuid?.()||s.mode&18)&&r();const m=a(c(e,"auth.json"),!0);let t;try{t=a(c(e,"config.toml"),!1)}catch(o){if(o.code!=="ENOENT")throw o}const D=p(m),F=t?p(t):void 0,n=M(c(e,".neocortex-executor-")),N=g(n),u=process.platform==="linux"?L(n):void 0;let x=!1;const E=()=>{const o=g(n),i=g(e);(S(e)!==e||i.dev!==s.dev||i.ino!==s.ino||i.uid!==s.uid||i.mode&18||o.dev!==N.dev||o.ino!==N.ino||o.uid!==process.getuid?.()||(o.mode&511)!==448||!o.isDirectory()||o.isSymbolicLink())&&r()};let y;const j=()=>{if(!x)try{E(),_(n,{recursive:!0}),x=!0,y&&w.delete(y),u?.connected&&u.disconnect()}catch{r()}};try{C(c(n,"auth.json"),m,{mode:384,flag:"wx"}),t&&C(c(n,"config.toml"),t,{mode:384,flag:"wx"}),m.fill(0),t?.fill(0);const o=()=>{try{(x||u&&(!u.connected||u.exitCode!==null||u.signalCode!==null))&&r(),E(),p(a(c(e,"auth.json"),!0))!==D&&r();let i;try{i=a(c(e,"config.toml"),!1)}catch(h){if(h.code!=="ENOENT")throw h}(i?p(i):void 0)!==F&&r(),a(c(n,"auth.json"),!0);try{a(c(n,"config.toml"),!0)}catch(h){if(h.code!=="ENOENT")throw h}}catch{r()}};return o(),y=Object.freeze({home:n,sourceHome:e,verify:o,close:j}),w.add(y),b||(b=!0,process.once("exit",()=>{for(const i of w)try{i.close()}catch{}})),y}catch(o){throw j(),o}}catch{r()}}export{K as createPrivateCodexHostRuntime};
|
|
@@ -1,97 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { spawn } from 'node:child_process';
|
|
3
|
-
import { lstatSync, realpathSync, rmSync } from 'node:fs';
|
|
4
|
-
import { basename } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
// Source-driven development tests launch the same compiled helper as the CLI.
|
|
7
|
-
export const codexLifecycleGuardPath = fileURLToPath(new URL(import.meta.url.endsWith('.ts')
|
|
8
|
-
? '../../dist/private-execution/codex-lifecycle-guard.js' : './codex-lifecycle-guard.js', import.meta.url));
|
|
9
|
-
export function startPrivateCodexHomeGuard(home) {
|
|
10
|
-
const identity = lstatSync(home);
|
|
11
|
-
const guard = spawn(process.execPath, [codexLifecycleGuardPath, 'home', home, String(identity.dev), String(identity.ino)], {
|
|
12
|
-
detached: true, env: {}, stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
|
13
|
-
});
|
|
14
|
-
// A failed guard is observed by runtime.verify(); never print host paths.
|
|
15
|
-
guard.on('error', () => undefined);
|
|
16
|
-
guard.unref();
|
|
17
|
-
guard.channel?.unref();
|
|
18
|
-
return guard;
|
|
19
|
-
}
|
|
20
|
-
function stopOwnGroup() {
|
|
21
|
-
// This process remains the group leader until this syscall: no stale PID kill.
|
|
22
|
-
process.kill(-process.pid, 'SIGKILL');
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
function homeGuard() {
|
|
26
|
-
const [home, dev, ino] = process.argv.slice(3);
|
|
27
|
-
let handled = false;
|
|
28
|
-
const close = () => {
|
|
29
|
-
if (handled)
|
|
30
|
-
return;
|
|
31
|
-
handled = true;
|
|
32
|
-
try {
|
|
33
|
-
if (!home || !basename(home).startsWith('.neocortex-executor-'))
|
|
34
|
-
throw new Error();
|
|
35
|
-
const identity = lstatSync(home);
|
|
36
|
-
if (realpathSync(home) !== home || !identity.isDirectory() || identity.isSymbolicLink()
|
|
37
|
-
|| identity.uid !== process.getuid?.() || (identity.mode & 0o777) !== 0o700
|
|
38
|
-
|| String(identity.dev) !== dev || String(identity.ino) !== ino)
|
|
39
|
-
throw new Error();
|
|
40
|
-
rmSync(home, { recursive: true });
|
|
41
|
-
process.exit(0);
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
// Missing means the root already closed it. Ambiguous custody is retained.
|
|
45
|
-
process.exit(error.code === 'ENOENT' ? 0 : 1);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
process.on('disconnect', close);
|
|
49
|
-
if (!process.connected)
|
|
50
|
-
close();
|
|
51
|
-
}
|
|
52
|
-
function processGuard() {
|
|
53
|
-
process.on('disconnect', stopOwnGroup);
|
|
54
|
-
process.on('SIGTERM', stopOwnGroup);
|
|
55
|
-
process.on('SIGINT', stopOwnGroup);
|
|
56
|
-
process.stdout.on('error', stopOwnGroup);
|
|
57
|
-
process.stderr.on('error', stopOwnGroup);
|
|
58
|
-
if (!process.connected)
|
|
59
|
-
stopOwnGroup();
|
|
60
|
-
process.once('message', (value) => {
|
|
61
|
-
const input = value;
|
|
62
|
-
if (!input || input.kind !== 'private-codex-launch' || !Array.isArray(input.args)
|
|
63
|
-
|| input.args.some(arg => typeof arg !== 'string')
|
|
64
|
-
|| input.codexHome !== undefined && typeof input.codexHome !== 'string')
|
|
65
|
-
stopOwnGroup();
|
|
66
|
-
const args = input.args;
|
|
67
|
-
const child = spawn(input.codexHome === undefined ? 'codex' : '/bin/sh', input.codexHome === undefined
|
|
68
|
-
? args : ['-c', 'umask 077; exec codex "$@"', 'neocortex-private-codex', ...args], {
|
|
69
|
-
cwd: process.cwd(), env: Object.fromEntries(['PATH', 'HOME', 'LANG', 'LC_ALL', 'TERM', 'CODEX_HOME']
|
|
70
|
-
.filter(key => process.env[key] !== undefined).map(key => [key, process.env[key]])),
|
|
71
|
-
detached: false, stdio: ['pipe', 'pipe', 'pipe'],
|
|
72
|
-
});
|
|
73
|
-
process.stdin.pipe(child.stdin);
|
|
74
|
-
child.stdin.on('error', () => undefined);
|
|
75
|
-
child.stdout.pipe(process.stdout);
|
|
76
|
-
child.stderr.pipe(process.stderr);
|
|
77
|
-
child.on('error', stopOwnGroup);
|
|
78
|
-
child.on('close', code => {
|
|
79
|
-
// close waits for inherited pipes, retaining this live group anchor.
|
|
80
|
-
process.stdin.unpipe(child.stdin);
|
|
81
|
-
process.stdin.pause();
|
|
82
|
-
process.removeListener('disconnect', stopOwnGroup);
|
|
83
|
-
if (process.connected)
|
|
84
|
-
process.disconnect?.();
|
|
85
|
-
// Natural exit drains forwarded stdout/stderr before the root reads close.
|
|
86
|
-
process.exitCode = typeof code === 'number' ? code : 1;
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
if (process.argv[1] === codexLifecycleGuardPath && process.platform === 'linux') {
|
|
91
|
-
if (process.argv[2] === 'home')
|
|
92
|
-
homeGuard();
|
|
93
|
-
else if (process.argv[2] === 'process')
|
|
94
|
-
processGuard();
|
|
95
|
-
else
|
|
96
|
-
process.exit(1);
|
|
97
|
-
}
|
|
1
|
+
import{spawn as i}from"node:child_process";import{lstatSync as d,realpathSync as a,rmSync as u}from"node:fs";import{basename as f}from"node:path";import{fileURLToPath as m}from"node:url";const p=m(new URL(import.meta.url.endsWith(".ts")?"../../dist/private-execution/codex-lifecycle-guard.js":"./codex-lifecycle-guard.js",import.meta.url));function L(r){const e=d(r),c=i(process.execPath,[p,"home",r,String(e.dev),String(e.ino)],{detached:!0,env:{},stdio:["ignore","ignore","ignore","ipc"]});return c.on("error",()=>{}),c.unref(),c.channel?.unref(),c}function n(){process.kill(-process.pid,"SIGKILL"),process.exit(1)}function l(){const[r,e,c]=process.argv.slice(3);let s=!1;const o=()=>{if(!s){s=!0;try{if(!r||!f(r).startsWith(".neocortex-executor-"))throw new Error;const t=d(r);if(a(r)!==r||!t.isDirectory()||t.isSymbolicLink()||t.uid!==process.getuid?.()||(t.mode&511)!==448||String(t.dev)!==e||String(t.ino)!==c)throw new Error;u(r,{recursive:!0}),process.exit(0)}catch(t){process.exit(t.code==="ENOENT"?0:1)}}};process.on("disconnect",o),process.connected||o()}function x(){process.on("disconnect",n),process.on("SIGTERM",n),process.on("SIGINT",n),process.stdout.on("error",n),process.stderr.on("error",n),process.connected||n(),process.once("message",r=>{const e=r;(!e||e.kind!=="private-codex-launch"||!Array.isArray(e.args)||e.args.some(o=>typeof o!="string")||e.codexHome!==void 0&&typeof e.codexHome!="string")&&n();const c=e.args,s=i(e.codexHome===void 0?"codex":"/bin/sh",e.codexHome===void 0?c:["-c",'umask 077; exec codex "$@"',"neocortex-private-codex",...c],{cwd:process.cwd(),env:Object.fromEntries(["PATH","HOME","LANG","LC_ALL","TERM","CODEX_HOME"].filter(o=>process.env[o]!==void 0).map(o=>[o,process.env[o]])),detached:!1,stdio:["pipe","pipe","pipe"]});process.stdin.pipe(s.stdin),s.stdin.on("error",()=>{}),s.stdout.pipe(process.stdout),s.stderr.pipe(process.stderr),s.on("error",n),s.on("close",o=>{process.stdin.unpipe(s.stdin),process.stdin.pause(),process.removeListener("disconnect",n),process.connected&&process.disconnect?.(),process.exitCode=typeof o=="number"?o:1})})}process.argv[1]===p&&process.platform==="linux"&&(process.argv[2]==="home"?l():process.argv[2]==="process"?x():process.exit(1));export{p as codexLifecycleGuardPath,L as startPrivateCodexHomeGuard};
|
|
@@ -1,128 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { accessSync, constants, lstatSync, readdirSync, realpathSync } from 'node:fs';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import { createRequire } from 'node:module';
|
|
5
|
-
import { basename, delimiter, dirname, join, resolve, sep } from 'node:path';
|
|
6
|
-
import { gitLifecycleRuntimeDirectory } from '../git/git-lifecycle-store.js';
|
|
7
|
-
/** SDK state shares the Git control directory but is not model-readable Git metadata. */
|
|
8
|
-
function rootOwnedGitStores(directories) {
|
|
9
|
-
const paths = new Set();
|
|
10
|
-
for (const directory of directories) {
|
|
11
|
-
const control = lstatSync(directory);
|
|
12
|
-
if (!control.isDirectory() || control.isSymbolicLink() || realpathSync(directory) !== directory) {
|
|
13
|
-
throw new Error('private-codex-root-state-isolation-unproven');
|
|
14
|
-
}
|
|
15
|
-
for (const name of readdirSync(directory)) {
|
|
16
|
-
if (!name.startsWith('neocortex-'))
|
|
17
|
-
continue;
|
|
18
|
-
const path = join(directory, name), entry = lstatSync(path);
|
|
19
|
-
if (!/^[A-Za-z0-9._-]{1,128}$/.test(name) || entry.isSymbolicLink()
|
|
20
|
-
|| !entry.isDirectory() && !entry.isFile())
|
|
21
|
-
throw new Error('private-codex-root-state-isolation-unproven');
|
|
22
|
-
paths.add(path);
|
|
23
|
-
if (paths.size > 64)
|
|
24
|
-
throw new Error('private-codex-root-state-isolation-unproven');
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return [...paths].sort();
|
|
28
|
-
}
|
|
29
|
-
function executableReadRoots() {
|
|
30
|
-
for (const directory of (process.env.PATH ?? '').split(delimiter).filter(Boolean)) {
|
|
31
|
-
try {
|
|
32
|
-
const executable = realpathSync(join(directory, 'codex'));
|
|
33
|
-
accessSync(executable, constants.X_OK);
|
|
34
|
-
if (!lstatSync(executable).isFile())
|
|
35
|
-
continue;
|
|
36
|
-
if (basename(executable) !== 'codex.js' || basename(dirname(executable)) !== 'bin')
|
|
37
|
-
return [dirname(executable)];
|
|
38
|
-
const roots = [dirname(dirname(executable))];
|
|
39
|
-
const platformPackage = process.arch === 'x64' ? '@openai/codex-linux-x64'
|
|
40
|
-
: process.arch === 'arm64' ? '@openai/codex-linux-arm64' : undefined;
|
|
41
|
-
if (platformPackage) {
|
|
42
|
-
try {
|
|
43
|
-
roots.push(realpathSync(dirname(createRequire(executable).resolve(`${platformPackage}/package.json`))));
|
|
44
|
-
}
|
|
45
|
-
catch { /* Older installations keep the native executable in the CLI package. */ }
|
|
46
|
-
}
|
|
47
|
-
return [...new Set(roots)];
|
|
48
|
-
}
|
|
49
|
-
catch { /* Continue searching the same executable path used by spawn. */ }
|
|
50
|
-
}
|
|
51
|
-
throw new Error('private-codex-version-unavailable');
|
|
52
|
-
}
|
|
53
|
-
/** Per-invocation permissions; never modifies the operator's configuration. */
|
|
54
|
-
export async function createPrivateCodexScopedRunner(projectRoot, base, options) {
|
|
55
|
-
const root = realpathSync(resolve(projectRoot));
|
|
56
|
-
const controlDirectories = Object.freeze([...options.gitControlDirectories]);
|
|
57
|
-
const userHome = options.userHome ?? homedir();
|
|
58
|
-
const codexHome = options.codexHome ?? process.env.CODEX_HOME ?? join(userHome, '.codex');
|
|
59
|
-
const binaryRoots = executableReadRoots();
|
|
60
|
-
if (binaryRoots.some((path) => [sep, resolve(userHome), resolve(codexHome), root].includes(path)
|
|
61
|
-
|| path.startsWith(root + sep)))
|
|
62
|
-
throw new Error('private-codex-executable-scope-unsafe');
|
|
63
|
-
const lifecycle = await gitLifecycleRuntimeDirectory(root);
|
|
64
|
-
const stores = rootOwnedGitStores(controlDirectories);
|
|
65
|
-
const filesystem = {
|
|
66
|
-
':root': 'deny', ':minimal': 'read', [root]: 'write',
|
|
67
|
-
[join(userHome, '.ssh')]: 'deny', [join(codexHome, 'auth.json')]: 'deny',
|
|
68
|
-
};
|
|
69
|
-
if (options.credentialSourceHome) {
|
|
70
|
-
const sourceHome = resolve(options.credentialSourceHome), privateHome = resolve(codexHome);
|
|
71
|
-
filesystem[sourceHome] = 'deny';
|
|
72
|
-
if (privateHome !== sourceHome && !privateHome.startsWith(sourceHome + sep))
|
|
73
|
-
filesystem[privateHome] = 'deny';
|
|
74
|
-
// A denied ancestor covers the credential file. A second bind beneath an
|
|
75
|
-
// already denied directory cannot be created by the Linux sandbox.
|
|
76
|
-
delete filesystem[join(codexHome, 'auth.json')];
|
|
77
|
-
}
|
|
78
|
-
for (const directory of binaryRoots)
|
|
79
|
-
filesystem[directory] = 'read';
|
|
80
|
-
for (const directory of controlDirectories)
|
|
81
|
-
filesystem[directory] = 'read';
|
|
82
|
-
// Linked worktrees also have a .git control file inside the writable checkout.
|
|
83
|
-
filesystem[join(root, '.git')] = 'read';
|
|
84
|
-
filesystem[lifecycle] = 'deny';
|
|
85
|
-
for (const path of stores)
|
|
86
|
-
filesystem[path] = 'deny';
|
|
87
|
-
const profile = `p222-isolated-${randomBytes(16).toString('hex')}`;
|
|
88
|
-
const configuration = `permissions.${profile}={filesystem={${Object.entries(filesystem)
|
|
89
|
-
.map(([path, mode]) => `${JSON.stringify(path)}=${JSON.stringify(mode)}`).join(',')}},network={enabled=false}}`;
|
|
90
|
-
return async (args, runOptions) => {
|
|
91
|
-
if (realpathSync(resolve(runOptions.cwd)) !== root)
|
|
92
|
-
throw new Error('private-codex-execution-root-drift');
|
|
93
|
-
if (JSON.stringify(rootOwnedGitStores(controlDirectories)) !== JSON.stringify(stores)) {
|
|
94
|
-
throw new Error('private-codex-root-state-isolation-unproven');
|
|
95
|
-
}
|
|
96
|
-
if (args[0] !== 'sandbox' && args[0] !== 'exec')
|
|
97
|
-
return base(args, runOptions);
|
|
98
|
-
const scoped = [...args];
|
|
99
|
-
if (args[0] === 'sandbox') {
|
|
100
|
-
if (args[1] !== '-P' || args[2] !== 'p222-isolated')
|
|
101
|
-
throw new Error('private-codex-permission-profile-invalid');
|
|
102
|
-
scoped[2] = profile;
|
|
103
|
-
}
|
|
104
|
-
else {
|
|
105
|
-
const index = scoped.findIndex((arg, i) => arg === 'default_permissions="p222-isolated"' && scoped[i - 1] === '-c');
|
|
106
|
-
if (index < 0)
|
|
107
|
-
throw new Error('private-codex-permission-profile-invalid');
|
|
108
|
-
scoped[index] = `default_permissions="${profile}"`;
|
|
109
|
-
// Prove every currently registered private SDK store is unreadable at
|
|
110
|
-
// the material boundary. Probes receive no model material on stdin.
|
|
111
|
-
for (const path of stores) {
|
|
112
|
-
const probe = await base(['-c', configuration, 'sandbox', '-P', profile,
|
|
113
|
-
'--', 'sh', '-c', 'test ! -r "$1"', 'sh', path], {
|
|
114
|
-
cwd: root, timeoutMs: 10000, maxOutputBytes: 16384,
|
|
115
|
-
});
|
|
116
|
-
if (probe.exitCode !== 0 || probe.timedOut || probe.outputExceeded
|
|
117
|
-
|| JSON.stringify(rootOwnedGitStores(controlDirectories)) !== JSON.stringify(stores)) {
|
|
118
|
-
throw new Error('private-codex-root-state-isolation-unproven');
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// exec owns its own -c parser. Keep the profile in the same override set
|
|
123
|
-
// as default_permissions; a root-level override can be shadowed there.
|
|
124
|
-
return base(args[0] === 'exec'
|
|
125
|
-
? ['exec', '-c', configuration, ...scoped.slice(1)]
|
|
126
|
-
: ['-c', configuration, ...scoped], runOptions);
|
|
127
|
-
};
|
|
128
|
-
}
|
|
1
|
+
import{randomBytes as g}from"node:crypto";import{accessSync as D,constants as J,lstatSync as S,readdirSync as N,realpathSync as u}from"node:fs";import{homedir as R}from"node:os";import{createRequire as k}from"node:module";import{basename as $,delimiter as P,dirname as x,join as a,resolve as l,sep as b}from"node:path";import{gitLifecycleRuntimeDirectory as _}from"../git/git-lifecycle-store.js";function E(p){const o=new Set;for(const t of p){const r=S(t);if(!r.isDirectory()||r.isSymbolicLink()||u(t)!==t)throw new Error("private-codex-root-state-isolation-unproven");for(const s of N(t)){if(!s.startsWith("neocortex-"))continue;const d=a(t,s),c=S(d);if(!/^[A-Za-z0-9._-]{1,128}$/.test(s)||c.isSymbolicLink()||!c.isDirectory()&&!c.isFile())throw new Error("private-codex-root-state-isolation-unproven");if(o.add(d),o.size>64)throw new Error("private-codex-root-state-isolation-unproven")}}return[...o].sort()}function C(){for(const p of(process.env.PATH??"").split(P).filter(Boolean))try{const o=u(a(p,"codex"));if(D(o,J.X_OK),!S(o).isFile())continue;if($(o)!=="codex.js"||$(x(o))!=="bin")return[x(o)];const t=[x(x(o))],r=process.arch==="x64"?"@openai/codex-linux-x64":process.arch==="arm64"?"@openai/codex-linux-arm64":void 0;if(r)try{t.push(u(x(k(o).resolve(`${r}/package.json`))))}catch{}return[...new Set(t)]}catch{}throw new Error("private-codex-version-unavailable")}async function M(p,o,t){const r=u(l(p)),s=Object.freeze([...t.gitControlDirectories]),d=t.userHome??R(),c=t.codexHome??process.env.CODEX_HOME??a(d,".codex"),O=C();if(O.some(e=>[b,l(d),l(c),r].includes(e)||e.startsWith(r+b)))throw new Error("private-codex-executable-scope-unsafe");const j=await _(r),y=E(s),i={":root":"deny",":minimal":"read",[r]:"write",[a(d,".ssh")]:"deny",[a(c,"auth.json")]:"deny"};if(t.credentialSourceHome){const e=l(t.credentialSourceHome),n=l(c);i[e]="deny",n!==e&&!n.startsWith(e+b)&&(i[n]="deny"),delete i[a(c,"auth.json")]}for(const e of O)i[e]="read";for(const e of s)i[e]="read";i[a(r,".git")]="read",i[j]="deny";for(const e of y)i[e]="deny";const h=`p222-isolated-${g(16).toString("hex")}`,w=`permissions.${h}={filesystem={${Object.entries(i).map(([e,n])=>`${JSON.stringify(e)}=${JSON.stringify(n)}`).join(",")}},network={enabled=false}}`;return async(e,n)=>{if(u(l(n.cwd))!==r)throw new Error("private-codex-execution-root-drift");if(JSON.stringify(E(s))!==JSON.stringify(y))throw new Error("private-codex-root-state-isolation-unproven");if(e[0]!=="sandbox"&&e[0]!=="exec")return o(e,n);const f=[...e];if(e[0]==="sandbox"){if(e[1]!=="-P"||e[2]!=="p222-isolated")throw new Error("private-codex-permission-profile-invalid");f[2]=h}else{const H=f.findIndex((v,m)=>v==='default_permissions="p222-isolated"'&&f[m-1]==="-c");if(H<0)throw new Error("private-codex-permission-profile-invalid");f[H]=`default_permissions="${h}"`;for(const v of y){const m=await o(["-c",w,"sandbox","-P",h,"--","sh","-c",'test ! -r "$1"',"sh",v],{cwd:r,timeoutMs:1e4,maxOutputBytes:16384});if(m.exitCode!==0||m.timedOut||m.outputExceeded||JSON.stringify(E(s))!==JSON.stringify(y))throw new Error("private-codex-root-state-isolation-unproven")}}return o(e[0]==="exec"?["exec","-c",w,...f.slice(1)]:["-c",w,...f],n)}}export{M as createPrivateCodexScopedRunner};
|