fix(ui): contain Dreaming trace layout (#63875)

Merged via squash.

Prepared head SHA: 9412bdfdbe
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
This commit is contained in:
Mariano
2026-04-09 23:20:43 +02:00
committed by GitHub
parent 5b268a04af
commit cf0ebd8f25
3 changed files with 50 additions and 2 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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",
);