shell-dsl 0.0.39 → 0.0.40

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.
Files changed (50) hide show
  1. package/README.md +117 -3
  2. package/dist/cjs/package.json +1 -1
  3. package/dist/cjs/src/commands/exit/exit.cjs +84 -0
  4. package/dist/cjs/src/commands/exit/exit.cjs.map +10 -0
  5. package/dist/cjs/src/commands/index.cjs +18 -2
  6. package/dist/cjs/src/commands/index.cjs.map +3 -3
  7. package/dist/cjs/src/commands/sh/sh.cjs +134 -0
  8. package/dist/cjs/src/commands/sh/sh.cjs.map +10 -0
  9. package/dist/cjs/src/index.cjs +2 -1
  10. package/dist/cjs/src/index.cjs.map +3 -3
  11. package/dist/cjs/src/interpreter/context.cjs +4 -1
  12. package/dist/cjs/src/interpreter/context.cjs.map +3 -3
  13. package/dist/cjs/src/interpreter/index.cjs +2 -1
  14. package/dist/cjs/src/interpreter/index.cjs.map +3 -3
  15. package/dist/cjs/src/interpreter/interpreter.cjs +301 -76
  16. package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
  17. package/dist/cjs/src/lexer/lexer.cjs +13 -1
  18. package/dist/cjs/src/lexer/lexer.cjs.map +3 -3
  19. package/dist/cjs/src/parser/parser.cjs +11 -1
  20. package/dist/cjs/src/parser/parser.cjs.map +3 -3
  21. package/dist/cjs/src/types.cjs.map +2 -2
  22. package/dist/mjs/package.json +1 -1
  23. package/dist/mjs/src/commands/exit/exit.mjs +44 -0
  24. package/dist/mjs/src/commands/exit/exit.mjs.map +10 -0
  25. package/dist/mjs/src/commands/index.mjs +18 -2
  26. package/dist/mjs/src/commands/index.mjs.map +3 -3
  27. package/dist/mjs/src/commands/sh/sh.mjs +94 -0
  28. package/dist/mjs/src/commands/sh/sh.mjs.map +10 -0
  29. package/dist/mjs/src/index.mjs +3 -2
  30. package/dist/mjs/src/index.mjs.map +3 -3
  31. package/dist/mjs/src/interpreter/context.mjs +4 -1
  32. package/dist/mjs/src/interpreter/context.mjs.map +3 -3
  33. package/dist/mjs/src/interpreter/index.mjs +3 -2
  34. package/dist/mjs/src/interpreter/index.mjs.map +2 -2
  35. package/dist/mjs/src/interpreter/interpreter.mjs +301 -76
  36. package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
  37. package/dist/mjs/src/lexer/lexer.mjs +13 -1
  38. package/dist/mjs/src/lexer/lexer.mjs.map +3 -3
  39. package/dist/mjs/src/parser/parser.mjs +11 -1
  40. package/dist/mjs/src/parser/parser.mjs.map +3 -3
  41. package/dist/mjs/src/types.mjs.map +2 -2
  42. package/dist/types/src/commands/exit/exit.d.ts +2 -0
  43. package/dist/types/src/commands/index.d.ts +2 -0
  44. package/dist/types/src/commands/sh/sh.d.ts +5 -0
  45. package/dist/types/src/index.d.ts +2 -2
  46. package/dist/types/src/interpreter/context.d.ts +2 -1
  47. package/dist/types/src/interpreter/index.d.ts +1 -1
  48. package/dist/types/src/interpreter/interpreter.d.ts +24 -0
  49. package/dist/types/src/types.d.ts +13 -0
  50. package/package.json +1 -1
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/parser/parser.ts"],
4
4
  "sourcesContent": [
5
- "import { ParseError } from \"../errors.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type {\n ASTNode,\n Redirect,\n RedirectMode,\n CommandNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n WordNode,\n WordPart,\n} from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n const items: WordNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' case_clause* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n this.match(\"openParen\");\n\n const patterns: WordNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n const body = this.parseCaseBody();\n clauses.push({ patterns, body });\n\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): WordNode {\n const token = this.peek();\n\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return this.createNoopCommand();\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n if (this.isCompoundListTerminator(terminators)) {\n return this.createNoopCommand();\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private createNoopCommand(): CommandNode {\n return {\n type: \"command\",\n name: this.createTextWord(\"true\"),\n args: [],\n redirects: [],\n assignments: [],\n };\n }\n\n private createTextWord(value: string, quoted = false): WordNode {\n return {\n type: \"word\",\n parts: value === \"\" && !quoted ? [] : [{ type: \"text\", value, quoted }],\n };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: WordNode }> = [];\n const args: WordNode[] = [];\n const redirects: Redirect[] = [];\n\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToWord(token.value),\n });\n }\n\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? this.createTextWord(redirects.length > 0 ? \":\" : \"\");\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): WordNode {\n const token = this.advance();\n return this.tokenToWord(token);\n }\n\n private tokenToWord(token: Token | string | Token[]): WordNode {\n const parts = this.tokenToWordParts(token);\n return {\n type: \"word\",\n parts,\n };\n }\n\n private tokenToWordParts(token: Token | string | Token[], quoted = false): WordPart[] {\n if (typeof token === \"string\") {\n return [{ type: \"text\", value: token, quoted }];\n }\n\n if (Array.isArray(token)) {\n return token.flatMap((part) => this.tokenToWordParts(part, quoted));\n }\n\n switch (token.type) {\n case \"word\":\n return [{ type: \"text\", value: token.value, quoted }];\n case \"singleQuote\":\n return [{ type: \"text\", value: token.value, quoted: true }];\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return [{ type: \"variable\", name: token.name, quoted }];\n case \"substitution\": {\n const innerParser = new Parser(\n new Lexer(token.command, { preserveNewlines: true }).tokenize()\n );\n return [{ type: \"substitution\", command: innerParser.parse(), quoted }];\n }\n case \"arithmetic\":\n return [{ type: \"arithmetic\", expression: token.expression, quoted }];\n case \"glob\":\n return [{ type: \"text\", value: token.pattern, quoted }];\n case \"assignment\":\n return this.tokenToWordParts(token.value, quoted);\n case \"heredoc\":\n return token.expand\n ? this.parseHeredocContent(token.content).parts\n : [{ type: \"text\", value: token.content, quoted: true }];\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): WordPart[] {\n if (parts.length === 0) {\n return [{ type: \"text\", value: \"\", quoted: true }];\n }\n\n return parts.flatMap((part) => this.tokenToWordParts(part, true));\n }\n\n private parseHeredocContent(content: string): WordNode {\n const parts: WordPart[] = [];\n let currentText = \"\";\n let i = 0;\n\n const pushText = () => {\n if (currentText.length > 0) {\n parts.push({ type: \"text\", value: currentText, quoted: false });\n currentText = \"\";\n }\n };\n\n while (i < content.length) {\n if (content[i] !== \"$\") {\n currentText += content[i];\n i++;\n continue;\n }\n\n pushText();\n i++;\n\n if (i >= content.length) {\n currentText += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n i++;\n let name = \"\";\n while (i < content.length && content[i] !== \"}\") {\n name += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n i += 2;\n let depth = 1;\n let expression = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n depth++;\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n if (content[i] === \")\" && content[i + 1] === \")\") {\n depth--;\n if (depth === 0) {\n i += 2;\n break;\n }\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n expression += content[i]!;\n i++;\n }\n parts.push({ type: \"arithmetic\", expression, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\") {\n i++;\n let depth = 1;\n let command = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\") {\n depth++;\n } else if (content[i] === \")\") {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n command += content[i]!;\n i++;\n }\n const innerParser = new Parser(\n new Lexer(command, { preserveNewlines: true }).tokenize()\n );\n parts.push({ type: \"substitution\", command: innerParser.parse(), quoted: false });\n continue;\n }\n\n if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n let name = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n name += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n currentText += \"$\";\n }\n\n pushText();\n\n return {\n type: \"word\",\n parts,\n };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: this.createTextWord(\"\") };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
5
+ "import { ParseError } from \"../errors.cjs\";\nimport { Lexer } from \"../lexer/lexer.cjs\";\nimport type { Token, KeywordValue } from \"../lexer/tokens.cjs\";\nimport type {\n ASTNode,\n Redirect,\n RedirectMode,\n CommandNode,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n WordNode,\n WordPart,\n} from \"./ast.cjs\";\n\nexport class Parser {\n private tokens: Token[];\n private pos: number = 0;\n\n constructor(tokens: Token[]) {\n this.tokens = tokens;\n }\n\n parse(): ASTNode {\n const result = this.parseSequence();\n if (!this.isAtEnd()) {\n throw new ParseError(`Unexpected token: ${JSON.stringify(this.peek())}`);\n }\n return result;\n }\n\n // sequence := and_or ((';'|'\\n') and_or)*\n private parseSequence(): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n commands.push(this.parseAndOr());\n\n while (this.match(\"semicolon\") || this.match(\"newline\")) {\n this.skipNewlines();\n if (this.isAtEnd() || this.check(\"semicolon\") || this.check(\"newline\") || this.isTerminatingKeyword()) continue;\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private skipNewlines(): void {\n while (this.match(\"newline\")) {\n // keep consuming newlines\n }\n }\n\n private isTerminatingKeyword(): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return [\"then\", \"elif\", \"else\", \"fi\", \"do\", \"done\", \"esac\"].includes(token.value);\n }\n\n // and_or := pipeline (('&&'|'||') pipeline)*\n private parseAndOr(): ASTNode {\n let left = this.parsePipeline();\n\n while (this.check(\"and\") || this.check(\"or\")) {\n if (this.match(\"and\")) {\n const right = this.parsePipeline();\n left = { type: \"and\", left, right };\n } else if (this.match(\"or\")) {\n const right = this.parsePipeline();\n left = { type: \"or\", left, right };\n }\n }\n\n return left;\n }\n\n // pipeline := command ('|' command)*\n private parsePipeline(): ASTNode {\n const commands: ASTNode[] = [];\n commands.push(this.parseCompoundOrCommand());\n\n while (this.match(\"pipe\")) {\n this.skipNewlines();\n commands.push(this.parseCompoundOrCommand());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"pipeline\", commands };\n }\n\n // compound_or_command := compound_command | simple_command\n private parseCompoundOrCommand(): ASTNode {\n this.skipNewlines();\n const token = this.peek();\n\n if (token.type === \"keyword\") {\n switch (token.value) {\n case \"if\":\n return this.parseIf();\n case \"for\":\n return this.parseFor();\n case \"while\":\n return this.parseWhile();\n case \"until\":\n return this.parseUntil();\n case \"case\":\n return this.parseCase();\n }\n }\n\n return this.parseCommand();\n }\n\n // if := 'if' compound_list 'then' compound_list ('elif' compound_list 'then' compound_list)* ['else' compound_list] 'fi'\n private parseIf(): IfNode {\n this.expectKeyword(\"if\");\n const condition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const thenBranch = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n\n const elifBranches: Array<{ condition: ASTNode; body: ASTNode }> = [];\n while (this.checkKeyword(\"elif\")) {\n this.expectKeyword(\"elif\");\n const elifCondition = this.parseCompoundList([\"then\"]);\n this.expectKeyword(\"then\");\n const elifBody = this.parseCompoundList([\"elif\", \"else\", \"fi\"]);\n elifBranches.push({ condition: elifCondition, body: elifBody });\n }\n\n let elseBranch: ASTNode | undefined;\n if (this.checkKeyword(\"else\")) {\n this.expectKeyword(\"else\");\n elseBranch = this.parseCompoundList([\"fi\"]);\n }\n\n this.expectKeyword(\"fi\");\n\n return {\n type: \"if\",\n condition,\n thenBranch,\n elifBranches,\n elseBranch,\n };\n }\n\n // for := 'for' NAME ['in' word*] (';'|'\\n') 'do' compound_list 'done'\n private parseFor(): ForNode {\n this.expectKeyword(\"for\");\n\n const varToken = this.peek();\n if (varToken.type !== \"word\") {\n throw new ParseError(\"Expected variable name after 'for'\");\n }\n this.advance();\n const variable = varToken.value;\n\n const items: WordNode[] = [];\n if (this.checkKeyword(\"in\")) {\n this.expectKeyword(\"in\");\n while (!this.isAtEnd() && !this.check(\"semicolon\") && !this.check(\"newline\") && !this.checkKeyword(\"do\")) {\n items.push(this.parseWordArg());\n }\n }\n\n if (!this.match(\"semicolon\")) {\n this.match(\"newline\");\n }\n this.skipNewlines();\n\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"for\",\n variable,\n items,\n body,\n };\n }\n\n // while := 'while' compound_list 'do' compound_list 'done'\n private parseWhile(): WhileNode {\n this.expectKeyword(\"while\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"while\",\n condition,\n body,\n };\n }\n\n // until := 'until' compound_list 'do' compound_list 'done'\n private parseUntil(): UntilNode {\n this.expectKeyword(\"until\");\n const condition = this.parseCompoundList([\"do\"]);\n this.expectKeyword(\"do\");\n const body = this.parseCompoundList([\"done\"]);\n this.expectKeyword(\"done\");\n\n return {\n type: \"until\",\n condition,\n body,\n };\n }\n\n // case := 'case' word 'in' case_clause* 'esac'\n private parseCase(): CaseNode {\n this.expectKeyword(\"case\");\n const word = this.parseWordArg();\n this.expectKeyword(\"in\");\n this.skipNewlines();\n\n const clauses: CaseClause[] = [];\n\n while (!this.isAtEnd() && !this.checkKeyword(\"esac\")) {\n this.match(\"openParen\");\n\n const patterns: WordNode[] = [];\n patterns.push(this.parseCasePattern());\n\n while (this.match(\"pipe\")) {\n patterns.push(this.parseCasePattern());\n }\n\n if (!this.match(\"closeParen\")) {\n throw new ParseError(\"Expected ')' after case pattern\");\n }\n\n const body = this.parseCaseBody();\n clauses.push({ patterns, body });\n\n this.match(\"doubleSemicolon\");\n this.skipNewlines();\n }\n\n this.expectKeyword(\"esac\");\n\n return {\n type: \"case\",\n word,\n clauses,\n };\n }\n\n private parseCasePattern(): WordNode {\n const token = this.peek();\n\n if (token.type === \"word\" || token.type === \"glob\" || token.type === \"singleQuote\" || token.type === \"doubleQuote\") {\n return this.parseWordArg();\n }\n\n throw new ParseError(`Expected pattern in case clause, got ${token.type}`);\n }\n\n private parseCaseBody(): ASTNode {\n const commands: ASTNode[] = [];\n this.skipNewlines();\n\n while (!this.isAtEnd() && !this.check(\"doubleSemicolon\") && !this.checkKeyword(\"esac\")) {\n commands.push(this.parseAndOr());\n if (!this.match(\"semicolon\") && !this.match(\"newline\")) {\n break;\n }\n this.skipNewlines();\n if (this.check(\"doubleSemicolon\") || this.checkKeyword(\"esac\")) {\n break;\n }\n }\n\n if (commands.length === 0) {\n return this.createNoopCommand();\n }\n if (commands.length === 1) {\n return commands[0]!;\n }\n return { type: \"sequence\", commands };\n }\n\n // compound_list := and_or ((';'|'\\n') and_or)* [';'|'\\n']\n private parseCompoundList(terminators: KeywordValue[]): ASTNode {\n this.skipNewlines();\n const commands: ASTNode[] = [];\n\n if (this.isCompoundListTerminator(terminators)) {\n return this.createNoopCommand();\n }\n\n commands.push(this.parseAndOr());\n\n while ((this.match(\"semicolon\") || this.match(\"newline\")) && !this.isAtEnd()) {\n this.skipNewlines();\n if (this.isCompoundListTerminator(terminators)) {\n break;\n }\n commands.push(this.parseAndOr());\n }\n\n if (commands.length === 1) {\n return commands[0]!;\n }\n\n return { type: \"sequence\", commands };\n }\n\n private createNoopCommand(): CommandNode {\n return {\n type: \"command\",\n name: this.createTextWord(\"true\"),\n args: [],\n redirects: [],\n assignments: [],\n };\n }\n\n private createTextWord(value: string, quoted = false): WordNode {\n return {\n type: \"word\",\n parts: value === \"\" && !quoted ? [] : [{ type: \"text\", value, quoted }],\n };\n }\n\n private isCompoundListTerminator(terminators: KeywordValue[]): boolean {\n const token = this.peek();\n if (token.type !== \"keyword\") return false;\n return terminators.includes(token.value);\n }\n\n private checkKeyword(value: KeywordValue): boolean {\n const token = this.peek();\n return token.type === \"keyword\" && token.value === value;\n }\n\n private expectKeyword(value: KeywordValue): void {\n if (!this.checkKeyword(value)) {\n throw new ParseError(`Expected '${value}'`);\n }\n this.advance();\n }\n\n // command := assignment* word+ redirect*\n private parseCommand(): CommandNode {\n const assignments: Array<{ name: string; value: WordNode }> = [];\n const args: WordNode[] = [];\n const redirects: Redirect[] = [];\n\n while (this.check(\"assignment\")) {\n const token = this.advance() as Token & { type: \"assignment\" };\n assignments.push({\n name: token.name,\n value: this.tokenToWord(token.value),\n });\n }\n\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n\n while (this.check(\"redirect\")) {\n const redirect = this.parseRedirect();\n redirects.push(redirect);\n while (this.isWordToken()) {\n if (this.peek().type === \"heredoc\") {\n const heredocToken = this.advance() as Token & { type: \"heredoc\" };\n redirects.push({\n mode: \"<\",\n target: this.tokenToWord(heredocToken),\n heredocContent: true,\n });\n } else {\n args.push(this.parseWordArg());\n }\n }\n }\n\n if (args.length === 0 && assignments.length === 0 && redirects.length === 0) {\n throw new ParseError(\"Expected command\");\n }\n\n const name = args.shift() ?? this.createTextWord(redirects.length > 0 ? \":\" : \"\");\n\n return {\n type: \"command\",\n name,\n args,\n redirects,\n assignments,\n };\n }\n\n private parseWordArg(): WordNode {\n const token = this.advance();\n return this.tokenToWord(token);\n }\n\n private tokenToWord(token: Token | string | Token[]): WordNode {\n const parts = this.tokenToWordParts(token);\n return {\n type: \"word\",\n parts,\n };\n }\n\n private tokenToWordParts(token: Token | string | Token[], quoted = false): WordPart[] {\n if (typeof token === \"string\") {\n return [{ type: \"text\", value: token, quoted }];\n }\n\n if (Array.isArray(token)) {\n return token.flatMap((part) => this.tokenToWordParts(part, quoted));\n }\n\n switch (token.type) {\n case \"word\":\n return [{ type: \"text\", value: token.value, quoted }];\n case \"singleQuote\":\n return [{ type: \"text\", value: token.value, quoted: true }];\n case \"doubleQuote\":\n return this.parseDoubleQuoteParts(token.parts);\n case \"variable\":\n return [{ type: \"variable\", name: token.name, quoted }];\n case \"substitution\": {\n const innerParser = new Parser(\n new Lexer(token.command, { preserveNewlines: true }).tokenize()\n );\n return [{ type: \"substitution\", command: innerParser.parse(), quoted }];\n }\n case \"arithmetic\":\n return [{ type: \"arithmetic\", expression: token.expression, quoted }];\n case \"glob\":\n return [{ type: \"text\", value: token.pattern, quoted }];\n case \"assignment\":\n return this.tokenToWordParts(token.value, quoted);\n case \"heredoc\":\n return token.expand\n ? this.parseHeredocContent(token.content).parts\n : [{ type: \"text\", value: token.content, quoted: true }];\n default:\n throw new ParseError(`Unexpected token type: ${(token as Token).type}`);\n }\n }\n\n private parseDoubleQuoteParts(parts: Array<string | Token>): WordPart[] {\n if (parts.length === 0) {\n return [{ type: \"text\", value: \"\", quoted: true }];\n }\n\n return parts.flatMap((part) => this.tokenToWordParts(part, true));\n }\n\n private parseHeredocContent(content: string): WordNode {\n const parts: WordPart[] = [];\n let currentText = \"\";\n let i = 0;\n\n const pushText = () => {\n if (currentText.length > 0) {\n parts.push({ type: \"text\", value: currentText, quoted: false });\n currentText = \"\";\n }\n };\n\n while (i < content.length) {\n if (content[i] !== \"$\") {\n currentText += content[i];\n i++;\n continue;\n }\n\n pushText();\n i++;\n\n if (i >= content.length) {\n currentText += \"$\";\n break;\n }\n\n if (content[i] === \"{\") {\n i++;\n let name = \"\";\n while (i < content.length && content[i] !== \"}\") {\n name += content[i];\n i++;\n }\n if (i < content.length && content[i] === \"}\") {\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n if ([\"#\", \"*\", \"@\", \"?\"].includes(content[i] ?? \"\")) {\n parts.push({ type: \"variable\", name: content[i]!, quoted: false });\n i++;\n continue;\n }\n\n if (/[0-9]/.test(content[i] ?? \"\")) {\n parts.push({ type: \"variable\", name: content[i]!, quoted: false });\n i++;\n continue;\n }\n\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n i += 2;\n let depth = 1;\n let expression = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\" && content[i + 1] === \"(\") {\n depth++;\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n if (content[i] === \")\" && content[i + 1] === \")\") {\n depth--;\n if (depth === 0) {\n i += 2;\n break;\n }\n expression += content[i]! + content[i + 1]!;\n i += 2;\n continue;\n }\n expression += content[i]!;\n i++;\n }\n parts.push({ type: \"arithmetic\", expression, quoted: false });\n continue;\n }\n\n if (content[i] === \"(\") {\n i++;\n let depth = 1;\n let command = \"\";\n while (i < content.length && depth > 0) {\n if (content[i] === \"(\") {\n depth++;\n } else if (content[i] === \")\") {\n depth--;\n if (depth === 0) {\n i++;\n break;\n }\n }\n command += content[i]!;\n i++;\n }\n const innerParser = new Parser(\n new Lexer(command, { preserveNewlines: true }).tokenize()\n );\n parts.push({ type: \"substitution\", command: innerParser.parse(), quoted: false });\n continue;\n }\n\n if (/[a-zA-Z_]/.test(content[i] ?? \"\")) {\n let name = \"\";\n while (i < content.length && /[a-zA-Z0-9_]/.test(content[i] ?? \"\")) {\n name += content[i];\n i++;\n }\n parts.push({ type: \"variable\", name, quoted: false });\n continue;\n }\n\n currentText += \"$\";\n }\n\n pushText();\n\n return {\n type: \"word\",\n parts,\n };\n }\n\n private parseRedirect(): Redirect {\n const token = this.advance() as Token & { type: \"redirect\" };\n const mode = token.mode as RedirectMode;\n\n if (mode === \"2>&1\" || mode === \"1>&2\") {\n return { mode, target: this.createTextWord(\"\") };\n }\n\n if (!this.isWordToken()) {\n throw new ParseError(`Expected redirect target after ${mode}`);\n }\n\n const target = this.parseWordArg();\n return { mode, target };\n }\n\n private isWordToken(): boolean {\n const token = this.peek();\n return (\n Array.isArray(token) ||\n token.type === \"word\" ||\n token.type === \"singleQuote\" ||\n token.type === \"doubleQuote\" ||\n token.type === \"variable\" ||\n token.type === \"substitution\" ||\n token.type === \"arithmetic\" ||\n token.type === \"glob\" ||\n token.type === \"heredoc\"\n );\n }\n\n private check(type: Token[\"type\"]): boolean {\n return this.peek().type === type;\n }\n\n private match(type: Token[\"type\"]): boolean {\n if (this.check(type)) {\n this.advance();\n return true;\n }\n return false;\n }\n\n private peek(): Token {\n return this.tokens[this.pos] ?? { type: \"eof\" };\n }\n\n private advance(): Token {\n const token = this.peek();\n this.pos++;\n return token;\n }\n\n private isAtEnd(): boolean {\n return this.peek().type === \"eof\";\n }\n}\n\nexport function parse(tokens: Token[]): ASTNode {\n return new Parser(tokens).parse();\n}\n"
6
6
  ],
