am-i-vibing
Version:
Detect agentic coding environments and AI assistant tools
1 lines • 7.72 kB
Source Map (JSON)
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { parseArgs } from \"node:util\";\nimport { getProcessAncestry } from \"process-ancestry\";\nimport {\n detectAgenticEnvironment,\n isAgent,\n isInteractive,\n isHybrid,\n} from \"./detector.js\";\n\ninterface CliOptions {\n format?: \"json\" | \"text\";\n check?: \"agent\" | \"interactive\" | \"hybrid\";\n quiet?: boolean;\n help?: boolean;\n debug?: boolean;\n checkProcesses?: boolean;\n}\n\nfunction parseCliArgs(): CliOptions {\n const { values } = parseArgs({\n args: process.argv.slice(2),\n options: {\n format: {\n type: \"string\",\n short: \"f\",\n default: \"text\",\n },\n check: {\n type: \"string\",\n short: \"c\",\n },\n quiet: {\n type: \"boolean\",\n short: \"q\",\n default: false,\n },\n help: {\n type: \"boolean\",\n short: \"h\",\n default: false,\n },\n debug: {\n type: \"boolean\",\n short: \"d\",\n default: false,\n },\n \"check-processes\": {\n type: \"boolean\",\n short: \"p\",\n default: false,\n },\n },\n allowPositionals: false,\n });\n\n // Validate format option\n if (values.format && ![\"json\", \"text\"].includes(values.format)) {\n console.error(\n `Error: Invalid format '${values.format}'. Must be 'json' or 'text'.`,\n );\n process.exit(1);\n }\n\n // Validate check option\n if (\n values.check &&\n ![\"agent\", \"interactive\", \"hybrid\"].includes(values.check)\n ) {\n console.error(\n `Error: Invalid check type '${values.check}'. Must be 'agent', 'interactive', or 'hybrid'.`,\n );\n process.exit(1);\n }\n\n return {\n format: values.format as \"json\" | \"text\",\n check: values.check as \"agent\" | \"interactive\" | \"hybrid\",\n quiet: values.quiet,\n help: values.help,\n debug: values.debug,\n checkProcesses: values[\"check-processes\"],\n };\n}\n\nfunction showHelp(): void {\n console.log(`\nam-i-vibing - Detect agentic coding environments\n\nUSAGE:\n npx am-i-vibing [OPTIONS]\n\nOPTIONS:\n -f, --format <json|text> Output format (default: text)\n -c, --check <agent|interactive|hybrid> Check for specific environment type\n -q, --quiet Only output result, no labels\n -p, --check-processes Also walk the process tree for detection\n (slower, off by default)\n -d, --debug Debug output with environment and process info\n -h, --help Show this help message\n\nEXAMPLES:\n npx am-i-vibing # Detect current environment\n npx am-i-vibing --format json # JSON output\n npx am-i-vibing --check agent # Check if running under agent\n npx am-i-vibing --check hybrid # Check if running under hybrid\n npx am-i-vibing --quiet # Minimal output\n npx am-i-vibing --check-processes # Include process-tree detection\n npx am-i-vibing --debug # Debug with full environment info\n\nEXIT CODES:\n 0 Agentic environment detected (or specific check passed)\n 1 No agentic environment detected (or specific check failed)\n`);\n}\n\nfunction checkEnvironmentType(\n checkType: string,\n options: { checkProcesses?: boolean },\n): boolean {\n switch (checkType) {\n case \"agent\":\n return isAgent({ checkProcesses: options.checkProcesses });\n case \"interactive\":\n return isInteractive({ checkProcesses: options.checkProcesses });\n case \"hybrid\":\n return isHybrid({ checkProcesses: options.checkProcesses });\n default:\n return false;\n }\n}\n\nfunction formatOutput(\n result: ReturnType<typeof detectAgenticEnvironment>,\n options: CliOptions,\n): string {\n if (options.debug) {\n let processAncestry: any[] = [];\n try {\n processAncestry = getProcessAncestry();\n } catch (error) {\n processAncestry = [{ error: \"Failed to get process ancestry\" }];\n }\n\n const debugOutput = {\n detection: result,\n environment: process.env,\n processAncestry,\n };\n return JSON.stringify(debugOutput, null, 2);\n }\n\n if (options.format === \"json\") {\n return JSON.stringify(result, null, 2);\n }\n\n if (options.quiet) {\n if (options.check) {\n return checkEnvironmentType(options.check, options) ? \"true\" : \"false\";\n }\n return result.isAgentic ? `${result.name}` : \"none\";\n }\n\n if (options.check) {\n const matches = checkEnvironmentType(options.check, options);\n return matches\n ? `✓ Running in ${options.check} environment: ${result.name}`\n : `✗ Not running in ${options.check} environment`;\n }\n\n if (!result.isAgentic) {\n return \"✗ No agentic environment detected\";\n }\n\n return `✓ Detected: [${result.id}] ${result.name} (${result.type})`;\n}\n\nfunction main(): void {\n const options = parseCliArgs();\n\n if (options.help) {\n showHelp();\n process.exit(0);\n }\n\n // --debug always reveals the full picture, including process detection\n const checkProcesses = options.checkProcesses || options.debug;\n const result = detectAgenticEnvironment({ checkProcesses });\n let exitCode = 1;\n\n if (options.check) {\n exitCode = checkEnvironmentType(options.check, { checkProcesses }) ? 0 : 1;\n } else {\n exitCode = result.isAgentic ? 0 : 1;\n }\n\n const output = formatOutput(result, options);\n console.log(output);\n\n process.exit(exitCode);\n}\n\nmain();\n"],"mappings":"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"}