From 3a1238dab7ad34b165cbc6abe6218e159af183e6 Mon Sep 17 00:00:00 2001 From: "Orca (ecs-claude)" Date: Thu, 20 Aug 2026 20:52:48 +0800 Subject: [PATCH 1/2] fix(console): fleets.toml/agents.toml editor fills to the window bottom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brett: empty space under "edit fleets.toml" — the bottom panel should align with the window box. `.cfg-editor-mount .cm-editor` was capped at a flat `max-height: 320px`, leaving a growing chunk of blank space below it on anything taller than that. Replaced with a live-measured `--cfg-editor-h` (same pattern as `--topbar-h` from the Debug drawer fix) — `syncEditorHeight()` sets it to `window.innerHeight - editorMount's top - 16px` whenever the editor opens, and stays in sync on `resize` (the window is resizable, and the space above the editor — the Fleets row's height — isn't constant either). ## Verification - `tsc --noEmit` — clean - `vitest run` — 97/97 passing (no logic under test touched) - `vite build` — clean - Playwright: confirmed the editor now sits 15px (the intentional bottom margin) from the window's bottom edge instead of stopping at 320px with open space below. 🤖 Generated by Orca ('ecs-claude'). --- console/src/main.ts | 16 ++++++++++++++++ console/src/styles.css | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/console/src/main.ts b/console/src/main.ts index d06c073..ff259fb 100644 --- a/console/src/main.ts +++ b/console/src/main.ts @@ -400,6 +400,18 @@ function showEditorError(msg: string | null): void { editorError.hidden = !msg; } +// Fill the editor down to the window's bottom edge (Brett: it capped at a +// fixed height with a chunk of blank space below) instead of a flat number — +// the space above it (the Fleets row's height) isn't constant, so this is +// measured live rather than hard-coded. No-ops while the editor is closed; +// wired to `resize` once at boot below since the window is resizable. +function syncEditorHeight(): void { + if (!editorMount || !editorSection || editorSection.hidden) return; + const top = editorMount.getBoundingClientRect().top; + const h = Math.max(200, window.innerHeight - top - 16); + editorMount.style.setProperty("--cfg-editor-h", `${h}px`); +} + async function openEditor(target: EditorTarget): Promise { if (!editorSection || !editorMount) return; editorTarget = target; @@ -436,6 +448,7 @@ async function openEditor(target: EditorTarget): Promise { }), }); editorSection.hidden = false; + syncEditorHeight(); editorView.focus(); } @@ -943,6 +956,9 @@ async function boot(): Promise { syncTopbarHeight(); new ResizeObserver(syncTopbarHeight).observe(topbarEl); } + // Keep the fleets.toml/agents.toml editor filling the window as it's + // resized (`syncEditorHeight` no-ops while closed). + window.addEventListener("resize", syncEditorHeight); setupUpdater(); await startCore(); // Debug drawer's Config tab: pin the oab-mcp target (cluster/profile/region → diff --git a/console/src/styles.css b/console/src/styles.css index afe5fbc..ccd99ae 100644 --- a/console/src/styles.css +++ b/console/src/styles.css @@ -798,7 +798,12 @@ button.act:disabled { font-size: 13px; } .cfg-editor-mount .cm-editor { - max-height: 320px; + /* Fills down to the window's bottom edge instead of capping at a fixed + height with blank space below it — `--cfg-editor-h` is measured in + main.ts (`syncEditorHeight`), same live-measurement pattern as + `--topbar-h`, since the window is resizable and the space above the + editor (Fleets row height, etc.) isn't constant. */ + height: var(--cfg-editor-h, 320px); } .cfg-editor-error { margin-top: 6px; From 29bfdd627c6a2d6050ff7beac9eea8215459e9af Mon Sep 17 00:00:00 2001 From: "Orca (ecs-claude)" Date: Thu, 20 Aug 2026 21:01:59 +0800 Subject: [PATCH 2/2] fix(console): Fleets and Agent chat columns match height, fill to window bottom MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Brett: the two-column style doesn't match; Fleets panel isn't scaled to the same height as Agent chat, looks weird; when there's no edit panel the bottom is all empty. `.drilldown-row` used `align-items: flex-start`, so each column sized to its own content — a short Fleets card list next to a taller Agent-chat panel, with a big stretch of bare page background below both. Switched to `align-items: stretch` + a live-measured floor (`--drilldown-row-h`, same pattern as `--topbar-h`/`--cfg-editor-h`) so both columns match height and reach the window's bottom edge when content is shorter than that: - `.drilldown-main`'s visible child (`#config`/`#fleet-detail`/`#deploy-wrap` — whichever isn't `[hidden]`) grows to fill the stretched column, and `.config`'s own bordered box grows with it, so the Fleets box's border now extends to match Agent chat's height instead of stopping short. `#deploy-wrap` gets this for free (it's the bordered box directly, no extra wrapper level). Added the by-now-familiar `[hidden]` override (`.drilldown-main > *[hidden]`) — `.drilldown-main > *`'s `display: flex` ties the UA `[hidden]` rule on specificity and would otherwise render a hidden sibling as an empty flex box (same trap as `.debug-drawer[hidden]`/ `.deploy-identity[hidden]`, caught before shipping this time). - `.chat-wrap`/`.chat-log` on the Agent chat side now flex-grow too, so any extra height `stretch` gives the column goes into the chat log itself (dropped its flat 560px cap — the row's own floor is the real ceiling now) rather than sitting as blank flex-gap below it. - Dropped `.config-wrap`'s stray `margin-bottom: 16px`, the last few px of mismatch between the two columns once the rest of this landed. Scoped to the top-level Fleets screen (`.config`) — Brett's screenshot was specifically that screen. Fleet-detail's roster/agent-console box still sizes to its own content (didn't extend it — its nested two-piece border makes that a separate, smaller job); flag if that should match too. ## Verification - `tsc --noEmit` — clean - `vitest run` — 97/97 passing (no logic under test touched) - `vite build` — clean - Playwright: confirmed `.config` and the Agent chat column now bottom out at the identical y-coordinate (0px diff, was ~803px vs 673px tall before); spot-checked fleet-detail and the deploy panel don't regress, and that switching screens correctly computes `display: none` for the hidden ones (the `[hidden]` override actually works, not just present in the CSS). 🤖 Generated by Orca ('ecs-claude'). --- console/src/main.ts | 16 ++++++++++++++ console/src/styles.css | 50 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/console/src/main.ts b/console/src/main.ts index ff259fb..a3ad2cb 100644 --- a/console/src/main.ts +++ b/console/src/main.ts @@ -956,6 +956,22 @@ async function boot(): Promise { syncTopbarHeight(); new ResizeObserver(syncTopbarHeight).observe(topbarEl); } + // The Fleets column and the Agent chat column used to size to their own + // content, so a short Fleets list ended up visibly shorter than the taller + // chat panel (Brett). `--drilldown-row-h` floors the row's height at the + // window's bottom edge; `align-items: stretch` (styles.css) then makes both + // columns match it. `.drilldown-row`'s own top is fixed (topbar height + + // `.content`'s padding, neither content-dependent), so this only needs + // `resize`, not a ResizeObserver on the row itself. + const drilldownRowEl = document.getElementById("drilldown-row"); + const syncDrilldownHeight = (): void => { + if (!drilldownRowEl) return; + const top = drilldownRowEl.getBoundingClientRect().top; + const h = Math.max(200, window.innerHeight - top - 16); + drilldownRowEl.style.setProperty("--drilldown-row-h", `${h}px`); + }; + syncDrilldownHeight(); + window.addEventListener("resize", syncDrilldownHeight); // Keep the fleets.toml/agents.toml editor filling the window as it's // resized (`syncEditorHeight` no-ops while closed). window.addEventListener("resize", syncEditorHeight); diff --git a/console/src/styles.css b/console/src/styles.css index ccd99ae..d184f82 100644 --- a/console/src/styles.css +++ b/console/src/styles.css @@ -188,9 +188,16 @@ body { instead of squeezing. ---- */ .drilldown-row { display: flex; - align-items: flex-start; + /* Was flex-start — the Fleets column (short: just a card list) and the + Agent chat column (tall: min-height'd chat log) never matched height, + leaving Fleets looking stubby next to a lot of blank page below it + (Brett). `stretch` + a live-measured floor (`--drilldown-row-h`, same + pattern as `--topbar-h`/`--cfg-editor-h`) makes both columns match and + reach the window's bottom edge when their content is shorter than that. */ + align-items: stretch; gap: 0; margin: 0 0 16px; + min-height: var(--drilldown-row-h, auto); } /* Nothing toggles `hidden` on this element today (deploy.ts used to; it now hides `#config`/`#fleet-detail` in place instead, see deploy.ts), but the @@ -203,6 +210,24 @@ body { .drilldown-main { flex: 1 1 0; min-width: 0; + display: flex; + flex-direction: column; +} +/* Whichever of #config/#fleet-detail/#deploy-wrap is showing (the others are + `[hidden]`) grows to fill the stretched column instead of sitting short at + the top. */ +.drilldown-main > * { + flex: 1 1 auto; + min-height: 0; + display: flex; + flex-direction: column; +} +/* Same equal-specificity trap as `.debug-drawer[hidden]`/`.deploy-identity + [hidden]` above — `.drilldown-main > *` and the UA `[hidden]` rule tie, and + the later author rule wins, so a hidden sibling would render as an empty + flex box instead of disappearing without this. */ +.drilldown-main > *[hidden] { + display: none; } /* Drag handle between the two columns — mousedown/move/up wiring lives in main.ts (src/splitPane.ts owns the pure clamp/persist logic). Widening @@ -244,10 +269,21 @@ body { } .drilldown-side > .chat-wrap { margin: 0; + /* Absorbs whatever extra height `align-items: stretch` (above) gives the + column beyond #remote's + the chat log's own natural size — otherwise + that space is just blank flex-gap below the chat, not inside it. */ + flex: 1 1 auto; + display: flex; + flex-direction: column; + min-height: 0; } .drilldown-side > .chat-wrap .chat-log { + flex: 1 1 auto; min-height: 240px; - max-height: 560px; + /* Cancels the base rule's 340px cap (still in effect for the agent + console's own embedded chat, which isn't in a stretched column) — the + row's own `min-height` is the real ceiling now. */ + max-height: none; } @media (max-width: 860px) { .drilldown-row { @@ -571,10 +607,10 @@ button.act:disabled { /* ---- Fleets screen (ADR #19: the "declare" side; ADR #83: promoted from a sidebar panel to the console's top-level screen — Slice 1) ---- */ -.config-wrap { - margin: 0 0 16px; -} .config { + flex: 1 1 auto; + display: flex; + flex-direction: column; border: 1px solid var(--border); border-radius: 6px; background: var(--panel); @@ -1277,7 +1313,9 @@ button.act:disabled { } /* ---- Deploy action panel (ADR #83 slice 5: `[+ New fleet]` / `[+ Add - instance]`) — replaces .drilldown-row while open. ---------------------- */ + instance]`) — replaces #config/#fleet-detail in `.drilldown-main` while + open (deploy.ts), so it inherits the fill-the-column treatment from + `.drilldown-main > *` above for free. ---------------------- */ .deploy-wrap { margin: 0 0 12px; padding: 14px;