diff options
| author | Agando <roduccomm@gmail.com> | 2026-10-22 01:46:42 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-10-22 01:46:42 +0200 |
| commit | b640d13799c3dc98e08b9c9d53b745c4d0d76a3a (patch) | |
| tree | 95bb59f4d720bd34aa3f0c57578eb44b62a305cc | |
| parent | 8dd236e7a03b3cfe3cfb4a0d77b62ce112e4d418 (diff) | |
docs(newos4): clear the help.html command backlog, and make it detectable
help.html had not been touched since 2026-08-02. Auditing the page against the
code found 74 commands the runtime registers but the docs never mentioned, and
4 rows documenting commands that no longer exist.
Documented (by section): terminal 11 (dashboard --watch/--stop, usage, ps, top,
df, free, history, run, sysmsg, view_module), a2a 6, AI 14 (webxai/webx/wx,
context*/smart-ask, commit-*, ai-model/ai-ignore), vaultmind 4, debug 2, filesystem 2,
sessions 1, memory-graph 3, modules 4, neural-vfs 1, agents 3, web 1, voice 3,
config 3, extras 8 (kanban, three, course, gzip, wget, gui-*), vault 2 (encrypt/decrypt),
skills 5, webdav 1, plus an alias row for h/s/ll.
Removed ghost rows: commands, check, sandbox-kill, webdav-explorer -- none are
registered anywhere in modules/; the sandbox prose no longer promises sandbox-kill.
New check: scripts/newos4-maintain.py check_help_coverage() derives the command
list from terminal.js (_baseWhitelist, internals, cmd === dispatch) plus every
commands['...'] registration in modules/ and compares it with help.html, so the
next gap shows up in the daily maintenance run instead of rotting for 11 weeks.
Verified: html.parser 0 errors (before the fix my own insertion broke the page --
a signature containing <script> opened a script element), 355/355 commands
documented, maintenance OK, 449 command rows in the DOM, 360/390 px 4/4 OK,
perms fixed (atlas.json, course.js were 664).
| -rw-r--r-- | course/atlas.json | 22 | ||||
| -rw-r--r-- | help.html | 138 | ||||
| -rw-r--r-- | scripts/newos4-maintain.py | 30 |
3 files changed, 155 insertions, 35 deletions
diff --git a/course/atlas.json b/course/atlas.json index af43b8a..4eeeff4 100644 --- a/course/atlas.json +++ b/course/atlas.json @@ -1,5 +1,5 @@ { - "version": "2026-10-18T15:01:55Z", + "version": "2026-10-21T23:46:07Z", "source_hash": "fdf2b4d2aaf3dbc0", "commands": { "a2a-ack": { @@ -3058,7 +3058,7 @@ "file": "modules/core/module-world-model.js", "tier": "core-bundle", "category": "ai", - "desc": "world-model-ask <question> — Query the model (e.g. \"what changed since yesterday\")", + "desc": "world-model-ask <question> — Ask the LLM about this system (grounded in the world model; --facts for the instant keyword lookup)", "builtin": false, "example": "world-model-ask" }, @@ -3174,7 +3174,7 @@ "commands": [ "course" ], - "lines": 339 + "lines": 342 }, "cron": { "file": "modules/ext/cron.js", @@ -3232,7 +3232,7 @@ "files", "preview" ], - "lines": 1066 + "lines": 1151 }, "finder": { "file": "modules/ext/finder.js", @@ -3350,7 +3350,7 @@ "vaultmind-status", "wallet-lookup" ], - "lines": 4528 + "lines": 4678 }, "module-chatstudio": { "file": "modules/core/module-chatstudio.js", @@ -3386,7 +3386,7 @@ "debug-sync-url", "debug-trends" ], - "lines": 838 + "lines": 890 }, "module-fetcher": { "file": "modules/core/module-fetcher.js", @@ -3439,7 +3439,7 @@ "vfs-size", "wc" ], - "lines": 750 + "lines": 823 }, "module-leases": { "file": "modules/core/module-leases.js", @@ -3553,7 +3553,7 @@ "orchestrator-wake", "pipeline" ], - "lines": 1382 + "lines": 1442 }, "module-predictor": { "file": "modules/core/module-predictor.js", @@ -3656,7 +3656,7 @@ "uptime", "version" ], - "lines": 805 + "lines": 815 }, "module-world-model": { "file": "modules/core/module-world-model.js", @@ -3668,7 +3668,7 @@ "world-model-refresh", "world-model-summary" ], - "lines": 502 + "lines": 600 }, "secret-vault": { "file": "modules/core/secret-vault.js", @@ -3770,7 +3770,7 @@ "webdav-rm", "webdav-status" ], - "lines": 2346 + "lines": 2368 }, "wpm": { "file": "modules/ext/wpm.js", @@ -504,8 +504,6 @@ diff a.txt b.txt</pre> <tr><td><code>logrotate</code></td><td>Rotate current.log to dated archive</td><td><code>logrotate</code></td></tr> <tr><td><code>health-check</code></td><td>Audit VFS, modules, logs, trash, skills</td><td><code>health-check</code></td></tr> <tr><td><code>memory-map-export</code></td><td>Generate memory map from /memory/index.json</td><td><code>memory-map-export</code></td></tr> - <tr><td><code>commands</code></td><td>List commands with module source</td><td><code>commands</code></td></tr> - <tr><td><code>check</code></td><td>System health + module requirements</td><td><code>check</code></td></tr> <tr><td><code>checkpoint</code></td><td>Create VFS snapshot</td><td><code>checkpoint</code></td></tr> <tr><td><code>checkpoint-list</code></td><td>List VFS checkpoints</td><td><code>checkpoint-list</code></td></tr> <tr><td><code>rollback</code></td><td>Restore VFS from checkpoint</td><td><code>rollback</code></td></tr> @@ -619,7 +617,9 @@ diff a.txt b.txt</pre> <tr><td><code>session-delete</code></td><td>Delete a session</td><td><code>session-delete old</code></td></tr> <tr><td><code>session-export</code></td><td>Export session as JSON download</td><td><code>session-export mysession</code></td></tr> <tr><td><code>session-import</code></td><td>Import a session from file</td><td><code>session-import</code></td></tr> - </table></div> + <tr><td><code>sed -n 'N,Mp' | s/a/b/ | /pat/d | -i</code></td><td>Print or edit VFS file lines</td></tr> + <tr><td><code>files</code></td><td>Open the Files panel</td></tr> +</table></div> </section> <!-- ── AI Agent ── --> @@ -667,7 +667,21 @@ diff a.txt b.txt</pre> <tr><td><code>vaultmind_connect</code></td><td>Connect wallet to VaultMind AI (reads key from SecretVault)</td><td>❌</td></tr> <tr><td><code>vaultmind_status</code></td><td>Check VaultMind session status</td><td>❌</td></tr> <tr><td><code>vaultmind_query</code></td><td>Query VaultMind: prices, portfolio, chat</td><td>❌</td></tr> - </table></div> + <tr><td><code>webx <question></code></td><td>Ask the assistant (short alias of <code>webxai</code>)</td></tr> + <tr><td><code>webxai <question></code></td><td>Ask the assistant a one-off question</td></tr> + <tr><td><code>wx <question></code></td><td>Alias of <code>webxai</code></td></tr> + <tr><td><code>ai-model [name]</code></td><td>Show or set the active model</td></tr> + <tr><td><code>ai-ignore <path></code></td><td>Exclude a path from AI context</td></tr> + <tr><td><code>commit-status</code></td><td>Show the pending AI file-commit batch</td></tr> + <tr><td><code>commit-approve</code></td><td>Apply the pending AI file commits</td></tr> + <tr><td><code>commit-deny</code></td><td>Discard the pending AI file commits</td></tr> + <tr><td><code>context</code></td><td>Show the active AI context profile</td></tr> + <tr><td><code>contexts</code></td><td>List context profiles</td></tr> + <tr><td><code>context-new <name> <display> <systemPrompt></code></td><td>Create a context profile</td></tr> + <tr><td><code>context-delete <name></code></td><td>Delete a context profile</td></tr> + <tr><td><code>context-auto on|off</code></td><td>Auto-switch contexts</td></tr> + <tr><td><code>smart-ask <question></code></td><td>Ask with automatic context selection</td></tr> +</table></div> <h3>Sound Notification</h3> <p>A short <strong>"ding"</strong> plays via WebAudio when AI finishes. Toggle with the <strong>🔊 Sound</strong> button in quick-actions. Persists in localStorage.</p> @@ -752,7 +766,18 @@ skill-import</pre> <h3>Auto-Creation</h3> <p>When the AI encounters the same tool error 3+ times, a workaround skill is auto-created. Every 20 messages, skills are audited for staleness.</p> - </section> + <table> + <thead><tr><th>Command</th><th>Description</th></tr></thead> + <tbody> + <tr><td><code>learn-skill <topic></code></td><td>Learn a new skill from a topic</td></tr> + <tr><td><code>skill-validate <name></code></td><td>Validate a skill file</td></tr> + <tr><td><code>skill-audit</code></td><td>Audit all installed skills</td></tr> + <tr><td><code>skill-restore <name></code></td><td>Restore a skill from its backup</td></tr> + <tr><td><code>skill-pack-core</code></td><td>Install / verify the core skill pack</td></tr> + </tbody> + </table> + +</section> <!-- ── Ollama ── --> <section id="ollama"> @@ -809,7 +834,8 @@ ollamaconnect</pre> <tr><td><code>fetch</code> / <code>web</code></td><td>Fetcher</td><td>Fetch URL content</td><td><code>fetch https://example.com</code></td></tr> <tr><td><code>extract</code></td><td>Fetcher</td><td>Clean readable text</td><td><code>extract https://news.article</code></td></tr> <tr><td><code>images</code></td><td>SearXNG</td><td>Image search</td><td><code>images cats</code></td></tr> - </table></div> + <tr><td><code>videos <query></code></td><td>Video search via SearXNG</td></tr> +</table></div> <p>The AI agent also has <code>web_search</code> and <code>web_fetch</code> tools using the same APIs.</p> </section> @@ -828,7 +854,16 @@ ollamaconnect</pre> </ul> <h3>Sound</h3> <p>Toggle AI response "ding" with the <strong>🔊 Sound</strong> button. Persists in localStorage.</p> - </section> + <table> + <thead><tr><th>Command</th><th>Description</th></tr></thead> + <tbody> + <tr><td><code>speak <text></code></td><td>Speak text aloud (TTS)</td></tr> + <tr><td><code>voice</code></td><td>Voice settings and microphone test</td></tr> + <tr><td><code>analyze <file> [--frames N] [--spectrogram] [--beats] [--scene]</code></td><td>Analyze an audio or video file</td></tr> + </tbody> + </table> + +</section> <!-- ── Config ── --> <section id="config"> @@ -854,7 +889,10 @@ ollamaconnect</pre> <tr><td><code>webx11_ai_context</code></td><td>AI conversation history</td></tr> <tr><td><code>webx11_user_profile</code></td><td>AI user profile</td></tr> <tr><td><code>webx11_aliases</code></td><td>User-defined aliases</td></tr> - </table></div> + <tr><td><code>bug</code></td><td>Generate a bug report from the current session</td></tr> + <tr><td><code>factory-reset-old --confirm</code></td><td>Legacy full reset (prefer <code>factory-reset</code>)</td></tr> + <tr><td><code>setfont <px></code></td><td>Set terminal font size (alias of <code>font-size</code>)</td></tr> +</table></div> </section> <!-- ── Secret Vault ── --> @@ -874,7 +912,9 @@ ollamaconnect</pre> <tr><td><code>secret-unlock</code></td><td>Unlock the vault with PIN</td></tr> <tr><td><code>secret-setpin</code></td><td>Set or change vault PIN</td></tr> <tr><td><code>secret-status</code></td><td>Show vault status (locked/unlocked/pin set)</td></tr> - </table></div> + <tr><td><code>encrypt <path> <passphrase></code></td><td>AES-256-GCM encrypt a VFS file</td></tr> + <tr><td><code>decrypt <path.enc> <passphrase></code></td><td>Decrypt a .enc file</td></tr> +</table></div> </section> <!-- ── VaultMind AI ── --> @@ -905,7 +945,11 @@ ollamaconnect</pre> <tr><th>Path</th><th>Backend</th></tr> <tr><td><code>/vmai/</code></td><td>Proxied to VaultMind backend at <code>127.0.0.1:8000</code></td></tr> <tr><td><code>/vmai-api/</code></td><td>Alias for frontend chat — also proxied to <code>127.0.0.1:8000</code></td></tr> - </table></div> + <tr><td><code>vaultmind-connect</code></td><td>Connect VaultMind to the trading API</td></tr> + <tr><td><code>vaultmind-status</code></td><td>VaultMind connection and balance status</td></tr> + <tr><td><code>vaultmind-query <prices|portfolio|transactions|copy-trade|chat></code></td><td>Query VaultMind</td></tr> + <tr><td><code>wallet-lookup <address></code></td><td>Look up a wallet address</td></tr> +</table></div> </section> <!-- ── Modules ── --> @@ -927,7 +971,11 @@ ollamaconnect</pre> <tr><td><code>js <expr></code></td><td>Evaluate JavaScript in page context</td></tr> <tr><td><code>js-run <path></code></td><td>Load and execute a JS file from VFS</td></tr> <tr><td><code>startup-modules</code></td><td>Configure boot modules</td></tr> - </table></div> + <tr><td><code>module-load <name></code></td><td>Load a module by name</td></tr> + <tr><td><code>module-unload <name></code></td><td>Unload a module</td></tr> + <tr><td><code>module-enable <name></code></td><td>Enable a module for startup</td></tr> + <tr><td><code>module-reset <name></code></td><td>Reset a module to its shipped source</td></tr> +</table></div> <h3>Boot Order</h3> <ol> @@ -958,7 +1006,6 @@ ollamaconnect</pre> <tr><td><code>webdav-backup</code></td><td>Backup VFS</td></tr> <tr><td><code>webdav-restore</code></td><td>Restore VFS</td></tr> <tr><td><code>webdav-backup-list</code></td><td>List backups</td></tr> - <tr><td><code>webdav-explorer</code></td><td>Interactive text browser</td></tr> <tr><td><code>webdav-browser</code></td><td>Visual file explorer modal</td></tr> </table></div> @@ -988,7 +1035,15 @@ ollamaconnect</pre> <tr><td><code>server-check</code></td><td>Ping a server</td></tr> <tr><td><code>server-remove</code></td><td>Remove server</td></tr> <tr><td><code>monitor</code></td><td>Toggle auto-monitoring</td></tr> - </table></div> + <tr><td><code>course open <lessonId> | course list</code></td><td>Course browser</td></tr> + <tr><td><code>kanban add <task> | list | done <id></code></td><td>Task board</td></tr> + <tr><td><code>three add text <text> | reset | screenshot</code></td><td>3D scene commands</td></tr> + <tr><td><code>gui-run <command></code></td><td>Run a command and render its output in the GUI panel</td></tr> + <tr><td><code>gui-text <content></code></td><td>Render text in the GUI panel</td></tr> + <tr><td><code>gui-clear</code></td><td>Clear the GUI panel</td></tr> + <tr><td><code>gzip <path></code></td><td>Compress a VFS file to .gz</td></tr> + <tr><td><code>wget <url> [filename]</code></td><td>Download a URL and save it to the VFS</td></tr> +</table></div> @@ -1162,7 +1217,19 @@ sh greet.sh</pre> <tr><td><code>sh <path.sh></code></td><td>Alias for <code>script</code> — run a VFS script file</td></tr> <tr><td><code>alias [name=value]</code></td><td>List aliases or set a custom alias name=command</td></tr> <tr><td><code>unalias <name></code></td><td>Remove a custom alias</td></tr> - </table></div> + <tr><td><code>h</code> · <code>s</code> · <code>ll</code></td><td>Short aliases: <code>h</code> = help, <code>s</code> = web search, <code>ll</code> = detailed listing</td></tr> + <tr><td><code>dashboard [--watch|--stop]</code></td><td>Collect live telemetry and open the dashboard page; --watch re-collects every 5 s</td></tr> + <tr><td><code>usage [--json] [--reset]</code></td><td>LLM token usage report for this browser (per model, cost estimate)</td></tr> + <tr><td><code>df</code></td><td>Virtual filesystem usage</td></tr> + <tr><td><code>free</code></td><td>JS heap / memory snapshot</td></tr> + <tr><td><code>top</code></td><td>Busiest commands and modules by activity</td></tr> + <tr><td><code>ps</code></td><td>Commands and follows currently running</td></tr> + <tr><td><code>history [--search <term>]</code></td><td>Command history, optionally filtered</td></tr> + <tr><td><code>run <script></code></td><td>Execute a saved script from the VFS</td></tr> + <tr><td><code>sysmsg [on|off]</code></td><td>Toggle system messages</td></tr> + <tr><td><code>view_module <name></code></td><td>Print a module's source</td></tr> + <tr><td><code>node <script.js></code></td><td>Run a JS file from the VFS (alias of <code>js-run</code>)</td></tr> +</table></div> </section> <!-- ── Floating UI ── --> @@ -1247,7 +1314,8 @@ floating-toggle files</pre> <tr><td><code>session_load</code></td><td>Load by date</td></tr> <tr><td><code>session_recent</code></td><td>Show last N</td></tr> <tr><td><code>session_stats</code></td><td>Aggregate statistics</td></tr> - </table></div> + <tr><td><code>session-new</code></td><td>Start a fresh AI session (clears context, keeps history)</td></tr> +</table></div> <p>The terminal auto-saves session state every 60s and auto-restores on page reload.</p> </section> @@ -1285,7 +1353,8 @@ vfs-import</pre> <tr><td><code>webdav-rename <old> <new></code></td><td>Rename remote file</td></tr> <tr><td><code>webdav-move <src> <dst></code></td><td>Move remote file (alias for rename)</td></tr> <tr><td><code>webdav-backup</code></td><td>Backup entire space</td></tr> - </table></div> + <tr><td><code>webdav-login <user></code></td><td>Store WebDAV credentials for this session</td></tr> +</table></div> <h3>Browser Features</h3> <ul> <li>Checkbox select + Select All toggle</li> @@ -1330,7 +1399,10 @@ vfs-import</pre> <tr><td><code>lease-list</code></td><td>Show active leases — agent tasks with status and TTL</td></tr> <tr><td><code>lease-revoke <id></code></td><td>Revoke an active lease</td></tr> <tr><td><code>lease-renew <id> <seconds></code></td><td>Extend an active lease by N seconds</td></tr> - </table></div> + <tr><td><code>orchestrator-schedule <role> <interval_s> <task...></code></td><td>Schedule a recurring task for a role</td></tr> + <tr><td><code>orchestrator-schedules</code></td><td>List scheduled tasks</td></tr> + <tr><td><code>orchestrator-unschedule <id></code></td><td>Remove a scheduled task</td></tr> +</table></div> </section> <!-- ── A2A Contracts ── --> @@ -1343,7 +1415,13 @@ vfs-import</pre> <tr><td><code>a2a-list</code></td><td>Show all A2A messages with pending status</td></tr> <tr><td><code>contract-register <role> [fields...] --output [fields...]</code></td><td>Register a contract with input/output schema</td></tr> <tr><td><code>contract-list</code></td><td>List all registered contracts</td></tr> - </table></div> + <tr><td><code>a2a-post <to> <type> <capability> <payload></code></td><td>Post a message to another agent's mailbox</td></tr> + <tr><td><code>a2a-poll</code></td><td>Read your own inbox</td></tr> + <tr><td><code>a2a-ack <id></code></td><td>Acknowledge a message</td></tr> + <tr><td><code>a2a-reject <id></code></td><td>Reject a message</td></tr> + <tr><td><code>a2a-status</code></td><td>Mailbox counters per agent</td></tr> + <tr><td><code>a2a-prune</code></td><td>Drop old and acknowledged messages</td></tr> +</table></div> </section> <!-- ── Neural VFS ── --> @@ -1365,7 +1443,8 @@ vfs-import</pre> <tr><td><code>nvfs-sync [--deep]</code></td><td>Incremental background sync dirty files</td></tr> <tr><td><code>nvfs-save</code></td><td>Force-save semantic index to VFS disk</td></tr> <tr><td><code>nvfs-cancel</code></td><td>Cancel running index operation</td></tr> - </table></div> + <tr><td><code>nvfs-index-graph [--deep]</code></td><td>Build the NVFS index dependency graph</td></tr> +</table></div> </section> <!-- ── Server Monitor ── --> @@ -1390,7 +1469,9 @@ vfs-import</pre> <div class="table-wrap"><table> <tr><th>Command</th><th>Description</th></tr> <tr><td><code>debug</code></td><td>Toggle debug panel on/off</td></tr> - </table></div> + <tr><td><code>debug-sync</code></td><td>Push debug records to the configured sync endpoint</td></tr> + <tr><td><code>debug-sync-url <url></code></td><td>Show or set the sync endpoint</td></tr> +</table></div> <h3>Debug Panel Shows</h3> <ul> <li><strong>Memory</strong> — localStorage usage, VFS size, session context size</li> @@ -1410,7 +1491,6 @@ vfs-import</pre> <tr><td><code>sandbox-status</code></td><td>Show worker pool health and task metrics</td></tr> <tr><td><code>sandbox-config <k> <v></code></td><td>Configure max-workers, min-workers</td></tr> <tr><td><code>sandbox-run <task></code></td><td>Execute a task in the sandbox pool</td></tr> - <tr><td><code>sandbox-kill <id></code></td><td>Terminate a running sandbox task</td></tr> </table></div> <p><code>orchestrate --sandboxed <task></code> routes delegation through the sandbox for full isolation.</p> </section> @@ -1427,7 +1507,10 @@ vfs-import</pre> <tr><td><code>memgraph-export</code></td><td>Export full graph as JSON to VFS</td></tr> <tr><td><code>memgraph-prune</code></td><td>Remove stale low-weight edges (>30d, <3 uses)</td></tr> <tr><td><code>memgraph-learn <entity> <fact></code></td><td>Add a fact to the memory graph</td></tr> - </table></div> + <tr><td><code>memgraph-agent <agentId></code></td><td>Show one agent's memory subgraph</td></tr> + <tr><td><code>memgraph-session [YYYY-MM-DD]</code></td><td>Show a day's session graph</td></tr> + <tr><td><code>memgraph-decay-config <days> <min_uses></code></td><td>Tune memory decay</td></tr> +</table></div> <p>Context is automatically injected into AI prompts for cross-session awareness.</p> </section> @@ -1575,6 +1658,15 @@ listmods</pre> <h2>📋 Changelog</h2> <div class="version-item"> + <div class="v-header"><span class="v-num">v4.6.52 — October 2026</span><span class="v-date">2026-10-22</span></div> + <ul> + <li><strong>Documentation backlog cleared</strong> — 74 commands that the code registered but this page never documented are now in their own sections: <code>dashboard</code> (with <code>--watch</code>/<code>--stop</code>), <code>usage</code>, <code>ps</code>/<code>top</code>/<code>df</code>/<code>free</code>, the six <code>a2a-*</code> mailbox commands, <code>webxai</code>/<code>webx</code>/<code>wx</code>, <code>context</code>/<code>contexts</code>/<code>context-new</code>/<code>context-delete</code>/<code>context-auto</code>/<code>smart-ask</code>, the <code>commit-*</code> approval trio, <code>module-load|unload|enable|reset</code>, <code>memgraph-agent|session|decay-config</code>, <code>orchestrator-schedule|schedules|unschedule</code>, <code>skill-validate|audit|restore|pack-core</code>, <code>learn-skill</code>, <code>encrypt</code>/<code>decrypt</code>, <code>gzip</code>/<code>wget</code>, <code>kanban</code>, <code>three</code>, <code>course</code>, <code>videos</code>, <code>speak</code>/<code>voice</code>/<code>analyze</code>, <code>gui-run|text|clear</code>, the <code>vaultmind-*</code> set, <code>debug-sync</code>/<code>debug-sync-url</code>, <code>setfont</code>, <code>bug</code>, <code>session-new</code>, <code>files</code>, <code>node</code>, <code>sed</code>, <code>nvfs-index-graph</code>, <code>wallet-lookup</code>, <code>ai-model</code>, <code>ai-ignore</code>, <code>webdav-login</code>, <code>view_module</code>, <code>run</code>, <code>sysmsg</code>, <code>history</code>.</li> + <li><strong>Ghost rows removed</strong> — <code>commands</code>, <code>check</code>, <code>sandbox-kill</code> and <code>webdav-explorer</code> were documented here but are not registered anywhere in the code. Their rows are gone; the sandbox prose no longer promises <code>sandbox-kill</code>.</li> + <li><strong>Audit method</strong> — the command list is now derived from <code>terminal.js</code> (<code>_baseWhitelist</code>, <code>internals</code>, <code>cmd ===</code> dispatch) plus every <code>commands['…']</code> registration in <code>modules/</code>, so the next gap can be found mechanically.</li> + </ul> + </div> + + <div class="version-item"> <div class="v-header"><span class="v-num">v4.5.86 — July 2026</span><span class="v-date">2026-07-04</span></div> <ul> <li><strong>Cold module activation</strong> — Three modules (Memory Graph, Predictor, World Model) were loaded but produced zero actionable data. All now wired into the AI agent loop.</li> @@ -1853,7 +1945,7 @@ listmods</pre> <li><strong>v4.4 complete</strong> — 46 modules, 24 skills, full A2A lifecycle, sandboxed execution, memory graph, world model, health monitoring</li> <li><strong>A2A Mailbox Transport</strong> — <code>a2a-send</code>, <code>a2a-list</code>, 500ms polling with envelope routing (request/response/broadcast/heartbeat)</li> <li><strong>Autonomous sub-agent spawning</strong> — auto-role derivation, sleep/reanimate VFS serialization</li> - <li><strong>Sandboxed execution</strong> — WebWorker pool <code>sandbox-run</code>, <code>sandbox-kill</code> with inline fallback for headless</li> + <li><strong>Sandboxed execution</strong> — WebWorker pool <code>sandbox-run</code> (there is no <code>sandbox-kill</code>; tasks end on timeout) with inline fallback for headless</li> <li><strong>A2A Protocol</strong> — Agent contract system: <code>contract-register</code>, <code>contract-list</code>, schema validation in orchestrator</li> <li><strong>Self-Optimization Telemetry</strong> — <code>system-health</code> command showing tool latency, VFS stats, error rates</li> <li><strong>AI tool: nvfs_resolve</strong> — AI can search VFS by concept</li> diff --git a/scripts/newos4-maintain.py b/scripts/newos4-maintain.py index 10ac62b..dd6c898 100644 --- a/scripts/newos4-maintain.py +++ b/scripts/newos4-maintain.py @@ -100,6 +100,34 @@ def check_course(): r = run([sys.executable, 'scripts/course-validate.py'], cwd=ROOT) add('PASS' if r.returncode == 0 else 'FAIL', 'course ' + ('valid' if r.returncode == 0 else 'INVALID: ' + r.stdout[-160:])) +def check_help_coverage(): + """Every command the code registers must appear in help.html (2026-10-22). + + help.html had a 74-command backlog because nothing compared the two. This + check makes the gap visible on every maintenance run. + """ + cmds, term = set(), open(os.path.join(ROOT, 'modules/core/terminal.js'), encoding='utf-8').read() + for m in re.finditer(r'this\._baseWhitelist = \[(.*?)\];', term, re.S): + cmds.update(re.findall(r"'([^']+)'", m.group(1))) + for m in re.finditer(r'const internals = \[(.*?)\];', term, re.S): + cmds.update(re.findall(r"'([^']+)'", m.group(1))) + cmds.update(re.findall(r"cmd === ['\"]([a-z0-9_-]+)['\"]", term)) + for p in glob.glob(os.path.join(ROOT, 'modules/**/*.js'), recursive=True): + if 'bundle' in p or '/test/' in p or '.bkp' in p: + continue + src = open(p, encoding='utf-8', errors='ignore').read() + cmds.update(re.findall(r"commands\[['\"]([a-z0-9_-]+)['\"]\]\s*=", src)) + doc = open(os.path.join(ROOT, 'help.html'), encoding='utf-8').read() + documented = set() + for tok in re.findall(r'<code>([^<]+)</code>', doc): + first = tok.replace('<', ' ').replace('>', ' ').split() + if first and re.fullmatch(r'[a-z][a-z0-9_-]{0,40}', first[0].lstrip('./')): + documented.add(first[0].lstrip('./')) + missing = sorted(cmds - documented) + add('PASS' if not missing else 'WARN', + f'help coverage {len(cmds) - len(missing)}/{len(cmds)} commands' + + ('' if not missing else f' — undocumented: {", ".join(missing[:8])}')) + def check_links(): if not DEEP: return broken = [] @@ -115,7 +143,7 @@ def check_links(): def main(): os.chdir(ROOT) - check_versions(); check_bundles(); check_syntax(); check_perms(); check_index(); check_data(); check_live(); check_atlas(); check_course(); check_links() + check_versions(); check_bundles(); check_syntax(); check_perms(); check_index(); check_data(); check_live(); check_atlas(); check_course(); check_help_coverage(); check_links() fails = [m for l, m in issues if l == 'FAIL'] print('newOS4 maintenance — ' + datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%MZ') + (' [fix]' if FIX else '') + (' [deep]' if DEEP else '')) for l, m in issues: print(f'{l}: {m}') |