shell-dsl 0.0.23 → 0.0.25

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.
@@ -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 isTTY?: boolean;\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 private isTTY: boolean;\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 this.isTTY = options.isTTY ?? false;\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout(this.isTTY);\n const stderr = createStderr(this.isTTY);\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 setCwd: (path: string) => this.setCwd(path),\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.env.OLDPWD = this.cwd;\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 isTTY?: boolean;\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 private isTTY: boolean;\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 this.isTTY = options.isTTY ?? false;\n }\n\n getLoopDepth(): number {\n return this.loopDepth;\n }\n\n async execute(ast: ASTNode): Promise<ExecResult> {\n const stdout = createStdout(this.isTTY);\n const stderr = createStderr(this.isTTY);\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 exec closure for sub-command invocation\n const exec = async (cmdName: string, cmdArgs: string[]) => {\n const cmd = this.commands[cmdName];\n if (!cmd) {\n return {\n stdout: Buffer.alloc(0),\n stderr: Buffer.from(`${cmdName}: command not found\\n`),\n exitCode: 127,\n };\n }\n const subStdout = createStdout();\n const subStderr = createStderr();\n const subCtx = createCommandContext({\n args: cmdArgs,\n stdin: createStdin(null),\n stdout: subStdout,\n stderr: subStderr,\n fs: this.fs,\n cwd: this.cwd,\n env: { ...localEnv },\n setCwd: (path: string) => this.setCwd(path),\n exec,\n });\n let exitCode: number;\n try {\n exitCode = await cmd(subCtx);\n } catch (err) {\n if (err instanceof BreakException || err instanceof ContinueException) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n await subStderr.writeText(`${cmdName}: ${message}\\n`);\n exitCode = 1;\n }\n subStdout.close();\n subStderr.close();\n return {\n stdout: await subStdout.collect(),\n stderr: await subStderr.collect(),\n exitCode,\n };\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 setCwd: (path: string) => this.setCwd(path),\n exec,\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.env.OLDPWD = this.cwd;\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": "7B263C6315A30CB564756E2164756E21",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEqC,IAArC;AAC4B,IAA5B;AACgG,IAAhG;AAAA;AAcO,MAAM,uBAAuB,MAAM;AAAA,EACrB;AAAA,EAAnB,WAAW,CAAQ,SAAiB,GAAG;AAAA,IACrC,MAAM,OAAO;AAAA,IADI;AAAA;AAGrB;AAAA;AAEO,MAAM,0BAA0B,MAAM;AAAA,EACxB;AAAA,EAAnB,WAAW,CAAQ,SAAiB,GAAG;AAAA,IACrC,MAAM,UAAU;AAAA,IADC;AAAA;AAGrB;AAAA;AAEO,MAAM,YAAY;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAoB;AAAA,EACpB;AAAA,EAER,WAAW,CAAC,SAA6B;AAAA,IACvC,KAAK,KAAK,QAAQ;AAAA,IAClB,KAAK,MAAM,QAAQ;AAAA,IACnB,KAAK,MAAM,KAAK,QAAQ,IAAI;AAAA,IAC5B,KAAK,WAAW,QAAQ;AAAA,IACxB,KAAK,kBAAkB,QAAQ,mBAAmB,CAAC;AAAA,IACnD,KAAK,QAAQ,QAAQ,SAAS;AAAA;AAAA,EAGhC,YAAY,GAAW;AAAA,IACrB,OAAO,KAAK;AAAA;AAAA,OAGR,QAAO,CAAC,KAAmC;AAAA,IAC/C,MAAM,SAAS,2BAAa,KAAK,KAAK;AAAA,IACtC,MAAM,SAAS,2BAAa,KAAK,KAAK;AAAA,IAEtC,MAAM,WAAW,MAAM,KAAK,YAAY,KAAK,MAAM,QAAQ,MAAM;AAAA,IAEjE,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IAEb,OAAO;AAAA,MACL,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7B,QAAQ,MAAM,OAAO,QAAQ;AAAA,MAC7B;AAAA,IACF;AAAA;AAAA,OAGY,YAAW,CACvB,MACA,aACA,QACA,QACiB;AAAA,IACjB,QAAQ,KAAK;AAAA,WACN;AAAA,QACH,OAAO,KAAK,eAAe,MAAM,aAAa,QAAQ,MAAM;AAAA,WACzD;AAAA,QACH,OAAO,KAAK,gBAAgB,KAAK,UAAU,aAAa,QAAQ,MAAM;AAAA,WACnE;AAAA,QACH,OAAO,KAAK,gBAAgB,KAAK,UAAU,aAAa,QAAQ,MAAM;AAAA,WACnE;AAAA,QACH,OAAO,KAAK,WAAW,KAAK,MAAM,KAAK,OAAO,aAAa,QAAQ,MAAM;AAAA,WACtE;AAAA,QACH,OAAO,KAAK,UAAU,KAAK,MAAM,KAAK,OAAO,aAAa,QAAQ,MAAM;AAAA,WACrE;AAAA,QACH,OAAO,KAAK,UAAU,MAAM,aAAa,QAAQ,MAAM;AAAA,WACpD;AAAA,QACH,OAAO,KAAK,WAAW,MAAM,aAAa,QAAQ,MAAM;AAAA,WACrD;AAAA,QACH,OAAO,KAAK,aAAa,MAAM,aAAa,QAAQ,MAAM;AAAA,WACvD;AAAA,QACH,OAAO,KAAK,aAAa,MAAM,aAAa,QAAQ,MAAM;AAAA,WACvD;AAAA,QACH,OAAO,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA;AAAA,QAEzD,MAAM,IAAI,MAAM,6BAA6B,KAAK,MAAM;AAAA;AAAA;AAAA,OAIhD,eAAc,CAC1B,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,WAAW,KAAK,KAAK,IAAI;AAAA,IAC/B,WAAW,cAAc,KAAK,aAAa;AAAA,MACzC,SAAS,WAAW,QAAQ,MAAM,KAAK,aAAa,WAAW,KAAK;AAAA,IACtE;AAAA,IAGA,MAAM,OAAO,MAAM,KAAK,aAAa,KAAK,IAAI;AAAA,IAC9C,IAAI,SAAS,MAAM,KAAK,YAAY,SAAS,GAAG;AAAA,MAC9C,WAAW,cAAc,KAAK,aAAa;AAAA,QACzC,KAAK,IAAI,WAAW,QAAQ,MAAM,KAAK,aAAa,WAAW,KAAK;AAAA,MACtE;AAAA,MACA,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,OAAiB,CAAC;AAAA,IACxB,WAAW,OAAO,KAAK,MAAM;AAAA,MAC3B,MAAM,YAAY,MAAM,KAAK,aAAa,KAAK,QAAQ;AAAA,MAEvD,IAAI,IAAI,SAAS,QAAQ;AAAA,QACvB,MAAM,UAAU,MAAM,KAAK,GAAG,KAAK,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,QAC/D,IAAI,QAAQ,SAAS,GAAG;AAAA,UACtB,KAAK,KAAK,GAAG,OAAO;AAAA,QACtB,EAAO;AAAA,UAEL,KAAK,KAAK,SAAS;AAAA;AAAA,MAEvB,EAAO;AAAA,QACL,KAAK,KAAK,SAAS;AAAA;AAAA,IAEvB;AAAA,IAGA,IAAI,cAAc;AAAA,IAClB,IAAI,eAAgC;AAAA,IACpC,IAAI,eAAgC;AAAA,IACpC,IAAI,iBAAiB;AAAA,IACrB,IAAI,iBAAiB;AAAA,IACrB,MAAM,oBAAqC,CAAC;AAAA,IAE5C,WAAW,YAAY,KAAK,WAAW;AAAA,MACrC,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,KAAK,eACxB,UACA,aACA,cACA,YACF;AAAA,QACA,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO;AAAA,QACtB,eAAe,OAAO;AAAA,QACtB,iBAAiB,OAAO,kBAAkB;AAAA,QAC1C,iBAAiB,OAAO,kBAAkB;AAAA,QAC1C,IAAI,OAAO,kBAAkB;AAAA,UAC3B,kBAAkB,KAAK,OAAO,gBAAgB;AAAA,QAChD;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,MAAM,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM;AAAA,QACtD,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,OAAO,UAAU,OAAO,WAAW;AAAA,CAAW;AAAA,QACpD,OAAO;AAAA;AAAA,IAEX;AAAA,IAGA,IAAI,gBAAgB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,IACA,IAAI,gBAAgB;AAAA,MAClB,eAAe;AAAA,IACjB;AAAA,IAGA,MAAM,UAAU,KAAK,SAAS;AAAA,IAC9B,IAAI,CAAC,SAAS;AAAA,MACZ,MAAM,OAAO,UAAU,GAAG;AAAA,CAA2B;AAAA,MACrD,OAAO;AAAA,IACT;AAAA,IAGA,MAAM,OAAO,OAAO,SAAiB,YAAsB;AAAA,MACzD,MAAM,MAAM,KAAK,SAAS;AAAA,MAC1B,IAAI,CAAC,KAAK;AAAA,QACR,OAAO;AAAA,UACL,QAAQ,OAAO,MAAM,CAAC;AAAA,UACtB,QAAQ,OAAO,KAAK,GAAG;AAAA,CAA8B;AAAA,UACrD,UAAU;AAAA,QACZ;AAAA,MACF;AAAA,MACA,MAAM,YAAY,2BAAa;AAAA,MAC/B,MAAM,YAAY,2BAAa;AAAA,MAC/B,MAAM,SAAS,oCAAqB;AAAA,QAClC,MAAM;AAAA,QACN,OAAO,yBAAY,IAAI;AAAA,QACvB,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,IAAI,KAAK;AAAA,QACT,KAAK,KAAK;AAAA,QACV,KAAK,KAAK,SAAS;AAAA,QACnB,QAAQ,CAAC,SAAiB,KAAK,OAAO,IAAI;AAAA,QAC1C;AAAA,MACF,CAAC;AAAA,MACD,IAAI;AAAA,MACJ,IAAI;AAAA,QACF,YAAW,MAAM,IAAI,MAAM;AAAA,QAC3B,OAAO,KAAK;AAAA,QACZ,IAAI,eAAe,kBAAkB,eAAe,mBAAmB;AAAA,UACrE,MAAM;AAAA,QACR;AAAA,QACA,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QAC/D,MAAM,UAAU,UAAU,GAAG,YAAY;AAAA,CAAW;AAAA,QACpD,YAAW;AAAA;AAAA,MAEb,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,OAAO;AAAA,QACL,QAAQ,MAAM,UAAU,QAAQ;AAAA,QAChC,QAAQ,MAAM,UAAU,QAAQ;AAAA,QAChC;AAAA,MACF;AAAA;AAAA,IAIF,MAAM,MAAM,oCAAqB;AAAA,MAC/B;AAAA,MACA,OAAO,yBAAY,WAAW;AAAA,MAC9B,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,IAAI,KAAK;AAAA,MACT,KAAK,KAAK;AAAA,MACV,KAAK;AAAA,MACL,QAAQ,CAAC,SAAiB,KAAK,OAAO,IAAI;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,QAAQ,GAAG;AAAA,MAC5B,OAAO,KAAK;AAAA,MAEZ,IAAI,eAAe,kBAAkB,eAAe,mBAAmB;AAAA,QACrE,MAAM;AAAA,MACR;AAAA,MACA,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,OAAO,UAAU,GAAG,SAAS;AAAA,CAAW;AAAA,MAC9C,WAAW;AAAA;AAAA,IAIb,IAAI,iBAAiB,QAAQ;AAAA,MAC3B,aAAa,MAAM;AAAA,IACrB;AAAA,IACA,IAAI,iBAAiB,UAAU,iBAAiB,cAAc;AAAA,MAC5D,aAAa,MAAM;AAAA,IACrB;AAAA,IAGA,IAAI;AAAA,MACF,MAAM,QAAQ,IAAI,iBAAiB;AAAA,MACnC,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAE/D,MAAM,iBAAiB,KAAK,UAAU,OAAO,OAAK,EAAE,SAAS,OAAO,EAAE,SAAS,UAAU,EAAE,SAAS,MAAM;AAAA,MAC1G,MAAM,SAAS,eAAe,SAAS,IACnC,MAAM,KAAK,aAAa,eAAe,eAAe,SAAS,GAAI,MAAM,IACzE;AAAA,MACJ,MAAM,OAAO,UAAU,OAAO,WAAW;AAAA,CAAW;AAAA,MACpD,WAAW;AAAA;AAAA,IAGb,OAAO;AAAA;AAAA,OAGK,eAAc,CAC1B,UACA,OACA,QACA,QAQC;AAAA,IACD,MAAM,SAAS,MAAM,KAAK,aAAa,SAAS,MAAM;AAAA,IAGtD,IAAI,UAAU,KAAK,iBAAiB;AAAA,MAClC,OAAO,KAAK,qBAAqB,SAAS,MAAM,KAAK,gBAAgB,SAAU,OAAO,QAAQ,MAAM;AAAA,IACtG;AAAA,IAEA,QAAQ,SAAS;AAAA,WACV,KAAK;AAAA,QACR,IAAI,SAAS,gBAAgB;AAAA,UAE3B,OAAO;AAAA,YACL,OAAQ,gBAAgB,GAAG;AAAA,cACzB,MAAM,IAAI,YAAY,EAAE,OAAO,MAAM;AAAA,cACpC;AAAA,YACH;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO;AAAA,YACL,OAAQ,gBAAgB,GAAG,GAAI;AAAA,YAC/B;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QAEA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,UAAU,MAAM,KAAK,GAAG,SAAS,IAAI;AAAA,QAC3C,OAAO;AAAA,UACL,OAAQ,gBAAgB,GAAG;AAAA,YACzB,MAAM,IAAI,WAAW,OAAO;AAAA,YAC3B;AAAA,UACH;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,WACK,KAAK;AAAA,QAER,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,WAAW,iBAAiB;AAAA,MAC9D;AAAA,WACK,OAAO;AAAA,QAEV,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,QAC5C;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,WAAW,iBAAiB;AAAA,MAC9D;AAAA,WACK,MAAM;AAAA,QAET,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,QACvD;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,UAAU,MAAM,IAAI;AAAA,WACjC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,WAAW,iBAAiB;AAAA,MACzE;AAAA,WACK,OAAO;AAAA,QAEV,MAAM,YAAY,2BAAa;AAAA,QAC/B,IAAI,WAAW,aAAa;AAAA,UAC1B,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,QACvD;AAAA,QACA,MAAM,OAAO,KAAK,GAAG,QAAQ,KAAK,KAAK,MAAM;AAAA,QAC7C,MAAM,oBAAoB,YAAY;AAAA,UACpC,MAAM,OAAO,MAAM,UAAU,QAAQ;AAAA,UACrC,MAAM,KAAK,GAAG,WAAW,MAAM,IAAI;AAAA,WAClC;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,WAAW,iBAAiB;AAAA,MACzE;AAAA,WACK;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,gBAAgB,KAAK;AAAA,WAClD;AAAA,QACH,OAAO,EAAE,OAAO,QAAQ,QAAQ,gBAAgB,KAAK;AAAA;AAAA,QAErD,OAAO,EAAE,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,OAIvB,qBAAoB,CAChC,MACA,KACA,OACA,QACA,QAQC;AAAA,IACD,QAAQ;AAAA,WACD,KAAK;AAAA,QAER,MAAM,OAAO,MAAM,KAAK,eAAe,GAAG;AAAA,QAC1C,OAAO;AAAA,UACL,OAAQ,gBAAgB,GAAG;AAAA,YACzB,MAAM;AAAA,YACL;AAAA,UACH;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,WACK;AAAA,WACA,MAAM;AAAA,QAET,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,WAAW,OAAO;AAAA,MAC5C;AAAA,WACK;AAAA,WACA,OAAO;AAAA,QAEV,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,QAAQ,UAAU;AAAA,MAC5C;AAAA,WACK;AAAA,WACA,OAAO;AAAA,QAEV,IAAI,CAAC,OAAO,SAAS,GAAG,GAAG;AAAA,UACzB,MAAM,IAAI,MAAM,mDAAmD;AAAA,QACrE;AAAA,QACA,MAAM,YAAY,0CAA4B,GAAG;AAAA,QACjD,OAAO,EAAE,OAAO,QAAQ,WAAW,QAAQ,UAAU;AAAA,MACvD;AAAA;AAAA,QAEE,OAAO,EAAE,OAAO,QAAQ,OAAO;AAAA;AAAA;AAAA,OAIvB,eAAc,CAAC,KAA6D;AAAA,IACxF,IAAI,OAAO,SAAS,GAAG,GAAG;AAAA,MACxB,OAAO,IAAI,WAAW,GAAG;AAAA,IAC3B;AAAA,IACA,IAAI,eAAe,MAAM;AAAA,MACvB,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IAC/C;AAAA,IACA,IAAI,eAAe,UAAU;AAAA,MAC3B,OAAO,IAAI,WAAW,MAAM,IAAI,YAAY,CAAC;AAAA,IAC/C;AAAA,IACA,IAAI,OAAO,QAAQ,UAAU;AAAA,MAC3B,OAAO,IAAI,YAAY,EAAE,OAAO,GAAG;AAAA,IACrC;AAAA,IACA,MAAM,IAAI,MAAM,kCAAkC;AAAA;AAAA,OAGtC,gBAAe,CAC3B,UACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,SAAS,WAAW;AAAA,MAAG,OAAO;AAAA,IAClC,IAAI,SAAS,WAAW,GAAG;AAAA,MACzB,OAAO,KAAK,YAAY,SAAS,IAAK,aAAa,QAAQ,MAAM;AAAA,IACnE;AAAA,IAGA,MAAM,QAAsB,CAAC;AAAA,IAC7B,SAAS,IAAI,EAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAAA,MAC5C,MAAM,KAAK,yBAAW,CAAC;AAAA,IACzB;AAAA,IAGA,MAAM,WAA8B,CAAC;AAAA,IAErC,SAAS,IAAI,EAAG,IAAI,SAAS,QAAQ,KAAK;AAAA,MACxC,MAAM,UAAU,SAAS;AAAA,MACzB,MAAM,WAAW,MAAM,IAAI,cAAc,MAAM,IAAI,GAAI,kBAAkB;AAAA,MACzE,MAAM,YAAY,MAAM,SAAS,SAAS,IAAI,SAAS,MAAM;AAAA,MAE7D,SAAS,KACP,KAAK,YAAY,SAAS,UAAU,WAAW,MAAM,EAAE,KAAK,CAAC,SAAS;AAAA,QAEpE,IAAI,IAAI,SAAS,SAAS,GAAG;AAAA,UAC3B,MAAM,GAAI,MAAM;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,OACR,CACH;AAAA,IACF;AAAA,IAGA,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ;AAAA,IAC1C,OAAO,QAAQ,QAAQ,SAAS;AAAA;AAAA,OAGpB,gBAAe,CAC3B,UACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IAEnB,WAAW,WAAW,UAAU;AAAA,MAC9B,eAAe,MAAM,KAAK,YAAY,SAAS,aAAa,QAAQ,MAAM;AAAA,IAC5E;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,WAAU,CACtB,MACA,OACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,WAAW,MAAM,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA,IACzE,IAAI,aAAa,GAAG;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,OAAO,KAAK,YAAY,OAAO,aAAa,QAAQ,MAAM;AAAA;AAAA,OAG9C,UAAS,CACrB,MACA,OACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,WAAW,MAAM,KAAK,YAAY,MAAM,aAAa,QAAQ,MAAM;AAAA,IACzE,IAAI,aAAa,GAAG;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,IACA,OAAO,KAAK,YAAY,OAAO,aAAa,QAAQ,MAAM;AAAA;AAAA,OAG9C,UAAS,CACrB,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,IAExF,IAAI,kBAAkB,GAAG;AAAA,MAEvB,OAAO,KAAK,YAAY,KAAK,YAAY,aAAa,QAAQ,MAAM;AAAA,IACtE;AAAA,IAGA,WAAW,QAAQ,KAAK,cAAc;AAAA,MACpC,MAAM,oBAAoB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,MAC5F,IAAI,sBAAsB,GAAG;AAAA,QAC3B,OAAO,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,IAGA,IAAI,KAAK,YAAY;AAAA,MACnB,OAAO,KAAK,YAAY,KAAK,YAAY,aAAa,QAAQ,MAAM;AAAA,IACtE;AAAA,IAEA,OAAO;AAAA;AAAA,OAGK,WAAU,CACtB,MACA,aACA,QACA,QACiB;AAAA,IAEjB,MAAM,gBAA0B,CAAC;AAAA,IACjC,WAAW,QAAQ,KAAK,OAAO;AAAA,MAC7B,MAAM,YAAY,MAAM,KAAK,aAAa,IAAI;AAAA,MAC9C,IAAI,KAAK,SAAS,QAAQ;AAAA,QACxB,MAAM,UAAU,MAAM,KAAK,GAAG,KAAK,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC;AAAA,QAC/D,IAAI,QAAQ,SAAS,GAAG;AAAA,UACtB,cAAc,KAAK,GAAG,OAAO;AAAA,QAC/B,EAAO;AAAA,UACL,cAAc,KAAK,SAAS;AAAA;AAAA,MAEhC,EAAO;AAAA,QACL,cAAc,KAAK,SAAS;AAAA;AAAA,IAEhC;AAAA,IAGA,IAAI,cAAc,WAAW,GAAG;AAAA,MAC9B,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,WAAW,SAAS,eAAe;AAAA,QAEjC,KAAK,IAAI,KAAK,YAAY;AAAA,QAE1B,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,aAAY,CACxB,MACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,OAAO,MAAM;AAAA,QAEX,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,QACxF,IAAI,kBAAkB,GAAG;AAAA,UACvB;AAAA,QACF;AAAA,QAEA,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,aAAY,CACxB,MACA,aACA,QACA,QACiB;AAAA,IACjB,IAAI,eAAe;AAAA,IACnB,KAAK;AAAA,IAEL,IAAI;AAAA,MACF,OAAO,MAAM;AAAA,QAEX,MAAM,gBAAgB,MAAM,KAAK,YAAY,KAAK,WAAW,aAAa,QAAQ,MAAM;AAAA,QACxF,IAAI,kBAAkB,GAAG;AAAA,UACvB;AAAA,QACF;AAAA,QAEA,IAAI;AAAA,UACF,eAAe,MAAM,KAAK,YAAY,KAAK,MAAM,aAAa,QAAQ,MAAM;AAAA,UAC5E,OAAO,GAAG;AAAA,UACV,IAAI,aAAa,mBAAmB;AAAA,YAClC,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,IAAI,aAAa,gBAAgB;AAAA,YAC/B,IAAI,EAAE,SAAS,GAAG;AAAA,cAChB,EAAE;AAAA,cACF,MAAM;AAAA,YACR;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM;AAAA;AAAA,MAEV;AAAA,cACA;AAAA,MACA,KAAK;AAAA;AAAA,IAGP,OAAO;AAAA;AAAA,OAGK,YAAW,CACvB,MACA,aACA,QACA,QACiB;AAAA,IACjB,MAAM,OAAO,MAAM,KAAK,aAAa,KAAK,IAAI;AAAA,IAE9C,WAAW,UAAU,KAAK,SAAS;AAAA,MACjC,WAAW,eAAe,OAAO,UAAU;AAAA,QACzC,MAAM,UAAU,MAAM,KAAK,aAAa,WAAW;AAAA,QAEnD,IAAI,KAAK,iBAAiB,MAAM,OAAO,GAAG;AAAA,UACxC,OAAO,KAAK,YAAY,OAAO,MAAM,aAAa,QAAQ,MAAM;AAAA,QAClE;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,EAGD,gBAAgB,CAAC,MAAc,SAA0B;AAAA,IAG/D,IAAI,WAAW;AAAA,IACf,SAAS,IAAI,EAAG,IAAI,QAAQ,QAAQ,KAAK;AAAA,MACvC,MAAM,OAAO,QAAQ;AAAA,MACrB,IAAI,SAAS,KAAK;AAAA,QAChB,YAAY;AAAA,MACd,EAAO,SAAI,SAAS,KAAK;AAAA,QACvB,YAAY;AAAA,MACd,EAAO,SAAI,SAAS,KAAK;AAAA,QAEvB,IAAI,IAAI,IAAI;AAAA,QACZ,OAAO,IAAI,QAAQ,UAAU,QAAQ,OAAO,KAAK;AAAA,UAC/C;AAAA,QACF;AAAA,QACA,IAAI,IAAI,QAAQ,QAAQ;AAAA,UACtB,YAAY,QAAQ,MAAM,GAAG,IAAI,CAAC;AAAA,UAClC,IAAI;AAAA,QACN,EAAO;AAAA,UACL,YAAY;AAAA;AAAA,MAEhB,EAAO,SAAI,gBAAgB,KAAK,IAAK,GAAG;AAAA,QAEtC,YAAY,OAAO;AAAA,MACrB,EAAO;AAAA,QACL,YAAY;AAAA;AAAA,IAEhB;AAAA,IACA,YAAY;AAAA,IAEZ,IAAI;AAAA,MACF,MAAM,QAAQ,IAAI,OAAO,QAAQ;AAAA,MACjC,OAAO,MAAM,KAAK,IAAI;AAAA,MACtB,MAAM;AAAA,MAEN,OAAO,SAAS;AAAA;AAAA;AAAA,OAIN,aAAY,CAAC,MAAe,UAAoD;AAAA,IAC5F,MAAM,MAAM,YAAY,KAAK;AAAA,IAC7B,QAAQ,KAAK;AAAA,WACN;AAAA,QACH,OAAO,KAAK;AAAA,WACT;AAAA,QACH,OAAO,IAAI,KAAK,SAAS;AAAA,WACtB;AAAA,QACH,OAAO,KAAK;AAAA,WACT,UAAU;AAAA,QACb,MAAM,QAAQ,MAAM,QAAQ,IAAI,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK,aAAa,GAAG,QAAQ,CAAC,CAAC;AAAA,QACrF,OAAO,MAAM,KAAK,EAAE;AAAA,MACtB;AAAA,WACK,gBAAgB;AAAA,QAEnB,MAAM,YAAY,2BAAa;AAAA,QAC/B,MAAM,YAAY,2BAAa;AAAA,QAC/B,MAAM,KAAK,YAAY,KAAK,SAAS,MAAM,WAAW,SAAS;AAAA,QAC/D,UAAU,MAAM;AAAA,QAChB,MAAM,SAAS,MAAM,UAAU,QAAQ;AAAA,QAEvC,OAAO,OAAO,SAAS,OAAO,EAAE,QAAQ,QAAQ,EAAE;AAAA,MACpD;AAAA,WACK,cAAc;AAAA,QACjB,MAAM,SAAS,KAAK,mBAAmB,KAAK,YAAY,GAAG;AAAA,QAC3D,OAAO,OAAO,MAAM;AAAA,MACtB;AAAA;AAAA,QAEE,MAAM,IAAI,MAAM,8BAA8B,KAAK,MAAM;AAAA;AAAA;AAAA,EAIvD,kBAAkB,CAAC,YAAoB,KAAqC;AAAA,IAElF,IAAI,eAAe;AAAA,IAEnB,eAAe,aAAa,QAAQ,mCAAmC,CAAC,GAAG,SAAS;AAAA,MAClF,OAAO,IAAI,SAAS;AAAA,KACrB;AAAA,IACD,eAAe,aAAa,QAAQ,+BAA+B,CAAC,GAAG,SAAS;AAAA,MAC9E,OAAO,IAAI,SAAS;AAAA,KACrB;AAAA,IAED,eAAe,aAAa,QAAQ,iCAAiC,CAAC,UAAU;AAAA,MAE9E,IAAI,QAAQ,KAAK,KAAK;AAAA,QAAG,OAAO;AAAA,MAChC,OAAO,IAAI,UAAU;AAAA,KACtB;AAAA,IAGD,OAAO,KAAK,oBAAoB,aAAa,KAAK,CAAC;AAAA;AAAA,EAG7C,mBAAmB,CAAC,MAAsB;AAAA,IAKhD,IAAI,MAAM;AAAA,IAEV,MAAM,iBAAiB,MAAM;AAAA,MAC3B,OAAO,MAAM,KAAK,UAAU,KAAK,KAAK,KAAK,IAAK;AAAA,QAAG;AAAA;AAAA,IAGrD,MAAM,cAAc,MAAc;AAAA,MAChC,eAAe;AAAA,MACf,IAAI,SAAS;AAAA,MACb,MAAM,WAAW,KAAK,SAAS;AAAA,MAC/B,IAAI,UAAU;AAAA,QACZ;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,MACA,OAAO,MAAM,KAAK,UAAU,QAAQ,KAAK,KAAK,IAAK,GAAG;AAAA,QACpD,UAAU,KAAK;AAAA,QACf;AAAA,MACF;AAAA,MACA,IAAI,WAAW;AAAA,QAAI,OAAO;AAAA,MAC1B,OAAO,WAAW,CAAC,SAAS,QAAQ,EAAE,IAAI,SAAS,QAAQ,EAAE;AAAA;AAAA,IAG/D,MAAM,eAAe,MAAc;AAAA,MACjC,eAAe;AAAA,MACf,IAAI,KAAK,SAAS,KAAK;AAAA,QACrB;AAAA,QACA,MAAM,SAAS,QAAQ;AAAA,QACvB,eAAe;AAAA,QACf,IAAI,KAAK,SAAS;AAAA,UAAK;AAAA,QACvB,OAAO;AAAA,MACT;AAAA,MACA,OAAO,YAAY;AAAA;AAAA,IAGrB,MAAM,aAAa,MAAc;AAAA,MAC/B,eAAe;AAAA,MACf,IAAI,KAAK,SAAS,OAAO,CAAC,QAAQ,KAAK,KAAK,MAAM,MAAM,EAAE,GAAG;AAAA,QAC3D;AAAA,QACA,OAAO,CAAC,WAAW;AAAA,MACrB;AAAA,MACA,IAAI,KAAK,SAAS,KAAK;AAAA,QACrB;AAAA,QACA,OAAO,WAAW,MAAM,IAAI,IAAI;AAAA,MAClC;AAAA,MACA,OAAO,aAAa;AAAA;AAAA,IAGtB,MAAM,cAAc,MAAc;AAAA,MAChC,IAAI,OAAO,WAAW;AAAA,MACtB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,MAAM,KAAK,KAAK;AAAA,QAChB,IAAI,OAAO,OAAO,OAAO,OAAO,OAAO,KAAK;AAAA,UAC1C;AAAA,UACA,MAAM,QAAQ,WAAW;AAAA,UACzB,IAAI,OAAO;AAAA,YAAK,OAAO,OAAO;AAAA,UACzB,SAAI,OAAO;AAAA,YAAK,OAAO,UAAU,IAAI,IAAI,KAAK,MAAM,OAAO,KAAK;AAAA,UAChE;AAAA,mBAAO,UAAU,IAAI,IAAI,OAAO;AAAA,QACvC,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,cAAc,MAAc;AAAA,MAChC,IAAI,OAAO,YAAY;AAAA,MACvB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,MAAM,KAAK,KAAK;AAAA,QAChB,IAAI,OAAO,OAAQ,OAAO,OAAO,CAAC,QAAQ,KAAK,KAAK,MAAM,MAAM,EAAE,GAAI;AAAA,UACpE;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,IAAI,OAAO;AAAA,YAAK,OAAO,OAAO;AAAA,UACzB;AAAA,mBAAO,OAAO;AAAA,QACrB,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,kBAAkB,MAAc;AAAA,MACpC,IAAI,OAAO,YAAY;AAAA,MACvB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,QAAQ,QAAQ,IAAI;AAAA,QAC7B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,QAAQ,QAAQ,IAAI;AAAA,QAC7B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,SAAS,QAAQ,IAAI;AAAA,QAC9B,EAAO,SAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UAC5C,OAAO;AAAA,UACP,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,SAAS,QAAQ,IAAI;AAAA,QAC9B,EAAO,SAAI,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,OAAO,QAAQ,IAAI;AAAA,QAC5B,EAAO,SAAI,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,MAAM,QAAQ,YAAY;AAAA,UAC1B,OAAO,OAAO,QAAQ,IAAI;AAAA,QAC5B,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,WAAW,MAAc;AAAA,MAC7B,IAAI,OAAO,gBAAgB;AAAA,MAC3B,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,gBAAgB;AAAA,UAC9B,OAAQ,SAAS,KAAK,UAAU,IAAK,IAAI;AAAA,QAC3C,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,MAAM,UAAU,MAAc;AAAA,MAC5B,IAAI,OAAO,SAAS;AAAA,MACpB,OAAO,MAAM;AAAA,QACX,eAAe;AAAA,QACf,IAAI,KAAK,MAAM,KAAK,MAAM,CAAC,MAAM,MAAM;AAAA,UACrC,OAAO;AAAA,UACP,MAAM,QAAQ,SAAS;AAAA,UACvB,OAAQ,SAAS,KAAK,UAAU,IAAK,IAAI;AAAA,QAC3C,EAAO;AAAA,UACL;AAAA;AAAA,MAEJ;AAAA,MACA,OAAO;AAAA;AAAA,IAGT,OAAO,QAAQ;AAAA;AAAA,EAGjB,MAAM,CAAC,KAAmB;AAAA,IACxB,KAAK,IAAI,SAAS,KAAK;AAAA,IACvB,KAAK,MAAM;AAAA;AAAA,EAGb,MAAM,CAAC,MAAoC;AAAA,IACzC,OAAO,OAAO,KAAK,KAAK,IAAI;AAAA;AAAA,EAG9B,MAAM,GAAW;AAAA,IACf,OAAO,KAAK;AAAA;AAAA,EAGd,MAAM,GAA2B;AAAA,IAC/B,OAAO,KAAK,KAAK,IAAI;AAAA;AAEzB;",
8
+ "debugId": "7AEBF15FDBC0001B64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/types.ts"],
4
4
  "sourcesContent": [
5
- "// Virtual Filesystem Interface\nexport interface VirtualFS {\n readFile(path: string): Promise<Buffer>;\n readdir(path: string): Promise<string[]>;\n stat(path: string): Promise<FileStat>;\n exists(path: string): Promise<boolean>;\n\n writeFile(path: string, data: Buffer | string): Promise<void>;\n appendFile(path: string, data: Buffer | string): Promise<void>;\n mkdir(path: string, opts?: { recursive?: boolean }): Promise<void>;\n\n rm(path: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void>;\n\n resolve(...paths: string[]): string;\n dirname(path: string): string;\n basename(path: string): string;\n glob(pattern: string, opts?: { cwd?: string }): Promise<string[]>;\n}\n\nexport interface FileStat {\n isFile(): boolean;\n isDirectory(): boolean;\n size: number;\n mtime: Date;\n}\n\n// Command Interfaces\nexport type Command = (ctx: CommandContext) => Promise<number>;\n\nexport interface CommandContext {\n args: string[];\n stdin: Stdin;\n stdout: Stdout;\n stderr: Stderr;\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n setCwd: (path: string) => void;\n}\n\nexport interface Stdin {\n stream(): AsyncIterable<Uint8Array>;\n buffer(): Promise<Buffer>;\n text(): Promise<string>;\n lines(): AsyncIterable<string>;\n}\n\nexport interface Stdout {\n write(chunk: Uint8Array): Promise<void>;\n writeText(str: string): Promise<void>;\n isTTY: boolean;\n}\n\nexport interface Stderr {\n write(chunk: Uint8Array): Promise<void>;\n writeText(str: string): Promise<void>;\n isTTY: boolean;\n}\n\nexport interface OutputCollector extends Stdout {\n close(): void;\n collect(): Promise<Buffer>;\n getReadableStream(): AsyncIterable<Uint8Array>;\n}\n\n// Execution Result\nexport interface ExecResult {\n stdout: Buffer;\n stderr: Buffer;\n exitCode: number;\n}\n\n// Shell Configuration\nexport interface ShellConfig {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n isTTY?: boolean;\n}\n\n// Raw escape hatch type\nexport interface RawValue {\n raw: string;\n}\n\nexport function isRawValue(value: unknown): value is RawValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"raw\" in value &&\n typeof (value as RawValue).raw === \"string\"\n );\n}\n\n// JS Object Redirection types\nexport type RedirectObject = Buffer | Blob | Response | string;\n\nexport interface RedirectObjectMap {\n [marker: string]: RedirectObject;\n}\n\nexport function isRedirectObject(value: unknown): value is RedirectObject {\n return (\n Buffer.isBuffer(value) ||\n value instanceof Blob ||\n value instanceof Response ||\n typeof value === \"string\"\n );\n}\n"
5
+ "// Virtual Filesystem Interface\nexport interface VirtualFS {\n readFile(path: string): Promise<Buffer>;\n readFile(path: string, encoding: BufferEncoding): Promise<string>;\n readdir(path: string): Promise<string[]>;\n stat(path: string): Promise<FileStat>;\n exists(path: string): Promise<boolean>;\n\n writeFile(path: string, data: Buffer | string): Promise<void>;\n appendFile(path: string, data: Buffer | string): Promise<void>;\n mkdir(path: string, opts?: { recursive?: boolean }): Promise<void>;\n\n rm(path: string, opts?: { recursive?: boolean; force?: boolean }): Promise<void>;\n\n resolve(...paths: string[]): string;\n dirname(path: string): string;\n basename(path: string): string;\n glob(pattern: string, opts?: { cwd?: string }): Promise<string[]>;\n}\n\nexport interface FileStat {\n isFile(): boolean;\n isDirectory(): boolean;\n size: number;\n mtime: Date;\n}\n\n// Command Interfaces\nexport type Command = (ctx: CommandContext) => Promise<number>;\n\nexport interface CommandContext {\n args: string[];\n stdin: Stdin;\n stdout: Stdout;\n stderr: Stderr;\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n setCwd: (path: string) => void;\n exec?: (name: string, args: string[]) => Promise<ExecResult>;\n}\n\nexport interface Stdin {\n stream(): AsyncIterable<Uint8Array>;\n buffer(): Promise<Buffer>;\n text(): Promise<string>;\n lines(): AsyncIterable<string>;\n}\n\nexport interface Stdout {\n write(chunk: Uint8Array): Promise<void>;\n writeText(str: string): Promise<void>;\n isTTY: boolean;\n}\n\nexport interface Stderr {\n write(chunk: Uint8Array): Promise<void>;\n writeText(str: string): Promise<void>;\n isTTY: boolean;\n}\n\nexport interface OutputCollector extends Stdout {\n close(): void;\n collect(): Promise<Buffer>;\n getReadableStream(): AsyncIterable<Uint8Array>;\n}\n\n// Execution Result\nexport interface ExecResult {\n stdout: Buffer;\n stderr: Buffer;\n exitCode: number;\n}\n\n// Shell Configuration\nexport interface ShellConfig {\n fs: VirtualFS;\n cwd: string;\n env: Record<string, string>;\n commands: Record<string, Command>;\n isTTY?: boolean;\n}\n\n// Raw escape hatch type\nexport interface RawValue {\n raw: string;\n}\n\nexport function isRawValue(value: unknown): value is RawValue {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"raw\" in value &&\n typeof (value as RawValue).raw === \"string\"\n );\n}\n\n// JS Object Redirection types\nexport type RedirectObject = Buffer | Blob | Response | string;\n\nexport interface RedirectObjectMap {\n [marker: string]: RedirectObject;\n}\n\nexport function isRedirectObject(value: unknown): value is RedirectObject {\n return (\n Buffer.isBuffer(value) ||\n value instanceof Blob ||\n value instanceof Response ||\n typeof value === \"string\"\n );\n}\n"
6
6
  ],
7
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsFO,SAAS,UAAU,CAAC,OAAmC;AAAA,EAC5D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,SAAS,SACT,OAAQ,MAAmB,QAAQ;AAAA;AAWhC,SAAS,gBAAgB,CAAC,OAAyC;AAAA,EACxE,OACE,OAAO,SAAS,KAAK,KACrB,iBAAiB,QACjB,iBAAiB,YACjB,OAAO,UAAU;AAAA;",
7
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwFO,SAAS,UAAU,CAAC,OAAmC;AAAA,EAC5D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,SAAS,SACT,OAAQ,MAAmB,QAAQ;AAAA;AAWhC,SAAS,gBAAgB,CAAC,OAAyC;AAAA,EACxE,OACE,OAAO,SAAS,KAAK,KACrB,iBAAiB,QACjB,iBAAiB,YACjB,OAAO,UAAU;AAAA;",
8
8
  "debugId": "A099C0F37A42BA3264756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "type": "module"
5
5
  }
