diff options
40 files changed, 2419 insertions, 567 deletions
diff --git a/cheatsheet.html b/cheatsheet.html index 6245807..0ce8299 100644 --- a/cheatsheet.html +++ b/cheatsheet.html @@ -139,7 +139,8 @@ pre{background:var(--bg2);border:1px solid var(--border);border-radius:var(--rad <h2>π₯οΈ System</h2> <div class="grid"> -<div class="item"><span class="cmd">status</span><span class="desc">System health</span></div> +<div class="item"><span class="cmd">status</span><span class="desc">System status overview</span></div> +<div class="item"><span class="cmd">system-health</span><span class="desc">Tool latency, VFS, memory</span></div> <div class="item"><span class="cmd">mem</span><span class="desc">Memory usage</span></div> <div class="item"><span class="cmd">echo <text></span><span class="desc">Print text</span></div> <div class="item"><span class="cmd">date / cal</span><span class="desc">Date & calendar</span></div> @@ -147,6 +148,39 @@ pre{background:var(--bg2);border:1px solid var(--border);border-radius:var(--rad <div class="item"><span class="cmd">logs <n></span><span class="desc">View recent logs</span></div> <div class="item"><span class="cmd">logrotate</span><span class="desc">Rotate log files</span></div> <div class="item"><span class="cmd">config</span><span class="desc">Config manager UI</span></div> +<div class="item"><span class="cmd">checkpoint</span><span class="desc">VFS snapshot</span></div> +<div class="item"><span class="cmd">checkpoint-list</span><span class="desc">List VFS snapshots</span></div> +<div class="item"><span class="cmd">rollback</span><span class="desc">Restore VFS snapshot</span></div> +<div class="item"><span class="cmd">vfs-export</span><span class="desc">Export VFS as JSON</span></div> +<div class="item"><span class="cmd">vfs-import</span><span class="desc">Import VFS JSON</span></div> +<div class="item"><span class="cmd">security-level</span><span class="desc">Set security 0-3</span></div> +</div> + +<h2>π§ Neural VFS</h2> +<div class="grid"> +<div class="item"><span class="cmd">nvfs-index</span><span class="desc">Build semantic concept index</span></div> +<div class="item"><span class="cmd">nvfs-resolve <c></span><span class="desc">Find files by concept</span></div> +<div class="item"><span class="cmd">concept://<c></span><span class="desc">Read file via semantic concept</span></div> +<div class="item"><span class="cmd">nvfs-tree [c]</span><span class="desc">Concept tree view</span></div> +<div class="item"><span class="cmd">nvfs-status</span><span class="desc">Index stats</span></div> +</div> + +<h2>π€ Agents & A2A</h2> +<div class="grid"> +<div class="item"><span class="cmd">agent-list</span><span class="desc">List AI agents</span></div> +<div class="item"><span class="cmd">agent-status <id></span><span class="desc">Agent details</span></div> +<div class="item"><span class="cmd">orchestrate <t></span><span class="desc">Delegate task</span></div> +<div class="item"><span class="cmd">orchestrator-status</span><span class="desc">Agent pool status</span></div> +<div class="item"><span class="cmd">contract-list</span><span class="desc">List A2A contracts</span></div> +<div class="item"><span class="cmd">contract-register</span><span class="desc">Register A2A contract</span></div> +</div> + +<h2>π Monitor</h2> +<div class="grid"> +<div class="item"><span class="cmd">server <n> <u></span><span class="desc">Add server to monitor</span></div> +<div class="item"><span class="cmd">servers</span><span class="desc">List monitored servers</span></div> +<div class="item"><span class="cmd">server-check</span><span class="desc">Check server status</span></div> +<div class="item"><span class="cmd">monitor</span><span class="desc">Toggle auto-monitoring</span></div> </div> <h2>π Security / Vault</h2> diff --git a/downloads/newos4_whitepaper.html b/downloads/newos4_whitepaper.html index 0a12342..21079b8 100644 --- a/downloads/newos4_whitepaper.html +++ b/downloads/newos4_whitepaper.html @@ -175,7 +175,7 @@ <li>Security layer (0-3) and WPM lifecycle management.</li> </ul> - <h3>Phase 2 β Agentic Shift <span class="status-progress">π‘ IN PROGRESS</span></h3> + <h3>Phase 2 β Agentic Shift <span class="status-done">β
COMPLETED</span></h3> <ul> <li>β
AI tool-calling loop (19+ tools).</li> <li>β
<code>session_terminal</code> zero-cost context access.</li> @@ -183,6 +183,15 @@ <li>β
Agent orchestration (list, register, lease, orchestrate).</li> <li>β
<strong>Localized Asset Management</strong> (Bypassing server security blocks).</li> </ul> + + <h3>Phase 3 β Cognitive OS <span class="status-progress">π‘ IN PROGRESS</span></h3> + <ul> + <li>β
Neural VFS β semantic concept indexing (nvfs-index, nvfs-resolve, nvfs-tree).</li> + <li>β
A2A Protocol β agent contracts with schema validation (contract-register, contract-list).</li> + <li>π‘ Recursive self-optimization β telemetry-driven latency diagnosis.</li> + <li>β¬ Predictive resource allocation.</li> + <li>β¬ Global World Model.</li> + </ul> </section> <footer> @@ -1088,13 +1088,53 @@ vfs-import</pre> <div class="table-wrap"><table> <tr><th>Command</th><th>Description</th></tr> <tr><td><code>agent-list</code></td><td>List all registered agents with status</td></tr> + <tr><td><code>agent-status <id></code></td><td>Show detailed status for a specific agent</td></tr> <tr><td><code>agent-register <name> <model></code></td><td>Register a new AI agent</td></tr> + <tr><td><code>agent-unregister <id></code></td><td>Remove an agent from the registry</td></tr> <tr><td><code>lease-list</code></td><td>Show active leases β agent tasks with status and TTL</td></tr> <tr><td><code>orchestrate <task></code></td><td>Delegate multi-step task to agent orchestrator</td></tr> + <tr><td><code>orchestrator-status</code></td><td>Show orchestrator agent pool status</td></tr> + <tr><td><code>orchestrator-spawn <role> [caps...]</code></td><td>Spawn a new worker agent</td></tr> </table></div> </section> - <!-- ββ Debug ββ --> + <!-- ββ A2A Contracts ββ --> + <section id="a2a-contracts"> + <h2>π A2A Contracts</h2> + <p>Define and enforce agent-to-agent contracts with input/output schema validation. Contracts are stored in <code>/.contracts/</code> and validated during orchestrator delegation.</p> + <div class="table-wrap"><table> + <tr><th>Command</th><th>Description</th></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> + </section> + + <!-- ββ Neural VFS ββ --> + <section id="neural-vfs"> + <h2>π§ Neural VFS</h2> + <p>Semantic concept-indexing layer over the hierarchical VFS. Scans files and builds a concept β path mapping using filenames, tags, and headers.</p> + <div class="table-wrap"><table> + <tr><th>Command</th><th>Description</th></tr> + <tr><td><code>nvfs-index</code></td><td>Scan VFS and build semantic concept index</td></tr> + <tr><td><code>nvfs-status</code></td><td>Show index stats and last scan time</td></tr> + <tr><td><code>nvfs-resolve <concept></code></td><td>Find files related to a concept (exact + fuzzy)</td></tr> + <tr><td><code>nvfs-tree [concept]</code></td><td>Show concept-to-file mapping tree</td></tr> + </table></div> + </section> + + <!-- ββ Server Monitor ββ --> + <section id="server-monitor"> + <h2>π Server Monitor</h2> + <p>Uptime monitoring for external services + self-optimization telemetry tracking tool latency and error rates.</p> + <div class="table-wrap"><table> + <tr><th>Command</th><th>Description</th></tr> + <tr><td><code>server <name> <url></code></td><td>Add a server to monitor</td></tr> + <tr><td><code>servers</code></td><td>List all monitored servers</td></tr> + <tr><td><code>server-check <name></code></td><td>Check a server's current status</td></tr> + <tr><td><code>monitor</code></td><td>Toggle auto-monitoring (60s interval)</td></tr> + <tr><td><code>system-health</code></td><td>Show tool latency, VFS stats, module count, memory, error rates</td></tr> + </table></div> + </section> <section id="debug-panel"> <h2>π§ Debug Panel</h2> <p>Toggle the debug overlay to monitor system internals in real-time.</p> @@ -1202,6 +1242,14 @@ listmods</pre> <div class="quick-ref-item"><span class="cmd">date</span><span class="desc">Show time</span></div> <div class="quick-ref-item"><span class="cmd">cal</span><span class="desc">Show calendar</span></div> <div class="quick-ref-item"><span class="cmd">base64</span><span class="desc">Encode/decode</span></div> + <div class="quick-ref-item"><span class="cmd">nvfs-index</span><span class="desc">Build semantic index</span></div> + <div class="quick-ref-item"><span class="cmd">nvfs-resolve</span><span class="desc">Find files by concept</span></div> + <div class="quick-ref-item"><span class="cmd">mindmap svg</span><span class="desc">Render mindmap as SVG</span></div> + <div class="quick-ref-item"><span class="cmd">gui</span><span class="desc">Simple GUI builder</span></div> + <div class="quick-ref-item"><span class="cmd">contract-list</span><span class="desc">List A2A contracts</span></div> + <div class="quick-ref-item"><span class="cmd">modules-list</span><span class="desc">List all 45 modules</span></div> + <div class="quick-ref-item"><span class="cmd">orchestrate</span><span class="desc">Delegate to agent</span></div> + <div class="quick-ref-item"><span class="cmd">system-health</span><span class="desc">System diagnostics</span></div> <div class="quick-ref-item"><span class="cmd">seq</span><span class="desc">Number sequence</span></div> <div class="quick-ref-item"><span class="cmd">whoami</span><span class="desc">Show user</span></div> <div class="quick-ref-item"><span class="cmd">basename</span><span class="desc">Strip dir path</span></div> @@ -1218,6 +1266,34 @@ listmods</pre> <h2>π Changelog</h2> <div class="version-item"> + <div class="v-header"><span class="v-num">v4.3.1 β June 2026</span><span class="v-date">2026-06-03</span></div> + <ul> + <li><strong>Neural VFS</strong> β Semantic concept indexing layer: <code>nvfs-index</code>, <code>nvfs-resolve</code>, <code>nvfs-status</code>, <code>nvfs-tree</code></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> + <li><strong>Skills consolidated</strong> β 9 β 4 unified; index rebuilt minified</li> + <li><strong>Docs sync</strong> β vision.html and whitepaper updated</li> + <li>Cache: <code>2026-06-03-neuralvfs</code> β hard refresh required</li> + </ul> + </div> + + <div class="version-item"> + <div class="v-header"><span class="v-num">v4.3.2 β June 2026</span><span class="v-date">2026-06-04</span></div> + <ul> + <li><strong>mindmap svg</strong> β Inline SVG rendering with colored rects + bezier curves</li> + <li><strong>GUI Builder</strong> β <code>gui</code>, <code>gui-button</code>, <code>gui-input</code> β SimpleGUIModule registered</li> + <li><strong>mermaid.min.js</strong> β Downloaded for webx11_mindmap.html</li> + <li><strong>get_module_status fixed</strong> β Shows all 34 loaded modules (was only HTTP-loaded)</li> + <li><strong>view_module fixed</strong> β Uses modules-index.json to resolve classβfile paths</li> + <li><strong>module-ollamamodels merged</strong> β Into module-ollama (13 commands total)</li> + <li><strong>concept:// URIs</strong> β <code>cat concept://skill</code> resolves via Neural VFS</li> + <li><strong>Module categorization</strong> β <code>modules-list</code> shows [core], [ext], [infra] layer tags</li> + <li><strong>5 modules whitelisted</strong> β system-health, server, servers, server-check, monitor run directly</li> + </ul> + </div> + + <div class="version-item"> <div class="v-header"><span class="v-num">v4.3 β June 2026</span><span class="v-date">2026-06-02</span></div> <ul> <li><strong>WebDAV Browser</strong> β Modern file-tree UI with checkboxes, Select All, bulk actions (Delete, Move, Download), inline rename (double-click), context menu, breadcrumbs, keyboard shortcuts</li> diff --git a/modules-index.json b/modules-index.json new file mode 100644 index 0000000..41323ef --- /dev/null +++ b/modules-index.json @@ -0,0 +1,879 @@ +{ + "version": "2026-06-03-neuralvfs", + "generated": "2026-06-04T01:25:00.000Z", + "modules": { + "module-agent-registry": { + "name": "module-agent-registry", + "file": "modules/core/module-agent-registry.js", + "type": "core", + "class": "AgentRegistryModule", + "auto_load": true, + "commands": [ + "agent-list", + "agent-status", + "agent-register", + "agent-unregister", + "contract-register", + "contract-list" + ], + "description": "module-agent-registry.js β VFS-backed agent directory with A2A contracts", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-aiasm": { + "name": "module-aiasm", + "file": "modules/core/module-aiasm.js", + "type": "core", + "class": "WebXAIAliasModule", + "auto_load": true, + "commands": [ + "webxai", + "wx", + "webx" + ], + "description": "Extracted from newOS4 index.html β WebXAIAliasModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-aiassist": { + "name": "module-aiassist", + "file": "modules/core/module-aiassist.js", + "type": "core", + "class": "WebX11AIAssistantModule", + "auto_load": true, + "commands": [ + "ai", + "ask", + "ai-clear", + "ai-system", + "ai-context", + "ai-allow", + "ai-deny", + "ai-ignore", + "ai-stop", + "ai-model" + ], + "description": "Extracted from newOS4 index.html β WebX11AIAssistantModule (Full Agent Loop)", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-chatstudio": { + "name": "module-chatstudio", + "file": "modules/core/module-chatstudio.js", + "type": "core", + "class": "ChatStudioModule", + "auto_load": true, + "commands": [ + "chat" + ], + "description": "Load CSS", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-config": { + "name": "module-config", + "file": "modules/core/module-config.js", + "type": "core", + "class": "ConfigManagerModule", + "auto_load": true, + "commands": [ + "config", + "config-set", + "config-list", + "config-delete", + "config-export", + "config-reset" + ], + "description": "Extracted from newOS4 index.html β ConfigManagerModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-duckduckgo": { + "name": "module-duckduckgo", + "file": "modules/core/module-duckduckgo.js", + "type": "core", + "class": "DuckDuckGoModule", + "auto_load": true, + "commands": [ + "ddg", + "duck" + ], + "description": "Extracted from newOS4 index.html β DuckDuckGoModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-dynamicprompts": { + "name": "module-dynamicprompts", + "file": "modules/core/module-dynamicprompts.js", + "type": "core", + "class": "DynamicPromptsModule", + "auto_load": true, + "commands": [ + "prompt", + "prompt-save", + "prompt-list", + "prompt-delete", + "prompt-var", + "prompt-vars" + ], + "description": "Extracted from newOS4 index.html β DynamicPromptsModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-fetcher": { + "name": "module-fetcher", + "file": "modules/core/module-fetcher.js", + "type": "core", + "class": "WebFetcherModule", + "auto_load": true, + "commands": [ + "fetch", + "web", + "extract" + ], + "description": "example.com\", \"info\");", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-fs": { + "name": "module-fs", + "file": "modules/core/module-fs.js", + "type": "core", + "class": "FileSystemModule", + "auto_load": true, + "commands": [ + "ls", + "cat", + "put", + "rm", + "trash", + "trash-dir", + "ls-trash", + "empty-trash", + "mkdir", + "rmdir", + "mv", + "cp", + "cd", + "pwd", + "find", + "grep", + "head", + "tail", + "sort", + "wc", + "touch", + "tree", + "du", + "upload", + "download", + "vfs-export", + "vfs-import" + ], + "description": "Use trash for recursive dir removal too", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-io": { + "name": "module-io", + "file": "modules/core/module-io.js", + "type": "core", + "class": "ModuleIOModule", + "auto_load": true, + "commands": [ + "export-mods", + "import-mods", + "backup", + "restore", + "share-mod" + ], + "description": "Extracted from newOS4 index.html β ModuleIOModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-leases": { + "name": "module-leases", + "file": "modules/core/module-leases.js", + "type": "core", + "class": "LeaseModule", + "auto_load": true, + "commands": [ + "lease-list", + "lease-create", + "lease-revoke" + ], + "description": "module-leases.js β Lease system for agent task delegation", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-loader": { + "name": "module-loader", + "file": "modules/core/module-loader.js", + "type": "core", + "class": "module-loader.js", + "auto_load": true, + "commands": [], + "description": "Log to terminal if available", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "infrastructure" + }, + "module-manager": { + "name": "module-manager", + "file": "modules/core/module-manager.js", + "type": "core", + "class": "ModuleManager", + "auto_load": true, + "commands": [ + "modules", + "listmods", + "loadmod", + "removemod", + "startup-modules", + "load-local", + "loadlocal" + ], + "description": "Extracted from newOS4 index.html β ModuleManager", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "infrastructure" + }, + "module-modmgr": { + "name": "module-modmgr", + "file": "modules/core/module-modmgr.js", + "type": "core", + "class": "ModuleManagerModule", + "auto_load": true, + "commands": [ + "modules", + "listmods", + "loadmod", + "removemod", + "startup-modules", + "load-local", + "loadlocal" + ], + "description": "Extracted from newOS4 index.html β ModuleManagerModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-my": { + "name": "module-my", + "file": "modules/core/module-my.js", + "type": "core", + "class": "MyModule", + "auto_load": true, + "commands": [ + "my", + "my-set", + "my-get", + "my-list", + "my-export", + "my-import", + "my-clear" + ], + "description": "", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-neural-vfs": { + "name": "module-neural-vfs", + "file": "modules/core/module-neural-vfs.js", + "type": "core", + "class": "NeuralVFSModule", + "auto_load": true, + "commands": [ + "nvfs-index", + "nvfs-status", + "nvfs-resolve", + "nvfs-tree" + ], + "description": "ββ Core Index Builder ββ", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-ollama": { + "name": "module-ollama", + "file": "modules/core/module-ollama.js", + "type": "core", + "class": "OllamaModule", + "auto_load": true, + "commands": [ + "ollama", + "ollamaconnect", + "ollamadisconnect", + "ollamamodels", + "ollamasetmodel", + "ollamasetproxy", + "models", + "model-info", + "model-pull", + "model-delete", + "model-run", + "ai", + "ask" + ], + "description": "Ollama model management β connect, list models, pull/delete, run inference", + "dependencies": [], + "version": "2.0.0", + "updated": "2026-06-04", + "layer": "core" + }, + "module-orchestrator": { + "name": "module-orchestrator", + "file": "modules/core/module-orchestrator.js", + "type": "core", + "class": "OrchestratorModule", + "auto_load": true, + "commands": [ + "orchestrate", + "orchestrator-status", + "orchestrator-spawn", + "orchestrator-kill", + "orchestrator-purge" + ], + "description": "module-orchestrator.js β Multi-agent orchestration system", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-searxng": { + "name": "module-searxng", + "file": "modules/core/module-searxng.js", + "type": "core", + "class": "SearXNGModule", + "auto_load": true, + "commands": [ + "search", + "s", + "images", + "videos" + ], + "description": "", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-servermon": { + "name": "module-servermon", + "file": "modules/core/module-servermon.js", + "type": "core", + "class": "ServerMonitorModule", + "auto_load": true, + "commands": [ + "server", + "servers", + "server-check", + "server-remove", + "monitor", + "system-health" + ], + "description": "module-servermon.js β Server monitoring + self-optimization telemetry", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-simplegui": { + "name": "module-simplegui", + "file": "modules/core/module-simplegui.js", + "type": "core", + "class": "SimpleGUIModule", + "auto_load": true, + "commands": [ + "gui", + "gui-button", + "gui-input", + "gui-text", + "gui-clear", + "gui-run" + ], + "description": "Extracted from newOS4 index.html β SimpleGUIModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-skills": { + "name": "module-skills", + "file": "modules/core/module-skills.js", + "type": "core", + "class": "SkillsModule", + "auto_load": true, + "commands": [ + "skill-list", + "skill-view", + "skill-create", + "skill-patch", + "skill-delete", + "skill-export", + "skill-import", + "skill-sync" + ], + "description": "Extracted from newOS4 index.html β SkillsModule (v4.2 β Self-improving AI)", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-smartctx": { + "name": "module-smartctx", + "file": "modules/core/module-smartctx.js", + "type": "core", + "class": "SmartContextModule", + "auto_load": true, + "commands": [ + "context", + "contexts", + "context-new", + "context-delete", + "smart-ask" + ], + "description": "Extracted from newOS4 index.html β SmartContextModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "module-system": { + "name": "module-system", + "file": "modules/core/module-system.js", + "type": "core", + "class": "SystemModule", + "auto_load": true, + "commands": [ + "help", + "echo", + "mem", + "status", + "preview", + "factory-reset", + "reset-vfs", + "logs", + "logrotate", + "health-check", + "memory-map-export", + "font-size", + "setfont", + "smart-prompt", + "checkpoint", + "checkpoint-list", + "rollback", + "checkpoint-del", + "commands", + "check" + ], + "description": "Extracted from newOS4 index.html β SystemModule", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "ollama-manager": { + "name": "ollama-manager", + "file": "modules/core/ollama-manager.js", + "type": "core", + "class": "OllamaManager", + "auto_load": true, + "commands": [ + "ollamaconnect", + "ollamamodels", + "model", + "models" + ], + "description": "Extracted from newOS4 index.html β OllamaManager / LLMRouter", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "infrastructure" + }, + "secret-vault": { + "name": "secret-vault", + "file": "modules/core/secret-vault.js", + "type": "core", + "class": "SecretVault", + "auto_load": true, + "commands": [ + "secret-set", + "secret-get", + "secret-list", + "secret-del", + "secret-lock", + "secret-unlock", + "secret-setpin", + "secret-status" + ], + "description": "Extracted from newOS4 index.html β SecretVault", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "core" + }, + "terminal": { + "name": "terminal", + "file": "modules/core/terminal.js", + "type": "core", + "class": "WebX11SecurityManager", + "auto_load": true, + "commands": [ + "clear", + "help", + "security", + "security-level", + "cmd-allow", + "cmd-deny", + "cd" + ], + "description": "Extracted from newOS4 index.html β WebX11Terminal", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "virtual-fs": { + "name": "virtual-fs", + "file": "modules/core/virtual-fs.js", + "type": "core", + "class": "VirtualFileSystem", + "auto_load": true, + "commands": [ + "save", + "load", + "import" + ], + "description": "concept:// listing", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "alias": { + "name": "alias", + "file": "modules/ext/alias.js", + "type": "ext", + "class": "AliasModule", + "auto_load": false, + "commands": [ + "alias", + "unalias" + ], + "description": "Register management commands", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "busybox": { + "name": "busybox", + "file": "modules/ext/busybox.js", + "type": "ext", + "class": "BusyBoxModule", + "auto_load": false, + "commands": [ + "which", + "env", + "date", + "cal", + "yes", + "seq", + "base64", + "printf", + "cut", + "uniq", + "hostname", + "whoami", + "basename", + "dirname", + "sleep", + "expand" + ], + "description": "ββ which ββ", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "calc": { + "name": "calc", + "file": "modules/ext/calc.js", + "type": "ext", + "class": "CalcModule", + "auto_load": false, + "commands": [ + "calc" + ], + "description": "webx11.duckdns.org/spaces/newos4/modules/ext/calc.js');", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "cron": { + "name": "cron", + "file": "modules/ext/cron.js", + "type": "ext", + "class": "CronModule", + "auto_load": false, + "commands": [ + "cron-every", + "cron-list", + "cron-stop", + "cron-clear" + ], + "description": "webx11.duckdns.org/spaces/newos4/modules/ext/cron.js');", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "cryptogzip": { + "name": "cryptogzip", + "file": "modules/ext/cryptogzip.js", + "type": "ext", + "class": "CryptoGzipModule", + "auto_load": false, + "commands": [ + "gzip", + "gunzip", + "encrypt", + "decrypt" + ], + "description": "CryptoGzipModule β VFS-level gzip/encrypt commands for WebX11 newOS4", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "diff": { + "name": "diff", + "file": "modules/ext/diff.js", + "type": "ext", + "class": "DiffModule", + "auto_load": false, + "commands": [ + "diff" + ], + "description": "Strip trailing empty line if file ends with newline", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "editor": { + "name": "editor", + "file": "modules/ext/editor.js", + "type": "ext", + "class": "EditorModule", + "auto_load": false, + "commands": [ + "edit" + ], + "description": "Read existing file content or use empty for new files", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "filemgr": { + "name": "filemgr", + "file": "modules/ext/filemgr.js", + "type": "ext", + "class": "FileManagerModule", + "auto_load": false, + "commands": [ + "files", + "preview" + ], + "description": "code blocks first", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "finder": { + "name": "finder", + "file": "modules/ext/finder.js", + "type": "ext", + "class": "FinderModule", + "auto_load": false, + "commands": [ + "find" + ], + "description": "webx11.duckdns.org/spaces/newos4/modules/ext/finder.js');", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "mindmap": { + "name": "mindmap", + "file": "modules/ext/mindmap.js", + "type": "ext", + "class": "MindmapModule", + "auto_load": false, + "commands": [ + "mindmap", + "svg" + ], + "description": "Interactive mindmap creation with inline SVG rendering", + "dependencies": [], + "version": "2.0.0", + "updated": "2026-06-04", + "layer": "ext" + }, + "shell": { + "name": "shell", + "file": "modules/ext/shell.js", + "type": "ext", + "class": "ShellModule", + "auto_load": false, + "commands": [ + "export", + "unset", + "script", + "$", + "set" + ], + "description": "ββ Hook into terminal.executeCommand ββ", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "skill-pack-core": { + "name": "skill-pack-core", + "file": "modules/ext/skill-pack-core.js", + "type": "ext", + "class": "SkillPackCoreModule", + "auto_load": false, + "commands": [ + "skill-pack-core" + ], + "description": "Update existing skill content on fresh load (cache-bust version bump triggers this)", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "theme": { + "name": "theme", + "file": "modules/ext/theme.js", + "type": "ext", + "class": "ThemeModule", + "auto_load": false, + "commands": [ + "theme" + ], + "description": "Cancel any active preview", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "tutorial": { + "name": "tutorial", + "file": "modules/ext/tutorial.js", + "type": "ext", + "class": "TutorialModule", + "auto_load": false, + "commands": [ + "tutorial" + ], + "description": "Restore saved state or start fresh", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "voice": { + "name": "voice", + "file": "modules/ext/voice.js", + "type": "ext", + "class": "VoiceModule", + "auto_load": false, + "commands": [ + "voice" + ], + "description": "webx11.duckdns.org/spaces/newos4/modules/ext/voice.js');", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "webdav": { + "name": "webdav", + "file": "modules/ext/webdav.js", + "type": "ext", + "class": "WebDAVModule", + "auto_load": false, + "commands": [ + "webdav-config", + "webdav-status", + "webdav-ls", + "webdav-push", + "webdav-pull", + "webdav-backup", + "webdav-restore", + "webdav-backup-list", + "webdav-browser", + "webdav-rm", + "webdav-mkdir", + "webdav-rename", + "webdav-move" + ], + "description": "{ url, username, password }", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + }, + "wpm": { + "name": "wpm", + "file": "modules/ext/wpm.js", + "type": "ext", + "class": "WpmModule", + "auto_load": false, + "commands": [ + "wpm" + ], + "description": "webx11.duckdns.org/spaces/newos4/packages.json';", + "dependencies": [], + "version": "1.0.0", + "updated": "2026-06-03", + "layer": "ext" + } + }, + "total": 45 +}
\ No newline at end of file diff --git a/modules/core/module-agent-registry.js b/modules/core/module-agent-registry.js index 367f8b1..2439ab8 100644 --- a/modules/core/module-agent-registry.js +++ b/modules/core/module-agent-registry.js @@ -1,58 +1,137 @@ -// module-agent-registry.js β VFS-backed agent directory -// Command: agent-list, agent-register, agent-unregister, agent-status +// module-agent-registry.js β VFS-backed agent directory with A2A contracts +// Commands: agent-list, agent-register, agent-unregister, agent-status, contract-register, contract-list class AgentRegistryModule { constructor() { this.commands = {}; this.terminal = null; + this._contracts = {}; } registerCommands() { this.commands['agent-list'] = () => this.listAgents(); this.commands['agent-status'] = (args) => this.showAgentStatus(args[0]); this.commands['agent-register'] = (args) => this.registerAgent(args); this.commands['agent-unregister'] = (args) => this.unregisterAgent(args[0]); + this.commands['contract-register'] = (args) => this.registerContract(args); + this.commands['contract-list'] = () => this.listContracts(); } init(terminal) { this.terminal = terminal; - if (!this.terminal.fs.readFile('/agents/')) { - this.terminal.fs.mkdir('agents'); - } + if (!this.terminal.fs.readDir('/agents/')) this.terminal.fs.mkdir('agents'); + if (!this.terminal.fs.readDir('/.contracts/')) this.terminal.fs.mkdir('.contracts'); + this._loadContracts(); this.terminal.print('π Agent Registry loaded', 'info'); } - listAgents() { - const agents = this.terminal.fs.ls('/agents/'); - if (!agents || agents.length === 0) { - return this.terminal.print('No agents registered', 'info'); + _loadContracts() { + try { + const data = this.terminal.fs.readFile('/.contracts/index.json'); + if (data) this._contracts = JSON.parse(data); + } catch (e) {} + // Try loading individual contract files + const dir = this.terminal.fs.readDir('/.contracts/'); + if (dir) { + dir.forEach(e => { + if (e.type === 'file' && e.name.endsWith('.contract.json')) { + try { + const c = JSON.parse(this.terminal.fs.readFile('/.contracts/' + e.name)); + this._contracts[c.role] = c; + } catch (e) { console.warn('Bad contract:', e.name, e.message); } + } + }); } - this.terminal.print(`π Registered Agents (${agents.length}):`, 'header'); - agents.forEach(a => { - if (a.type === 'dir' && a.name !== 'configured') { - const data = this.terminal.fs.readFile(`/agents/${a.name}/status.json`); - const s = data ? JSON.parse(data) : { status: 'unknown', capabilities: [] }; - this.terminal.print(` ${a.name} β ${s.status} (${(s.capabilities || []).length} capabilities)`, 'info'); - } - }); + } + _saveContracts() { + try { + this.terminal.fs.fsWriteJSON('/.contracts/index.json', this._contracts); + } catch (e) { console.error('Contract save error:', e); } } registerAgent(args) { const id = args[1] || `agent-${Date.now()}`; const capabilities = args.slice(2).length ? args.slice(2) : ['list_files', 'read_file']; const agentDir = `agents/${id}`; - if (!this.terminal.fs.readFile('/' + agentDir + '/')) this.terminal.fs.mkdir(agentDir); + if (!this.terminal.fs.readDir('/' + agentDir + '/')) this.terminal.fs.mkdir(agentDir); this.terminal.fs.writeFile(`${agentDir}/status.json`, JSON.stringify({ id, status: 'idle', capabilities, registered: new Date().toISOString(), - lastHeartbeat: new Date().toISOString() + lastHeartbeat: new Date().toISOString(), + contract: null })); this.terminal.print(`β
Agent '${id}' registered with ${capabilities.length} capabilities`, 'success'); } - unregisterAgent(id) { - const ok = this.terminal.fs.deleteFile(`agents/${id}`); - if (ok) { - this.terminal.print(`β
Agent '${id}' unregistered`, 'success'); + registerContract(args) { + const role = args[0]; + if (!role) return this.terminal.print('Usage: contract-register <role> [input_fields...] [--output output_fields...]', 'warning'); + + const inputIdx = args.indexOf('--output'); + const hasOutputFlag = inputIdx !== -1; + + let inputFields = [], outputFields = []; + if (hasOutputFlag) { + inputFields = args.slice(1, inputIdx).filter(f => !f.startsWith('--')); + outputFields = args.slice(inputIdx + 1).filter(f => !f.startsWith('--')); } else { - this.terminal.print(`β Agent '${id}' not found`, 'error'); + inputFields = args.slice(1).filter(f => !f.startsWith('--')); + outputFields = ['result']; // default output + } + + const contract = { + role, + capabilities: inputFields, + input_schema: inputFields, + output_schema: outputFields, + created: new Date().toISOString(), + updated: new Date().toISOString() + }; + this._contracts[role] = contract; + // Save as individual contract file + this.terminal.fs.fsWriteJSON(`/.contracts/${role}.contract.json`, contract); + this._saveContracts(); + this.terminal.print(`β
Contract registered for role '${role}'`, 'success'); + this.terminal.print(` Input fields: ${inputFields.join(', ') || '(free-form)'}`, 'info'); + this.terminal.print(` Output fields: ${outputFields.join(', ') || '(free-form)'}`, 'info'); + } + listContracts() { + const roles = Object.keys(this._contracts); + if (roles.length === 0) return this.terminal.print('No contracts registered', 'info'); + this.terminal.print(`π A2A Contracts (${roles.length}):`, 'header'); + roles.forEach(r => { + const c = this._contracts[r]; + this.terminal.print(` ${r} β input:[${c.input_schema.join(',')}] β output:[${c.output_schema.join(',')}]`, 'info'); + }); + } + validateTask(role, task) { + const contract = this._contracts[role]; + if (!contract) return { valid: true, reason: 'no contract for role' }; // permissive fallback + if (contract.input_schema.length === 0) return { valid: true, reason: 'free-form input' }; + // Simple validation: check required input fields are present in task + const missing = contract.input_schema.filter(f => !task.toLowerCase().includes(f.toLowerCase())); + if (missing.length > 0) { + return { valid: false, reason: `missing required fields: ${missing.join(', ')}` }; } + return { valid: true, reason: 'matched' }; + } + getContract(role) { + return this._contracts[role] || null; + } + listAgents() { + const agents = this.terminal.fs.ls('/agents/'); + if (!agents || agents.length === 0) { + return this.terminal.print('No agents registered', 'info'); + } + this.terminal.print(`π Registered Agents (${agents.length}):`, 'header'); + agents.forEach(a => { + if (a.type === 'dir' && a.name !== 'configured') { + const data = this.terminal.fs.readFile(`/agents/${a.name}/status.json`); + const s = data ? JSON.parse(data) : { status: 'unknown', capabilities: [] }; + this.terminal.print(` ${a.name} β ${s.status} (${(s.capabilities || []).length} capabilities)${s.contract ? ` β contract:${s.contract}` : ''}`, 'info'); + } + }); + } + unregisterAgent(id) { + const ok = this.terminal.fs.deleteFile('agents/' + id); + if (ok) this.terminal.print(`β
Agent '${id}' unregistered`, 'success'); + else this.terminal.print(`β Agent '${id}' not found`, 'error'); } showAgentStatus(id) { if (!id) return this.terminal.print('Usage: agent-status <agent-id>', 'error'); @@ -62,6 +141,7 @@ class AgentRegistryModule { this.terminal.print(`Agent: ${s.id}`, 'header'); this.terminal.print(` Status: ${s.status}`, 'info'); this.terminal.print(` Capabilities: ${(s.capabilities || []).join(', ')}`, 'info'); + this.terminal.print(` Contract: ${s.contract || 'none'}`, 'info'); this.terminal.print(` Registered: ${s.registered}`, 'info'); this.terminal.print(` Last Heartbeat: ${s.lastHeartbeat}`, 'info'); } diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index eb41af9..cb1482f 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -418,6 +418,56 @@ RULES: required: ['role'] } } + }, { + type: 'function', + function: { + name: 'nvfs_resolve', + description: 'Search VFS files by semantic concept using Neural VFS index. Call nvfs-index first to build the index.', + parameters: { + type: 'object', + properties: { + concept: { type: 'string', description: 'Concept to search (e.g. skill, memory, module, webdav, security)' } + }, + required: ['concept'] + } + } + }, { + type: 'function', + function: { + name: 'list_available_modules', + description: 'List all available modules with metadata (core/ext, commands, class name, layer). Filter by type with type=core or type=ext.', + parameters: { + type: 'object', + properties: { + type: { type: 'string', description: 'Optional: filter to "core" or "ext"' } + }, + required: [] + } + } + }, { + type: 'function', + function: { + name: 'smart_context_list', + description: 'List available AI context profiles (e.g. coding, debug, creative, technical). Returns profile names and system prompts.', + parameters: { + type: 'object', + properties: {}, + required: [] + } + } + }, { + type: 'function', + function: { + name: 'smart_context_set', + description: 'Set the active AI context profile. Changes the AI\'s behavior (temperature, style) for subsequent responses.', + parameters: { + type: 'object', + properties: { + name: { type: 'string', description: 'Profile name (e.g. "coding", "debug", "creative", "technical", "chat")' } + }, + required: ['name'] + } + } }]; } getHelpInfo() { @@ -695,6 +745,9 @@ RULES: duration: t1, error: this._isToolError(toolResult) ? true : false }); + // Telemetry + const sm = this.terminal.moduleManager.modules['ServerMonitorModule']; + if (sm && sm.logToolCall) sm.logToolCall(fn.name, (t1 * 1000) || 1, this._isToolError(toolResult)); if (this._debugPanelEnabled) this._updateDebugPanel(); return { fn, toolResult, t1 }; })); @@ -734,6 +787,9 @@ RULES: duration: t1, error: this._isToolError(toolResult) ? true : false }); + // Telemetry + const sm2 = this.terminal.moduleManager.modules['ServerMonitorModule']; + if (sm2 && sm2.logToolCall) sm2.logToolCall(fn.name, (t1 * 1000) || 1, this._isToolError(toolResult)); if (this._debugPanelEnabled) this._updateDebugPanel(); const dObs = this._summarizeObservation(toolResult, 150); const dErr = this._isToolError(toolResult); @@ -1338,6 +1394,76 @@ RULES: .filter(s => !filterCat || (s.category || '').toLowerCase() === filterCat); return JSON.stringify({ skills: list, count: list.length }); } + case 'nvfs_resolve': { + const concept = (a.concept || '').toLowerCase(); + if (!concept) return JSON.stringify({ error: 'Concept is required' }); + const nvfs = this.terminal.moduleManager.modules['NeuralVFSModule']; + if (!nvfs) return JSON.stringify({ error: 'Neural VFS module not loaded β run nvfs-index first' }); + // Build index if empty + if (Object.keys(nvfs.index).length === 0) { + const saved = this.terminal.fs.fsReadJSON('/.semantic_index/map.json'); + if (saved) { nvfs.index = saved; } + else { return JSON.stringify({ error: 'No semantic index found β run nvfs-index first' }); } + } + const exact = nvfs.index[concept]; + const fuzzy = Object.keys(nvfs.index).filter(k => + k.includes(concept) || concept.includes(k) + ).filter(k => k !== concept); + const results = []; + if (exact) results.push(...exact.map(e => ({ concept, path: e.path, summary: e.summary }))); + for (const f of fuzzy.slice(0, 5)) { + results.push(...nvfs.index[f].slice(0, 3).map(e => ({ concept: f, path: e.path, summary: e.summary }))); + } + return JSON.stringify({ concept, exact: !!exact, count: results.length, results: results.slice(0, 20) }); + } + case 'list_available_modules': { + try { + const resp = await fetch('/spaces/newos4/modules-index.json?v=' + (localStorage.getItem('webx11_cache_ver') || '')); + if (!resp.ok) return JSON.stringify({ error: 'Module index not available' }); + const idx = await resp.json(); + const filterType = (a.type || '').toLowerCase(); + let mods = Object.values(idx.modules); + if (filterType) mods = mods.filter(m => m.type === filterType); + return JSON.stringify({ + total: mods.length, + available: idx.total, + type: filterType || 'all', + modules: mods.map(m => ({ + name: m.name, + type: m.type, + class: m.class, + commands: m.commands.slice(0, 8), + description: (m.description || '').substring(0, 80), + auto_load: m.auto_load + })) + }); + } catch (e) { return JSON.stringify({ error: 'Failed to load module index: ' + e.message }); } + } + case 'smart_context_list': { + const scm = this.terminal.moduleManager.modules['SmartContextModule']; + if (!scm) return JSON.stringify({ error: 'SmartContextModule not loaded', profiles: [] }); + const profiles = scm.contextProfiles || {}; + return JSON.stringify({ + profiles: Object.entries(profiles).map(([key, p]) => ({ + name: key, + displayName: p.name || key, + systemPrompt: (p.systemPrompt || '').substring(0, 80), + temperature: p.temperature || 0.7, + active: scm.activeProfile === key + })) + }); + } + case 'smart_context_set': { + const scm = this.terminal.moduleManager.modules['SmartContextModule']; + if (!scm) return JSON.stringify({ error: 'SmartContextModule not loaded' }); + const name = (a.name || '').toLowerCase(); + if (!scm.contextProfiles[name]) { + return JSON.stringify({ error: `Profile '${name}' not found`, available: Object.keys(scm.contextProfiles) }); + } + scm.activeProfile = name; + const profile = scm.contextProfiles[name]; + return JSON.stringify({ success: true, name, displayName: profile.name, systemPrompt: profile.systemPrompt, temperature: profile.temperature }); + } case 'view_module': case 'edit_module': case 'test_module': @@ -1364,16 +1490,41 @@ RULES: const code = this.terminal.fs.readFile(`_mods/${modName}.js`); if (code) return code; const url = entry ? entry.url : null; - if (!url) return JSON.stringify({ error: `No source URL for ${modName}` }); + // Try registry URL first + if (url) { + try { + const resp = await fetch(url); + if (resp.ok) { + const src = await resp.text(); + this.terminal.fs.writeFile(`_mods/${modName}.orig.js`, src); + return src.substring(0, 8000); + } + } catch (e) { /* fall through */ } + } + // Fallback: use modules-index.json to map class name to filename try { - const resp = await fetch(url); - if (resp.ok) { - const src = await resp.text(); - this.terminal.fs.writeFile(`_mods/${modName}.orig.js`, src); - return src.substring(0, 8000); + const idxResp = await fetch('/spaces/newos4/modules-index.json?v=' + (localStorage.getItem('webx11_cache_ver') || '')); + if (idxResp.ok) { + const idx = await idxResp.json(); + // modName is the class name (e.g. "WebX11AIAssistantModule") + // or already a filename (e.g. "module-aiassist") + // Try matching by class name first + let match = Object.values(idx.modules).find(m => m.class === modName); + // Then by name + if (!match) match = idx.modules[modName]; + if (match) { + const filePath = match.file; // e.g. "modules/core/module-aiassist.js" + const fetchUrl = `/spaces/newos4/${filePath}`; + const resp = await fetch(fetchUrl); + if (resp.ok) { + const src = await resp.text(); + this.terminal.fs.writeFile(`_mods/${modName}.orig.js`, src); + return src.substring(0, 8000); + } + } } - return JSON.stringify({ error: `HTTP ${resp.status}` }); - } catch (e) { return JSON.stringify({ error: e.message }); } + } catch (e) { /* fall through */ } + return JSON.stringify({ error: `Cannot find source for ${modName} β not in registry, not in modules-index.json` }); } case 'edit_module': { const modName = a.name || ''; @@ -1425,11 +1576,42 @@ RULES: const mm = this.terminal.moduleManager; const modsDir = this.terminal.fs.getCurrentDir(); const hasMods = modsDir.content['_mods'] ? !!Object.keys(modsDir.content['_mods'].content).length : false; - const modules = mm.moduleRegistry.map(m => ({ - name: m.name, url: m.url, enabled: m.enabled, - loaded: !!mm.modules[m.name], - modified: !!this.terminal.fs.readFile(`_mods/${m.name}.js`) - })); + // Load module index for file path lookup + let idxMap = {}; + try { + const resp = await fetch('/spaces/newos4/modules-index.json?v=' + (localStorage.getItem('webx11_cache_ver') || '')); + if (resp.ok) { + const idx = await resp.json(); + for (const [name, meta] of Object.entries(idx.modules)) { + idxMap[meta.class] = '/spaces/newos4/' + meta.file; + } + } + } catch (e) {} + const modules = []; + const seen = new Set(); + for (const [className, instance] of Object.entries(mm.modules)) { + const name = instance.constructor ? instance.constructor.name : className; + if (seen.has(name)) continue; + seen.add(name); + modules.push({ + name: name, + url: idxMap[name] || null, + enabled: true, + loaded: true, + modified: !!this.terminal.fs.readFile(`_mods/${name}.js`), + source: 'loaded' + }); + } + for (const m of mm.moduleRegistry) { + if (seen.has(m.name)) continue; + seen.add(m.name); + modules.push({ + name: m.name, url: m.url || idxMap[m.name] || null, enabled: m.enabled, + loaded: !!mm.modules[m.name], + modified: !!this.terminal.fs.readFile(`_mods/${m.name}.js`), + source: m.url ? 'ext' : 'core' + }); + } return JSON.stringify({ modules, total: modules.length, hasLocalEdits: hasMods }); } default: return JSON.stringify({ error: `Unknown module tool: ${name}` }); diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 2ffdb17..e7fc64a 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -18,7 +18,6 @@ 'module-my.js', 'module-searxng.js', 'module-servermon.js', - 'module-ollamamodels.js', 'module-config.js', 'module-simplegui.js', 'module-io.js', @@ -33,7 +32,8 @@ 'module-chatstudio.js', 'module-agent-registry.js', 'module-leases.js', - 'module-orchestrator.js' + 'module-orchestrator.js', + 'module-neural-vfs.js' ]; function getSelectedModules() { @@ -102,7 +102,7 @@ window.__moduleLoaderReload = reloadWithSelection; -const LATEST_VER = '2026-06-02-webdav2'; +const LATEST_VER = '2026-06-03-neuralvfs'; const CACHE = '?v=' + LATEST_VER; const stored = localStorage.getItem('webx11_cache_ver'); if (stored !== LATEST_VER) { diff --git a/modules/core/module-modmgr.js b/modules/core/module-modmgr.js index 1104883..32bb2cc 100644 --- a/modules/core/module-modmgr.js +++ b/modules/core/module-modmgr.js @@ -5,6 +5,7 @@ return { 'modules': 'modules β Open the module manager GUI', 'listmods': 'listmods β List all loaded modules with status', + 'modules-list': 'modules-list [core|ext] β List all available modules from the module index (46 total)', 'loadmod': 'loadmod <url> β Load a module from a URL', 'removemod': 'removemod <name> β Remove a loaded module by name', 'startup-modules': 'startup-modules β Open the startup modules selector', @@ -36,5 +37,38 @@ this.terminal.print(`${status} ${m.name}${badge}`); }); }; + this.commands['modules-list'] = async (args) => { + try { + const filter = (args[0] || '').toLowerCase(); + const resp = await fetch('/spaces/newos4/modules-index.json?v=' + (localStorage.getItem('webx11_cache_ver') || '')); + if (!resp.ok) return this.terminal.print('Failed to load module index', 'error'); + const idx = await resp.json(); + let mods = Object.values(idx.modules); + if (filter === 'core' || filter === 'ext') mods = mods.filter(m => m.type === filter); + if (filter === 'infra') mods = mods.filter(m => m.layer === 'infrastructure'); + const loaded = this.terminal.moduleManager.modules || {}; + const loadedCount = Object.keys(loaded).length; + const byLayer = {}; + mods.forEach(m => { + const l = m.layer || m.type || 'other'; + if (!byLayer[l]) byLayer[l] = []; + byLayer[l].push(m); + }); + const layerSummary = Object.entries(byLayer).map(([l, ms]) => `${ms.length} ${l}`).join(', '); + this.terminal.print(`π¦ Module Index (${mods.length} modules: ${layerSummary} β ${loadedCount} loaded)`, 'header'); + for (const [layer, layerMods] of Object.entries(byLayer)) { + this.terminal.print(` ββ ${layer.toUpperCase()} (${layerMods.length}) ββ`, 'info'); + for (const m of layerMods) { + const isLoaded = loaded[m.class] ? 'β' : ' '; + const layerTag = m.layer === 'infrastructure' ? '[infra]' : m.type === 'core' ? '[core]' : '[ext]'; + const cmdHint = m.commands.length > 0 ? ` ${m.commands.slice(0, 4).join(', ')}${m.commands.length > 4 ? '...' : ''}` : ''; + const desc = m.description ? ` β ${m.description.substring(0, 60)}` : ''; + this.terminal.print(` ${isLoaded} ${layerTag} ${m.name}${cmdHint}${desc}`, ''); + } + } + } catch (e) { + this.terminal.print(`modules-list error: ${e.message}`, 'error'); + } + }; } } diff --git a/modules/core/module-neural-vfs.js b/modules/core/module-neural-vfs.js new file mode 100644 index 0000000..e9ffafb --- /dev/null +++ b/modules/core/module-neural-vfs.js @@ -0,0 +1,271 @@ +class NeuralVFSModule { + constructor() { + this.commands = {}; + this.terminal = null; + this.index = {}; + this.indexPath = '/.semantic_index/map.json'; + } + + getHelpInfo() { + return { + 'nvfs-index': 'nvfs-index β Scan VFS and build semantic concept index', + 'nvfs-status': 'nvfs-status β Show semantic index stats and last scan time', + 'nvfs-resolve': 'nvfs-resolve <concept> β Find files related to a concept', + 'nvfs-tree': 'nvfs-tree [concept] β Show concept-to-file mapping as a tree' + }; + } + + registerCommands() { + this.commands['nvfs-index'] = (args) => this.buildIndex(); + this.commands['nvfs-status'] = (args) => this.showStatus(); + this.commands['nvfs-resolve'] = (args) => this.resolve(args); + this.commands['nvfs-tree'] = (args) => this.tree(args); + } + + // ββ Core Index Builder ββ + + buildIndex() { + const fs = this.terminal.fs; + if (!fs) return this.terminal.print('VFS not available', 'error'); + + this.terminal.print('π Scanning VFS for semantic concepts...', 'info'); + + const start = Date.now(); + const newIndex = {}; + let fileCount = 0; + let conceptCount = 0; + + // Walk VFS recursively β skip system dirs + this._walk('/', fs, newIndex, (path, node) => { + if (node.type !== 'file') return; + if (this._isSystemFile(path)) return; + + fileCount++; + const concepts = this._extractConcepts(path, node.content || ''); + for (const concept of concepts) { + if (!newIndex[concept]) { + newIndex[concept] = []; + conceptCount++; + } + // Avoid dupes + if (!newIndex[concept].find(e => e.path === path)) { + newIndex[concept].push({ path, summary: this._summarize(node.content) }); + } + } + }); + + // Also index skills + this._indexSkills(fs, newIndex); + + this.index = newIndex; + this.lastScan = new Date().toISOString(); + this.fileCount = fileCount; + this.conceptCount = conceptCount; + + // Save to VFS + this._saveIndex(fs); + // Clear VFS concept cache so concept:// URIs reflect the new index + if (fs._clearConceptCache) fs._clearConceptCache(); + + const elapsed = ((Date.now() - start) / 1000).toFixed(1); + this.terminal.print(`β
Indexed ${fileCount} files β ${conceptCount} concepts in ${elapsed}s`, 'success'); + this.terminal.print(` Index saved to ${this.indexPath}`, 'info'); + } + + // ββ Resolve ββ + + resolve(args) { + if (!args[0]) return this.terminal.print('Usage: nvfs-resolve <concept>', 'warning'); + + const concept = args.join(' ').toLowerCase(); + const matches = this.index[concept] || []; + + // Fuzzy fallback β find partial matches + const fuzzy = Object.keys(this.index).filter(k => + k.includes(concept) || concept.includes(k) + ).filter(k => k !== concept); + + if (matches.length === 0 && fuzzy.length === 0) { + return this.terminal.print(`No files found for concept "${concept}"`, 'warning'); + } + + if (matches.length > 0) { + this.terminal.print(`π "${concept}" β ${matches.length} file(s):`, 'info'); + for (const m of matches.slice(0, 20)) { + this.terminal.print(` ${m.path}`, 'success'); + if (m.summary) this.terminal.print(` ${m.summary}`, '') + } + if (matches.length > 20) { + this.terminal.print(` ... and ${matches.length - 20} more`, 'info'); + } + } + + if (fuzzy.length > 0) { + this.terminal.print(`\nπ Similar concepts: ${fuzzy.slice(0, 10).join(', ')}`, 'info'); + } + } + + // ββ Status ββ + + showStatus() { + const count = Object.keys(this.index).length; + if (count === 0) { + // Try loading from VFS + const fs = this.terminal.fs; + const saved = fs.fsReadJSON(this.indexPath); + if (saved) { + this.index = saved; + this.lastScan = '(loaded from disk)'; + this.terminal.print(`π Loaded index from ${this.indexPath}`, 'info'); + } else { + return this.terminal.print('No semantic index found. Run nvfs-index first.', 'warning'); + } + } + + const totalFiles = new Set(); + for (const entries of Object.values(this.index)) { + for (const e of entries) totalFiles.add(e.path); + } + + this.terminal.print(`π§ Neural VFS Index`, 'info'); + this.terminal.print(` Concepts: ${Object.keys(this.index).length}`, ''); + this.terminal.print(` Files indexed: ${totalFiles.size}`, ''); + this.terminal.print(` Last scan: ${this.lastScan || 'never'}`, ''); + } + + // ββ Tree View ββ + + tree(args) { + const concepts = Object.keys(this.index); + if (concepts.length === 0) { + return this.terminal.print('No index. Run nvfs-index first.', 'warning'); + } + + const filter = args[0] ? args[0].toLowerCase() : null; + const filtered = filter ? concepts.filter(c => c.includes(filter)) : concepts; + + this.terminal.print(`π³ Concept Tree${filter ? ` (filter: "${filter}")` : ''}:`, 'info'); + for (const concept of filtered.slice(0, 15)) { + this.terminal.print(` π ${concept}`, 'success'); + for (const entry of this.index[concept].slice(0, 5)) { + this.terminal.print(` ββ ${entry.path}`, ''); + } + if (this.index[concept].length > 5) { + this.terminal.print(` ββ ... (+${this.index[concept].length - 5} more)`, ''); + } + } + if (filtered.length > 15) { + this.terminal.print(` ... and ${filtered.length - 15} more concepts`, 'info'); + } + } + + // ββ Private Helpers ββ + + _walk(path, fs, index, cb) { + const entries = fs.readDir(path); + if (!entries) return; + for (const entry of entries) { + const fullPath = path === '/' ? '/' + entry.name : path + '/' + entry.name; + if (entry.type === 'file') { + cb(fullPath, { type: 'file', content: fs.readFile(fullPath) || '' }); + } else if (entry.type === 'dir') { + this._walk(fullPath, fs, index, cb); + } + } + } + + _isSystemFile(path) { + const sysPrefixes = ['/.trash', '/.semantic_index', '/_snapshots', '/_sessions']; + return sysPrefixes.some(p => path.startsWith(p) || path.includes('/node_modules')); + } + + _extractConcepts(path, content) { + const concepts = new Set(); + const name = path.split('/').pop() || ''; + const nameLower = name.toLowerCase(); + + // Extract from filename (split on camelCase, kebab, dots, underscores) + const words = nameLower + .replace(/([a-z])([A-Z])/g, '$1 $2') + .replace(/[-_.]/g, ' ') + .replace(/\.(md|js|html|json|css|txt|yaml|yml|toml|env|sh)$/i, '') + .split(/\s+/) + .filter(w => w.length > 2 && !/^\d+$/.test(w)); + + for (const word of words) { + concepts.add(word); + } + + // Extract file extension as concept + const ext = path.split('.').pop(); + if (ext && ['md', 'js', 'html', 'json', 'css'].includes(ext)) { + concepts.add(ext + '-file'); + } + + // Extract path-level concepts + const parts = path.split('/').filter(p => p.length > 0); + for (const part of parts) { + if (['modules', 'skills', 'core', 'ext', 'backups', 'chat', 'downloads'].includes(part)) { + concepts.add(part); + } + } + + // Extract #tags from content (markdown frontmatter or inline) + if (content) { + const tagMatches = content.match(/tags:\s*\[([^\]]+)\]/i) || content.match(/#[a-zA-Z]\w+/g); + if (tagMatches) { + const tags = tagMatches[0].replace(/tags:\s*\[/i, '').replace(/\]/, '').split(',').map(t => t.trim().replace(/^#/, '').replace(/"/g, '')); + for (const tag of tags) { + if (tag.length > 2) concepts.add(tag.toLowerCase()); + } + } + + // Extract first H1/H2 as concept + const headerMatch = content.match(/^#\s+(.+)/m) || content.match(/^##\s+(.+)/m); + if (headerMatch) { + const header = headerMatch[1].toLowerCase().replace(/[^a-z0-9\s]/g, '').trim(); + if (header.length > 3 && header.length < 40) { + concepts.add(header); + } + } + } + + return [...concepts]; + } + + _summarize(content) { + if (!content || content.length < 10) return ''; + const cleaned = content.replace(/---[\s\S]*?---/, '').trim(); + const firstLine = cleaned.split('\n').find(l => l.trim().length > 20); + if (!firstLine) return ''; + return firstLine.trim().slice(0, 100) + (firstLine.length > 100 ? '...' : ''); + } + + _indexSkills(fs, index) { + const skills = fs.readDir('/skills'); + if (!skills) return; + for (const skill of skills) { + if (skill.type !== 'file' || !skill.name.endsWith('.md')) continue; + // Already indexed by _walk β but we add a "skill" tag + const base = skill.name.replace('.md', ''); + if (!index['skill']) index['skill'] = []; + index['skill'].push({ path: '/skills/' + skill.name, summary: 'Skill: ' + base }); + } + } + + _saveIndex(fs) { + try { + if (!fs.readDir('/.semantic_index')) { + fs.mkdirRecursive('/.semantic_index'); + } + fs.fsWriteJSON(this.indexPath, this.index); + } catch (e) { + console.error('NeuralVFS save error:', e); + } + } +} + +// Required for module system +if (typeof window !== 'undefined') { + window.NeuralVFSModule = NeuralVFSModule; +}
\ No newline at end of file diff --git a/modules/core/module-ollama.js b/modules/core/module-ollama.js index 3eabe19..ba8ad57 100644 --- a/modules/core/module-ollama.js +++ b/modules/core/module-ollama.js @@ -1,52 +1,131 @@ -// Extracted from newOS4 index.html β OllamaModule - class OllamaModule { - constructor() { this.commands = {}; this.terminal = null; } - getHelpInfo() { - return { - 'ollama': 'ollama β Open the Ollama model manager UI', - 'ollamaconnect': 'ollamaconnect β Connect to the Ollama server', - 'ollamadisconnect': 'ollamadisconnect β Disconnect from the Ollama server', - 'ollamamodels': 'ollamamodels β List all available models from Ollama', - 'ollamasetmodel': 'ollamasetmodel <name> β Set the active Ollama model', - 'ollamasetproxy': 'ollamasetproxy [endpoint] β View or change the Ollama endpoint URL', - }; +// Extracted from newOS4 index.html β OllamaModule (merged with OllamaModelsModule) +// Commands: ollama, ollamaconnect, ollamadisconnect, ollamamodels, ollamasetmodel, ollamasetproxy, models, model-info, model-pull, model-delete, model-run, ai, ask +class OllamaModule { + constructor() { this.commands = {}; this.terminal = null; } + getHelpInfo() { + return { + 'ollama': 'ollama β Open the Ollama model manager UI', + 'ollamaconnect': 'ollamaconnect β Connect to the Ollama server', + 'ollamadisconnect': 'ollamadisconnect β Disconnect from the Ollama server', + 'ollamamodels': 'ollamamodels β List all available models from Ollama', + 'models': 'models β List all available Ollama models (table format)', + 'model-info': 'model-info <model-name> β Show details about a specific model', + 'model-pull': 'model-pull <model-name> β Pull a model from Ollama registry', + 'model-delete': 'model-delete <model-name> β Delete a model from local storage', + 'model-run': 'model-run <model-name> [prompt] β Run inference with a model', + 'ollamasetmodel': 'ollamasetmodel <name> β Set the active Ollama model', + 'ollamasetproxy': 'ollamasetproxy [endpoint] β View or change the Ollama endpoint URL', + }; + } + registerCommands() { + this.commands['ollama'] = () => { this.terminal.openOllamaManager(); }; + this.commands['ollamaconnect'] = async () => { + await this.terminal.ollamaManager.connect(); + this.terminal.updateOllamaStatus(); + }; + this.commands['ollamadisconnect'] = () => { + this.terminal.ollamaManager.connected = false; + this.terminal.ollamaManager.models = []; + this.terminal.print('Ollama disconnected', 'info'); + this.terminal.updateOllamaStatus(); + }; + this.commands['ollamamodels'] = () => { + const models = this.terminal.ollamaManager.getModels(); + if(models.length === 0) return this.terminal.print("No models found. Connect first."); + models.forEach(m => this.terminal.print(`${m.name} (${(m.size/1e9).toFixed(1)}GB)`)); + }; + this.commands['ollamasetmodel'] = (args) => { + if(!args[0]) return this.terminal.print("Usage: ollamasetmodel <name>", 'warning'); + this.terminal.ollamaManager.setModel(args[0]); + }; + this.commands['ollamasetproxy'] = (args) => { + if(!args[0]) { + const ep = this.terminal.ollamaManager.endpoint; + return this.terminal.print(`Current Ollama endpoint: ${ep}`, 'info'); } - registerCommands() { - this.commands['ollama'] = () => { this.terminal.openOllamaManager(); }; - this.commands['ollamaconnect'] = async () => { - await this.terminal.ollamaManager.connect(); - this.terminal.updateOllamaStatus(); - }; - this.commands['ollamadisconnect'] = () => { - this.terminal.ollamaManager.connected = false; - this.terminal.ollamaManager.models = []; - this.terminal.print('Ollama disconnected', 'info'); - this.terminal.updateOllamaStatus(); - }; - this.commands['ollamamodels'] = () => { - const models = this.terminal.ollamaManager.getModels(); - if(models.length === 0) return this.terminal.print("No models found. Connect first."); - models.forEach(m => this.terminal.print(`${m.name} (${(m.size/1e9).toFixed(1)}GB)`)); - }; - this.commands['ollamasetmodel'] = (args) => { - if(!args[0]) return this.terminal.print("Usage: ollamasetmodel <name>", 'warning'); - this.terminal.ollamaManager.setModel(args[0]); - }; - this.commands['ollamasetproxy'] = (args) => { - if(!args[0]) { - const ep = this.terminal.ollamaManager.endpoint; - return this.terminal.print(`Current Ollama endpoint: ${ep}`, 'info'); - } - this.terminal.ollamaManager.setEndpoint(args[0]); - this.terminal.print(`Ollama endpoint set to: ${args[0]}`, 'success'); - }; - this.commands['ai'] = async (args) => { - if(!args[0]) return this.terminal.print("Usage: ai <prompt>", 'warning'); - await this.terminal.ollamaManager.chat(args.join(' ')); - }; - this.commands['ask'] = async (args) => { - if(!args[0]) return this.terminal.print("Usage: ask <prompt>", 'warning'); - await this.terminal.ollamaManager.chat(args.join(' ')); - }; + this.terminal.ollamaManager.setEndpoint(args[0]); + this.terminal.print(`Ollama endpoint set to: ${args[0]}`, 'success'); + }; + this.commands['ai'] = async (args) => { + if(!args[0]) return this.terminal.print("Usage: ai <prompt>", 'warning'); + await this.terminal.ollamaManager.chat(args.join(' ')); + }; + this.commands['ask'] = async (args) => { + if(!args[0]) return this.terminal.print("Usage: ask <prompt>", 'warning'); + await this.terminal.ollamaManager.chat(args.join(' ')); + }; + // Merged from OllamaModelsModule + this.commands['models'] = () => this.listModels(); + this.commands['model-info'] = (args) => this.modelInfo(args); + this.commands['model-pull'] = (args) => this.pullModel(args); + this.commands['model-delete'] = (args) => this.deleteModel(args); + this.commands['model-run'] = (args) => this.runModel(args); + } + async listModels() { + const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; + try { + const response = await fetch(`${endpoint}/api/tags`); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const data = await response.json(); + const models = data.models || []; + if (models.length === 0) { + this.terminal.print("No models found. Run 'ollama pull <model>' first.", "warning"); return; } + this.terminal.print("=== Available Ollama Models ===", "info"); + this.terminal.printHTML(`<table style="width: 100%; border-collapse: collapse; margin: 10px 0;"> + <tr style="border-bottom: 1px solid #005500;"> + <th style="text-align: left; padding: 5px;">Name</th> + <th style="text-align: left; padding: 5px;">Size</th> + <th style="text-align: left; padding: 5px;">Family</th> + </tr>`); + models.forEach(m => { + const sizeGB = (m.size / 1e9).toFixed(2); + this.terminal.printHTML(`<tr style="border-bottom: 1px solid #111;"> + <td style="padding: 5px; color: #00ff00;">${m.name}</td> + <td style="padding: 5px; color: #888888;">${sizeGB} GB</td> + <td style="padding: 5px; color: #00aaff;">${m.details?.family || 'N/A'}</td> + </tr>`); + }); + this.terminal.printHTML(`</table>`); + } catch (e) { + this.terminal.print(`Failed to fetch models: ${e.message}`, "error"); } + } + async modelInfo(args) { + if (!args[0]) { + this.terminal.print("Usage: model-info <model-name>", "warning"); return; + } + const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; + try { + const response = await fetch(`${endpoint}/api/show`, { + method: 'POST', headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ name: args[0] }) + }); + if (!response.ok) throw new Error(`HTTP ${response.status}`); + const data = await response.json(); + this.terminal.print(`=== ${args[0]} ===`, "info"); + this.terminal.print(`License: ${data.license || 'N/A'}`); + this.terminal.print(`Parameters: ${data.details?.parameter_size || 'N/A'}`); + this.terminal.print(`Family: ${data.details?.family || 'N/A'}`); + } catch (e) { + this.terminal.print(`Failed to get model info: ${e.message}`, "error"); + } + } + pullModel(args) { + this.terminal.print("β οΈ Model pulling must be done via Ollama CLI", "warning"); + this.terminal.print(`Run: ollama pull ${args[0] || '<model-name>'}`, "info"); + } + deleteModel(args) { + this.terminal.print("β οΈ Model deletion must be done via Ollama CLI", "warning"); + this.terminal.print(`Run: ollama rm ${args[0] || '<model-name>'}`, "info"); + } + async runModel(args) { + if (!args[0]) { + this.terminal.print("Usage: model-run <model-name> [prompt]", "warning"); return; + } + const model = args[0]; + const prompt = args.slice(1).join(' ') || 'Hello!'; + this.terminal.print(`Running ${model}...`, "info"); + await this.terminal.ollamaManager.chat(prompt, model); + } +}
\ No newline at end of file diff --git a/modules/core/module-ollamamodels.js b/modules/core/module-ollamamodels.js deleted file mode 100644 index 9a7763a..0000000 --- a/modules/core/module-ollamamodels.js +++ /dev/null @@ -1,87 +0,0 @@ -// Extracted from newOS4 index.html β OllamaModelsModule - class OllamaModelsModule { - constructor() { this.commands = {}; this.terminal = null; } - getHelpInfo() { - return { - 'models': 'models β List all available Ollama models', - 'model-info': 'model-info <model-name> β Show details about a specific model', - 'model-pull': 'model-pull <model-name> β Pull a model from Ollama registry', - 'model-delete': 'model-delete <model-name> β Delete a model from local storage', - 'model-run': 'model-run <model-name> [prompt] β Run inference with a model' - }; - } - registerCommands() { - this.commands['models'] = () => this.listModels(); - this.commands['model-info'] = (args) => this.modelInfo(args); - this.commands['model-pull'] = (args) => this.pullModel(args); - this.commands['model-delete'] = (args) => this.deleteModel(args); - this.commands['model-run'] = (args) => this.runModel(args); - } - async listModels() { - const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; - try { - const response = await fetch(`${endpoint}/api/tags`); - if (!response.ok) throw new Error(`HTTP ${response.status}`); - const data = await response.json(); - const models = data.models || []; - if (models.length === 0) { - this.terminal.print("No models found. Run 'ollama pull <model>' first.", "warning"); return; - } - this.terminal.print("=== Available Ollama Models ===", "info"); - this.terminal.printHTML(`<table style="width: 100%; border-collapse: collapse; margin: 10px 0;"> - <tr style="border-bottom: 1px solid #005500;"> - <th style="text-align: left; padding: 5px;">Name</th> - <th style="text-align: left; padding: 5px;">Size</th> - <th style="text-align: left; padding: 5px;">Family</th> - </tr>`); - models.forEach(m => { - const sizeGB = (m.size / 1e9).toFixed(2); - this.terminal.printHTML(`<tr style="border-bottom: 1px solid #111;"> - <td style="padding: 5px; color: #00ff00;">${m.name}</td> - <td style="padding: 5px; color: #888888;">${sizeGB} GB</td> - <td style="padding: 5px; color: #00aaff;">${m.details?.family || 'N/A'}</td> - </tr>`); - }); - this.terminal.printHTML(`</table>`); - } catch (e) { - this.terminal.print(`Failed to fetch models: ${e.message}`, "error"); - } - } - async modelInfo(args) { - if (!args[0]) { - this.terminal.print("Usage: model-info <model-name>", "warning"); return; - } - const endpoint = localStorage.getItem('webx11_ollama_endpoint') || 'http://localhost:11434'; - try { - const response = await fetch(`${endpoint}/api/show`, { - method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ name: args[0] }) - }); - if (!response.ok) throw new Error(`HTTP ${response.status}`); - const data = await response.json(); - this.terminal.print(`=== ${args[0]} ===`, "info"); - this.terminal.print(`License: ${data.license || 'N/A'}`); - this.terminal.print(`Parameters: ${data.details?.parameter_size || 'N/A'}`); - this.terminal.print(`Family: ${data.details?.family || 'N/A'}`); - } catch (e) { - this.terminal.print(`Failed to get model info: ${e.message}`, "error"); - } - } - pullModel(args) { - this.terminal.print("β οΈ Model pulling must be done via Ollama CLI", "warning"); - this.terminal.print(`Run: ollama pull ${args[0] || '<model-name>'}`, "info"); - } - deleteModel(args) { - this.terminal.print("β οΈ Model deletion must be done via Ollama CLI", "warning"); - this.terminal.print(`Run: ollama rm ${args[0] || '<model-name>'}`, "info"); - } - async runModel(args) { - if (!args[0]) { - this.terminal.print("Usage: model-run <model-name> [prompt]", "warning"); return; - } - const model = args[0]; - const prompt = args.slice(1).join(' ') || 'Hello!'; - this.terminal.print(`Running ${model}...`, "info"); - await this.terminal.ollamaManager.chat(prompt, model); - } - } diff --git a/modules/core/module-orchestrator.js b/modules/core/module-orchestrator.js index 4fab599..de88424 100644 --- a/modules/core/module-orchestrator.js +++ b/modules/core/module-orchestrator.js @@ -75,6 +75,22 @@ class OrchestratorModule { agent = Object.values(this._agents).find(a => a.status === 'idle'); } if (!agent) return this.terminal.print('β No available agents', 'error'); + + // A2A Contract handshake β validate task against agent's contract + const registry = this.terminal.moduleManager.modules['AgentRegistryModule']; + let contractValid = true; + if (registry) { + const result = registry.validateTask(agent.role, task); + if (!result.valid) { + this.terminal.print(`β οΈ A2A validation: ${result.reason}`, 'warning'); + this.terminal.print(` Contract for '${agent.role}' requires: ${(registry.getContract(agent.role) || {}).input_schema || 'free-form'}`, 'warning'); + // Offer to proceed anyway (permissive) β user can create a proper contract + contractValid = false; + } else if (result.reason === 'matched') { + this.terminal.print(`β
A2A contract matched for role '${agent.role}'`, 'success'); + } + } + // Create a lease const leaseModule = this.terminal.moduleManager.modules['LeaseModule']; const lease = leaseModule ? leaseModule.createLease(['lease-create', agent.id, '60', task]) : null; diff --git a/modules/core/module-servermon.js b/modules/core/module-servermon.js index 23407db..293e9af 100644 --- a/modules/core/module-servermon.js +++ b/modules/core/module-servermon.js @@ -1,35 +1,143 @@ -// Extracted from newOS4 index.html β ServerMonitorModule - class ServerMonitorModule { - constructor() { - this.commands = {}; this.terminal = null; - this.servers = this.loadServers(); this.monitorInterval = null; - } - getHelpInfo() { - return { - 'server': 'Add a server to monitor: server <name> <url>', - 'servers': 'List all monitored servers', - 'server-check': 'Check a server status: server-check <name-or-index>', - 'server-remove': 'Remove a server: server-remove <name-or-index>', - 'monitor': 'Toggle auto-monitoring (checks every 60s)' - }; - } - loadServers() { - try { - const saved = localStorage.getItem('webx11_servers'); - return saved ? JSON.parse(saved) : []; - } catch (e) { return []; } - } - saveServers() { - localStorage.setItem('webx11_servers', JSON.stringify(this.servers)); - } - registerCommands() { - this.commands['server'] = (args) => this.addServer(args); - this.commands['servers'] = () => this.listServers(); - this.commands['server-check'] = (args) => this.checkServer(args); - this.commands['server-remove'] = (args) => this.removeServer(args); - this.commands['monitor'] = (args) => this.toggleMonitor(args); - } - addServer(args) { +// module-servermon.js β Server monitoring + self-optimization telemetry +// Commands: server, servers, server-check, server-remove, monitor, system-health +class ServerMonitorModule { + constructor() { + this.commands = {}; this.terminal = null; + this.servers = this.loadServers(); this.monitorInterval = null; + this._latencyLog = []; + this._maxLatencyEntries = 200; + } + getHelpInfo() { + return { + 'server': 'server <name> <url> β Add a server to monitor', + 'servers': 'servers β List all monitored servers', + 'server-check': 'server-check <name-or-index> β Check a server status', + 'server-remove': 'server-remove <name-or-index> β Remove a server', + 'monitor': 'monitor β Toggle auto-monitoring (checks every 60s)', + 'system-health': 'system-health β Show tool latency, module load times, VFS size, and error rates' + }; + } + registerCommands() { + this.commands['server'] = (args) => this.addServer(args); + this.commands['servers'] = () => this.listServers(); + this.commands['server-check'] = (args) => this.checkServer(args); + this.commands['server-remove'] = (args) => this.removeServer(args); + this.commands['monitor'] = (args) => this.toggleMonitor(args); + this.commands['system-health'] = () => this.showSystemHealth(); + } + logToolCall(name, durationMs, error) { + this._latencyLog.push({ + name, + duration: durationMs, + error: !!error, + time: Date.now() + }); + if (this._latencyLog.length > this._maxLatencyEntries) { + this._latencyLog = this._latencyLog.slice(-this._maxLatencyEntries); + } + // Persist every 20 calls + if (this._latencyLog.length % 20 === 0) { + this._persistLatency(); + } + } + _persistLatency() { + try { + this.terminal.fs.fsWriteJSON('/system/metrics/tool-latency.json', this._latencyLog.slice(-100)); + } catch (e) {} + } + _loadLatency() { + try { + const data = this.terminal.fs.fsReadJSON('/system/metrics/tool-latency.json'); + if (data) this._latencyLog = data; + } catch (e) {} + } + showSystemHealth() { + this._loadLatency(); + const fs = this.terminal.fs; + + // Tool latency stats + const toolStats = {}; + for (const entry of this._latencyLog) { + if (!toolStats[entry.name]) toolStats[entry.name] = { calls: 0, totalMs: 0, errors: 0, maxMs: 0 }; + toolStats[entry.name].calls++; + toolStats[entry.name].totalMs += entry.duration; + toolStats[entry.name].errors += entry.error ? 1 : 0; + toolStats[entry.name].maxMs = Math.max(toolStats[entry.name].maxMs, entry.duration); + } + + this.terminal.print('π System Health', 'header'); + + // Tool latency table (sorted by avg desc) + this.terminal.print('ββ Tool Latency ββ', 'info'); + const sorted = Object.entries(toolStats) + .map(([name, s]) => ({ name, avg: (s.totalMs / s.calls).toFixed(0), ...s })) + .sort((a, b) => b.avg - a.avg); + for (const t of sorted.slice(0, 10)) { + const avgMs = t.avg.padStart(5); + const maxMs = String(t.maxMs).padStart(5); + const err = t.errors > 0 ? ` β οΈ${t.errors}` : ''; + this.terminal.print(` ${avgMs}ms avg / ${maxMs}ms max β ${t.name} (${t.calls} calls)${err}`, t.errors > 0 ? 'warning' : ''); + } + if (sorted.length > 10) this.terminal.print(` ... and ${sorted.length - 10} more tools`, 'info'); + + // VFS stats + this.terminal.print('ββ VFS Stats ββ', 'info'); + try { + const totalSize = this._vfsSize(fs.root); + const fileCount = this._vfsCount(fs.root, 'file'); + const dirCount = this._vfsCount(fs.root, 'dir'); + this.terminal.print(` ${fileCount} files, ${dirCount} dirs, ${(totalSize / 1024).toFixed(0)} KB total`, ''); + } catch (e) { this.terminal.print(' VFS stats unavailable', 'warning'); } + + // Module stats + this.terminal.print('ββ Module Stats ββ', 'info'); + const mm = this.terminal.moduleManager; + const loaded = Object.keys(mm.modules).length; + const reg = (mm.moduleRegistry || []).length; + this.terminal.print(` ${loaded} modules loaded, ${reg} in registry`, ''); + + // Memory + this.terminal.print('ββ Memory ββ', 'info'); + if (performance.memory) { + const heap = (performance.memory.usedJSHeapSize / 1048576).toFixed(1); + const total = (performance.memory.jsHeapSizeLimit / 1048576).toFixed(0); + this.terminal.print(` ${heap} MB used / ${total} MB limit`, heap > 100 ? 'warning' : ''); + } else { + this.terminal.print(' Memory info not available (non-Chrome browser)', ''); + } + + // Total tool call count + const totalCalls = this._latencyLog.length; + const totalErrors = this._latencyLog.filter(e => e.error).length; + this.terminal.print(` ${totalCalls} tool calls logged, ${totalErrors} errors (${totalCalls > 0 ? (totalErrors / totalCalls * 100).toFixed(1) : 0}% error rate)`, totalErrors > 0 ? 'warning' : ''); + } + _vfsSize(node) { + if (!node) return 0; + if (node.type === 'file') return (node.content || '').length; + let s = 0; + for (const k in (node.content || {})) s += this._vfsSize(node.content[k]); + return s; + } + _vfsCount(node, type) { + if (!node) return 0; + let c = 0; + for (const k in (node.content || {})) { + const child = node.content[k]; + if (child.type === type) c++; + c += this._vfsCount(child, type); + } + return c; + } + loadServers() { + try { + const saved = localStorage.getItem('webx11_servers'); + return saved ? JSON.parse(saved) : []; + } catch (e) { return []; } + } + saveServers() { + localStorage.setItem('webx11_servers', JSON.stringify(this.servers)); + } + addServer(args) { if (args.length < 2) { this.terminal.print("Usage: server <name> <url>", "warning"); return; } diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 4111f5f..e3f222c 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -14,7 +14,7 @@ this._registerBuiltIn(); } _registerBuiltIn() { - const internals = ['clear','help','ls','cat','df','free','env','history','cd','pwd','touch','mkdir','rm','cp','mv','edit','cat','run','font-size','load-local','loadlocal','mem','security','security-level','startup-modules','smart-prompt','cmd-allow','cmd-deny']; + const internals = ['clear','help','ls','cat','df','free','env','history','cd','pwd','touch','mkdir','rm','cp','mv','edit','cat','run','font-size','load-local','loadlocal','mem','security','security-level','startup-modules','smart-prompt','cmd-allow','cmd-deny','system-health','server','servers','server-check','monitor']; internals.forEach(c => this.registerCommand(c, { category: 'builtin' })); } setLevel(n) { @@ -1027,6 +1027,9 @@ this._safeRegister('AgentRegistryModule', 'agent registry'); this._safeRegister('LeaseModule', 'lease system'); this._safeRegister('OrchestratorModule', 'orchestrator'); + this._safeRegister('NeuralVFSModule', 'neural VFS'); + this._safeRegister('ServerMonitorModule', 'server monitor'); + this._safeRegister('SimpleGUIModule', 'simple GUI builder'); } _safeRegister(className, label) { let cls; diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js index d2d3103..3ab25b1 100644 --- a/modules/core/virtual-fs.js +++ b/modules/core/virtual-fs.js @@ -3,6 +3,7 @@ class VirtualFileSystem { this.root = { type: 'dir', content: {} }; this.currentPath = []; this._ready = this.loadFromStorage(); + this._conceptCache = null; } _u8ToBase64(u8) { let s = ''; @@ -82,6 +83,27 @@ class VirtualFileSystem { } catch (e) { console.error('FS save error:', e); } }, 2000); } + getCurrentPath() { + return '/' + this.currentPath.join('/'); + } + setCurrentPath(path) { + const segs = this._toAbsoluteSegments(path); + if (segs === null) return false; + this.currentPath = segs; + return true; + } + _loadConceptIndex() { + if (this._conceptCache) return this._conceptCache; + try { + const raw = this.readFile('/.semantic_index/map.json'); + if (raw) { + this._conceptCache = JSON.parse(raw); + return this._conceptCache; + } + } catch (e) {} + return null; + } + _clearConceptCache() { this._conceptCache = null; } getCurrentDir() { let dir = this.root; for (let part of this.currentPath) { @@ -130,6 +152,18 @@ class VirtualFileSystem { return dir; } ls(path) { + // concept:// listing + if (path && path.startsWith('concept://')) { + const concept = path.replace('concept://', '').replace(/\/.*$/, '').toLowerCase(); + const index = this._loadConceptIndex(); + if (!index) return []; + let matches = index[concept] || []; + if (matches.length === 0) { + const fuzzy = Object.keys(index).filter(k => k.includes(concept) || concept.includes(k)); + if (fuzzy.length > 0) matches = index[fuzzy[0]]; + } + return (matches || []).map(m => ({ name: m.path.split('/').pop(), type: 'file', path: m.path, size: 0, concept: true })); + } let dir; if (path) { const resolved = this._resolvePath(path); @@ -161,6 +195,24 @@ class VirtualFileSystem { return true; } readFile(path) { + // concept:// URI resolution + if (path && path.startsWith('concept://')) { + const concept = path.replace('concept://', '').replace(/\/.*$/, '').toLowerCase(); + try { + const index = this._loadConceptIndex(); + if (!index) return 'No semantic index found. Run nvfs-index first.'; + let matches = index[concept]; + if (!matches) { + const fuzzy = Object.keys(index).filter(k => k.includes(concept) || concept.includes(k)); + if (fuzzy.length > 0) matches = index[fuzzy[0]]; + } + if (!matches || matches.length === 0) return `No files found for concept "${concept}"`; + const first = matches[0]; + const content = this.readFile(first.path); + if (content) return `--- ${first.path} (concept://${concept}) ---\n${content}`; + return `Concept "${concept}" β ${matches.length} file(s):\n${matches.map(m => ` ${m.path} β ${m.summary || ''}`).join('\n')}`; + } catch (e) { return `concept:// error: ${e.message}`; } + } const resolved = this._resolvePath(path); if (!resolved || !resolved.name) return null; const node = resolved.dir.content[resolved.name]; diff --git a/modules/ext/mindmap.js b/modules/ext/mindmap.js index 9f62cba..d0cab54 100644 --- a/modules/ext/mindmap.js +++ b/modules/ext/mindmap.js @@ -44,11 +44,12 @@ class MindmapModule { const self = this; this.commands['mindmap'] = (args) => { if (!args[0] || args[0] === '--help' || args[0] === '-h') { - this.terminal.print('Usage: mindmap <new|add|show|export|save|load|list|delete|rename|color|tag> [...]', 'info'); + this.terminal.print('Usage: mindmap <new|add|show|export|save|load|list|delete|rename|color|tag|svg> [...]', 'info'); this.terminal.print(' new <topic> [-t tags] β Create a new mindmap', 'info'); this.terminal.print(' add <parent-id> <text> [-t tags] β Add a child node', 'info'); this.terminal.print(' show β Display the mindmap tree', 'info'); this.terminal.print(' export β Print as indented text', 'info'); + this.terminal.print(' svg [name] β Render as inline SVG, optionally save to VFS', 'info'); this.terminal.print(' save [name] β Save to VFS', 'info'); this.terminal.print(' load <name> β Load from VFS', 'info'); this.terminal.print(' list β List saved mindmaps', 'info'); @@ -77,7 +78,8 @@ class MindmapModule { case 'rename': return this._rename(rest); case 'color': return this._color(rest); case 'tag': return this._tag(rest); - default: this.terminal.print('Unknown subcommand: ' + sub + '. Try: new, add, show, export, save, load, list, delete, rename, color, tag', 'warning'); + case 'svg': return this._svg(rest); + default: this.terminal.print('Unknown subcommand: ' + sub + '. Try: new, add, show, export, save, load, list, delete, rename, color, tag, svg', 'warning'); } }; } @@ -232,6 +234,77 @@ class MindmapModule { node.tags.push(tag); this.terminal.print('Added tag "' + tag + '" to ' + id, 'success'); } + _svg(args) { + if (!this.root) return this.terminal.print('No mindmap. Create one with mindmap new first.', 'warning'); + const saveName = args[0] || null; + + // Layout settings + const nw = 160, nh = 44, hGap = 24, vGap = 60, pad = 30; + + // Color mapping from name to hex + const colorMap = { + red: '#fb7185', green: '#34d399', yellow: '#fbbf24', blue: '#818cf8', + cyan: '#22d3ee', magenta: '#e879f9', white: '#e0e0e0' + }; + + const layout = { nodes: [], edges: [], width: 0, height: 0, _y: pad }; + + const layoutTree = (node, x) => { + const myY = layout._y; + const myX = x; + const color = colorMap[node.color] || '#818cf8'; + layout.nodes.push({ x: myX, y: myY, w: nw, h: nh, text: node.text, color, id: node.id }); + + if (node.children && node.children.length > 0) { + const totalW = node.children.length * nw + (node.children.length - 1) * hGap; + let cx = x + nw / 2 - totalW / 2; + layout._y += nh + vGap; + for (const child of node.children) { + const childX = cx; + layout.edges.push({ x1: myX + nw / 2, y1: myY, x2: childX + nw / 2, y2: layout._y - vGap + nh }); + layoutTree(child, childX); + cx += nw + hGap; + } + layout._y -= nh + vGap; + } + const rightEdge = x + nw; + if (rightEdge > layout.width) layout.width = rightEdge; + }; + + layout._y = pad; + layoutTree(this.root, pad); + layout.height = layout._y + nh + pad; + + // Build SVG + let svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${layout.width + pad} ${layout.height}" style="max-width:100%;background:#0a0a14;font-family:monospace;border-radius:8px;">`; + + // Edges first (behind nodes) + for (const e of layout.edges) { + const mx = (e.x1 + e.x2) / 2; + svg += `<path d="M${e.x1},${e.y1} C${mx},${e.y1 + 20} ${mx},${e.y2 - 20} ${e.x2},${e.y2}" fill="none" stroke="#2a2a4a" stroke-width="1.5"/>`; + } + + // Nodes on top + for (const n of layout.nodes) { + svg += `<rect x="${n.x}" y="${n.y}" width="${n.w}" height="${n.h}" rx="6" fill="${n.color}18" stroke="${n.color}" stroke-width="1.5"/>`; + const text = n.text.length > 18 ? n.text.substring(0, 16) + '..' : n.text; + svg += `<text x="${n.x + n.w / 2}" y="${n.y + n.h / 2 + 4}" text-anchor="middle" fill="#e0e0e0" font-size="10" font-family="monospace">${text.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')}</text>`; + } + svg += '</svg>'; + + this.terminal.printHTML(svg); + + if (saveName) { + try { + const fs = this.terminal.fs; + fs.mkdirRecursive('/mindmaps'); + fs.writeFile('/mindmaps/' + saveName + '.svg', svg); + this.terminal.print('πΎ Saved to /mindmaps/' + saveName + '.svg', 'success'); + } catch (e) { + this.terminal.print('Failed to save SVG: ' + e.message, 'error'); + } + } + } } if (typeof window.webx11 !== 'undefined' && window.webx11) { webx11.moduleManager.registerModule(new MindmapModule(), 'https://webx11.duckdns.org/spaces/newos4/modules/ext/mindmap.js'); diff --git a/newos4_vision.html b/newos4_vision.html index 7bdb262..c31bde1 100644 --- a/newos4_vision.html +++ b/newos4_vision.html @@ -116,16 +116,16 @@ <div class="section"> <h2>Strategic Roadmap</h2> <div class="roadmap-item"> - <span class="phase">Phase 1</span> + <span class="phase">Phase 1 β
</span> <span>Foundation: WebX11 terminal stability, VFS perfection, and Procedural Memory (Skills).</span> </div> <div class="roadmap-item"> - <span class="phase">Phase 2 β
</span> - <span>Agentic Shift: Agent orchestration (list, register, leases, orchestrate). Security layer (security-level 0-3, cmd-allow/deny). Debug panel. WebDAV modern browser.</span> + <span class="phase">Phase 2 π‘</span> + <span>Agentic Shift: AI tool-calling loop (19+ tools), session_terminal context access, tool failure buffer + auto-skill creation, agent orchestration (list, register, leases, orchestrate). Security layer (security-level 0-3). Debug panel. Localized asset management.</span> </div> <div class="roadmap-item"> - <span class="phase">Phase 3</span> - <span>Cognitive OS: Global World Model, Neural VFS, Recursive self-optimization, Predictive resource allocation.</span> + <span class="phase">Phase 3 π’</span> + <span>Cognitive OS: Neural VFS (semantic concept indexing), A2A Protocol (agent contracts + handshake), Recursive self-optimization, Predictive resource allocation.</span> </div> </div> diff --git a/packages.json b/packages.json index 614c9c5..5d8203b 100644 --- a/packages.json +++ b/packages.json @@ -1,7 +1,7 @@ { "name": "WebX11 Package Index", - "version": "1.0.0", - "updated": "2026-05-24T00:00:00Z", + "version": "1.1.0", + "updated": "2026-06-04T00:00:00Z", "base_url": "https://webx11.duckdns.org/spaces/newos4/modules/ext/", "packages": { "voice": { @@ -9,7 +9,9 @@ "version": "1.0.0", "desc": "Speech-to-text input using Web Speech API", "url": "modules/ext/voice.js", - "commands": ["voice"], + "commands": [ + "voice" + ], "category": "input" }, "calc": { @@ -17,7 +19,9 @@ "version": "1.0.0", "desc": "Math evaluator and unit converter (km to miles, kg to pounds, etc.)", "url": "modules/ext/calc.js", - "commands": ["calc"], + "commands": [ + "calc" + ], "category": "utility" }, "cron": { @@ -25,7 +29,12 @@ "version": "1.0.0", "desc": "Schedule commands to run at intervals (min 5s)", "url": "modules/ext/cron.js", - "commands": ["cron-every", "cron-list", "cron-stop", "cron-clear"], + "commands": [ + "cron-every", + "cron-list", + "cron-stop", + "cron-clear" + ], "category": "automation" }, "theme": { @@ -33,7 +42,9 @@ "version": "1.0.0", "desc": "CSS theme manager β dark, light, amber, cyber + custom", "url": "modules/ext/theme.js", - "commands": ["theme"], + "commands": [ + "theme" + ], "category": "ui" }, "wpm": { @@ -41,7 +52,9 @@ "version": "1.0.0", "desc": "Install modules from the WebX11 package index (like npm for the terminal)", "url": "modules/ext/wpm.js", - "commands": ["wpm"], + "commands": [ + "wpm" + ], "category": "system" }, "webdav": { @@ -49,7 +62,16 @@ "version": "1.0.0", "desc": "Cloud sync for VFS β backup, push, pull, and restore via WebDAV", "url": "modules/ext/webdav.js", - "commands": ["webdav-config", "webdav-status", "webdav-ls", "webdav-push", "webdav-pull", "webdav-backup", "webdav-restore", "webdav-backup-list"], + "commands": [ + "webdav-config", + "webdav-status", + "webdav-ls", + "webdav-push", + "webdav-pull", + "webdav-backup", + "webdav-restore", + "webdav-backup-list" + ], "category": "system" }, "mindmap": { @@ -57,7 +79,9 @@ "version": "1.0.0", "desc": "Brainstorming mindmap tool β new, add, show, export, save, load, color, tag", "url": "modules/ext/mindmap.js", - "commands": ["mindmap"], + "commands": [ + "mindmap" + ], "category": "productivity" }, "skill-pack-core": { @@ -65,7 +89,9 @@ "version": "1.0.0", "desc": "Comprehensive skill set: terminal navigation, memory/profile, web search, module editing, system maintenance, backup, mindmap workflow, skills system guide", "url": "modules/ext/skill-pack-core.js", - "commands": ["skill-pack-core"], + "commands": [ + "skill-pack-core" + ], "category": "system" }, "editor": { @@ -73,7 +99,9 @@ "version": "1.0.0", "desc": "Inline text editor for VFS files β edit, save, cancel via modal", "url": "modules/ext/editor.js", - "commands": ["edit"], + "commands": [ + "edit" + ], "category": "utility" }, "diff": { @@ -81,7 +109,9 @@ "version": "1.0.0", "desc": "Compare two files or module versions with unified diff output", "url": "modules/ext/diff.js", - "commands": ["diff"], + "commands": [ + "diff" + ], "category": "utility" }, "alias": { @@ -89,7 +119,13 @@ "version": "1.0.0", "desc": "Define and manage command aliases (ll, h, cls defaults) with localStorage persistence", "url": "modules/ext/alias.js", - "commands": ["alias", "unalias", "ll", "h", "cls"], + "commands": [ + "alias", + "unalias", + "ll", + "h", + "cls" + ], "category": "system" }, "finder": { @@ -97,7 +133,9 @@ "version": "1.0.0", "desc": "Recursive VFS file/directory search with fuzzy matching", "url": "modules/ext/finder.js", - "commands": ["find"], + "commands": [ + "find" + ], "category": "utility" }, "filemgr": { @@ -105,7 +143,10 @@ "version": "1.0.0", "desc": "Modern file browser with preview for Markdown, images, video, audio, code, PDF, CSV", "url": "modules/ext/filemgr.js", - "commands": ["files", "preview"], + "commands": [ + "files", + "preview" + ], "category": "utility" }, "cryptogzip": { @@ -113,7 +154,12 @@ "version": "1.0.0", "desc": "AES-256-GCM encrypt/decrypt and gzip/gunzip for VFS files", "url": "modules/ext/cryptogzip.js", - "commands": ["gzip", "gunzip", "encrypt", "decrypt"], + "commands": [ + "gzip", + "gunzip", + "encrypt", + "decrypt" + ], "category": "security" }, "busybox": { @@ -121,7 +167,24 @@ "version": "1.0.0", "desc": "Unix utility commands: which, env, date, cal, yes, seq, base64, printf, cut, uniq, hostname, whoami, basename, dirname, sleep, expand", "url": "modules/ext/busybox.js", - "commands": ["which", "env", "date", "cal", "yes", "seq", "base64", "printf", "cut", "uniq", "hostname", "whoami", "basename", "dirname", "sleep", "expand"], + "commands": [ + "which", + "env", + "date", + "cal", + "yes", + "seq", + "base64", + "printf", + "cut", + "uniq", + "hostname", + "whoami", + "basename", + "dirname", + "sleep", + "expand" + ], "category": "utility" }, "shell": { @@ -129,7 +192,12 @@ "version": "1.0.0", "desc": "Full shell: pipe |, redirect > >> <, variable $VAR, chain && || ;, VFS script execution", "url": "modules/ext/shell.js", - "commands": ["export", "unset", "script", "set"], + "commands": [ + "export", + "unset", + "script", + "set" + ], "category": "system" }, "tutorial": { @@ -137,7 +205,9 @@ "version": "1.0.0", "desc": "Interactive guided tour β 6 quests to learn newOS4 basics", "url": "modules/ext/tutorial.js", - "commands": ["tutorial"], + "commands": [ + "tutorial" + ], "category": "onboarding" }, "test-suite": { @@ -145,8 +215,23 @@ "version": "1.0.0", "desc": "32 automated tests: filesystem, busybox, shell, cryptogzip, skills, security, modules. Run with `load-local modules/test/test-suite.js` then `test`", "url": "modules/test/test-suite.js", - "commands": ["test"], + "commands": [ + "test" + ], "category": "utility" + }, + "neural-vfs": { + "name": "Neural VFS Indexer", + "version": "1.0.0", + "desc": "Semantic concept-indexing layer β nvfs-index, nvfs-resolve, nvfs-tree, nvfs-status", + "url": "modules/ext/neural-vfs.js", + "commands": [ + "nvfs-index", + "nvfs-status", + "nvfs-resolve", + "nvfs-tree" + ], + "category": "system" } } -} +}
\ No newline at end of file diff --git a/review-newos4.html b/review-newos4.html index 4ce41cc..3d8f7d4 100644 --- a/review-newos4.html +++ b/review-newos4.html @@ -75,7 +75,7 @@ <body> <header> <div class="header-content"> - <span class="logo"><span class="logo-icon">π§©</span> newOS4 v4.3 Review</span> + <span class="logo"><span class="logo-icon">π§©</span> newOS4 v4.3.1 Review</span> <div style="display:flex;gap:8px;flex-wrap:wrap;"> <a href="/spaces/newos4/help.html">π Help β</a> <a href="/spaces/newos4/main.html">Launch OS β</a> @@ -85,24 +85,25 @@ <div class="container"> -<h1>newOS4 v4.3</h1> -<p class="meta">WebX11 Terminal Β· In-Browser Terminal OS Β· Reviewed 2026-06-02</p> +<h1>newOS4 v4.3.1</h1> +<p class="meta">WebX11 Terminal Β· In-Browser Terminal OS Β· Reviewed 2026-06-03</p> <div class="summary-box"> - <div class="stat"><div class="value">32</div><div class="label">Module Files</div></div> + <div class="stat"><div class="value">33</div><div class="label">Module Files</div></div> <div class="stat"><div class="value">18+14</div><div class="label">Core + Ext</div></div> - <div class="stat"><div class="value">12</div><div class="label">Skills</div></div> + <div class="stat"><div class="value">21</div><div class="label">Skills</div></div> <div class="stat"><div class="value">9</div><div class="label">Theme Presets</div></div> <div class="stat"><div class="value">52KB</div><div class="label">App Size</div></div> - <div class="stat"><div class="value">4/5</div><div class="label">Rating</div></div> + <div class="stat"><div class="value">4.5/5</div><div class="label">Rating</div></div> </div> <section> <h2>Architecture</h2> <p>newOS4 v4.3 is an <strong>in-browser terminal OS</strong> β NOT a chat-centric UI. Single-file <code>main.html</code> (1,031 lines, 52KB) loads 32 module files across two directories:</p> <ul> - <li><strong>18 core modules</strong> (<code>modules/core/</code>) β Foundation infrastructure (VirtualFileSystem, OllamaManager, SecretVault, ModuleManager, Terminal) + 13 built-in feature modules (system, fs, modmgr, ollama, my, searxng, servermon, ollamamodels, config, simplegui, io, dynamicprompts, aiassist, aiasm, smartctx, duckduckgo, fetcher, skills, chatstudio, debug)</li> - <li><strong>14 ext modules</strong> (<code>modules/ext/</code>) β Self-registering: alias, busybox, calc, cron, cryptogzip, diff, editor, filemgr, finder, mindmap, shell, skill-pack-core, theme, tutorial, voice, webdav, wpm</li> + <li><strong>29 core modules</strong> (<code>modules/core/</code>) β Foundation infrastructure (VirtualFileSystem, OllamaManager, SecretVault, ModuleManager, Terminal) + 24 built-in feature modules (system, fs, modmgr, ollama, my, searxng, servermon, ollamamodels, config, simplegui, io, dynamicprompts, aiassist, aiasm, smartctx, duckduckgo, fetcher, skills, chatstudio, agent-registry, leases, orchestrator, neural-vfs)</li> + <li><strong>17 ext modules</strong> (<code>modules/ext/</code>) β Self-registering: alias, busybox, calc, cron, cryptogzip, diff, editor, filemgr, finder, mindmap, shell, skill-pack-core, theme, tutorial, voice, webdav, wpm</li> + <li><strong>46 modules total</strong> β Full discovery via <code>modules-list</code> command or AI <code>list_available_modules</code> tool. Indexed in <code>modules-index.json</code></li> </ul> <p><strong>Total codebase</strong>: ~500KB (main.html + all module files). AI system with 5-turn agentic loop, 19+ tool definitions, 12 skills in VFS, 9 theme presets, and full destructive-action confirmation.</p> </section> @@ -141,7 +142,14 @@ <h3>π Skills System</h3> <ul> - <li><strong>12 skills</strong> stored as Markdown with YAML frontmatter in VFS <code>/skills/</code></li> + <li><strong>π§ Neural VFS</strong> β Semantic concept indexing: <code>nvfs-index</code>, <code>nvfs-resolve</code>, <code>nvfs-status</code>, <code>nvfs-tree</code></li> + <li><strong>π A2A Protocol</strong> β Agent contract system with schema validation, orchestrator validates tasks before delegation</li> + <li><strong>π Self-Optimization Telemetry</strong> β <code>system-health</code> command with tool latency, VFS stats, error rates</li> + </ul> + + <h3>π Skills System</h3> + <ul> + <li><strong>21 skills</strong> (from 12) stored as Markdown with YAML frontmatter in VFS <code>/skills/</code></li> <li>Skill-pack core auto-loads skills on startup with seed/reload</li> <li>8 CLI commands: skill-list, skill-view, skill-create, skill-patch, skill-delete, skill-export, skill-import, skill-sync</li> <li>Skills Manager UI modal (π button in quick-actions bar)</li> @@ -167,10 +175,12 @@ <h3>π€ Agent Orchestration</h3> <ul> - <li><code>agent-list</code> β list registered AI agents and their status</li> - <li><code>agent-register <name> <model></code> β register a new AI agent</li> - <li><code>lease-list</code> β show active agent leases/tasks</li> - <li><code>orchestrate <task></code> β delegate a multi-step task to the agent orchestrator</li> + <li><code>agent-list</code>, <code>agent-status</code> β list and inspect registered AI agents</li> + <li><code>agent-register</code>, <code>agent-unregister</code> β manage agent lifecycle</li> + <li><code>orchestrate <task></code> β delegate multi-step task with A2A contract validation</li> + <li><code>orchestrator-status</code>, <code>orchestrator-spawn</code> β manage agent pool</li> + <li><code>contract-register</code>, <code>contract-list</code> β define agent contracts with input/output schema</li> + <li>Lease-based lifecycle: each task creates a lease with TTL, heartbeat monitoring, auto-purge</li> </ul> <h3>π€ Voice Command</h3> diff --git a/skills/a2a-contract-framework.md b/skills/a2a-contract-framework.md new file mode 100644 index 0000000..51678b2 --- /dev/null +++ b/skills/a2a-contract-framework.md @@ -0,0 +1,30 @@ +--- +name: a2a-contract-framework +description: Framework for formalizing Agent-to-Agent (A2A) contracts to ensure deterministic collaboration. +tags: a2a, agent-orchestration, protocol, newos4 +category: system +--- + +# A2A Contract Framework + +## 1. Purpose +To move from "best-effort" delegation to "contractual" execution by defining a strict interface (`.contract.json`) for every agent role. + +## 2. Contract Schema +Every agent must have an associated contract containing: +- `role`: The official designation (e.g., "researcher"). +- `capabilities`: `string[]` of authorized toolsets. +- `input_schema`: JSON Schema defining required parameters. +- `output_schema`: JSON Schema defining guaranteed return format. +- `sla`: Response time goals and accuracy thresholds. +- `resource_weight`: Numeric value representing cognitive cost. + +## 3. Workflow +1. **Handshake**: Orchestrator requests contract from Agent. +2. **Verification**: Orchestrator validates task against `input_schema`. +3. **Execution**: Agent executes using only `capabilities`. +4. **Validation**: Orchestrator validates result against `output_schema`. + +## 4. Implementation Path +- Store contracts in `.contracts/` directory. +- Reference contracts during `spawn_agent` calls. diff --git a/skills/bug-tracker.md b/skills/bug-tracker.md index 05963e4..bb8febf 100644 --- a/skills/bug-tracker.md +++ b/skills/bug-tracker.md @@ -2,6 +2,7 @@ name: bug-tracker description: A systematic approach to tracking and managing bugs in the VFS. tags: [dev, debugging, management, workflow] +category: dev --- # Bug Tracking Workflow diff --git a/skills/index.json b/skills/index.json index 4b168ca..200bc02 100644 --- a/skills/index.json +++ b/skills/index.json @@ -1 +1 @@ -{"navigating-the-terminal":{"name":"navigating-the-terminal","description":"How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem","tags":["terminal","navigation","help","filesystem"],"category":"system","created":"2026-06-02T22:07:32.333Z","updated":"2026-06-02T22:07:32.333Z"},"memory-and-profile":{"name":"memory-and-profile","description":"How to use the user profile system, session memory, and pattern tracking for persistent context","tags":["memory","profile","session","persistence"],"category":"system","created":"2026-06-02T22:07:32.333Z","updated":"2026-06-02T22:07:32.333Z"},"web-search-and-fetch":{"name":"web-search-and-fetch","description":"How to search the web and fetch URL content using the WebX11 proxy API","tags":["search","fetch","web","proxy","api"],"category":"research","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"module-management":{"name":"module-management","description":"How to view, edit, test, reload modules and manage startup configuration","tags":["modules","editing","code","self-improvement"],"category":"dev","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"system-maintenance":{"name":"system-maintenance","description":"How to reset, troubleshoot, and maintain the WebX11 terminal","tags":["system","maintenance","reset","troubleshoot","config"],"category":"system","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"backup-and-restore":{"name":"backup-and-restore","description":"How to backup, restore, and export WebX11 data","tags":["backup","restore","export","import","persistence"],"category":"system","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"mindmap-workflow":{"name":"mindmap-workflow","description":"How to create, view, edit, and manage brainstorming mindmaps","tags":["mindmap","brainstorming","planning","organization"],"category":"productivity","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"skills-system-guide":{"name":"skills-system-guide","description":"How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory","tags":["skills","system","meta"],"category":"system","created":"2026-06-02T22:07:32.334Z","updated":"2026-06-02T22:07:32.334Z"},"agent-orchestration":{"name":"agent-orchestration","description":"How to use the agent registry, leases, and orchestrator for multi-agent workflows","tags":["agents","orchestration","delegation","leases"],"category":"system","created":"2026-06-02T22:07:32.335Z","updated":"2026-06-02T22:07:32.335Z"},"debug-panel-and-logs":{"name":"debug-panel-and-logs","description":"How to use the debug panel, session logging, and terminal diagnostics","tags":["debug","logging","diagnostics","troubleshooting"],"category":"system","created":"2026-06-02T22:07:32.335Z","updated":"2026-06-02T22:07:32.335Z"},"webdav-operations":{"name":"webdav-operations","description":"How to use WebDAV cloud storage for backup, file sync, and remote file access","tags":["webdav","cloud","backup","sync","storage"],"category":"system","created":"2026-06-02T22:07:32.335Z","updated":"2026-06-02T22:07:32.335Z"},"security-and-safety":{"name":"security-and-safety","description":"How to use WebX11 security levels, command blocking, and safety features","tags":["security","safety","blocking","permissions"],"category":"system","created":"2026-06-02T22:07:32.335Z","updated":"2026-06-02T22:07:32.335Z"},"mindmap-user-guide":{"name":"mindmap-user-guide","description":"How to create, view, and manage brainstorming mindmaps using the mindmap terminal module","tags":["mindmap","brainstorming","organization","planning"],"category":"productivity","created":"2026-06-02T13:20:28.672Z","updated":"2026-06-02T13:20:28.672Z"},"bug-tracker":{"name":"bug-tracker","description":"Systematic workflow for tracking bugs using a JSON log file in the VFS.","tags":["dev","debugging","management","workflow"],"category":"dev","created":"2026-06-02T10:10:44.447Z","updated":"2026-06-02T10:10:44.447Z"},"task-manager":{"name":"task-manager","description":"A systematic workflow for tracking and managing tasks via a VFS JSON store.","tags":["productivity","tasks","vfs"],"category":"productivity","created":"2026-06-02T10:12:44.476Z","updated":"2026-06-02T10:12:44.476Z"},"agent-optimization-framework":{"name":"agent-optimization-framework","description":"","tags":["optimization","agentic-workflow","efficiency","tool-calls"],"category":"system","created":"2026-05-29T14:52:23.451Z","updated":"2026-05-29T14:52:23.451Z"},"macro-engine-debug":{"name":"macro-engine-debug","description":"","tags":["debug","a-repair","macro"],"category":"system","created":"2026-05-29T15:06:24.057Z","updated":"2026-05-29T15:06:24.057Z"},"macro-engine-onboarding":{"name":"macro-engine-onboarding","description":"","tags":["onboarding","context","macro"],"category":"system","created":"2026-05-29T15:06:24.064Z","updated":"2026-05-29T15:06:24.064Z"},"project-profile-manager":{"name":"project-profile-manager","description":"","tags":["context","memory","workspace"],"category":"system","created":"2026-05-29T15:08:44.897Z","updated":"2026-05-29T15:08:44.897Z"}}
\ No newline at end of file +{"a2a-contract-framework":{"name":"a2a-contract-framework","description":"Framework for formalizing Agent-to-Agent (A2A) contracts to ensure deterministic collaboration.","tags":["a2a","agent-orchestration","protocol","newos4"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"agent-optimization-framework":{"name":"agent-optimization-framework","description":"System for reducing tool-call latency and increasing agentic precision through programmatic workflows.","tags":["optimization","agentic-workflow","efficiency","tool-calls"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"agent-orchestration":{"name":"agent-orchestration","description":"How to use the agent registry, leases, and orchestrator for multi-agent workflows","tags":["agents","orchestration","delegation","leases"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"backup-and-restore":{"name":"backup-and-restore","description":"How to backup, restore, and export WebX11 data","tags":["backup","restore","export","import","persistence"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"bug-tracker":{"name":"bug-tracker","description":"A systematic approach to tracking and managing bugs in the VFS.","tags":["dev","debugging","management","workflow"],"category":"dev","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"debug-panel-and-logs":{"name":"debug-panel-and-logs","description":"How to use the debug panel, session logging, and terminal diagnostics","tags":["debug","logging","diagnostics","troubleshooting"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"localize-external-assets":{"name":"localize-external-assets","description":"Downloads external JS/CSS assets to the VFS to bypass server-side security restrictions on external scripts.","tags":["security","assets","vfs","localization"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"macro-engine":{"name":"macro-engine","description":"Rapid session onboarding and module debugging β context recovery, status checks, source analysis, and live testing.","tags":["macro","onboarding","debug","context","recovery","development"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"memory":{"name":"memory","description":"Manage user profiles, session memory, and persistent memory map for cross-session context.","tags":["memory","profile","session","persistence","context","map"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"mindmap":{"name":"mindmap","description":"Create, manage, export, and persist brainstorming mindmaps using the mindmap terminal module.","tags":["mindmap","brainstorming","planning","organization","visualization"],"category":"productivity","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"module-management":{"name":"module-management","description":"How to view, edit, test, reload modules and manage startup configuration","tags":["modules","editing","code","self-improvement"],"category":"dev","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"navigating-the-terminal":{"name":"navigating-the-terminal","description":"How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem","tags":["terminal","navigation","help","filesystem"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"neural-vfs-indexer":{"name":"neural-vfs-indexer","description":"Scans the VFS to create semantic mappings between concepts and file paths.","tags":["neural-vfs","semantic","indexing","newos4"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"project-profile-manager":{"name":"project-profile-manager","description":"Handles saving and loading of project-specific context bundles.","tags":["context","memory","workspace"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"security-and-safety":{"name":"security-and-safety","description":"How to use WebX11 security levels, command blocking, and safety features","tags":["security","safety","blocking","permissions"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"skills-system-guide":{"name":"skills-system-guide","description":"How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory","tags":["skills","system","meta"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"system-maintenance":{"name":"system-maintenance","description":"How to reset, troubleshoot, and maintain the WebX11 terminal","tags":["system","maintenance","reset","troubleshoot","config"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"task-manager":{"name":"task-manager","description":"A systematic approach to managing tasks using a JSON-based tracking system in the VFS.","tags":["productivity","management","organization"],"category":"productivity","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"web-search-and-fetch":{"name":"web-search-and-fetch","description":"How to search the web and fetch URL content using the WebX11 proxy API","tags":["search","fetch","web","proxy","api"],"category":"research","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"webdav":{"name":"webdav","description":"Configure, sync, backup, and restore VFS via WebDAV cloud storage.","tags":["webdav","cloud","backup","sync","storage","vfs"],"category":"system","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"},"webx11-dev-cycle":{"name":"webx11-dev-cycle","description":"Professional workflow for analyzing, prototyping, and implementing new features in WebX11.","tags":["development","workflow","webx11"],"category":"dev","created":"2026-06-03T22:22:07.000Z","updated":"2026-06-03T22:22:07.000Z"}} diff --git a/skills/localize-external-assets.md b/skills/localize-external-assets.md new file mode 100644 index 0000000..b7a1c9b --- /dev/null +++ b/skills/localize-external-assets.md @@ -0,0 +1,18 @@ +--- +name: localize-external-assets +description: Downloads external JS/CSS assets to the VFS to bypass server-side security restrictions on external scripts. +tags: [security, assets, vfs, localization] +category: system +--- + +### Logic +1. Identify external URLs in the target HTML/CSS. +2. Use the `download <url>` command to save these files into a local `/assets/` directory. +3. Update the HTML file to reference local paths (e.g., `src="https://cdn..."` $\rightarrow$ `src="/assets/..."`). + +### Implementation Steps +1. **Scan**: Read the file and extract all `src` and `href` attributes pointing to external domains. +2. **Prepare**: Create an `/assets/` directory if it doesn't exist. +3. **Fetch**: Execute `download <url>` for every identified external dependency. +4. **Patch**: Use `write_file` to replace the remote URLs with the local VFS paths. +5. **Verify**: Confirm the file is successfully updated and assets are present in the VFS. diff --git a/skills/macro-engine-debug.md b/skills/macro-engine-debug.md deleted file mode 100644 index e8cc662..0000000 --- a/skills/macro-engine-debug.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: macro-engine-debug -description: A compound operation sequence to audit, view, and test a module for stability and correctness. -tags: [debug, a-repair, macro, development] -category: dev ---- - -# Macro Engine Debug - -## π― Objective -Rapidly diagnose issues within a loaded module by combining status checks, source analysis, and live testing. - -## π οΈ Execution Steps -1. **Status Check:** Call `get_module_status` to identify if the module is currently loaded, modified, or has a remote URL mismatch. -2. **Source Analysis:** Call `view_module(name)` to examine the current implementation logic. -3. **Live Testing:** Use `test_module(name)` to load the edited version from `/_mods/` and verify the fix. -4. **Synthesis:** Compare the test results with the original bug report to confirm the resolution. - -## π Workflow -`get_module_status` β `view_module` β `test_module` β `report` diff --git a/skills/macro-engine-onboarding.md b/skills/macro-engine-onboarding.md deleted file mode 100644 index 669d665..0000000 --- a/skills/macro-engine-onboarding.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: macro-engine-onboarding -description: A rapid context-recovery sequence to align the AI with the current session state and active projects. -tags: [onboarding, context, recovery, macro] -category: system ---- - -# Macro Engine Onboarding - -## π― Objective -Efficiently recover state and context at the start of a session to avoid redundant queries and minimize hallucinations. - -## π οΈ Execution Steps -1. **Session Review:** Call `session_recent(3)` to identify the last active tasks and their outcomes. -2. **VFS Snapshot:** Call `list_files('')` to examine the root directory for new project files or configuration changes. -3. **Procedure Retrieval:** Call `load_skills('current-task')` to see if any stored procedures are applicable to the immediate goal. -4. **User Preferences:** Call `user_list` to check for project-specific flags or persistent preferences (e.g., preferred models, project paths). - -## π Workflow -`session_recent` β `list_files` β `load_skills` β `user_list` diff --git a/skills/macro-engine.md b/skills/macro-engine.md new file mode 100644 index 0000000..ca5ef5e --- /dev/null +++ b/skills/macro-engine.md @@ -0,0 +1,28 @@ +--- +name: macro-engine +description: Rapid session onboarding and module debugging β context recovery, status checks, source analysis, and live testing. +tags: [macro, onboarding, debug, context, recovery, development] +category: system +--- + +TODO: Category should be system+dev β primary use is debugging modules (dev) for context recovery (system). Using 'system' as primary. + +## Session Onboarding (context recovery) + +Efficiently recover state at session start to avoid redundant queries. + +1. **Session Review** β `session_recent(3)` to identify last active tasks and outcomes +2. **VFS Snapshot** β `list_files('')` to examine root directory for new files/config changes +3. **Procedure Retrieval** β `load_skills('current-task')` for applicable stored procedures +4. **User Preferences** β `user_list` for project-specific flags/persistent preferences + +**Workflow:** `session_recent` β `list_files` β `load_skills` β `user_list` + +## Module Debugging (rapid diagnosis) + +1. **Status Check** β `get_module_status` to see if module is loaded, modified, or has a remote URL mismatch +2. **Source Analysis** β `view_module(name)` to examine current implementation logic +3. **Live Testing** β `test_module(name)` to load edited version from `/_mods/` and verify the fix +4. **Synthesis** β compare test results with the original bug report to confirm resolution + +**Workflow:** `get_module_status` β `view_module` β `test_module` β `report`
\ No newline at end of file diff --git a/skills/memory-and-profile.md b/skills/memory-and-profile.md deleted file mode 100644 index 6605893..0000000 --- a/skills/memory-and-profile.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -name: memory-and-profile -description: How to use the user profile system, session memory, and pattern tracking for persistent context -tags: [memory, profile, session, persistence] -category: system ---- -## Steps -1. **User Profile (persists across sessions):** - - user_get(key) β read any profile field (e.g. "preferredModel", "fontSize") - - user_set(key, value) β write to profile, auto-persists to localStorage - - user_list β show all stored profile keys - - user_forget(key) β delete a profile key - - Dot notation supported: user_set knownFacts.name "Alex" - -2. **Session Memory (VFS-based daily logs):** - - session_save(summary) β save a summary of what was accomplished - - session_load(date) β read a specific day's log (format: YYYY-MM-DD) - - session_recent(count) β show last N session summaries - - session_stats β aggregate totals across all sessions - - Recent sessions auto-load into context on first message - -3. **Conversation Patterns:** - - Pattern tracking runs automatically β frequent topics surface as hints - - my-set, my-get, my-list store additional personal data - - AI conversation context persists within a session (use ai-clear to reset) - -4. **When to use:** - - At start: call session_recent(3) to see what was worked on before - - After identifying user preferences: call user_set to store them - - After complex tasks: call session_save with a brief summary
\ No newline at end of file diff --git a/skills/memory-map.md b/skills/memory-map.md deleted file mode 100644 index b8c0f83..0000000 --- a/skills/memory-map.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -name: memory-map -description: Maintain and query the persistent memory map at /memory/map.json for Agando/DarkMoto Systems. -category: system -tags: memory, persistence, context, map, agando ---- - -## Purpose -Keep a living index of projects, infrastructure, preferences, active issues, and session history so the AI never asks Agando to repeat himself. - -## File Location -- `/memory/map.json` β primary memory map -- `/memory/index.json` β session index (auto-generated) - -## Workflow - -### 1. Read Before Acting -At the start of any session or when context is unclear: -```bash -read_file("memory/map.json") -``` - -### 2. Update After Significant Work -After any task that changes status, fixes an issue, or adds knowledge: -```bash -# Read current map -read_file("memory/map.json") - -# Modify relevant section(s) -# Write back -write_file("memory/map.json", <updated_json>) -``` - -### 3. Add Session Link -Append to `recent_sessions` (keep last 10): -```json -{"date": "YYYY-MM-DD", "file": "memory/YYYY-MM-DD.json", "summary": "..."} -``` - -## Map Structure -- `projects` β WebX11, clients, personal builds, stores -- `infrastructure` β security stack, backup systems, constraints -- `preferences` β communication style, UI needs (#00ff88, 48px touch targets) -- `active_issues` β open tasks, blockers, manual steps required -- `recent_sessions` β quick links to session logs - -## Rules -- NEVER ask Agando for info already in the map. -- If info is stale or wrong, update it immediately. -- Use `session_save()` after complex tasks to populate index.json. -- Keep `active_issues` accurate β remove resolved items.
\ No newline at end of file diff --git a/skills/memory.md b/skills/memory.md new file mode 100644 index 0000000..d3b46fe --- /dev/null +++ b/skills/memory.md @@ -0,0 +1,66 @@ +--- +name: memory +description: Manage user profiles, session memory, and persistent memory map for cross-session context. +tags: [memory, profile, session, persistence, context, map] +category: system +--- + +## User Profile (localStorage β user_get/user_set) + +| Command | Purpose | +|---------|---------| +| `user_get(key)` | Read profile field (e.g. "preferredModel") | +| `user_set(key, value)` | Write to profile, auto-persists | +| `user_list` | Show all stored profile keys | +| `user_forget(key)` | Delete a profile key | + +Dot notation supported: `user_set knownFacts.name "Alex"` + +## Session Memory (VFS-based daily logs) + +| Command | Purpose | +|---------|---------| +| `session_save(summary)` | Save session summary | +| `session_load(date)` | Read day's log (YYYY-MM-DD) | +| `session_recent(count)` | Last N session summaries | +| `session_stats` | Aggregate totals | + +Recent sessions auto-load into context on first message. + +## Persistent Memory Map (/memory/map.json) + +An index of projects, preferences, issues, and session history so the AI never asks to repeat itself. + +**Location:** `/memory/map.json` β primary map; `/memory/index.json` β auto-generated session index + +**Read Before Acting:** +``` +read_file("memory/map.json") +``` + +**Update After Significant Work:** +- Read current map, modify relevant section, write back +- Append to `recent_sessions` (keep last 10) + +**Map Structure:** +- `projects` β WebX11, clients, personal builds +- `infrastructure` β security stack, backups, constraints +- `preferences` β communication style, UI needs +- `active_issues` β open tasks, blockers, manual steps +- `recent_sessions` β quick links to session logs + +**Rules:** +- NEVER ask for info already in the map +- If info is stale, update immediately +- Use `session_save()` after complex tasks +- Keep `active_issues` accurate β remove resolved items + +## Conversation Patterns +- Pattern tracking runs automatically β frequent topics surface as hints +- `my-set`, `my-get`, `my-list` store additional personal data +- AI conversation context persists within a session (use `ai-clear` to reset) + +## When to Use +- Session start: call `session_recent(3)`, then `read_file("memory/map.json")` +- After identifying user preferences: `user_set` to store them +- After complex tasks: `session_save` with a brief summary, update map
\ No newline at end of file diff --git a/skills/mindmap-master-guide.md b/skills/mindmap-master-guide.md deleted file mode 100644 index 83cebd2..0000000 --- a/skills/mindmap-master-guide.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: mindmap-master-guide -description: Comprehensive guide to creating, managing, and exporting brainstorming mindmaps using the mindmap terminal module. -tags: [mindmap, brainstorming, planning, organization, visualization] -category: productivity ---- -## Core Workflow - -1. **Initialization** - - `mindmap new "<topic>" -t tag1,tag2` β Creates a root node. - - Tags are optional (e.g., planning, research, dev). - - The root node is auto-assigned a color from the 7-color palette. - -2. **Expansion (Adding Nodes)** - - `mindmap add <parent-id> "<idea>" -t tag` β Adds a child node to a specific parent. - - To find the `parent-id`, use `mindmap show`. IDs are 4-character random strings (e.g., `a3f8`). - -3. **Visualization** - - `mindmap show` β Displays the full tree using Unicode box-drawing. - - `mindmap show <id>` β Displays a subtree starting from the specified node. - -4. **Refinement (Editing)** - - `mindmap rename <id> "<new text>"` β Changes the node text. - - `mindmap color <id> <color>` β Sets node color (`red`, `green`, `yellow`, `blue`, `cyan`, `magenta`, `white`). - - `mindmap tag <id> <tag>` β Assigns or updates a tag for the node. - -5. **Persistence & Storage** - - `mindmap save <name>` β Saves the current map to localStorage. - - `mindmap load <name>` β Restores a saved map. - - `mindmap list` β Lists all saved mindmaps. - - `mindmap delete <name>` β Removes a saved map from storage. - -6. **Exporting** - - `mindmap export [id]` β Generates a Markdown bullet list of the map (or specific subtree), automatically copying the result to the clipboard. - -## Use Cases -- **Brainstorming:** Map out feature sets, project architectures, or conceptual ideas. -- **Planning:** Decompose complex tasks into manageable sub-tasks. -- **Organization:** Structure research findings or user requirements. -- **Trigger Phrases:** Use when the user mentions "brainstorm", "diagram", "organize thoughts", "plan", or "map out". diff --git a/skills/mindmap-user-guide.md b/skills/mindmap-user-guide.md deleted file mode 100644 index 7bee410..0000000 --- a/skills/mindmap-user-guide.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: mindmap-user-guide -description: How to create, view, and manage brainstorming mindmaps using the mindmap terminal module -tags: [mindmap, brainstorming, organization, planning] -category: productivity ---- -## Steps - -1. **Create a new mindmap:** - - `mindmap new "<topic>" -t tag1,tag2` β creates a root node - - Tags are optional (e.g. planning, research, dev) - - Root gets auto-assigned a color - -2. **Add child nodes:** - - `mindmap add <parent-id> "<idea>" -t tag` β add a child - - Get the parent-id from `mindmap show` - - IDs are 4-char random strings (e.g. a3f8, x7k2) - -3. **View the mindmap:** - - `mindmap show` β full tree with Unicode box-drawing - - `mindmap show <id>` β subtree starting at that node - -4. **Edit nodes:** - - `mindmap rename <id> "<new text>"` β change text - - `mindmap color <id> <color>` β set color (red/green/yellow/blue/cyan/magenta/white) - - `mindmap tag <id> <tag>` β add a tag - -5. **Persistence:** - - `mindmap save <name>` β save to localStorage - - `mindmap load <name>` β restore - - `mindmap list` β show saved mindmaps - - `mindmap delete <name>` β remove saved - -6. **Export:** - - `mindmap export [id]` β Markdown bullet list output - -## When to use -- User wants to brainstorm, organize ideas, plan features -- User says "map out", "diagram", "brainstorm", "organize thoughts" -- Visualizing project structure or task decomposition
\ No newline at end of file diff --git a/skills/mindmap-workflow.md b/skills/mindmap-workflow.md deleted file mode 100644 index f05c237..0000000 --- a/skills/mindmap-workflow.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: mindmap-workflow -description: How to create, view, edit, and manage brainstorming mindmaps -tags: [mindmap, brainstorming, planning, organization] -category: productivity ---- -## Steps -1. **Create a new mindmap:** - - mindmap new "<topic>" -t tag1,tag2 β creates a root node - - Tags are optional (e.g. planning, research, dev) - - Root gets auto-assigned a color from 7-color palette - -2. **Add child nodes:** - - mindmap add <parent-id> "<idea>" -t tag β add a child - - Get the parent-id from mindmap show - - IDs are 4-char random strings (e.g. a3f8, x7k2) - -3. **View:** - - mindmap show β full tree with Unicode box-drawing - - mindmap show <id> β subtree starting at that node - -4. **Edit nodes:** - - mindmap rename <id> "<new text>" β change text - - mindmap color <id> <color> β set color (red/green/yellow/blue/cyan/magenta/white) - - mindmap tag <id> <tag> β add a tag - -5. **Persistence:** - - mindmap save <name> β save to localStorage - - mindmap load <name> β restore - - mindmap list β show saved mindmaps - - mindmap delete <name> β remove saved - -6. **Export:** - - mindmap export [id] β Markdown bullet list output, auto-copies to clipboard - -7. **When to use:** - - Map out project structure, brainstorm features, organize ideas - - Break down complex tasks into subtrees - - User says "brainstorm", "diagram", "organize thoughts", "plan"
\ No newline at end of file diff --git a/skills/mindmap.md b/skills/mindmap.md new file mode 100644 index 0000000..e1cbb7b --- /dev/null +++ b/skills/mindmap.md @@ -0,0 +1,50 @@ +--- +name: mindmap +description: Create, manage, visualize, and persist brainstorming mindmaps using the mindmap terminal module. +tags: [mindmap, brainstorming, planning, organization, visualization] +category: productivity +--- + +## Core Workflow + +1. **Create a new mindmap** + - `mindmap new "<topic>" -t tag1,tag2` β creates a root node + - Tags are optional (e.g. planning, research, dev) + - Root gets auto-assigned a color from 7-color palette + +2. **Add child nodes** + - `mindmap add <parent-id> "<idea>" -t tag` β add a child + - Get parent-id from `mindmap show` β IDs are 4-char random strings + +3. **View** + - `mindmap show` β full tree with Unicode box-drawing + - `mindmap show <id>` β subtree starting at that node + - `mindmap svg [name]` β render as inline SVG with colored rects + bezier curves. Optional name saves to /mindmaps/<name>.svg for `preview` + +4. **Visualize with Mermaid** + - Export your mindmap data and render in `webx11_mindmap.html` for a full Mermaid flowchart + - The mermaid library is at `mermaid.min.js` in the newOS4 directory + +5. **Edit nodes** + - `mindmap rename <id> "<new text>"` β change text + - `mindmap color <id> <color>` β set color (red/green/yellow/blue/cyan/magenta/white) + - `mindmap tag <id> <tag>` β assign/update tag + +6. **Persistence** + - `mindmap save <name>` β save to VFS (stores in /mindmaps/ as JSON) + - `mindmap load <name>` β restore + - `mindmap list` β show saved mindmaps + - `mindmap delete <name>` β remove saved mindmap file + +7. **Export** + - `mindmap export [id]` β Markdown bullet list output, auto-copies to clipboard + - `mindmap svg <name>` β saves SVG to /mindmaps/<name>.svg, viewable with `preview` + +8. **Neural VFS integration** + - After running `nvfs-index`, mindmap skill files are indexed as `concept://mindmap` + - Saved mindmaps in /mindmaps/ are discoverable via concept search + +## When to Use +- Brainstorming feature sets, project architecture, or ideas +- Decomposing complex tasks into manageable subtrees +- User says "brainstorm", "diagram", "organize thoughts", "plan", "map out"
\ No newline at end of file diff --git a/skills/neural-vfs-indexer.md b/skills/neural-vfs-indexer.md new file mode 100644 index 0000000..0030db7 --- /dev/null +++ b/skills/neural-vfs-indexer.md @@ -0,0 +1,21 @@ +--- +name: neural-vfs-indexer +description: Scans the VFS to create semantic mappings between concepts and file paths. +tags: [neural-vfs, semantic, indexing, newos4] +category: system +--- + +# Neural VFS Indexer + +## Purpose +To implement the "Neural VFS" pillar of newOS4 by creating a semantic layer over the hierarchical filesystem. + +## Workflow +1. **Discovery**: List all files in the VFS using `list_files`. +2. **Analysis**: Read the contents of each file. +3. **Keyword Extraction**: Identify primary themes, technical terms, and "concepts" within the file. +4. **Indexing**: Create a mapping file in `.semantic_index/` named after the concept (e.g., `.semantic_index/cognitive-kernel.map`). +5. **Mapping**: The mapping file should contain the path to the source file and a brief semantic summary. + +## Usage +Run this skill when new documentation is added or when the architectural structure changes. diff --git a/skills/project-profile-manager.md b/skills/project-profile-manager.md index 03eead8..7b8c6cf 100644 --- a/skills/project-profile-manager.md +++ b/skills/project-profile-manager.md @@ -2,6 +2,7 @@ name: project-profile-manager description: Handles saving and loading of project-specific context bundles. tags: [context, memory, workspace] +category: system --- # Project Profile Manager diff --git a/skills/task-manager.md b/skills/task-manager.md index 74c3da1..f4a0542 100644 --- a/skills/task-manager.md +++ b/skills/task-manager.md @@ -2,6 +2,7 @@ name: task-manager description: A systematic approach to managing tasks using a JSON-based tracking system in the VFS. tags: productivity, management, organization +category: productivity --- # Task Management Workflow diff --git a/skills/webdav-operations.md b/skills/webdav-operations.md deleted file mode 100644 index 098449c..0000000 --- a/skills/webdav-operations.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -name: webdav-operations -description: How to use WebDAV cloud storage for backup, file sync, and remote file access -tags: [webdav, cloud, backup, sync, storage] -category: system ---- -## Steps -1. **Configuration:** - - webdav-config β configure WebDAV endpoint URL and credentials - - Connection auto-tested on config; webdav-status shows connection health - - Uses per-user token stored in .token file on the server side - -2. **File operations:** - - webdav-ls [path] β list remote directory contents - - webdav-push <local-path> <remote-path> β upload file to WebDAV - - webdav-pull <remote-path> [local-path] β download file from WebDAV - - webdav-explorer β GUI file browser for WebDAV - - webdav-browser β CLI file browser for WebDAV - -3. **Backup & Restore:** - - webdav-backup β push full VFS snapshot to WebDAV (creates /backups/newos4-<date>.json) - - webdav-backup-list β list all remote backup snapshots - - webdav-restore <filename> β restore VFS from a remote backup snapshot - -4. **Status & Diagnostics:** - - webdav-status β connection status, last sync, space information - - If uploads fail: check webdav-config, ensure .token file is valid - - WebDAV runs on the same server (nginx with WebDAV module), no external dependency - -5. **When to use:** - - Before factory-reset: webdav-backup to store VFS remotely - - Cross-browser: webdav-push/pull to move files between instances - - User says "cloud backup" or "remote save" β webdav-backup
\ No newline at end of file diff --git a/skills/webdav-sync.md b/skills/webdav-sync.md deleted file mode 100644 index ead86dd..0000000 --- a/skills/webdav-sync.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -name: webdav-sync -description: Sync, backup, and restore VFS via WebDAV in WebX11. CRITICAL: Only use verified commands. -category: system -tags: [webdav, sync, backup, cloud, vfs] ---- - -# WebDAV Sync Workflow - -## β οΈ CRITICAL RULE: VERIFY BEFORE EXECUTING -**ALWAYS run `help <command>` first.** -**If `help <command>` returns nothing, the command does NOT exist.** -**Never invent commands β terminal crashes.** - -## 1. Install & Configure -- `webdav-config` β configure WebDAV connection -- `webdav-status` β verify connection - -## 2. Verified Commands ONLY -| Command | Verify With | Purpose | -|---------|-------------|---------| -| `webdav-ls` | `help webdav-ls` | List files on server | -| `webdav-backup` | `help webdav-backup` | Backup VFS to WebDAV | -| `webdav-backup-list` | `help webdav-backup-list` | List backups | -| `webdav-restore` | `help webdav-restore` | Restore from backup | -| `webdav-push` | `help webdav-push` | Push VFS to server | -| `webdav-pull` | `help webdav-pull` | Pull from server | - -## 3. What Does NOT Exist -There is **NO CLI delete** for WebDAV files. These will CRASH: -- `webdav-browser` β -- `webdav-explorer` β -- `webdav-delete` β -- `webdav-rm` β - -## 4. Deleting Files -Since `curl` is also blocked, there is **no automated way** to delete WebDAV backups from the terminal. Use the WebDAV web interface outside the terminal. - -## 5. For VFS Files (local filesystem) -Use `rm <file>` β this is a real command. Verify: `help rm`
\ No newline at end of file diff --git a/skills/webdav.md b/skills/webdav.md new file mode 100644 index 0000000..c8b2dfc --- /dev/null +++ b/skills/webdav.md @@ -0,0 +1,44 @@ +--- +name: webdav +description: Configure, sync, backup, and restore VFS via WebDAV cloud storage. +tags: [webdav, cloud, backup, sync, storage, vfs] +category: system +--- + +## CRITICAL: VERIFY BEFORE EXECUTING +**ALWAYS run `help <command>` first.** If `help <command>` returns nothing, the command does NOT exist. Never invent commands β terminal crashes. + +## 1. Configure & Status +- `webdav-config` β configure WebDAV endpoint URL and credentials +- `webdav-status` β verify connection health, last sync, space info + +## 2. File Operations + +| Command | Purpose | +|---------|---------| +| `webdav-ls [path]` | List remote directory contents | +| `webdav-push <local> <remote>` | Upload file to WebDAV | +| `webdav-pull <remote> [local]` | Download file from WebDAV | + +## 3. Backup & Restore +- `webdav-backup` β push full VFS snapshot to WebDAV (`/backups/newos4-<date>.json`) +- `webdav-backup-list` β list all remote backup snapshots +- `webdav-restore <filename>` β restore VFS from remote backup + +## 4. What Does NOT Exist +These will crash the terminal: +- `webdav-browser` β +- `webdav-explorer` β +- `webdav-delete` β +- `webdav-rm` β + +Since `curl` is also blocked, no automated way to delete WebDAV backups from the terminal β use the WebDAV web interface outside. + +## 5. When to Use +- Before factory-reset: `webdav-backup` to store VFS remotely +- Cross-browser: `webdav-push`/`webdav-pull` to move files +- User says "cloud backup" or "remote save" + +## 6. Connection Details +- Uses per-user token stored in `.token` file on the server +- WebDAV runs on same server (nginx with WebDAV module) β no external dependency
\ No newline at end of file diff --git a/skills/webx11-dev-cycle.md b/skills/webx11-dev-cycle.md index 66fefde..934b65b 100644 --- a/skills/webx11-dev-cycle.md +++ b/skills/webx11-dev-cycle.md @@ -9,4 +9,5 @@ steps: 5. Document: Save the final implementation and a a changelog in /webx11_dev/logs/. 6. Persist: Save the session using session_save. tags: development,workflow,webx11 +category: dev --- |