class ArgumentBuilder { constructor() { this.arguments = []; this.container = document.getElementById('arguments-container'); this.headerInput = document.getElementById('custom-header'); this.generateBtn = document.getElementById('generate-btn'); this.helpContent = document.getElementById('help-content'); this.outputSection = document.getElementById('output-section'); this.generatedCode = document.getElementById('generated-code'); this.copyBtn = document.getElementById('copy-btn'); this.init(); } init() { // Add initial empty row this.addArgumentRow(); // Event listeners this.generateBtn.addEventListener('click', () => this.generateScript()); this.headerInput.addEventListener('input', () => this.updateHelpPreview()); this.copyBtn.addEventListener('click', () => this.copyToClipboard()); // Update help preview initially this.updateHelpPreview(); } addArgumentRow(params = '', command = '', helpText = '') { const row = document.createElement('div'); row.className = 'argument-row'; const paramsInput = document.createElement('input'); paramsInput.type = 'text'; paramsInput.placeholder = '-v --verbose'; paramsInput.value = params; const commandInput = document.createElement('input'); commandInput.type = 'text'; commandInput.placeholder = 'verbose'; commandInput.value = command; const helpTextInput = document.createElement('input'); helpTextInput.type = 'text'; helpTextInput.placeholder = 'Enable verbose output'; helpTextInput.value = helpText; const removeBtn = document.createElement('button'); removeBtn.className = 'remove-btn'; removeBtn.innerHTML = '×'; removeBtn.addEventListener('click', () => { row.remove(); this.updateHelpPreview(); }); // Add input event listeners for real-time updates const updatePreview = () => { this.updateHelpPreview(); // Add new empty row if this is the last row and has content const rows = this.container.querySelectorAll('.argument-row'); const isLastRow = rows[rows.length - 1] === row; const hasContent = commandInput.value.trim() !== ''; if (isLastRow && hasContent) { this.addArgumentRow(); } }; paramsInput.addEventListener('input', updatePreview); commandInput.addEventListener('input', updatePreview); helpTextInput.addEventListener('input', updatePreview); row.appendChild(paramsInput); row.appendChild(commandInput); row.appendChild(helpTextInput); row.appendChild(removeBtn); this.container.appendChild(row); } getArguments() { const rows = this.container.querySelectorAll('.argument-row'); const args = []; rows.forEach(row => { const inputs = row.querySelectorAll('input'); const params = inputs[0].value.trim(); const command = inputs[1].value.trim(); const helpText = inputs[2].value.trim(); if (command) { args.push({ params: params || command, command: command, helpText: helpText || command }); } }); return args; } addSubcommand(name = '', description = '') { const subcommandSection = document.createElement('div'); subcommandSection.className = 'subcommand-section'; const header = this.createSubcommandHeader(name, description); const argsContainer = this.createArgumentsContainer(); subcommandSection.appendChild(header); subcommandSection.appendChild(argsContainer); this.subcommandContainer.appendChild(subcommandSection); return subcommandSection; } updateHelpPreview() { const header = this.headerInput.value.trim(); const args = this.getArguments(); if (args.length === 0) { this.helpContent.textContent = 'Add arguments to see the help output...'; return; } let helpText = ''; if (header) { helpText += header + '\n\n'; } helpText += 'Usage: script.sh [OPTIONS]\n\n'; helpText += 'Options:\n'; args.forEach(arg => { const params = arg.params || arg.command; const help = arg.helpText || arg.command; helpText += ` ${params.padEnd(20)} ${help}\n`; }); helpText += ` ${'-h --help'.padEnd(20)} Show this help message\n`; this.helpContent.textContent = helpText; } createSubcommandHeader(name, description) { const header = document.createElement('div'); header.className = 'subcommand-header'; header.innerHTML = ` `; return header; } getSubcommands() { const sections = this.subcommandContainer.querySelectorAll('.subcommand-section'); return Array.from(sections).map(section => { const nameInput = section.querySelector('.subcommand-name'); const descInput = section.querySelector('.subcommand-desc'); const args = this.getArgumentsFromSection(section); return { name: nameInput.value.trim(), description: descInput.value.trim(), arguments: args }; }).filter(sc => sc.name); } async generateScript() { const header = this.headerInput.value.trim(); const args = this.getArguments(); if (args.length === 0) { alert('Please add at least one argument'); return; } const payload = { header: this.headerInput.value.trim(), arguments: this.getArguments(), subcommands: this.getSubcommands() }; try { const response = await fetch('/generate', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); if (!response.ok) { throw new Error('Failed to generate script'); } const scriptCode = await response.text(); this.generatedCode.textContent = scriptCode; this.outputSection.style.display = 'block'; // Smooth scroll to output this.outputSection.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); } catch (error) { alert('Error generating script: ' + error.message); } } async copyToClipboard() { const code = this.generatedCode.textContent; try { await navigator.clipboard.writeText(code); this.copyBtn.textContent = 'Copied!'; this.copyBtn.classList.add('copied'); setTimeout(() => { this.copyBtn.textContent = 'Copy'; this.copyBtn.classList.remove('copied'); }, 2000); } catch (error) { alert('Failed to copy to clipboard'); } } } // Initialize the application when DOM is ready document.addEventListener('DOMContentLoaded', () => { new ArgumentBuilder(); });