Skip to content

Commit 7785eae

Browse files
authored
feat(core): extract sandbox detection into reusable utility (#34408)
Add isSandbox() utility that checks for sandbox environment variables (SANDBOX_RUNTIME, GEMINI_SANDBOX, CODEX_SANDBOX, CURSOR_SANDBOX) and use it to disable the daemon and plugin isolation in sandbox environments.
1 parent 28c5d95 commit 7785eae

5 files changed

Lines changed: 52 additions & 17 deletions

File tree

packages/nx/bin/nx.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,8 @@ import { performance } from 'perf_hooks';
2121
import { setupWorkspaceContext } from '../src/utils/workspace-context';
2222
import { daemonClient } from '../src/daemon/client/client';
2323
import { removeDbConnections } from '../src/utils/db-connection';
24-
import { isAiAgent } from '../src/native';
25-
26-
function handleAgenticSandbox() {
27-
const sandboxEnvVars = [
28-
'SANDBOX_RUNTIME',
29-
'CODEX_SANDBOX',
30-
'GEMINI_SANDBOX',
31-
'CURSOR_SANDBOX',
32-
];
33-
if (isAiAgent() && sandboxEnvVars.some((e) => process.env[e] !== undefined)) {
34-
process.env['NX_DAEMON'] = 'false';
35-
process.env['NX_ISOLATE_PLUGINS'] = 'false';
36-
}
37-
}
3824

3925
async function main() {
40-
handleAgenticSandbox();
4126
if (
4227
process.argv[2] !== 'report' &&
4328
process.argv[2] !== '--version' &&

packages/nx/src/daemon/client/client.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { ConfigurationSourceMaps } from '../../project-graph/utils/project-confi
3030
import { isJsonMessage } from '../../utils/consume-messages-from-socket';
3131
import { DelayedSpinner } from '../../utils/delayed-spinner';
3232
import { isCI } from '../../utils/is-ci';
33+
import { isSandbox } from '../../utils/is-sandbox';
3334
import { output } from '../../utils/output';
3435
import { PromisedBasedQueue } from '../../utils/promised-based-queue';
3536
import type {
@@ -230,7 +231,7 @@ export class DaemonClient {
230231
// version mismatch => no daemon because the installed nx version differs from the running one
231232
if (
232233
isNxVersionMismatch() ||
233-
((isCI() || isDocker()) && env !== 'true') ||
234+
((isCI() || isDocker() || isSandbox()) && env !== 'true') ||
234235
isDaemonDisabled() ||
235236
nxJsonIsNotPresent() ||
236237
(useDaemonProcessOption === undefined && env === 'false') ||

packages/nx/src/project-graph/plugins/isolation/enabled.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { IS_WASM } from '../../../native';
2+
import { isSandbox } from '../../../utils/is-sandbox';
23

34
export function isIsolationEnabled() {
45
// Explicitly enabled, regardless of further conditions
@@ -9,7 +10,9 @@ export function isIsolationEnabled() {
910
// Explicitly disabled
1011
process.env.NX_ISOLATE_PLUGINS === 'false' ||
1112
// Isolation is disabled on WASM builds currently.
12-
IS_WASM
13+
IS_WASM ||
14+
// Isolation is disabled in sandbox environments (AI agents, etc.)
15+
isSandbox()
1316
) {
1417
return false;
1518
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { isSandbox } from './is-sandbox';
2+
3+
describe('isSandbox', () => {
4+
const envVars = [
5+
'SANDBOX_RUNTIME',
6+
'GEMINI_SANDBOX',
7+
'CODEX_SANDBOX',
8+
'CURSOR_SANDBOX',
9+
];
10+
11+
const originalEnv: Record<string, string | undefined> = {};
12+
13+
beforeEach(() => {
14+
for (const key of envVars) {
15+
originalEnv[key] = process.env[key];
16+
delete process.env[key];
17+
}
18+
});
19+
20+
afterEach(() => {
21+
for (const key of envVars) {
22+
if (originalEnv[key] !== undefined) {
23+
process.env[key] = originalEnv[key];
24+
} else {
25+
delete process.env[key];
26+
}
27+
}
28+
});
29+
30+
it('should return false when no sandbox env vars are set', () => {
31+
expect(isSandbox()).toBe(false);
32+
});
33+
34+
it.each(envVars)('should return true when %s is set', (envVar: string) => {
35+
process.env[envVar] = 'true';
36+
expect(isSandbox()).toBe(true);
37+
});
38+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export function isSandbox(): boolean {
2+
return (
3+
!!process.env.SANDBOX_RUNTIME ||
4+
!!process.env.GEMINI_SANDBOX ||
5+
!!process.env.CODEX_SANDBOX ||
6+
!!process.env.CURSOR_SANDBOX
7+
);
8+
}

0 commit comments

Comments
 (0)