@@ -55,7 +55,7 @@ function matchGlob(pattern, str, caseInsensitive = false) {
55
55
  return false;
56
56
  }
57
57
  }
58
- function evalExpr(expr, basename, isFile, isDir) {
58
+ async function evalExpr(expr, basename, isFile, isDir, entryPath, ctx) {
59
59
  switch (expr.type) {
60
60
  case "true":
61
61
  return true;
@@ -63,12 +63,65 @@ function evalExpr(expr, basename, isFile, isDir) {
63
63
  return matchGlob(expr.pattern, basename, expr.ignoreCase);
64
64
  case "ftype":
65
65
  return expr.value === "f" ? isFile : isDir;
66
+ case "and": {
67
+ const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);
68
+ if (!leftResult)
69
+ return false;
70
+ return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);
71
+ }
72
+ case "or": {
73
+ const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);
74
+ if (leftResult)
75
+ return true;
76
+ return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);
77
+ }
78
+ case "not":
79
+ return !await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx);
80
+ case "exec": {
81
+ if (expr.batchMode) {
82
+ return true;
83
+ }
84
+ if (!ctx.exec) {
85
+ await ctx.stderr.writeText(`find: -exec not supported (no exec capability)
86
+ `);
87
+ return false;
88
+ }
89
+ const resolvedArgs = expr.cmdArgs.map((a) => a === "{}" ? entryPath : a);
90
+ const result = await ctx.exec(expr.cmdName, resolvedArgs);
91
+ if (result.stdout.length > 0) {
92
+ await ctx.stdout.write(result.stdout);
93
+ }
94
+ if (result.stderr.length > 0) {
95
+ await ctx.stderr.write(result.stderr);
96
+ }
97
+ return result.exitCode === 0;
98
+ }
99
+ }
100
+ }
101
+ function hasActionExpr(expr) {
102
+ switch (expr.type) {
103
+ case "exec":
104
+ return true;
105
+ case "and":
106
+ case "or":
107
+ return hasActionExpr(expr.left) || hasActionExpr(expr.right);
108
+ case "not":
109
+ return hasActionExpr(expr.expr);
110
+ default:
111
+ return false;
112
+ }
113
+ }
114
+ function collectBatchExecNodes(expr) {
115
+ switch (expr.type) {
116
+ case "exec":
117
+ return expr.batchMode ? [expr] : [];
66
118
  case "and":
67
- return evalExpr(expr.left, basename, isFile, isDir) && evalExpr(expr.right, basename, isFile, isDir);
68
119
  case "or":
69
- return evalExpr(expr.left, basename, isFile, isDir) || evalExpr(expr.right, basename, isFile, isDir);
120
+ return [...collectBatchExecNodes(expr.left), ...collectBatchExecNodes(expr.right)];
70
121
  case "not":
71
- return !evalExpr(expr.expr, basename, isFile, isDir);
122
+ return collectBatchExecNodes(expr.expr);
123
+ default:
124
+ return [];
72
125
  }
73
126
  }