7
- "mappings": "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",
8
- "debugId": "6385A138BE695E0C64756E2164756E21",
7
+ "mappings": "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",
8
+ "debugId": "BB94E2D814E2C9C664756E2164756E21",
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 VirtualFSWritable {\n write(chunk: Uint8Array): Promise<void>;\n close(): Promise<void>;\n abort?(reason?: unknown): Promise<void>;\n}\n\nexport interface VirtualFS {\n readFile(path: string): Promise<Buffer>;\n readFile(path: string, encoding: BufferEncoding): Promise<string>;\n readStream(path: string): AsyncIterable<Uint8Array>;\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 writeStream(path: string, opts?: { append?: boolean }): Promise<VirtualFSWritable>;\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 mtimeMs: number;\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"
5
+ "// Virtual Filesystem Interface\nexport interface VirtualFSWritable {\n write(chunk: Uint8Array): Promise<void>;\n close(): Promise<void>;\n abort?(reason?: unknown): Promise<void>;\n}\n\nexport interface VirtualFS {\n readFile(path: string): Promise<Buffer>;\n readFile(path: string, encoding: BufferEncoding): Promise<string>;\n readStream(path: string): AsyncIterable<Uint8Array>;\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 writeStream(path: string, opts?: { append?: boolean }): Promise<VirtualFSWritable>;\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 mtimeMs: number;\n}\n\n// Command Interfaces\nexport type Command = (ctx: CommandContext) => Promise<number>;\n\nexport interface ShellRunOptions {\n argv0?: string;\n args?: string[];\n}\n\nexport interface ShellCommandApi {\n eval(source: string): Promise<number>;\n source(path: string, args?: string[]): Promise<number>;\n runScript(path: string, args?: string[]): Promise<number>;\n runShell(source: string, options?: ShellRunOptions): Promise<number>;\n getLastExitCode(): number;\n exit(exitCode?: number): never;\n}\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 shell?: ShellCommandApi;\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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiGO,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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgHO,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": "324A9AF65A2908F664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "shell-dsl",
3
- "version": "0.0.39",
3
+ "version": "0.0.40",
4
4
  "type": "module"
5
5
  }
