# Web Terminal Integration for Z3ed This document describes how to integrate the z3ed terminal functionality into the WASM web build. ## Overview The `wasm_terminal_bridge.cc` file provides C++ functions that can be called from JavaScript to enable z3ed command processing in the browser. This allows users to interact with ROM data and use AI-powered features directly in the web interface. ## Exported Functions ### Core Functions ```javascript // Process a z3ed command const char* Z3edProcessCommand(const char* command); // Get command completions for autocomplete const char* Z3edGetCompletions(const char* partial); // Set API key for AI services (Gemini) void Z3edSetApiKey(const char* api_key); // Check if terminal bridge is ready int Z3edIsReady(); // Load ROM data from ArrayBuffer int Z3edLoadRomData(const uint8_t* data, size_t size); // Get current ROM information as JSON const char* Z3edGetRomInfo(); // Execute resource queries const char* Z3edQueryResource(const char* query); ``` ## JavaScript Integration Example ```javascript // Initialize the terminal when module is ready Module.onRuntimeInitialized = function() { // Check if terminal is ready if (Module.ccall('Z3edIsReady', 'number', [], [])) { console.log('Z3ed terminal ready'); } // Set API key for AI features const apiKey = localStorage.getItem('gemini_api_key'); if (apiKey) { Module.ccall('Z3edSetApiKey', null, ['string'], [apiKey]); } // Create terminal interface const terminal = new Terminal({ prompt: 'z3ed> ', onCommand: (cmd) => { const result = Module.ccall('Z3edProcessCommand', 'string', ['string'], [cmd]); terminal.print(result); }, onTab: (partial) => { const completions = Module.ccall('Z3edGetCompletions', 'string', ['string'], [partial]); return JSON.parse(completions); } }); // Expose terminal globally window.z3edTerminal = terminal; }; // Load ROM file async function loadRomFile(file) { const arrayBuffer = await file.arrayBuffer(); const data = new Uint8Array(arrayBuffer); // Allocate memory in WASM heap const ptr = Module._malloc(data.length); Module.HEAPU8.set(data, ptr); // Load ROM const success = Module.ccall('Z3edLoadRomData', 'number', ['number', 'number'], [ptr, data.length]); // Free memory Module._free(ptr); if (success) { // Get ROM info const info = Module.ccall('Z3edGetRomInfo', 'string', [], []); console.log('ROM loaded:', JSON.parse(info)); } } ``` ## Terminal UI Component ```javascript class Z3edTerminal { constructor(containerId) { this.container = document.getElementById(containerId); this.history = []; this.historyIndex = 0; this.setupUI(); } setupUI() { this.container.innerHTML = `
z3ed>
`; this.output = this.container.querySelector('.terminal-output'); this.input = this.container.querySelector('.command-input'); this.input.addEventListener('keydown', (e) => this.handleKeydown(e)); } handleKeydown(e) { if (e.key === 'Enter') { this.executeCommand(this.input.value); this.history.push(this.input.value); this.historyIndex = this.history.length; this.input.value = ''; } else if (e.key === 'Tab') { e.preventDefault(); this.handleAutocomplete(); } else if (e.key === 'ArrowUp') { this.navigateHistory(-1); } else if (e.key === 'ArrowDown') { this.navigateHistory(1); } } executeCommand(cmd) { this.print(`z3ed> ${cmd}`, 'command'); if (!Module.ccall) { this.printError('WASM module not loaded'); return; } try { const result = Module.ccall('Z3edProcessCommand', 'string', ['string'], [cmd]); this.print(result); } catch (error) { this.printError(`Error: ${error.message}`); } } handleAutocomplete() { const partial = this.input.value; const completions = Module.ccall('Z3edGetCompletions', 'string', ['string'], [partial]); const options = JSON.parse(completions); if (options.length === 1) { this.input.value = options[0]; } else if (options.length > 1) { this.print(`Available commands: ${options.join(', ')}`); } } navigateHistory(direction) { this.historyIndex = Math.max(0, Math.min(this.history.length, this.historyIndex + direction)); this.input.value = this.history[this.historyIndex] || ''; } print(text, className = 'output') { const line = document.createElement('div'); line.className = className; line.textContent = text; this.output.appendChild(line); this.output.scrollTop = this.output.scrollHeight; } printError(text) { this.print(text, 'error'); } clear() { this.output.innerHTML = ''; } } ``` ## Available Commands The WASM build includes a subset of z3ed commands that don't require native dependencies: ### Basic Commands - `help` - Show available commands - `help ` - Show commands in a category - `clear` - Clear terminal output - `version` - Show version information ### ROM Commands - `rom load ` - Load ROM from file - `rom info` - Display ROM information - `rom validate` - Validate ROM structure ### Resource Queries - `resource query dungeon.rooms` - List dungeon rooms - `resource query overworld.maps` - List overworld maps - `resource query graphics.sheets` - List graphics sheets - `resource query palettes` - List palettes ### AI Commands (requires API key) - `ai ` - Generate AI response - `ai analyze ` - Analyze ROM resource - `ai suggest ` - Get suggestions ### Graphics Commands - `gfx list` - List graphics resources - `gfx export ` - Export graphics (returns base64) ## Build Configuration The WASM terminal bridge is automatically included when building with Emscripten: ```bash # Configure for WASM with AI support cmake --preset wasm-ai # Build cmake --build build --target yaze # The resulting files will be: # - yaze.js (JavaScript loader) # - yaze.wasm (WebAssembly module) # - yaze.html (Example HTML page) ``` ## Security Considerations 1. **API Keys**: Store API keys in sessionStorage or localStorage, never hardcode them 2. **ROM Data**: ROM data stays in browser memory, never sent to servers 3. **CORS**: AI API requests go through browser fetch, respecting CORS policies 4. **Sandboxing**: WASM runs in browser sandbox with limited filesystem access ## Troubleshooting ### Module not loading - Ensure WASM files are served with correct MIME type: `application/wasm` - Check browser console for CORS errors - Verify SharedArrayBuffer support if using threads ### Commands not working - Check if ROM is loaded: `Z3edGetRomInfo()` - Verify terminal is ready: `Z3edIsReady()` - Check browser console for error messages ### AI features not working - Ensure API key is set: `Z3edSetApiKey()` - Check network tab for API request failures - Verify Gemini API quota and limits