aboutsummaryrefslogtreecommitdiff
path: root/modules/core
diff options
context:
space:
mode:
Diffstat (limited to 'modules/core')
-rw-r--r--modules/core/module-loader.js4
-rw-r--r--modules/core/terminal.js26
2 files changed, 21 insertions, 9 deletions
diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js
index 2510fde..3a32f38 100644
--- a/modules/core/module-loader.js
+++ b/modules/core/module-loader.js
@@ -99,9 +99,9 @@
window.__moduleLoaderReload = reloadWithSelection;
- const CACHE = '?v=' + (localStorage.getItem('webx11_cache_ver') || '2026-05-27-14');
+ const CACHE = '?v=' + (localStorage.getItem('webx11_cache_ver') || '2026-05-28');
if (!localStorage.getItem('webx11_cache_ver')) {
- localStorage.setItem('webx11_cache_ver', '2026-05-27-14');
+ localStorage.setItem('webx11_cache_ver', '2026-05-28');
}
async function init() {
diff --git a/modules/core/terminal.js b/modules/core/terminal.js
index 309e477..1bfc4cd 100644
--- a/modules/core/terminal.js
+++ b/modules/core/terminal.js
@@ -1160,7 +1160,7 @@
// Remove leading slash for VFS paths
const vfsPath = path.replace(/^\/*/, '');
let content = this.fs.readFile(vfsPath);
- if (content === null) content = this.fs.fsRead('/' + vfsPath);
+ if (content === null) content = this.fs.readFile('/' + vfsPath);
if (content === null) {
this.print(`File not found: ${path}`, 'error');
return;
@@ -1285,11 +1285,11 @@
}
viewSkillUI(name) {
const fs = this.fs;
- const content = fs.fsRead(`/skills/${name}.md`);
+ const content = fs.readFile(`/skills/${name}.md`);
if (!content) { this.print(`Skill '${name}' not found`, 'error'); return; }
document.getElementById('skill-preview-title').textContent = name;
document.getElementById('skill-preview-content').textContent = content;
- document.getElementById('skill-preview').style.display = 'block';
+ document.getElementById('skill-preview').style.display = 'flex';
}
closeSkillPreview() {
document.getElementById('skill-preview').style.display = 'none';
@@ -1298,7 +1298,7 @@
if (!confirm(`Delete skill "${name}"?`)) return;
const fs = this.fs;
fs.mkdirRecursive('/skills');
- fs.fsWrite(`/skills/${name}.md`, '');
+ fs.writeFile(`/skills/${name}.md`, '');
const index = fs.fsReadJSON('/skills/index.json') || {};
delete index[name];
fs.fsWriteJSON('/skills/index.json', index);
@@ -1313,7 +1313,7 @@
if (!name) { alert('Skill name is required'); return; }
const fs = this.fs;
fs.mkdirRecursive('/skills');
- if (fs.fsRead(`/skills/${name}.md`)) {
+ if (fs.readFile(`/skills/${name}.md`)) {
alert(`Skill '${name}' already exists. Delete it first or use skill-patch command.`);
return;
}
@@ -1321,7 +1321,7 @@
if (!content.startsWith('---')) {
content = `---\nname: ${name}\ndescription: ${description}\ntags: [${tags.join(', ')}]\ncategory: general\n---\n${content}`;
}
- fs.fsWrite(`/skills/${name}.md`, content);
+ fs.writeFile(`/skills/${name}.md`, content);
const index = fs.fsReadJSON('/skills/index.json') || {};
index[name] = { name, description, category: 'general', tags };
fs.fsWriteJSON('/skills/index.json', index);
@@ -1346,14 +1346,26 @@
renderOllamaModels() {
const container = document.getElementById('ollama-models');
const select = document.getElementById('ollama-current-model');
+ const searchInput = document.getElementById('ollama-search');
+ const countDiv = document.getElementById('ollama-model-count');
+ const query = (searchInput ? searchInput.value : '').toLowerCase().trim();
container.innerHTML = '';
select.innerHTML = '<option value="">Select a model</option>';
const models = this.ollamaManager.getModels();
if (models.length === 0) {
container.innerHTML = '<div class="text-center" style="padding:20px; color:#666">Connect to see models</div>';
+ if (countDiv) countDiv.textContent = '';
return;
}
- models.forEach(model => {
+ const filtered = query ? models.filter(m => m.name.toLowerCase().includes(query)) : models;
+ if (countDiv) countDiv.textContent = filtered.length === models.length
+ ? models.length + ' model' + (models.length !== 1 ? 's' : '')
+ : filtered.length + ' / ' + models.length + ' model' + (models.length !== 1 ? 's' : '');
+ if (filtered.length === 0) {
+ container.innerHTML = '<div class="text-center" style="padding:20px; color:#888">No models match "' + query + '"</div>';
+ return;
+ }
+ filtered.forEach(model => {
const div = document.createElement('div');
div.className = 'model-item';
div.innerHTML = `<span>${model.name}</span><span style="font-size:0.8em; color:#666">${model.size ? (model.size / 1e9).toFixed(1) + 'GB' : ''}</span>`;