@@ -0,0 +1,44 @@
1
+ // src/commands/exit/exit.ts
2
+ function parseExitCode(value) {
3
+ if (!/^[+-]?\d+$/.test(value)) {
4
+ return null;
5
+ }
6
+ return Number(value);
7
+ }
8
+ var exitCmd = async (ctx) => {
9
+ if (!ctx.shell) {
10
+ await ctx.stderr.writeText(`exit: shell control not supported
11
+ `);
12
+ return 1;
13
+ }
14
+ if (ctx.args.length === 0) {
15
+ ctx.shell.exit(ctx.shell.getLastExitCode());
16
+ return 0;
17
+ }
18
+ const rawExitCode = ctx.args[0];
19
+ const exitCode = parseExitCode(rawExitCode);
20
+ if (exitCode === null) {
21
+ await ctx.stderr.writeText(`exit: ${rawExitCode}: numeric argument required
22
+ `);
23
+ ctx.shell.exit(2);
24
+ return 0;
25
+ }
26
+ if (!Number.isFinite(exitCode)) {
27
+ await ctx.stderr.writeText(`exit: ${rawExitCode}: numeric argument required
28
+ `);
29
+ ctx.shell.exit(2);
30
+ return 0;
31
+ }
32
+ if (ctx.args.length > 1) {
33
+ await ctx.stderr.writeText(`exit: too many arguments
34
+ `);
35
+ return 1;
36
+ }
37
+ ctx.shell.exit(exitCode);
38
+ return 0;
39
+ };
40
+ export {
41
+ exitCmd
42
+ };
43
+
44
+ //# debugId=D6B1A7CA5FF6DAE464756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/commands/exit/exit.ts"],
4
+ "sourcesContent": [
5
+ "import type { Command } from \"../../types.mjs\";\n\nfunction parseExitCode(value: string): number | null {\n if (!/^[+-]?\\d+$/.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nexport const exitCmd: Command = async (ctx) => {\n if (!ctx.shell) {\n await ctx.stderr.writeText(\"exit: shell control not supported\\n\");\n return 1;\n }\n\n if (ctx.args.length === 0) {\n ctx.shell.exit(ctx.shell.getLastExitCode());\n return 0;\n }\n\n const rawExitCode = ctx.args[0]!;\n const exitCode = parseExitCode(rawExitCode);\n if (exitCode === null) {\n await ctx.stderr.writeText(`exit: ${rawExitCode}: numeric argument required\\n`);\n ctx.shell.exit(2);\n return 0;\n }\n\n if (!Number.isFinite(exitCode)) {\n await ctx.stderr.writeText(`exit: ${rawExitCode}: numeric argument required\\n`);\n ctx.shell.exit(2);\n return 0;\n }\n\n if (ctx.args.length > 1) {\n await ctx.stderr.writeText(\"exit: too many arguments\\n\");\n return 1;\n }\n\n ctx.shell.exit(exitCode);\n return 0;\n};\n"
6
+ ],
7
+ "mappings": ";AAEA,SAAS,aAAa,CAAC,OAA8B;AAAA,EACnD,IAAI,CAAC,aAAa,KAAK,KAAK,GAAG;AAAA,IAC7B,OAAO;AAAA,EACT;AAAA,EACA,OAAO,OAAO,KAAK;AAAA;AAGd,IAAM,UAAmB,OAAO,QAAQ;AAAA,EAC7C,IAAI,CAAC,IAAI,OAAO;AAAA,IACd,MAAM,IAAI,OAAO,UAAU;AAAA,CAAqC;AAAA,IAChE,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,IAAI,KAAK,WAAW,GAAG;AAAA,IACzB,IAAI,MAAM,KAAK,IAAI,MAAM,gBAAgB,CAAC;AAAA,IAC1C,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,IAAI,KAAK;AAAA,EAC7B,MAAM,WAAW,cAAc,WAAW;AAAA,EAC1C,IAAI,aAAa,MAAM;AAAA,IACrB,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAA0C;AAAA,IAC9E,IAAI,MAAM,KAAK,CAAC;AAAA,IAChB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,CAAC,OAAO,SAAS,QAAQ,GAAG;AAAA,IAC9B,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAA0C;AAAA,IAC9E,IAAI,MAAM,KAAK,CAAC;AAAA,IAChB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,IAAI,KAAK,SAAS,GAAG;AAAA,IACvB,MAAM,IAAI,OAAO,UAAU;AAAA,CAA4B;AAAA,IACvD,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,MAAM,KAAK,QAAQ;AAAA,EACvB,OAAO;AAAA;",
8
+ "debugId": "D6B1A7CA5FF6DAE464756E2164756E21",
9
+ "names": []
10
+ }
@@ -28,6 +28,8 @@ import { cd } from "./cd/cd.mjs";
28
28
  import { tr } from "./tr/tr.mjs";
