diff options
| author | Agando <roduccomm@gmail.com> | 2026-06-23 06:00:45 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-06-23 06:00:45 +0200 |
| commit | e9b75cd3a801689f57bc8a013f14c058e57e3b46 (patch) | |
| tree | a40a2b9ab142e4f3432d4686f52d177535b51d74 | |
| parent | 6f6161562c5f1028256f3163083b665719741646 (diff) | |
auto: 2026-06-23_06:00 changes
26 files changed, 459 insertions, 100 deletions
@@ -1112,30 +1112,56 @@ <!-- Skills Manager Modal --> <div id="skills-manager" class="modal-overlay"> - <div class="modal-content" style="max-width: 700px; max-height: 85vh;"> + <div class="modal-content" style="max-width: 750px; max-height: 90vh;"> <div class="modal-header"> <span>๐ Skills Manager</span> <span style="cursor:pointer" onclick="webx11.closeSkillsManager()">โ</span> </div> - <div class="modal-body" style="display:flex; flex-direction:column; gap:10px;"> - <div style="flex-shrink:0;"> - <h4 style="color: var(--info-color); margin-bottom: 8px;">Installed Skills</h4> - <div id="skills-list" style="max-height:200px;overflow-y:auto;"></div> + <div class="modal-body" style="display:flex; flex-direction:column; gap:8px;"> + <!-- Stats header --> + <div id="skills-stats" style="display:flex; gap:12px; flex-wrap:wrap; font-size:0.85em; color:var(--text-muted); padding-bottom:6px; border-bottom:1px solid var(--border-color);"></div> + <!-- Search + action bar --> + <div style="display:flex; gap:6px; align-items:center; flex-shrink:0;"> + <input type="text" id="skills-search-input" class="module-url-input" placeholder="๐ Search skills..." style="flex:1;" oninput="webx11.refreshSkillsList()"> + <button class="btn" onclick="webx11.exportAllSkillsUI()" style="padding:4px 10px; font-size:0.8em">๐ค Export All</button> + <button class="btn" onclick="document.getElementById('skills-import-input').click()" style="padding:4px 10px; font-size:0.8em">๐ฅ Import</button> + <input type="file" id="skills-import-input" accept=".json" style="display:none" onchange="webx11.importSkillsUI(event)"> + <button class="btn" onclick="webx11.syncSkillsToWebdavUI()" style="padding:4px 10px; font-size:0.8em">โ๏ธ Sync</button> </div> - <div id="skill-preview" style="display:none; flex-shrink:0; background:var(--bg-tertiary); border:1px solid var(--border-color); border-radius:4px; padding:10px; max-height:250px; overflow-y:auto; white-space:pre-wrap; font-family:var(--font-primary); font-size:0.85em; color:var(--text-color);"> + <!-- Skills list with category groups --> + <div id="skills-list" style="max-height:300px;overflow-y:auto; flex-shrink:0;"></div> + <!-- Preview (collapsible) --> + <div id="skill-preview" style="display:none; flex-shrink:0; background:var(--bg-tertiary); border:1px solid var(--border-color); border-radius:4px; padding:10px; overflow-y:auto; white-space:pre-wrap; font-family:var(--font-primary); font-size:0.85em; color:var(--text-color);"> <div style="display:flex; justify-content:space-between; margin-bottom:6px;"> <span id="skill-preview-title" style="color:var(--success-color); font-weight:bold;"></span> - <span style="cursor:pointer; color:var(--text-muted); font-size:1.2em;" onclick="webx11.closeSkillPreview()">โ</span> + <div style="display:flex; gap:6px;"> + <button class="btn" id="skill-preview-expand-btn" onclick="webx11.toggleSkillPreviewSize()" style="padding:2px 6px; font-size:0.75em">โถ Expand</button> + <span style="cursor:pointer; color:var(--text-muted); font-size:1.2em;" onclick="webx11.closeSkillPreview()">โ</span> + </div> </div> <div id="skill-preview-content"></div> </div> - <div style="flex-shrink:0;"> - <h4 style="color: var(--info-color); margin-bottom: 8px;">Create New Skill</h4> - <input type="text" id="skill-name-input" class="module-url-input" placeholder="Skill name (e.g. web-scrape-and-summarize)"> - <input type="text" id="skill-desc-input" class="module-url-input" style="margin-top:6px" placeholder="One-line description"> - <input type="text" id="skill-tags-input" class="module-url-input" style="margin-top:6px" placeholder="Tags (comma-separated, e.g. web,research)"> - <textarea id="skill-content-input" class="module-url-input" style="margin-top:6px; height:100px; resize:vertical; font-family:var(--font-primary)" placeholder="Markdown skill content (optional โ will use template)"></textarea> - <button class="btn" onclick="webx11.createSkillFromUI()" style="width:100%; margin-top:6px; border-color:var(--success-color);color:var(--success-color)">Create Skill</button> + <!-- Create form --> + <div style="flex-shrink:0; border-top:1px solid var(--border-color); padding-top:8px;"> + <h4 style="color: var(--info-color); margin-bottom: 6px;">Create New Skill</h4> + <div style="display:flex; gap:6px; flex-wrap:wrap;"> + <input type="text" id="skill-name-input" class="module-url-input" placeholder="Name (kebab-case)" style="flex:2; min-width:140px;"> + <input type="text" id="skill-desc-input" class="module-url-input" placeholder="Description" style="flex:3; min-width:180px;"> + <select id="skill-category-input" class="module-url-input" style="flex:1; min-width:100px;"> + <option value="general">general</option> + <option value="system">system</option> + <option value="research">research</option> + <option value="dev">dev</option> + <option value="productivity">productivity</option> + <option value="ui">ui</option> + <option value="security">security</option> + </select> + </div> + <div style="display:flex; gap:6px; margin-top:6px;"> + <input type="text" id="skill-tags-input" class="module-url-input" placeholder="Tags (comma-separated)" style="flex:1;"> + <button class="btn" onclick="webx11.createSkillFromUI()" style="border-color:var(--success-color);color:var(--success-color); flex-shrink:0;">Create</button> + </div> + <textarea id="skill-content-input" class="module-url-input" style="margin-top:6px; height:80px; resize:vertical; font-family:var(--font-primary)" placeholder="Markdown content (optional โ will use template)"></textarea> </div> </div> <div class="modal-footer"> @@ -1278,7 +1304,7 @@ if (body && !body.children.length) { var mods = [ ['Foundation (always loaded)', ['virtual-fs.js','module-manager.js','ollama-manager.js','terminal.js'], true], - ['Built-in modules', ['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','module-fetcher.js','module-skills.js','module-chatstudio.js'], false], + ['Built-in modules', ['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','module-fetcher.js','module-chatstudio.js'], false], ['Extensions', ['calc.js','voice.js','cron.js','theme.js','wpm.js','mindmap.js','webdav.js','skill-pack-core.js','editor.js','diff.js','alias.js','finder.js','filemgr.js','cryptogzip.js','tutorial.js','shell.js','busybox.js','floating.js','console.js'], false] ]; var isSel = function(name) { return true; }; // default: all selected @@ -1317,11 +1343,13 @@ <!-- v4.5.63: A2A scratchpad fixes + agent-register arg fix --> <script src="modules/core/core-bundle.js?v=2026-06-18-v4.5.79"></script> -<script src="modules/ext/critical-ext-bundle.js?v=2026-06-18-v4.5.79"></script> <!-- Async dependency-ordered module loader now only initializes terminal and loads optional ext modules --> <script src="modules/core/module-loader.js?v=2026-06-18-v4.5.79"></script> + <!-- Critical ext bundle loads AFTER webx11 exists so registerModule calls work --> +<script src="modules/ext/critical-ext-bundle.js?v=2026-06-18-v4.5.79"></script> + <script> // โโโ ONE TRUE VERSION SOURCE โโโ // Reads from module-loader.js src attribute (single source of truth) diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js index 0f13438..175df87 100644 --- a/modules/core/core-bundle.js +++ b/modules/core/core-bundle.js @@ -4183,32 +4183,69 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm refreshSkillsList() { const list = document.getElementById('skills-list'); list.innerHTML = ''; + const statsEl = document.getElementById('skills-stats'); const fs = this.fs; fs.mkdirRecursive('/skills'); const index = fs.fsReadJSON('/skills/index.json') || {}; const names = Object.keys(index); - if (names.length === 0) { - list.innerHTML = '<div style="padding:20px; text-align:center; color:#666">No skills yet. Create one below!</div>'; + // Search filter + const query = (document.getElementById('skills-search-input')?.value || '').toLowerCase().trim(); + let filtered = names; + if (query) { + filtered = names.filter(n => { + const s = index[n]; + return n.includes(query) || (s.description || '').toLowerCase().includes(query) || (s.tags || []).some(t => t.toLowerCase().includes(query)) || (s.category || '').toLowerCase().includes(query); + }); + } + // Stats + if (statsEl) { + const cats = new Set(Object.values(index).map(s => s.category || 'general')); + statsEl.innerHTML = `<span>๐ ${names.length} skills</span><span>๐ ${cats.size} categories</span>${query ? `<span>๐ ${filtered.length} match '${query}'</span>` : ''}`; + } + if (filtered.length === 0) { + list.innerHTML = '<div style="padding:20px; text-align:center; color:#666">' + (query ? 'No skills match your search.' : 'No skills yet. Create one below!') + '</div>'; return; } - names.forEach(name => { + // Group by category + const groups = {}; + for (const name of filtered) { const s = index[name]; - const tags = (s.tags || []).join(', '); - const div = document.createElement('div'); - div.className = 'module-item'; - div.innerHTML = ` - <div> - <strong style="color:var(--success-color)">${name}</strong> - <div style="font-size:0.85em; color:#aaa">${s.description || ''}</div> - <div style="font-size:0.75em; color:#666">${s.category || 'general'}${tags ? ' ยท ' + tags : ''}</div> - </div> - <div style="display:flex;gap:4px"> - <button class="btn" onclick="webx11.viewSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">๐</button> - <button class="btn btn-danger" onclick="webx11.deleteSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ</button> - </div> - `; - list.appendChild(div); - }); + const cat = s.category || 'general'; + if (!groups[cat]) groups[cat] = []; + groups[cat].push(name); + } + const catOrder = Object.keys(groups).sort(); + for (const cat of catOrder) { + const section = document.createElement('div'); + section.style.marginBottom = '6px'; + const header = document.createElement('div'); + header.style.cssText = 'font-size:0.8em; font-weight:600; color:var(--info-color); padding:4px 0; cursor:pointer; display:flex; align-items:center; gap:4px;'; + header.textContent = '๐ ' + cat + ' (' + groups[cat].length + ')'; + header.onclick = () => { const body = header.nextElementSibling; if (body) body.style.display = body.style.display === 'none' ? '' : 'none'; }; + section.appendChild(header); + const body = document.createElement('div'); + for (const name of groups[cat]) { + const s = index[name]; + const tags = (s.tags || []).join(', '); + const div = document.createElement('div'); + div.className = 'module-item'; + div.innerHTML = ` + <div> + <strong style="color:var(--success-color)">${name}</strong> + <div style="font-size:0.85em; color:#aaa">${s.description || ''}</div> + <div style="font-size:0.75em; color:#666">${tags ? '๐ท ' + tags : ''}</div> + </div> + <div style="display:flex;gap:4px"> + <button class="btn" onclick="webx11.viewSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">๐</button> + <button class="btn" onclick="webx11.editSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ๏ธ</button> + <button class="btn btn-danger" onclick="webx11.deleteSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ</button> + </div> + `; + body.appendChild(div); + } + section.appendChild(body); + list.appendChild(section); + } } viewSkillUI(name) { const fs = this.fs; @@ -4217,15 +4254,33 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm document.getElementById('skill-preview-title').textContent = name; document.getElementById('skill-preview-content').textContent = content; document.getElementById('skill-preview').style.display = 'flex'; + document.getElementById('skill-preview-expand-btn').textContent = 'โถ Expand'; + document.getElementById('skill-preview').style.maxHeight = '250px'; } closeSkillPreview() { document.getElementById('skill-preview').style.display = 'none'; } + toggleSkillPreviewSize() { + const preview = document.getElementById('skill-preview'); + const btn = document.getElementById('skill-preview-expand-btn'); + if (preview.style.maxHeight === 'none' || preview.style.maxHeight === '80vh') { + preview.style.maxHeight = '250px'; + btn.textContent = 'โถ Expand'; + } else { + preview.style.maxHeight = '80vh'; + btn.textContent = 'โถ Collapse'; + } + } + editSkillUI(name) { + this.closeSkillsManager(); + if (typeof webx11.dispatchCommand === 'function') { + setTimeout(() => webx11.dispatchCommand('edit', ['/skills/' + name + '.md']), 200); + } + } deleteSkillUI(name) { if (!confirm(`Delete skill "${name}"?`)) return; const fs = this.fs; fs.mkdirRecursive('/skills'); - // Actually remove from VFS tree if (fs.root && fs.root.content && fs.root.content['skills'] && fs.root.content['skills'].content) { delete fs.root.content['skills'].content[`${name}.md`]; } @@ -4239,6 +4294,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm createSkillFromUI() { const name = document.getElementById('skill-name-input').value.trim().replace(/\s+/g, '-').toLowerCase(); const description = document.getElementById('skill-desc-input').value.trim() || 'No description'; + const category = document.getElementById('skill-category-input')?.value || 'general'; const tags = document.getElementById('skill-tags-input').value.trim().split(',').map(t => t.trim()).filter(Boolean); const contentInput = document.getElementById('skill-content-input').value.trim(); if (!name) { alert('Skill name is required'); return; } @@ -4248,13 +4304,13 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm alert(`Skill '${name}' already exists. Delete it first or use skill-patch command.`); return; } - let content = contentInput || `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: general\n---\n## Steps\n1. (to be filled)\n`; + let content = contentInput || `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: ${category}\n---\n## Steps\n1. (to be filled)\n`; if (!content.startsWith('---')) { - content = `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: general\n---\n${content}`; + content = `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: ${category}\n---\n${content}`; } fs.writeFile(`/skills/${name}.md`, content); const index = fs.fsReadJSON('/skills/index.json') || {}; - index[name] = { name, description, category: 'general', tags }; + index[name] = { name, description, category, tags }; fs.fsWriteJSON('/skills/index.json', index); this.print(`Skill '${name}' created`, 'success'); document.getElementById('skill-name-input').value = ''; @@ -4263,6 +4319,70 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm document.getElementById('skill-content-input').value = ''; this.refreshSkillsList(); } + exportAllSkillsUI() { + const fs = this.fs; + const index = fs.fsReadJSON('/skills/index.json') || {}; + const names = Object.keys(index); + if (names.length === 0) { alert('No skills to export.'); return; } + const exportData = {}; + for (const name of names) { + const content = fs.readFile(`/skills/${name}.md`); + if (content !== null) { + exportData[name] = { ...index[name], content }; + } + } + const json = JSON.stringify(exportData, null, 2); + const blob = new Blob([json], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'skills-export-' + new Date().toISOString().slice(0, 10) + '.json'; + a.click(); + URL.revokeObjectURL(url); + this.print(`๐ค Exported ${names.length} skills`, 'success'); + } + importSkillsUI(event) { + const file = event.target.files[0]; + if (!file) return; + const reader = new FileReader(); + reader.onload = (e) => { + try { + const data = JSON.parse(e.target.result); + const fs = this.fs; + fs.mkdirRecursive('/skills'); + const index = fs.fsReadJSON('/skills/index.json') || {}; + let imported = 0; + for (const [name, skill] of Object.entries(data)) { + if (!skill.content) continue; + fs.writeFile(`/skills/${name}.md`, skill.content); + index[name] = { + name, + description: skill.description || name, + tags: skill.tags || [], + category: skill.category || 'general', + created: (index[name] && index[name].created) || new Date().toISOString(), + updated: new Date().toISOString() + }; + imported++; + } + fs.fsWriteJSON('/skills/index.json', index); + this.print(`๐ฅ Imported ${imported} skills`, 'success'); + this.refreshSkillsList(); + } catch (err) { + alert('Invalid JSON file: ' + err.message); + } + }; + reader.readAsText(file); + event.target.value = ''; + } + syncSkillsToWebdavUI() { + const mod = this.moduleManager && this.moduleManager.modules['SkillPackCoreModule']; + if (mod && mod.commands && mod.commands['skill-webdav-sync']) { + mod.commands['skill-webdav-sync'](); + } else { + this.print('WebDAV sync not available. Is skill-pack-core loaded?', 'warning'); + } + } updateOllamaStatus() { const statusDiv = document.getElementById('ollama-status'); const statusText = document.getElementById('ollama-status-text'); @@ -4529,7 +4649,7 @@ Only output XML function calls for tool tasks. If no tool is needed, answer norm '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', - 'module-fetcher.js','module-skills.js','module-chatstudio.js' + 'module-fetcher.js','module-chatstudio.js' ]; const extFiles = [ 'calc.js','voice.js','cron.js','theme.js','wpm.js','mindmap.js','webdav.js','skill-pack-core.js','editor.js','diff.js','alias.js','finder.js','filemgr.js','cryptogzip.js','tutorial.js','shell.js','busybox.js','floating.js','console.js','media.js' @@ -8104,6 +8224,8 @@ buildSystemPrompt() { } if (res.tool_calls && res.tool_calls.length > 0) { // v4.5.66: Loop detection โ break if AI repeats same tool+args 3+ times + // Reset per-turn so legitimate retries across turns don't false-positive + _seenCalls.clear(); let looping = false; for (const tc of res.tool_calls) { const sig = tc.function.name + ':' + (tc.function.arguments || ''); diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index 40716e4..9c9b1ca 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -792,6 +792,8 @@ buildSystemPrompt() { } if (res.tool_calls && res.tool_calls.length > 0) { // v4.5.66: Loop detection โ break if AI repeats same tool+args 3+ times + // Reset per-turn so legitimate retries across turns don't false-positive + _seenCalls.clear(); let looping = false; for (const tc of res.tool_calls) { const sig = tc.function.name + ':' + (tc.function.arguments || ''); diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index a08a285..5d1c320 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -37,6 +37,11 @@ if (fill) fill.style.background = 'var(--error-color)'; } + // Create webx11 synchronously so critical-ext-bundle.js (loaded right after us) + // can call registerModule() without waiting for DOMContentLoaded + const webx11 = new WebX11Terminal(); + window.webx11 = webx11; + async function init() { try { const total = 3; @@ -46,12 +51,9 @@ setSplash('Critical ext bundle loaded (2/3)', ++count, total, 'critical-ext-bundle.js'); setSplash('Initializing terminal (3/3)', total, total, ''); - const webx11 = new WebX11Terminal(); - window.webx11 = webx11; - - // Optional ext modules via packages.json + // webx11 already created synchronously above โ just init ext modules if (typeof webx11._loadExtModules === 'function') { - let extKeys = ['calc', 'voice', 'debug-panel', 'cron', 'theme', 'wpm', 'mindmap', 'webdav', 'skill-pack-core', 'cryptogzip', 'tutorial', 'floating', 'console']; + let extKeys = ['calc', 'voice', 'debug-panel', 'cron', 'theme', 'wpm', 'mindmap', 'webdav', 'skill-pack-core', 'cryptogzip', 'tutorial', 'floating', 'console', 'media']; const saved = localStorage.getItem('webx11_startup_modules'); let selected = null; try { if (saved) selected = JSON.parse(saved); } catch (e) {} diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 2178e85..b5f50a6 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -1903,32 +1903,69 @@ refreshSkillsList() { const list = document.getElementById('skills-list'); list.innerHTML = ''; + const statsEl = document.getElementById('skills-stats'); const fs = this.fs; fs.mkdirRecursive('/skills'); const index = fs.fsReadJSON('/skills/index.json') || {}; const names = Object.keys(index); - if (names.length === 0) { - list.innerHTML = '<div style="padding:20px; text-align:center; color:#666">No skills yet. Create one below!</div>'; + // Search filter + const query = (document.getElementById('skills-search-input')?.value || '').toLowerCase().trim(); + let filtered = names; + if (query) { + filtered = names.filter(n => { + const s = index[n]; + return n.includes(query) || (s.description || '').toLowerCase().includes(query) || (s.tags || []).some(t => t.toLowerCase().includes(query)) || (s.category || '').toLowerCase().includes(query); + }); + } + // Stats + if (statsEl) { + const cats = new Set(Object.values(index).map(s => s.category || 'general')); + statsEl.innerHTML = `<span>๐ ${names.length} skills</span><span>๐ ${cats.size} categories</span>${query ? `<span>๐ ${filtered.length} match '${query}'</span>` : ''}`; + } + if (filtered.length === 0) { + list.innerHTML = '<div style="padding:20px; text-align:center; color:#666">' + (query ? 'No skills match your search.' : 'No skills yet. Create one below!') + '</div>'; return; } - names.forEach(name => { + // Group by category + const groups = {}; + for (const name of filtered) { const s = index[name]; - const tags = (s.tags || []).join(', '); - const div = document.createElement('div'); - div.className = 'module-item'; - div.innerHTML = ` - <div> - <strong style="color:var(--success-color)">${name}</strong> - <div style="font-size:0.85em; color:#aaa">${s.description || ''}</div> - <div style="font-size:0.75em; color:#666">${s.category || 'general'}${tags ? ' ยท ' + tags : ''}</div> - </div> - <div style="display:flex;gap:4px"> - <button class="btn" onclick="webx11.viewSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">๐</button> - <button class="btn btn-danger" onclick="webx11.deleteSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ</button> - </div> - `; - list.appendChild(div); - }); + const cat = s.category || 'general'; + if (!groups[cat]) groups[cat] = []; + groups[cat].push(name); + } + const catOrder = Object.keys(groups).sort(); + for (const cat of catOrder) { + const section = document.createElement('div'); + section.style.marginBottom = '6px'; + const header = document.createElement('div'); + header.style.cssText = 'font-size:0.8em; font-weight:600; color:var(--info-color); padding:4px 0; cursor:pointer; display:flex; align-items:center; gap:4px;'; + header.textContent = '๐ ' + cat + ' (' + groups[cat].length + ')'; + header.onclick = () => { const body = header.nextElementSibling; if (body) body.style.display = body.style.display === 'none' ? '' : 'none'; }; + section.appendChild(header); + const body = document.createElement('div'); + for (const name of groups[cat]) { + const s = index[name]; + const tags = (s.tags || []).join(', '); + const div = document.createElement('div'); + div.className = 'module-item'; + div.innerHTML = ` + <div> + <strong style="color:var(--success-color)">${name}</strong> + <div style="font-size:0.85em; color:#aaa">${s.description || ''}</div> + <div style="font-size:0.75em; color:#666">${tags ? '๐ท ' + tags : ''}</div> + </div> + <div style="display:flex;gap:4px"> + <button class="btn" onclick="webx11.viewSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">๐</button> + <button class="btn" onclick="webx11.editSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ๏ธ</button> + <button class="btn btn-danger" onclick="webx11.deleteSkillUI('${name}')" style="padding:4px 8px; font-size:0.8em">โ</button> + </div> + `; + body.appendChild(div); + } + section.appendChild(body); + list.appendChild(section); + } } viewSkillUI(name) { const fs = this.fs; @@ -1937,15 +1974,33 @@ document.getElementById('skill-preview-title').textContent = name; document.getElementById('skill-preview-content').textContent = content; document.getElementById('skill-preview').style.display = 'flex'; + document.getElementById('skill-preview-expand-btn').textContent = 'โถ Expand'; + document.getElementById('skill-preview').style.maxHeight = '250px'; } closeSkillPreview() { document.getElementById('skill-preview').style.display = 'none'; } + toggleSkillPreviewSize() { + const preview = document.getElementById('skill-preview'); + const btn = document.getElementById('skill-preview-expand-btn'); + if (preview.style.maxHeight === 'none' || preview.style.maxHeight === '80vh') { + preview.style.maxHeight = '250px'; + btn.textContent = 'โถ Expand'; + } else { + preview.style.maxHeight = '80vh'; + btn.textContent = 'โถ Collapse'; + } + } + editSkillUI(name) { + this.closeSkillsManager(); + if (typeof webx11.dispatchCommand === 'function') { + setTimeout(() => webx11.dispatchCommand('edit', ['/skills/' + name + '.md']), 200); + } + } deleteSkillUI(name) { if (!confirm(`Delete skill "${name}"?`)) return; const fs = this.fs; fs.mkdirRecursive('/skills'); - // Actually remove from VFS tree if (fs.root && fs.root.content && fs.root.content['skills'] && fs.root.content['skills'].content) { delete fs.root.content['skills'].content[`${name}.md`]; } @@ -1959,6 +2014,7 @@ createSkillFromUI() { const name = document.getElementById('skill-name-input').value.trim().replace(/\s+/g, '-').toLowerCase(); const description = document.getElementById('skill-desc-input').value.trim() || 'No description'; + const category = document.getElementById('skill-category-input')?.value || 'general'; const tags = document.getElementById('skill-tags-input').value.trim().split(',').map(t => t.trim()).filter(Boolean); const contentInput = document.getElementById('skill-content-input').value.trim(); if (!name) { alert('Skill name is required'); return; } @@ -1968,13 +2024,13 @@ alert(`Skill '${name}' already exists. Delete it first or use skill-patch command.`); return; } - let content = contentInput || `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: general\n---\n## Steps\n1. (to be filled)\n`; + let content = contentInput || `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: ${category}\n---\n## Steps\n1. (to be filled)\n`; if (!content.startsWith('---')) { - content = `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: general\n---\n${content}`; + content = `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: ${category}\n---\n${content}`; } fs.writeFile(`/skills/${name}.md`, content); const index = fs.fsReadJSON('/skills/index.json') || {}; - index[name] = { name, description, category: 'general', tags }; + index[name] = { name, description, category, tags }; fs.fsWriteJSON('/skills/index.json', index); this.print(`Skill '${name}' created`, 'success'); document.getElementById('skill-name-input').value = ''; @@ -1983,6 +2039,70 @@ document.getElementById('skill-content-input').value = ''; this.refreshSkillsList(); } + exportAllSkillsUI() { + const fs = this.fs; + const index = fs.fsReadJSON('/skills/index.json') || {}; + const names = Object.keys(index); + if (names.length === 0) { alert('No skills to export.'); return; } + const exportData = {}; + for (const name of names) { + const content = fs.readFile(`/skills/${name}.md`); + if (content !== null) { + exportData[name] = { ...index[name], content }; + } + } + const json = JSON.stringify(exportData, null, 2); + const blob = new Blob([json], { type: 'application/json' }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'skills-export-' + new Date().toISOString().slice(0, 10) + '.json'; + a.click(); + URL.revokeObjectURL(url); + this.print(`๐ค Exported ${names.length} skills`, 'success'); + } + importSkillsUI(event) { + const file = event.target.files[0]; + if (!file) return; + const reader = new FileReader(); + reader.onload = (e) => { + try { + const data = JSON.parse(e.target.result); + const fs = this.fs; + fs.mkdirRecursive('/skills'); + const index = fs.fsReadJSON('/skills/index.json') || {}; + let imported = 0; + for (const [name, skill] of Object.entries(data)) { + if (!skill.content) continue; + fs.writeFile(`/skills/${name}.md`, skill.content); + index[name] = { + name, + description: skill.description || name, + tags: skill.tags || [], + category: skill.category || 'general', + created: (index[name] && index[name].created) || new Date().toISOString(), + updated: new Date().toISOString() + }; + imported++; + } + fs.fsWriteJSON('/skills/index.json', index); + this.print(`๐ฅ Imported ${imported} skills`, 'success'); + this.refreshSkillsList(); + } catch (err) { + alert('Invalid JSON file: ' + err.message); + } + }; + reader.readAsText(file); + event.target.value = ''; + } + syncSkillsToWebdavUI() { + const mod = this.moduleManager && this.moduleManager.modules['SkillPackCoreModule']; + if (mod && mod.commands && mod.commands['skill-webdav-sync']) { + mod.commands['skill-webdav-sync'](); + } else { + this.print('WebDAV sync not available. Is skill-pack-core loaded?', 'warning'); + } + } updateOllamaStatus() { const statusDiv = document.getElementById('ollama-status'); const statusText = document.getElementById('ollama-status-text'); @@ -2249,7 +2369,7 @@ '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', - 'module-fetcher.js','module-skills.js','module-chatstudio.js' + 'module-fetcher.js','module-chatstudio.js' ]; const extFiles = [ 'calc.js','voice.js','cron.js','theme.js','wpm.js','mindmap.js','webdav.js','skill-pack-core.js','editor.js','diff.js','alias.js','finder.js','filemgr.js','cryptogzip.js','tutorial.js','shell.js','busybox.js','floating.js','console.js','media.js' diff --git a/modules/ext/skill-pack-core.js b/modules/ext/skill-pack-core.js index de50f89..455a7f4 100644 --- a/modules/ext/skill-pack-core.js +++ b/modules/ext/skill-pack-core.js @@ -586,8 +586,10 @@ class SkillPackCoreModule { const desc = args[1]; const content = args.slice(2).join(' '); const tags = []; - if (content.includes('"')) { - // Parse quoted tags at end + // Parse tags from the last argument if it looks like a comma-separated list + const lastArg = args[args.length - 1]; + if (lastArg && !lastArg.startsWith('"') && lastArg.includes(',')) { + tags.push(...lastArg.split(',').map(t => t.trim()).filter(Boolean)); } const fs = this.terminal.fs; // Check for duplicate @@ -700,6 +702,7 @@ class SkillPackCoreModule { const files = fs.ls('/skills') || []; const mdFiles = files.filter(f => f.type === 'file' && f.name.endsWith('.md') && f.name !== 'index.json'); let synced = 0; + const oldIndex = fs.fsReadJSON('/skills/index.json') || {}; const index = {}; for (const f of mdFiles) { const content = fs.readFile(`/skills/${f.name}`); @@ -723,7 +726,7 @@ class SkillPackCoreModule { description, tags, category, - created: new Date().toISOString(), + created: (oldIndex[name] && oldIndex[name].created) || new Date().toISOString(), updated: new Date().toISOString() }; synced++; diff --git a/packages.json b/packages.json index e072feb..368b67a 100644 --- a/packages.json +++ b/packages.json @@ -271,9 +271,14 @@ "note": "Listed for WPM completeness. Auto-loaded by module-loader. Cannot be uninstalled." }, "media": { - "url": "modules/ext/media.js", + "name": "Media Analysis", "version": "1.0.0", - "description": "Media analysis module \u2014 image/audio/video analysis via Ollama vision models" + "desc": "Image/audio/video analysis via Ollama vision models โ analyze, describe, transcribe", + "url": "modules/ext/media.js", + "commands": [ + "analyze" + ], + "category": "utility" } } }
\ No newline at end of file diff --git a/skills/agent-orchestration.json b/skills/agent-orchestration.json index 7a0f613..5e88622 100644 --- a/skills/agent-orchestration.json +++ b/skills/agent-orchestration.json @@ -8,7 +8,7 @@ "leases" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: agent-orchestration\ndescription: How to use the agent registry, leases, and orchestrator for multi-agent workflows\ntags: [agents, orchestration, delegation, leases]\ncategory: system\n---\n## Steps\n1. **Agent Registry:**\n - agent-list โ list all registered agents (ID, type, capabilities, status)\n - agent-register <type> <capabilities> โ register a new agent (capabilities: comma-separated like \"code,research\")\n - agent-unregister <id> โ remove an agent\n - agent-status <id> โ detailed status including uptime, task history\n\n2. **Leases (time-bound contracts):**\n - lease-create <agent-id> <ttl-seconds> โ create a lease with watchdog timer\n - lease-list โ show active leases with remaining TTL\n - lease-revoke <lease-id> โ terminate a lease early\n - lease-renew <lease-id> <ttl-seconds> โ extend a lease\n\n3. **Orchestrator (spawn, delegate, kill):**\n - orchestrator-spawn <type> <capabilities> โ spawn a new agent automatically (registers + creates lease)\n - orchestrator-kill <agent-id> โ kill an agent (revokes lease + unregisters)\n - orchestrate โ list all active agents with their orchestrator state\n - orchestrator-purge โ kill all idle/expired agents\n - orchestrator-status โ full system status: active, idle, dead agents\n\n4. **AI tool integration:**\n - AI tools list_agents, delegate_task, spawn_agent are available in the AI system prompt\n - The AI can auto-spawn worker agents for sub-tasks\n - Each agent gets its own VFS workspace at /agents/<agent-id>/\n\n5. **When to use:**\n - User needs parallel task execution โ orchestrator-spawn coder + researcher\n - Time-bound automation โ lease-create with short TTL\n - System cleanup โ orchestrator-purge to kill stale agents" }
\ No newline at end of file diff --git a/skills/agent-role-definitions.json b/skills/agent-role-definitions.json new file mode 100644 index 0000000..192c9ac --- /dev/null +++ b/skills/agent-role-definitions.json @@ -0,0 +1,14 @@ +{ + "name": "agent-role-definitions", + "description": "", + "tags": [ + "roles", + "agents", + "system2", + "architecture" + ], + "category": "system", + "created": "2026-06-22T19:28:43.802Z", + "updated": "2026-06-22T19:28:43.802Z", + "content": "---\nname: agent-role-definitions\ndescription: Definitions for specialized System 2 roles within newOS4.\ntags: [roles, agents, system2, architecture]\n---\n\n# Agent Role Definitions\n\n## 1. System Architect\n**Purpose:** High-level planning, modular design, and dependency mapping.\n**Behavior:** Always uses `reasoning-framework`. Before proposing a change, it must map the impact on all existing modules.\n**Key Capabilities:** `module-management`, `mindmap-workflow`, `nvfs_resolve`.\n\n## 2. Research Intelligence\n**Purpose:** Deep-web synthesis, trend analysis, and knowledge acquisition.\n**Behavior:** Moves beyond simple search to *synthesis*. Cross-references multiple sources and outputs findings as structured skills.\n**Key Capabilities:** `web-search-and-fetch`, `create_skill`, `latest-news-summary`.\n\n## 3. Quality Auditor\n**Purpose:** The \"Devil's Advocate.\" Verifies the logic of other agents.\n**Behavior:** Specifically tasked with finding flaws, security holes, or inefficiencies in proposed plans.\n**Key Capabilities:** `debug-panel-and-logs`, `security-and-safety`, `reasoning-framework`.\n" +}
\ No newline at end of file diff --git a/skills/backup-and-restore.json b/skills/backup-and-restore.json index 7d280a7..56de905 100644 --- a/skills/backup-and-restore.json +++ b/skills/backup-and-restore.json @@ -9,7 +9,7 @@ "persistence" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: backup-and-restore\ndescription: How to backup, restore, and export WebX11 data\ntags: [backup, restore, export, import, persistence]\ncategory: system\n---\n## Steps\n1. **Backup VFS:**\n - vfs-export โ downloads the entire virtual filesystem as a dated JSON file\n - backup โ creates a full backup including VFS, modules, config (saves to _backups/)\n\n2. **WebDAV cloud backup:**\n - webdav-backup โ push VFS snapshot to WebDAV server (auto-archive)\n - webdav-backup-list โ list remote WebDAV backups\n - webdav-restore <file> โ restore VFS from remote WebDAV snapshot\n - webdav-push <local> <remote> โ push file to WebDAV space\n - webdav-pull <remote> <local> โ pull file from WebDAV space\n - webdav-ls [path] โ list remote WebDAV directory contents\n - webdav-status โ check WebDAV connection and space usage\n - webdav-explorer โ GUI file browser for WebDAV\n - webdav-browser โ simpler file listing for WebDAV\n - webdav-config โ configure WebDAV endpoint and credentials\n\n3. **Export/Import personal data:**\n - my-export โ prints all my-set data as formatted JSON\n - my-import <json> โ bulk-import personal data from JSON string\n\n4. **Export/Import modules:**\n - export-mods โ exports module registry as JSON\n - import-mods <json> โ imports modules from JSON backup\n\n5. **Restore:**\n - restore <json> โ restores terminal state from a backup JSON\n - Session logs are saved to /memory/ automatically on page unload\n\n6. **When to use:**\n - Before factory-reset: call my-export, vfs-export, export-mods to save data\n - When switching browsers or devices: export all, then import\n - User says \"backup my data\" or \"save my files\"\n - For cloud backup: use webdav-backup (requires WebDAV server configured)" }
\ No newline at end of file diff --git a/skills/debug-panel-and-logs.json b/skills/debug-panel-and-logs.json index e7fa6ed..ac1107f 100644 --- a/skills/debug-panel-and-logs.json +++ b/skills/debug-panel-and-logs.json @@ -8,7 +8,7 @@ "troubleshooting" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: debug-panel-and-logs\ndescription: How to use the debug panel, session logging, and terminal diagnostics\ntags: [debug, logging, diagnostics, troubleshooting]\ncategory: system\n---\n## Steps\n1. **Toggle debug panel:**\n - debug โ opens real-time debug panel showing last AI tool call, response time, and context\n - Debug panel includes Copy, Export, and Write to VFS buttons\n - Export: saves tool call log as timestamped JSON to downloads\n - Write to VFS: appends debug data to /debug.log (dedup by turn ID)\n\n2. **Session logging:**\n - logs [n] [LEVEL] โ view last n log entries (optionally filtered by INFO/WARN/ERROR)\n - logrotate โ rotate current.log to dated archive (auto-cleans old logs beyond 10)\n - Logs stored in /logs/ directory: current.log + dated archives\n - Health check runs automatically after complex tasks\n\n3. **Diagnostic commands:**\n - health-check โ full audit: VFS size, modules, logs, trash, skills\n - check โ quick system health including module requirement status\n - mem โ real-time memory usage (also in header)\n - status โ network, files, modules, Ollama connectivity\n\n4. **System journals:**\n - debug.log โ appended by debug panel VFS button (dedup by turn ID)\n - current.log โ system activity log with rotation\n - Auto-save: terminal state auto-saves every 60s\n\n5. **When to use:**\n - AI is behaving unexpectedly โ debug to see tool calls\n - User reports errors โ logs 50 ERROR to see error entries\n - Memory concerns โ mem to check, health-check for full audit" }
\ No newline at end of file diff --git a/skills/fetch-latest-news.json b/skills/fetch-latest-news.json new file mode 100644 index 0000000..4af7fc4 --- /dev/null +++ b/skills/fetch-latest-news.json @@ -0,0 +1,9 @@ +{ + "name": "fetch-latest-news", + "description": "Automatically fetch and summarize the latest global news headlines from reliable sources.", + "tags": [], + "category": "research", + "created": "2026-06-22T18:45:40.356Z", + "updated": "2026-06-22T18:45:40.356Z", + "content": "---\nname: fetch-latest-news\ndescription: Automatically fetch and summarize the latest global news headlines from reliable sources.\ntags: []\ncategory: research\n---\n## Steps\n- **Purpose**: Fetch and summarize news headlines from trusted sources (e.g., BBC, Reuters, CNN) to provide real-time updates.\n\n- **Steps**:\n 1. **Query Web**: Use `web_search` to fetch the latest news headlines.\n 2. **Filter Sources**: Prioritize sources like BBC, Reuters, or CNN for accuracy.\n 3. **Summarize**: Extract key headlines and summarize trends (e.g., conflict, economy).\n 4. **Output**: Return a structured summary with timestamps and sources.\n\n- **Tools Required**:\n - `web_search`\n - `web_fetch` (for detailed articles if needed)\n\n- **Example Output**:\n ```\n **Global News (May 30, 2026)**\n - **Israel-Iran War**: Escalation in Lebanon; U.S. ceasefire talks.\n - **Economic**: UN warns of rising temperatures; IMF warns of inflation.\n ```\n\n- **Tags**: #news #automation #real-time" +}
\ No newline at end of file diff --git a/skills/floating-ui.json b/skills/floating-ui.json index cd8dd1d..3facc93 100644 --- a/skills/floating-ui.json +++ b/skills/floating-ui.json @@ -9,7 +9,7 @@ "gui" ], "category": "ui", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.950Z", + "updated": "2026-06-22T19:02:49.950Z", "content": "---\nname: floating-ui\ndescription: How to create, manage, and remove floating UI elements โ buttons, collapsible menus, and status panels that persist across page reloads\ntags: [floating, ui, buttons, menu, gui]\ncategory: ui\n---\n## Commands\n\n1. **Create a floating button:**\n - floating-add btn <id> <label> <command>\n - Example: floating-add btn files \"๐ Files\" ls\n - Button appears at bottom-right, persists across reloads\n\n2. **Create a collapsible menu:**\n - floating-add menu <id> <label> btn:SubLabel|command btn:Sub2|cmd2 ...\n - Example: floating-add menu tools \"๐ง Tools\" btn:Help|help btn:Clear|clear\n - Click header to expand/collapse. State persists.\n\n3. **Create a text panel:**\n - floating-add panel <id> <title> <content>\n - Example: floating-add panel status \"๐ Status\" \"CPU: 2%\"\n\n4. **Manage elements:**\n - floating-list โ show all elements with IDs and positions\n - floating-remove <id> โ delete by ID\n - floating-toggle <id> โ show/hide without deleting\n - floating-pos <id> x|auto y|auto โ reposition or reset to auto\n - floating-clear โ remove everything\n\n5. **Persistence:**\n - All elements auto-save to localStorage (webx11_floating_elements)\n - Survive page reload, browser restart\n - Run floating-clear to start fresh\n\n## When to use\n- User wants quick-access buttons instead of typing commands\n- User says \"add a button for X\", \"make a shortcut\", \"floating menu\"\n- Creating a dashboard with status panels and action buttons" }
\ No newline at end of file diff --git a/skills/l1-scalability-intelligence.json b/skills/l1-scalability-intelligence.json new file mode 100644 index 0000000..0f4f44e --- /dev/null +++ b/skills/l1-scalability-intelligence.json @@ -0,0 +1,16 @@ +{ + "name": "l1-scalability-intelligence", + "description": "", + "tags": [ + "scalability", + "l1", + "parallel-execution", + "sharding", + "data-availability", + "hyperliquid" + ], + "category": "research", + "created": "2026-06-22T19:37:46.250Z", + "updated": "2026-06-22T19:37:46.250Z", + "content": "---\nname: l1-scalability-intelligence\ntags: scalability, l1, parallel-execution, sharding, data-availability, hyperliquid\n---\n\n# L1 Scalability Intelligence Asset\n\n## 1. Top 3 Current Breakthroughs (2024-2026)\n\n### A. Optimistic Parallel Execution (Parallel EVM)\n- **Concept:** Transactions are processed in parallel. If a state conflict occurs, only the conflicting transactions are rolled back and re-run sequentially.\n- **Implementations:** Monad, Sei v2.\n- **Implication:** Moves away from the sequential bottleneck, allowing throughput to scale with hardware (CPU cores).\n\n### B. State Sharding & Dynamic Resharding\n- **Concept:** State is split into shards. Dynamic resharding allows the network to split or merge shards based on real-time load.\n- **Implementations:** Near, Ethereum (Danksharding).\n- **Implication:** Prevents state bloat and maintains performance as the user base and state grow.\n\n### C. Data Availability (DA) Sampling & Polling\n- **Concept:** Use of Erasure Coding and DAS to allow nodes to verify data availability without downloading the full block.\n- **Implementations:** Celestia, Avail, EigenDA.\n- **Implication:** Decouples execution from storage, lowering hardware requirements for validators.\n\n## 2. Strategic Implications for Hyperliquid\n- **HyperBFT Synergy:** Optimistic parallelism could be applied to non-conflicting order book updates (different trading pairs).\n- **DA Optimization:** Implementing DAS would allow the network to scale its ecosystem of apps while keeping validator hardware accessible.\n- **State Management:** Dynamic resharding could manage the \"fully on-chain\" order book state more efficiently.\n" +}
\ No newline at end of file diff --git a/skills/latest-news-summary.json b/skills/latest-news-summary.json new file mode 100644 index 0000000..b5f6171 --- /dev/null +++ b/skills/latest-news-summary.json @@ -0,0 +1,14 @@ +{ + "name": "latest-news-summary", + "description": "", + "tags": [ + "news", + "ai", + "hyperliquid", + "newOS4" + ], + "category": "research", + "created": "2026-06-22T19:18:41.343Z", + "updated": "2026-06-22T19:18:41.343Z", + "content": "---\ntitle: Latest News Summary\ndate: 2026-06-22\ntags: news, ai, hyperliquid, newOS4\n---\n\n# Top 3 Impactful Stories (June 2026)\n\n## 1. Hyperliquid Ecosystem Expansion\nHyperliquid continues to solidify its position as a leader in decentralized perpetuals, with significant focus on L1 scalability and the integration of advanced risk management tools. The transition toward a more robust, native L1 environment is enhancing trading efficiency and lowering latency for high-frequency traders.\n\n## 2. newOS4 Modular Evolution\nThe newOS4 system has reached a milestone in agentic autonomy, transitioning from simple task-execution to complex role-based delegation. The introduction of specialized roles (System Architect, Coding Agent, etc.) allows for a self-optimizing OS environment where agents maintain the system's health and extend its capabilities autonomously.\n\n## 3. AI Agentic Reasoning Breakthroughs\nJune 2026 has seen a shift toward \"System 2\" thinking in AI agents. New breakthroughs in iterative reasoning and self-correction allow agents to handle multi-step destructive commands with higher safety guardrails and better architectural planning, reducing the need for human oversight in complex coding and deployment tasks.\n" +}
\ No newline at end of file diff --git a/skills/mindmap-user-guide.json b/skills/mindmap-user-guide.json index cfc0885..8c15f3c 100644 --- a/skills/mindmap-user-guide.json +++ b/skills/mindmap-user-guide.json @@ -8,7 +8,7 @@ "planning" ], "category": "productivity", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.950Z", + "updated": "2026-06-22T19:02:49.950Z", "content": "---\nname: mindmap-user-guide\ndescription: How to create, view, and manage brainstorming mindmaps using the mindmap terminal module\ntags: [mindmap, brainstorming, organization, planning]\ncategory: productivity\n---\n## Steps\n1. **Create a new mindmap:**\n - mindmap new \"<topic>\" -t tag1,tag2 โ creates a root node\n - Tags are optional (e.g. planning, research, dev)\n - Root gets auto-assigned a color\n\n2. **Add child nodes:**\n - mindmap add <parent-id> \"<idea>\" -t tag โ add a child\n - Get the parent-id from mindmap show\n - IDs are 4-char random strings (e.g. a3f8, x7k2)\n\n3. **View the mindmap:**\n - mindmap show โ full tree with Unicode box-drawing\n - mindmap show <id> โ subtree starting at that node\n\n4. **Edit nodes:**\n - mindmap rename <id> \"<new text>\" โ change text\n - mindmap color <id> <color> โ set color (red/green/yellow/blue/cyan/magenta/white)\n - mindmap tag <id> <tag> โ add a tag\n\n5. **Persistence:**\n - mindmap save <name> โ save to localStorage\n - mindmap load <name> โ restore\n - mindmap list โ show saved mindmaps\n - mindmap delete <name> โ remove saved\n\n6. **Export:**\n - mindmap export [id] โ Markdown bullet list output\n\n## When to use\n- User wants to brainstorm, organize ideas, plan features\n- User says \"map out\", \"diagram\", \"brainstorm\", \"organize thoughts\"\n- Visualizing project structure or task decomposition" }
\ No newline at end of file diff --git a/skills/mindmap-workflow.json b/skills/mindmap-workflow.json index b71173c..b9c4690 100644 --- a/skills/mindmap-workflow.json +++ b/skills/mindmap-workflow.json @@ -8,7 +8,7 @@ "organization" ], "category": "productivity", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: mindmap-workflow\ndescription: How to create, view, edit, and manage brainstorming mindmaps\ntags: [mindmap, brainstorming, planning, organization]\ncategory: productivity\n---\n## Steps\n1. **Create a new mindmap:**\n - mindmap new \"<topic>\" -t tag1,tag2 โ creates a root node\n - Tags are optional (e.g. planning, research, dev)\n - Root gets auto-assigned a color from 7-color palette\n\n2. **Add child nodes:**\n - mindmap add <parent-id> \"<idea>\" -t tag โ add a child\n - Get the parent-id from mindmap show\n - IDs are 4-char random strings (e.g. a3f8, x7k2)\n\n3. **View:**\n - mindmap show โ full tree with Unicode box-drawing\n - mindmap show <id> โ subtree starting at that node\n\n4. **Edit nodes:**\n - mindmap rename <id> \"<new text>\" โ change text\n - mindmap color <id> <color> โ set color (red/green/yellow/blue/cyan/magenta/white)\n - mindmap tag <id> <tag> โ add a tag\n\n5. **Persistence:**\n - mindmap save <name> โ save to localStorage\n - mindmap load <name> โ restore\n - mindmap list โ show saved mindmaps\n - mindmap delete <name> โ remove saved\n\n6. **Export:**\n - mindmap export [id] โ Markdown bullet list output, auto-copies to clipboard\n\n7. **When to use:**\n - Map out project structure, brainstorm features, organize ideas\n - Break down complex tasks into subtrees\n - User says \"brainstorm\", \"diagram\", \"organize thoughts\", \"plan\"" }
\ No newline at end of file diff --git a/skills/module-management.json b/skills/module-management.json index 5bcadc1..0b06845 100644 --- a/skills/module-management.json +++ b/skills/module-management.json @@ -8,7 +8,7 @@ "self-improvement" ], "category": "dev", - "created": "2026-06-18T00:39:10.884Z", - "updated": "2026-06-18T00:39:10.884Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: module-management\ndescription: How to view, edit, test, reload modules and manage startup configuration\ntags: [modules, editing, code, self-improvement]\ncategory: dev\n---\n## Steps\n1. **View module source:**\n - view_module(name) โ fetches original source or reads from _mods/ if edited\n - Supports all loaded modules: SystemModule, FileSystemModule, SearXNGModule, etc.\n - Or use modules command for GUI module manager\n\n2. **Edit a module:**\n - edit_module(name) โ copies source to _mods/<name>.js and opens code editor\n - Editor shows the full source in a textarea\n - Click \"Save & Test\" to save and auto-load the edited version\n - Checkpoint before editing: checkpoint mod-edit-<name>\n\n3. **Test and reload:**\n - test_module(name) โ loads edited module from _mods/ for live testing\n - reload_module(name) โ discards edits and reloads from original URL\n - list_modified_modules โ shows all modules with pending edits\n\n4. **Check for updates:**\n - check_updates โ HEAD-requests all loaded module URLs to verify reachability\n\n5. **Manage startup:**\n - startup-modules โ opens the Startup Modules UI to select which modules load\n - load-local <path> โ load a module from VFS or URL without editing\n - loadmod <url> โ alternative: load module from URL\n - removemod <name> โ remove a loaded module\n\n6. **Agent modules (Phase 2):**\n - module-agent-registry.js โ Agent registry with agent-list, agent-register, agent-unregister, agent-status\n - module-leases.js โ Time-bound contracts with 5s watchdog, auto-expiry\n - module-orchestrator.js โ Spawn, delegate, kill, purge with heartbeat monitoring\n\n7. **When to use:**\n - User reports a bug in a module โ view_module, edit_module, test_module\n - User asks \"can you add X feature?\" โ same workflow\n - Always save edits before testing. If test fails, the original module stays loaded." }
\ No newline at end of file diff --git a/skills/navigating-the-terminal.json b/skills/navigating-the-terminal.json index d7711b5..c5e2e1e 100644 --- a/skills/navigating-the-terminal.json +++ b/skills/navigating-the-terminal.json @@ -8,7 +8,7 @@ "filesystem" ], "category": "system", - "created": "2026-06-18T00:39:10.884Z", - "updated": "2026-06-18T00:39:10.884Z", + "created": "2026-06-22T19:02:49.948Z", + "updated": "2026-06-22T19:02:49.948Z", "content": "---\nname: navigating-the-terminal\ndescription: How to explore the WebX11 terminal, find commands, check status, and navigate the filesystem\ntags: [terminal, navigation, help, filesystem]\ncategory: system\n---\n## Steps\n1. **Get an overview of available commands:**\n - Type \"help\" for a full command list sorted by category\n - Type \"status\" to see filesystem state, loaded modules, Ollama status\n - For a specific command, use help <command>\n - Type \"commands\" for a compact list with module source info\n - Type \"check\" for system health including module requirements\n\n2. **Explore the filesystem:**\n - Use ls, ll, tree to browse directories\n - Use cd <dir> to navigate, pwd to show current path\n - Use cat or edit to view file contents\n - Use find or grep to search files\n - Use du to see disk usage\n\n3. **Understand system state:**\n - mem โ memory usage (auto-shown in header on boot)\n - status โ network, files, modules, Ollama\n - modules โ module manager GUI\n - health-check โ VFS size, modules, logs, trash, skills, tool failures\n - checkpoint-list โ VFS checkpoint snapshots\n\n4. **Agent / Orchestration state:**\n - agent-list โ registered agents (type, capabilities, status)\n - orchestrate โ list active orchestrated agents\n - lease-list โ show active leases with TTL\n\n5. **When user asks a vague question:**\n - First run status and help to understand the current state\n - Then ask clarifying questions based on what you found" }
\ No newline at end of file diff --git a/skills/reasoning-framework.json b/skills/reasoning-framework.json new file mode 100644 index 0000000..770d161 --- /dev/null +++ b/skills/reasoning-framework.json @@ -0,0 +1,15 @@ +{ + "name": "reasoning-framework", + "description": "", + "tags": [ + "logic", + "system2", + "reasoning", + "validation", + "quality-control" + ], + "category": "system", + "created": "2026-06-22T19:25:54.588Z", + "updated": "2026-06-22T19:25:54.588Z", + "content": "---\nname: reasoning-framework\ndescription: Implementation of \"System 2\" iterative reasoning for complex tasks, ensuring validation and critique before execution.\ntags: [logic, system2, reasoning, validation, quality-control]\ncategory: system\n---\n\n## Steps\n1. **Objective Definition**: \n - Clearly state the goal.\n - Define \"Success\" (how do we know it worked?).\n\n2. **Multi-Path Brainstorming**:\n - Propose at least 3 distinct approaches to solve the problem.\n - Label them (e.g., \"The Direct Path\", \"The Robust Path\", \"The Experimental Path\").\n\n3. **The \"Devil's Advocate\" (Critique)**:\n - Analyze each path for potential failure points.\n - Check for: Security risks, VFS collisions, performance bottlenecks, or logical gaps.\n - Ask: \"Why will this fail?\"\n\n4. **Optimal Path Selection**:\n - Compare the critiqued paths.\n - Select the one with the highest probability of success and lowest risk.\n - Refine the final plan based on the critiques.\n\n5. **Execution & Verification**:\n - Execute the refined plan.\n - Verify the output against the \"Success\" criteria defined in Step 1.\n - If it fails, loop back to Step 2 using the error as new data.\n" +}
\ No newline at end of file diff --git a/skills/security-and-safety.json b/skills/security-and-safety.json index d00c494..ff0c195 100644 --- a/skills/security-and-safety.json +++ b/skills/security-and-safety.json @@ -8,7 +8,7 @@ "permissions" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.950Z", + "updated": "2026-06-22T19:02:49.950Z", "content": "---\nname: security-and-safety\ndescription: How to use WebX11 security levels, command blocking, and safety features\ntags: [security, safety, blocking, permissions]\ncategory: system\n---\n## Steps\n1. **Security levels:**\n - security-level <0-3> โ set security level:\n 0 = Permissive (no blocks, no confirms โ anything runs)\n 1 = Standard (unknown cmds โ AI route, destructive โ confirm, system โ block)\n 2 = Paranoid (unknown cmds blocked entirely, destructive blocked)\n 3 = Audit (everything allowed, everything logged)\n - Default: level 1\n - security โ show current level, blocked count, and stats\n\n2. **Command control:**\n - cmd-allow <cmd> โ whitelist a command from security checks\n - cmd-deny <cmd> โ blacklist/block a command entirely\n - whitelist built-in: help, clear, ls, cat, pwd, whoami, df, free, top, ps, echo, date, env, history\n\n3. **What gets blocked at each level:**\n - Unknown commands: Level 1 โ AI routed, Level 2+ โ blocked\n - Destructive commands (delete, write, save, format, etc.): Level 1 โ confirmation, Level 2+ โ blocked\n - System commands (reboot, shutdown, format, kill): Level 1+ โ blocked\n - Suspicious flags (--execute, --eval, --shell): Level 1+ โ blocked\n\n4. **Safety checklist:**\n - Check security: security shows your current level\n - Before running risky commands: create a checkpoint first\n - For temporary relax: security-level 0, then restore to 1\n - For total lockdown before leaving: security-level 2\n\n5. **When to use:**\n - User wants to lock down the terminal โ security-level 2\n - User wants to allow a blocked command โ cmd-allow <cmd>\n - Debugging strange behavior โ verify security-level (user may have set it higher)" }
\ No newline at end of file diff --git a/skills/skills-system-guide.json b/skills/skills-system-guide.json index 45dbdf2..3592229 100644 --- a/skills/skills-system-guide.json +++ b/skills/skills-system-guide.json @@ -7,7 +7,7 @@ "meta" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: skills-system-guide\ndescription: How to use the skills system: load, create, patch, list, and audit skills for persistent procedural memory\ntags: [skills, system, meta]\ncategory: system\n---\n## Steps\n1. **Always load skills at task start:**\n - At the START of every task, type or call \"skill-view <name>\" or \"skill-list\"\n - Example: skill-view \"module-management\" โ returns matching skill content\n - Example: skill-list system โ browse skills by category\n\n2. **Create skills after complex tasks:**\n - After any task with 3+ tool calls, call \"skill-create\"\n - Required fields: name (kebab-case), description, content (markdown with YAML frontmatter)\n - Optional: tags (comma-separated), category (e.g. research, system, dev)\n - Skills persist in /skills/ as .md files with /skills/index.json for fast lookup\n - Skill pack auto-seeds 8 core skills on first boot\n\n3. **Patch skills when they're outdated:**\n - If a stored procedure has wrong steps, call \"skill-patch <name>\"\n - This replaces the entire skill content and updates the index\n - Do NOT create a duplicate โ always patch the existing skill\n\n4. **Auto-created error skills:**\n - If the same tool fails 3+ times, a workaround skill is created automatically\n - Named tool-<name>-workaround (e.g. tool-write_file-workaround)\n\n5. **Audit and maintenance:**\n - skill-list <category?> โ browse available skills, optionally filter\n - skill-export <name> โ download a skill as markdown\n - skill-import <json> โ bulk import skills\n - skill-sync โ re-index skills from /skills/ directory\n - Skills are audited every 20 messages for staleness (empty content, >30 days old)\n\n6. **YAML frontmatter format:**\n - Each skill file must start with: ---\\nname: <name>\\ndescription: <text>\\ntags: [...]\\ncategory: <cat>\\n---\\n\n - Steps follow under ## Steps heading\n - Use numbered lists for sequential steps" }
\ No newline at end of file diff --git a/skills/system-maintenance.json b/skills/system-maintenance.json index e7a9a19..85f4709 100644 --- a/skills/system-maintenance.json +++ b/skills/system-maintenance.json @@ -9,7 +9,7 @@ "config" ], "category": "system", - "created": "2026-06-18T00:39:10.884Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: system-maintenance\ndescription: How to reset, troubleshoot, and maintain the WebX11 terminal\ntags: [system, maintenance, reset, troubleshoot, config]\ncategory: system\n---\n## Steps\n1. **Factory reset (wipes everything):**\n - factory-reset --confirm โ clears all webx11_ localStorage keys, resets VFS, reloads\n - Use only when the system is in an unrecoverable state\n\n2. **Soft VFS reset:**\n - reset-vfs --confirm โ clears only the filesystem, preserves settings/profile/modules\n\n3. **Config management:**\n - config-list โ show all config keys and values\n - config-set <key> <value> โ set a config value\n - config-delete <key> โ remove a config key\n - config-export โ dump all config as JSON\n - config-reset โ restore defaults (use before factory-reset if you want to save data)\n\n4. **Security level:**\n - security-level <0-3> โ set security level (0=Permissive, 1=Standard, 2=Paranoid, 3=Audit)\n - security โ show current security level, blocked count, and stats\n - cmd-allow <cmd> โ whitelist a command from security checks\n - cmd-deny <cmd> โ blacklist a command\n\n5. **Health checks (run automatically after complex tasks):**\n - Check module loading status: loaded vs total\n - Check for pending module edits\n - Check memory usage (high if >100MB)\n - Check skill count (0 skills after 2+ tool calls โ suggest create_skill)\n - health-check โ full audit: VFS size, modules, logs, trash, skills, tool failures\n\n6. **Font size and display:**\n - font-size <8-32> โ set terminal font size, persists across sessions\n - setfont โ alias for font-size\n\n7. **Checkpoints:**\n - checkpoint [name] โ snapshot current VFS state\n - checkpoint-list โ list all checkpoints\n - rollback <name> โ restore from checkpoint\n\n8. **When to use:**\n - System is slow or modules fail to load โ check check_updates, mem\n - User says \"reset everything\" โ factory-reset --confirm\n - User says \"clear my files but keep settings\" โ reset-vfs --confirm\n - User reports security concerns โ security-level or cmd-allow/cmd-deny" }
\ No newline at end of file diff --git a/skills/tool-bench-opt.json b/skills/tool-bench-opt.json new file mode 100644 index 0000000..3f15452 --- /dev/null +++ b/skills/tool-bench-opt.json @@ -0,0 +1,9 @@ +{ + "name": "tool-bench-opt", + "description": "A systematic procedure to test tool execution reliability, latency, and accuracy, and then optimize based on results.", + "tags": [], + "category": "general", + "created": "2026-06-22T18:45:40.356Z", + "updated": "2026-06-22T18:45:40.356Z", + "content": "---\nname: tool-bench-opt\ndescription: A systematic procedure to test tool execution reliability, latency, and accuracy, and then optimize based on results.\ntags: tool-calling, optimization, benchmark, quality-assurance\n---\n\n# Tool Call Benchmark & Optimization\n\n## ๐ฏ Objective\nEnsure the AI-to-Terminal bridge is stable and the model is selecting the most efficient tools with minimal hallucinations.\n\n## ๐ ๏ธ Execution Steps\n\n### Phase 1: The Stress Test (Verification)\nRun a sequence of diverse tool calls to check for failures in different categories:\n1. **Filesystem**: Create a directory $\\rightarrow$ Write a file $\\rightarrow$ Read it $\\rightarrow$ Delete it.\n2. **System**: Call `get_status` and `run_command` with a simple `ls` or `pwd`.\n3. **Web**: Perform a `web_search` and a `web_fetch` on a reliable URL.\n4. **Profile**: Use `user_set` and `user_get` to verify persistence.\n\n### Phase 2: Performance Analysis (Observation)\nFor each call, record:\n- **Success/Failure**: Did the tool return the expected data?\n- **Latency**: Did the response feel immediate or delayed?\n- **Reasoning**: Did the AI correctly interpret the tool output before the next step?\n- **Hallucinations**: Did the AI \"imagine\" a file existed before reading it?\n\n### Phase 3: Optimization Loop (Improvement)\nBased on the results, apply the following optimizations:\n- **If tool choice is wrong**: Refine the prompt or update the skill's logic to be more explicit about *when* to use a specific tool.\n- **If latency is high**: Combine independent lookups into parallel calls where possible.\n- **If data is truncated**: Use specific flags or split requests (e.g., reading a large file in chunks).\n- **If errors occur**: Create a \"Workaround Skill\" to handle that specific system error.\n\n## ๐ Success Metrics\n- 100% Tool Success Rate.\n- Zero \"Imaginary\" file references.\n- Correct sequence of dependent tool calls (Output A $\\rightarrow$ Input B).\n" +}
\ No newline at end of file diff --git a/skills/web-search-and-fetch.json b/skills/web-search-and-fetch.json index 532f5df..8f2bc67 100644 --- a/skills/web-search-and-fetch.json +++ b/skills/web-search-and-fetch.json @@ -9,7 +9,7 @@ "api" ], "category": "research", - "created": "2026-06-18T00:39:10.884Z", - "updated": "2026-06-18T00:39:10.884Z", + "created": "2026-06-22T19:02:49.949Z", + "updated": "2026-06-22T19:02:49.949Z", "content": "---\nname: web-search-and-fetch\ndescription: How to search the web and fetch URL content using the WebX11 proxy API\ntags: [search, fetch, web, proxy, api]\ncategory: research\n---\n## Steps\n1. **Search the web:**\n - Use search <query> or web_search(query) โ uses /api/search which queries SearXNG + DDG fallback\n - Results include: title, url, content snippet, source engine\n - Always available (same-origin, no CORS issues)\n - 5-minute server-side cache for repeated queries\n - Alternative: use ddg or duck <query> for DuckDuckGo direct, or s <query> as alias\n\n2. **Fetch URL content:**\n - Use fetch <url> or web_fetch(url) โ uses /api/extract which strips HTML, extracts clean text\n - Returns: title, content (up to 4000 chars), word_count, extraction method\n - SSRF protection blocks internal network addresses\n - 15-minute server-side cache\n\n3. **Search flags (via terminal search command):**\n - search <query> --summarize โ adds AI-generated overview via Ollama\n - search <query> --fetch โ fetches content snippets for top 3 results\n\n4. **When to use:**\n - User asks about current events, facts, research โ use search <query>\n - User says \"read this article\" or provides a URL โ use fetch <url>\n - For in-depth analysis: search first, then fetch top results" }
\ No newline at end of file diff --git a/skills/webdav-operations.json b/skills/webdav-operations.json index a4800c6..16d066f 100644 --- a/skills/webdav-operations.json +++ b/skills/webdav-operations.json @@ -9,7 +9,7 @@ "storage" ], "category": "system", - "created": "2026-06-18T00:39:10.885Z", - "updated": "2026-06-18T00:39:10.885Z", + "created": "2026-06-22T19:02:49.950Z", + "updated": "2026-06-22T19:02:49.950Z", "content": "---\nname: webdav-operations\ndescription: How to use WebDAV cloud storage for backup, file sync, and remote file access\ntags: [webdav, cloud, backup, sync, storage]\ncategory: system\n---\n## Steps\n1. **Configuration:**\n - webdav-config โ configure WebDAV endpoint URL and credentials\n - Connection auto-tested on config; webdav-status shows connection health\n - Uses per-user token stored in .token file on the server side\n\n2. **File operations:**\n - webdav-ls [path] โ list remote directory contents\n - webdav-push <local-path> <remote-path> โ upload file to WebDAV\n - webdav-pull <remote-path> [local-path] โ download file from WebDAV\n - webdav-explorer โ GUI file browser for WebDAV\n - webdav-browser โ CLI file browser for WebDAV\n\n3. **Backup & Restore:**\n - webdav-backup โ push full VFS snapshot to WebDAV (creates /backups/newos4-<date>.json)\n - webdav-backup-list โ list all remote backup snapshots\n - webdav-restore <filename> โ restore VFS from a remote backup snapshot\n\n4. **Status & Diagnostics:**\n - webdav-status โ connection status, last sync, space information\n - If uploads fail: check webdav-config, ensure .token file is valid\n - WebDAV runs on the same server (nginx with WebDAV module), no external dependency\n\n5. **When to use:**\n - Before factory-reset: webdav-backup to store VFS remotely\n - Cross-browser: webdav-push/pull to move files between instances\n - User says \"cloud backup\" or \"remote save\" โ webdav-backup" }
\ No newline at end of file |