<feed xmlns='http://www.w3.org/2005/Atom'>
<title>newos4/packages.json, branch v4.6.168</title>
<subtitle>newOS4 - the browser terminal that runs WebX11 user spaces</subtitle>
<id>https://newos.webx11.duckdns.org/newos4/atom?h=v4.6.168</id>
<link rel='self' href='https://newos.webx11.duckdns.org/newos4/atom?h=v4.6.168'/>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/'/>
<updated>2026-11-09T22:58:35+00:00</updated>
<entry>
<title>fix(newos4): six crash classes from the feedback queue (v4.6.158)</title>
<updated>2026-11-09T22:58:35+00:00</updated>
<author>
<name>Hermes SysOp</name>
<email>sysop@webx11.duckdns.org</email>
</author>
<published>2026-11-09T22:58:35+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=9f6744dd5cb99b904f9a23fce6f2d98e8332bbf8'/>
<id>urn:sha1:9f6744dd5cb99b904f9a23fce6f2d98e8332bbf8</id>
<content type='text'>
Each item is symptom -&gt; cause -&gt; fix, re-verified against the served bytes.

1. debug-ai panel threw "Cannot read properties of undefined (reading 'substring')"
   (RPT-20261108-231622). _updateDebugPanel and two sibling previews called
   JSON.stringify(entry.args).substring(); JSON.stringify(undefined) returns
   undefined, and _toolCallLog entries carry args: undefined for any tool call
   with no arguments. All three previews now go through _formatToolArgs(), which
   renders "null" and never throws.

2. test_module threw "Cannot convert undefined or null to object"
   (RPT-20261108-232127). Object.keys(instance.commands) assumed every module
   initialises a command map. The throw landed after loadModuleFromCode had
   already succeeded, so the rolledBack:true branches were skipped and an
   unverified module stayed loaded. Both sites now require instance.commands.

3. list_files threw "originalPath.replace is not a function" (RPT-20261109-172742,
   3 occurrences in errors.json). A model can send a non-string path despite the
   schema. The path family (list_files/read_file/write_file/make_directory/
   delete_file) now coerces through _pathArg() and answers the tool's own honest
   error instead of a TypeError.

4. wpm search failed for EVERY keyword (RPT-20261109-123907): packages.json entry
   `kanban` used `description` while the other 31 use `desc`, and search() called
   pkg.desc.toLowerCase() mid-loop. Catalog reads now go through _pkg() /
   _packageMap() (desc || description, values coerced to strings), and the kanban
   entry carries name/version/desc/commands. Re-running the original loop for
   pdf/git/zzz is clean.

5. wx/webxai/webx turned a chat-lock timeout into an unhandled rejection
   (RPT-20261107-150726): forwardToAI() called chat(args) in a synchronous
   function without returning or catching the promise, so the 10 s busy throw
   never reached dispatchCommand's catch. It now returns the promise with a
   .catch that prints "AI error: ..." through terminal.print — console.error is
   hooked by the debug supervisor and would re-file the same report.

6. CryptoGzip._base64ToBytes threw a raw DOMException on non-base64 input
   (RPT-20261102-203616). It now validates first and throws
   Error("not valid base64 input (&lt;reason&gt;)"). The duplicate shadowing
   definitions at the bottom of the class were deleted — the later copy is the
   one that carried the unguarded atob().

Also regenerated modules/core/core-bundle.js (generated, never hand-edited) and
bumped the build v4.6.157 -&gt; v4.6.158 (main.html x3 + module-loader.js).

Verified: 35/35 node tests, including 6 new regression tests each proven red
against the pre-fix source; an independent orchestrator harness 36/36; and
newos4-maintain.py --fix all PASS after regenerating the stale changelog page.
Served bytes are byte-identical for the bundle, main.html and both ext modules,
and a live headless-Chromium run against v4.6.158 shows WpmModule.search('pdf')
returning 1 result, the debug panel rendering a no-arg entry as "null",
_base64ToBytes('grüße') raising a plain Error that names base64, and 0 JS errors
on load.

m.pull (RPT-20261102-211438) is closed as a usage error: no module in the tree
defines pull(); the real interfaces are the webdav-pull and model-pull commands.
</content>
</entry>
<entry>
<title>feat(newos4): six interface modes (easy -&gt; cockpit) over one terminal</title>
<updated>2026-11-07T17:19:47+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-11-07T17:19:47+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=aac2b1c0689aefeb140e08c24278ec486611fe10'/>
<id>urn:sha1:aac2b1c0689aefeb140e08c24278ec486611fe10</id>
<content type='text'>
Symptom: newOS4 had exactly one layout. A first-time user had no way in that did
not require learning commands, and an operator had no surface showing live runtime
state; the only way to see heap/VFS/tool-call telemetry was to type cat /sys/...

Root cause: no UI layer existed. main.html hard-codes one flex column, and
terminal.js binds the stock nodes by id at construction, so an alternative layout
had to either duplicate the output stream or reparent the real nodes.

