| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Found by running the shipped runner the way a user would, not by re-reading it.
- _evalTest() stripped [ ] but not the `test` keyword, so `if test -f /work/alpha.txt` evaluated
the word "test" as an operator, returned false, and every such branch took the else arm —
measured live: "alpha missing" for a file that exists. Both spellings work now
(`test -f x`, `[ -f x ]`), plus `-d`, `-e`, `-z`, `-n`, `!` and the = / != comparisons.
- `for f in /work/*.txt` ran ONCE with $f set to the literal pattern, because only command
arguments went through _expandGlobs. Loop items are expanded per iteration now, so the body runs
once per matched file with the real path.
- _expandGlobs() falls back to readDir() when a fs has no ls(), so the helper works against either
shape instead of silently returning the literal pattern.
Verification, live on v4.6.119:
- for+glob: "--- /work/alpha.txt / 3 /work/alpha.txt / --- /work/beta.txt / 1 /work/beta.txt"
(6 statements, exit 0) — previously one iteration printing the pattern.
- conditionals: "alpha exists", "nope missing", grep + $? intact.
- end-to-end /work/report.sh (loop + glob + >> append + test -f) wrote a correct log:
"start / file: /work/alpha.txt / 3 /work/alpha.txt / file: /work/beta.txt / 1 /work/beta.txt …".
- unknown command still reports "command not found" and never calls the AI.
- test-shell-script.js 27 -> 35 asserts.
Retracted: I reported `echo x > file` as broken. It was my probe monkey-patching terminal.print,
which bypassed the capture stack the redirect uses. Both paths write correctly:
direct helper -> "direct-call", prompt -> "prompt-call\n".
|
|
|
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.
|