UNPKG

am-i-vibing

Version:

Detect agentic coding environments and AI assistant tools

251 lines (248 loc) 6.01 kB
import { getProcessAncestry } from "process-ancestry"; //#region src/providers.ts /** * Provider configurations for major AI coding tools */ const providers = [ { id: "sst-opencode", name: "SST OpenCode", type: "agent", envVars: [{ any: [ "OPENCODE_BIN_PATH", "OPENCODE_SERVER", "OPENCODE_APP_INFO", "OPENCODE_MODES" ] }] }, { id: "jules", name: "Jules", type: "agent", envVars: [{ all: [["HOME", "/home/jules"], ["USER", "swebot"]] }] }, { id: "claude-code", name: "Claude Code", type: "agent", envVars: ["CLAUDECODE"] }, { id: "cursor-agent", name: "Cursor Agent", type: "agent", envVars: [{ all: ["CURSOR_TRACE_ID", ["PAGER", "head -n 10000 | cat"]] }] }, { id: "cursor", name: "Cursor", type: "interactive", envVars: ["CURSOR_TRACE_ID"] }, { id: "gemini-agent", name: "Gemini Agent", type: "agent", processChecks: ["gemini"] }, { id: "codex", name: "OpenAI Codex", type: "agent", processChecks: ["codex"] }, { id: "replit", name: "Replit", type: "agent", envVars: ["REPL_ID"] }, { id: "aider", name: "Aider", type: "agent", envVars: ["AIDER_API_KEY"], processChecks: ["aider"] }, { id: "bolt-agent", name: "Bolt.new Agent", type: "agent", envVars: [{ all: [["SHELL", "/bin/jsh"], "npm_config_yes"] }] }, { id: "bolt", name: "Bolt.new", type: "interactive", envVars: [{ all: [["SHELL", "/bin/jsh"]], none: ["npm_config_yes"] }] }, { id: "zed-agent", name: "Zed Agent", type: "agent", envVars: [{ all: [["TERM_PROGRAM", "zed"], ["PAGER", "cat"]] }] }, { id: "zed", name: "Zed", type: "interactive", envVars: [{ all: [["TERM_PROGRAM", "zed"]], none: [["PAGER", "cat"]] }] }, { id: "replit-assistant", name: "Replit Assistant", type: "agent", envVars: [{ all: ["REPL_ID", ["REPLIT_MODE", "assistant"]] }] }, { id: "replit", name: "Replit", type: "interactive", envVars: [{ all: ["REPL_ID"], none: [["REPLIT_MODE", "assistant"]] }] }, { id: "windsurf", name: "Windsurf", type: "agent", envVars: ["CODEIUM_EDITOR_APP_ROOT"] }, { id: "crush", name: "Crush", type: "agent", processChecks: ["crush"] }, { id: "vscode-copilot-agent", name: "GitHub Copilot in VS Code", type: "agent", envVars: [{ all: [["TERM_PROGRAM", "vscode"], ["GIT_PAGER", "cat"]] }] }, { id: "warp", name: "Warp Terminal", type: "hybrid", envVars: [{ all: [["TERM_PROGRAM", "WarpTerminal"]] }] }, { id: "octofriend", name: "Octofriend", type: "agent", processChecks: ["octofriend"] } ]; /** * Get provider configuration by name */ function getProvider(name) { return providers.find((p) => p.name === name); } /** * Get all providers of a specific type */ function getProvidersByType(type) { return providers.filter((p) => p.type === type); } //#endregion //#region src/detector.ts /** * Check if a specific environment variable exists (handles both strings and tuples) */ function checkEnvVar(envVarDef, env = process.env) { const [envVar, expectedValue] = typeof envVarDef === "string" ? [envVarDef, void 0] : envVarDef; const actualValue = env[envVar]; return Boolean(actualValue && (!expectedValue || actualValue === expectedValue)); } /** * Check if a process is running in the process tree */ function checkProcess(processName, processAncestry) { try { const ancestry = processAncestry ?? getProcessAncestry(); for (const ancestorProcess of ancestry) if (ancestorProcess.command?.includes(processName)) return true; } catch (error) {} return false; } /** * Check if an environment variable group matches based on its properties */ function checkEnvVars(definition, env = process.env) { if (typeof definition === "string" || Array.isArray(definition)) return checkEnvVar(definition, env); const { any, all, none } = definition; const anyResult = !any?.length || any.some((envVar) => checkEnvVar(envVar, env)); const allResult = !all?.length || all.every((envVar) => checkEnvVar(envVar, env)); const noneResult = !none?.length || !none.some((envVar) => checkEnvVar(envVar, env)); return anyResult && allResult && noneResult; } /** * Run custom detectors for a provider */ function runCustomDetectors(provider) { return provider.customDetectors?.some((detector) => { try { return detector(); } catch { return false; } }) ?? false; } /** * Create a positive detection result */ function createDetectedResult(provider) { return { isAgentic: true, id: provider.id, name: provider.name, type: provider.type }; } /** * Detect agentic coding environment */ function detectAgenticEnvironment(env = process.env, processAncestry) { for (const provider of providers) { if (provider.envVars?.some((group) => checkEnvVars(group, env))) return createDetectedResult(provider); if (provider.processChecks?.some((processName) => checkProcess(processName, processAncestry))) return createDetectedResult(provider); if (runCustomDetectors(provider)) return createDetectedResult(provider); } return { isAgentic: false, id: null, name: null, type: null }; } /** * Check if currently running in any agent environment */ function isAgent(env = process.env, processAncestry) { const result = detectAgenticEnvironment(env, processAncestry); return result.type === "agent" || result.type === "hybrid"; } /** * Check if currently running in any interactive AI environment */ function isInteractive(env = process.env, processAncestry) { const result = detectAgenticEnvironment(env, processAncestry); return result.type === "interactive" || result.type === "hybrid"; } /** * Check if currently running in any hybrid AI environment */ function isHybrid(env = process.env, processAncestry) { const result = detectAgenticEnvironment(env, processAncestry); return result.type === "hybrid"; } //#endregion export { detectAgenticEnvironment, getProvider, getProvidersByType, isAgent, isHybrid, isInteractive, providers }; //# sourceMappingURL=detector-LEsE74_L.js.map