Fix:
- modules/core/module-uishell.js (new): mode registry, #ui-root, stock-node
  snapshot/restore, identity check that reverts to classic when a mode removes or
  clones #terminal-container, shell-docked #ui-foot (the AI stop button exists in
  every mode), ui command, gated first-run picker, ?ui= honoured only if the mode
  actually registers, lazy mode loading via the same loader ext modules use.
- modules/ext/ui-{easy,chat,studio,workspace,commander,cockpit}.js (new): six
  reparenting skins with scoped CSS. Workspace/commander/cockpit read real /sys/*
  mounts and captured command output; no value on screen is invented.
- modules/test/test-ui-shell.js (new): 25 assertions - teardown, clone rejection,
  failed-mount fallback, footer docking, destructive-mode rejection.
- terminal.js: register the shell; make one failing ext module stop aborting the
  rest of the serial load loop (it did, silently, which is why six ui-* files at
  the end of extKeys never loaded).
- module-loader.js: LATEST_VER v4.6.152. The six ui-* keys are deliberately NOT
  in extKeys - see the rate-limit note below.
- admin/scripts/probe-ui-modes.py (new): 6 modes x 2 viewports plus a --cycle pass
  that switches all seven states on ONE page and asserts the output node keeps its
  identity.

Also fixed, found while testing (pre-existing, production-affecting):
- nginx limit_req zone=webx11 burst 50 -&gt; 200. One newOS4 boot fans out ~40 assets;
  the bucket emptied mid-boot and every later module got 503. Measured in
  webx11.error.log: "limiting requests, excess: 50.696 by zone webx11" against
  modules/ext/ui-chat.js. A reload within ~50 s silently broke modules. Sustained
  rate unchanged at 60r/m.

Verified: node modules/test/test-ui-shell.js -&gt; 25/25; removing both _restoreStock()
calls measures 20/25 with five FAILs; probe-ui-modes.py --cycle against production -&gt;
ALL PASS, 13 checks; served bytes: v4.6.152 x3 in main.html, class UIShellModule x1
in core-bundle.js, six ui-* packages in packages.json.
</content>
</entry>
<entry>
<title>newOS4: interactive AI course (terminal module, portal, atlas, telemetry, daily maintenance+cron) + free store card</title>
<updated>2026-10-18T12:05:18+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-10-18T12:05:18+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=88ad8ed2fbbda61920b11a79df29acb58928b5af'/>
<id>urn:sha1:88ad8ed2fbbda61920b11a79df29acb58928b5af</id>
<content type='text'>
</content>
</entry>
<entry>
<title>fix: add kanban to packages.json, update cache version to 2026-07-29</title>
<updated>2026-07-29T20:31:53+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-07-29T20:31:53+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=17c2d8bc91d99eb9f102254bcd650204c5c9426c'/>
<id>urn:sha1:17c2d8bc91d99eb9f102254bcd650204c5c9426c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-07-02_06:00 changes</title>
<updated>2026-07-02T04:00:40+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-07-02T04:00:40+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=ea4d09fb5ccba12ed774fcf7c913edfa1e6a851a'/>
<id>urn:sha1:ea4d09fb5ccba12ed774fcf7c913edfa1e6a851a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-06-23_06:00 changes</title>
<updated>2026-06-23T04:00:45+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-06-23T04:00:45+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=e9b75cd3a801689f57bc8a013f14c058e57e3b46'/>
<id>urn:sha1:e9b75cd3a801689f57bc8a013f14c058e57e3b46</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-06-22_18:00 changes</title>
<updated>2026-06-22T16:00:43+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-06-22T16:00:43+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=6f6161562c5f1028256f3163083b665719741646'/>
<id>urn:sha1:6f6161562c5f1028256f3163083b665719741646</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-06-16_06:00 changes</title>
<updated>2026-06-16T04:01:21+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-06-16T04:01:21+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=6aa24b976952a698c673d350977721b27193183d'/>
<id>urn:sha1:6aa24b976952a698c673d350977721b27193183d</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-06-10_06:00 changes</title>
<updated>2026-06-10T04:00:30+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-06-10T04:00:30+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=39b2df36ee5ccea52558d0537bfee87058558e94'/>
<id>urn:sha1:39b2df36ee5ccea52558d0537bfee87058558e94</id>
<content type='text'>
</content>
</entry>
<entry>
<title>auto: 2026-06-09_06:00 changes</title>
<updated>2026-06-09T04:00:43+00:00</updated>
<author>
<name>Agando</name>
<email>roduccomm@gmail.com</email>
</author>
<published>2026-06-09T04:00:43+00:00</published>
<link rel='alternate' type='text/html' href='https://newos.webx11.duckdns.org/newos4/commit/?id=9f60030e39feecc76f11671a4b9d82303c83670c'/>
<id>urn:sha1:9f60030e39feecc76f11671a4b9d82303c83670c</id>
<content type='text'>
</content>
</entry>
</feed>
