diff options
| author | Agando <roduccomm@gmail.com> | 2026-06-09 06:00:43 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-06-09 06:00:43 +0200 |
| commit | 9f60030e39feecc76f11671a4b9d82303c83670c (patch) | |
| tree | cd4d35985f98aef0f4e688e4bcc283a476c8cd3b /modules/core | |
| parent | b562e1491513163921593985f3542d4ee8ae0e75 (diff) | |
auto: 2026-06-09_06:00 changes
Diffstat (limited to 'modules/core')
| -rw-r--r-- | modules/core/module-aiassist.js | 133 | ||||
| -rw-r--r-- | modules/core/module-fs.js | 6 | ||||
| -rw-r--r-- | modules/core/module-loader.js | 5 | ||||
| -rw-r--r-- | modules/core/module-neural-vfs.js | 5 | ||||
| -rw-r--r-- | modules/core/module-system.js | 92 | ||||
| -rw-r--r-- | modules/core/terminal.js | 37 | ||||
| -rw-r--r-- | modules/core/virtual-fs.js | 7 |
7 files changed, 140 insertions, 145 deletions
diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index 7f99386..ecd4637 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -60,114 +60,37 @@ } } } catch (e) {} - const CR = String.fromCharCode(10); - const optNote = CR + CR + '== TOOL EXECUTION RULES (STRICT) ==' + CR + 'STRICT RULE 1: NEVER describe what the filesystem looks like from your training data. ALWAYS call list_files() or read_file() first, then report the ACTUAL result.' + CR + 'STRICT RULE 2: If you return text without calling any tool, you have failed. Use tools for every factual question.' + CR + 'STRICT RULE 3: A response like "/bin/, /etc/, /home/" without calling list_files is ILLEGAL. Call the tool.' + CR + 'STRICT RULE 4: When calling a tool, base your answer ENTIRELY on the tool result. If result is empty, say "empty".' + CR + CR; - return `Current date: ${dateStr}\nCurrent time: ${timeStr}\n${nvfsNote}\n\nYou are WebX11AI, the AI assistant embedded in the WebX11 browser terminal. You have direct access to read/write files, search the web, install packages, edit modules, and run terminal commands — all via tool calls. Use tools proactively. Keep responses concise.${optNote}== TOOL REFERENCE == -You have these tools available. Use them WITHOUT asking permission unless the tool description says (DESTRUCTIVE): + return `Current date: ${dateStr} +Current time: ${timeStr}${nvfsNote} -FILESYSTEM: -- list_files(path?) — List files in VFS directory (omit for current dir) -- read_file(path) — Read file content (truncated past 8000 chars) -- write_file(path, content) — Write to file (DESTRUCTIVE — confirm with user first) -- make_directory(path) — Create a directory (DESTRUCTIVE — confirm first) -- delete_file(path) — Delete file (DESTRUCTIVE — confirm first) -- get_current_dir — Show current working directory +You are WebX11AI — embedded in the WebX11 newOS4 terminal. 3-layer system: VFS → Modules → AI. You can edit your own modules via edit_module/test_module/reload_module. -SYSTEM: -- get_status — Show filesystem, modules, Ollama, memory status -- get_help — List all available terminal commands -- run_command(command) — Execute any terminal command and capture output -- font-size <8-32> — Change terminal font size (persists in localStorage) +=== WORKFLOW === +1. Tool → Observe → Answer. Don't re-verify what a tool just told you. +2. find_files("about X") → nvfs_resolve(X) FIRST. NVFS is built-in core, never WPM. +3. load_skills("anti-loop-protocol") BEFORE tool #4 to prevent loops. +4. If editing a module: load_skills("module-editing-workflow") FIRST. +5. run_command may be blocked by security-level/guardrails — read the output. +6. Concise. Bullets. If a tool fails, try another. -SEARCH: -- web_search(query) — Search the web via proxy API (SearXNG + DDG fallback, results with title/url/snippet) -- web_fetch(url) — Fetch and extract readable content from a URL via proxy API (returns title + clean text + word count) - -PACKAGES: -- wpm_install(package) — Install WPM package by name (e.g. "widget", "calc") -- wpm_search(keyword) — Search available WPM packages - -SKILLS (PERSISTENT PROCEDURAL MEMORY): -- list_skills(category?) — Browse available skills, optionally filtered by category -- load_skills(query) — Search skills relevant to current task. Call at START of every task. -- create_skill(name, description, content, tags, category) — Save a new stored procedure. Call after completing complex multi-step tasks (3+ tool calls). -- patch_skill(name, content) — Update an existing skill when the approach changes - -FLOATING UI (PERSISTENT UI ELEMENTS): Use 'run_command' tool with these terminal commands: -- 'floating-add btn <id> <label> <command>' — Create a floating button that runs a terminal command when clicked -- 'floating-add menu <id> <label> <btn1>,<btn2>...' — Create a collapsible floating menu (buttons: label:command pairs) -- 'floating-add panel <id> <title> <content>' — Create a floating text/status panel -- 'floating-remove <id>' — Remove a floating element by ID -- 'floating-toggle <id>' — Show/hide a floating element without deleting -- 'floating-list' — List all floating elements -- 'floating-clear' — Remove all floating elements -- NOTE: These are terminal commands, run via 'run_command'. Use SPACES not hyphens between subcommands. -MODULE SELF-IMPROVEMENT: -- view_module(name) — View source code of any loaded module -- edit_module(name) — Copy module into editor. Opens editor for modifications. -- test_module(name) — Load edited module from /_mods/ for live testing -- reload_module(name) — Discard edits and reload from original URL -- list_modified_modules — List modules with local edits pending -- get_module_status — Full status of all modules (loaded, modified, URLs) - -== SKILLS WORKFLOW == -1. At the START of every task, call load_skills(query) to check if a stored procedure exists -2. Follow the skill's steps. If they're wrong, call patch_skill to fix them. -3. After a complex multi-step task (3+ tool calls), call create_skill to save the approach -4. Skills persist in /skills/ as markdown files with YAML frontmatter - -== MEMORY SYSTEM == -- I maintain a conversation context (this.context) that persists across messages in this session -- The last ${this.maxContext} exchanges are remembered -- Type "ai-clear" to reset conversation memory -- Type "ai-context" to see what I remember -- Type "ai-model" to see/switch models -- Type "ai-stop" to cancel a running AI request -- Smart context profiles (set via "context <name>") adjust my temperature and system prompt style -- Saved prompts (via "prompt", "prompt-save") let you reuse template with {variable} substitution - -== USER PROFILE == -- Use user_get, user_set to read/write persistent user preferences across sessions -- user_set dot-notation supported: user_set knownFacts.name "Alex" -- Profile auto-stores known facts (name, project, preferences) -- Use session_save after complex tasks to log what was done -- Use session_load to review past sessions -- Use session_recent at start of session to remember what was worked on before - -== SELF-IMPROVEMENT WORKFLOW == -1. User asks for module changes → call get_module_status to list modules -2. Call view_module(name) to read the module source -3. Call edit_module(name) to copy source into editor for modification -4. After editing, call test_module(name) to load and test the edit -5. If it works, the user keeps it. If not, call reload_module(name). - -== AUTO-IMPROVEMENT (SYSTEM-DRIVEN) == -- If I encounter the same tool error 3+ times, a workaround skill is created automatically -- After complex tasks (3+ tool calls), I run health checks and suggest improvements -- I track conversation patterns and surface frequent topics -- Every 20 messages, skills are audited for staleness -- Use check_updates to verify module source URLs are reachable - -== RESPONSE STYLE == -- Be concise. Use bullet points for lists. -- When using tools, explain what you're doing briefly. -- If a tool fails, try an alternative approach. -- For web research tasks: search first, then analyze the results, then present findings. -|- When the user says "update" or "improve" without specifics, use get_status + get_help to understand the current state first. - -== REACT PROTOCOL == -For every task, follow this cycle: -1. **REASON** — Think about what you need next. What information is missing? -2. **ACT** — Call ONE tool at a time (unless multiple independent lookups are needed). -3. **OBSERVE** — Study the tool result carefully. Did it succeed? Is the data useful? -4. **DECIDE** — Do you have enough to answer? If not, go back to step 1. - -RULES: -- Call tools in sequence when the second depends on the first result -- Independent lookups (e.g. reading two unrelated files) can run in parallel -- If a tool returns an error, try a different approach before giving up -- After 6 tool turns, start synthesizing a final answer -- Always provide a complete, helpful final answer — don't leave the user hanging`; +=== CAPABILITY MAP === +[FS] list_files, read_file, write_file, make_directory, delete_file, get_current_dir +[NVFS] nvfs_resolve(concept), run_command: nvfs-status, nvfs-index, nvfs-tree. Skills: vfs-content-search, neural-vfs-management. +[MODULES] view_module, edit_module, test_module, reload_module, list_modified_modules, get_module_status. CORE modules (never WPM): NVFS, Floating, Config, Vault, Sandbox, Orchestrator, Memory-Graph, World-Model, Predictor, Neural-VFS. +[WPM] wpm_install, wpm_search, list_available_modules +[SEARCH] web_search, web_fetch +[AGENTS] delegate_task, list_agents, spawn_agent. A2A: a2a-send, a2a-list. Leases: lease-create, lease-list, lease-revoke. +[SANDBOX] run_command: sandbox-status, sandbox-run, sandbox-config +[CONFIG] run_command: config, config-set, ai-config +[SKILLS] load_skills, create_skill, patch_skill, list_skills +[PROFILE/SESSION] user_get/set/list/forget, session_save/load/recent/stats/terminal +[SMART-CTX] smart_context_list, smart_context_set +[MINDS] create_mindmap +[SAFETY] run_command: guardrail, guardrail-add/remove, shadow, shadow-commit, shadow-rollback +[VAULT] run_command: secret-set/get/list/del, secret-setpin, secret-status +[CHECKPOINTS] run_command: checkpoint, checkpoint-list, checkpoint-del, rollback +[WEBDAV] run_command: webdav-config/ls/push/pull/backup/restore +[ALL OTHERS] cron, theme, voice, edit, diff, alias, mindmap, ll, cls, trash, gui, server, modules, ollama, context, world-model, memgraph, model, webxai, predict, predictor-config, memgraph-export, tar, untar, wget`; } getToolDefinitions() { if (!this._toolDefs) this._toolDefs = this._buildToolDefs(); diff --git a/modules/core/module-fs.js b/modules/core/module-fs.js index c2f29c4..309010d 100644 --- a/modules/core/module-fs.js +++ b/modules/core/module-fs.js @@ -1,5 +1,9 @@ class FileSystemModule { - constructor() { this.commands = {}; this.terminal = null; } + constructor() { this.commands = {}; this.commandsMeta = { + 'trash': { argType: 'file' }, 'ls-trash': { argType: 'file' }, + 'upload': { argType: 'dir' }, 'vfs-export': { argType: 'file' }, + 'vfs-import': { argType: 'file' }, 'download': { argType: 'file' }, + }; this.terminal = null; } getHelpInfo() { return { 'ls': 'ls [path] [-la] — List files and directories', diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 96fee00..9b8d892 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -13,7 +13,6 @@ const BUILTIN = [ 'module-system.js', 'module-fs.js', - 'module-modmgr.js', 'module-ollama.js', 'module-my.js', 'module-searxng.js', @@ -105,8 +104,8 @@ window.__moduleLoaderReload = reloadWithSelection; -const LATEST_VER = '2026-06-08-v4.5.22'; -const CACHE = '?v=' + LATEST_VER; + const LATEST_VER = '2026-06-08-v4.5.25'; + const CACHE = '?v=' + LATEST_VER; const stored = localStorage.getItem('webx11_cache_ver'); if (stored !== LATEST_VER) { localStorage.setItem('webx11_cache_ver', LATEST_VER); diff --git a/modules/core/module-neural-vfs.js b/modules/core/module-neural-vfs.js index e216656..59618c8 100644 --- a/modules/core/module-neural-vfs.js +++ b/modules/core/module-neural-vfs.js @@ -1,6 +1,11 @@ class NeuralVFSModule { constructor() { this.commands = {}; + this.commandsMeta = { + 'nvfs-index': { argType: 'file' }, 'nvfs-resolve': { argType: 'file' }, + 'nvfs-tree': { argType: 'file' }, 'nvfs-alias': { argType: 'file' }, + 'nvfs-sync': { argType: 'file' }, + }; this.terminal = null; this.index = {}; this.indexPath = '/.semantic_index/map.json'; diff --git a/modules/core/module-system.js b/modules/core/module-system.js index 77525c7..cfb7cc4 100644 --- a/modules/core/module-system.js +++ b/modules/core/module-system.js @@ -277,39 +277,73 @@ } return; } - // Categorize all commands - const cats = { - files: ['ls','ll','cat','put','rm','mv','cp','mkdir','rmdir','cd','pwd','find','grep','head','tail','sort','wc','touch','tree','du','upload','download','vfs-export','vfs-import','edit','diff','trash','trash-dir','ls-trash','empty-trash'], - ai: ['ai','ask','ai-clear','ai-system','ai-context','ai-allow','ai-deny','ai-ignore','ai-stop','ai-model','ai-compress','debug'], - search: ['search','s','ddg','duck','fetch','web','extract'], - tools: ['calc','cron-every','cron-list','cron-stop','cron-clear','wpm','mindmap','theme','voice','alias','unalias', - 'which','env','date','cal','yes','seq','base64','printf','cut','uniq','hostname','whoami','basename','dirname','sleep','expand','tutorial','gzip','gunzip','encrypt','decrypt','files','session-save','session-load','session-list','session-delete','session-export','session-import'], - system: ['help','clear','cls','echo','mem','status','font-size','setfont','smart-prompt','logs','preview','factory-reset','reset-vfs','export','unset','script','sh','set','test','logrotate','health-check','memory-map-export','commands','check','checkpoint','checkpoint-list','rollback','checkpoint-del'], - net: ['server','servers','server-check','server-remove','monitor'], - mods: ['modules','listmods','loadmod','removemod','load-local','loadlocal','startup-modules'], - ollama: ['ollama','ollamaconnect','ollamadisconnect','ollamamodels','ollamasetmodel','ollamasetproxy','models','model-info','model-pull','model-delete','model-run'], - skills: ['skill-list','skill-view','skill-create','skill-patch','skill-delete','skill-export','skill-import','skill-sync','skill-pack-core'], - config: ['config','config-set','config-list','config-delete','config-export','config-reset'], - webx: ['webxai','wx','webx','context','contexts','context-new','context-delete','smart-ask','prompt','prompt-save','prompt-list','prompt-delete','prompt-var','prompt-vars'], - data: ['my','my-set','my-get','my-list','my-export','my-import','my-clear','export-mods','import-mods','backup','restore','share-mod'], - ext: ['chat','chat-setapi','chat-setmodel','chat-ask','webdav-config','webdav-status','webdav-ls','webdav-push','webdav-pull','webdav-backup','webdav-restore','webdav-backup-list','webdav-explorer','webdav-browser'], - gui: ['gui','gui-button','gui-input','gui-text','gui-clear','gui-run'], - vault: ['secret-set','secret-get','secret-list','secret-del','secret-lock','secret-unlock','secret-setpin','secret-status'], - }; - const labels = { - files:'📁 Filesystem', ai:'🤖 AI', search:'🔍 Search & Web', tools:'🔧 Tools', - system:'⚙️ System', net:'📡 Network', mods:'🧩 Modules', ollama:'🦙 Ollama', - skills:'📚 Skills', config:'⚙️ Config', webx:'🌐 WebX', data:'💾 Data', - ext:'🧰 Extras', gui:'🖥️ GUI', vault:'🔒 Vault' + // Dynamically group commands by owning module + const cmdToModule = this.terminal.moduleManager.getAllCommands(); + const moduleGroups = {}; + for (const [cmd, modName] of Object.entries(cmdToModule)) { + if (!moduleGroups[modName]) moduleGroups[modName] = []; + moduleGroups[modName].push(cmd); + } + const modLabels = { + FileSystemModule: '📁 Filesystem', + WebX11AIAssistantModule: '🤖 AI', + WebXAIAliasModule: '🌐 WebX', + DuckDuckGoModule: '🔍 Search & Web', + SearXNGModule: '🔍 Search & Web', + WebFetcherModule: '🔍 Search & Web', + AliasModule: '🔧 Tools', + BusyBoxModule: '🔧 Tools', + CalcModule: '🔧 Tools', + CronModule: '🔧 Tools', + CryptoGzipModule: '🔧 Tools', + DiffModule: '🔧 Tools', + EditorModule: '🔧 Tools', + FileManagerModule: '🔧 Tools', + FinderModule: '🔧 Tools', + MindmapModule: '🔧 Tools', + ThemeModule: '🔧 Tools', + TutorialModule: '🔧 Tools', + VoiceModule: '🔧 Tools', + WpmModule: '🔧 Tools', + SystemModule: '⚙️ System', + ShellModule: '⚙️ System', + ServerMonitorModule: '📡 Network', + ModuleManagerModule: '🧩 Modules', + OllamaModule: '🦙 Ollama', + NeuralVFSModule: '🧠 Neural VFS', + SkillPackCoreModule: '📚 Skills', + ConfigManagerModule: '⚙️ Config', + ModuleIOModule: '🔌 I/O', + SandboxModule: '🏖️ Sandbox', + MyModule: '💾 Data', + WebDAVModule: '🧰 Extras', + ChatStudioModule: '🧰 Extras', + SimpleGUIModule: '🖥️ GUI', + SecretVault: '🔒 Vault', + OrchestratorModule: '🧠 Orchestrator', + PredictorModule: '🔮 Prediction', + SmartContextModule: '🧠 Context', + MemoryGraphModule: '📊 Memory', + DynamicPromptsModule: '💬 Prompts', + WorldModelModule: '🌍 World', + LeaseModule: '🔐 Leases', + AgentRegistryModule: '🤖 Agents', }; + // Merge modules with the same label + const grouped = {}; + const usedLabels = new Set(); + for (const [modName, cmds] of Object.entries(moduleGroups)) { + const label = modLabels[modName] || `🧩 ${modName.replace(/Module$/, '')}`; + if (!grouped[label]) grouped[label] = []; + grouped[label].push(...cmds); + usedLabels.add(label); + } let result = '╔══════════════════════════════════════╗\n║ 🔷 WebX11 ' + (window.NEWOS4_VERSION || 'v4.0') + ' — All Commands ║\n╚══════════════════════════════════════╝\n\n'; const total = Object.keys(helpMap).length; result += `📊 ${total} commands loaded\n\n`; - for (const [key, cmds] of Object.entries(cats)) { - const present = cmds.filter(c => helpMap[c]); - if (present.length === 0) continue; - result += labels[key] + '\n'; - present.forEach(c => { + for (const [label, cmds] of Object.entries(grouped)) { + result += label + '\n'; + cmds.forEach(c => { const desc = (helpMap[c] || c).split(' — ')[1] || ''; const short = desc.substring(0, 55); result += ` ${c.padEnd(16)}${short}\n`; diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 1fb44aa..3651713 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -896,6 +896,25 @@ .filter(e => e.name.startsWith(filterPrefix)) .map(e => e.type === 'dir' ? prefix + e.name + '/' : prefix + e.name); } + + // ── Enum autocomplete from commandsMeta ── + + _tryEnumAutocomplete(cmdName) { + this.suggestions = []; + for (const modName in this.moduleManager.modules) { + const mod = this.moduleManager.modules[modName]; + const meta = mod.commandsMeta && mod.commandsMeta[cmdName]; + if (meta && meta.argType === 'enum' && meta.enumFn && typeof mod[meta.enumFn] === 'function') { + const values = mod[meta.enumFn](); + if (Array.isArray(values) && values.length > 0) { + this.suggestions.push(...values); + return true; + } + } + } + return false; + } + showAutocomplete() { if (!this.moduleManager || !this.security) return; const input = this.inputField.value; @@ -919,8 +938,8 @@ const lowerInput = input.toLowerCase(); // Expanded command lists for autocomplete - const fileArgCommands = ['cat', 'preview', 'rm', 'rmdir', 'edit', 'view', 'cp', 'mv', 'touch', 'put', 'run', 'chmod', 'gzip', 'gunzip', 'encrypt', 'decrypt', 'download', 'webdav-backup', 'webdav-restore', 'webdav-upload', 'webdav-download', 'webdav-list']; - const dirArgCommands = ['ls', 'cd', 'mkdir', 'rmdir']; + const fileArgCommands = ['cat', 'preview', 'rm', 'rmdir', 'edit', 'view', 'cp', 'mv', 'touch', 'put', 'run', 'chmod', 'gzip', 'gunzip', 'encrypt', 'decrypt', 'download', 'webdav-backup', 'webdav-restore', 'webdav-upload', 'webdav-download', 'webdav-list', 'trash', 'ls-trash', 'upload', 'vfs-export', 'vfs-import', 'files', 'preview', 'skill-list', 'skill-view', 'skill-create', 'skill-patch', 'skill-delete', 'skill-sync', 'webdav-ls', 'webdav-push', 'webdav-pull', 'webdav-rm', 'webdav-mkdir', 'webdav-rename', 'webdav-move', 'webdav-config', 'nvfs-index', 'nvfs-resolve', 'nvfs-tree', 'nvfs-alias', 'nvfs-sync']; + const dirArgCommands = ['ls', 'cd', 'mkdir', 'rmdir', 'upload', 'webdav-ls', 'webdav-mkdir', 'vfs-export', 'vfs-import', 'skill-list', 'skill-create']; const sessionArgCommands = ['session-load', 'session-delete', 'session-export', 'session-save', 'session-list', 'session-import']; const pathArgCommands = ['cat', 'preview', 'rm', 'edit', 'view', 'cp', 'mv', 'touch', 'put', 'run', 'chmod', 'gzip', 'gunzip', 'encrypt', 'decrypt', 'download', 'webdav-backup', 'webdav-restore', 'webdav-upload', 'webdav-download', 'webdav-list', 'ls', 'cd', 'mkdir', 'rmdir', 'cat', 'preview']; @@ -954,9 +973,11 @@ this._isCdAutocomplete = true; } else if (fileArgCommands.includes(cmdPart) || extFileCmds.has(cmdPart)) { this.suggestions = this._getPathSuggestions(partialTrimmed, 'file'); + } else if (this._tryEnumAutocomplete(cmdPart)) { + this.suggestions = this.suggestions.filter(s => s.startsWith(partialTrimmed)); } else { - this.hideAutocomplete(); - return; + // Fallback: show files anyway + this.suggestions = this._getPathSuggestions(partialTrimmed, 'file'); } this._autocompletePrefix = cmdPart + ' '; @@ -977,9 +998,11 @@ this._isCdAutocomplete = true; } else if (fileArgCommands.includes(cmdPart) || extFileCmds.has(cmdPart)) { this.suggestions = this._getPathSuggestions('', 'file'); + } else if (this._tryEnumAutocomplete(cmdPart)) { + // suggestions already populated } else { - this.hideAutocomplete(); - return; + // Fallback: show files + this.suggestions = this._getPathSuggestions('', 'file'); } this._autocompletePrefix = cmdPart + ' '; if (this.suggestions.length > 0) { @@ -2048,7 +2071,7 @@ const foundation = ['virtual-fs.js','module-manager.js','ollama-manager.js','terminal.js']; const builtin = [ - 'module-system.js','module-fs.js','module-modmgr.js','module-ollama.js', + 'module-system.js','module-fs.js','module-ollama.js', 'module-my.js','module-searxng.js','module-servermon.js','module-ollamamodels.js', 'module-config.js','module-simplegui.js','module-io.js','module-dynamicprompts.js', 'module-aiassist.js','module-aiasm.js','module-smartctx.js','module-duckduckgo.js', diff --git a/modules/core/virtual-fs.js b/modules/core/virtual-fs.js index cb8020a..f6e2826 100644 --- a/modules/core/virtual-fs.js +++ b/modules/core/virtual-fs.js @@ -545,6 +545,13 @@ class VirtualFileSystem { mkdir(path) { return this.mkdirRecursive(path); } list(path) { return this.ls(path); } dir(path) { return this.ls(path); } + reset() { + this.root = { type: 'dir', content: {} }; + this.currentPath = []; + // Wipe all localStorage keys + ['webx11_filesystem', 'webx11_filesystem_v2'].forEach(k => localStorage.removeItem(k)); + return true; + } } // Also expose for module system |