74
127
 
@@ -154,6 +207,37 @@ function parseExprArgs(args) {
154
207
  advance();
155
208
  return { type: "ftype", value: val };
156
209
  }
210
+ if (tok === "-exec") {
211
+ advance();
212
+ const cmdName = peek();
213
+ if (cmdName === undefined || cmdName === ";" || cmdName === "+") {
214
+ throw new ParseError("find: -exec: missing command");
215
+ }
216
+ advance();
217
+ const cmdArgs = [];
218
+ let batchMode = false;
219
+ let foundTerminator = false;
220
+ while (pos < args.length) {
221
+ const a = args[pos];
222
+ if (a === ";") {
223
+ advance();
224
+ foundTerminator = true;
225
+ break;
226
+ }
227
+ if (a === "+") {
228
+ advance();
229
+ batchMode = true;
230
+ foundTerminator = true;
231
+ break;
232
+ }
233
+ cmdArgs.push(a);
234
+ advance();
235
+ }
236
+ if (!foundTerminator) {
237
+ throw new ParseError("find: -exec: missing terminator (';' or '+')");
238
+ }
239
+ return { type: "exec", cmdName, cmdArgs, batchMode };
240
+ }
157
241
  throw new ParseError(`find: unknown predicate '${tok}'`);
158
242
  }
