Compare commits

..

1 Commits

Author SHA1 Message Date
Yaojia Wang
00fa695d3b fix(grid): add bottom padding to grid panes so the focus ring/border doesn't crowd the last terminal line
Some checks failed
relay-tripwire / cross-tenant-tripwire (push) Has been cancelled
Grid-cell panes had 0 bottom padding (single mode fills to the key-bar), so the
last terminal row butted against the cell border and the gold focus ring looked
like it covered the text. Adds 6px bottom clearance in grid mode only.
2026-07-12 06:00:26 +02:00
2 changed files with 5 additions and 19 deletions

View File

@@ -24,14 +24,6 @@ Sessions survive disconnects: the shell (and whatever's running in it) keeps goi
- **Sessions ↔ Projects toggle** — a segmented control on the home screen flips between the running-sessions view and the projects view.
- **⌂ Home overlay** — a Home button in the tab bar overlays the chooser on top of the current terminal so you can start another session/project without closing your tabs.
### Split-grid watch board (v0.8, desktop)
On a large screen (≥ 1024px) the terminal area can split into a grid so several **live, interactive** sessions show at once — built for watching multiple Claude Code runs in parallel. Desktop-only (a 2×2 of terminals is unusable on a phone); the server and wire protocol are untouched, and single-pane mode is unchanged.
- **Layouts** — a toolbar toggle cycles **single / 1×2 / 1×3 / 2×2 / 2×3**. The board shows the first N tabs (drag-reorder the tab bar, or drag a tab straight onto a quadrant, to choose which); a dashed **+ New session** tile fills any empty slot. The choice persists.
- **Click-to-focus** — the quadrant you click wears a focus ring and owns the keyboard, mobile key-bar, voice, and the approval bar; **Ctrl+`** cycles focus (⇧ reverses). Only the focused pane takes keyboard focus, so panes don't fight over it.
- **Inline approve per quadrant** — a background quadrant waiting on a tool permission glows amber and shows its own **✓ / ✗** buttons, so you can clear approvals across several sessions without switching; its OS notification is suppressed while it's on screen.
- **Maximize (⛶) / monitor (👁) per quadrant** — ⛶ expands one quadrant to fill the grid (the others stay live behind it); 👁 flips a quadrant to a **read-only preview** (polled screen snapshots — no WebSocket attach, no resize) so watching a session in a small quadrant never shrinks it for another device using it full-screen.
- **Resizable splitters + saved presets** — drag the gutters between panes to re-balance column/row sizes (persisted per layout), and save a layout + its split as a named preset to re-apply in one click.
### Claude Code cockpit
- **Live per-tab status** — Claude Code hooks POST to the server (loopback side-channel); each tab badge shows **working / waiting-for-approval / idle / stuck** in real time. Install once with `npm run setup-hooks`.
- **Remote approve / reject** — when Claude asks for tool permission, the request is *held* server-side and an **Approve / Reject** bar appears on every attached device — resolve it with a tap, no typing. Works across multiple devices (closing one mirror doesn't cancel the prompt for the others).
@@ -121,7 +113,7 @@ This wires Claude Code's hooks → **live per-tab status**, the **statusLine gau
### Tests
```bash
npm test # vitest, all modules (~1600 tests, 80% coverage gate)
npm test # vitest, all modules (~1470 tests, 80% coverage gate)
npm run typecheck # tsc (backend + frontend)
npm run build # compile backend to dist/
```
@@ -208,6 +200,6 @@ The server is a **byte-shuttle, not a terminal**: `node-pty` gives the shell a r
The other central design point: **PTY lifecycle ≠ WebSocket lifecycle.** A WS close *detaches* a client (the PTY keeps running for other devices and for reconnect); only an idle timeout (or explicit kill / server shutdown) ends a session.
Tested with **vitest** (~1600 tests, 80% coverage gate across backend + the logic-bearing frontend modules), plus real-PTY integration tests that auto-skip where `posix_spawn` is unavailable (sandboxes) and run everywhere else.
Tested with **vitest** (~470 tests, 80% coverage gate across backend + the logic-bearing frontend modules), plus real-PTY integration tests that auto-skip where `posix_spawn` is unavailable (sandboxes) and run everywhere else.
Design and rationale: [`docs/TECH_DOC.md`](docs/TECH_DOC.md) (the *why*) and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) (the *how*). Feature PRDs: [`docs/FEATURE_PROJECT_MANAGER.md`](docs/FEATURE_PROJECT_MANAGER.md) (v0.6) and [`docs/FEATURE_WALKAWAY_WORKBENCH.md`](docs/FEATURE_WALKAWAY_WORKBENCH.md) (v0.7).

View File

@@ -357,16 +357,10 @@ body {
border-radius: var(--radius);
background: var(--bg);
}
/* Keep the last terminal row clear of the cell border/focus ring in a grid.
* Root cause (measured): the base .term-pane is box-sizing:border-box, so
* getComputedStyle(pane).height — which xterm's FitAddon reads to compute rows —
* returns the PADDING-box height and double-counts the pane's own padding, packing
* one extra row that overruns into the border (overflow +6px). content-box makes
* that height report the CONTENT box, so FitAddon drops the phantom row and the 6px
* padding becomes real clearance. (Single mode keeps padding 0 so the terminal
* still fills to the key-bar.) */
/* In a grid cell the pane butts against the cell's border; without a bottom gap
* the last terminal row sits under the border/focus ring. Give it clearance
* (single mode keeps padding 0 so the terminal fills to the key-bar as before). */
#term.grid .term-pane {
box-sizing: content-box;
padding-bottom: 6px;
}
/* Maximized quadrant fills the whole grid as an ABSOLUTE overlay (taken out of