🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@vercel/detect-agent

Package Overview
Dependencies
Maintainers
4
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@vercel/detect-agent - npm Package Compare versions

Comparing version
0.2.0
to
1.0.0
+19
CHANGELOG.md
# @vercel/detect-agent
## 1.0.0
### Major Changes
- Change return format to be an object to future proof ([#13965](https://github.com/vercel/vercel/pull/13965))
## 0.2.0
### Minor Changes
- Improve agent detection ([#13762](https://github.com/vercel/vercel/pull/13762))
## 0.1.0
### Minor Changes
- Initial release ([#13745](https://github.com/vercel/vercel/pull/13745))
# @vercel/detect-agent
A lightweight utility for detecting if code is being executed by an AI agent or automated development environment.
## Installation
```bash
npm install @vercel/detect-agent
```
## Usage
```typescript
import { determineAgent } from '@vercel/detect-agent';
const { isAgent, agent } = await determineAgent();
if (isAgent) {
console.log(`Running in ${agent.name} environment`);
// Adapt behavior for AI agent context
}
```
## Supported Agents
This package can detect the following AI agents and development environments:
- **Custom agents** via `AI_AGENT` environment variable
- **Cursor** (cursor editor and cursor-cli)
- **Claude Code** (Anthropic's Claude)
- **Devin** (Cognition Labs)
- **Gemini CLI** (Google)
- **Codex** (OpenAI)
- **Replit** (online IDE)
## The AI_AGENT Standard
We're promoting `AI_AGENT` as a universal environment variable standard for AI development tools. This allows any tool or library to easily detect when it's running in an AI-driven environment.
### For AI Tool Developers
Set the `AI_AGENT` environment variable to identify your tool:
```bash
export AI_AGENT="your-tool-name"
# or
AI_AGENT="your-tool-name" your-command
```
### Recommended Naming Convention
- Use lowercase with hyphens for multi-word names
- Include version information if needed, separated by an `@` symbol
- Examples: `claude-code`, `cursor-cli`, `devin@1`, `custom-agent@2.0`
## Use Cases
### Adaptive Behavior
```typescript
import { determineAgent } from '@vercel/detect-agent';
async function setupEnvironment() {
const { isAgent, agent } = await determineAgent();
if (isAgent) {
// Running in AI environment - adjust behavior
process.env.LOG_LEVEL = 'verbose';
console.log(`🤖 Detected AI agent: ${agent.name}`);
}
}
```
### Telemetry and Analytics
```typescript
import { determineAgent } from '@vercel/detect-agent';
async function trackUsage(event: string) {
const result = await determineAgent();
analytics.track(event, {
agent: result.isAgent ? result.agent.name : 'human',
timestamp: Date.now(),
});
}
```
### Feature Toggles
```typescript
import { determineAgent } from '@vercel/detect-agent';
async function shouldEnableFeature(feature: string) {
const result = await determineAgent();
// Enable experimental features for AI agents
if (result.isAgent && feature === 'experimental-ai-mode') {
return true;
}
return false;
}
```
## Contributing
We welcome contributions! Please see our [contributing guidelines](../../CONTRIBUTING.md).
### Adding New Agent Support
To add support for a new AI agent:
1. Add detection logic to `src/index.ts`
2. Add comprehensive test cases in `test/unit/determine-agent.test.ts`
3. Update this README with the new agent information
4. Follow the existing priority order pattern
## Links
- [GitHub Repository](https://github.com/vercel/vercel/tree/main/packages/detect-agent)
- [npm Package](https://www.npmjs.com/package/@vercel/detect-agent)
- [Vercel Documentation](https://vercel.com/docs)
+28
-11

@@ -21,2 +21,3 @@ "use strict";

__export(src_exports, {
KNOWN_AGENTS: () => KNOWN_AGENTS,
determineAgent: () => determineAgent

@@ -27,3 +28,3 @@ });

var import_node_fs = require("node:fs");
const devinLocalPath = "/opt/.devin";
const DEVIN_LOCAL_PATH = "/opt/.devin";
const CURSOR = "cursor";

@@ -36,34 +37,50 @@ const CURSOR_CLI = "cursor-cli";

const CODEX = "codex";
const KNOWN_AGENTS = {
CURSOR,
CURSOR_CLI,
CLAUDE,
DEVIN,
REPLIT,
GEMINI,
CODEX
};
async function determineAgent() {
if (process.env.AI_AGENT) {
return process.env.AI_AGENT;
const name = process.env.AI_AGENT.trim();
if (name) {
return {
isAgent: true,
agent: { name }
};
}
}
if (process.env.CURSOR_TRACE_ID) {
return CURSOR;
return { isAgent: true, agent: { name: CURSOR } };
}
if (process.env.CURSOR_AGENT) {
return CURSOR_CLI;
return { isAgent: true, agent: { name: CURSOR_CLI } };
}
if (process.env.GEMINI_CLI) {
return GEMINI;
return { isAgent: true, agent: { name: GEMINI } };
}
if (process.env.CODEX_SANDBOX) {
return CODEX;
return { isAgent: true, agent: { name: CODEX } };
}
if (process.env.CLAUDECODE || process.env.CLAUDE_CODE) {
return CLAUDE;
return { isAgent: true, agent: { name: CLAUDE } };
}
if (process.env.REPL_ID) {
return REPLIT;
return { isAgent: true, agent: { name: REPLIT } };
}
try {
await (0, import_promises.access)(devinLocalPath, import_node_fs.constants.F_OK);
return DEVIN;
await (0, import_promises.access)(DEVIN_LOCAL_PATH, import_node_fs.constants.F_OK);
return { isAgent: true, agent: { name: DEVIN } };
} catch (error) {
return false;
}
return { isAgent: false, agent: void 0 };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
KNOWN_AGENTS,
determineAgent
});

@@ -1,1 +0,29 @@

export declare function determineAgent(): Promise<string | false>;
declare const CURSOR: "cursor";
declare const CURSOR_CLI: "cursor-cli";
declare const CLAUDE: "claude";
declare const DEVIN: "devin";
declare const REPLIT: "replit";
declare const GEMINI: "gemini";
declare const CODEX: "codex";
export type KnownAgentNames = typeof CURSOR | typeof CURSOR_CLI | typeof CLAUDE | typeof DEVIN | typeof REPLIT | typeof GEMINI | typeof CODEX;
export interface KnownAgentDetails {
name: KnownAgentNames;
}
export type AgentResult = {
isAgent: true;
agent: KnownAgentDetails;
} | {
isAgent: false;
agent: undefined;
};
export declare const KNOWN_AGENTS: {
readonly CURSOR: "cursor";
readonly CURSOR_CLI: "cursor-cli";
readonly CLAUDE: "claude";
readonly DEVIN: "devin";
readonly REPLIT: "replit";
readonly GEMINI: "gemini";
readonly CODEX: "codex";
};
export declare function determineAgent(): Promise<AgentResult>;
export {};

@@ -21,2 +21,3 @@ "use strict";

__export(src_exports, {
KNOWN_AGENTS: () => KNOWN_AGENTS,
determineAgent: () => determineAgent

@@ -27,3 +28,3 @@ });

var import_node_fs = require("node:fs");
const devinLocalPath = "/opt/.devin";
const DEVIN_LOCAL_PATH = "/opt/.devin";
const CURSOR = "cursor";

@@ -36,34 +37,50 @@ const CURSOR_CLI = "cursor-cli";

const CODEX = "codex";
const KNOWN_AGENTS = {
CURSOR,
CURSOR_CLI,
CLAUDE,
DEVIN,
REPLIT,
GEMINI,
CODEX
};
async function determineAgent() {
if (process.env.AI_AGENT) {
return process.env.AI_AGENT;
const name = process.env.AI_AGENT.trim();
if (name) {
return {
isAgent: true,
agent: { name }
};
}
}
if (process.env.CURSOR_TRACE_ID) {
return CURSOR;
return { isAgent: true, agent: { name: CURSOR } };
}
if (process.env.CURSOR_AGENT) {
return CURSOR_CLI;
return { isAgent: true, agent: { name: CURSOR_CLI } };
}
if (process.env.GEMINI_CLI) {
return GEMINI;
return { isAgent: true, agent: { name: GEMINI } };
}
if (process.env.CODEX_SANDBOX) {
return CODEX;
return { isAgent: true, agent: { name: CODEX } };
}
if (process.env.CLAUDECODE || process.env.CLAUDE_CODE) {
return CLAUDE;
return { isAgent: true, agent: { name: CLAUDE } };
}
if (process.env.REPL_ID) {
return REPLIT;
return { isAgent: true, agent: { name: REPLIT } };
}
try {
await (0, import_promises.access)(devinLocalPath, import_node_fs.constants.F_OK);
return DEVIN;
await (0, import_promises.access)(DEVIN_LOCAL_PATH, import_node_fs.constants.F_OK);
return { isAgent: true, agent: { name: DEVIN } };
} catch (error) {
return false;
}
return { isAgent: false, agent: void 0 };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
KNOWN_AGENTS,
determineAgent
});
{
"name": "@vercel/detect-agent",
"version": "0.2.0",
"version": "1.0.0",
"description": "Detect if code is running in an AI agent or automated development environment",
"keywords": [
"ai",
"agent",
"detection",
"environment",
"cursor",
"claude",
"devin",
"automation",
"ai-agent"
],
"license": "Apache-2.0",
"author": "Vercel",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.js"
}
},
"publishConfig": {
"access": "public"
},
"homepage": "https://vercel.com/docs",
"homepage": "https://github.com/vercel/vercel/tree/main/packages/detect-agent#readme",
"repository": {

@@ -15,4 +36,12 @@ "type": "git",

},
"bugs": {
"url": "https://github.com/vercel/vercel/issues"
},
"engines": {
"node": ">=14"
},
"files": [
"dist"
"dist",
"README.md",
"CHANGELOG.md"
],

@@ -28,6 +57,5 @@ "dependencies": {},

"build": "node ../../utils/build.mjs",
"vitest-run": "vitest -c ../../vitest.config.mts",
"vitest-unit": "glob --absolute 'test/unit/**/*.test.ts' 'test/unit/**/*.test.mts'",
"test": "vitest -c ../../vitest.config.mts",
"type-check": "tsc --noEmit"
}
}