@vibe-agent-toolkit/utils 0.1.0-rc.7

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.
@@ -0,0 +1,393 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import which from 'which';
3
+ /**
4
+ * Error thrown when command execution fails
5
+ */
6
+ export class CommandExecutionError extends Error {
7
+ status;
8
+ stdout;
9
+ stderr;
10
+ constructor(message, status, stdout, stderr) {
11
+ super(message);
12
+ this.name = 'CommandExecutionError';
13
+ this.status = status;
14
+ this.stdout = stdout;
15
+ this.stderr = stderr;
16
+ }
17
+ }
18
+ /**
19
+ * Determine if shell should be used for command execution on Windows
20
+ *
21
+ * ## Security Context
22
+ *
23
+ * This package's primary security model is `shell: false` to prevent command injection.
24
+ * Windows requires `shell: true` only for shell scripts (.cmd/.bat/.ps1) which require
25
+ * a shell interpreter by design (not executable binaries).
26
+ *
27
+ * ## Node.js on Windows - NO SHELL REQUIRED
28
+ *
29
+ * **Previous behavior (REMOVED):** Used shell:true for 'node' command
30
+ * **Problem discovered:** Node.js DEP0190 deprecation warning - passing args array with
31
+ * shell:true leads to incorrect command execution. Exit codes are ignored (always returns 0).
32
+ *
33
+ * **Testing shows:**
34
+ * - ✅ `shell: false` + absolute path from `which.sync('node')` → Works correctly
35
+ * - ❌ `shell: true` + args array → Exit codes ignored, security warning
36
+ *
37
+ * **Root Cause of Previous ENOENT Issues:** Likely resolved in newer Node.js versions.
38
+ * Current testing (Node 20+) shows shell:false works correctly with absolute path.
39
+ *
40
+ * ## Why This Is Secure
41
+ *
42
+ * 1. **Minimal Shell Usage:** Shell only used for .cmd/.bat/.ps1 files (required)
43
+ * 2. **Path Validation:** Command paths resolved via `which.sync()` before execution
44
+ * 3. **Array-Based Arguments:** Arguments passed as array, preventing injection
45
+ * 4. **Controlled Environment:** Commands from trusted configuration, not user input
46
+ * 5. **No String Interpolation:** Never concatenate user input into command strings
47
+ *
48
+ * ## References
49
+ *
50
+ * - Node.js deprecation: https://nodejs.org/api/deprecations.html#DEP0190
51
+ * - Security tests: `packages/utils/test/safe-exec.test.ts`
52
+ * - Windows fix: PR #94 (fix/windows-shell-independence-v2)
53
+ *
54
+ * @param commandPath - Resolved absolute path to command
55
+ * @returns true if shell should be used, false otherwise
56
+ */
57
+ function shouldUseShell(commandPath) {
58
+ if (process.platform !== 'win32') {
59
+ return false;
60
+ }
61
+ // Node.js deprecation warning (DEP0190): Passing args with shell:true leads to incorrect
62
+ // command execution and security vulnerabilities. Testing shows shell:false works correctly
63
+ // with absolute path from which.sync('node') on Windows.
64
+ // Previous ENOENT issues may have been resolved in newer Node.js versions.
65
+ //
66
+ // REMOVED: if (command === 'node') return true;
67
+ // Reason: shell:true causes exit codes to be ignored (always returns 0)
68
+ // Fix: Use shell:false with absolute path - works correctly
69
+ // Windows shell scripts require shell by design (case-insensitive check)
70
+ const lowerPath = commandPath.toLowerCase();
71
+ return lowerPath.endsWith('.cmd') || lowerPath.endsWith('.bat') || lowerPath.endsWith('.ps1');
72
+ }
73
+ /**
74
+ * Safe command execution using spawnSync + which pattern
75
+ *
76
+ * More secure than execSync:
77
+ * - Resolves PATH once using pure Node.js (which package)
78
+ * - Executes with absolute path and shell: false
79
+ * - No shell interpreter = no command injection risk
80
+ * - Supports custom env vars (e.g., GIT_INDEX_FILE)
81
+ *
82
+ * @param command - Command name (e.g., 'git', 'gitleaks', 'node')
83
+ * @param args - Array of arguments
84
+ * @param options - Execution options
85
+ * @returns Buffer or string output
86
+ * @throws Error if command not found or execution fails
87
+ *
88
+ * @example
89
+ * // Tool detection
90
+ * safeExecSync('gitleaks', ['--version'], { stdio: 'ignore' });
91
+ *
92
+ * @example
93
+ * // Git with custom env
94
+ * safeExecSync('git', ['add', '--all'], {
95
+ * env: { ...process.env, GIT_INDEX_FILE: tempFile }
96
+ * });
97
+ *
98
+ * @example
99
+ * // Get output as string
100
+ * const version = safeExecSync('node', ['--version'], { encoding: 'utf8' });
101
+ */
102
+ export function safeExecSync(command, args = [], options = {}) {
103
+ // Resolve command path using which (pure Node.js, no shell)
104
+ const commandPath = which.sync(command);
105
+ // Determine if shell is needed (Windows-specific logic)
106
+ const useShell = shouldUseShell(commandPath);
107
+ const spawnOptions = {
108
+ shell: useShell, // shell:true on Windows for node and shell scripts, shell:false otherwise for security
109
+ stdio: options.stdio ?? 'pipe',
110
+ env: options.env,
111
+ cwd: options.cwd,
112
+ maxBuffer: options.maxBuffer,
113
+ timeout: options.timeout,
114
+ encoding: options.encoding,
115
+ };
116
+ // Execute with absolute path (or command name if using shell on Windows)
117
+ // When shell:true, use command name so shell can resolve it properly
118
+ const execCommand = useShell ? command : commandPath;
119
+ const result = spawnSync(execCommand, args, spawnOptions);
120
+ // Check for spawn errors
121
+ if (result.error) {
122
+ throw result.error;
123
+ }
124
+ // Check exit code
125
+ if (result.status !== 0) {
126
+ throw new CommandExecutionError(`Command failed with exit code ${result.status ?? 'unknown'}: ${command} ${args.join(' ')}`, result.status ?? -1, result.stdout, result.stderr);
127
+ }
128
+ return result.stdout;
129
+ }
130
+ /**
131
+ * Safe command execution that returns detailed result (doesn't throw)
132
+ *
133
+ * Use this when you need to handle errors programmatically
134
+ * instead of catching exceptions.
135
+ *
136
+ * @param command - Command name (e.g., 'git', 'node')
137
+ * @param args - Array of arguments
138
+ * @param options - Execution options
139
+ * @returns Detailed execution result
140
+ *
141
+ * @example
142
+ * const result = safeExecResult('git', ['status']);
143
+ * if (result.status === 0) {
144
+ * console.log(result.stdout.toString());
145
+ * } else {
146
+ * console.error(`Failed: ${result.stderr.toString()}`);
147
+ * }
148
+ */
149
+ export function safeExecResult(command, args = [], options = {}) {
150
+ try {
151
+ const commandPath = which.sync(command);
152
+ // Determine if shell is needed (Windows-specific logic)
153
+ const useShell = shouldUseShell(commandPath);
154
+ const spawnOptions = {
155
+ shell: useShell,
156
+ stdio: options.stdio ?? 'pipe',
157
+ env: options.env,
158
+ cwd: options.cwd,
159
+ maxBuffer: options.maxBuffer,
160
+ timeout: options.timeout,
161
+ encoding: options.encoding,
162
+ };
163
+ // When shell:true, use command name so shell can resolve it properly
164
+ const execCommand = useShell ? command : commandPath;
165
+ const result = spawnSync(execCommand, args, spawnOptions);
166
+ const execResult = {
167
+ status: result.status ?? -1,
168
+ stdout: result.stdout ?? Buffer.from(''),
169
+ stderr: result.stderr ?? Buffer.from(''),
170
+ };
171
+ // Only include error property if it exists (exactOptionalPropertyTypes compliance)
172
+ if (result.error) {
173
+ execResult.error = result.error;
174
+ }
175
+ return execResult;
176
+ }
177
+ catch (error) {
178
+ // which.sync throws if command not found
179
+ return {
180
+ status: -1,
181
+ stdout: Buffer.from(''),
182
+ stderr: Buffer.from(''),
183
+ error: error instanceof Error ? error : new Error(String(error)),
184
+ };
185
+ }
186
+ }
187
+ /**
188
+ * Check if a command-line tool is available
189
+ *
190
+ * @param toolName - Name of tool to check (e.g., 'gh', 'gitleaks', 'node')
191
+ * @returns true if tool is available, false otherwise
192
+ *
193
+ * @example
194
+ * if (isToolAvailable('gh')) {
195
+ * console.log('GitHub CLI is installed');
196
+ * }
197
+ */
198
+ export function isToolAvailable(toolName) {
199
+ try {
200
+ safeExecSync(toolName, ['--version'], { stdio: 'ignore' });
201
+ return true;
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ }
207
+ /**
208
+ * Get tool version if available
209
+ *
210
+ * @param toolName - Name of tool (e.g., 'node', 'pnpm')
211
+ * @param versionArg - Argument to get version (default: '--version')
212
+ * @returns Version string or null if not available
213
+ *
214
+ * @example
215
+ * const nodeVersion = getToolVersion('node');
216
+ * console.log(nodeVersion); // "v20.11.0"
217
+ *
218
+ * @example
219
+ * const gitVersion = getToolVersion('git', 'version');
220
+ * console.log(gitVersion); // "git version 2.39.2"
221
+ */
222
+ export function getToolVersion(toolName, versionArg = '--version') {
223
+ try {
224
+ const version = safeExecSync(toolName, [versionArg], {
225
+ encoding: 'utf8',
226
+ stdio: 'pipe',
227
+ });
228
+ return version.trim();
229
+ }
230
+ catch {
231
+ return null;
232
+ }
233
+ }
234
+ /**
235
+ * Shell syntax character sets for hyper-efficient single-pass detection
236
+ *
237
+ * Used by hasShellSyntax() and safeExecFromString() for shift-left validation.
238
+ *
239
+ * Performance: O(n) single pass with O(1) Set lookups - no regex backtracking.
240
+ */
241
+ const QUOTE_CHARS = new Set(['"', "'", '`']);
242
+ const GLOB_CHARS = new Set(['*', '?', '[', ']']);
243
+ const OPERATOR_CHARS = new Set(['|', '>', '<', '&', ';']);
244
+ /**
245
+ * Metadata for each shell syntax type (used for error messages)
246
+ */
247
+ const SHELL_SYNTAX_METADATA = {
248
+ quotes: { name: 'quotes', example: 'echo "hello"' },
249
+ globs: { name: 'glob patterns', example: 'ls *.txt' },
250
+ variables: { name: 'variable expansion', example: 'echo $HOME' },
251
+ operators: { name: 'pipes/redirects/operators', example: 'cat file | grep text' },
252
+ };
253
+ /**
254
+ * Check if a command string contains shell-specific syntax
255
+ *
256
+ * Detects patterns that require shell interpretation:
257
+ * - Quotes (", ', `)
258
+ * - Glob patterns (*, ?, [])
259
+ * - Variable expansion ($)
260
+ * - Pipes/redirects/operators (|, >, <, &, ;, &&, ||)
261
+ *
262
+ * Performance: Single-pass O(n) algorithm with O(1) Set lookups.
263
+ * Short-circuits on first match (no backtracking, no regex overhead).
264
+ *
265
+ * @param commandString - Command string to check
266
+ * @returns Object with detection result and details
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * const check1 = hasShellSyntax('npm test');
271
+ * console.log(check1); // { hasShellSyntax: false }
272
+ *
273
+ * const check2 = hasShellSyntax('npm test && npm run build');
274
+ * console.log(check2);
275
+ * // {
276
+ * // hasShellSyntax: true,
277
+ * // pattern: 'pipes/redirects/operators',
278
+ * // example: 'cat file | grep text'
279
+ * // }
280
+ * ```
281
+ */
282
+ export function hasShellSyntax(commandString) {
283
+ // Single-pass check with early return on first match
284
+ for (const char of commandString) {
285
+ // Check quotes: " ' `
286
+ if (QUOTE_CHARS.has(char)) {
287
+ return {
288
+ hasShellSyntax: true,
289
+ pattern: SHELL_SYNTAX_METADATA.quotes.name,
290
+ example: SHELL_SYNTAX_METADATA.quotes.example,
291
+ };
292
+ }
293
+ // Check glob patterns: * ? [ ]
294
+ if (GLOB_CHARS.has(char)) {
295
+ return {
296
+ hasShellSyntax: true,
297
+ pattern: SHELL_SYNTAX_METADATA.globs.name,
298
+ example: SHELL_SYNTAX_METADATA.globs.example,
299
+ };
300
+ }
301
+ // Check variable expansion: $
302
+ if (char === '$') {
303
+ return {
304
+ hasShellSyntax: true,
305
+ pattern: SHELL_SYNTAX_METADATA.variables.name,
306
+ example: SHELL_SYNTAX_METADATA.variables.example,
307
+ };
308
+ }
309
+ // Check operators: | > < & ;
310
+ if (OPERATOR_CHARS.has(char)) {
311
+ return {
312
+ hasShellSyntax: true,
313
+ pattern: SHELL_SYNTAX_METADATA.operators.name,
314
+ example: SHELL_SYNTAX_METADATA.operators.example,
315
+ };
316
+ }
317
+ }
318
+ return { hasShellSyntax: false };
319
+ }
320
+ /**
321
+ * Execute a command from a simple command string (convenience wrapper)
322
+ *
323
+ * **IMPORTANT: Shift-Left Validation** - This function actively rejects shell syntax
324
+ * to prevent subtle bugs where shell features are expected but not executed.
325
+ *
326
+ * **Supported:**
327
+ * - Simple commands: `git status`, `pnpm test`, `node --version`
328
+ * - Commands with flags: `git log --oneline --max-count 10`
329
+ * - Multiple unquoted arguments: `gh pr view 123`
330
+ *
331
+ * **NOT Supported (will throw error):**
332
+ * - Quotes: `echo "hello world"` ❌
333
+ * - Glob patterns: `ls *.txt` ❌
334
+ * - Variable expansion: `echo $HOME` ❌
335
+ * - Pipes/redirects: `cat file | grep text` ❌
336
+ * - Command chaining: `build && test` ❌
337
+ *
338
+ * **Why these restrictions?**
339
+ * We don't use a shell interpreter (for security), so shell features like
340
+ * glob expansion, variable substitution, and pipes don't work. By detecting
341
+ * and rejecting these patterns, we force you to use the safer `safeExecSync()`
342
+ * API with explicit argument arrays.
343
+ *
344
+ * @param commandString - Simple command string (no shell syntax)
345
+ * @param options - Execution options
346
+ * @returns Command output (Buffer or string depending on encoding option)
347
+ * @throws Error if command contains shell-specific syntax
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * // ✅ Simple commands (these work)
352
+ * safeExecFromString('git status');
353
+ * safeExecFromString('pnpm test --watch');
354
+ * safeExecFromString('gh pr view 123');
355
+ * ```
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * // ❌ Shell syntax (these throw errors)
360
+ * safeExecFromString('echo "hello"'); // Quotes
361
+ * safeExecFromString('ls *.txt'); // Glob pattern
362
+ * safeExecFromString('cat file | grep text'); // Pipe
363
+ * safeExecFromString('echo $HOME'); // Variable expansion
364
+ *
365
+ * // ✅ Use safeExecSync() instead with explicit arguments
366
+ * safeExecSync('echo', ['hello']);
367
+ * safeExecSync('ls', ['file1.txt', 'file2.txt']); // Or use glob library
368
+ * safeExecSync('grep', ['text', 'file']);
369
+ * safeExecSync('echo', [process.env.HOME || '']);
370
+ * ```
371
+ *
372
+ */
373
+ export function safeExecFromString(commandString, options = {}) {
374
+ // Detect shell-specific syntax (shift-left validation)
375
+ // This prevents subtle bugs where shell features are expected but not executed
376
+ const check = hasShellSyntax(commandString);
377
+ if (check.hasShellSyntax) {
378
+ throw new Error(`safeExecFromString does not support ${check.pattern}.\n` +
379
+ `Found in: ${commandString}\n\n` +
380
+ `Use safeExecSync() with explicit argument array instead:\n` +
381
+ ` // Bad: safeExecFromString('${check.example}')\n` +
382
+ ` // Good: safeExecSync('command', ['arg1', 'arg2'], options)\n\n` +
383
+ `This ensures no shell interpreter is used and arguments are explicit.`);
384
+ }
385
+ const parts = commandString.trim().split(/\s+/);
386
+ const command = parts[0];
387
+ if (!command) {
388
+ throw new Error('Empty command string');
389
+ }
390
+ const args = parts.slice(1);
391
+ return safeExecSync(command, args, options);
392
+ }
393
+ //# sourceMappingURL=safe-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-exec.js","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@vibe-agent-toolkit/utils",
3
+ "version": "0.1.0-rc.7",
4
+ "type": "module",
5
+ "description": "Core utility functions with no external dependencies",
6
+ "keywords": [
7
+ "typescript",
8
+ "utilities",
9
+ "toolkit"
10
+ ],
11
+ "author": "Jeff Dutton",
12
+ "license": "MIT",
13
+ "main": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "typecheck": "tsc --noEmit",
30
+ "clean": "rimraf dist *.tsbuildinfo"
31
+ },
32
+ "dependencies": {
33
+ "ignore": "^7.0.5",
34
+ "picomatch": "^4.0.3",
35
+ "which": "^5.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/picomatch": "^4.0.2",
39
+ "@types/which": "^3.0.4",
40
+ "rimraf": "^6.0.1",
41
+ "typescript": "^5.9.3",
42
+ "vitest": "^3.2.4"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/jdutton/vibe-agent-toolkit.git"
50
+ }
51
+ }