shell-dsl 0.0.11 → 0.0.13

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "type": "commonjs"
5
5
  }
@@ -173,6 +173,7 @@ var find = async (ctx) => {
173
173
  }
174
174
  let hasError = false;
175
175
  for (const startPath of paths) {
176
+ const normalizedPath = startPath === "/" ? "/" : startPath.replace(/\/+$/, "");
176
177
  const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);
177
178
  let stat;
178
179
  try {
@@ -238,14 +239,14 @@ var find = async (ctx) => {
238
239
  matches = false;
239
240
  }
240
241
  if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {
241
- await ctx.stdout.writeText(startPath + `
242
+ await ctx.stdout.writeText(normalizedPath + `
242
243
  `);
243
244
  }
244
245
  } else {
245
- await traverse(resolvedStart, startPath, 0);
246
+ await traverse(resolvedStart, normalizedPath, 0);
246
247
  }
247
248
  }
248
249
  return hasError ? 1 : 0;
249
250
  };
250
251
 
251
- //# debugId=07DE90BFF224BE6064756E2164756E21
252
+ //# debugId=079983875D7F5C7264756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/find/find.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.cjs\";\n\n/**\n * Simple glob pattern matching (fnmatch-style)\n * Supports: * (any chars), ? (single char), [...] (character class)\n */\nfunction matchGlob(pattern: string, str: string, caseInsensitive = false): boolean {\n if (caseInsensitive) {\n pattern = pattern.toLowerCase();\n str = str.toLowerCase();\n }\n\n // Convert glob to regex\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i]!;\n switch (c) {\n case \"*\":\n regex += \".*\";\n break;\n case \"?\":\n regex += \".\";\n break;\n case \"[\": {\n // Find closing bracket\n let j = i + 1;\n // Handle negation\n if (pattern[j] === \"!\" || pattern[j] === \"^\") j++;\n // Handle ] as first char in class\n if (pattern[j] === \"]\") j++;\n while (j < pattern.length && pattern[j] !== \"]\") j++;\n if (j >= pattern.length) {\n // No closing bracket, treat [ as literal\n regex += \"\\\\[\";\n } else {\n let charClass = pattern.slice(i, j + 1);\n // Convert ! to ^ for negation in regex\n charClass = charClass.replace(/^\\[!/, \"[^\");\n regex += charClass;\n i = j;\n }\n break;\n }\n case \".\":\n case \"^\":\n case \"$\":\n case \"+\":\n case \"{\":\n case \"}\":\n case \"(\":\n case \")\":\n case \"|\":\n case \"\\\\\":\n regex += \"\\\\\" + c;\n break;\n default:\n regex += c;\n }\n }\n regex += \"$\";\n\n try {\n return new RegExp(regex).test(str);\n } catch {\n return false;\n }\n}\n\ninterface FindOptions {\n namePattern?: string;\n nameIgnoreCase?: boolean;\n type?: \"f\" | \"d\";\n maxDepth?: number;\n minDepth?: number;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n const options: FindOptions = {};\n\n // Parse arguments: paths come before first flag, then expressions\n let i = 0;\n\n // Collect paths (args before first -)\n while (i < args.length && !args[i]!.startsWith(\"-\")) {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Parse expression flags\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"-name\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-name'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = false;\n } else if (arg === \"-iname\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-iname'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = true;\n } else if (arg === \"-type\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-type'\\n\");\n return 1;\n }\n const typeArg = args[i]!;\n if (typeArg !== \"f\" && typeArg !== \"d\") {\n await ctx.stderr.writeText(`find: Unknown argument to -type: ${typeArg}\\n`);\n return 1;\n }\n options.type = typeArg;\n } else if (arg === \"-maxdepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -maxdepth\\n`);\n return 1;\n }\n options.maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -mindepth\\n`);\n return 1;\n }\n options.minDepth = depth;\n } else if (arg.startsWith(\"-\")) {\n await ctx.stderr.writeText(`find: unknown predicate '${arg}'\\n`);\n return 1;\n } else {\n // This shouldn't happen since paths are parsed first, but treat as path\n paths.push(arg);\n }\n\n i++;\n }\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n\n // Check if this entry matches filters\n let matches = true;\n\n // Type filter\n if (options.type === \"f\" && !isFile) {\n matches = false;\n } else if (options.type === \"d\" && !isDir) {\n matches = false;\n }\n\n // Name filter (only check basename)\n if (matches && options.namePattern !== undefined) {\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n // Output if matches and above mindepth\n if (matches && (options.minDepth === undefined || depth >= options.minDepth)) {\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n // For a single file, it's at depth 0\n // For a directory, the directory itself is depth 0, contents are depth 1+\n if (stat.isFile()) {\n // Starting from a file - depth 0\n let matches = true;\n\n if (options.type === \"d\") {\n matches = false;\n }\n\n if (matches && options.namePattern !== undefined) {\n const basename = ctx.fs.basename(resolvedStart);\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n if (options.maxDepth !== undefined && options.maxDepth < 0) {\n matches = false;\n }\n\n if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {\n await ctx.stdout.writeText(startPath + \"\\n\");\n }\n } else {\n await traverse(resolvedStart, startPath, 0);\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
5
+ "import type { Command } from \"../../types.cjs\";\n\n/**\n * Simple glob pattern matching (fnmatch-style)\n * Supports: * (any chars), ? (single char), [...] (character class)\n */\nfunction matchGlob(pattern: string, str: string, caseInsensitive = false): boolean {\n if (caseInsensitive) {\n pattern = pattern.toLowerCase();\n str = str.toLowerCase();\n }\n\n // Convert glob to regex\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i]!;\n switch (c) {\n case \"*\":\n regex += \".*\";\n break;\n case \"?\":\n regex += \".\";\n break;\n case \"[\": {\n // Find closing bracket\n let j = i + 1;\n // Handle negation\n if (pattern[j] === \"!\" || pattern[j] === \"^\") j++;\n // Handle ] as first char in class\n if (pattern[j] === \"]\") j++;\n while (j < pattern.length && pattern[j] !== \"]\") j++;\n if (j >= pattern.length) {\n // No closing bracket, treat [ as literal\n regex += \"\\\\[\";\n } else {\n let charClass = pattern.slice(i, j + 1);\n // Convert ! to ^ for negation in regex\n charClass = charClass.replace(/^\\[!/, \"[^\");\n regex += charClass;\n i = j;\n }\n break;\n }\n case \".\":\n case \"^\":\n case \"$\":\n case \"+\":\n case \"{\":\n case \"}\":\n case \"(\":\n case \")\":\n case \"|\":\n case \"\\\\\":\n regex += \"\\\\\" + c;\n break;\n default:\n regex += c;\n }\n }\n regex += \"$\";\n\n try {\n return new RegExp(regex).test(str);\n } catch {\n return false;\n }\n}\n\ninterface FindOptions {\n namePattern?: string;\n nameIgnoreCase?: boolean;\n type?: \"f\" | \"d\";\n maxDepth?: number;\n minDepth?: number;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n const options: FindOptions = {};\n\n // Parse arguments: paths come before first flag, then expressions\n let i = 0;\n\n // Collect paths (args before first -)\n while (i < args.length && !args[i]!.startsWith(\"-\")) {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Parse expression flags\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"-name\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-name'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = false;\n } else if (arg === \"-iname\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-iname'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = true;\n } else if (arg === \"-type\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-type'\\n\");\n return 1;\n }\n const typeArg = args[i]!;\n if (typeArg !== \"f\" && typeArg !== \"d\") {\n await ctx.stderr.writeText(`find: Unknown argument to -type: ${typeArg}\\n`);\n return 1;\n }\n options.type = typeArg;\n } else if (arg === \"-maxdepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -maxdepth\\n`);\n return 1;\n }\n options.maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -mindepth\\n`);\n return 1;\n }\n options.minDepth = depth;\n } else if (arg.startsWith(\"-\")) {\n await ctx.stderr.writeText(`find: unknown predicate '${arg}'\\n`);\n return 1;\n } else {\n // This shouldn't happen since paths are parsed first, but treat as path\n paths.push(arg);\n }\n\n i++;\n }\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const normalizedPath = startPath === \"/\" ? \"/\" : startPath.replace(/\\/+$/, '');\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n\n // Check if this entry matches filters\n let matches = true;\n\n // Type filter\n if (options.type === \"f\" && !isFile) {\n matches = false;\n } else if (options.type === \"d\" && !isDir) {\n matches = false;\n }\n\n // Name filter (only check basename)\n if (matches && options.namePattern !== undefined) {\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n // Output if matches and above mindepth\n if (matches && (options.minDepth === undefined || depth >= options.minDepth)) {\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n // For a single file, it's at depth 0\n // For a directory, the directory itself is depth 0, contents are depth 1+\n if (stat.isFile()) {\n // Starting from a file - depth 0\n let matches = true;\n\n if (options.type === \"d\") {\n matches = false;\n }\n\n if (matches && options.namePattern !== undefined) {\n const basename = ctx.fs.basename(resolvedStart);\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n if (options.maxDepth !== undefined && options.maxDepth < 0) {\n matches = false;\n }\n\n if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {\n await ctx.stdout.writeText(normalizedPath + \"\\n\");\n }\n } else {\n await traverse(resolvedStart, normalizedPath, 0);\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "07DE90BFF224BE6064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "079983875D7F5C7264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -187,6 +187,8 @@ function buildMatcher(options) {
187
187
  let patterns = options.patterns;
188
188
  if (options.fixedStrings) {
189
189
  patterns = patterns.map(escapeRegex);
190
+ } else {
191
+ patterns = patterns.map((p) => p.replace(/\\\|/g, "|").replace(/\\\(/g, "(").replace(/\\\)/g, ")"));
190
192
  }
191
193
  let combined = patterns.length > 1 ? patterns.map((p) => `(?:${p})`).join("|") : patterns[0] || "";
192
194
  if (options.wholeWord) {
@@ -534,4 +536,4 @@ var grep = async (ctx) => {
534
536
  return globalFound ? 0 : 1;
535
537
  };
536
538
 
537
- //# debugId=E1E2499749A3C23A64756E2164756E21
539
+ //# debugId=549D8A8ACE2FBD1464756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/grep/grep.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition, type FlagError } from \"../../utils/flag-parser.cjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n include: string[]; // --include\n exclude: string[]; // --exclude\n}\n\nconst spec = {\n name: \"grep\",\n flags: [\n { short: \"E\", long: \"extended-regexp\" },\n { short: \"F\", long: \"fixed-strings\" },\n { short: \"i\", long: \"ignore-case\" },\n { short: \"w\", long: \"word-regexp\" },\n { short: \"x\", long: \"line-regexp\" },\n { short: \"v\", long: \"invert-match\" },\n { short: \"c\", long: \"count\" },\n { short: \"l\", long: \"files-with-matches\" },\n { short: \"L\", long: \"files-without-match\" },\n { short: \"n\", long: \"line-number\" },\n { short: \"o\", long: \"only-matching\" },\n { short: \"q\", long: \"quiet\" },\n { short: \"H\", long: \"with-filename\" },\n { short: \"h\", long: \"no-filename\" },\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"e\", long: \"regexp\", takesValue: true },\n { short: \"m\", long: \"max-count\", takesValue: true },\n { short: \"A\", long: \"after-context\", takesValue: true },\n { short: \"B\", long: \"before-context\", takesValue: true },\n { short: \"C\", long: \"context\", takesValue: true },\n { long: \"include\", takesValue: true },\n { long: \"exclude\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]\",\n};\n\nfunction createDefaults(): GrepOptions {\n return {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n include: [],\n exclude: [],\n };\n}\n\nconst handler = (flags: GrepOptions, flag: FlagDefinition, value?: string) => {\n switch (flag.short) {\n case \"E\": flags.extendedRegex = true; break;\n case \"F\": flags.fixedStrings = true; break;\n case \"i\": flags.ignoreCase = true; break;\n case \"w\": flags.wholeWord = true; break;\n case \"x\": flags.wholeLine = true; break;\n case \"v\": flags.invert = true; break;\n case \"c\": flags.countOnly = true; break;\n case \"l\": flags.filesWithMatches = true; break;\n case \"L\": flags.filesWithoutMatches = true; break;\n case \"n\": flags.showLineNumbers = true; break;\n case \"o\": flags.onlyMatching = true; break;\n case \"q\": flags.quiet = true; break;\n case \"H\": flags.showFilename = true; break;\n case \"h\": flags.showFilename = false; break;\n case \"r\":\n case \"R\": flags.recursive = true; break;\n case \"e\": if (value) flags.patterns.push(value); break;\n case \"m\": if (value) flags.maxMatches = parseInt(value, 10); break;\n case \"A\": if (value) flags.afterContext = parseInt(value, 10); break;\n case \"B\": if (value) flags.beforeContext = parseInt(value, 10); break;\n case \"C\":\n if (value) {\n const num = parseInt(value, 10);\n flags.beforeContext = num;\n flags.afterContext = num;\n }\n break;\n default:\n // Handle long-only flags\n if (flag.long === \"include\" && value) flags.include.push(value);\n else if (flag.long === \"exclude\" && value) flags.exclude.push(value);\n break;\n }\n};\n\nfunction matchGlob(str: string, pattern: string): boolean {\n // Convert shell glob to regex: * -> .*, ? -> ., rest escaped\n let re = \"^\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \".*\";\n else if (ch === \"?\") re += \".\";\n else if (/[.+^${}()|[\\]\\\\]/.test(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n re += \"$\";\n return new RegExp(re).test(str);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\nexport const grep: Command = async (ctx) => {\n // Create fresh parser with fresh defaults for each invocation\n const parser = createFlagParser(spec, createDefaults(), handler);\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const options = result.flags;\n const args = result.args;\n\n // First positional arg is pattern if no -e patterns\n let files: string[];\n if (options.patterns.length === 0) {\n if (args.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n options.patterns.push(args[0]!);\n files = args.slice(1);\n } else {\n files = args;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Filter by include/exclude patterns\n if (options.include.length > 0 || options.exclude.length > 0) {\n expandedFiles = expandedFiles.filter((f) => {\n const basename = ctx.fs.basename(f);\n if (options.include.length > 0) {\n const included = options.include.some((pat) => matchGlob(basename, pat));\n if (!included) return false;\n }\n if (options.exclude.length > 0) {\n const excluded = options.exclude.some((pat) => matchGlob(basename, pat));\n if (excluded) return false;\n }\n return true;\n });\n }\n\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
5
+ "import type { Command } from \"../../types.cjs\";\nimport { createFlagParser, type FlagDefinition, type FlagError } from \"../../utils/flag-parser.cjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n include: string[]; // --include\n exclude: string[]; // --exclude\n}\n\nconst spec = {\n name: \"grep\",\n flags: [\n { short: \"E\", long: \"extended-regexp\" },\n { short: \"F\", long: \"fixed-strings\" },\n { short: \"i\", long: \"ignore-case\" },\n { short: \"w\", long: \"word-regexp\" },\n { short: \"x\", long: \"line-regexp\" },\n { short: \"v\", long: \"invert-match\" },\n { short: \"c\", long: \"count\" },\n { short: \"l\", long: \"files-with-matches\" },\n { short: \"L\", long: \"files-without-match\" },\n { short: \"n\", long: \"line-number\" },\n { short: \"o\", long: \"only-matching\" },\n { short: \"q\", long: \"quiet\" },\n { short: \"H\", long: \"with-filename\" },\n { short: \"h\", long: \"no-filename\" },\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"e\", long: \"regexp\", takesValue: true },\n { short: \"m\", long: \"max-count\", takesValue: true },\n { short: \"A\", long: \"after-context\", takesValue: true },\n { short: \"B\", long: \"before-context\", takesValue: true },\n { short: \"C\", long: \"context\", takesValue: true },\n { long: \"include\", takesValue: true },\n { long: \"exclude\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]\",\n};\n\nfunction createDefaults(): GrepOptions {\n return {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n include: [],\n exclude: [],\n };\n}\n\nconst handler = (flags: GrepOptions, flag: FlagDefinition, value?: string) => {\n switch (flag.short) {\n case \"E\": flags.extendedRegex = true; break;\n case \"F\": flags.fixedStrings = true; break;\n case \"i\": flags.ignoreCase = true; break;\n case \"w\": flags.wholeWord = true; break;\n case \"x\": flags.wholeLine = true; break;\n case \"v\": flags.invert = true; break;\n case \"c\": flags.countOnly = true; break;\n case \"l\": flags.filesWithMatches = true; break;\n case \"L\": flags.filesWithoutMatches = true; break;\n case \"n\": flags.showLineNumbers = true; break;\n case \"o\": flags.onlyMatching = true; break;\n case \"q\": flags.quiet = true; break;\n case \"H\": flags.showFilename = true; break;\n case \"h\": flags.showFilename = false; break;\n case \"r\":\n case \"R\": flags.recursive = true; break;\n case \"e\": if (value) flags.patterns.push(value); break;\n case \"m\": if (value) flags.maxMatches = parseInt(value, 10); break;\n case \"A\": if (value) flags.afterContext = parseInt(value, 10); break;\n case \"B\": if (value) flags.beforeContext = parseInt(value, 10); break;\n case \"C\":\n if (value) {\n const num = parseInt(value, 10);\n flags.beforeContext = num;\n flags.afterContext = num;\n }\n break;\n default:\n // Handle long-only flags\n if (flag.long === \"include\" && value) flags.include.push(value);\n else if (flag.long === \"exclude\" && value) flags.exclude.push(value);\n break;\n }\n};\n\nfunction matchGlob(str: string, pattern: string): boolean {\n // Convert shell glob to regex: * -> .*, ? -> ., rest escaped\n let re = \"^\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \".*\";\n else if (ch === \"?\") re += \".\";\n else if (/[.+^${}()|[\\]\\\\]/.test(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n re += \"$\";\n return new RegExp(re).test(str);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n } else {\n // Support BRE-style \\| \\( \\) even in ERE mode for compatibility\n patterns = patterns.map(p => p.replace(/\\\\\\|/g, \"|\").replace(/\\\\\\(/g, \"(\").replace(/\\\\\\)/g, \")\"));\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\nexport const grep: Command = async (ctx) => {\n // Create fresh parser with fresh defaults for each invocation\n const parser = createFlagParser(spec, createDefaults(), handler);\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const options = result.flags;\n const args = result.args;\n\n // First positional arg is pattern if no -e patterns\n let files: string[];\n if (options.patterns.length === 0) {\n if (args.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n options.patterns.push(args[0]!);\n files = args.slice(1);\n } else {\n files = args;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Filter by include/exclude patterns\n if (options.include.length > 0 || options.exclude.length > 0) {\n expandedFiles = expandedFiles.filter((f) => {\n const basename = ctx.fs.basename(f);\n if (options.include.length > 0) {\n const included = options.include.some((pat) => matchGlob(basename, pat));\n if (!included) return false;\n }\n if (options.exclude.length > 0) {\n const excluded = options.exclude.some((pat) => matchGlob(basename, pat));\n if (excluded) return false;\n }\n return true;\n });\n }\n\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "E1E2499749A3C23A64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "549D8A8ACE2FBD1464756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -142,14 +142,22 @@ class Interpreter {
142
142
  let stdoutToStderr = false;
143
143
  const fileWritePromises = [];
144
144
  for (const redirect of node.redirects) {
145
- const result = await this.handleRedirect(redirect, actualStdin, actualStdout, actualStderr);
146
- actualStdin = result.stdin;
147
- actualStdout = result.stdout;
148
- actualStderr = result.stderr;
149
- stderrToStdout = result.stderrToStdout || stderrToStdout;
150
- stdoutToStderr = result.stdoutToStderr || stdoutToStderr;
151
- if (result.fileWritePromise) {
152
- fileWritePromises.push(result.fileWritePromise);
145
+ try {
146
+ const result = await this.handleRedirect(redirect, actualStdin, actualStdout, actualStderr);
147
+ actualStdin = result.stdin;
148
+ actualStdout = result.stdout;
149
+ actualStderr = result.stderr;
150
+ stderrToStdout = result.stderrToStdout || stderrToStdout;
151
+ stdoutToStderr = result.stdoutToStderr || stdoutToStderr;
152
+ if (result.fileWritePromise) {
153
+ fileWritePromises.push(result.fileWritePromise);
154
+ }
155
+ } catch (err) {
156
+ const target = await this.evaluateNode(redirect.target);
157
+ const message = err instanceof Error ? err.message : String(err);
158
+ await stderr.writeText(`sh: ${target}: ${message}
159
+ `);
160
+ return 1;
153
161
  }
154
162
  }
155
163
  if (stderrToStdout) {
@@ -191,7 +199,16 @@ class Interpreter {
191
199
  if (actualStderr !== stderr && actualStderr !== actualStdout) {
192
200
  actualStderr.close();
193
201
  }
194
- await Promise.all(fileWritePromises);
202
+ try {
203
+ await Promise.all(fileWritePromises);
204
+ } catch (err) {
205
+ const message = err instanceof Error ? err.message : String(err);
206
+ const writeRedirects = node.redirects.filter((r) => r.mode !== "<" && r.mode !== "2>&1" && r.mode !== "1>&2");
207
+ const target = writeRedirects.length > 0 ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1].target) : "unknown";
208
+ await stderr.writeText(`sh: ${target}: ${message}
209
+ `);
210
+ exitCode = 1;
211
+ }
195
212
  return exitCode;
196
213
  }
197
214
  async handleRedirect(redirect, stdin, stdout, stderr) {
@@ -791,4 +808,4 @@ class Interpreter {
791
808
  }
792
809
  }
793
810
 
794
- //# debugId=E644F0E2930B665A64756E2164756E21
811
+ //# debugId=0698AC93C00817D564756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/interpreter/interpreter.ts"],
4
4
  "sourcesContent": [
5
- "import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.cjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.cjs\";\nimport { createCommandContext } from \"./context.cjs\";\nimport { createStdin } from \"../io/stdin.cjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport { Parser } from \"../parser/parser.cjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout();\n const stderr = createStderr();\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n await Promise.all(fileWritePromises);\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
5
+ "import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.cjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.cjs\";\nimport { createCommandContext } from \"./context.cjs\";\nimport { createStdin } from \"../io/stdin.cjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport { Parser } from \"../parser/parser.cjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout();\n const stderr = createStderr();\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n try {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n } catch (err) {\n const target = await this.evaluateNode(redirect.target);\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n return 1;\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n try {\n await Promise.all(fileWritePromises);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // Find the redirect target for the error message\n const writeRedirects = node.redirects.filter(r => r.mode !== \"<\" && r.mode !== \"2>&1\" && r.mode !== \"1>&2\");\n const target = writeRedirects.length > 0\n ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1]!.target)\n : \"unknown\";\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n exitCode = 1;\n }\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "E644F0E2930B665A64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "0698AC93C00817D564756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "type": "module"
5
5
  }
@@ -140,6 +140,7 @@ var find = async (ctx) => {
140
140
  }
141
141
  let hasError = false;
142
142
  for (const startPath of paths) {
143
+ const normalizedPath = startPath === "/" ? "/" : startPath.replace(/\/+$/, "");
143
144
  const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);
144
145
  let stat;
145
146
  try {
@@ -205,11 +206,11 @@ var find = async (ctx) => {
205
206
  matches = false;
206
207
  }
207
208
  if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {
208
- await ctx.stdout.writeText(startPath + `
209
+ await ctx.stdout.writeText(normalizedPath + `
209
210
  `);
