Compare commits
2 Commits
00fa695d3b
...
e7bfbe951d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7bfbe951d | ||
|
|
f8f82dce21 |
12
README.md
12
README.md
@@ -24,6 +24,14 @@ 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).
|
||||
@@ -113,7 +121,7 @@ This wires Claude Code's hooks → **live per-tab status**, the **statusLine gau
|
||||
|
||||
### Tests
|
||||
```bash
|
||||
npm test # vitest, all modules (~1470 tests, 80% coverage gate)
|
||||
npm test # vitest, all modules (~1600 tests, 80% coverage gate)
|
||||
npm run typecheck # tsc (backend + frontend)
|
||||
npm run build # compile backend to dist/
|
||||
```
|
||||
@@ -200,6 +208,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** (~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.
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
@@ -357,6 +357,18 @@ 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.) */
|
||||
#term.grid .term-pane {
|
||||
box-sizing: content-box;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
/* Maximized quadrant fills the whole grid as an ABSOLUTE overlay (taken out of
|
||||
* grid flow so the siblings keep their placement — spanning grid tracks instead
|
||||
* would shove auto-placed siblings into implicit rows, resizing their live PTYs).
|
||||
|
||||
Reference in New Issue
Block a user