diff --git a/diagnostic/index.html b/diagnostic/index.html
index 94c3490..fc3811b 100644
--- a/diagnostic/index.html
+++ b/diagnostic/index.html
@@ -153,7 +153,7 @@
@@ -347,6 +377,10 @@
el.textContent = msg.error ? `Fehler: ${msg.error}` : msg.info;
return;
}
+ // Live SSH + Desktop
+ if (msg.type?.startsWith('live_ssh_')) { handleLiveSSH(msg); return; }
+ if (msg.type === 'desktop_status') { handleDesktop(msg); return; }
+
if (msg.type === 'term_ready') {
document.getElementById('term-status').textContent = 'Verbunden — interaktives Terminal';
if (term) term.writeln('\x1b[32mVerbunden!\x1b[0m\r\n');
@@ -646,6 +680,120 @@
if (e.key === 'Enter') testGateway();
});
+ // ── ARIA Live-Ansicht (SSH + Desktop) ──────────────────
+
+ let liveSshTerm = null;
+ let liveSshFit = null;
+
+ function switchLiveTab(tab) {
+ document.getElementById('live-ssh').style.display = tab === 'ssh' ? 'block' : 'none';
+ document.getElementById('live-desktop').style.display = tab === 'desktop' ? 'block' : 'none';
+ document.getElementById('live-tab-ssh').className = 'tab-btn' + (tab === 'ssh' ? ' active' : '');
+ document.getElementById('live-tab-desktop').className = 'tab-btn' + (tab === 'desktop' ? ' active' : '');
+ if (tab === 'ssh' && liveSshTerm && liveSshFit) {
+ setTimeout(() => liveSshFit.fit(), 50);
+ }
+ }
+
+ function startLiveSSH() {
+ const statusEl = document.getElementById('live-ssh-status');
+ const btn = document.getElementById('btn-live-ssh');
+
+ // Wenn schon verbunden, trennen
+ if (liveSshTerm && liveSshTerm._sshConnected) {
+ send({ action: 'live_ssh_close' });
+ statusEl.textContent = 'Getrennt';
+ statusEl.style.color = '#FF6B6B';
+ btn.textContent = 'Verbinden';
+ liveSshTerm._sshConnected = false;
+ return;
+ }
+
+ statusEl.textContent = 'Verbinde...';
+ statusEl.style.color = '#FFD60A';
+
+ function initSSHTerm() {
+ const container = document.getElementById('live-ssh-term');
+ if (!liveSshTerm) {
+ liveSshTerm = new Terminal({
+ theme: { background: '#080810', foreground: '#E0E0F0', cursor: '#0096FF' },
+ fontFamily: 'Courier New, monospace',
+ fontSize: 12,
+ cursorBlink: true,
+ });
+ liveSshFit = new FitAddon.FitAddon();
+ liveSshTerm.loadAddon(liveSshFit);
+ liveSshTerm.open(container);
+ liveSshFit.fit();
+ liveSshTerm.onData((data) => {
+ send({ action: 'live_ssh_input', data });
+ });
+ }
+ liveSshTerm.clear();
+ send({ action: 'live_ssh_start' });
+ }
+
+ if (typeof Terminal === 'undefined') {
+ const s = document.createElement('script');
+ s.src = 'https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.min.js';
+ s.onload = () => {
+ const s2 = document.createElement('script');
+ s2.src = 'https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.min.js';
+ s2.onload = () => initSSHTerm();
+ document.head.appendChild(s2);
+ };
+ document.head.appendChild(s);
+ } else {
+ initSSHTerm();
+ }
+ }
+
+ function handleLiveSSH(msg) {
+ const statusEl = document.getElementById('live-ssh-status');
+ const btn = document.getElementById('btn-live-ssh');
+ if (msg.type === 'live_ssh_data' && liveSshTerm) {
+ const raw = atob(msg.data);
+ const bytes = new Uint8Array(raw.length);
+ for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
+ liveSshTerm.write(bytes);
+ } else if (msg.type === 'live_ssh_connected') {
+ statusEl.textContent = 'Verbunden mit aria-wohnung';
+ statusEl.style.color = '#34C759';
+ btn.textContent = 'Trennen';
+ if (liveSshTerm) liveSshTerm._sshConnected = true;
+ } else if (msg.type === 'live_ssh_error') {
+ statusEl.textContent = msg.error || 'Fehler';
+ statusEl.style.color = '#FF6B6B';
+ btn.textContent = 'Verbinden';
+ if (liveSshTerm) liveSshTerm._sshConnected = false;
+ } else if (msg.type === 'live_ssh_closed') {
+ statusEl.textContent = 'Getrennt';
+ statusEl.style.color = '#8888AA';
+ btn.textContent = 'Verbinden';
+ if (liveSshTerm) liveSshTerm._sshConnected = false;
+ }
+ }
+
+ function checkDesktop() {
+ send({ action: 'check_desktop' });
+ }
+
+ function handleDesktop(msg) {
+ if (msg.type === 'desktop_status') {
+ const placeholder = document.getElementById('desktop-placeholder');
+ const vnc = document.getElementById('desktop-vnc');
+ if (msg.available && msg.url) {
+ placeholder.style.display = 'none';
+ vnc.style.display = 'block';
+ vnc.src = msg.url;
+ } else {
+ placeholder.style.display = 'flex';
+ vnc.style.display = 'none';
+ placeholder.querySelector('div:nth-child(2)').textContent = msg.message || 'Kein Desktop verfuegbar';
+ }
+ }
+ }
+
connectWS();