fix(ui): contain trajectory scrolling and overlays

This commit is contained in:
_Kerman
2026-07-30 14:45:07 +08:00
parent 2a53806275
commit c0b8fea4c8
4 changed files with 42 additions and 5 deletions

View File

@@ -175,6 +175,29 @@ describe('web e2e: live-turn interactions (cancel / error / retry)', () => {
expect(tripwire.warnings).toEqual([])
}, 120_000)
it.skipIf(MODE === 'record')('keeps a terminal request marker inside the trajectory table', async () => {
await launch(() => ({
patches: [{ at: 0, entry: { kind: 'throw', chunks: [], message: 'invalid api key', code: 'AUTH' } }],
}))
const { settled } = await sendPrompt()
await settled
await page.getByRole('tab', { name: 'Trajectory' }).click()
const tailRequest = page.locator('tr[data-request-only="true"]').last()
await tailRequest.waitFor({ timeout: 10_000 })
const requestMarker = tailRequest.getByRole('button', { name: /Request #/ })
const markerWithinTable = await requestMarker.evaluate((element) => {
const marker = element.getBoundingClientRect()
const table = element.closest('table')?.getBoundingClientRect()
if (table === undefined) throw new Error('request marker has no table')
return marker.bottom <= table.bottom
})
expect(markerWithinTable).toBe(true)
expect(tripwire.pageErrors).toEqual([])
expect(tripwire.warnings).toEqual([])
}, 120_000)
it.skipIf(MODE === 'record')('recovers a transient SERVER failure through llm-retry and completes', async () => {
const derived = deriveReplayScript(parseSessionLog(await readFile(FIXTURE, 'utf8')))
expect(derived).toHaveLength(1)

View File

@@ -103,6 +103,11 @@
border-bottom: 0;
}
.table tbody tr[data-request-only='true']:last-child td {
/* Retain the lower half of the 16px boundary marker at the table's end. */
height: 9px;
}
.table tbody tr[data-request-only='true'] .turnRail {
top: -15px;
bottom: 0;

View File

@@ -1,4 +1,7 @@
.root {
position: relative;
z-index: 0;
isolation: isolate;
flex: none;
border-bottom: 1px solid var(--dsw-alias-border-l2);
user-select: none;

View File

@@ -13,11 +13,17 @@
background: var(--dsw-alias-bg-layer-1);
}
/* Under the active conversation column (`[data-conversation-scroll]`) the
* parent owns overflow so the sticky composer stays in the same scrollport. */
:global([data-conversation-scroll]) .root {
overflow: visible;
height: auto;
/* Trajectory keeps the ledger and details panel inside the remaining
* conversation height. Only the ledger pane scrolls; the composer remains
* the fixed flex sibling below this view. */
:global([data-conversation-scroll]):has(.root) {
overflow: hidden;
}
:global([data-conversation-scroll]):has(.root) > :first-child {
flex: 1 1 0;
min-height: 0;
overflow: hidden;
}
.ledger {