aboutsummaryrefslogtreecommitdiff
path: root/modules/ext/critical-ext-bundle.js
Commit message (Collapse)AuthorAgeFilesLines
* fix(newos4): `if test …` was always false and `for` items never globbedAgando11 days1-6/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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".
* fix(newos4): piped grep searched the working directory instead of its inputAgando11 days1-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | The stdin work in 5cf5010 fixed wc/head/tail but left grep alone, and grep's no-operand branch sweeps the cwd. Measured on v4.6.115: `cat /gdir/in.txt | grep zzz` answered `other.txt:1: zzz in a cwd file` — a file that was never piped, and `cat in.txt | grep bbb` reported the match twice (`in.txt` from the cwd sweep plus `__pipebuf__` from the injected file). - module-fs.js: when terminal._pipeInput is set and no file operand was given, grep searches the staged text and prints `<line>: <text>` (stdin has no filename, as in GNU). The cwd sweep stays for a bare interactive `grep x`. - shell.js: _isPipeAware now covers only sort/cut/uniq/expand. grep/head/tail/wc read _pipeInput themselves, so injecting the __pipebuf__ file produced duplicate hits and named stdin results. Verification: - test-shell-stdin.js 20 asserts (+4 for grep: no cwd match, non-match reports none, match prints no filename, -c counts stdin). RED on HEAD: G1/G2/G3 fail with `other.txt:1: zzz in a cwd file`. - Suite 18/18 files; maintain --fix "node tests 18/18 pass". - Live v4.6.116 after `cd /gdir` (where other.txt contains zzz): `cat /gdir/in.txt | grep zzz` -> (no matches) · `| grep bbb` -> `2: bbb` · `| grep -c b` -> 1 · `| head -n 2` -> aaa,bbb · `| tail -n 1` -> ccc · `| wc -l` -> 3. Credit: the false-positive grep was reported by the stdin subagent as an aside; re-derived here against the live terminal before fixing.
* feat(newos4): the script runner runs scripts — control flow, variables, ↵Agando11 days1-62/+300
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* feat(newos4): cut/copy in Files, paste into WebDAV (Issue D2)Agando12 days1-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | The two panes kept separate clipboards (filemgr._clipboard vs webdav._selected), so "cut here, paste there" did not exist — the operator's last phone-test item. filemgr.js _openOverlay() publishes a read-only view of its clipboard on the terminal object: webx11.fileClipboard() / fileClipboardClear() / fileClipboardSet(paths, mode). webdav.js the bulk bar gains "📥 Paste N" (hidden when the clipboard is empty). Handler: for each path readFile -> _webdavRequest('PUT', dest + '/' + name, {body}); only 200/201/204 counts. For mode "cut" the local file is deleted AFTER the server accepted the bytes, never before. A failed PUT keeps the local copy, prints "📥 Paste failed: <name> — HTTP n", and leaves that path in the clipboard so "📥 Paste 1" is a retry. Successes leave it. Summary "📥 Pasted N item(s) to <path>" (+ "— M failed"), then the pane reopens there. Semantics: cut moves (upload then delete local), copy leaves the local file and keeps the clipboard so the same files can go into several folders. Verified with the transport stubbed in the live page (this browser has no WebDAV credential): button "📥 Paste 2" for a 2-path cut PUT ok (201) -> local file null (moved) PUT fail(500) -> local file "BBB" (kept) clipboard after -> {mode:"cut", paths:["/fail-d.txt"]}, button "📥 Paste 1" node --check both modules, no-undef clean (55 files), v4.6.101 x3 in main.html, syntax OK, help 362/362.
* fix(newos4): four phone-test defects — no preview close, single-file ↵Agando12 days1-50/+100
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | share, dead-end fullscreen, silent WebDAV move All four came from the operator's phone pass on v4.6.95 and each collapsed to a line of code. A "No file selected to download": the preview pane had no close control; the only ✕ was the file manager's own, and it calls _closeOverlay() which wipes _multiSelect/_selectedFile/_selectMode. On a phone the preview covers the list, so closing it before pressing Download always emptied the selection. The toolbar now starts with ✕ -> _clearPreview(), which keeps the selection and leaves fullscreen first; Download with no targets names the fix instead of stating a dead end. B share/copy: 🔗 existed only in the preview toolbar and took a single path, and after the Android share sheet there was no copy affordance. Added _sharePaths(paths, mode) used by both the toolbar (1 path, 📋 copy and 🔗 share) and a new action-bar 🔗 Share (whole selection), plus _inlineLinkBox() which renders a selectable input/textarea with all URLs when neither the share sheet nor the clipboard is available. No prompt() anywhere on this path. C fullscreen: requestFullscreen targeted .fm-preview-body, which sits INSIDE the pane but excludes the toolbar, so ⛶ and ✗ disappeared and only the OS back gesture got out. Now fullscreens #filemgr-preview — toolbar, ✕ and ⛶ stay on screen and ⛶ toggles. D webdav move: bulk Move asked for the destination with prompt(), which returns null in iOS standalone PWAs and most Android WebViews, so it silently did nothing and looked unimplemented. Destination is now an inline row in the bulk bar (44px input + "Move here"/"Cancel", prefilled). Verified on the served code: ext bundle md5 5f440c77b6ab5529729aee8019a6c351 (served == local), webdav.js carries wdav-move-dest x2, and a headless browser probe on the real page shows the toolbar as ["✕","⛶","📋","🔗"], closing the preview prints "Preview closed — selection kept" with the selection intact, selecting 3 files and copying yields a textarea with the 3 real WebDAV URLs, and Download with nothing selected explains what to do. 6 PASS on the URL test, no-undef clean, v4.6.99, help 362/362. Not done, deliberately: cut/copy + paste across the VFS/WebDAV border. Recorded as Issue D2 in the plan with the exact insertion points, the upload-then-delete ordering rule and the failure case.
* feat(newos4): mobile download/share UX — deferred blob revoke, ↵Agando12 days1-37/+105
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | multi-select, Web Share, 44px targets Executes .hermes/plans/2026-10-24_051600-newos4-mobile-download-share.md (approved via the feedback dashboard; marker autonomy: safe). Front-end only, v4.6.94 -> v4.6.95. T1 modules/ext/filemgr.js — URL.revokeObjectURL ran in the same tick as a.click(); iOS Safari and Android Chrome hand the blob: URL to the download manager asynchronously, so the transfer was aborted while the status line still said "Downloaded". Now revoked after 30 s. T2 download honours the multi-selection via _getSelectedPaths() (falling back to _selectedFile), reports "⬇ Downloaded N files" and "❌ Skipped <path>" instead of a silent partial success. T3 share: navigator.share -> clipboard.writeText -> inline read-only <input> (focused, selected). prompt() is suppressed in iOS standalone PWAs and most Android WebViews, which is why tapping 🔗 did nothing. Unresolvable space now reports "🔗 Share unavailable — no space resolved". T4 both preview toolbar buttons: min-height/min-width 44px, touch-action manipulation, 1em, gap 10px (was 24px/0.85em/6px — the smallest tap targets in the UI). T5 _previewShareUrl falls back _resolveSpaceName -> _detectSpaceName (webdav.js:22) -> page path, and returns null rather than emitting /spaces//<path>. T6 the URL helpers are now module-scope pure functions exported for Node, so modules/test/test-download-url.js tests the shipped code instead of a local copy (4 -> 6 cases). Also fixes a latent bug that made require() impossible: `typeof window.webx11` throws under Node because typeof does not protect a member access on an undefined global. Verified on the served bundle (filemgr.js is concatenated into critical-ext-bundle.js, NOT core-bundle.js — the plan's T7 grep pointed at the wrong file): HTTP 200, 129 867 B, 2x navigator.share, 3x fmBuildShareUrl, deferred revoke present, 11x min-height:44px. Live browser probe on /spaces/newos4/main.html: _previewShareUrl('docs/a.md') -> https://webx11.duckdns.org/spaces/newos4/docs/a.md (no double slash); with navigator.share absent and clipboard blocked, clicking 🔗 produced .fm-share-input containing that URL; button style ends min-height:44px;min-width:44px;touch-action:manipulation; toolbar gap:10px. node modules/test/test-download-url.js -> 6 PASS. lint-no-undef clean (55 files). maintain: PASS version v4.6.95 x3, syntax OK, HTTP 200 /main.html. Also adds admin/docs/session-overview-2026-10-26.md (glm-5.3-compressed session record).
* fix(newos4): download link uses the user's space; WebDAV share copies ↵Agando2026-10-211-7/+87
| | | | | | | | | | | | verified file links; preview fullscreen+share; files->WebDAV upload button (v4.6.45) - download: URL built from _resolveSpaceName() (config url = logged-in user), not the page space - WebDAV browser 🔗: shares selected FILES only, URL-encoded, HEAD-verified (200) before claiming success; folders offer a tar fallback instead of a guaranteed-403 link - file manager preview: ⛶ fullscreen + 🔗 copy-link toolbar (was none) - file manager toolbar: ☁ WebDAV publishes selected/current file via webdav-push - modules/test/test-download-url.js: 4 PASS - rebuild bundles, bump v4.6.44 -> v4.6.45 (loader + 3 script tags)
* newOS4 v4.6.40: review fixes (bug diagnostics, trash tree, dir paste, stale ↵Agando2026-10-181-4/+9
| | | | capture, preview)
* newOS4 v4.6.35: file manager multi-select + safe paste/rename/delete (Part B)Agando2026-10-181-81/+160
|
* newOS4 v4.6.15: reentrant print-capture stack, AI tail -f block, read-only ↵Agando2026-09-291-9/+11
| | | | sed in safeRead, security test harness (21 checks)
* auto: 2026-07-09_06:00 changesAgando2026-07-091-116/+199
|
* auto: 2026-06-22_18:00 changesAgando2026-06-221-5/+178
|
* auto: 2026-06-18_06:00 changesAgando2026-06-181-2/+5
|
* auto: 2026-06-17_06:01 changesAgando2026-06-171-1/+3
|
* auto: 2026-06-13_18:00 changesAgando2026-06-131-0/+2363