diff options
Diffstat (limited to 'modules/core')
| -rw-r--r-- | modules/core/core-bundle.js | 14 | ||||
| -rw-r--r-- | modules/core/module-loader.js | 2 | ||||
| -rw-r--r-- | modules/core/terminal.js | 14 |
3 files changed, 23 insertions, 7 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js index fcf1505..9682596 100644 --- a/modules/core/core-bundle.js +++ b/modules/core/core-bundle.js @@ -2788,6 +2788,11 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm return null; } async checkAndRun(rawInput) { + // v4.6.130: keep the untokenised line for the command itself. _parseArgs turns + // quote characters into delimiters and drops them, so `js "abc".toUpperCase()` + // reaches the module as `abc.toUpperCase()` and every string literal dies. + // Security classification still runs on the tokenised form below. + this._currentRaw = rawInput; const badOp = this.detectComposition(rawInput); if (badOp) { this.terminal.print('⚠️ No shell here — `' + badOp + '` is not interpreted. ' + @@ -2870,7 +2875,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm return this._dispatch(cmd, args); } async _dispatch(cmd, args) { - return this.terminal.dispatchCommand(cmd, args); + return this.terminal.dispatchCommand(cmd, args, this._currentRaw || null); } async _tryAIRoute(rawInput) { // AI routing cooldown guard @@ -4215,7 +4220,10 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm } return trimmed; } - async dispatchCommand(cmd, args) { + // rawText (v4.6.130): the untokenised command line, when the call came from the + // terminal. Commands that need their delimiters (`js`, `node -e`) read it; every + // other command keeps using `args` and ignores the extra parameter. + async dispatchCommand(cmd, args, rawText) { if (cmd === 'clear') { this.clearOutput(); return; } if (cmd === 'expand') { this.toggleExpand(); return; } if (cmd === 'sysmsg') { this.toggleSystemMessages(args[0]); return; } @@ -4522,7 +4530,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm if (typeof _m.onCommandStart === 'function') { try { _m.onCommandStart(cmd, args); } catch (_e) {} } } } - try { await mod.commands[cmd](args); + try { await mod.commands[cmd](args, rawText); if (cmd !== 'tutorial' && cmd !== 'course') { for (const _m of Object.values(this.moduleManager.modules)) { if (typeof _m.onCommandExecuted === 'function') { try { _m.onCommandExecuted(cmd, args); } catch (_e) {} } diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 1d79b3a..ad6d0b7 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -4,7 +4,7 @@ // Core module bundle loaded synchronously in main.html. // This loader only handles version cache-busting, splash, terminal init, and optional ext modules. - const LATEST_VER = 'v4.6.128'; + const LATEST_VER = 'v4.6.130'; const CACHE = '?v=' + LATEST_VER; // Exposed so ext modules can register their own URL with the same cache-busting version // instead of an unversioned path the browser may already have cached (shell.js did). diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 76406b5..16e2c7e 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -196,6 +196,11 @@ return null; } async checkAndRun(rawInput) { + // v4.6.130: keep the untokenised line for the command itself. _parseArgs turns + // quote characters into delimiters and drops them, so `js "abc".toUpperCase()` + // reaches the module as `abc.toUpperCase()` and every string literal dies. + // Security classification still runs on the tokenised form below. + this._currentRaw = rawInput; const badOp = this.detectComposition(rawInput); if (badOp) { this.terminal.print('⚠️ No shell here — `' + badOp + '` is not interpreted. ' + @@ -278,7 +283,7 @@ return this._dispatch(cmd, args); } async _dispatch(cmd, args) { - return this.terminal.dispatchCommand(cmd, args); + return this.terminal.dispatchCommand(cmd, args, this._currentRaw || null); } async _tryAIRoute(rawInput) { // AI routing cooldown guard @@ -1623,7 +1628,10 @@ } return trimmed; } - async dispatchCommand(cmd, args) { + // rawText (v4.6.130): the untokenised command line, when the call came from the + // terminal. Commands that need their delimiters (`js`, `node -e`) read it; every + // other command keeps using `args` and ignores the extra parameter. + async dispatchCommand(cmd, args, rawText) { if (cmd === 'clear') { this.clearOutput(); return; } if (cmd === 'expand') { this.toggleExpand(); return; } if (cmd === 'sysmsg') { this.toggleSystemMessages(args[0]); return; } @@ -1930,7 +1938,7 @@ if (typeof _m.onCommandStart === 'function') { try { _m.onCommandStart(cmd, args); } catch (_e) {} } } } - try { await mod.commands[cmd](args); + try { await mod.commands[cmd](args, rawText); if (cmd !== 'tutorial' && cmd !== 'course') { for (const _m of Object.values(this.moduleManager.modules)) { if (typeof _m.onCommandExecuted === 'function') { try { _m.onCommandExecuted(cmd, args); } catch (_e) {} } |