Nico 3a9c2795cf v0.15.2: ES6 module refactor, 2-row layout, dashboard test, PA routing fix
Frontend refactored to ES6 modules (no bundler):
  js/main.js    — entry point, wires all modules
  js/auth.js    — OIDC login, token management
  js/ws.js      — /ws, /ws/test, /ws/trace connections + HUD handler
  js/chat.js    — messages, send, streaming
  js/graph.js   — Cytoscape visualization + animation
  js/trace.js   — trace panel
  js/dashboard.js — workspace controls rendering
  js/awareness.js — state panel, sensors, meters
  js/tests.js   — test status display
  js/util.js    — shared utilities

New 2-row layout:
  Top:    test status | connection status
  Middle: Workspace | Node Details | Graph
  Bottom: Chat | Awareness | Trace

PA routing: routes ALL tool requests to expert (DB, UI, buttons, machines)
Dashboard integration test: 15/15

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:58:47 +02:00

35 lines
1.0 KiB
JavaScript

/** Shared utility functions. */
export function scroll(el) { el.scrollTop = el.scrollHeight; }
export function esc(s) {
const d = document.createElement('span');
d.textContent = s;
return d.innerHTML;
}
export function truncate(s, n) {
return s.length > n ? s.slice(0, n) + '\u2026' : s;
}
export function renderMarkdown(text) {
let html = esc(text);
// Code blocks
html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) =>
'<pre class="md-code"><code>' + code.trim() + '</code></pre>');
// Inline code
html = html.replace(/`([^`]+)`/g, '<code class="md-inline">$1</code>');
// Bold
html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
// Italic
html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
// Bullet lists
html = html.replace(/^[\*\-]\s+(.+)$/gm, '<li>$1</li>');
html = html.replace(/(<li>.*<\/li>\n?)+/g, m => '<ul>' + m + '</ul>');
// Numbered lists
html = html.replace(/^\d+\.\s+(.+)$/gm, '<li>$1</li>');
// Line breaks (but not inside pre/code)
html = html.replace(/\n/g, '<br>');
return html;
}