diff --git a/.claude/nocache-server.py b/.claude/nocache-server.py index 367cc2ae..2b42dff8 100644 --- a/.claude/nocache-server.py +++ b/.claude/nocache-server.py @@ -11,7 +11,9 @@ """ import http.server import os +import socket import sys +import threading # Serve from the repo root (two levels up from .claude/). ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) @@ -31,8 +33,20 @@ def log_message(self, fmt, *args): def main(): port = int(sys.argv[1]) if len(sys.argv) > 1 else int(os.environ.get("PORT", "8091")) os.chdir(ROOT) - httpd = http.server.HTTPServer(("127.0.0.1", port), NoCacheHandler) - sys.stderr.write("Arena Studio dev server: http://127.0.0.1:%d/ (root: %s)\n" % (port, ROOT)) + # Threaded: with the single-threaded HTTPServer, Chrome's idle pre-connected sockets + # block every other request, so the Studio's module graph (≈ 60 imports) stalls and the + # whole + + - + diff --git a/arena_studio.html b/arena_studio.html index 0cd898fb..93caa5cb 100644 --- a/arena_studio.html +++ b/arena_studio.html @@ -196,6 +196,7 @@ .wdt-channel{font:600 10px/1.6 var(--head, 'JetBrains Mono', monospace);padding:0 6px;border-radius:9px;margin-left:6px;white-space:nowrap;cursor:help;vertical-align:middle} .wdt-ch-prod{color:var(--dim, #8b949e);border:1px solid var(--border, #2d3640)} .wdt-ch-next{color:#0f1419;background:#ff9100;font-weight:700} + .wdt-ch-ros{color:#0f1419;background:#d500f9;font-weight:700} /* ROS Studio side tier (LAB-303 spike) */ .wdt-ch-local{color:var(--dim, #8b949e);border:1px dashed var(--border, #2d3640)} .brand{font-family:var(--head);font-weight:700;letter-spacing:.5px;color:var(--accent);font-size:14px;white-space:nowrap} .status{display:flex;align-items:center;gap:6px;font-size:12px} @@ -213,6 +214,13 @@ .rig-tag{font-size:11px;color:var(--dim);border:1px solid var(--border);border-radius:20px;padding:2px 8px;white-space:nowrap;cursor:pointer;max-width:220px;overflow:hidden;text-overflow:ellipsis} .rig-tag:hover{border-color:var(--accent);color:var(--text)} .chip.rig-mismatch{color:var(--warn);border-color:var(--warn);background:color-mix(in srgb,var(--warn) 8%,transparent);cursor:help} + /* Qwiic chip (LAB-214): shown only on controllers with the I2C bridge; click → Console → Qwiic */ + .chip.qwiic-chip{cursor:pointer} + body:not(.hasproto) .chip.qwiic-chip{display:inline-block} /* bench state, not protocol state: shown with no protocol loaded (inline display:none still hides it) */ + .chip.qw-ok{color:var(--accent);border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)} + .chip.qw-warn{color:var(--warn);border-color:var(--warn);background:color-mix(in srgb,var(--warn) 8%,transparent)} + .chip.qw-err{color:var(--danger);border-color:var(--danger);background:color-mix(in srgb,var(--danger) 8%,transparent)} + .chip.qw-off{color:var(--dim);border-color:var(--border)} .doc-name{font-family:var(--head);font-weight:700;font-size:12.5px;white-space:nowrap} .chip{font-family:var(--mono);font-size:11px;font-weight:600;border-radius:20px;padding:2px 8px;border:1px solid;white-space:nowrap} .chip.saved{color:var(--accent);border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)} @@ -813,6 +821,11 @@ #ghQuickLinks .ql-link:hover{border-color:var(--accent);background:color-mix(in srgb,var(--accent) 8%,transparent)} .banner{background:color-mix(in srgb,var(--warn) 12%,transparent);border:1px solid var(--warn);color:var(--warn);border-radius:8px;padding:8px 12px;margin:10px 20px;font-size:12px;display:none} .banner.show{display:block} + /* Run alert: a safety event the operator must SEE (bridge lost mid-run) — stays until + dismissed or the next run starts, unlike #banner, which later messages replace. */ + .run-alert{background:color-mix(in srgb,var(--danger) 12%,transparent);border-color:var(--danger);color:var(--danger);font-weight:600;align-items:center;gap:12px} + .run-alert.show{display:flex} + .run-alert button{margin-left:auto;flex:0 0 auto;background:transparent;border:1px solid currentColor;color:inherit;border-radius:5px;padding:1px 8px;cursor:pointer;font:inherit} /* ── Edit view: tab bar (Designer | YAML) + YAML pane ───────────── */ .edit-view .edit-tabs{display:flex;border:1px solid var(--border);border-radius:5px;overflow:hidden;flex:0 0 auto} @@ -2229,6 +2242,27 @@ .console-view .ai-range{font-size:10px;color:var(--dim);min-width:130px} .console-view #cAiChart{display:block;width:100%;max-width:460px;height:90px;border:1px solid var(--border);border-radius:4px;background:var(--chart-bg)} .console-view .ai-table{font-size:10.5px;border-collapse:collapse} + /* Qwiic panel (LAB-214): scan table, one-device readout grid, AS7343 spectrum bars */ + .console-view table.qw-table td,.console-view table.qw-table th{padding:2px 10px 2px 0;text-align:left;vertical-align:top} + .console-view .qw-table tr.qw-pick{cursor:pointer} + .console-view .qw-table tr.qw-pick:hover td{background:var(--surface2)} + .console-view .qw-table tr.qw-selrow td{background:color-mix(in srgb,var(--accent) 10%,transparent)} + .console-view .qw-table input[type=radio]{margin:0 2px 0 0;accent-color:var(--accent);cursor:pointer} + .console-view .qw-table .qw-cat{color:var(--text);font-weight:600;white-space:nowrap} + .console-view .qw-sel{font-family:var(--head);font-size:11.5px;color:var(--text);min-width:180px} + .console-view .qw-flags{font-size:11px;line-height:1.5} + .console-view .qw-out{display:block} + .console-view .qw-title{font-family:var(--head);font-size:12px;margin-bottom:4px} + .console-view .qw-grid{display:grid;grid-template-columns:max-content max-content;gap:2px 14px;align-items:baseline} + .console-view .qw-l{color:var(--dim);font-size:11px} + .console-view .qw-v{font-family:var(--head);font-size:15px;color:var(--text)} + .console-view .qw-bars{grid-column:1 / -1;display:flex;gap:3px;align-items:flex-end;height:74px;margin-top:4px} + .console-view .qw-bar{display:flex;flex-direction:column;align-items:center;justify-content:flex-end;height:100%;width:26px} + .console-view .qw-bar i{display:block;width:16px;background:var(--accent);opacity:.85;border-radius:2px 2px 0 0} + .console-view .qw-bar span{font-size:9px;color:var(--dim);margin-top:2px} + .qw-ok-t{color:var(--accent)} + .qw-warn-t{color:var(--warn)} + .qw-err-t{color:var(--danger)} .console-view .ai-table td,.console-view .ai-table th{padding:1px 10px 1px 0;text-align:right;color:var(--text);font-family:var(--mono)} .console-view .ai-table th{color:var(--dim);font-weight:normal} .console-view .ai-table td.bad{color:var(--danger-text)} @@ -2254,6 +2288,7 @@ .console-view .stage>.panel[data-panel="fw"]{order:7} .console-view .stage>.panel[data-panel="ai"]{order:8} .console-view .stage>.panel[data-panel="fictrac"]{order:9} + .console-view .stage>.panel[data-panel="qwiic"]{order:10} } /* Outer panel box: soft near-white 1.5px edge so panels stay distinct on a dark monitor in a lit room (grey var(--border) washed out). Internal @@ -2356,6 +2391,7 @@ rig — + @@ -2472,6 +2508,7 @@ +