From b562e1491513163921593985f3542d4ee8ae0e75 Mon Sep 17 00:00:00 2001 From: Agando Date: Mon, 8 Jun 2026 18:01:06 +0200 Subject: auto: 2026-06-08_18:00 changes --- modules/ext/alias.js | 26 +++- modules/ext/floating.js | 331 +++++++++++++++++++++++++++++++++++++++++ modules/ext/shell.js | 2 + modules/ext/skill-pack-core.js | 36 ++++- 4 files changed, 386 insertions(+), 9 deletions(-) create mode 100644 modules/ext/floating.js (limited to 'modules/ext') diff --git a/modules/ext/alias.js b/modules/ext/alias.js index 80663ac..06a5d47 100644 --- a/modules/ext/alias.js +++ b/modules/ext/alias.js @@ -3,8 +3,10 @@ class AliasModule { this.commands = {}; this.terminal = null; this.key = 'webx11_aliases'; - this.defaults = { 'll': 'ls', 'h': 'help', 'cls': 'clear' }; + this.defaults = { 'll': 'ls', 'h': 'help', 'cls': 'clear', 'sh': 'script' }; this.aliases = this.load(); + this._aliasDepth = 0; + this._aliasMaxDepth = 10; } getHelpInfo() { @@ -37,7 +39,10 @@ class AliasModule { if (name === 'alias' || name === 'unalias') return; const target = this.aliases[name]; this.commands[name] = (args) => { - this.terminal.executeCommand(target + (args.length ? ' ' + args.join(' ') : '')); + if (this._aliasDepth >= this._aliasMaxDepth) { this.terminal.print(`alias: max depth (${this._aliasMaxDepth}) reached`, 'error'); return; } + this._aliasDepth++; + try { this.terminal.executeCommand(target + (args.length ? ' ' + args.join(' ') : '')); } + finally { this._aliasDepth--; } }; }); } @@ -64,7 +69,8 @@ class AliasModule { // Show specific alias value const name = args[0]; if (this.aliases[name]) { - this.terminal.print(`${name}=${this.aliases[name]}`, 'info'); + const mark = this.defaults[name] ? ' (built-in)' : ''; + this.terminal.print(`${name}=${this.aliases[name]}${mark}`, 'info'); } else { this.terminal.print(`Alias '${name}' not found`, 'error'); } @@ -77,15 +83,19 @@ class AliasModule { if (name === 'alias' || name === 'unalias') { return this.terminal.print('Cannot alias reserved command name', 'error'); } + if (this.defaults[name]) { + return this.terminal.print(`Cannot alias built-in alias '${name}'`, 'warning'); + } this.aliases[name] = value; this.save(); // Register the new alias as a command immediately - if (!this.defaults[name]) { - const target = value; - this.commands[name] = (args) => { - this.terminal.executeCommand(target + (args.length ? ' ' + args.join(' ') : '')); + const target = value; + this.commands[name] = (args) => { + if (this._aliasDepth >= this._aliasMaxDepth) { this.terminal.print(`alias: max depth (${this._aliasMaxDepth}) reached`, 'error'); return; } + this._aliasDepth++; + try { this.terminal.executeCommand(target + (args.length ? ' ' + args.join(' ') : '')); } + finally { this._aliasDepth--; } }; - } this.terminal.print(`Alias set: ${name}=${value}`, 'success'); } handleUnalias(args) { diff --git a/modules/ext/floating.js b/modules/ext/floating.js new file mode 100644 index 0000000..b6f5a93 --- /dev/null +++ b/modules/ext/floating.js @@ -0,0 +1,331 @@ +// FloatingModule — Remixable floating UI elements (buttons, menus, panels) +// Persisted in localStorage. Created/modified/removed via terminal commands. +// Accessible to AI via normal run_command path. + +class FloatingModule { + constructor() { + this.commands = {}; + this.terminal = null; + this._elements = {}; + this._storageKey = 'webx11_floating_elements'; + } + + requirements() { return { met: true, missing: [] }; } + + getHelpInfo() { + return { + 'floating-add': 'floating-add btn|menu|panel