210
211
  }
211
212
  } else {
212
- await traverse(resolvedStart, startPath, 0);
213
+ await traverse(resolvedStart, normalizedPath, 0);
213
214
  }
214
215
  }
215
216
  return hasError ? 1 : 0;
@@ -218,4 +219,4 @@ export {
218
219
  find
219
220
  };
220
221
 
221
- //# debugId=0DD0859E30BDE7B964756E2164756E21
222
+ //# debugId=DA671804DAD6CB3364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/find/find.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\n\n/**\n * Simple glob pattern matching (fnmatch-style)\n * Supports: * (any chars), ? (single char), [...] (character class)\n */\nfunction matchGlob(pattern: string, str: string, caseInsensitive = false): boolean {\n if (caseInsensitive) {\n pattern = pattern.toLowerCase();\n str = str.toLowerCase();\n }\n\n // Convert glob to regex\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i]!;\n switch (c) {\n case \"*\":\n regex += \".*\";\n break;\n case \"?\":\n regex += \".\";\n break;\n case \"[\": {\n // Find closing bracket\n let j = i + 1;\n // Handle negation\n if (pattern[j] === \"!\" || pattern[j] === \"^\") j++;\n // Handle ] as first char in class\n if (pattern[j] === \"]\") j++;\n while (j < pattern.length && pattern[j] !== \"]\") j++;\n if (j >= pattern.length) {\n // No closing bracket, treat [ as literal\n regex += \"\\\\[\";\n } else {\n let charClass = pattern.slice(i, j + 1);\n // Convert ! to ^ for negation in regex\n charClass = charClass.replace(/^\\[!/, \"[^\");\n regex += charClass;\n i = j;\n }\n break;\n }\n case \".\":\n case \"^\":\n case \"$\":\n case \"+\":\n case \"{\":\n case \"}\":\n case \"(\":\n case \")\":\n case \"|\":\n case \"\\\\\":\n regex += \"\\\\\" + c;\n break;\n default:\n regex += c;\n }\n }\n regex += \"$\";\n\n try {\n return new RegExp(regex).test(str);\n } catch {\n return false;\n }\n}\n\ninterface FindOptions {\n namePattern?: string;\n nameIgnoreCase?: boolean;\n type?: \"f\" | \"d\";\n maxDepth?: number;\n minDepth?: number;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n const options: FindOptions = {};\n\n // Parse arguments: paths come before first flag, then expressions\n let i = 0;\n\n // Collect paths (args before first -)\n while (i < args.length && !args[i]!.startsWith(\"-\")) {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Parse expression flags\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"-name\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-name'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = false;\n } else if (arg === \"-iname\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-iname'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = true;\n } else if (arg === \"-type\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-type'\\n\");\n return 1;\n }\n const typeArg = args[i]!;\n if (typeArg !== \"f\" && typeArg !== \"d\") {\n await ctx.stderr.writeText(`find: Unknown argument to -type: ${typeArg}\\n`);\n return 1;\n }\n options.type = typeArg;\n } else if (arg === \"-maxdepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -maxdepth\\n`);\n return 1;\n }\n options.maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -mindepth\\n`);\n return 1;\n }\n options.minDepth = depth;\n } else if (arg.startsWith(\"-\")) {\n await ctx.stderr.writeText(`find: unknown predicate '${arg}'\\n`);\n return 1;\n } else {\n // This shouldn't happen since paths are parsed first, but treat as path\n paths.push(arg);\n }\n\n i++;\n }\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n\n // Check if this entry matches filters\n let matches = true;\n\n // Type filter\n if (options.type === \"f\" && !isFile) {\n matches = false;\n } else if (options.type === \"d\" && !isDir) {\n matches = false;\n }\n\n // Name filter (only check basename)\n if (matches && options.namePattern !== undefined) {\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n // Output if matches and above mindepth\n if (matches && (options.minDepth === undefined || depth >= options.minDepth)) {\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n // For a single file, it's at depth 0\n // For a directory, the directory itself is depth 0, contents are depth 1+\n if (stat.isFile()) {\n // Starting from a file - depth 0\n let matches = true;\n\n if (options.type === \"d\") {\n matches = false;\n }\n\n if (matches && options.namePattern !== undefined) {\n const basename = ctx.fs.basename(resolvedStart);\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n if (options.maxDepth !== undefined && options.maxDepth < 0) {\n matches = false;\n }\n\n if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {\n await ctx.stdout.writeText(startPath + \"\\n\");\n }\n } else {\n await traverse(resolvedStart, startPath, 0);\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\n\n/**\n * Simple glob pattern matching (fnmatch-style)\n * Supports: * (any chars), ? (single char), [...] (character class)\n */\nfunction matchGlob(pattern: string, str: string, caseInsensitive = false): boolean {\n if (caseInsensitive) {\n pattern = pattern.toLowerCase();\n str = str.toLowerCase();\n }\n\n // Convert glob to regex\n let regex = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const c = pattern[i]!;\n switch (c) {\n case \"*\":\n regex += \".*\";\n break;\n case \"?\":\n regex += \".\";\n break;\n case \"[\": {\n // Find closing bracket\n let j = i + 1;\n // Handle negation\n if (pattern[j] === \"!\" || pattern[j] === \"^\") j++;\n // Handle ] as first char in class\n if (pattern[j] === \"]\") j++;\n while (j < pattern.length && pattern[j] !== \"]\") j++;\n if (j >= pattern.length) {\n // No closing bracket, treat [ as literal\n regex += \"\\\\[\";\n } else {\n let charClass = pattern.slice(i, j + 1);\n // Convert ! to ^ for negation in regex\n charClass = charClass.replace(/^\\[!/, \"[^\");\n regex += charClass;\n i = j;\n }\n break;\n }\n case \".\":\n case \"^\":\n case \"$\":\n case \"+\":\n case \"{\":\n case \"}\":\n case \"(\":\n case \")\":\n case \"|\":\n case \"\\\\\":\n regex += \"\\\\\" + c;\n break;\n default:\n regex += c;\n }\n }\n regex += \"$\";\n\n try {\n return new RegExp(regex).test(str);\n } catch {\n return false;\n }\n}\n\ninterface FindOptions {\n namePattern?: string;\n nameIgnoreCase?: boolean;\n type?: \"f\" | \"d\";\n maxDepth?: number;\n minDepth?: number;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n const options: FindOptions = {};\n\n // Parse arguments: paths come before first flag, then expressions\n let i = 0;\n\n // Collect paths (args before first -)\n while (i < args.length && !args[i]!.startsWith(\"-\")) {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Parse expression flags\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"-name\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-name'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = false;\n } else if (arg === \"-iname\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-iname'\\n\");\n return 1;\n }\n options.namePattern = args[i]!;\n options.nameIgnoreCase = true;\n } else if (arg === \"-type\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-type'\\n\");\n return 1;\n }\n const typeArg = args[i]!;\n if (typeArg !== \"f\" && typeArg !== \"d\") {\n await ctx.stderr.writeText(`find: Unknown argument to -type: ${typeArg}\\n`);\n return 1;\n }\n options.type = typeArg;\n } else if (arg === \"-maxdepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -maxdepth\\n`);\n return 1;\n }\n options.maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n i++;\n if (i >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[i]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[i]}' to -mindepth\\n`);\n return 1;\n }\n options.minDepth = depth;\n } else if (arg.startsWith(\"-\")) {\n await ctx.stderr.writeText(`find: unknown predicate '${arg}'\\n`);\n return 1;\n } else {\n // This shouldn't happen since paths are parsed first, but treat as path\n paths.push(arg);\n }\n\n i++;\n }\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const normalizedPath = startPath === \"/\" ? \"/\" : startPath.replace(/\\/+$/, '');\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (options.maxDepth !== undefined && depth > options.maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n\n // Check if this entry matches filters\n let matches = true;\n\n // Type filter\n if (options.type === \"f\" && !isFile) {\n matches = false;\n } else if (options.type === \"d\" && !isDir) {\n matches = false;\n }\n\n // Name filter (only check basename)\n if (matches && options.namePattern !== undefined) {\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n // Output if matches and above mindepth\n if (matches && (options.minDepth === undefined || depth >= options.minDepth)) {\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n // For a single file, it's at depth 0\n // For a directory, the directory itself is depth 0, contents are depth 1+\n if (stat.isFile()) {\n // Starting from a file - depth 0\n let matches = true;\n\n if (options.type === \"d\") {\n matches = false;\n }\n\n if (matches && options.namePattern !== undefined) {\n const basename = ctx.fs.basename(resolvedStart);\n if (!matchGlob(options.namePattern, basename, options.nameIgnoreCase)) {\n matches = false;\n }\n }\n\n if (options.maxDepth !== undefined && options.maxDepth < 0) {\n matches = false;\n }\n\n if (matches && (options.minDepth === undefined || options.minDepth <= 0)) {\n await ctx.stdout.writeText(normalizedPath + \"\\n\");\n }\n } else {\n await traverse(resolvedStart, normalizedPath, 0);\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "0DD0859E30BDE7B964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "DA671804DAD6CB3364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -154,6 +154,8 @@ function buildMatcher(options) {
154
154
  let patterns = options.patterns;
