diff options
Diffstat (limited to 'modules/ext')
| -rw-r--r-- | modules/ext/console.js | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/modules/ext/console.js b/modules/ext/console.js index 60f75a7..f2731f1 100644 --- a/modules/ext/console.js +++ b/modules/ext/console.js @@ -14,12 +14,17 @@ class JSConsoleModule { } registerCommands() { - this.commands['js'] = (args) => this.evalJS(args); + // rawText is the untokenised line from the dispatcher (v4.6.130): `js "abc".toUpperCase()` + // must reach eval with its quotes, and _parseArgs deletes them. + this.commands['js'] = (args, rawText) => this.evalJS(args, rawText); this.commands['js-run'] = (args) => this.evalJSFile(args); this.commands['node'] = (args) => { // Bridge: AI hallucinates `node script.js` — map to js-run if (!args[0]) return this.terminal.print('Usage: node <script.js> (alias for js-run)', 'warning'); - // Handle `node -e "expr"` — inline eval like Node.js + // Handle `node -e "expr"` — inline eval like Node.js. No rawText here on purpose: + // _parseArgs keeps `'…'` inside `"…"` verbatim, so `args` already carries the + // expression, whereas the raw form would hand eval `"import('fs')"` (a string + // literal) instead of `import('fs')` (an import). Measured v4.6.130. if (args[0] === '-e') { return this.evalJS(args.slice(1)); } @@ -27,9 +32,19 @@ class JSConsoleModule { }; } - evalJS(args) { + // The expression to evaluate: the raw remainder when the terminal provided one, + // otherwise the tokenised arguments (AI tool calls, script runner, direct calls). + _expr(args, rawText) { + if (typeof rawText === 'string') { + const rest = rawText.trim().replace(/^\S+\s*/, ''); // drop the command word + if (rest) return rest; + } + return (args || []).join(' '); + } + + evalJS(args, rawText) { if (!args[0]) return this.terminal.print('Usage: js <expression>', 'warning'); - const expr = args.join(' '); + const expr = this._expr(args, rawText); // v4.6.128: Sandboxed eval — restrict access to dangerous globals, still allows math/JSON/Array etc. try { const result = (function() { @@ -68,7 +83,8 @@ class JSConsoleModule { _printError(e) { const msg = (e && e.message) ? e.message : String(e); this.terminal.print(`Error: ${msg}`, 'error'); - const m = /(?:Failed to resolve module specifier|Cannot find module) '([^']+)'/.exec(msg); + const m = /(?:Failed to resolve module specifier|Cannot find module) '([^']+)'/.exec(msg) + || /No such built-in module: ?([\w@/.:-]+)/.exec(msg); if (m) { this.terminal.print(`'${m[1]}' is a Node built-in; the browser has no Node — ` + `use the VFS (ls/cat/run, terminal.fs) instead`, 'warning'); |