@vibe-validate/utils 0.17.6-rc.2 → 0.18.0-rc.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/dist/index.d.ts CHANGED
@@ -6,6 +6,6 @@
6
6
  *
7
7
  * @package @vibe-validate/utils
8
8
  */
9
- export { safeExecSync, safeExecFromString, safeExecResult, isToolAvailable, getToolVersion, CommandExecutionError, type SafeExecOptions, type SafeExecResult } from './safe-exec.js';
9
+ export { safeExecSync, safeExecFromString, safeExecResult, isToolAvailable, getToolVersion, hasShellSyntax, CommandExecutionError, type SafeExecOptions, type SafeExecResult } from './safe-exec.js';
10
10
  export { normalizedTmpdir, mkdirSyncReal, normalizePath } from './path-helpers.js';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
  * @package @vibe-validate/utils
8
8
  */
9
9
  // Safe command execution (security-critical)
10
- export { safeExecSync, safeExecFromString, safeExecResult, isToolAvailable, getToolVersion, CommandExecutionError } from './safe-exec.js';
10
+ export { safeExecSync, safeExecFromString, safeExecResult, isToolAvailable, getToolVersion, hasShellSyntax, CommandExecutionError } from './safe-exec.js';
11
11
  // Cross-platform path helpers (Windows 8.3 short name handling)
12
12
  export { normalizedTmpdir, mkdirSyncReal, normalizePath } from './path-helpers.js';
