@cli4ai/lib
Advanced tools
+59
-16
| /** | ||
| * cli4ai - cliforai.com | ||
| * cli4ai - cli4ai.com | ||
| * Standardized CLI framework for AI agent tools | ||
@@ -7,7 +7,6 @@ */ | ||
| import { Command } from 'commander'; | ||
| import { resolve, dirname } from 'path'; | ||
| import { resolve } from 'path'; | ||
| import { existsSync, readFileSync } from 'fs'; | ||
| import { fileURLToPath } from 'url'; | ||
| const BRAND = 'cli4ai - cliforai.com'; | ||
| const BRAND = 'cli4ai - cli4ai.com'; | ||
@@ -32,12 +31,24 @@ // ═══════════════════════════════════════════════════════════════════════════ | ||
| export interface LoadEnvOptions { | ||
| cwd?: string; | ||
| searchParents?: boolean; | ||
| maxDepth?: number; | ||
| } | ||
| /** | ||
| * Load .env file from current directory or parent directories | ||
| * Load .env file from disk (explicit opt-in). | ||
| * | ||
| * SECURITY NOTE: Prefer `cli4ai secrets set <key>` over loading .env files. | ||
| */ | ||
| export function loadEnv(): void { | ||
| export function loadEnv(options: LoadEnvOptions = {}): void { | ||
| if (envLoaded) return; | ||
| envLoaded = true; | ||
| // Start from current working directory | ||
| let dir = process.cwd(); | ||
| for (let i = 0; i < 5; i++) { | ||
| const cwd = options.cwd ?? process.cwd(); | ||
| const searchParents = options.searchParents ?? false; | ||
| const maxDepth = options.maxDepth ?? (searchParents ? 5 : 0); | ||
| // Start from current working directory (optionally walk parents) | ||
| let dir = cwd; | ||
| for (let i = 0; i <= maxDepth; i++) { | ||
| const envPath = resolve(dir, '.env'); | ||
@@ -63,2 +74,3 @@ if (existsSync(envPath)) { | ||
| } | ||
| if (!searchParents) return; | ||
| dir = resolve(dir, '..'); | ||
@@ -72,2 +84,9 @@ } | ||
| // SECURITY NOTE: We intentionally do NOT auto-load .env files from the filesystem. | ||
| // This prevents supply chain attacks where malicious .env files in parent directories | ||
| // could inject credentials or override security settings. | ||
| // | ||
| // Use `cli4ai secrets set <key>` for secure credential storage, or set environment | ||
| // variables explicitly in your shell/CI environment. | ||
| /** | ||
@@ -77,4 +96,2 @@ * Require environment variables to be set. Exits with parseable error if missing. | ||
| export function requireEnv(...variables: string[]): void { | ||
| loadEnv(); | ||
| const missing = variables.filter(v => !process.env[v]); | ||
@@ -84,3 +101,3 @@ if (missing.length > 0) { | ||
| variables: missing, | ||
| hint: 'Set these in .env file in agent-tools root' | ||
| hint: 'Use "cli4ai secrets set <key>" to store securely, or set in your shell environment' | ||
| }); | ||
@@ -94,3 +111,2 @@ } | ||
| export function env(name: string): string { | ||
| loadEnv(); | ||
| const value = process.env[name]; | ||
@@ -100,3 +116,3 @@ if (!value) { | ||
| variables: [name], | ||
| hint: 'Set this in .env file in agent-tools root' | ||
| hint: 'Use "cli4ai secrets set ' + name + '" to store securely, or set in your shell environment' | ||
| }); | ||
@@ -111,3 +127,2 @@ } | ||
| export function envOr(name: string, defaultValue: string): string { | ||
| loadEnv(); | ||
| return process.env[name] || defaultValue; | ||
@@ -120,2 +135,20 @@ } | ||
| const EXIT_CODES: Record<string, number> = { | ||
| NOT_FOUND: 2, | ||
| INVALID_INPUT: 3, | ||
| ENV_MISSING: 4, | ||
| MANIFEST_ERROR: 4, | ||
| INSTALL_ERROR: 4, | ||
| AUTH_FAILED: 6, | ||
| NETWORK_ERROR: 7, | ||
| RATE_LIMITED: 8, | ||
| TIMEOUT: 9, | ||
| PARSE_ERROR: 10, | ||
| NPM_ERROR: 11, | ||
| }; | ||
| function getExitCode(code: string): number { | ||
| return EXIT_CODES[code] ?? 1; | ||
| } | ||
| /** | ||
@@ -141,5 +174,12 @@ * Output JSON data to stdout | ||
| })); | ||
| process.exit(1); | ||
| process.exit(getExitCode(code)); | ||
| } | ||
| /** | ||
| * Log to stderr (for progress messages) | ||
| */ | ||
| export function log(message: string): void { | ||
| console.error(message); | ||
| } | ||
| // ═══════════════════════════════════════════════════════════════════════════ | ||
@@ -202,2 +242,5 @@ // CLI CREATION | ||
| PARSE_ERROR: 'PARSE_ERROR', | ||
| MANIFEST_ERROR: 'MANIFEST_ERROR', | ||
| INSTALL_ERROR: 'INSTALL_ERROR', | ||
| NPM_ERROR: 'NPM_ERROR', | ||
| } as const; | ||
@@ -204,0 +247,0 @@ |
+3
-3
| { | ||
| "name": "@cli4ai/lib", | ||
| "version": "1.0.2", | ||
| "description": "Shared CLI framework for c4ai tools", | ||
| "version": "1.0.3", | ||
| "description": "Shared CLI framework for cli4ai tools", | ||
| "author": "cliforai", | ||
@@ -10,3 +10,3 @@ "license": "MIT", | ||
| "keywords": [ | ||
| "c4ai", | ||
| "cli4ai", | ||
| "cli", | ||
@@ -13,0 +13,0 @@ "ai-tools", |
+1
-1
| # @cli4ai/lib | ||
| > Official @cli4ai package • https://cli4ai.com • Install c4ai: `npm i -g c4ai` | ||
| > Official @cli4ai package • https://cli4ai.com • Install cli4ai: `npm i -g cli4ai` | ||
@@ -5,0 +5,0 @@ Shared CLI framework used by `@cli4ai/*` tool packages (env loading, JSON output, consistent errors). |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
11759
13.06%264
16.81%