class AliasModule { constructor() { this.commands = {}; this.terminal = null; this.key = 'webx11_aliases'; this.defaults = { 'll': 'ls', 'h': 'help', 'cls': 'clear' }; this.aliases = this.load(); } getHelpInfo() { return { 'alias': 'List, set, or show aliases (usage: alias [name=value])', 'unalias': 'Remove a user-defined alias (usage: unalias )', }; } load() { try { const data = localStorage.getItem(this.key); return data ? { ...this.defaults, ...JSON.parse(data) } : { ...this.defaults }; } catch (e) { return { ...this.defaults }; } } save() { const custom = {}; Object.keys(this.aliases).forEach(k => { if (!this.defaults[k]) custom[k] = this.aliases[k]; }); localStorage.setItem(this.key, JSON.stringify(custom)); } registerCommands() { const self = this; // Register management commands this.commands['alias'] = (args) => self.handleAlias(args); this.commands['unalias'] = (args) => self.handleUnalias(args); // Register each alias as a delegating command Object.keys(this.aliases).forEach(name => { if (name === 'alias' || name === 'unalias') return; const target = this.aliases[name]; this.commands[name] = (args) => { this.terminal.executeCommand(target + (args.length ? ' ' + args.join(' ') : '')); }; }); } handleAlias(args) { if (!args[0]) { // List all aliases this.terminal.print('=== Aliases ===', 'info'); const keys = Object.keys(this.aliases); if (keys.length === 0) { this.terminal.print(' No aliases defined', 'warning'); } else { keys.forEach(name => { const mark = this.defaults[name] ? ' (built-in)' : ''; this.terminal.print(` ${name}=${this.aliases[name]}${mark}`); }); } this.terminal.print('Usage: alias <name>=<value>', 'info'); return; } // Parse name=value const input = args.join(' '); const eqIdx = input.indexOf('='); if (eqIdx === -1) { // Show specific alias value const name = args[0]; if (this.aliases[name]) { this.terminal.print(`${name}=${this.aliases[name]}`, 'info'); } else { this.terminal.print(`Alias '${name}' not found`, 'error'); } return; } const name = input.substring(0, eqIdx).trim(); const value = input.substring(eqIdx + 1).trim(); if (!name) return this.terminal.print('Invalid alias name', 'error'); if (!value) return this.terminal.print('Invalid alias value', 'error'); if (name === 'alias' || name === 'unalias') { return this.terminal.print('Cannot alias reserved command name', 'error'); } 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(' ') : '')); }; } this.terminal.print(`Alias set: ${name}=${value}`, 'success'); } handleUnalias(args) { if (!args[0]) return this.terminal.print('Usage: unalias <name>', 'warning'); const name = args[0]; if (this.defaults[name]) { return this.terminal.print(`Cannot unalias built-in alias '${name}'`, 'warning'); } if (!this.aliases[name]) { return this.terminal.print(`Alias '${name}' not found`, 'error'); } delete this.aliases[name]; delete this.commands[name]; this.save(); this.terminal.print(`Alias removed: ${name}`, 'success'); } } if (typeof window.webx11 !== 'undefined' && window.webx11) { webx11.moduleManager.registerModule(new AliasModule(), 'https://webx11.duckdns.org/spaces/newos4/modules/ext/alias.js'); }