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();
});