29
29
  import { cut } from "./cut/cut.mjs";
30
30
  import { od } from "./od/od.mjs";
31
+ import { sh, evalCmd, evalCmd as evalCmd2, source, dot } from "./sh/sh.mjs";
32
+ import { exitCmd, exitCmd as exitCmd2 } from "./exit/exit.mjs";
31
33
  import { echo as echo2 } from "./echo/echo.mjs";
32
34
  import { printf as printf2 } from "./printf/printf.mjs";
33
35
  import { cat as cat2 } from "./cat/cat.mjs";
@@ -57,6 +59,8 @@ import { cd as cd2 } from "./cd/cd.mjs";
57
59
  import { tr as tr2 } from "./tr/tr.mjs";
58
60
  import { cut as cut2 } from "./cut/cut.mjs";
59
61
  import { od as od2 } from "./od/od.mjs";
62
+ import { sh as sh2, evalCmd as evalCmd3, source as source2, dot as dot2 } from "./sh/sh.mjs";
63
+ import { exitCmd as exitCmd3 } from "./exit/exit.mjs";
60
64
  var builtinCommands = {
61
65
  echo: echo2,
62
66
  printf: printf2,
@@ -89,7 +93,12 @@ var builtinCommands = {
89
93
  cd: cd2,
90
94
  tr: tr2,
91
95
  cut: cut2,
92
- od: od2
96
+ od: od2,
97
+ sh: sh2,
98
+ eval: evalCmd3,
99
+ source: source2,
100
+ ".": dot2,
101
+ exit: exitCmd3
93
102
  };
94
103
  export {
95
104
  wc,
@@ -101,7 +110,9 @@ export {
101
110
  test,
102
111
  tee,
103
112
  tail,
113
+ source,
104
114
  sort,
115
+ sh,
105
116
  sed,
106
117
  rm,
107
118
  pwd,
@@ -114,7 +125,12 @@ export {
114
125
  grep,
115
126
  find,
116
127
  falseCmd,
128
+ exitCmd2 as exitCmd,
129
+ exitCmd as exit,
130
+ evalCmd2 as evalCmd,
131
+ evalCmd as eval,
117
132
  echo,
133
+ dot,
118
134
  cut,
119
135
  cp,
120
136
  continueCmd,
@@ -127,4 +143,4 @@ export {
127
143
  awk
128
144
  };
129
145
 
130
- //# debugId=56B4F99C3CC35C8764756E2164756E21
146
+ //# debugId=48840C464F27115B64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/commands/index.ts"],
4
4
  "sourcesContent": [
5
- "import type { Command } from \"../types.mjs\";\n\nexport { echo } from \"./echo/echo.mjs\";\nexport { printf } from \"./printf/printf.mjs\";\nexport { cat } from \"./cat/cat.mjs\";\nexport { grep } from \"./grep/grep.mjs\";\nexport { wc } from \"./wc/wc.mjs\";\nexport { head } from \"./head/head.mjs\";\nexport { tail } from \"./tail/tail.mjs\";\nexport { sort } from \"./sort/sort.mjs\";\nexport { uniq } from \"./uniq/uniq.mjs\";\nexport { pwd } from \"./pwd/pwd.mjs\";\nexport { ls } from \"./ls/ls.mjs\";\nexport { mkdir } from \"./mkdir/mkdir.mjs\";\nexport { rm } from \"./rm/rm.mjs\";\nexport { test, bracket } from \"./test/test.mjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nexport { touch } from \"./touch/touch.mjs\";\nexport { cp } from \"./cp/cp.mjs\";\nexport { mv } from \"./mv/mv.mjs\";\nexport { tee } from \"./tee/tee.mjs\";\nexport { tree } from \"./tree/tree.mjs\";\nexport { find } from \"./find/find.mjs\";\nexport { sed } from \"./sed/sed.mjs\";\nexport { awk } from \"./awk/awk.mjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nexport { colon } from \"./colon/colon.mjs\";\nexport { cd } from \"./cd/cd.mjs\";\nexport { tr } from \"./tr/tr.mjs\";\nexport { cut } from \"./cut/cut.mjs\";\nexport { od } from \"./od/od.mjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.mjs\";\nimport { printf } from \"./printf/printf.mjs\";\nimport { cat } from \"./cat/cat.mjs\";\nimport { grep } from \"./grep/grep.mjs\";\nimport { wc } from \"./wc/wc.mjs\";\nimport { head } from \"./head/head.mjs\";\nimport { tail } from \"./tail/tail.mjs\";\nimport { sort } from \"./sort/sort.mjs\";\nimport { uniq } from \"./uniq/uniq.mjs\";\nimport { pwd } from \"./pwd/pwd.mjs\";\nimport { ls } from \"./ls/ls.mjs\";\nimport { mkdir } from \"./mkdir/mkdir.mjs\";\nimport { rm } from \"./rm/rm.mjs\";\nimport { test, bracket } from \"./test/test.mjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nimport { touch } from \"./touch/touch.mjs\";\nimport { cp } from \"./cp/cp.mjs\";\nimport { mv } from \"./mv/mv.mjs\";\nimport { tee } from \"./tee/tee.mjs\";\nimport { tree } from \"./tree/tree.mjs\";\nimport { find } from \"./find/find.mjs\";\nimport { sed } from \"./sed/sed.mjs\";\nimport { awk } from \"./awk/awk.mjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nimport { colon } from \"./colon/colon.mjs\";\nimport { cd } from \"./cd/cd.mjs\";\nimport { tr } from \"./tr/tr.mjs\";\nimport { cut } from \"./cut/cut.mjs\";\nimport { od } from \"./od/od.mjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n printf,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n cd,\n tr,\n cut,\n od,\n};\n"
5
+ "import type { Command } from \"../types.mjs\";\n\nexport { echo } from \"./echo/echo.mjs\";\nexport { printf } from \"./printf/printf.mjs\";\nexport { cat } from \"./cat/cat.mjs\";\nexport { grep } from \"./grep/grep.mjs\";\nexport { wc } from \"./wc/wc.mjs\";\nexport { head } from \"./head/head.mjs\";\nexport { tail } from \"./tail/tail.mjs\";\nexport { sort } from \"./sort/sort.mjs\";\nexport { uniq } from \"./uniq/uniq.mjs\";\nexport { pwd } from \"./pwd/pwd.mjs\";\nexport { ls } from \"./ls/ls.mjs\";\nexport { mkdir } from \"./mkdir/mkdir.mjs\";\nexport { rm } from \"./rm/rm.mjs\";\nexport { test, bracket } from \"./test/test.mjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nexport { touch } from \"./touch/touch.mjs\";\nexport { cp } from \"./cp/cp.mjs\";\nexport { mv } from \"./mv/mv.mjs\";\nexport { tee } from \"./tee/tee.mjs\";\nexport { tree } from \"./tree/tree.mjs\";\nexport { find } from \"./find/find.mjs\";\nexport { sed } from \"./sed/sed.mjs\";\nexport { awk } from \"./awk/awk.mjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nexport { colon } from \"./colon/colon.mjs\";\nexport { cd } from \"./cd/cd.mjs\";\nexport { tr } from \"./tr/tr.mjs\";\nexport { cut } from \"./cut/cut.mjs\";\nexport { od } from \"./od/od.mjs\";\nexport { sh, evalCmd as eval, evalCmd, source, dot } from \"./sh/sh.mjs\";\nexport { exitCmd as exit, exitCmd } from \"./exit/exit.mjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.mjs\";\nimport { printf } from \"./printf/printf.mjs\";\nimport { cat } from \"./cat/cat.mjs\";\nimport { grep } from \"./grep/grep.mjs\";\nimport { wc } from \"./wc/wc.mjs\";\nimport { head } from \"./head/head.mjs\";\nimport { tail } from \"./tail/tail.mjs\";\nimport { sort } from \"./sort/sort.mjs\";\nimport { uniq } from \"./uniq/uniq.mjs\";\nimport { pwd } from \"./pwd/pwd.mjs\";\nimport { ls } from \"./ls/ls.mjs\";\nimport { mkdir } from \"./mkdir/mkdir.mjs\";\nimport { rm } from \"./rm/rm.mjs\";\nimport { test, bracket } from \"./test/test.mjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.mjs\";\nimport { touch } from \"./touch/touch.mjs\";\nimport { cp } from \"./cp/cp.mjs\";\nimport { mv } from \"./mv/mv.mjs\";\nimport { tee } from \"./tee/tee.mjs\";\nimport { tree } from \"./tree/tree.mjs\";\nimport { find } from \"./find/find.mjs\";\nimport { sed } from \"./sed/sed.mjs\";\nimport { awk } from \"./awk/awk.mjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.mjs\";\nimport { colon } from \"./colon/colon.mjs\";\nimport { cd } from \"./cd/cd.mjs\";\nimport { tr } from \"./tr/tr.mjs\";\nimport { cut } from \"./cut/cut.mjs\";\nimport { od } from \"./od/od.mjs\";\nimport { sh, evalCmd, source, dot } from \"./sh/sh.mjs\";\nimport { exitCmd } from \"./exit/exit.mjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n printf,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n cd,\n tr,\n cut,\n od,\n sh,\n eval: evalCmd,\n source,\n \".\": dot,\n exit: exitCmd,\n};\n"
6
6
  ],
7
- "mappings": ";AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA,iBAAS;AACT,mBAAS;AACT,gBAAS;AACT,iBAAS;AACT,eAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,eAAS;AACT,kBAAS;AACT,eAAS;AACT,iBAAS,kBAAM;AACf,oBAAS,sBAAS;AAClB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,gBAAS;AACT,qBAAS,0BAAU;AACnB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,eAAS;AAEF,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
8
- "debugId": "56B4F99C3CC35C8764756E2164756E21",
7
+ "mappings": ";AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAA8B;AAC9B,6BAA0B;AAG1B,iBAAS;AACT,mBAAS;AACT,gBAAS;AACT,iBAAS;AACT,eAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,eAAS;AACT,kBAAS;AACT,eAAS;AACT,iBAAS,kBAAM;AACf,oBAAS,sBAAS;AAClB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,iBAAS;AACT,iBAAS;AACT,gBAAS;AACT,gBAAS;AACT,qBAAS,0BAAU;AACnB,kBAAS;AACT,eAAS;AACT,eAAS;AACT,gBAAS;AACT,eAAS;AACT,eAAS,gBAAI,oBAAS,gBAAQ;AAC9B,oBAAS;AAEF,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AACR;",
8
+ "debugId": "48840C464F27115B64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -0,0 +1,94 @@
1
+ // src/commands/sh/sh.ts
2
+ async function readShellFile(fs, cwd, pathName, stderr) {
3
+ const path = fs.resolve(cwd, pathName);
4
+ if (!await fs.exists(path)) {
5
+ await stderr.writeText(`sh: ${pathName}: No such file or directory
6
+ `);
7
+ return { ok: false, exitCode: 127 };
8
+ }
9
+ const stat = await fs.stat(path);
10
+ if (stat.isDirectory()) {
11
+ await stderr.writeText(`sh: ${pathName}: is a directory
12
+ `);
13
+ return { ok: false, exitCode: 126 };
14
+ }
15
+ if (!stat.isFile()) {
16
+ await stderr.writeText(`sh: ${pathName}: not a file
17
+ `);
18
+ return { ok: false, exitCode: 126 };
19
+ }
20
+ try {
21
+ return { ok: true, source: await fs.readFile(path, "utf-8") };
22
+ } catch (err) {
23
+ const message = err instanceof Error ? err.message : String(err);
24
+ await stderr.writeText(`sh: ${pathName}: ${message}
25
+ `);
26
+ return { ok: false, exitCode: 126 };
27
+ }
28
+ }
29
+ var sh = async (ctx) => {
30
+ if (!ctx.shell) {
31
+ await ctx.stderr.writeText(`sh: shell evaluation not supported
32
+ `);
33
+ return 1;
34
+ }
35
+ if (ctx.args.length === 0) {
36
+ return ctx.shell.runShell(await ctx.stdin.text(), { argv0: "sh", args: [] });
37
+ }
38
+ const first = ctx.args[0];
39
+ if (first === "-c") {
40
+ const source = ctx.args[1];
41
+ if (source === undefined) {
42
+ await ctx.stderr.writeText(`sh: -c requires an argument
43
+ `);
44
+ return 2;
45
+ }
46
+ const argv0 = ctx.args[2] ?? "sh";
47
+ const args = ctx.args[2] === undefined ? [] : ctx.args.slice(3);
48
+ return ctx.shell.runShell(source, { argv0, args });
49
+ }
50
+ if (first.startsWith("-")) {
51
+ await ctx.stderr.writeText(`sh: unsupported option: ${first}
52
+ `);
53
+ return 2;
54
+ }
55
+ const loaded = await readShellFile(ctx.fs, ctx.cwd, first, ctx.stderr);
56
+ if (!loaded.ok) {
57
+ return loaded.exitCode;
58
+ }
59
+ return ctx.shell.runShell(loaded.source, { argv0: first, args: ctx.args.slice(1) });
60
+ };
61
+ var evalCmd = async (ctx) => {
62
+ if (!ctx.shell) {
63
+ await ctx.stderr.writeText(`eval: shell evaluation not supported
64
+ `);
65
+ return 1;
66
+ }
67
+ if (ctx.args.length === 0) {
68
+ return 0;
69
+ }
70
+ return ctx.shell.eval(ctx.args.join(" "));
71
+ };
72
+ var source = async (ctx) => {
73
+ if (!ctx.shell) {
74
+ await ctx.stderr.writeText(`source: shell evaluation not supported
75
+ `);
76
+ return 1;
77
+ }
78
+ const path = ctx.args[0];
79
+ if (path === undefined) {
80
+ await ctx.stderr.writeText(`source: filename argument required
81
+ `);
82
+ return 2;
83
+ }
84
+ return ctx.shell.source(path, ctx.args.slice(1));
85
+ };
86
+ var dot = source;
87
+ export {
88
+ source,
89
+ sh,
90
+ evalCmd,
91
+ dot
92
+ };
93
+
94
+ //# debugId=F711664330E99B5E64756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/commands/sh/sh.ts"],
4
+ "sourcesContent": [
5
+ "import type { Command, Stderr, VirtualFS } from \"../../types.mjs\";\n\nasync function readShellFile(\n fs: VirtualFS,\n cwd: string,\n pathName: string,\n stderr: Stderr\n): Promise<{ ok: true; source: string } | { ok: false; exitCode: number }> {\n const path = fs.resolve(cwd, pathName);\n\n if (!(await fs.exists(path))) {\n await stderr.writeText(`sh: ${pathName}: No such file or directory\\n`);\n return { ok: false, exitCode: 127 };\n }\n\n const stat = await fs.stat(path);\n if (stat.isDirectory()) {\n await stderr.writeText(`sh: ${pathName}: is a directory\\n`);\n return { ok: false, exitCode: 126 };\n }\n if (!stat.isFile()) {\n await stderr.writeText(`sh: ${pathName}: not a file\\n`);\n return { ok: false, exitCode: 126 };\n }\n\n try {\n return { ok: true, source: await fs.readFile(path, \"utf-8\") };\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await stderr.writeText(`sh: ${pathName}: ${message}\\n`);\n return { ok: false, exitCode: 126 };\n }\n}\n\nexport const sh: Command = async (ctx) => {\n if (!ctx.shell) {\n await ctx.stderr.writeText(\"sh: shell evaluation not supported\\n\");\n return 1;\n }\n\n if (ctx.args.length === 0) {\n return ctx.shell.runShell(await ctx.stdin.text(), { argv0: \"sh\", args: [] });\n }\n\n const first = ctx.args[0]!;\n if (first === \"-c\") {\n const source = ctx.args[1];\n if (source === undefined) {\n await ctx.stderr.writeText(\"sh: -c requires an argument\\n\");\n return 2;\n }\n\n const argv0 = ctx.args[2] ?? \"sh\";\n const args = ctx.args[2] === undefined ? [] : ctx.args.slice(3);\n return ctx.shell.runShell(source, { argv0, args });\n }\n\n if (first.startsWith(\"-\")) {\n await ctx.stderr.writeText(`sh: unsupported option: ${first}\\n`);\n return 2;\n }\n\n const loaded = await readShellFile(ctx.fs, ctx.cwd, first, ctx.stderr);\n if (!loaded.ok) {\n return loaded.exitCode;\n }\n\n return ctx.shell.runShell(loaded.source, { argv0: first, args: ctx.args.slice(1) });\n};\n\nexport const evalCmd: Command = async (ctx) => {\n if (!ctx.shell) {\n await ctx.stderr.writeText(\"eval: shell evaluation not supported\\n\");\n return 1;\n }\n if (ctx.args.length === 0) {\n return 0;\n }\n return ctx.shell.eval(ctx.args.join(\" \"));\n};\n\nexport const source: Command = async (ctx) => {\n if (!ctx.shell) {\n await ctx.stderr.writeText(\"source: shell evaluation not supported\\n\");\n return 1;\n }\n const path = ctx.args[0];\n if (path === undefined) {\n await ctx.stderr.writeText(\"source: filename argument required\\n\");\n return 2;\n }\n return ctx.shell.source(path, ctx.args.slice(1));\n};\n\nexport const dot = source;\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "F711664330E99B5E64756E2164756E21",
9
+ "names": []
10
+ }
@@ -18,7 +18,7 @@ import {
18
18
  isUntilNode,
19
19
  isCaseNode
20
20
  } from "./parser/index.mjs";
21
- import { Interpreter, BreakException, ContinueException } from "./interpreter/index.mjs";
21
+ import { Interpreter, BreakException, ContinueException, ExitException } from "./interpreter/index.mjs";
22
22
  import { createVirtualFS } from "./fs/index.mjs";
23
23
  import {
24
24
  FileSystem,
@@ -71,8 +71,9 @@ export {
71
71
  LexError,
72
72
  Interpreter,
73
73
  FileSystem,
74
+ ExitException,
74
75
  ContinueException,
75
76
  BreakException
76
77
  };
77
78
 
78
- //# debugId=C4DB171A1954453764756E2164756E21
79
+ //# debugId=D29830CA96A8F15764756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../src/index.ts"],
4
4
  "sourcesContent": [
5
- "// Main class exports\nexport { ShellDSL, createShellDSL, type Program } from \"./shell-dsl.mjs\";\nexport { ShellPromise, type ShellPromiseOptions } from \"./shell-promise.mjs\";\n\n// Types\nexport type {\n VirtualFS,\n VirtualFSWritable,\n FileStat,\n Command,\n CommandContext,\n Stdin,\n Stdout,\n Stderr,\n OutputCollector,\n ExecResult,\n ShellConfig,\n RawValue,\n} from \"./types.mjs\";\nexport { isRawValue } from \"./types.mjs\";\n\n// Errors\nexport { ShellError, LexError, ParseError } from \"./errors.mjs\";\n\n// Lexer\nexport { Lexer, lex, tokenToString } from \"./lexer/index.mjs\";\nexport type { Token, RedirectMode } from \"./lexer/index.mjs\";\n\n// Parser\nexport { Parser, parse } from \"./parser/index.mjs\";\nexport type {\n ASTNode,\n Redirect,\n CommandNode,\n PipelineNode,\n AndNode,\n OrNode,\n SequenceNode,\n WordNode,\n WordPart,\n TextPart,\n VariablePart,\n SubstitutionPart,\n ArithmeticPart,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n} from \"./parser/index.mjs\";\nexport {\n isWordNode,\n isCommandNode,\n isPipelineNode,\n isAndNode,\n isOrNode,\n isSequenceNode,\n isIfNode,\n isForNode,\n isWhileNode,\n isUntilNode,\n isCaseNode,\n} from \"./parser/index.mjs\";\n\n// Interpreter\nexport { Interpreter, type InterpreterOptions, BreakException, ContinueException } from \"./interpreter/index.mjs\";\n\n// Filesystem\nexport { createVirtualFS } from \"./fs/index.mjs\";\nexport {\n FileSystem,\n ReadOnlyFileSystem,\n WebFileSystem,\n createWebUnderlyingFS,\n type PathOps,\n type Permission,\n type PermissionRules,\n type UnderlyingFS,\n} from \"./fs/index.mjs\";\n\n// I/O\nexport { createStdin, StdinImpl } from \"./io/index.mjs\";\nexport { createStdout, createStderr, createPipe, OutputCollectorImpl, PipeBuffer } from \"./io/index.mjs\";\n\n// Utilities\nexport { escape, escapeForInterpolation, globVirtualFS } from \"./utils/index.mjs\";\nexport type { GlobVirtualFS, GlobOptions } from \"./utils/index.mjs\";\n\n// Version Control\nexport { VersionControlSystem } from \"./vcs/index.mjs\";\nexport type {\n VCSConfig,\n VCSAttributeRule,\n VCSResolvedAttributes,\n VCSDiffMode,\n VCSPatchSuppressionReason,\n Revision,\n DiffEntry,\n TreeManifest,\n TreeEntry,\n FileEntry,\n DirectoryEntry,\n VCSIndexEntry,\n VCSIndexFile,\n CommitOptions,\n CheckoutOptions,\n LogOptions,\n LogEntry,\n BranchInfo,\n} from \"./vcs/index.mjs\";\n"
5
+ "// Main class exports\nexport { ShellDSL, createShellDSL, type Program } from \"./shell-dsl.mjs\";\nexport { ShellPromise, type ShellPromiseOptions } from \"./shell-promise.mjs\";\n\n// Types\nexport type {\n VirtualFS,\n VirtualFSWritable,\n FileStat,\n Command,\n CommandContext,\n Stdin,\n Stdout,\n Stderr,\n OutputCollector,\n ExecResult,\n ShellConfig,\n ShellCommandApi,\n ShellRunOptions,\n RawValue,\n} from \"./types.mjs\";\nexport { isRawValue } from \"./types.mjs\";\n\n// Errors\nexport { ShellError, LexError, ParseError } from \"./errors.mjs\";\n\n// Lexer\nexport { Lexer, lex, tokenToString } from \"./lexer/index.mjs\";\nexport type { Token, RedirectMode } from \"./lexer/index.mjs\";\n\n// Parser\nexport { Parser, parse } from \"./parser/index.mjs\";\nexport type {\n ASTNode,\n Redirect,\n CommandNode,\n PipelineNode,\n AndNode,\n OrNode,\n SequenceNode,\n WordNode,\n WordPart,\n TextPart,\n VariablePart,\n SubstitutionPart,\n ArithmeticPart,\n IfNode,\n ForNode,\n WhileNode,\n UntilNode,\n CaseNode,\n CaseClause,\n} from \"./parser/index.mjs\";\nexport {\n isWordNode,\n isCommandNode,\n isPipelineNode,\n isAndNode,\n isOrNode,\n isSequenceNode,\n isIfNode,\n isForNode,\n isWhileNode,\n isUntilNode,\n isCaseNode,\n} from \"./parser/index.mjs\";\n\n// Interpreter\nexport { Interpreter, type InterpreterOptions, BreakException, ContinueException, ExitException } from \"./interpreter/index.mjs\";\n\n// Filesystem\nexport { createVirtualFS } from \"./fs/index.mjs\";\nexport {\n FileSystem,\n ReadOnlyFileSystem,\n WebFileSystem,\n createWebUnderlyingFS,\n type PathOps,\n type Permission,\n type PermissionRules,\n type UnderlyingFS,\n} from \"./fs/index.mjs\";\n\n// I/O\nexport { createStdin, StdinImpl } from \"./io/index.mjs\";\nexport { createStdout, createStderr, createPipe, OutputCollectorImpl, PipeBuffer } from \"./io/index.mjs\";\n\n// Utilities\nexport { escape, escapeForInterpolation, globVirtualFS } from \"./utils/index.mjs\";\nexport type { GlobVirtualFS, GlobOptions } from \"./utils/index.mjs\";\n\n// Version Control\nexport { VersionControlSystem } from \"./vcs/index.mjs\";\nexport type {\n VCSConfig,\n VCSAttributeRule,\n VCSResolvedAttributes,\n VCSDiffMode,\n VCSPatchSuppressionReason,\n Revision,\n DiffEntry,\n TreeManifest,\n TreeEntry,\n FileEntry,\n DirectoryEntry,\n VCSIndexEntry,\n VCSIndexFile,\n CommitOptions,\n CheckoutOptions,\n LogOptions,\n LogEntry,\n BranchInfo,\n} from \"./vcs/index.mjs\";\n"
6
6
  ],
7
- "mappings": ";AACA;AACA;AAiBA;AAGA;AAGA;AAIA;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AACA;AAGA;AAIA;",
8
- "debugId": "C4DB171A1954453764756E2164756E21",
7
+ "mappings": ";AACA;AACA;AAmBA;AAGA;AAGA;AAIA;AAsBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA;AAGA;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA;AACA;AAGA;AAIA;",
8
+ "debugId": "D29830CA96A8F15764756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -13,10 +13,13 @@ function createCommandContext(options) {
13
13
  if (options.exec) {
14
14
  ctx.exec = options.exec;
15
15
  }
16
+ if (options.shell) {
17
+ ctx.shell = options.shell;
18
+ }
16
19
  return ctx;
17
20
  }
18
21
  export {
19
22
  createCommandContext
20
23
  };
21
24
 
22
- //# debugId=5FC196A79A9EB9E864756E2164756E21
25
+ //# debugId=114011848381283E64756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/interpreter/context.ts"],
4
4
  "sourcesContent": [
5
- "import type { CommandContext, VirtualFS, Stdin, Stdout, Stderr, ExecResult } from \"../types.mjs\";\n\nexport interface ContextOptions {\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 function createCommandContext(options: ContextOptions): CommandContext {\n const ctx: CommandContext = {\n args: options.args,\n stdin: options.stdin,\n stdout: options.stdout,\n stderr: options.stderr,\n fs: options.fs,\n cwd: options.cwd,\n env: options.env,\n setCwd: options.setCwd,\n };\n if (options.exec) {\n ctx.exec = options.exec;\n }\n return ctx;\n}\n"
5
+ "import type { CommandContext, VirtualFS, Stdin, Stdout, Stderr, ExecResult, ShellCommandApi } from \"../types.mjs\";\n\nexport interface ContextOptions {\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 shell?: ShellCommandApi;\n}\n\nexport function createCommandContext(options: ContextOptions): CommandContext {\n const ctx: CommandContext = {\n args: options.args,\n stdin: options.stdin,\n stdout: options.stdout,\n stderr: options.stderr,\n fs: options.fs,\n cwd: options.cwd,\n env: options.env,\n setCwd: options.setCwd,\n };\n if (options.exec) {\n ctx.exec = options.exec;\n }\n if (options.shell) {\n ctx.shell = options.shell;\n }\n return ctx;\n}\n"
6
6
  ],
7
- "mappings": ";AAcO,SAAS,oBAAoB,CAAC,SAAyC;AAAA,EAC5E,MAAM,MAAsB;AAAA,IAC1B,MAAM,QAAQ;AAAA,IACd,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,IAAI,QAAQ;AAAA,IACZ,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,IACb,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,IAAI,QAAQ,MAAM;AAAA,IAChB,IAAI,OAAO,QAAQ;AAAA,EACrB;AAAA,EACA,OAAO;AAAA;",
8
- "debugId": "5FC196A79A9EB9E864756E2164756E21",
7
+ "mappings": ";AAeO,SAAS,oBAAoB,CAAC,SAAyC;AAAA,EAC5E,MAAM,MAAsB;AAAA,IAC1B,MAAM,QAAQ;AAAA,IACd,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,IAAI,QAAQ;AAAA,IACZ,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ;AAAA,IACb,QAAQ,QAAQ;AAAA,EAClB;AAAA,EACA,IAAI,QAAQ,MAAM;AAAA,IAChB,IAAI,OAAO,QAAQ;AAAA,EACrB;AAAA,EACA,IAAI,QAAQ,OAAO;AAAA,IACjB,IAAI,QAAQ,QAAQ;AAAA,EACtB;AAAA,EACA,OAAO;AAAA;",
8
+ "debugId": "114011848381283E64756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,11 +1,12 @@
1
1
  // src/interpreter/index.ts
2
- import { Interpreter, BreakException, ContinueException } from "./interpreter.mjs";
2
+ import { Interpreter, BreakException, ContinueException, ExitException } from "./interpreter.mjs";
3
3
  import { createCommandContext } from "./context.mjs";
4
4
  export {
5
5
  createCommandContext,
6
6
  Interpreter,
7
+ ExitException,
7
8
  ContinueException,
8
9
  BreakException
9
10
  };
10
11
 
11
- //# debugId=71A1B05D75F46BFA64756E2164756E21
12
+ //# debugId=3382F60717545D4664756E2164756E21
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/interpreter/index.ts"],
4
4
  "sourcesContent": [
5
- "export { Interpreter, type InterpreterOptions, BreakException, ContinueException } from \"./interpreter.mjs\";\nexport { createCommandContext, type ContextOptions } from \"./context.mjs\";\n"
5
+ "export { Interpreter, type InterpreterOptions, BreakException, ContinueException, ExitException } from \"./interpreter.mjs\";\nexport { createCommandContext, type ContextOptions } from \"./context.mjs\";\n"
6
6
  ],
7
7
  "mappings": ";AAAA;AACA;",
8
- "debugId": "71A1B05D75F46BFA64756E2164756E21",
8
+ "debugId": "3382F60717545D4664756E2164756E21",
9
9
  "names": []
10
10
  }