159
243
  const expr = parseOr();
@@ -223,6 +307,9 @@ var find = async (ctx) => {
223
307
  }
224
308
  throw e;
225
309
  }
310
+ const hasAction = hasActionExpr(expr);
311
+ const batchExecNodes = collectBatchExecNodes(expr);
312
+ const batchPaths = [];
226
313
  let hasError = false;
227
314
  for (const startPath of paths) {
228
315
  const normalizedPath = startPath === "/" ? "/" : startPath.replace(/\/+$/, "");
@@ -249,10 +336,14 @@ var find = async (ctx) => {
249
336
  const isDir = entryStat.isDirectory();
250
337
  const isFile = entryStat.isFile();
251
338
  const basename = ctx.fs.basename(path);
252
- const matches = evalExpr(expr, basename, isFile, isDir);
339
+ const matches = await evalExpr(expr, basename, isFile, isDir, displayPath, ctx);
253
340
  if (matches && (minDepth === undefined || depth >= minDepth)) {
254
- await ctx.stdout.writeText(displayPath + `
341
+ if (batchExecNodes.length > 0) {
342
+ batchPaths.push(displayPath);
343
+ } else if (!hasAction) {
344
+ await ctx.stdout.writeText(displayPath + `
255
345
  `);
346
+ }
256
347
  }
257
348
  if (isDir) {
258
349
  try {
@@ -268,19 +359,42 @@ var find = async (ctx) => {
268
359
  }
269
360
  if (stat.isFile()) {
270
361
  const basename = ctx.fs.basename(resolvedStart);
271
- const matches = evalExpr(expr, basename, true, false);
362
+ const matches = await evalExpr(expr, basename, true, false, normalizedPath, ctx);
272
363
  if (maxDepth !== undefined && maxDepth < 0) {} else if (matches && (minDepth === undefined || minDepth <= 0)) {
273
- await ctx.stdout.writeText(normalizedPath + `
364
+ if (batchExecNodes.length > 0) {
365
+ batchPaths.push(normalizedPath);
366
+ } else if (!hasAction) {
367
+ await ctx.stdout.writeText(normalizedPath + `
274
368
  `);
369
+ }
275
370
  }
276
371
  } else {
277
372
  await traverse(resolvedStart, normalizedPath, 0);
278
373
  }
279
374
  }
375
+ if (batchExecNodes.length > 0 && batchPaths.length > 0 && ctx.exec) {
376
+ for (const node of batchExecNodes) {
377
+ const resolvedArgs = [];
378
+ for (const a of node.cmdArgs) {
379
+ if (a === "{}") {
380
+ resolvedArgs.push(...batchPaths);
381
+ } else {
382
+ resolvedArgs.push(a);
383
+ }
384
+ }
385
+ const result = await ctx.exec(node.cmdName, resolvedArgs);
386
+ if (result.stdout.length > 0) {
387
+ await ctx.stdout.write(result.stdout);
388
+ }
389
+ if (result.stderr.length > 0) {
390
+ await ctx.stderr.write(result.stderr);
391
+ }
392
+ }
393
+ }
280
394
  return hasError ? 1 : 0;
281
395
  };
