am-i-vibing 0.0.1

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 ADDED
@@ -0,0 +1,118 @@
1
+ # am-i-vibing
2
+
3
+ Detect agentic coding environments and AI assistant tools. This library allows CLI tools and applications to detect when they're being executed by AI agents (like Claude Code) and adapt their behavior accordingly.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install am-i-vibing
9
+ ```
10
+
11
+ ## CLI Usage
12
+
13
+ Use the CLI to quickly check if you're running in an agentic environment:
14
+
15
+ ```bash
16
+ # Basic detection
17
+ npx am-i-vibing
18
+ # ✓ Detected: Claude Code (agent)
19
+
20
+ # JSON output
21
+ npx am-i-vibing --format json
22
+ # {"isAgentic": true, "id": "claude-code", "name": "Claude Code", "type": "agent"}
23
+
24
+ # Check for specific environment type
25
+ npx am-i-vibing --check agent
26
+ # ✓ Running in agent environment: Claude Code
27
+
28
+ npx am-i-vibing --check interactive
29
+ # ✗ Not running in interactive environment
30
+
31
+ # Quiet mode (useful for scripts)
32
+ npx am-i-vibing --quiet
33
+ # Claude Code
34
+ ```
35
+
36
+ ### CLI Options
37
+
38
+ - `-f, --format <json|text>` - Output format (default: text)
39
+ - `-c, --check <agent|interactive>` - Check for specific environment type
40
+ - `-q, --quiet` - Only output result, no labels
41
+ - `-h, --help` - Show help message
42
+
43
+ ### Exit Codes
44
+
45
+ - `0` - Agentic environment detected (or specific check passed)
46
+ - `1` - No agentic environment detected (or specific check failed)
47
+
48
+ ## Library Usage
49
+
50
+ ```typescript
51
+ import { detectAgenticEnvironment, isAgent, isInteractive } from 'am-i-vibing';
52
+
53
+ // Full detection
54
+ const result = detectAgenticEnvironment();
55
+ console.log(`Detected: ${result.name} (${result.type})`);
56
+ console.log(`ID: ${result.id}`);
57
+ console.log(`Is agentic: ${result.isAgentic}`);
58
+
59
+ // Quick checks
60
+ if (isAgent()) {
61
+ console.log('Running under direct AI agent control');
62
+ }
63
+
64
+ if (isInteractive()) {
65
+ console.log('Running in interactive AI environment');
66
+ }
67
+ ```
68
+
69
+ ## Detection Result
70
+
71
+ The library returns a `DetectionResult` object with the following structure:
72
+
73
+ ```typescript
74
+ interface DetectionResult {
75
+ isAgentic: boolean; // Whether any agentic environment was detected
76
+ id: string | null; // Provider ID (e.g., "claude-code")
77
+ name: string | null; // Human-readable name (e.g., "Claude Code")
78
+ type: AgenticType | null; // "agent" | "interactive" | "hybrid"
79
+ }
80
+ ```
81
+
82
+ ## Supported AI Tools
83
+
84
+ ### Direct Agents (Full CLI control)
85
+ - **Claude Code** - Anthropic's official CLI tool
86
+ - **Replit AI** - Replit's AI assistant
87
+ - **Aider** - AI pair programming tool
88
+ - **Bolt.new** - AI-powered development environment
89
+
90
+ ### Embedded IDE Features
91
+ - **Cursor** - AI-powered code editor
92
+ - **GitHub Copilot** - AI code completion
93
+ - **Windsurf/Codeium** - AI coding assistant
94
+ - **Continue.dev** - Open-source AI code assistant
95
+ - **Tabnine** - AI code completion
96
+ - **Zed** - High-performance editor with AI features
97
+
98
+ ## Environment Types
99
+
100
+ - **Agent**: Full autonomous control over the terminal/CLI
101
+ - **Interactive**: AI assistance within an IDE or editor environment
102
+ - **Hybrid**: Tools that can operate in both modes
103
+
104
+ ## Use Cases
105
+
106
+ - **CLI Tools**: Adapt behavior when running under AI control (e.g., provide more detailed output)
107
+ - **Development Scripts**: Skip interactive prompts when detected as automated
108
+ - **Testing**: Detect test environments vs. human usage
109
+ - **Analytics**: Track usage patterns across different AI tools
110
+ - **Documentation**: Generate context-aware help and examples
111
+
112
+ ## Contributing
113
+
114
+ This project uses a monorepo structure with pnpm workspaces. See the main repository for contribution guidelines.
115
+
116
+ ## License
117
+
118
+ MIT
@@ -0,0 +1,220 @@
1
+ // src/providers.ts
2
+ var providers = [
3
+ {
4
+ id: "claude-code",
5
+ name: "Claude Code",
6
+ type: "agent",
7
+ envVars: ["CLAUDECODE"]
8
+ },
9
+ {
10
+ id: "cursor-agent",
11
+ name: "Cursor Agent",
12
+ type: "agent",
13
+ envVars: [
14
+ {
15
+ all: ["CURSOR_TRACE_ID", ["PAGER", "head -n 10000 | cat"]]
16
+ }
17
+ ]
18
+ },
19
+ {
20
+ id: "cursor",
21
+ name: "Cursor",
22
+ type: "interactive",
23
+ envVars: ["CURSOR_TRACE_ID"]
24
+ },
25
+ {
26
+ id: "gemini-agent",
27
+ name: "Gemini Agent",
28
+ type: "agent",
29
+ processChecks: ["gemini"]
30
+ },
31
+ {
32
+ id: "codex",
33
+ name: "OpenAI Codex",
34
+ type: "agent",
35
+ processChecks: ["codex"]
36
+ },
37
+ {
38
+ id: "replit",
39
+ name: "Replit",
40
+ type: "agent",
41
+ envVars: ["REPL_ID"]
42
+ },
43
+ {
44
+ id: "aider",
45
+ name: "Aider",
46
+ type: "agent",
47
+ envVars: ["AIDER_API_KEY"],
48
+ processChecks: ["aider"]
49
+ },
50
+ {
51
+ id: "bolt-agent",
52
+ name: "Bolt.new Agent",
53
+ type: "agent",
54
+ envVars: [
55
+ {
56
+ all: [["SHELL", "/bin/jsh"], "npm_config_yes"]
57
+ }
58
+ ]
59
+ },
60
+ {
61
+ id: "bolt",
62
+ name: "Bolt.new",
63
+ type: "interactive",
64
+ envVars: [
65
+ {
66
+ all: [["SHELL", "/bin/jsh"]],
67
+ none: ["npm_config_yes"]
68
+ }
69
+ ]
70
+ },
71
+ {
72
+ id: "zed-agent",
73
+ name: "Zed Agent",
74
+ type: "agent",
75
+ envVars: [
76
+ {
77
+ all: [
78
+ ["TERM_PROGRAM", "zed"],
79
+ ["PAGER", "cat"]
80
+ ]
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ id: "zed",
86
+ name: "Zed",
87
+ type: "interactive",
88
+ envVars: [
89
+ {
90
+ all: [["TERM_PROGRAM", "zed"]],
91
+ none: [["PAGER", "cat"]]
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ id: "replit-assistant",
97
+ name: "Replit Assistant",
98
+ type: "agent",
99
+ envVars: [
100
+ {
101
+ all: ["REPL_ID", ["REPLIT_MODE", "assistant"]]
102
+ }
103
+ ]
104
+ },
105
+ {
106
+ id: "replit",
107
+ name: "Replit",
108
+ type: "interactive",
109
+ envVars: [
110
+ {
111
+ all: ["REPL_ID"],
112
+ none: [["REPLIT_MODE", "assistant"]]
113
+ }
114
+ ]
115
+ },
116
+ {
117
+ id: "github-copilot-agent",
118
+ name: "VS Code Copilot",
119
+ type: "agent",
120
+ envVars: [
121
+ {
122
+ all: [
123
+ ["TERM_PROGRAM", "vscode"],
124
+ ["GIT_PAGER", "cat"]
125
+ ]
126
+ }
127
+ ]
128
+ }
129
+ ];
130
+ function getProvider(name) {
131
+ return providers.find((p) => p.name === name);
132
+ }
133
+ function getProvidersByType(type) {
134
+ return providers.filter((p) => p.type === type);
135
+ }
136
+
137
+ // src/detector.ts
138
+ import { getProcessAncestry } from "process-ancestry";
139
+ function checkEnvVar(envVarDef, env = process.env) {
140
+ const [envVar, expectedValue] = typeof envVarDef === "string" ? [envVarDef, void 0] : envVarDef;
141
+ const actualValue = env[envVar];
142
+ return Boolean(
143
+ actualValue && (!expectedValue || actualValue === expectedValue)
144
+ );
145
+ }
146
+ function checkProcess(processName) {
147
+ try {
148
+ const ancestry = getProcessAncestry();
149
+ for (const ancestorProcess of ancestry) {
150
+ if (ancestorProcess.command?.includes(processName)) {
151
+ return true;
152
+ }
153
+ }
154
+ } catch (error) {
155
+ }
156
+ return false;
157
+ }
158
+ function checkEnvVars(definition, env = process.env) {
159
+ if (typeof definition === "string" || Array.isArray(definition)) {
160
+ return checkEnvVar(definition, env);
161
+ }
162
+ const { any, all, none } = definition;
163
+ const anyResult = !any?.length || any.some((envVar) => checkEnvVar(envVar, env));
164
+ const allResult = !all?.length || all.every((envVar) => checkEnvVar(envVar, env));
165
+ const noneResult = !none?.length || !none.some((envVar) => checkEnvVar(envVar, env));
166
+ return anyResult && allResult && noneResult;
167
+ }
168
+ function runCustomDetectors(provider) {
169
+ return provider.customDetectors?.some((detector) => {
170
+ try {
171
+ return detector();
172
+ } catch {
173
+ return false;
174
+ }
175
+ }) ?? false;
176
+ }
177
+ function createDetectedResult(provider) {
178
+ return {
179
+ isAgentic: true,
180
+ id: provider.id,
181
+ name: provider.name,
182
+ type: provider.type
183
+ };
184
+ }
185
+ function detectAgenticEnvironment(env = process.env) {
186
+ for (const provider of providers) {
187
+ if (provider.envVars?.some((group) => checkEnvVars(group, env))) {
188
+ return createDetectedResult(provider);
189
+ }
190
+ if (provider.processChecks?.some(checkProcess)) {
191
+ return createDetectedResult(provider);
192
+ }
193
+ if (runCustomDetectors(provider)) {
194
+ return createDetectedResult(provider);
195
+ }
196
+ }
197
+ return {
198
+ isAgentic: false,
199
+ id: null,
200
+ name: null,
201
+ type: null
202
+ };
203
+ }
204
+ function isAgent(env = process.env) {
205
+ const result = detectAgenticEnvironment(env);
206
+ return result.type === "agent";
207
+ }
208
+ function isInteractive(env = process.env) {
209
+ const result = detectAgenticEnvironment(env);
210
+ return result.type === "interactive";
211
+ }
212
+
213
+ export {
214
+ providers,
215
+ getProvider,
216
+ getProvidersByType,
217
+ detectAgenticEnvironment,
218
+ isAgent,
219
+ isInteractive
220
+ };
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/cli.js ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ detectAgenticEnvironment,
4
+ isAgent,
5
+ isInteractive
6
+ } from "./chunk-G62RWBK7.js";
7
+
8
+ // src/cli.ts
9
+ function parseArgs(args) {
10
+ const options = {};
11
+ for (let i = 0; i < args.length; i++) {
12
+ const arg = args[i];
13
+ switch (arg) {
14
+ case "--format":
15
+ case "-f":
16
+ options.format = args[++i];
17
+ break;
18
+ case "--check":
19
+ case "-c":
20
+ options.check = args[++i];
21
+ break;
22
+ case "--quiet":
23
+ case "-q":
24
+ options.quiet = true;
25
+ break;
26
+ case "--help":
27
+ case "-h":
28
+ options.help = true;
29
+ break;
30
+ }
31
+ }
32
+ return options;
33
+ }
34
+ function showHelp() {
35
+ console.log(`
36
+ am-i-vibing - Detect agentic coding environments
37
+
38
+ USAGE:
39
+ npx am-i-vibing [OPTIONS]
40
+
41
+ OPTIONS:
42
+ -f, --format <json|text> Output format (default: text)
43
+ -c, --check <agent|interactive> Check for specific environment type
44
+ -q, --quiet Only output result, no labels
45
+ -h, --help Show this help message
46
+
47
+ EXAMPLES:
48
+ npx am-i-vibing # Detect current environment
49
+ npx am-i-vibing --format json # JSON output
50
+ npx am-i-vibing --check agent # Check if running under agent
51
+ npx am-i-vibing --quiet # Minimal output
52
+
53
+ EXIT CODES:
54
+ 0 Agentic environment detected (or specific check passed)
55
+ 1 No agentic environment detected (or specific check failed)
56
+ `);
57
+ }
58
+ function formatOutput(result, options) {
59
+ if (options.format === "json") {
60
+ return JSON.stringify(result, null, 2);
61
+ }
62
+ if (options.quiet) {
63
+ if (options.check) {
64
+ return result.type === options.check ? "true" : "false";
65
+ }
66
+ return result.isAgentic ? `${result.name}` : "none";
67
+ }
68
+ if (options.check) {
69
+ const matches = result.type === options.check;
70
+ return matches ? `\u2713 Running in ${options.check} environment: ${result.name}` : `\u2717 Not running in ${options.check} environment`;
71
+ }
72
+ if (!result.isAgentic) {
73
+ return "\u2717 No agentic environment detected";
74
+ }
75
+ return `\u2713 Detected: ${result.name} (${result.type})`;
76
+ }
77
+ function main() {
78
+ const args = process.argv.slice(2);
79
+ const options = parseArgs(args);
80
+ if (options.help) {
81
+ showHelp();
82
+ process.exit(0);
83
+ }
84
+ let result;
85
+ let exitCode = 1;
86
+ if (options.check === "agent") {
87
+ const isAgentEnv = isAgent();
88
+ result = detectAgenticEnvironment();
89
+ exitCode = isAgentEnv ? 0 : 1;
90
+ } else if (options.check === "interactive") {
91
+ const isInteractiveEnv = isInteractive();
92
+ result = detectAgenticEnvironment();
93
+ exitCode = isInteractiveEnv ? 0 : 1;
94
+ } else {
95
+ result = detectAgenticEnvironment();
96
+ exitCode = result.isAgentic ? 0 : 1;
97
+ }
98
+ const output = formatOutput(result, options);
99
+ console.log(output);
100
+ process.exit(exitCode);
101
+ }
102
+ main();
@@ -0,0 +1,81 @@
1
+ /**
2
+ * The type of AI coding environment detected
3
+ */
4
+ type AgenticType = "agent" | "interactive" | "hybrid";
5
+ /**
6
+ * Environment variable definition - either just a name or a name/value tuple
7
+ */
8
+ type EnvVarDefinition = string | [string, string];
9
+ /**
10
+ * Environment variable group with logical operators
11
+ */
12
+ interface EnvVarGroup {
13
+ /** ANY of these environment variables can match (OR logic) */
14
+ any?: EnvVarDefinition[];
15
+ /** ALL of these environment variables must match (AND logic) */
16
+ all?: EnvVarDefinition[];
17
+ /** NONE of these environment variables should be present (NOT logic) */
18
+ none?: EnvVarDefinition[];
19
+ }
20
+ /**
21
+ * Configuration for detecting a specific AI coding provider
22
+ */
23
+ interface ProviderConfig {
24
+ /** Unique identifier for the provider */
25
+ id: string;
26
+ /** Human-readable name of the provider */
27
+ name: string;
28
+ /** Type of AI coding environment */
29
+ type: AgenticType;
30
+ /** Environment variables */
31
+ envVars?: Array<EnvVarGroup | EnvVarDefinition>;
32
+ /** Process names to check for in the process tree */
33
+ processChecks?: string[];
34
+ /** Custom detection functions for complex logic */
35
+ customDetectors?: (() => boolean)[];
36
+ }
37
+ /**
38
+ * Result of agentic environment detection
39
+ */
40
+ interface DetectionResult {
41
+ /** Whether an agentic environment was detected */
42
+ isAgentic: boolean;
43
+ /** ID of the detected provider, if any */
44
+ id: string | null;
45
+ /** Name of the detected provider, if any */
46
+ name: string | null;
47
+ /** Type of agentic environment, if detected */
48
+ type: AgenticType | null;
49
+ }
50
+
51
+ /**
52
+ * Provider configurations for major AI coding tools
53
+ */
54
+ declare const providers: ProviderConfig[];
55
+ /**
56
+ * Get provider configuration by name
57
+ */
58
+ declare function getProvider(name: string): ProviderConfig | undefined;
59
+ /**
60
+ * Get all providers of a specific type
61
+ */
62
+ declare function getProvidersByType(type: "agent" | "interactive"): ProviderConfig[];
63
+
64
+ /**
65
+ * Detect agentic coding environment
66
+ */
67
+ declare function detectAgenticEnvironment(env?: Record<string, string | undefined>): DetectionResult;
68
+ /**
69
+ * Check if currently running in any agent environment
70
+ */
71
+ declare function isAgent(env?: Record<string, string | undefined>): boolean;
72
+ /**
73
+ * Check if currently running in any interactive AI environment
74
+ */
75
+ declare function isInteractive(env?: Record<string, string | undefined>): boolean;
76
+
77
+ /**
78
+ * am-i-vibing - Detect agentic coding environments and AI assistant tools
79
+ */
80
+
81
+ export { type AgenticType, type DetectionResult, type ProviderConfig, detectAgenticEnvironment as default, detectAgenticEnvironment, getProvider, getProvidersByType, isAgent, isInteractive, providers };
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ import {
2
+ detectAgenticEnvironment,
3
+ getProvider,
4
+ getProvidersByType,
5
+ isAgent,
6
+ isInteractive,
7
+ providers
8
+ } from "./chunk-G62RWBK7.js";
9
+
10
+ // src/index.ts
11
+ var index_default = detectAgenticEnvironment;
12
+ export {
13
+ index_default as default,
14
+ detectAgenticEnvironment,
15
+ getProvider,
16
+ getProvidersByType,
17
+ isAgent,
18
+ isInteractive,
19
+ providers
20
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "am-i-vibing",
3
+ "version": "0.0.1",
4
+ "description": "Detect agentic coding environments and AI assistant tools",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "am-i-vibing": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "exports": {
14
+ ".": "./dist/index.js"
15
+ },
16
+ "devDependencies": {
17
+ "@arethetypeswrong/cli": "^0.18.2",
18
+ "@types/node": "^20.0.0",
19
+ "publint": "^0.3.12",
20
+ "tsup": "^8.5.0",
21
+ "typescript": "^5.8.3",
22
+ "vitest": "^2.0.0"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com:ascorbic/am-i-vibing.git",
27
+ "directory": "packages/am-i-vibing"
28
+ },
29
+ "homepage": "https://github.com/ascorbic/am-i-vibing",
30
+ "keywords": [
31
+ "ai",
32
+ "agentic",
33
+ "coding",
34
+ "detection",
35
+ "llm",
36
+ "assistant"
37
+ ],
38
+ "author": "Matt Kane",
39
+ "license": "MIT",
40
+ "dependencies": {
41
+ "process-ancestry": "^0.0.2"
42
+ },
43
+ "scripts": {
44
+ "build": "tsup src/index.ts src/cli.ts --format esm --dts --clean",
45
+ "dev": "tsup src/index.ts src/cli.ts --format esm --dts --watch",
46
+ "check": "publint && attw --pack --ignore-rules=cjs-resolves-to-esm",
47
+ "test": "vitest run",
48
+ "whoami": "tsx scripts/whoami.ts"
49
+ }
50
+ }