aboutsummaryrefslogtreecommitdiff
path: root/modules/core/module-loader.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-10-27 16:23:21 +0100
committerAgando <roduccomm@gmail.com>2026-10-27 16:23:21 +0100
commitf325b6d15179bb02147039c89e9fcfac6d8e067b (patch)
treebdd839cbed1efa77c0b896c6a3511d1b575f41e1 /modules/core/module-loader.js
parent2e9401a5587b0a45daaf0af116bb7da573b0988d (diff)
feat(newos4): the script runner runs scripts — control flow, variables, globs, redirects, stdin
MAINT-021 and MAINT-017, executed from .hermes/plans/2026-10-27_145500-newos4-script-runner.md. - shell.js: new block parser (_parseBlocks) and executor (_runInstructions/_runSimple/_runCommand/ _dispatchOne). `for`/`while`/`if` bodies now run, including one-line `if [ -f x ]; then y; fi`. Variables expand through _expandVars ($VAR, ${VAR}, $?, single quotes literal), globs expand through _expandGlobs (unquoted args only, per-command), and `>`/`>>` capture the command's output into the VFS instead of being passed to the command as text. - shell.js: a script never answers an unknown command by calling the AI any more. It prints `script:<path>:<line>: <cmd>: command not found` and sets $? — the AI fallback stays for typing. - shell.js: unclosed blocks and bad `for` headers surface as `Script <path> failed: …` (the parse used to sit outside the try, so a bad script crashed the runner). - shell.js: interactive path gets the same treatment — prompt globbing and `echo hi > /f` now work. Cause of the asymmetry: the two code paths had separate dispatch. - shell.js: `_isPipeAware` no longer injects the __pipebuf__ file into wc (it reads _pipeInput), and the module registers itself with a versioned URL and calls its own init() — registerModule() does not call init(), so the executeCommand wrapper was never installed from the boot bundle. - module-fs.js: wc/head/tail/grep read piped stdin when no file operand is given; `cat` accepts several operands (`cat *.txt`); `ls <file>` names the file instead of printing "(empty)". - main.html: shell.js removed from the extension list — it is already inside critical-ext-bundle.js, and loading it twice produced two ShellModule instances that could disagree about their version. Verification: - test-shell-script.js 27 asserts (parser, variables, globs, executor, redirect, command-not-found, one-line if, parse error). RED on HEAD: `TypeError: shell._parseBlocks is not a function`. - test-shell-stdin.js 16 asserts (added by a subagent): wc -l/-c, head -n, tail -n over stdin, and the file-argument path unchanged. - Suite 18/18 files; maintain --fix "node tests 18/18 pass". - Live on v4.6.115, through the real executeCommand: `ls /n*.txt` -> /n1.txt · `cat /n*.txt` -> one|two · `echo hi > /r.txt` then `cat /r.txt` -> hi · `cat /probe.txt | wc -l` -> 3 (bare, no __pipebuf__) · `script /run.sh` -> item 1 / item 2 / item 3 / exists / command not found, exit 1, no AI routing.
Diffstat (limited to 'modules/core/module-loader.js')
-rw-r--r--modules/core/module-loader.js7
1 files changed, 6 insertions, 1 deletions
diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js
index 329d0f7..29a1b62 100644
--- a/modules/core/module-loader.js
+++ b/modules/core/module-loader.js
@@ -4,8 +4,13 @@
// 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.110';
+ const LATEST_VER = 'v4.6.115';
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).
+ if (typeof window !== 'undefined' && window.webx11 && window.webx11.moduleManager) {
+ window.webx11.moduleManager.LATEST_VER = LATEST_VER;
+ }
const stored = localStorage.getItem('webx11_cache_ver');
if (stored !== LATEST_VER) {
localStorage.setItem('webx11_cache_ver', LATEST_VER);