Sign In

sandbox-cli-detector

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sandbox-cli-detector - npm Package Compare versions

Comparing version
0.1.0
to
0.1.1
+10
-5
package.json
{
"name": "sandbox-cli-detector",
"version": "0.1.0",
"version": "0.1.1",
"description": "Detect whether a CLI is running inside a sandboxed environment (E2B, Vercel Sandbox, Replit, Daytona, Modal, and more)",

@@ -28,5 +28,10 @@ "keywords": [

".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}

@@ -38,3 +43,3 @@ },

"bin": {
"sandbox-cli-detector": "./dist/cli.js"
"sandbox-cli-detector": "dist/cli.js"
},

@@ -41,0 +46,0 @@ "files": [

+188
-53
# sandbox-cli-detector
Detect whether your CLI is running inside a sandboxed environment — an AI code-execution sandbox (E2B, Vercel Sandbox, Daytona, Modal, ...), an AI app builder (Replit, bolt.new, Rork, ...), or a cloud development environment (Codespaces, CodeSandbox, ...).
Detect whether the current process is running inside a sandboxed developer
environment.
Inspired by [ci-info](https://github.com/watson/ci-info) and a companion to [agent-cli-detector](https://github.com/davidmokos/detect-agent): `agent-cli-detector` tells you *which agent* is driving your CLI, this package tells you *where* it is running.
This is useful for CLIs, SDKs, test runners, and install scripts that need to
adjust behavior inside AI sandboxes, AI app builders, and cloud IDEs.
Inspired by [ci-info](https://github.com/watson/ci-info) and built as a
companion to [agent-cli-detector](https://github.com/davidmokos/detect-agent):
`agent-cli-detector` tells you which agent is driving your CLI;
`sandbox-cli-detector` tells you where that CLI is running.
Please open an issue if a sandbox is missing or incorrectly detected.
## Installation

@@ -19,62 +28,96 @@

if (isRunningInSandbox()) {
// e.g. skip interactive prompts, adjust telemetry, relax auth flows
// Skip interactive prompts, tune telemetry, relax auth flows, etc.
}
const result = detectSandbox();
// {
// detected: true,
// sandbox: {
// id: "e2b",
// name: "E2B",
// category: "ai-sandbox",
// instanceId: "sbx_abc123",
// evidence: [{ envVar: "E2B_SANDBOX", value: "true" }]
// },
// matches: [ ... ] // all matched sandboxes, most specific first
// }
if (result.detected) {
console.log("sandbox:", result.sandbox?.name);
} else {
console.log("not running in a known sandbox");
}
```
Or from the command line (exit code 0 when a sandbox is detected, 1 otherwise):
Example result:
```sh
npx sandbox-cli-detector # "detected: E2B (sbx_abc123)" / "no sandbox detected"
npx sandbox-cli-detector --json # full detection result as JSON
npx sandbox-cli-detector --quiet # exit code only
```json
{
"detected": true,
"sandbox": {
"id": "e2b",
"name": "E2B",
"category": "ai-sandbox",
"instanceId": "sbx_abc123",
"evidence": [{ "envVar": "E2B_SANDBOX", "value": "true" }]
},
"matches": [
{
"id": "e2b",
"name": "E2B",
"category": "ai-sandbox",
"instanceId": "sbx_abc123",
"evidence": [{ "envVar": "E2B_SANDBOX", "value": "true" }]
}
]
}
```
Layered environments are common — an app builder may run its builds inside a generic AI sandbox. `result.sandbox` is the most specific match (app builder → AI sandbox → cloud IDE) and `result.matches` lists everything that matched.
Layered environments are common. For example, an app builder may run user code
inside a generic AI sandbox. `result.sandbox` is the primary match and
`result.matches` contains every matched environment in definition order. The
built-in definitions are ordered from most specific to least specific:
app builders, then AI code-execution sandboxes, then cloud IDEs.
## Supported environments
Use `result.sandbox.id` for stable checks. `result.sandbox.name` is display text
and may change.
Detection currently relies on environment variables only. Every marker below was confirmed by probing the real platform — no guessed or documentation-only markers.
## CLI
### AI code-execution sandboxes
```sh
npx sandbox-cli-detector
# detected: E2B (sbx_abc123)
# no sandbox detected
| Sandbox | id | Detection env vars |
| --- | --- | --- |
| [E2B](https://e2b.dev) | `e2b` | `E2B_SANDBOX=true` (id: `E2B_SANDBOX_ID`) |
| [Vercel Sandbox](https://vercel.com/docs/sandbox) | `vercel-sandbox` | `HOME=/home/vercel-sandbox` |
| [Daytona](https://daytona.io) | `daytona` | `DAYTONA_SANDBOX_ID` |
| [Modal](https://modal.com) | `modal` | `MODAL_SANDBOX_ID` or `MODAL_TASK_ID` |
| [Cloudflare Sandbox](https://developers.cloudflare.com/sandbox/) | `cloudflare-sandbox` | `CLOUDFLARE_DURABLE_OBJECT_ID` |
npx sandbox-cli-detector --json
# prints the full DetectionResult as JSON
### AI app builders
npx sandbox-cli-detector --quiet
# no output, exit code only
```
| Sandbox | id | Detection env vars |
| --- | --- | --- |
| [Replit](https://replit.com) | `replit` | `REPLIT_SESSION`, `REPLIT_CONTAINER`, or `REPLIT_USER` |
| [bolt.new](https://bolt.new) | `bolt` | `BOLT_ENV`, `BOLT_ORIGIN`, or `BOLT_SERVER_URL` |
| [Rork](https://rork.com) | `rork` | `RORK_API_URL` (runs on E2B, so `e2b` also matches) |
Exit codes:
Lovable, v0, and Base44 are intentionally not on the list: they expose no shell, so a CLI can never run inside them.
| Code | Meaning |
| --- | --- |
| `0` | a known sandbox was detected |
| `1` | no known sandbox was detected |
### Cloud development environments
## Supported environments
| Sandbox | id | Detection env vars |
| --- | --- | --- |
| [GitHub Codespaces](https://github.com/features/codespaces) | `codespaces` | `CODESPACES=true` (id: `CODESPACE_NAME`) |
| [CodeSandbox](https://codesandbox.io) | `codesandbox` | `CSB=true` or `CSB_SANDBOX_ID` (id: `CSB_SANDBOX_ID`) |
Detection currently uses environment variables only. Every built-in marker was
confirmed by probing the real platform; guessed or documentation-only markers
are intentionally not included.
Missing a platform (Morph, Runloop, Gitpod, Cloud Shell, Coder, ...)? Please open an issue or PR with the env vars it sets — the fastest way to check is running `env | sort` (or `npx sandbox-cli-detector --json`) inside it.
| Name | Category | Stable id | Detection env vars | Instance id |
| --- | --- | --- | --- | --- |
| [Replit](https://replit.com) | app builder | `replit` | `REPLIT_SESSION`, `REPLIT_CONTAINER`, or `REPLIT_USER` | - |
| [bolt.new](https://bolt.new) | app builder | `bolt` | `BOLT_ENV`, `BOLT_ORIGIN`, or `BOLT_SERVER_URL` | - |
| [Rork](https://rork.com) | app builder | `rork` | `RORK_API_URL` | - |
| [E2B](https://e2b.dev) | AI sandbox | `e2b` | `E2B_SANDBOX=true` | `E2B_SANDBOX_ID` |
| [Vercel Sandbox](https://vercel.com/docs/sandbox) | AI sandbox | `vercel-sandbox` | `HOME=/home/vercel-sandbox` | - |
| [Daytona](https://daytona.io) | AI sandbox | `daytona` | `DAYTONA_SANDBOX_ID` | `DAYTONA_SANDBOX_ID` |
| [Modal](https://modal.com) | AI sandbox | `modal` | `MODAL_SANDBOX_ID` or `MODAL_TASK_ID` | `MODAL_SANDBOX_ID`, `MODAL_TASK_ID` |
| [Cloudflare Sandbox](https://developers.cloudflare.com/sandbox/) | AI sandbox | `cloudflare-sandbox` | `CLOUDFLARE_DURABLE_OBJECT_ID` | `CLOUDFLARE_DURABLE_OBJECT_ID` |
| [GitHub Codespaces](https://github.com/features/codespaces) | cloud IDE | `codespaces` | `CODESPACES=true` | `CODESPACE_NAME` |
| [CodeSandbox](https://codesandbox.io) | cloud IDE | `codesandbox` | `CSB=true` or `CSB_SANDBOX_ID` | `CSB_SANDBOX_ID` |
Notes:
- Rork currently runs on E2B, so `detectSandbox()` can report both `rork` and
`e2b` in `matches`.
- Lovable, v0, and Base44 are intentionally absent because they do not expose a
shell where a CLI can run.
- Some platforms do not provide a dedicated marker. Vercel Sandbox is detected
by its sandbox user home directory.
## API

@@ -84,26 +127,118 @@

Returns a `DetectionResult`:
Returns a `DetectionResult`.
- `detected: boolean`
- `sandbox: DetectedSandbox | null` — the most specific match
- `matches: DetectedSandbox[]` — all matches, in definition order
```ts
interface DetectionResult {
detected: boolean;
sandbox: DetectedSandbox | null;
matches: DetectedSandbox[];
}
```
Each `DetectedSandbox` has `id`, `name`, `category` (`"ai-sandbox" | "app-builder" | "cloud-ide"`), optional `instanceId`, and the `evidence` (which env vars matched).
`sandbox` is the primary match. `matches` includes all matches, in definition
order.
```ts
interface DetectedSandbox {
id: string;
name: string;
category: "ai-sandbox" | "app-builder" | "cloud-ide";
instanceId?: string;
evidence: DetectionEvidence[];
}
interface DetectionEvidence {
envVar: string;
value: string;
}
```
`evidence` contains the environment variables that caused a match. Treat the
values as runtime metadata and avoid logging them unless you are comfortable
with exposing your environment.
Options:
- `env` — environment to inspect (defaults to `process.env`)
- `sandboxes` — custom `SandboxDefinition[]` (defaults to the built-in list)
- `strategies` — custom `DetectionStrategy[]` (defaults to env-variable detection; more strategies, e.g. filesystem markers, may come later)
```ts
interface DetectSandboxOptions {
env?: Record<string, string | undefined>;
sandboxes?: readonly SandboxDefinition[];
strategies?: readonly DetectionStrategy[];
}
```
- `env` defaults to `process.env`.
- `sandboxes` defaults to the built-in `defaultSandboxes` list.
- `strategies` defaults to environment-variable detection.
### `isRunningInSandbox(options?)`
Convenience wrapper returning just the boolean.
Returns `true` when `detectSandbox(options).detected` is `true`.
```ts
if (isRunningInSandbox()) {
// running in a known sandbox
}
```
### `defaultSandboxes`
The built-in `SandboxDefinition[]`, exported so you can extend or filter it.
The built-in `SandboxDefinition[]`, exported so you can extend, filter, or
replace the supported environment list.
```ts
import { defaultSandboxes, detectSandbox } from "sandbox-cli-detector";
const result = detectSandbox({
sandboxes: defaultSandboxes.filter((sandbox) => sandbox.category !== "cloud-ide"),
});
```
### Custom sandbox definitions
Use custom definitions when you know about an internal sandbox or want to test
against a controlled environment object.
```ts
import { detectSandbox, defaultSandboxes } from "sandbox-cli-detector";
const result = detectSandbox({
env: {
INTERNAL_SANDBOX: "true",
INTERNAL_SANDBOX_ID: "dev-123",
},
sandboxes: [
{
id: "internal",
name: "Internal Sandbox",
category: "ai-sandbox",
env: [{ name: "INTERNAL_SANDBOX", value: "true" }],
idEnv: ["INTERNAL_SANDBOX_ID"],
verified: true,
},
...defaultSandboxes,
],
});
```
## Contributing platform detections
The best detection signals are stable environment variables that are present in
every shell for that platform and absent elsewhere.
To propose a new platform, open an issue or PR with:
- The platform name and URL.
- The output of `env | sort` from inside the platform, with secrets removed.
- Which variables identify the platform.
- Which variable, if any, contains the sandbox or instance id.
You can also run:
```sh
npx sandbox-cli-detector --json
```
## License
MIT