diff --git a/CHANGELOG.md b/CHANGELOG.md index 59fd73dbd65..db9b61cd457 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ Docs: https://docs.openclaw.ai - Gateway/agents: fix stale run-context TTL cleanup so the new maintenance sweep compiles and resets orphaned run sequence state correctly. (#52731) thanks @artwalker - Memory/lancedb: accept `dreaming` config when `memory-lancedb` owns the memory slot so Dreaming surfaces can read slot-owner settings without schema rejection. (#63874) Thanks @mbelinky. - Heartbeats/sessions: remove stale accumulated isolated heartbeat session keys when the next tick converges them back to the canonical sibling, so repaired sessions stop showing orphaned `:heartbeat:heartbeat` variants in session listings. (#59606) Thanks @rogerdigital. +- Control UI/dreaming: keep the Dreaming trace area contained and scrollable so overlays no longer cover tabs or blow out the page layout. ## 2026.4.9 diff --git a/ui/src/styles/dreams.css b/ui/src/styles/dreams.css index 5eb0904bd4a..9db89e7f3ef 100644 --- a/ui/src/styles/dreams.css +++ b/ui/src/styles/dreams.css @@ -18,6 +18,8 @@ gap: 2px; padding: 6px 8px; flex-shrink: 0; + position: relative; + z-index: 10; } .dreams__tab { @@ -283,6 +285,7 @@ /* ---- Stats bar ---- */ .dreams__stats { + position: relative; display: flex; align-items: center; gap: 48px; @@ -317,22 +320,31 @@ } .dreams__trace { + position: relative; width: min(900px, calc(100% - 40px)); margin-top: 28px; display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + align-items: start; gap: 12px; z-index: 1; user-select: text; + max-height: min(500px, calc(100vh - 240px)); + overflow-y: auto; + overflow-x: hidden; } .dreams__trace-section { + position: relative; background: color-mix(in oklab, var(--panel) 82%, transparent); border: 1px solid color-mix(in oklab, var(--border) 78%, transparent); border-radius: 16px; padding: 12px; min-height: 180px; backdrop-filter: blur(14px); + overflow: hidden; + min-width: 0; + z-index: 1; } .dreams__trace-header { @@ -369,6 +381,7 @@ display: flex; flex-direction: column; gap: 8px; + min-width: 0; } .dreams__trace-item { @@ -376,12 +389,18 @@ border-radius: 12px; background: color-mix(in oklab, var(--panel-raised) 88%, transparent); border: 1px solid color-mix(in oklab, var(--border) 72%, transparent); + overflow: hidden; + overflow-wrap: anywhere; + word-break: break-word; } .dreams__trace-snippet { font-size: 13px; line-height: 1.35; color: var(--text); + overflow-wrap: anywhere; + word-break: break-word; + white-space: normal; } .dreams__trace-source, @@ -395,6 +414,14 @@ .dreams__trace-source { font-family: var(--mono); + overflow-wrap: anywhere; + word-break: break-word; +} + +.dreams__trace-meta, +.dreams__trace-empty { + overflow-wrap: anywhere; + word-break: break-word; } @media (max-width: 980px) { @@ -838,8 +865,9 @@ .dreams-diary__grid { display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; + align-items: start; } .dreams-diary__panel { @@ -847,6 +875,7 @@ flex-direction: column; gap: 10px; min-height: 100%; + min-width: 0; padding: 18px 18px 16px; border: 1px solid color-mix(in oklab, var(--border) 70%, transparent); border-radius: 16px; @@ -882,6 +911,7 @@ display: flex; flex-direction: column; gap: 8px; + min-width: 0; } .dreams-diary__panel-list--points { @@ -917,6 +947,8 @@ font-size: 13px; line-height: 1.6; color: color-mix(in oklab, var(--text) 88%, var(--muted)); + overflow-wrap: anywhere; + word-break: break-word; } .dreams-diary__item--reflection { @@ -938,6 +970,8 @@ color: color-mix(in oklab, var(--text) 85%, var(--muted)); font-style: italic; animation: diary-text-stream 2.4s cubic-bezier(0.22, 1, 0.36, 1) both; + overflow-wrap: anywhere; + word-break: break-word; } .dreams-diary__para:last-child { diff --git a/ui/src/ui/views/dreaming.test.ts b/ui/src/ui/views/dreaming.test.ts index c74b6dd64e3..f68429ba079 100644 --- a/ui/src/ui/views/dreaming.test.ts +++ b/ui/src/ui/views/dreaming.test.ts @@ -146,6 +146,15 @@ describe("dreaming view", () => { ).toContain("grounded-led"); }); + it("keeps the tab bar above the scene trace shell", () => { + const container = renderInto(buildProps()); + const page = container.querySelector(".dreams-page"); + expect(page?.firstElementChild?.matches("nav.dreams__tabs")).toBe(true); + expect(page?.children[1]?.matches("section.dreams")).toBe(true); + expect(container.querySelector(".dreams__trace")).not.toBeNull(); + expect(container.querySelectorAll(".dreams__trace-section")).toHaveLength(4); + }); + it("renders scene backfill, reset, and clear grounded controls", () => { const container = renderInto(buildProps()); const buttons = [...container.querySelectorAll("button")].map((node) => @@ -264,6 +273,10 @@ describe("dreaming view", () => { "Reflections", "Candidates + Possible Lasting Updates", ]); + expect(container.querySelector(".dreams-diary__grid")).not.toBeNull(); + expect(container.querySelectorAll(".dreams-diary__grid > .dreams-diary__panel")).toHaveLength( + 3, + ); expect(container.querySelector(".dreams-diary__panel-subtitle")?.textContent).toContain( "Candidates", );