282
396
  export {
283
397
  find
284
398
  };
285
399
 
286
- //# debugId=5D73614E490180B964756E2164756E21
400
+ //# debugId=E2340A182AC9F02C64756E2164756E21
@@ -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\n// Expression tree types\ntype FindExpr =\n | { type: \"name\"; pattern: string; ignoreCase: boolean }\n | { type: \"ftype\"; value: \"f\" | \"d\" }\n | { type: \"and\"; left: FindExpr; right: FindExpr }\n | { type: \"or\"; left: FindExpr; right: FindExpr }\n | { type: \"not\"; expr: FindExpr }\n | { type: \"true\" };\n\nfunction evalExpr(expr: FindExpr, basename: string, isFile: boolean, isDir: boolean): boolean {\n switch (expr.type) {\n case \"true\":\n return true;\n case \"name\":\n return matchGlob(expr.pattern, basename, expr.ignoreCase);\n case \"ftype\":\n return expr.value === \"f\" ? isFile : isDir;\n case \"and\":\n return evalExpr(expr.left, basename, isFile, isDir) && evalExpr(expr.right, basename, isFile, isDir);\n case \"or\":\n return evalExpr(expr.left, basename, isFile, isDir) || evalExpr(expr.right, basename, isFile, isDir);\n case \"not\":\n return !evalExpr(expr.expr, basename, isFile, isDir);\n }\n}\n\nclass ParseError extends Error {\n constructor(msg: string) {\n super(msg);\n }\n}\n\nfunction parseExprArgs(args: string[]): FindExpr {\n if (args.length === 0) return { type: \"true\" };\n\n let pos = 0;\n\n function peek(): string | undefined {\n return args[pos];\n }\n\n function advance(): string {\n return args[pos++]!;\n }\n\n function parseOr(): FindExpr {\n let left = parseAnd();\n while (peek() === \"-o\") {\n advance();\n const right = parseAnd();\n left = { type: \"or\", left, right };\n }\n return left;\n }\n\n function parseAnd(): FindExpr {\n let left = parseUnary();\n while (pos < args.length) {\n const next = peek();\n if (next === \"-o\" || next === \")\" || next === undefined) break;\n if (next === \"-a\") {\n advance();\n }\n const right = parseUnary();\n left = { type: \"and\", left, right };\n }\n return left;\n }\n\n function parseUnary(): FindExpr {\n const next = peek();\n if (next === \"!\" || next === \"-not\") {\n advance();\n const expr = parseUnary();\n return { type: \"not\", expr };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): FindExpr {\n const tok = peek();\n if (tok === undefined) {\n throw new ParseError(\"find: expected expression\");\n }\n\n if (tok === \"(\") {\n advance();\n const expr = parseOr();\n if (peek() !== \")\") {\n throw new ParseError(\"find: missing closing ')'\");\n }\n advance();\n return expr;\n }\n\n if (tok === \"-name\" || tok === \"-iname\") {\n advance();\n const pattern = peek();\n if (pattern === undefined) {\n throw new ParseError(`find: missing argument to '${tok}'`);\n }\n advance();\n return { type: \"name\", pattern, ignoreCase: tok === \"-iname\" };\n }\n\n if (tok === \"-type\") {\n advance();\n const val = peek();\n if (val === undefined) {\n throw new ParseError(\"find: missing argument to '-type'\");\n }\n if (val !== \"f\" && val !== \"d\") {\n throw new ParseError(`find: Unknown argument to -type: ${val}`);\n }\n advance();\n return { type: \"ftype\", value: val };\n }\n\n throw new ParseError(`find: unknown predicate '${tok}'`);\n }\n\n const expr = parseOr();\n if (pos < args.length) {\n throw new ParseError(`find: unexpected '${args[pos]}'`);\n }\n return expr;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n\n // Parse arguments: paths come before first flag/operator\n let i = 0;\n\n // Collect paths (args before first -, !, or ()\n while (i < args.length && !args[i]!.startsWith(\"-\") && args[i] !== \"!\" && args[i] !== \"(\" && args[i] !== \")\") {\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 // Extract global options (-maxdepth, -mindepth) from remaining args\n let maxDepth: number | undefined;\n let minDepth: number | undefined;\n const exprArgs: string[] = [];\n\n let j = i;\n while (j < args.length) {\n const arg = args[j]!;\n if (arg === \"-maxdepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -maxdepth\\n`);\n return 1;\n }\n maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -mindepth\\n`);\n return 1;\n }\n minDepth = depth;\n } else {\n exprArgs.push(arg);\n }\n j++;\n }\n\n // Parse expression tree\n let expr: FindExpr;\n try {\n expr = parseExprArgs(exprArgs);\n } catch (e) {\n if (e instanceof ParseError) {\n await ctx.stderr.writeText(e.message + \"\\n\");\n return 1;\n }\n throw e;\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 (maxDepth !== undefined && depth > 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 the expression\n const matches = evalExpr(expr, basename, isFile, isDir);\n\n // Output if matches and above mindepth\n if (matches && (minDepth === undefined || depth >= 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 if (stat.isFile()) {\n const basename = ctx.fs.basename(resolvedStart);\n const matches = evalExpr(expr, basename, true, false);\n\n if (maxDepth !== undefined && maxDepth < 0) {\n // skip\n } else if (matches && (minDepth === undefined || 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"
5
+ "import type { Command, CommandContext, ExecResult } 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\n// Expression tree types\ntype FindExpr =\n | { type: \"name\"; pattern: string; ignoreCase: boolean }\n | { type: \"ftype\"; value: \"f\" | \"d\" }\n | { type: \"and\"; left: FindExpr; right: FindExpr }\n | { type: \"or\"; left: FindExpr; right: FindExpr }\n | { type: \"not\"; expr: FindExpr }\n | { type: \"true\" }\n | { type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean };\n\nasync function evalExpr(\n expr: FindExpr,\n basename: string,\n isFile: boolean,\n isDir: boolean,\n entryPath: string,\n ctx: CommandContext,\n): Promise<boolean> {\n switch (expr.type) {\n case \"true\":\n return true;\n case \"name\":\n return matchGlob(expr.pattern, basename, expr.ignoreCase);\n case \"ftype\":\n return expr.value === \"f\" ? isFile : isDir;\n case \"and\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);\n if (!leftResult) return false;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);\n }\n case \"or\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);\n if (leftResult) return true;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);\n }\n case \"not\":\n return !(await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx));\n case \"exec\": {\n if (expr.batchMode) {\n // In batch mode, always return true during traversal; paths are collected externally\n return true;\n }\n // Per-file mode: execute command with {} replaced by entryPath\n if (!ctx.exec) {\n await ctx.stderr.writeText(\"find: -exec not supported (no exec capability)\\n\");\n return false;\n }\n const resolvedArgs = expr.cmdArgs.map(a => a === \"{}\" ? entryPath : a);\n const result: ExecResult = await ctx.exec(expr.cmdName, resolvedArgs);\n // Pass stdout/stderr through to find's streams\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n return result.exitCode === 0;\n }\n }\n}\n\n/** Check if expression tree contains any -exec node */\nfunction hasActionExpr(expr: FindExpr): boolean {\n switch (expr.type) {\n case \"exec\":\n return true;\n case \"and\":\n case \"or\":\n return hasActionExpr(expr.left) || hasActionExpr(expr.right);\n case \"not\":\n return hasActionExpr(expr.expr);\n default:\n return false;\n }\n}\n\n/** Collect all batch-mode -exec nodes from the expression tree */\nfunction collectBatchExecNodes(expr: FindExpr): Array<{ type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean }> {\n switch (expr.type) {\n case \"exec\":\n return expr.batchMode ? [expr] : [];\n case \"and\":\n case \"or\":\n return [...collectBatchExecNodes(expr.left), ...collectBatchExecNodes(expr.right)];\n case \"not\":\n return collectBatchExecNodes(expr.expr);\n default:\n return [];\n }\n}\n\nclass ParseError extends Error {\n constructor(msg: string) {\n super(msg);\n }\n}\n\nfunction parseExprArgs(args: string[]): FindExpr {\n if (args.length === 0) return { type: \"true\" };\n\n let pos = 0;\n\n function peek(): string | undefined {\n return args[pos];\n }\n\n function advance(): string {\n return args[pos++]!;\n }\n\n function parseOr(): FindExpr {\n let left = parseAnd();\n while (peek() === \"-o\") {\n advance();\n const right = parseAnd();\n left = { type: \"or\", left, right };\n }\n return left;\n }\n\n function parseAnd(): FindExpr {\n let left = parseUnary();\n while (pos < args.length) {\n const next = peek();\n if (next === \"-o\" || next === \")\" || next === undefined) break;\n if (next === \"-a\") {\n advance();\n }\n const right = parseUnary();\n left = { type: \"and\", left, right };\n }\n return left;\n }\n\n function parseUnary(): FindExpr {\n const next = peek();\n if (next === \"!\" || next === \"-not\") {\n advance();\n const expr = parseUnary();\n return { type: \"not\", expr };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): FindExpr {\n const tok = peek();\n if (tok === undefined) {\n throw new ParseError(\"find: expected expression\");\n }\n\n if (tok === \"(\") {\n advance();\n const expr = parseOr();\n if (peek() !== \")\") {\n throw new ParseError(\"find: missing closing ')'\");\n }\n advance();\n return expr;\n }\n\n if (tok === \"-name\" || tok === \"-iname\") {\n advance();\n const pattern = peek();\n if (pattern === undefined) {\n throw new ParseError(`find: missing argument to '${tok}'`);\n }\n advance();\n return { type: \"name\", pattern, ignoreCase: tok === \"-iname\" };\n }\n\n if (tok === \"-type\") {\n advance();\n const val = peek();\n if (val === undefined) {\n throw new ParseError(\"find: missing argument to '-type'\");\n }\n if (val !== \"f\" && val !== \"d\") {\n throw new ParseError(`find: Unknown argument to -type: ${val}`);\n }\n advance();\n return { type: \"ftype\", value: val };\n }\n\n if (tok === \"-exec\") {\n advance();\n const cmdName = peek();\n if (cmdName === undefined || cmdName === \";\" || cmdName === \"+\") {\n throw new ParseError(\"find: -exec: missing command\");\n }\n advance();\n\n const cmdArgs: string[] = [];\n let batchMode = false;\n let foundTerminator = false;\n\n while (pos < args.length) {\n const a = args[pos]!;\n if (a === \";\") {\n advance();\n foundTerminator = true;\n break;\n }\n if (a === \"+\") {\n advance();\n batchMode = true;\n foundTerminator = true;\n break;\n }\n cmdArgs.push(a);\n advance();\n }\n\n if (!foundTerminator) {\n throw new ParseError(\"find: -exec: missing terminator (';' or '+')\");\n }\n\n return { type: \"exec\", cmdName, cmdArgs, batchMode };\n }\n\n throw new ParseError(`find: unknown predicate '${tok}'`);\n }\n\n const expr = parseOr();\n if (pos < args.length) {\n throw new ParseError(`find: unexpected '${args[pos]}'`);\n }\n return expr;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n\n // Parse arguments: paths come before first flag/operator\n let i = 0;\n\n // Collect paths (args before first -, !, or ()\n while (i < args.length && !args[i]!.startsWith(\"-\") && args[i] !== \"!\" && args[i] !== \"(\" && args[i] !== \")\") {\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 // Extract global options (-maxdepth, -mindepth) from remaining args\n let maxDepth: number | undefined;\n let minDepth: number | undefined;\n const exprArgs: string[] = [];\n\n let j = i;\n while (j < args.length) {\n const arg = args[j]!;\n if (arg === \"-maxdepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -maxdepth\\n`);\n return 1;\n }\n maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -mindepth\\n`);\n return 1;\n }\n minDepth = depth;\n } else {\n exprArgs.push(arg);\n }\n j++;\n }\n\n // Parse expression tree\n let expr: FindExpr;\n try {\n expr = parseExprArgs(exprArgs);\n } catch (e) {\n if (e instanceof ParseError) {\n await ctx.stderr.writeText(e.message + \"\\n\");\n return 1;\n }\n throw e;\n }\n\n const hasAction = hasActionExpr(expr);\n const batchExecNodes = collectBatchExecNodes(expr);\n const batchPaths: string[] = [];\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 (maxDepth !== undefined && depth > 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 the expression\n const matches = await evalExpr(expr, basename, isFile, isDir, displayPath, ctx);\n\n if (matches && (minDepth === undefined || depth >= minDepth)) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(displayPath);\n } else if (!hasAction) {\n // No action expressions: default print behavior\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n // If has per-file -exec actions, output was already handled in evalExpr\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 if (stat.isFile()) {\n const basename = ctx.fs.basename(resolvedStart);\n const matches = await evalExpr(expr, basename, true, false, normalizedPath, ctx);\n\n if (maxDepth !== undefined && maxDepth < 0) {\n // skip\n } else if (matches && (minDepth === undefined || minDepth <= 0)) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(normalizedPath);\n } else if (!hasAction) {\n await ctx.stdout.writeText(normalizedPath + \"\\n\");\n }\n }\n } else {\n await traverse(resolvedStart, normalizedPath, 0);\n }\n }\n\n // Execute batch -exec nodes with all collected paths\n if (batchExecNodes.length > 0 && batchPaths.length > 0 && ctx.exec) {\n for (const node of batchExecNodes) {\n // Replace {} in cmdArgs with all paths\n const resolvedArgs: string[] = [];\n for (const a of node.cmdArgs) {\n if (a === \"{}\") {\n resolvedArgs.push(...batchPaths);\n } else {\n resolvedArgs.push(a);\n }\n }\n const result = await ctx.exec(node.cmdName, resolvedArgs);\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "5D73614E490180B964756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "E2340A182AC9F02C64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -3,11 +3,12 @@ import * as pathModule from "path";
3
3
  function createVirtualFS(memfs) {
4
4
  const { promises: fs } = memfs;
5
5
  return {
6
- async readFile(path) {
6
+ readFile: async (path, encoding) => {
7
7
  if (path === "/dev/null")
8
- return Buffer.alloc(0);
8
+ return encoding ? "" : Buffer.alloc(0);
9
9
  const content = await fs.readFile(path);
10
- return Buffer.from(content);
10
+ const buf = Buffer.from(content);
11
+ return encoding ? buf.toString(encoding) : buf;
11
12
  },
12
13
  async readdir(path) {
13
14
  const entries = await fs.readdir(path);
@@ -177,4 +178,4 @@ export {
177
178
  createVirtualFS
178
179
  };
179
180
 
180
- //# debugId=FECADF24168DA75064756E2164756E21
181
+ //# debugId=12701BFA42EE2D4964756E2164756E21