feat(grid): v3a — read-only monitor quadrants (no shared-PTY shrink)

A quadrant can be flipped to "monitor" mode via a 👁 header toggle: instead of
the live interactive terminal, it renders the session's screen from periodic
GET /live-sessions/:id/preview snapshots into a read-only xterm. A monitored
quadrant never attaches a WS and never sends a resize, so — unlike a live
quadrant (latest-writer-wins) — it does not drive the shared PTY size. That lets
you watch a session in a small quadrant without shrinking it for another device
using it full-screen (the cross-device shrink the split-grid design flagged).

- public/cell-monitor.ts (new): mountCellMonitor(host, id) — polling read-only
  preview, scaled to fit, best-effort, disposes cleanly (no write after dispose).
- tabs.ts: per-entry monitor state; applyLayout keeps the live pane hidden and
  starts/stops the monitor; 👁 toggle in the cell header; teardown on close /
  leaving grid mode.
- style.css: monitor button + .cell-monitor container.
- tests: cell-monitor.test.ts (poll→write, dispose, late-resolve guard) + monitor
  wiring in tabs.test.ts. typecheck + build clean, 1587 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yaojia Wang
2026-07-11 19:58:47 +02:00
parent 5475b661ae
commit cd97114f87
6 changed files with 331 additions and 3 deletions

View File

@@ -396,6 +396,35 @@ body {
color: var(--text);
background: var(--surface-3);
}
.cell-monitor-btn {
border: 0;
background: transparent;
color: var(--text-faint);
cursor: pointer;
font-size: 12px;
line-height: 1;
padding: 2px 4px;
border-radius: 5px;
opacity: 0.7;
}
.cell-monitor-btn:hover {
color: var(--text);
background: var(--surface-3);
opacity: 1;
}
.cell-monitor-btn.active {
color: var(--accent);
opacity: 1;
}
/* Read-only monitor preview fills the cell below the header. */
.cell-monitor {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
position: relative;
padding: 6px 8px 0;
box-sizing: border-box;
}
.cell-name {
font-weight: 600;
color: var(--text);
@@ -604,7 +633,8 @@ body {
width: 36px;
height: 34px;
}
.cell-max {
.cell-max,
.cell-monitor-btn {
padding: 6px 9px;
font-size: 15px;
}