155
155
  if (options.fixedStrings) {
156
156
  patterns = patterns.map(escapeRegex);
157
+ } else {
158
+ patterns = patterns.map((p) => p.replace(/\\\|/g, "|").replace(/\\\(/g, "(").replace(/\\\)/g, ")"));
157
159
  }
158
160
  let combined = patterns.length > 1 ? patterns.map((p) => `(?:${p})`).join("|") : patterns[0] || "";
159
161
  if (options.wholeWord) {
@@ -504,4 +506,4 @@ export {
504
506
  grep
505
507
  };
506
508
 
507
- //# debugId=195CF226D8C741D064756E2164756E21
509
+ //# debugId=0E1412C2E9C31AE364756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/commands/grep/grep.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition, type FlagError } from \"../../utils/flag-parser.mjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n include: string[]; // --include\n exclude: string[]; // --exclude\n}\n\nconst spec = {\n name: \"grep\",\n flags: [\n { short: \"E\", long: \"extended-regexp\" },\n { short: \"F\", long: \"fixed-strings\" },\n { short: \"i\", long: \"ignore-case\" },\n { short: \"w\", long: \"word-regexp\" },\n { short: \"x\", long: \"line-regexp\" },\n { short: \"v\", long: \"invert-match\" },\n { short: \"c\", long: \"count\" },\n { short: \"l\", long: \"files-with-matches\" },\n { short: \"L\", long: \"files-without-match\" },\n { short: \"n\", long: \"line-number\" },\n { short: \"o\", long: \"only-matching\" },\n { short: \"q\", long: \"quiet\" },\n { short: \"H\", long: \"with-filename\" },\n { short: \"h\", long: \"no-filename\" },\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"e\", long: \"regexp\", takesValue: true },\n { short: \"m\", long: \"max-count\", takesValue: true },\n { short: \"A\", long: \"after-context\", takesValue: true },\n { short: \"B\", long: \"before-context\", takesValue: true },\n { short: \"C\", long: \"context\", takesValue: true },\n { long: \"include\", takesValue: true },\n { long: \"exclude\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]\",\n};\n\nfunction createDefaults(): GrepOptions {\n return {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n include: [],\n exclude: [],\n };\n}\n\nconst handler = (flags: GrepOptions, flag: FlagDefinition, value?: string) => {\n switch (flag.short) {\n case \"E\": flags.extendedRegex = true; break;\n case \"F\": flags.fixedStrings = true; break;\n case \"i\": flags.ignoreCase = true; break;\n case \"w\": flags.wholeWord = true; break;\n case \"x\": flags.wholeLine = true; break;\n case \"v\": flags.invert = true; break;\n case \"c\": flags.countOnly = true; break;\n case \"l\": flags.filesWithMatches = true; break;\n case \"L\": flags.filesWithoutMatches = true; break;\n case \"n\": flags.showLineNumbers = true; break;\n case \"o\": flags.onlyMatching = true; break;\n case \"q\": flags.quiet = true; break;\n case \"H\": flags.showFilename = true; break;\n case \"h\": flags.showFilename = false; break;\n case \"r\":\n case \"R\": flags.recursive = true; break;\n case \"e\": if (value) flags.patterns.push(value); break;\n case \"m\": if (value) flags.maxMatches = parseInt(value, 10); break;\n case \"A\": if (value) flags.afterContext = parseInt(value, 10); break;\n case \"B\": if (value) flags.beforeContext = parseInt(value, 10); break;\n case \"C\":\n if (value) {\n const num = parseInt(value, 10);\n flags.beforeContext = num;\n flags.afterContext = num;\n }\n break;\n default:\n // Handle long-only flags\n if (flag.long === \"include\" && value) flags.include.push(value);\n else if (flag.long === \"exclude\" && value) flags.exclude.push(value);\n break;\n }\n};\n\nfunction matchGlob(str: string, pattern: string): boolean {\n // Convert shell glob to regex: * -> .*, ? -> ., rest escaped\n let re = \"^\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \".*\";\n else if (ch === \"?\") re += \".\";\n else if (/[.+^${}()|[\\]\\\\]/.test(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n re += \"$\";\n return new RegExp(re).test(str);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\nexport const grep: Command = async (ctx) => {\n // Create fresh parser with fresh defaults for each invocation\n const parser = createFlagParser(spec, createDefaults(), handler);\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const options = result.flags;\n const args = result.args;\n\n // First positional arg is pattern if no -e patterns\n let files: string[];\n if (options.patterns.length === 0) {\n if (args.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n options.patterns.push(args[0]!);\n files = args.slice(1);\n } else {\n files = args;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Filter by include/exclude patterns\n if (options.include.length > 0 || options.exclude.length > 0) {\n expandedFiles = expandedFiles.filter((f) => {\n const basename = ctx.fs.basename(f);\n if (options.include.length > 0) {\n const included = options.include.some((pat) => matchGlob(basename, pat));\n if (!included) return false;\n }\n if (options.exclude.length > 0) {\n const excluded = options.exclude.some((pat) => matchGlob(basename, pat));\n if (excluded) return false;\n }\n return true;\n });\n }\n\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
5
+ "import type { Command } from \"../../types.mjs\";\nimport { createFlagParser, type FlagDefinition, type FlagError } from \"../../utils/flag-parser.mjs\";\n\ninterface GrepOptions {\n patterns: string[];\n extendedRegex: boolean; // -E (default for JS)\n fixedStrings: boolean; // -F\n ignoreCase: boolean; // -i\n wholeWord: boolean; // -w\n wholeLine: boolean; // -x\n invert: boolean; // -v\n countOnly: boolean; // -c\n filesWithMatches: boolean; // -l\n filesWithoutMatches: boolean; // -L\n showLineNumbers: boolean; // -n\n onlyMatching: boolean; // -o\n quiet: boolean; // -q\n maxMatches: number; // -m (0 = unlimited)\n showFilename: boolean | null; // null=auto, true=-H, false=-h\n beforeContext: number; // -B\n afterContext: number; // -A\n recursive: boolean; // -r/-R\n include: string[]; // --include\n exclude: string[]; // --exclude\n}\n\nconst spec = {\n name: \"grep\",\n flags: [\n { short: \"E\", long: \"extended-regexp\" },\n { short: \"F\", long: \"fixed-strings\" },\n { short: \"i\", long: \"ignore-case\" },\n { short: \"w\", long: \"word-regexp\" },\n { short: \"x\", long: \"line-regexp\" },\n { short: \"v\", long: \"invert-match\" },\n { short: \"c\", long: \"count\" },\n { short: \"l\", long: \"files-with-matches\" },\n { short: \"L\", long: \"files-without-match\" },\n { short: \"n\", long: \"line-number\" },\n { short: \"o\", long: \"only-matching\" },\n { short: \"q\", long: \"quiet\" },\n { short: \"H\", long: \"with-filename\" },\n { short: \"h\", long: \"no-filename\" },\n { short: \"r\", long: \"recursive\" },\n { short: \"R\" },\n { short: \"e\", long: \"regexp\", takesValue: true },\n { short: \"m\", long: \"max-count\", takesValue: true },\n { short: \"A\", long: \"after-context\", takesValue: true },\n { short: \"B\", long: \"before-context\", takesValue: true },\n { short: \"C\", long: \"context\", takesValue: true },\n { long: \"include\", takesValue: true },\n { long: \"exclude\", takesValue: true },\n ] as FlagDefinition[],\n usage: \"grep [-ivnclLqHhEFwxorR] [-e pattern] [-m num] pattern [file ...]\",\n};\n\nfunction createDefaults(): GrepOptions {\n return {\n patterns: [],\n extendedRegex: true, // JS regex is extended by default\n fixedStrings: false,\n ignoreCase: false,\n wholeWord: false,\n wholeLine: false,\n invert: false,\n countOnly: false,\n filesWithMatches: false,\n filesWithoutMatches: false,\n showLineNumbers: false,\n onlyMatching: false,\n quiet: false,\n maxMatches: 0,\n showFilename: null,\n beforeContext: 0,\n afterContext: 0,\n recursive: false,\n include: [],\n exclude: [],\n };\n}\n\nconst handler = (flags: GrepOptions, flag: FlagDefinition, value?: string) => {\n switch (flag.short) {\n case \"E\": flags.extendedRegex = true; break;\n case \"F\": flags.fixedStrings = true; break;\n case \"i\": flags.ignoreCase = true; break;\n case \"w\": flags.wholeWord = true; break;\n case \"x\": flags.wholeLine = true; break;\n case \"v\": flags.invert = true; break;\n case \"c\": flags.countOnly = true; break;\n case \"l\": flags.filesWithMatches = true; break;\n case \"L\": flags.filesWithoutMatches = true; break;\n case \"n\": flags.showLineNumbers = true; break;\n case \"o\": flags.onlyMatching = true; break;\n case \"q\": flags.quiet = true; break;\n case \"H\": flags.showFilename = true; break;\n case \"h\": flags.showFilename = false; break;\n case \"r\":\n case \"R\": flags.recursive = true; break;\n case \"e\": if (value) flags.patterns.push(value); break;\n case \"m\": if (value) flags.maxMatches = parseInt(value, 10); break;\n case \"A\": if (value) flags.afterContext = parseInt(value, 10); break;\n case \"B\": if (value) flags.beforeContext = parseInt(value, 10); break;\n case \"C\":\n if (value) {\n const num = parseInt(value, 10);\n flags.beforeContext = num;\n flags.afterContext = num;\n }\n break;\n default:\n // Handle long-only flags\n if (flag.long === \"include\" && value) flags.include.push(value);\n else if (flag.long === \"exclude\" && value) flags.exclude.push(value);\n break;\n }\n};\n\nfunction matchGlob(str: string, pattern: string): boolean {\n // Convert shell glob to regex: * -> .*, ? -> ., rest escaped\n let re = \"^\";\n for (const ch of pattern) {\n if (ch === \"*\") re += \".*\";\n else if (ch === \"?\") re += \".\";\n else if (/[.+^${}()|[\\]\\\\]/.test(ch)) re += \"\\\\\" + ch;\n else re += ch;\n }\n re += \"$\";\n return new RegExp(re).test(str);\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction buildMatcher(options: GrepOptions): RegExp {\n let patterns = options.patterns;\n\n // If fixed strings mode, escape regex metacharacters\n if (options.fixedStrings) {\n patterns = patterns.map(escapeRegex);\n } else {\n // Support BRE-style \\| \\( \\) even in ERE mode for compatibility\n patterns = patterns.map(p => p.replace(/\\\\\\|/g, \"|\").replace(/\\\\\\(/g, \"(\").replace(/\\\\\\)/g, \")\"));\n }\n\n // Combine multiple patterns with OR\n let combined = patterns.length > 1 ? patterns.map(p => `(?:${p})`).join(\"|\") : patterns[0] || \"\";\n\n // Whole word match\n if (options.wholeWord) {\n combined = `\\\\b(?:${combined})\\\\b`;\n }\n\n // Whole line match\n if (options.wholeLine) {\n combined = `^(?:${combined})$`;\n }\n\n const flags = options.ignoreCase ? \"gi\" : \"g\";\n return new RegExp(combined, flags);\n}\n\nexport const grep: Command = async (ctx) => {\n // Create fresh parser with fresh defaults for each invocation\n const parser = createFlagParser(spec, createDefaults(), handler);\n const result = parser.parse(ctx.args);\n\n if (result.error) {\n await parser.writeError(result.error, ctx.stderr);\n return 1;\n }\n\n const options = result.flags;\n const args = result.args;\n\n // First positional arg is pattern if no -e patterns\n let files: string[];\n if (options.patterns.length === 0) {\n if (args.length === 0) {\n await ctx.stderr.writeText(\"grep: missing pattern\\n\");\n return 1;\n }\n options.patterns.push(args[0]!);\n files = args.slice(1);\n } else {\n files = args;\n }\n\n let regex: RegExp;\n try {\n regex = buildMatcher(options);\n } catch (err) {\n await ctx.stderr.writeText(`grep: invalid pattern: ${options.patterns.join(\", \")}\\n`);\n return 1;\n }\n\n let globalFound = false;\n let globalMatchCount = 0;\n let earlyExit = false;\n\n // Determine filename display mode\n let showFilenames = options.showFilename;\n\n // Expand files if recursive\n let expandedFiles = files;\n if (options.recursive && files.length > 0) {\n expandedFiles = [];\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const stat = await ctx.fs.stat(path);\n if (stat.isDirectory()) {\n // Glob all files in directory\n const globbed = await ctx.fs.glob(\"**/*\", { cwd: path });\n for (const f of globbed) {\n const fullPath = ctx.fs.resolve(path, f);\n try {\n const s = await ctx.fs.stat(fullPath);\n if (s.isFile()) {\n expandedFiles.push(fullPath);\n }\n } catch {\n // Skip if can't stat\n }\n }\n } else {\n expandedFiles.push(path);\n }\n } catch {\n expandedFiles.push(path); // Will error later\n }\n }\n // Filter by include/exclude patterns\n if (options.include.length > 0 || options.exclude.length > 0) {\n expandedFiles = expandedFiles.filter((f) => {\n const basename = ctx.fs.basename(f);\n if (options.include.length > 0) {\n const included = options.include.some((pat) => matchGlob(basename, pat));\n if (!included) return false;\n }\n if (options.exclude.length > 0) {\n const excluded = options.exclude.some((pat) => matchGlob(basename, pat));\n if (excluded) return false;\n }\n return true;\n });\n }\n\n // Default to showing filenames for recursive\n if (showFilenames === null) {\n showFilenames = true;\n }\n }\n\n // Default: show filenames if multiple files\n if (showFilenames === null) {\n showFilenames = expandedFiles.length > 1;\n }\n\n const processContent = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n\n // For context lines, we need a buffer approach\n const hasContext = options.beforeContext > 0 || options.afterContext > 0;\n\n if (hasContext) {\n return await processWithContext(lines, filename);\n }\n\n for (let lineIdx = 0; lineIdx < lines.length && !earlyExit; lineIdx++) {\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n\n // Reset regex lastIndex for each line\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n\n if (shouldOutput) {\n fileFound = true;\n fileMatchCount++;\n\n // Quiet mode: exit immediately on first match\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n // -l mode: we found a match in this file, stop processing this file\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n // Output the match (unless countOnly or filesWithoutMatches)\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n // Output only the matched parts\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n // Prevent infinite loop for zero-width matches\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n // Check max matches\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n }\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n const processWithContext = async (\n lines: string[],\n filename?: string\n ): Promise<{ found: boolean; count: number }> => {\n let fileFound = false;\n let fileMatchCount = 0;\n let lastPrintedLine = -1;\n\n // First pass: find all matching lines\n const matchingLines = new Set<number>();\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n const line = lines[lineIdx]!;\n regex.lastIndex = 0;\n const matches = regex.test(line);\n const shouldOutput = options.invert ? !matches : matches;\n if (shouldOutput) {\n matchingLines.add(lineIdx);\n }\n }\n\n // Determine which lines to print (matches + context)\n const linesToPrint = new Set<number>();\n for (const matchIdx of matchingLines) {\n // Add before context\n for (let i = Math.max(0, matchIdx - options.beforeContext); i < matchIdx; i++) {\n linesToPrint.add(i);\n }\n // Add the match itself\n linesToPrint.add(matchIdx);\n // Add after context\n for (let i = matchIdx + 1; i <= Math.min(lines.length - 1, matchIdx + options.afterContext); i++) {\n linesToPrint.add(i);\n }\n }\n\n // Sort and print\n const sortedLines = Array.from(linesToPrint).sort((a, b) => a - b);\n\n for (let i = 0; i < sortedLines.length && !earlyExit; i++) {\n const lineIdx = sortedLines[i]!;\n const line = lines[lineIdx]!;\n const lineNum = lineIdx + 1;\n const isMatch = matchingLines.has(lineIdx);\n\n // Print separator if there's a gap\n if (lastPrintedLine >= 0 && lineIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n\n if (isMatch) {\n fileFound = true;\n fileMatchCount++;\n\n if (options.quiet) {\n earlyExit = true;\n return { found: true, count: 1 };\n }\n\n if (options.filesWithMatches) {\n return { found: true, count: 1 };\n }\n\n if (!options.countOnly && !options.filesWithoutMatches) {\n if (options.onlyMatching && !options.invert) {\n regex.lastIndex = 0;\n let match;\n while ((match = regex.exec(line)) !== null) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += match[0] + \"\\n\";\n await ctx.stdout.writeText(output);\n if (match[0].length === 0) regex.lastIndex++;\n }\n } else {\n let output = \"\";\n if (filename && showFilenames) output += filename + \":\";\n if (options.showLineNumbers) output += lineNum + \":\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n if (options.maxMatches > 0 && fileMatchCount >= options.maxMatches) {\n // Still need to output remaining context lines after this match\n // Continue to output context but mark we should stop looking for more matches\n const remainingContextLines = sortedLines.slice(i + 1).filter(idx => !matchingLines.has(idx));\n for (const contextIdx of remainingContextLines) {\n const contextLine = lines[contextIdx]!;\n const contextLineNum = contextIdx + 1;\n // Check if it's within after-context of current match\n if (contextIdx <= lineIdx + options.afterContext) {\n if (lastPrintedLine >= 0 && contextIdx > lastPrintedLine + 1) {\n await ctx.stdout.writeText(\"--\\n\");\n }\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += contextLineNum + \"-\";\n output += contextLine + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n lastPrintedLine = contextIdx;\n }\n }\n earlyExit = true;\n return { found: true, count: fileMatchCount };\n }\n } else {\n // Context line\n if (!options.countOnly && !options.filesWithoutMatches) {\n let output = \"\";\n if (filename && showFilenames) output += filename + \"-\";\n if (options.showLineNumbers) output += lineNum + \"-\";\n output += line + \"\\n\";\n await ctx.stdout.writeText(output);\n }\n }\n\n lastPrintedLine = lineIdx;\n }\n\n return { found: fileFound, count: fileMatchCount };\n };\n\n if (expandedFiles.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if content ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n const { found, count } = await processContent(lines);\n globalFound = found;\n globalMatchCount = count;\n\n if (options.countOnly && !options.quiet && !options.filesWithMatches && !options.filesWithoutMatches) {\n await ctx.stdout.writeText(globalMatchCount + \"\\n\");\n }\n } else {\n // Read from files\n const perFileResults: Map<string, { found: boolean; count: number }> = new Map();\n\n for (const file of expandedFiles) {\n if (earlyExit && options.quiet) break;\n\n try {\n const path = file.startsWith(\"/\") ? file : ctx.fs.resolve(ctx.cwd, file);\n const stat = await ctx.fs.stat(path);\n\n if (stat.isDirectory()) {\n if (!options.recursive) {\n await ctx.stderr.writeText(`grep: ${file}: Is a directory\\n`);\n }\n continue;\n }\n\n const content = await ctx.fs.readFile(path);\n const lines = content.toString().split(\"\\n\");\n\n // Remove trailing empty line if file ends with newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n // Use original filename for display, not resolved path\n const displayName = files.includes(file) ? file :\n (options.recursive ? path : file);\n\n const { found, count } = await processContent(lines, displayName);\n perFileResults.set(displayName, { found, count });\n\n if (found) {\n globalFound = true;\n globalMatchCount += count;\n }\n } catch (err) {\n await ctx.stderr.writeText(`grep: ${file}: No such file or directory\\n`);\n // Continue to other files instead of immediately returning\n if (expandedFiles.length === 1) {\n return 1;\n }\n }\n }\n\n // Handle -l, -L, -c output modes\n let hasFilesWithoutMatches = false;\n if (options.filesWithMatches) {\n for (const [filename, result] of perFileResults) {\n if (result.found && !options.quiet) {\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.filesWithoutMatches) {\n for (const [filename, result] of perFileResults) {\n if (!result.found) {\n hasFilesWithoutMatches = true;\n await ctx.stdout.writeText(filename + \"\\n\");\n }\n }\n } else if (options.countOnly && !options.quiet) {\n for (const [filename, result] of perFileResults) {\n if (showFilenames) {\n await ctx.stdout.writeText(`${filename}:${result.count}\\n`);\n } else {\n await ctx.stdout.writeText(result.count + \"\\n\");\n }\n }\n }\n\n // Determine exit code for file processing\n if (options.filesWithoutMatches) {\n // -L: success if any file had NO matches\n return hasFilesWithoutMatches ? 0 : 1;\n }\n }\n\n // Determine exit code\n return globalFound ? 0 : 1;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "195CF226D8C741D064756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "0E1412C2E9C31AE364756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -107,14 +107,22 @@ class Interpreter {
107
107
  let stdoutToStderr = false;
108
108
  const fileWritePromises = [];
109
109
  for (const redirect of node.redirects) {
110
- const result = await this.handleRedirect(redirect, actualStdin, actualStdout, actualStderr);
111
- actualStdin = result.stdin;
112
- actualStdout = result.stdout;
113
- actualStderr = result.stderr;
114
- stderrToStdout = result.stderrToStdout || stderrToStdout;
115
- stdoutToStderr = result.stdoutToStderr || stdoutToStderr;
116
- if (result.fileWritePromise) {
117
- fileWritePromises.push(result.fileWritePromise);
110
+ try {
111
+ const result = await this.handleRedirect(redirect, actualStdin, actualStdout, actualStderr);
112
+ actualStdin = result.stdin;
113
+ actualStdout = result.stdout;
114
+ actualStderr = result.stderr;
115
+ stderrToStdout = result.stderrToStdout || stderrToStdout;
116
+ stdoutToStderr = result.stdoutToStderr || stdoutToStderr;
117
+ if (result.fileWritePromise) {
118
+ fileWritePromises.push(result.fileWritePromise);
119
+ }
120
+ } catch (err) {
121
+ const target = await this.evaluateNode(redirect.target);
122
+ const message = err instanceof Error ? err.message : String(err);
123
+ await stderr.writeText(`sh: ${target}: ${message}
124
+ `);
125
+ return 1;
118
126
  }
119
127
  }
120
128
  if (stderrToStdout) {
@@ -156,7 +164,16 @@ class Interpreter {
156
164
  if (actualStderr !== stderr && actualStderr !== actualStdout) {
157
165
  actualStderr.close();
158
166
  }
159
- await Promise.all(fileWritePromises);
167
+ try {
168
+ await Promise.all(fileWritePromises);
169
+ } catch (err) {
170
+ const message = err instanceof Error ? err.message : String(err);
171
+ const writeRedirects = node.redirects.filter((r) => r.mode !== "<" && r.mode !== "2>&1" && r.mode !== "1>&2");
172
+ const target = writeRedirects.length > 0 ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1].target) : "unknown";
173
+ await stderr.writeText(`sh: ${target}: ${message}
174
+ `);
175
+ exitCode = 1;
176
+ }
160
177
  return exitCode;
161
178
  }
162
179
  async handleRedirect(redirect, stdin, stdout, stderr) {
@@ -761,4 +778,4 @@ export {
761
778
  BreakException
762
779
  };
763
780
 
764
- //# debugId=75622AF9F6C7A68964756E2164756E21
781
+ //# debugId=FF91F2326D4DFFED64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/interpreter/interpreter.ts"],
4
4
  "sourcesContent": [
5
- "import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.mjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.mjs\";\nimport { createCommandContext } from \"./context.mjs\";\nimport { createStdin } from \"../io/stdin.mjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.mjs\";\nimport { Lexer } from \"../lexer/lexer.mjs\";\nimport { Parser } from \"../parser/parser.mjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout();\n const stderr = createStderr();\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n await Promise.all(fileWritePromises);\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
5
+ "import type { ASTNode, CommandNode, Redirect, IfNode, ForNode, WhileNode, UntilNode, CaseNode } from \"../parser/ast.mjs\";\nimport type { Command, VirtualFS, ExecResult, OutputCollector, RedirectObjectMap } from \"../types.mjs\";\nimport { createCommandContext } from \"./context.mjs\";\nimport { createStdin } from \"../io/stdin.mjs\";\nimport { createStdout, createStderr, createPipe, PipeBuffer, createBufferTargetCollector } from \"../io/stdout.mjs\";\nimport { Lexer } from \"../lexer/lexer.mjs\";\nimport { Parser } from \"../parser/parser.mjs\";\n\nexport interface InterpreterOptions {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n redirectObjects?: RedirectObjectMap;\n}\n\n// Loop control flow exceptions\nexport class BreakException extends Error {\n constructor(public levels: number = 1) {\n super(\"break\");\n }\n}\n\nexport class ContinueException extends Error {\n constructor(public levels: number = 1) {\n super(\"continue\");\n }\n}\n\nexport class Interpreter {\n private fs: VirtualFS;\n private cwd: string;\n private env: Record<string, string>;\n private commands: Record<string, Command>;\n private redirectObjects: RedirectObjectMap;\n private loopDepth: number = 0;\n\n constructor(options: InterpreterOptions) {\n this.fs = options.fs;\n this.cwd = options.cwd;\n this.env = { ...options.env };\n this.commands = options.commands;\n this.redirectObjects = options.redirectObjects ?? {};\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout();\n const stderr = createStderr();\n\n const exitCode = await this.executeNode(ast, null, stdout, stderr);\n\n stdout.close();\n stderr.close();\n\n return {\n stdout: await stdout.collect(),\n stderr: await stderr.collect(),\n exitCode,\n };\n }\n\n private async executeNode(\n node: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n switch (node.type) {\n case \"command\":\n return this.executeCommand(node, stdinSource, stdout, stderr);\n case \"pipeline\":\n return this.executePipeline(node.commands, stdinSource, stdout, stderr);\n case \"sequence\":\n return this.executeSequence(node.commands, stdinSource, stdout, stderr);\n case \"and\":\n return this.executeAnd(node.left, node.right, stdinSource, stdout, stderr);\n case \"or\":\n return this.executeOr(node.left, node.right, stdinSource, stdout, stderr);\n case \"if\":\n return this.executeIf(node, stdinSource, stdout, stderr);\n case \"for\":\n return this.executeFor(node, stdinSource, stdout, stderr);\n case \"while\":\n return this.executeWhile(node, stdinSource, stdout, stderr);\n case \"until\":\n return this.executeUntil(node, stdinSource, stdout, stderr);\n case \"case\":\n return this.executeCase(node, stdinSource, stdout, stderr);\n default:\n throw new Error(`Cannot execute node type: ${node.type}`);\n }\n }\n\n private async executeCommand(\n node: CommandNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Create local env with assignments\n const localEnv = { ...this.env };\n for (const assignment of node.assignments) {\n localEnv[assignment.name] = await this.evaluateNode(assignment.value);\n }\n\n // If there's no command name but there are assignments, just update env\n const name = await this.evaluateNode(node.name);\n if (name === \"\" && node.assignments.length > 0) {\n for (const assignment of node.assignments) {\n this.env[assignment.name] = await this.evaluateNode(assignment.value);\n }\n return 0;\n }\n\n // Evaluate arguments using localEnv for scoped variable expansion\n const args: string[] = [];\n for (const arg of node.args) {\n const evaluated = await this.evaluateNode(arg, localEnv);\n // Glob expansion returns multiple values\n if (arg.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n args.push(...matches);\n } else {\n // No matches - use pattern as-is\n args.push(evaluated);\n }\n } else {\n args.push(evaluated);\n }\n }\n\n // Handle redirects\n let actualStdin = stdinSource;\n let actualStdout: OutputCollector = stdout;\n let actualStderr: OutputCollector = stderr;\n let stderrToStdout = false;\n let stdoutToStderr = false;\n const fileWritePromises: Promise<void>[] = [];\n\n for (const redirect of node.redirects) {\n try {\n const result = await this.handleRedirect(\n redirect,\n actualStdin,\n actualStdout,\n actualStderr\n );\n actualStdin = result.stdin;\n actualStdout = result.stdout;\n actualStderr = result.stderr;\n stderrToStdout = result.stderrToStdout || stderrToStdout;\n stdoutToStderr = result.stdoutToStderr || stdoutToStderr;\n if (result.fileWritePromise) {\n fileWritePromises.push(result.fileWritePromise);\n }\n } catch (err) {\n const target = await this.evaluateNode(redirect.target);\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n return 1;\n }\n }\n\n // Handle stderr->stdout redirect\n if (stderrToStdout) {\n actualStderr = actualStdout;\n }\n if (stdoutToStderr) {\n actualStdout = actualStderr;\n }\n\n // Look up command\n const command = this.commands[name];\n if (!command) {\n await stderr.writeText(`${name}: command not found\\n`);\n return 127;\n }\n\n // Create context and execute\n const ctx = createCommandContext({\n args,\n stdin: createStdin(actualStdin),\n stdout: actualStdout,\n stderr: actualStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: localEnv,\n });\n\n let exitCode: number;\n try {\n exitCode = await command(ctx);\n } catch (err) {\n // Re-throw loop control exceptions\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`${name}: ${message}\\n`);\n exitCode = 1;\n }\n\n // Close redirect collectors and wait for file writes\n if (actualStdout !== stdout) {\n actualStdout.close();\n }\n if (actualStderr !== stderr && actualStderr !== actualStdout) {\n actualStderr.close();\n }\n\n // Wait for all file write operations to complete\n try {\n await Promise.all(fileWritePromises);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n // Find the redirect target for the error message\n const writeRedirects = node.redirects.filter(r => r.mode !== \"<\" && r.mode !== \"2>&1\" && r.mode !== \"1>&2\");\n const target = writeRedirects.length > 0\n ? await this.evaluateNode(writeRedirects[writeRedirects.length - 1]!.target)\n : \"unknown\";\n await stderr.writeText(`sh: ${target}: ${message}\\n`);\n exitCode = 1;\n }\n\n return exitCode;\n }\n\n private async handleRedirect(\n redirect: Redirect,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n const target = await this.evaluateNode(redirect.target);\n\n // Check if target is a redirect object marker\n if (target in this.redirectObjects) {\n return this.handleObjectRedirect(redirect.mode, this.redirectObjects[target]!, stdin, stdout, stderr);\n }\n\n switch (redirect.mode) {\n case \"<\": {\n if (redirect.heredocContent) {\n // Heredoc: target is already the content\n return {\n stdin: (async function* () {\n yield new TextEncoder().encode(target);\n })(),\n stdout,\n stderr,\n };\n }\n // /dev/null: empty input\n if (target === \"/dev/null\") {\n return {\n stdin: (async function* () {})(),\n stdout,\n stderr,\n };\n }\n // Input redirect from file\n const path = this.fs.resolve(this.cwd, target);\n const content = await this.fs.readFile(path);\n return {\n stdin: (async function* () {\n yield new Uint8Array(content);\n })(),\n stdout,\n stderr,\n };\n }\n case \">\": {\n // Output redirect (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \">>\": {\n // Output redirect (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr, fileWritePromise };\n }\n case \"2>\": {\n // Stderr redirect (overwrite)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"2>>\": {\n // Stderr redirect (append)\n const collector = createStderr();\n if (target === \"/dev/null\") {\n return { stdin, stdout, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout, stderr: collector, fileWritePromise };\n }\n case \"&>\": {\n // Both to file (overwrite)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.writeFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"&>>\": {\n // Both to file (append)\n const collector = createStdout();\n if (target === \"/dev/null\") {\n return { stdin, stdout: collector, stderr: collector };\n }\n const path = this.fs.resolve(this.cwd, target);\n const fileWritePromise = (async () => {\n const data = await collector.collect();\n await this.fs.appendFile(path, data);\n })();\n return { stdin, stdout: collector, stderr: collector, fileWritePromise };\n }\n case \"2>&1\":\n return { stdin, stdout, stderr, stderrToStdout: true };\n case \"1>&2\":\n return { stdin, stdout, stderr, stdoutToStderr: true };\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async handleObjectRedirect(\n mode: string,\n obj: Buffer | Blob | Response | string,\n stdin: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<{\n stdin: AsyncIterable<Uint8Array> | null;\n stdout: OutputCollector;\n stderr: OutputCollector;\n stderrToStdout?: boolean;\n stdoutToStderr?: boolean;\n fileWritePromise?: Promise<void>;\n }> {\n switch (mode) {\n case \"<\": {\n // Input from object\n const data = await this.readFromObject(obj);\n return {\n stdin: (async function* () {\n yield data;\n })(),\n stdout,\n stderr,\n };\n }\n case \">\":\n case \">>\": {\n // Output to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Output redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr };\n }\n case \"2>\":\n case \"2>>\": {\n // Stderr to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Stderr redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout, stderr: collector };\n }\n case \"&>\":\n case \"&>>\": {\n // Both to object (only Buffer supported)\n if (!Buffer.isBuffer(obj)) {\n throw new Error(\"Combined redirection only supports Buffer targets\");\n }\n const collector = createBufferTargetCollector(obj);\n return { stdin, stdout: collector, stderr: collector };\n }\n default:\n return { stdin, stdout, stderr };\n }\n }\n\n private async readFromObject(obj: Buffer | Blob | Response | string): Promise<Uint8Array> {\n if (Buffer.isBuffer(obj)) {\n return new Uint8Array(obj);\n }\n if (obj instanceof Blob) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (obj instanceof Response) {\n return new Uint8Array(await obj.arrayBuffer());\n }\n if (typeof obj === \"string\") {\n return new TextEncoder().encode(obj);\n }\n throw new Error(\"Unsupported redirect object type\");\n }\n\n private async executePipeline(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n if (commands.length === 0) return 0;\n if (commands.length === 1) {\n return this.executeNode(commands[0]!, stdinSource, stdout, stderr);\n }\n\n // Create pipes between commands\n const pipes: PipeBuffer[] = [];\n for (let i = 0; i < commands.length - 1; i++) {\n pipes.push(createPipe());\n }\n\n // Execute all commands concurrently\n const promises: Promise<number>[] = [];\n\n for (let i = 0; i < commands.length; i++) {\n const command = commands[i]!;\n const cmdStdin = i === 0 ? stdinSource : pipes[i - 1]!.getReadableStream();\n const cmdStdout = i === commands.length - 1 ? stdout : pipes[i]!;\n\n promises.push(\n this.executeNode(command, cmdStdin, cmdStdout, stderr).then((code) => {\n // Close pipe when command finishes\n if (i < commands.length - 1) {\n pipes[i]!.close();\n }\n return code;\n })\n );\n }\n\n // Wait for all commands and return last exit code\n const results = await Promise.all(promises);\n return results[results.length - 1]!;\n }\n\n private async executeSequence(\n commands: ASTNode[],\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n\n for (const command of commands) {\n lastExitCode = await this.executeNode(command, stdinSource, stdout, stderr);\n }\n\n return lastExitCode;\n }\n\n private async executeAnd(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode !== 0) {\n return leftCode;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeOr(\n left: ASTNode,\n right: ASTNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const leftCode = await this.executeNode(left, stdinSource, stdout, stderr);\n if (leftCode === 0) {\n return 0;\n }\n return this.executeNode(right, stdinSource, stdout, stderr);\n }\n\n private async executeIf(\n node: IfNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Execute condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n\n if (conditionCode === 0) {\n // Condition succeeded, execute then branch\n return this.executeNode(node.thenBranch, stdinSource, stdout, stderr);\n }\n\n // Check elif branches\n for (const elif of node.elifBranches) {\n const elifConditionCode = await this.executeNode(elif.condition, stdinSource, stdout, stderr);\n if (elifConditionCode === 0) {\n return this.executeNode(elif.body, stdinSource, stdout, stderr);\n }\n }\n\n // Execute else branch if present\n if (node.elseBranch) {\n return this.executeNode(node.elseBranch, stdinSource, stdout, stderr);\n }\n\n return 0;\n }\n\n private async executeFor(\n node: ForNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n // Evaluate items and expand globs\n const expandedItems: string[] = [];\n for (const item of node.items) {\n const evaluated = await this.evaluateNode(item);\n if (item.type === \"glob\") {\n const matches = await this.fs.glob(evaluated, { cwd: this.cwd });\n if (matches.length > 0) {\n expandedItems.push(...matches);\n } else {\n expandedItems.push(evaluated);\n }\n } else {\n expandedItems.push(evaluated);\n }\n }\n\n // If no items provided, use positional parameters (not implemented, so empty)\n if (expandedItems.length === 0) {\n return 0;\n }\n\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n for (const value of expandedItems) {\n // Set the loop variable\n this.env[node.variable] = value;\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeWhile(\n node: WhileNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode !== 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeUntil(\n node: UntilNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n let lastExitCode = 0;\n this.loopDepth++;\n\n try {\n while (true) {\n // Check condition - loop until condition succeeds\n const conditionCode = await this.executeNode(node.condition, stdinSource, stdout, stderr);\n if (conditionCode === 0) {\n break;\n }\n\n try {\n lastExitCode = await this.executeNode(node.body, stdinSource, stdout, stderr);\n } catch (e) {\n if (e instanceof ContinueException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n continue;\n }\n if (e instanceof BreakException) {\n if (e.levels > 1) {\n e.levels--;\n throw e;\n }\n break;\n }\n throw e;\n }\n }\n } finally {\n this.loopDepth--;\n }\n\n return lastExitCode;\n }\n\n private async executeCase(\n node: CaseNode,\n stdinSource: AsyncIterable<Uint8Array> | null,\n stdout: OutputCollector,\n stderr: OutputCollector\n ): Promise<number> {\n const word = await this.evaluateNode(node.word);\n\n for (const clause of node.clauses) {\n for (const patternNode of clause.patterns) {\n const pattern = await this.evaluateNode(patternNode);\n\n if (this.matchCasePattern(word, pattern)) {\n return this.executeNode(clause.body, stdinSource, stdout, stderr);\n }\n }\n }\n\n return 0;\n }\n\n private matchCasePattern(word: string, pattern: string): boolean {\n // Convert shell glob pattern to regex\n // * matches any string, ? matches any single character\n let regexStr = \"^\";\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n if (char === \"*\") {\n regexStr += \".*\";\n } else if (char === \"?\") {\n regexStr += \".\";\n } else if (char === \"[\") {\n // Character class - find closing bracket\n let j = i + 1;\n while (j < pattern.length && pattern[j] !== \"]\") {\n j++;\n }\n if (j < pattern.length) {\n regexStr += pattern.slice(i, j + 1);\n i = j;\n } else {\n regexStr += \"\\\\[\";\n }\n } else if (/[.+^${}()|\\\\]/.test(char!)) {\n // Escape regex special characters\n regexStr += \"\\\\\" + char;\n } else {\n regexStr += char;\n }\n }\n regexStr += \"$\";\n\n try {\n const regex = new RegExp(regexStr);\n return regex.test(word);\n } catch {\n // If regex fails, fall back to exact match\n return word === pattern;\n }\n }\n\n private async evaluateNode(node: ASTNode, localEnv?: Record<string, string>): Promise<string> {\n const env = localEnv ?? this.env;\n switch (node.type) {\n case \"literal\":\n return node.value;\n case \"variable\":\n return env[node.name] ?? \"\";\n case \"glob\":\n return node.pattern;\n case \"concat\": {\n const parts = await Promise.all(node.parts.map((p) => this.evaluateNode(p, localEnv)));\n return parts.join(\"\");\n }\n case \"substitution\": {\n // Execute the command and capture output\n const subStdout = createStdout();\n const subStderr = createStderr();\n await this.executeNode(node.command, null, subStdout, subStderr);\n subStdout.close();\n const output = await subStdout.collect();\n // Trim trailing newlines\n return output.toString(\"utf-8\").replace(/\\n+$/, \"\");\n }\n case \"arithmetic\": {\n const result = this.evaluateArithmetic(node.expression, env);\n return String(result);\n }\n default:\n throw new Error(`Cannot evaluate node type: ${node.type}`);\n }\n }\n\n private evaluateArithmetic(expression: string, env: Record<string, string>): number {\n // Expand variables in the expression\n let expandedExpr = expression;\n // Replace $VAR and ${VAR} with their values\n expandedExpr = expandedExpr.replace(/\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n expandedExpr = expandedExpr.replace(/\\$([a-zA-Z_][a-zA-Z0-9_]*)/g, (_, name) => {\n return env[name] ?? \"0\";\n });\n // Also handle bare variable names (in arithmetic, variables can be referenced without $)\n expandedExpr = expandedExpr.replace(/\\b([a-zA-Z_][a-zA-Z0-9_]*)\\b/g, (match) => {\n // Don't replace if it looks like a number\n if (/^\\d+$/.test(match)) return match;\n return env[match] ?? \"0\";\n });\n\n // Parse and evaluate the expression\n return this.parseArithmeticExpr(expandedExpr.trim());\n }\n\n private parseArithmeticExpr(expr: string): number {\n // Simple arithmetic expression parser\n // Supports: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, parentheses\n // Uses a simple recursive descent parser\n\n let pos = 0;\n\n const skipWhitespace = () => {\n while (pos < expr.length && /\\s/.test(expr[pos]!)) pos++;\n };\n\n const parseNumber = (): number => {\n skipWhitespace();\n let numStr = \"\";\n const negative = expr[pos] === \"-\";\n if (negative) {\n pos++;\n skipWhitespace();\n }\n while (pos < expr.length && /[0-9]/.test(expr[pos]!)) {\n numStr += expr[pos];\n pos++;\n }\n if (numStr === \"\") return 0;\n return negative ? -parseInt(numStr, 10) : parseInt(numStr, 10);\n };\n\n const parsePrimary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"(\") {\n pos++; // consume (\n const result = parseOr();\n skipWhitespace();\n if (expr[pos] === \")\") pos++; // consume )\n return result;\n }\n return parseNumber();\n };\n\n const parseUnary = (): number => {\n skipWhitespace();\n if (expr[pos] === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\")) {\n pos++;\n return -parseUnary();\n }\n if (expr[pos] === \"!\") {\n pos++;\n return parseUnary() === 0 ? 1 : 0;\n }\n return parsePrimary();\n };\n\n const parseMulDiv = (): number => {\n let left = parseUnary();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"*\" || op === \"/\" || op === \"%\") {\n pos++;\n const right = parseUnary();\n if (op === \"*\") left = left * right;\n else if (op === \"/\") left = right === 0 ? 0 : Math.trunc(left / right);\n else left = right === 0 ? 0 : left % right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAddSub = (): number => {\n let left = parseMulDiv();\n while (true) {\n skipWhitespace();\n const op = expr[pos];\n if (op === \"+\" || (op === \"-\" && !/[0-9]/.test(expr[pos + 1] ?? \"\"))) {\n pos++;\n const right = parseMulDiv();\n if (op === \"+\") left = left + right;\n else left = left - right;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseComparison = (): number => {\n let left = parseAddSub();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"<=\") {\n pos += 2;\n const right = parseAddSub();\n left = left <= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \">=\") {\n pos += 2;\n const right = parseAddSub();\n left = left >= right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"==\") {\n pos += 2;\n const right = parseAddSub();\n left = left === right ? 1 : 0;\n } else if (expr.slice(pos, pos + 2) === \"!=\") {\n pos += 2;\n const right = parseAddSub();\n left = left !== right ? 1 : 0;\n } else if (expr[pos] === \"<\") {\n pos++;\n const right = parseAddSub();\n left = left < right ? 1 : 0;\n } else if (expr[pos] === \">\") {\n pos++;\n const right = parseAddSub();\n left = left > right ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseAnd = (): number => {\n let left = parseComparison();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"&&\") {\n pos += 2;\n const right = parseComparison();\n left = (left !== 0 && right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n const parseOr = (): number => {\n let left = parseAnd();\n while (true) {\n skipWhitespace();\n if (expr.slice(pos, pos + 2) === \"||\") {\n pos += 2;\n const right = parseAnd();\n left = (left !== 0 || right !== 0) ? 1 : 0;\n } else {\n break;\n }\n }\n return left;\n };\n\n return parseOr();\n }\n\n setCwd(cwd: string): void {\n this.cwd = cwd;\n }\n\n setEnv(vars: Record<string, string>): void {\n Object.assign(this.env, vars);\n }\n\n getCwd(): string {\n return this.cwd;\n }\n\n getEnv(): Record<string, string> {\n return { ...this.env };\n }\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "75622AF9F6C7A68964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "FF91F2326D4DFFED64756E2164756E21",
9
9
  "names": []
10
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "A sandboxed shell-style DSL for running scriptable command pipelines in-process without host OS access",
5
5
  "author": "ricsam <oss@ricsam.dev>",
6
6
  "license": "MIT",