From 6d41e590a38c73ef60f1c04beaf8f5438f350f46 Mon Sep 17 00:00:00 2001 From: Agando Date: Tue, 2 Jun 2026 06:00:29 +0200 Subject: auto: 2026-06-02_06:00 changes --- modules/core/module-aiassist.js | 4 +- modules/core/module-fs.js | 28 ++-------- modules/core/module-loader.js | 8 +-- modules/core/module-system.js | 20 +++++++ modules/core/terminal.js | 117 ++++++++++++++++++++++++---------------- 5 files changed, 102 insertions(+), 75 deletions(-) (limited to 'modules/core') diff --git a/modules/core/module-aiassist.js b/modules/core/module-aiassist.js index f7be209..edc5225 100644 --- a/modules/core/module-aiassist.js +++ b/modules/core/module-aiassist.js @@ -568,7 +568,7 @@ RULES: (entry.error ? ' ⚠️' : '') + ''; } - panel.innerHTML = '
🔧 Tool Log ' + this._toolCallLog.length + ' calls
' + html; + panel.innerHTML = '
🔧 Tool Log ' + this._toolCallLog.length + ' calls✕
' + html; } _isToolError(result) { if (!result || typeof result !== 'string') return null; @@ -931,7 +931,7 @@ RULES: // Create the debug panel panel = document.createElement('div'); panel.id = 'debug-panel'; - panel.style.cssText = 'position:fixed;right:10px;bottom:50px;width:380px;max-height:400px;overflow-y:auto;background:#0a0a0a;border:1px solid #333;border-radius:6px;z-index:9999;font-family:monospace;font-size:0.78em;display:none;'; + panel.style.cssText = 'position:fixed;right:10px;top:50px;width:340px;max-height:350px;overflow-y:auto;background:#0a0a0a;border:1px solid #333;border-radius:6px;z-index:100;font-family:monospace;font-size:0.75em;display:none;'; document.body.appendChild(panel); // Add close button handler panel.addEventListener('click', function() { diff --git a/modules/core/module-fs.js b/modules/core/module-fs.js index ae8b5f4..da2e740 100644 --- a/modules/core/module-fs.js +++ b/modules/core/module-fs.js @@ -148,37 +148,17 @@ class FileSystemModule { }; this.commands['mv'] = (args) => { if(!args[0] || !args[1]) return this.terminal.print('Usage: mv ', 'warning'); - const srcDir = this.terminal.fs.readDir(args[0]); - if (srcDir !== null) { - if (this.terminal.fs.moveDir(args[0], args[1])) { - this.terminal.print('Moved directory: ' + args[0] + ' to ' + args[1], 'success'); - } else { - this.terminal.print('mv: ' + args[0] + ': failed to move directory', 'error'); - } - return; - } - if (this.terminal.fs.moveFile(args[0], args[1])) { + if (this.terminal.fs.mv(args[0], args[1])) this.terminal.print('Moved: ' + args[0] + ' to ' + args[1], 'success'); - } else { + else this.terminal.print('mv: ' + args[0] + ': No such file or directory', 'error'); - } }; this.commands['cp'] = (args) => { if(!args[0] || !args[1]) return this.terminal.print('Usage: cp ', 'warning'); - const srcDir = this.terminal.fs.readDir(args[0]); - if (srcDir !== null) { - if (this.terminal.fs.copyDir(args[0], args[1])) { - this.terminal.print('Copied directory: ' + args[0] + ' to ' + args[1], 'success'); - } else { - this.terminal.print('cp: ' + args[0] + ': failed to copy directory', 'error'); - } - return; - } - if (this.terminal.fs.copyFile(args[0], args[1])) { + if (this.terminal.fs.cp(args[0], args[1])) this.terminal.print('Copied: ' + args[0] + ' to ' + args[1], 'success'); - } else { + else this.terminal.print('cp: ' + args[0] + ': No such file or directory', 'error'); - } }; this.commands['cd'] = (args) => { if (!args[0] || args[0] === '/') { diff --git a/modules/core/module-loader.js b/modules/core/module-loader.js index 61bde20..7187fec 100644 --- a/modules/core/module-loader.js +++ b/modules/core/module-loader.js @@ -99,9 +99,11 @@ window.__moduleLoaderReload = reloadWithSelection; -const CACHE = '?v=' + (localStorage.getItem('webx11_cache_ver') || '2026-06-01-fix3'); - if (!localStorage.getItem('webx11_cache_ver')) { - localStorage.setItem('webx11_cache_ver', '2026-06-01-fix3'); +const LATEST_VER = '2026-06-02-fontfix3'; +const CACHE = '?v=' + LATEST_VER; + const stored = localStorage.getItem('webx11_cache_ver'); + if (stored !== LATEST_VER) { + localStorage.setItem('webx11_cache_ver', LATEST_VER); } async function init() { diff --git a/modules/core/module-system.js b/modules/core/module-system.js index beed699..e54a5fe 100644 --- a/modules/core/module-system.js +++ b/modules/core/module-system.js @@ -107,6 +107,26 @@ }; this.commands['health-check'] = () => this._healthCheck(); this.commands['memory-map-export'] = () => this._memoryMapExport(); + this.commands['font-size'] = (args) => { + if (!args.length || !args[0]) { + const cur = localStorage.getItem('webx11_font_size'); + this.terminal.print(`Current font-size: ${cur || '16'}px`, 'info'); + this.terminal.print('Usage: font-size <8-32>', 'info'); + return; + } + const val = parseInt(args[0], 10); + if (isNaN(val) || val < 8 || val > 32) { + this.terminal.print('font-size must be between 8 and 32', 'error'); + return; + } + localStorage.setItem('webx11_font_size', val.toString()); + // Apply directly to body — bypasses CSS inheritance issues + document.body.style.fontSize = val + 'px'; + document.getElementById('terminal-container').style.fontSize = val + 'px'; + document.getElementById('command-input').style.fontSize = val + 'px'; + this.terminal.print(`Font size set to ${val}px (saved) 👆`, 'success'); + }; + this.commands['setfont'] = this.commands['font-size']; } _autoRotateLogs(force = false) { try { diff --git a/modules/core/terminal.js b/modules/core/terminal.js index 607c51a..f0ef036 100644 --- a/modules/core/terminal.js +++ b/modules/core/terminal.js @@ -7,7 +7,7 @@ this.lastRouteTime = 0; this.lastRouteCmd = ''; this.blockedCount = 0; - this.destructiveCmds = new Set(['rm','delete','del','write','save','overwrite','format','kill','stop','shutdown','reboot']); + this.destructiveCmds = new Set(['delete','del','write','save','overwrite','format','kill','stop','shutdown','reboot']); this.systemCmds = new Set(['reboot','shutdown','format','kill','halt','poweroff']); this.suspiciousFlags = new Set(['--dump','--execute','--eval','--exec','--shell','--script']); this.whitelist = new Set(['help','clear','ls','cat','pwd','whoami','df','free','top','ps','echo','date','env','history']); @@ -374,8 +374,16 @@ } print(text, type = '') { const line = document.createElement('div'); - line.className = `output-line ${type}`; - line.textContent = text; + // Use card layout for typed messages (error/warning/info/success/text-muted), plain for bare text + const isTyped = ['error','warning','success'].includes(type); + if (isTyped) { + line.className = 'output-line msg-card system ' + type; + const safeText = String(text).replace(//g, ">"); + line.innerHTML = '
⚙ System
' + safeText + '
'; + } else { + line.className = 'output-line'; + line.textContent = text; + } this.outputContainer.appendChild(line); this._historyBuffer.push({ l: text, t: type }); if (this._historyBuffer.length > this._historyMaxLines) { @@ -411,7 +419,7 @@ const before = text.slice(lastIndex, match.index); if (before.trim()) { const safeBefore = before.replace(//g, ">"); - fragments.push({ type: 'text', html: `
${safeBefore}
` }); + fragments.push({ type: 'text', html: '
' + safeBefore + '
' }); } fragments.push({ type: 'render', html: this._renderHTMLPreview(match[1].trim()) }); lastIndex = match.index + match[0].length; @@ -419,7 +427,7 @@ const after = text.slice(lastIndex); if (after.trim()) { const safeAfter = after.replace(//g, ">"); - fragments.push({ type: 'text', html: `
${safeAfter}
` }); + fragments.push({ type: 'text', html: '
' + safeAfter + '
' }); } return fragments.length > 0 ? fragments : null; } @@ -427,23 +435,24 @@ this._flushStreamChunks(); const fragments = this._renderHTMLBlock(text); if (fragments) { + const wrapper = document.createElement('div'); + wrapper.className = 'output-line msg-card ai'; + wrapper.innerHTML = '
🤖 AI
'; + const body = wrapper.querySelector('.msg-card-body'); for (const frag of fragments) { - const wrapper = document.createElement('div'); - wrapper.className = 'output-line' + (frag.type === 'text' ? ' ollama' : ''); - wrapper.innerHTML = frag.html; - this.outputContainer.appendChild(wrapper); + const div = document.createElement('div'); + div.innerHTML = frag.html; + body.appendChild(div); } + this.outputContainer.appendChild(wrapper); this.scrollToBottom(); this._trimOutput(); return; } const wrapper = document.createElement('div'); - wrapper.className = 'output-line ollama'; + wrapper.className = 'output-line msg-card ai'; const safeText = text.replace(//g, ">"); - wrapper.innerHTML = ` - -
${safeText}
- `; + wrapper.innerHTML = '
🤖 AI
' + safeText + '
'; this.outputContainer.appendChild(wrapper); this.scrollToBottom(); this._trimOutput(); @@ -453,15 +462,12 @@ if (!append) { const safeText = text.replace(//g, ">"); const wrapper = document.createElement('div'); - wrapper.className = 'output-line ollama'; - wrapper.innerHTML = ` - -
${safeText}
- `; + wrapper.className = 'output-line msg-card ai'; + wrapper.innerHTML = '
🤖 AI
' + safeText + '
'; this.outputContainer.appendChild(wrapper); this._streamChunks = []; } else { - const contentDiv = this.outputContainer.querySelector('.output-line.ollama:last-child .ai-content'); + const contentDiv = this.outputContainer.querySelector('.msg-card.ai:last-child .msg-card-body'); if (contentDiv) { this._streamChunks.push(text); if (this._streamChunks.length >= 5) { @@ -477,7 +483,7 @@ this._trimOutput(); } _flushStreamChunks() { - const contentDiv = this.outputContainer.querySelector('.output-line.ollama:last-child .ai-content'); + const contentDiv = this.outputContainer.querySelector('.msg-card.ai:last-child .msg-card-body'); if (contentDiv && this._streamChunks && this._streamChunks.length > 0) { contentDiv.textContent += this._streamChunks.join(''); this._streamChunks = []; @@ -485,17 +491,13 @@ } printUserPrompt(rawInput) { const wrapper = document.createElement('div'); - wrapper.className = 'output-line user-prompt-line'; + wrapper.className = 'output-line msg-card user'; const safe = rawInput.replace(//g, '>'); const hasHtml = /<[a-z][\s\S]*>/i.test(rawInput.trim()); - const previewBtn = hasHtml ? `` : ''; - wrapper.innerHTML = ` - webx11@module:~$ - ${safe} - - ${previewBtn} - - `; + let buttons = ''; + if (hasHtml) buttons += ''; + buttons += ''; + wrapper.innerHTML = '
👤 User' + buttons + '
' + safe + '
'; this.outputContainer.appendChild(wrapper); this._historyBuffer.push({ l: rawInput, t: 'command-prompt' }); if (this._historyBuffer.length > this._historyMaxLines) this._historyBuffer.shift(); @@ -508,22 +510,37 @@ this.inputField.setSelectionRange(text.length, text.length); } copyToClipboard(btn) { - let text; - if (btn.classList.contains('user-copy-btn')) { - // User prompt: text is in .prompt-text sibling - const pSpan = btn.parentElement.querySelector('.prompt-text'); - if (pSpan) text = pSpan.textContent; + let text = ''; + const card = btn.closest('.msg-card'); + if (card) { + const cardBody = card.querySelector('.msg-card-body'); + if (cardBody) text = cardBody.textContent; } else { - // AI response: text is in next sibling .ai-content - const contentDiv = btn.nextElementSibling; - if (contentDiv) text = contentDiv.innerText; + const nd = btn.nextElementSibling; + if (nd) text = nd.innerText || nd.textContent; } if (!text) return; - navigator.clipboard.writeText(text).then(() => { - const originalText = btn.textContent; - btn.textContent = 'Copied!'; - setTimeout(() => { btn.textContent = originalText; }, 2000); - }).catch(err => { console.error('Failed to copy: ', err); }); + btn.textContent = 'Copied!'; + setTimeout(function(){ btn.textContent = 'Copy'; }, 2000); + // Use navigator.clipboard on secure contexts (iOS 14+, modern browsers). + // This is the preferred API — NOTHING blocks it on HTTPS pages. + if (navigator.clipboard) { + navigator.clipboard.writeText(text).catch(function(){}); + } + // Also try textarea+execCommand synchronously for older browsers. + // DO NOT wrap in setTimeout — iOS Safari requires execCommand to run + // in the same microtask as the user's click event. + try { + var ta = document.createElement('textarea'); + ta.value = text; + ta.style.cssText = 'position:fixed;left:10px;top:10px;width:200px;height:40px;font-size:16px;padding:4px;z-index:-1;opacity:0.01'; + document.body.appendChild(ta); + ta.focus(); + ta.select(); + ta.setSelectionRange(0, text.length); + document.execCommand('copy'); + document.body.removeChild(ta); + } catch(e) {} } printClickable(items) { const line = document.createElement('div'); @@ -1853,7 +1870,13 @@ const saved = localStorage.getItem('webx11_font_size'); if (saved) { const s = parseInt(saved); - if (s >= 8 && s <= 32) document.documentElement.style.fontSize = s + 'px'; + if (s >= 8 && s <= 32) { + document.body.style.fontSize = s + 'px'; + const tc = document.getElementById('terminal-container'); + if (tc) tc.style.fontSize = s + 'px'; + const inp = document.getElementById('command-input'); + if (inp) inp.style.fontSize = s + 'px'; + } } } catch (e) {} } @@ -2004,8 +2027,10 @@ this.print('Usage: font-size <8-32>', 'warning'); return; } - document.documentElement.style.fontSize = s + 'px'; + document.body.style.fontSize = s + 'px'; + document.getElementById('terminal-container').style.fontSize = s + 'px'; + document.getElementById('command-input').style.fontSize = s + 'px'; try { localStorage.setItem('webx11_font_size', String(s)); } catch (e) {} - this.print('Font size set to ' + s + 'px', 'success'); + this.print('Font size set to ' + s + 'px 👆', 'success'); } } -- cgit v1.2.3