13
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6CAA6C;AAC7C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,qBAAqB,EAGtB,MAAM,gBAAgB,CAAC;AAExB,gEAAgE;AAChE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,6CAA6C;AAC7C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,qBAAqB,EAGtB,MAAM,gBAAgB,CAAC;AAExB,gEAAgE;AAChE,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACd,MAAM,mBAAmB,CAAC"}
@@ -69,17 +69,22 @@ export declare function mkdirSyncReal(path: string, options?: Parameters<typeof
69
69
  * Normalize any path (resolve short names on Windows)
70
70
  *
71
71
  * Utility to normalize paths without creating directories.
72
- * Useful when you have an existing path that might contain short names.
72
+ * Accepts multiple path segments like path.resolve() for convenience.
73
73
  *
74
- * @param path - Path to normalize
75
- * @returns Real (normalized) path, or original if normalization fails
74
+ * @param paths - Path segments to join and normalize
75
+ * @returns Real (normalized) path, or resolved path if normalization fails
76
76
  *
77
77
  * @example
78
78
  * ```typescript
79
+ * // Single path
79
80
  * const shortPath = 'C:\\PROGRA~1\\nodejs';
80
81
  * const longPath = normalizePath(shortPath);
81
82
  * // Result: 'C:\\Program Files\\nodejs'
83
+ *
84
+ * // Multiple segments (like path.resolve)
85
+ * const cliPath = normalizePath(__dirname, '../../dist/bin.js');
86
+ * // Resolves to absolute path AND normalizes short names
82
87
  * ```
83
88
  */
84
- export declare function normalizePath(path: string): string;
89
+ export declare function normalizePath(...paths: string[]): string;
85
90
  //# sourceMappingURL=path-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-helpers.d.ts","sourceRoot":"","sources":["../src/path-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,SAAS,CAAC;AAGlD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAUzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,GACxC,MAAM,CAYR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlD"}
1
+ {"version":3,"file":"path-helpers.d.ts","sourceRoot":"","sources":["../src/path-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAgB,MAAM,SAAS,CAAC;AAKlD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,GACxC,MAAM,CAiBR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAmBxD"}
@@ -36,13 +36,19 @@ import { tmpdir } from 'node:os';
36
36
  export function normalizedTmpdir() {
37
37
  const temp = tmpdir();
38
38
  try {
39
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: temp is from tmpdir() (OS-provided system temp directory), not user input
40
- return realpathSync(temp);
39
+ // Use native OS realpath for better Windows compatibility
40
+ return realpathSync.native(temp);
41
41
  }
42
42
  catch {
43
- // Fallback: if realpathSync fails, return original
44
- // (shouldn't happen, but safety first)
45
- return temp;
43
+ // Fallback to regular realpathSync
44
+ try {
45
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: temp is from tmpdir()
46
+ return realpathSync(temp);
47
+ }
48
+ catch {
49
+ // Last resort: return original
50
+ return temp;
51
+ }
46
52
  }
47
53
  }
48
54
  /**
@@ -77,41 +83,64 @@ export function normalizedTmpdir() {
77
83
  * ```
78
84
  */
79
85
  export function mkdirSyncReal(path, options) {
80
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: path is function parameter from test setup (tmpdir + test name), not user input
86
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- This IS the mkdirSyncReal() implementation
81
87
  mkdirSync(path, options);
82
88
  try {
83
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: path is function parameter from test setup (tmpdir + test name), not user input
84
- return realpathSync(path);
89
+ // Use native OS realpath for better Windows compatibility
90
+ return realpathSync.native(path);
85
91
  }
86
92
  catch {
87
- // Fallback: if realpathSync fails, return original
88
- // (might happen if directory creation failed)
89
- return path;
93
+ // Fallback to regular realpathSync
94
+ try {
95
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: path is function parameter
96
+ return realpathSync(path);
97
+ }
98
+ catch {
99
+ // Last resort: return original
100
+ return path;
101
+ }
90
102
  }
91
103
  }
92
104
  /**
93
105
  * Normalize any path (resolve short names on Windows)
94
106
  *
95
107
  * Utility to normalize paths without creating directories.
96
- * Useful when you have an existing path that might contain short names.
108
+ * Accepts multiple path segments like path.resolve() for convenience.
97
109
  *
98
- * @param path - Path to normalize
99
- * @returns Real (normalized) path, or original if normalization fails
110
+ * @param paths - Path segments to join and normalize
111
+ * @returns Real (normalized) path, or resolved path if normalization fails
100
112
  *
101
113
  * @example
102
114
  * ```typescript
115
+ * // Single path
103
116
  * const shortPath = 'C:\\PROGRA~1\\nodejs';
104
117
  * const longPath = normalizePath(shortPath);
105
118
  * // Result: 'C:\\Program Files\\nodejs'
119
+ *
120
+ * // Multiple segments (like path.resolve)
121
+ * const cliPath = normalizePath(__dirname, '../../dist/bin.js');
122
+ * // Resolves to absolute path AND normalizes short names
106
123
  * ```
107
124
  */
108
- export function normalizePath(path) {
125
+ export function normalizePath(...paths) {
126
+ // First resolve to absolute path (handles multiple segments)
127
+ const resolved = paths.length === 1
128
+ ? paths[0]
129
+ : require('node:path').resolve(...paths);
109
130
  try {
110
- // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: path is function parameter from test setup (tmpdir + test name), not user input
111
- return realpathSync(path);
131
+ // Use native OS realpath for better Windows compatibility
132
+ return realpathSync.native(resolved);
112
133
  }
113
134
  catch {
114
- return path;
135
+ // Fallback to regular realpathSync
136
+ try {
137
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- Safe: resolved is from path.resolve
138
+ return realpathSync(resolved);
139
+ }
140
+ catch {
141
+ // Last resort: return resolved path (better than original input)
142
+ return resolved;
143
+ }
115
144
  }
116
145
  }
117
146
  //# sourceMappingURL=path-helpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-helpers.js","sourceRoot":"","sources":["../src/path-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,sJAAsJ;QACtJ,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;QACnD,uCAAuC;QACvC,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,OAAyC;IAEzC,4JAA4J;IAC5J,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEzB,IAAI,CAAC;QACH,4JAA4J;QAC5J,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;QACnD,8CAA8C;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,IAAI,CAAC;QACH,4JAA4J;QAC5J,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"path-helpers.js","sourceRoot":"","sources":["../src/path-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAIjC;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,gBAAgB;IAE9B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,0DAA0D;QAC1D,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,IAAI,CAAC;YACH,kGAAkG;YAClG,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,OAAyC;IAEzC,iHAAiH;IACjH,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEzB,IAAI,CAAC;QACH,0DAA0D;QAC1D,OAAO,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,IAAI,CAAC;YACH,uGAAuG;YACvG,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;YAC/B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,aAAa,CAAC,GAAG,KAAe;IAC9C,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC;QACjC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACV,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IAE3C,IAAI,CAAC;QACH,0DAA0D;QAC1D,OAAO,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;QACnC,IAAI,CAAC;YACH,0GAA0G;YAC1G,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,iEAAiE;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -116,38 +116,91 @@ export declare function isToolAvailable(toolName: string): boolean;
116
116
  */
117
117
  export declare function getToolVersion(toolName: string, versionArg?: string): string | null;
118
118
  /**
119
- * Execute a command from a command string (convenience wrapper)
119
+ * Check if a command string contains shell-specific syntax
120
120
  *
121
- * **WARNING**: This function parses command strings using simple whitespace splitting.
122
- * It does NOT handle shell quoting, escaping, or complex command syntax.
123
- * Use only for simple commands like "gitleaks protect --staged --verbose".
121
+ * Detects patterns that require shell interpretation:
122
+ * - Quotes (", ', `)
123
+ * - Glob patterns (*, ?, [])
124
+ * - Variable expansion ($)
125
+ * - Pipes/redirects/operators (|, >, <, &, ;, &&, ||)
124
126
  *
125
- * For complex commands with quoted arguments, pipes, or shell features,
126
- * use `safeExecSync()` directly with an explicit args array.
127
+ * Performance: Single-pass O(n) algorithm with O(1) Set lookups.
128
+ * Short-circuits on first match (no backtracking, no regex overhead).
127
129
  *
128
- * @param commandString - Command string to execute (e.g., "git status --short")
130
+ * @param commandString - Command string to check
131
+ * @returns Object with detection result and details
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const check1 = hasShellSyntax('npm test');
136
+ * console.log(check1); // { hasShellSyntax: false }
137
+ *
138
+ * const check2 = hasShellSyntax('npm test && npm run build');
139
+ * console.log(check2);
140
+ * // {
141
+ * // hasShellSyntax: true,
142
+ * // pattern: 'pipes/redirects/operators',
143
+ * // example: 'cat file | grep text'
144
+ * // }
145
+ * ```
146
+ */
147
+ export declare function hasShellSyntax(commandString: string): {
148
+ hasShellSyntax: boolean;
149
+ pattern?: string;
150
+ example?: string;
151
+ };
152
+ /**
153
+ * Execute a command from a simple command string (convenience wrapper)
154
+ *
155
+ * **IMPORTANT: Shift-Left Validation** - This function actively rejects shell syntax
156
+ * to prevent subtle bugs where shell features are expected but not executed.
157
+ *
158
+ * **Supported:**
159
+ * - Simple commands: `git status`, `pnpm test`, `node --version`
160
+ * - Commands with flags: `git log --oneline --max-count 10`
161
+ * - Multiple unquoted arguments: `gh pr view 123`
162
+ *
163
+ * **NOT Supported (will throw error):**
164
+ * - Quotes: `echo "hello world"` ❌
165
+ * - Glob patterns: `ls *.txt` ❌
166
+ * - Variable expansion: `echo $HOME` ❌
167
+ * - Pipes/redirects: `cat file | grep text` ❌
168
+ * - Command chaining: `build && test` ❌
169
+ *
170
+ * **Why these restrictions?**
171
+ * We don't use a shell interpreter (for security), so shell features like
172
+ * glob expansion, variable substitution, and pipes don't work. By detecting
173
+ * and rejecting these patterns, we force you to use the safer `safeExecSync()`
174
+ * API with explicit argument arrays.
175
+ *
176
+ * @param commandString - Simple command string (no shell syntax)
129
177
  * @param options - Execution options
130
178
  * @returns Command output (Buffer or string depending on encoding option)
179
+ * @throws Error if command contains shell-specific syntax
131
180
  *
132
181
  * @example
133
182
  * ```typescript
134
- * // Simple command with flags
135
- * safeExecFromString('gitleaks protect --staged --verbose');
136
- *
137
- * // Multiple arguments
138
- * safeExecFromString('gh pr view --json number,title');
183
+ * // Simple commands (these work)
184
+ * safeExecFromString('git status');
185
+ * safeExecFromString('pnpm test --watch');
186
+ * safeExecFromString('gh pr view 123');
139
187
  * ```
140
188
  *
141
189
  * @example
142
190
  * ```typescript
143
- * // ❌ DON'T: Complex shell features won't work
144
- * safeExecFromString('cat file.txt | grep "error"'); // Pipe ignored
145
- * safeExecFromString('echo "hello world"'); // Quotes not parsed correctly
146
- *
147
- * // DO: Use safeExecSync directly for these cases
148
- * safeExecSync('grep', ['error', 'file.txt']);
149
- * safeExecSync('echo', ['hello world']);
191
+ * // ❌ Shell syntax (these throw errors)
192
+ * safeExecFromString('echo "hello"'); // Quotes
193
+ * safeExecFromString('ls *.txt'); // Glob pattern
194
+ * safeExecFromString('cat file | grep text'); // Pipe
195
+ * safeExecFromString('echo $HOME'); // Variable expansion
196
+ *
197
+ * // ✅ Use safeExecSync() instead with explicit arguments
198
+ * safeExecSync('echo', ['hello']);
199
+ * safeExecSync('ls', ['file1.txt', 'file2.txt']); // Or use glob library
200
+ * safeExecSync('grep', ['text', 'file']);
201
+ * safeExecSync('echo', [process.env.HOME || '']);
150
202
  * ```
203
+ *
151
204
  */
152
205
  export declare function safeExecFromString(commandString: string, options?: SafeExecOptions): Buffer | string;
153
206
  //# sourceMappingURL=safe-exec.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-exec.d.ts","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IACjE,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,qBAAqB;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;gBAGtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,MAAM,EAAE,MAAM,GAAG,MAAM;CAQ1B;AAwED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAsCjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAoChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAoB,GAC/B,MAAM,GAAG,IAAI,CAUf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAMjB"}
1
+ {"version":3,"file":"safe-exec.d.ts","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IACjE,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,qBAAqB;IACrB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxC,SAAgB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;gBAGtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,MAAM,EAAE,MAAM,GAAG,MAAM;CAQ1B;AAwED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAsCjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,eAAoB,GAC5B,cAAc,CAoChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAOzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,MAAoB,GAC/B,MAAM,GAAG,IAAI,CAUf;AAuBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG;IACrD,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CA0CA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,eAAoB,GAC5B,MAAM,GAAG,MAAM,CAoBjB"}
package/dist/safe-exec.js CHANGED
@@ -240,40 +240,156 @@ export function getToolVersion(toolName, versionArg = '--version') {
240
240
  }
241
241
  }
242
242
  /**
243
- * Execute a command from a command string (convenience wrapper)
243
+ * Shell syntax character sets for hyper-efficient single-pass detection
244
244
  *
245
- * **WARNING**: This function parses command strings using simple whitespace splitting.
246
- * It does NOT handle shell quoting, escaping, or complex command syntax.
247
- * Use only for simple commands like "gitleaks protect --staged --verbose".
245
+ * Used by hasShellSyntax() and safeExecFromString() for shift-left validation.
248
246
  *
249
- * For complex commands with quoted arguments, pipes, or shell features,
250
- * use `safeExecSync()` directly with an explicit args array.
247
+ * Performance: O(n) single pass with O(1) Set lookups - no regex backtracking.
248
+ */
249
+ const QUOTE_CHARS = new Set(['"', "'", '`']);
250
+ const GLOB_CHARS = new Set(['*', '?', '[', ']']);
251
+ const OPERATOR_CHARS = new Set(['|', '>', '<', '&', ';']);
252
+ /**
253
+ * Metadata for each shell syntax type (used for error messages)
254
+ */
255
+ const SHELL_SYNTAX_METADATA = {
256
+ quotes: { name: 'quotes', example: 'echo "hello"' },
257
+ globs: { name: 'glob patterns', example: 'ls *.txt' },
258
+ variables: { name: 'variable expansion', example: 'echo $HOME' },
259
+ operators: { name: 'pipes/redirects/operators', example: 'cat file | grep text' },
260
+ };
261
+ /**
262
+ * Check if a command string contains shell-specific syntax
263
+ *
264
+ * Detects patterns that require shell interpretation:
265
+ * - Quotes (", ', `)
266
+ * - Glob patterns (*, ?, [])
267
+ * - Variable expansion ($)
268
+ * - Pipes/redirects/operators (|, >, <, &, ;, &&, ||)
251
269
  *
252
- * @param commandString - Command string to execute (e.g., "git status --short")
270
+ * Performance: Single-pass O(n) algorithm with O(1) Set lookups.
271
+ * Short-circuits on first match (no backtracking, no regex overhead).
272
+ *
273
+ * @param commandString - Command string to check
274
+ * @returns Object with detection result and details
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * const check1 = hasShellSyntax('npm test');
279
+ * console.log(check1); // { hasShellSyntax: false }
280
+ *
281
+ * const check2 = hasShellSyntax('npm test && npm run build');
282
+ * console.log(check2);
283
+ * // {
284
+ * // hasShellSyntax: true,
285
+ * // pattern: 'pipes/redirects/operators',
286
+ * // example: 'cat file | grep text'
287
+ * // }
288
+ * ```
289
+ */
290
+ export function hasShellSyntax(commandString) {
291
+ // Single-pass check with early return on first match
292
+ for (const char of commandString) {
293
+ // Check quotes: " ' `
294
+ if (QUOTE_CHARS.has(char)) {
295
+ return {
296
+ hasShellSyntax: true,
297
+ pattern: SHELL_SYNTAX_METADATA.quotes.name,
298
+ example: SHELL_SYNTAX_METADATA.quotes.example,
299
+ };
300
+ }
301
+ // Check glob patterns: * ? [ ]
302
+ if (GLOB_CHARS.has(char)) {
303
+ return {
304
+ hasShellSyntax: true,
305
+ pattern: SHELL_SYNTAX_METADATA.globs.name,
306
+ example: SHELL_SYNTAX_METADATA.globs.example,
307
+ };
308
+ }
309
+ // Check variable expansion: $
310
+ if (char === '$') {
311
+ return {
312
+ hasShellSyntax: true,
313
+ pattern: SHELL_SYNTAX_METADATA.variables.name,
314
+ example: SHELL_SYNTAX_METADATA.variables.example,
315
+ };
316
+ }
317
+ // Check operators: | > < & ;
318
+ if (OPERATOR_CHARS.has(char)) {
319
+ return {
320
+ hasShellSyntax: true,
321
+ pattern: SHELL_SYNTAX_METADATA.operators.name,
322
+ example: SHELL_SYNTAX_METADATA.operators.example,
323
+ };
324
+ }
325
+ }
326
+ return { hasShellSyntax: false };
327
+ }
328
+ /**
329
+ * Execute a command from a simple command string (convenience wrapper)
330
+ *
331
+ * **IMPORTANT: Shift-Left Validation** - This function actively rejects shell syntax
332
+ * to prevent subtle bugs where shell features are expected but not executed.
333
+ *
334
+ * **Supported:**
335
+ * - Simple commands: `git status`, `pnpm test`, `node --version`
336
+ * - Commands with flags: `git log --oneline --max-count 10`
337
+ * - Multiple unquoted arguments: `gh pr view 123`
338
+ *
339
+ * **NOT Supported (will throw error):**
340
+ * - Quotes: `echo "hello world"` ❌
341
+ * - Glob patterns: `ls *.txt` ❌
342
+ * - Variable expansion: `echo $HOME` ❌
343
+ * - Pipes/redirects: `cat file | grep text` ❌
344
+ * - Command chaining: `build && test` ❌
345
+ *
346
+ * **Why these restrictions?**
347
+ * We don't use a shell interpreter (for security), so shell features like
348
+ * glob expansion, variable substitution, and pipes don't work. By detecting
349
+ * and rejecting these patterns, we force you to use the safer `safeExecSync()`
350
+ * API with explicit argument arrays.
351
+ *
352
+ * @param commandString - Simple command string (no shell syntax)
253
353
  * @param options - Execution options
254
354
  * @returns Command output (Buffer or string depending on encoding option)
355
+ * @throws Error if command contains shell-specific syntax
255
356
  *
256
357
  * @example
257
358
  * ```typescript
258
- * // Simple command with flags
259
- * safeExecFromString('gitleaks protect --staged --verbose');
260
- *
261
- * // Multiple arguments
262
- * safeExecFromString('gh pr view --json number,title');
359
+ * // Simple commands (these work)
360
+ * safeExecFromString('git status');
361
+ * safeExecFromString('pnpm test --watch');
362
+ * safeExecFromString('gh pr view 123');
263
363
  * ```
264
364
  *
265
365
  * @example
266
366
  * ```typescript
267
- * // ❌ DON'T: Complex shell features won't work
268
- * safeExecFromString('cat file.txt | grep "error"'); // Pipe ignored
269
- * safeExecFromString('echo "hello world"'); // Quotes not parsed correctly
270
- *
271
- * // DO: Use safeExecSync directly for these cases
272
- * safeExecSync('grep', ['error', 'file.txt']);
273
- * safeExecSync('echo', ['hello world']);
367
+ * // ❌ Shell syntax (these throw errors)
368
+ * safeExecFromString('echo "hello"'); // Quotes
369
+ * safeExecFromString('ls *.txt'); // Glob pattern
370
+ * safeExecFromString('cat file | grep text'); // Pipe
371
+ * safeExecFromString('echo $HOME'); // Variable expansion
372
+ *
373
+ * // ✅ Use safeExecSync() instead with explicit arguments
374
+ * safeExecSync('echo', ['hello']);
375
+ * safeExecSync('ls', ['file1.txt', 'file2.txt']); // Or use glob library
376
+ * safeExecSync('grep', ['text', 'file']);
377
+ * safeExecSync('echo', [process.env.HOME || '']);
274
378
  * ```
379
+ *
275
380
  */
276
381
  export function safeExecFromString(commandString, options = {}) {
382
+ // Detect shell-specific syntax (shift-left validation)
383
+ // This prevents subtle bugs where shell features are expected but not executed
384
+ const check = hasShellSyntax(commandString);
385
+ if (check.hasShellSyntax) {
386
+ throw new Error(`safeExecFromString does not support ${check.pattern}.\n` +
387
+ `Found in: ${commandString}\n\n` +
388
+ `Use safeExecSync() with explicit argument array instead:\n` +
389
+ ` // Bad: safeExecFromString('${check.example}')\n` +
390
+ ` // Good: safeExecSync('command', ['arg1', 'arg2'], options)\n\n` +
391
+ `This ensures no shell interpreter is used and arguments are explicit.`);
392
+ }
277
393
  const parts = commandString.trim().split(/\s+/);
278
394
  const command = parts[0];
279
395
  const args = parts.slice(1);
@@ -1 +1 @@
1
- {"version":3,"file":"safe-exec.js","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"safe-exec.js","sourceRoot":"","sources":["../src/safe-exec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-validate/utils",
3
- "version": "0.17.6-rc.2",
3
+ "version": "0.18.0-rc.1",
4
4
  "description": "Common utilities for vibe-validate packages (command execution, path normalization)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",