Something went wrong. Try again.
I'm going to build my own OpenClaw, with blackjack... and bun!
Something went wrong. Try again.
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151<!DOCTYPE html><html lang="en"><!-- index.html – Main web UI shell for PiClaw.
Single-page app entry point that loads the Preact-based timeline, compose box, workspace explorer, and status components. Also loads vendor libraries (marked, KaTeX, Mermaid) for markdown rendering.
Served by: channels/web/http/static.ts at the root URL. Auth: This page is only served to authenticated users. The login page (login.html) is a separate entrypoint that loads login.bundle.js.
Bundles: ──────── The authenticated SPA is shipped as app bundles: - /static/dist/app.bundle.js - /static/dist/app.bundle.css Login is a separate minimal bundle set: - /static/dist/login.bundle.js (loaded only by login.html) - /static/dist/login.bundle.css (loaded only by login.html)
Vendor JS globals (marked, KaTeX, Mermaid) remain separate prebuilt files. App/login CSS is bundled into /static/dist/*.bundle.css. request-router-service.ts auth-gates /static/dist/app.bundle.{js,css} and only exposes /static/dist/login.bundle.{js,css} to unauthenticated visitors.--><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"> <meta id="dynamic-theme-color" name="theme-color" content="#ffffff"> <meta id="theme-color-light" name="theme-color" media="(prefers-color-scheme: light)" content="#ffffff"> <meta id="theme-color-dark" name="theme-color" media="(prefers-color-scheme: dark)" content="#000000"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> <title>PiClaw</title> <meta name="apple-mobile-web-app-title" content="PiClaw"> <link rel="stylesheet" href="/static/dist/app.bundle.css?v=__APP_ASSET_VERSION__"> <link rel="manifest" href="/manifest.json?v=__APP_ASSET_VERSION__"> <link id="dynamic-favicon" rel="icon" href="/favicon.ico" data-default="/favicon.ico"> <link rel="icon" type="image/png" sizes="192x192" href="/static/icon-192.png"> <link rel="icon" type="image/png" sizes="512x512" href="/static/icon-512.png"> <link rel="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png"> <link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167x167.png"> <link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png"> <link rel="apple-touch-icon" sizes="192x192" href="/static/icon-192.png"> <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-precomposed.png"> <script> // Early theme application — prevents white flash on navigation. // Reads per-chat or global theme from localStorage and sets // data-theme + background color before first paint. (function() { try { var chatJid = 'web:default'; try { var p = new URLSearchParams(location.search); var raw = p.get('chat_jid'); if (raw && raw.trim()) chatJid = raw.trim(); } catch(e) {}
var theme = 'default', tint = null;
// Try per-chat override first try { var chatThemes = JSON.parse(localStorage.getItem('piclaw_chat_themes') || '{}'); if (chatThemes[chatJid]) { theme = chatThemes[chatJid].theme || 'default'; tint = chatThemes[chatJid].tint || null; } } catch(e) {}
// Fall back to global if (theme === 'default' && !tint) { theme = localStorage.getItem('piclaw_theme') || 'default'; tint = localStorage.getItem('piclaw_tint') || null; }
// Resolve mode: dark presets get dark, auto follows system var darkPresets = ['xterm','monokai','monokai-pro','ristretto','dracula','catppuccin','nord','gruvbox','tokyo','miasma','gotham']; var autoPresets = ['default','solarized','github']; var mode; if (darkPresets.indexOf(theme) >= 0) { mode = 'dark'; } else if (autoPresets.indexOf(theme) >= 0) { mode = (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light'; } else { mode = 'light'; }
var root = document.documentElement; root.dataset.theme = mode; root.dataset.colorTheme = theme; root.style.colorScheme = mode;
// Set background immediately to prevent white flash var bg = mode === 'dark' ? '#000000' : '#ffffff'; if (theme === 'dracula') bg = '#282a36'; else if (theme === 'catppuccin') bg = '#1e1e2e'; else if (theme === 'nord') bg = '#2e3440'; else if (theme === 'gruvbox') bg = '#282828'; else if (theme === 'tokyo') bg = '#1a1b26'; else if (theme === 'monokai') bg = '#272822'; else if (theme === 'monokai-pro') bg = '#2d2a2e'; else if (theme === 'ristretto') bg = '#2c2525'; else if (theme === 'miasma') bg = '#1f1f23'; else if (theme === 'gotham') bg = '#0b0f14'; else if (theme === 'xterm') bg = '#000000'; else if (theme === 'solarized' && mode === 'dark') bg = '#002b36'; else if (theme === 'solarized' && mode === 'light') bg = '#fdf6e3'; else if (theme === 'github' && mode === 'dark') bg = '#0d1117'; else if (theme === 'tango') bg = '#f6f5f4'; root.style.background = bg; document.body && (document.body.style.background = bg);
// Update theme-color meta tags for the status bar var meta = document.getElementById('dynamic-theme-color'); if (meta) meta.setAttribute('content', bg); var darkMeta = document.getElementById('theme-color-dark'); if (darkMeta) darkMeta.setAttribute('content', bg); } catch(e) {} })(); </script></head><body> <div id="app"> <div style="padding: 20px; text-align: center; color: var(--text-secondary, #888);">Loading...</div> </div> <script> window.onerror = function(msg, url, line, col, error) { var text = String((error && error.message) || msg || ''); if (/ResizeObserver loop (completed with undelivered notifications|limit exceeded)/i.test(text)) { return true; } document.getElementById('app').innerHTML = '<pre style="padding:20px;color:red;">Error: ' + msg + '\nLine: ' + line + '</pre>'; return false; }; </script> <script src="/static/js/marked.min.js"></script> <script src="/static/js/vendor/katex.min.js"></script> <script src="/static/js/vendor/beautiful-mermaid.js"></script> <script type="module" src="/static/dist/app.bundle.js?v=__APP_ASSET_VERSION__"></script> <script type="module"> // Fallback error display for module errors import('/static/dist/app.bundle.js?v=__APP_ASSET_VERSION__').catch(function(e) { document.getElementById('app').innerHTML = '<pre style="padding:20px;color:red;">Module Error: ' + e.message + '</pre>'; }); </script></body></html>