feat(web): collapsible hideable left+right debug panes
Each debug pane (#rail-left, #affect-console) gains an independent collapse control: a chevron button in the pane header folds it to a 22px re-open strip, and #center (flex:1) reflows to fill. State persists per-pane in localStorage (ratatoskr-left-collapsed / -right-collapsed), matching the theme/cot-toggle idiom; the right-side drag-resizer hides with its pane. Collapsing both yields a clean chat-only surface. Playwright-verified end-to-end (default-open, collapse-to-strip, center reflow, independent left/right, reload persistence, re-open).
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "ratatoskr"
|
||||
version = "0.20.16"
|
||||
version = "0.20.17"
|
||||
description = "Worldtree Conversation API debug TUI — multi-pane observability dashboard"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
|
||||
@@ -178,6 +178,29 @@ kbd {
|
||||
#app.live { display: flex; }
|
||||
#cols { flex: 1; display: flex; min-height: 0; }
|
||||
|
||||
/* ---- collapsible debug panes (independent left/right; #center reflows to fill) ---- */
|
||||
.pane-collapse {
|
||||
width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
|
||||
background: transparent; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
|
||||
color: var(--fg-3); cursor: pointer; flex: 0 0 auto; font-size: 13px; line-height: 1; padding: 0;
|
||||
}
|
||||
.pane-collapse:hover { background: var(--bg-2); color: var(--fg-0); border-color: var(--border-default); }
|
||||
.ac-head-row { display: flex; align-items: center; justify-content: space-between; position: relative; }
|
||||
/* re-open strip: hidden while the pane is open, becomes the full-height handle when collapsed */
|
||||
.pane-reopen { display: none; }
|
||||
#cols.left-collapsed #rail-left { width: 22px !important; flex-basis: 22px !important; overflow: hidden; }
|
||||
#cols.right-collapsed #affect-console { width: 22px !important; flex-basis: 22px !important; overflow: hidden; }
|
||||
#cols.left-collapsed #rail-left > *:not(.pane-reopen) { display: none; }
|
||||
#cols.right-collapsed #affect-console > *:not(.pane-reopen) { display: none; }
|
||||
#cols.left-collapsed #rail-left .pane-reopen,
|
||||
#cols.right-collapsed #affect-console .pane-reopen {
|
||||
display: flex; flex: 1; width: 100%; align-items: center; justify-content: center;
|
||||
background: transparent; border: none; color: var(--fg-3); cursor: pointer; font-size: 13px;
|
||||
}
|
||||
#cols.left-collapsed #rail-left .pane-reopen:hover,
|
||||
#cols.right-collapsed #affect-console .pane-reopen:hover { background: var(--bg-2); color: var(--fg-0); }
|
||||
#cols.right-collapsed #affect-resizer { display: none; }
|
||||
|
||||
/* eyebrow — mono uppercase wide-tracked (Australis signature) */
|
||||
.eyebrow {
|
||||
font-family: var(--font-mono); font-size: 9.5px;
|
||||
@@ -554,6 +577,7 @@ body.cot-hidden #cot-toggle { border-color: rgba(66,220,209,0.55); color: var(--
|
||||
<svg class="i-sun" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"></path></svg>
|
||||
<svg class="i-moon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"></path></svg>
|
||||
</button>
|
||||
<button class="pane-collapse" id="collapse-left" title="Collapse debug rail">‹</button>
|
||||
</div>
|
||||
|
||||
<div id="conn" data-state="offline">
|
||||
@@ -576,6 +600,7 @@ body.cot-hidden #cot-toggle { border-color: rgba(66,220,209,0.55); color: var(--
|
||||
<span class="eyebrow off" id="bifrost-head">⇄ bifrost · not bound</span>
|
||||
<div id="bifrost-body"><div class="bf-note">observe-only session</div></div>
|
||||
</div>
|
||||
<button class="pane-reopen" id="reopen-left" title="Expand debug rail">›</button>
|
||||
</aside>
|
||||
|
||||
<!-- ══════════ CENTER · conversation ══════════ -->
|
||||
@@ -613,7 +638,10 @@ body.cot-hidden #cot-toggle { border-color: rgba(66,220,209,0.55); color: var(--
|
||||
</defs></svg>
|
||||
<div class="ac-sec" id="ac-dominant">
|
||||
<div class="glow"></div>
|
||||
<div class="eyebrow">affect · dominant</div>
|
||||
<div class="ac-head-row">
|
||||
<div class="eyebrow">affect · dominant</div>
|
||||
<button class="pane-collapse" id="collapse-right" title="Collapse affect console">›</button>
|
||||
</div>
|
||||
<div id="dominant-emotion" class="muted">—</div>
|
||||
<div id="emotions-active"></div>
|
||||
</div>
|
||||
@@ -711,6 +739,7 @@ body.cot-hidden #cot-toggle { border-color: rgba(66,220,209,0.55); color: var(--
|
||||
<span class="grow"></span>
|
||||
<span id="version">ratatoskr —</span>
|
||||
</div>
|
||||
<button class="pane-reopen" id="reopen-right" title="Expand affect console">‹</button>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1948,6 +1977,24 @@ async function cancelTurn() {
|
||||
});
|
||||
})();
|
||||
|
||||
// ---- collapsible debug panes (independent left / right; state persists) ----
|
||||
(function () {
|
||||
const cols = $("cols");
|
||||
function apply(side, collapsed) {
|
||||
cols.classList.toggle(side + "-collapsed", collapsed);
|
||||
try { localStorage.setItem("ratatoskr-" + side + "-collapsed", collapsed ? "1" : "0"); } catch (_) {}
|
||||
}
|
||||
let left = false, right = false;
|
||||
try { left = localStorage.getItem("ratatoskr-left-collapsed") === "1"; } catch (_) {}
|
||||
try { right = localStorage.getItem("ratatoskr-right-collapsed") === "1"; } catch (_) {}
|
||||
cols.classList.toggle("left-collapsed", left);
|
||||
cols.classList.toggle("right-collapsed", right);
|
||||
$("collapse-left").addEventListener("click", () => apply("left", true));
|
||||
$("reopen-left").addEventListener("click", () => apply("left", false));
|
||||
$("collapse-right").addEventListener("click", () => apply("right", true));
|
||||
$("reopen-right").addEventListener("click", () => apply("right", false));
|
||||
})();
|
||||
|
||||
// ---- composer auto-grow + keyboard ----
|
||||
$("prompt-input").addEventListener("input", (e) => {
|
||||
const el = e.target;
|
||||
|
||||
Reference in New Issue
Block a user