⚡ TSC-AI Build
",
'index.html': 'Vue App',
},
};
const tmplFiles = templates[tmpl] || templates.react;
if (tmplFiles) {
files = JSON.parse(JSON.stringify(tmplFiles));
openFiles = [];
renderFileTree();
const firstFile = Object.keys(files)[0];
if (firstFile) openFile(firstFile);
}
}
// === Run Code ===
async function runCode() {
saveCurrentFile();
const box = document.getElementById('output-box');
box.style.display = 'block';
box.innerHTML = ' Running...';
try {
const pkg = files['package.json'];
const mainFile = pkg ? JSON.parse(pkg).main || Object.keys(files).find(f => f.endsWith('.js') && !f.includes('node_modules')) : Object.keys(files).find(f => f.endsWith('.js'));
const r = await fetch(API + '/api/terminal/exec', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command: 'node -e ' + JSON.stringify(files[mainFile] || files[Object.keys(files).find(f => f.endsWith('.js'))]) })
});
const data = await r.json();
box.innerHTML = '$ node ' + (mainFile || 'script') + '\n' + escapeHtml(data.output);
} catch(e) {
box.innerHTML = 'Error: ' + e.message;
}
}
function clearOutput() {
document.getElementById('output-box').style.display = 'none';
document.getElementById('output-box').innerHTML = '';
}
// === Terminal ===
function initTerminal() {
const termEl = document.getElementById('terminal');
term = new Terminal({ theme: { background: '#0a0a0f', foreground: '#4ade80', cursor: '#4ade80' }, fontSize: 13, cursorBlink: true });
fitAddon = new FitAddon.FitAddon();
term.loadAddon(fitAddon);
term.open(termEl);
fitAddon.fit();
let cmdBuffer = '';
term.write('$ ');
term.onData(data => {
if (data === '\r') {
term.write('\r\n');
if (cmdBuffer.trim()) {
fetch(API + '/api/terminal/exec', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command: cmdBuffer })
}).then(r => r.json()).then(res => {
term.writeln(res.output || ' ');
term.write('$ ');
});
} else {
term.write('$ ');
}
cmdBuffer = '';
} else if (data === '\x7f') {
if (cmdBuffer.length > 0) { cmdBuffer = cmdBuffer.slice(0, -1); term.write('\b \b'); }
} else {
cmdBuffer += data;
term.write(data);
}
});
}
// === AI Chat ===
async function sendChat() {
const input = document.getElementById('chat-input');
const msg = input.value.trim();
if (!msg) return;
input.value = '';
const box = document.getElementById('chat-msgs');
box.innerHTML += 'You
' + escapeHtml(msg) + '
';
box.scrollTop = box.scrollHeight;
box.innerHTML += '';
try {
const r = await fetch(API + '/api/chat', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: msg + '\n\nContext - current file: ' + (activeFile || 'none') + '\n```\n' + (editor ? editor.getValue() : '') + '\n```' })
});
const data = await r.json();
const lastMsg = box.querySelector('.chat-msg:last-child');
if (lastMsg) lastMsg.innerHTML = 'Assistant
' + escapeHtml(data.response);
} catch(e) {
const lastMsg = box.querySelector('.chat-msg:last-child');
if (lastMsg) lastMsg.innerHTML = 'Assistant
Error: ' + e.message;
}
box.scrollTop = box.scrollHeight;
}
function escapeHtml(s) {
const d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
// === Init ===
window.addEventListener('resize', () => { if (fitAddon) fitAddon.fit(); });
initTerminal();