mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 08:59:40 +02:00
feat(tiles): the grid holds at most 6 tiles (owner decision 7)
Six was tested smooth on the owner's desktop; nine missed the headless frame bar and is untested on real hardware. TILE_GRID_MAX (constants.js) is now 6 and stays the one cap every limit reads; the layout table gets its own bound, TILE_LAYOUT_MAX = 9, so the 7 to 9 layouts keep working (unreachable) and going back to nine is that one line. Every way in stops at the cap: opening, addTile, a tile's +, a session Run makes, Ctrl/Cmd+click, the picker, "Open group as tiles", and a stored grid with more ids (it comes back as its first six, focus kept only if it survives, a dropped zoom cleared, row fractions that no longer match the 3x2 reset). The limits now go through one helper, _tileGridLimit(), whose texts say which limit binds: "Up to 6 tiles" / "The grid holds at most 6 tiles" when it is the cap, "This window fits N" when it is the window. Docs: decision 7 and an as-built entry in the spec, CLAUDE.md, the invariants, the wiki's Tile Grid and Dashboard pages. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -797,7 +797,7 @@ Further detail: with many sessions the horizontal strip stops being scannable, w
|
||||
|
||||
### Tile grid
|
||||
|
||||
**Tile grid** (`showTileGridButton`, header Tiles button + `Ctrl+Shift+G`, default OFF, per-device: in `displayKeys`, stripped from the settings PUT, not in `SettingsUpdateSchema`; desktop-only at 1180px by a JS width check with a live media listener plus a `@media (max-width: 1179px)` backstop, never in a solo window). 1 to 9 live sessions side by side in one window, each a `TerminalTile` (terminal-tile.js), orchestrated by tile-grid.js (load order 7.6, `CodemanApp.prototype` methods like the split's). Pure helpers live in constants.js as `window.CodemanTileGrid`: `computeTileLayout` (1x1, 2x1, 3x1 on a grid area at least 1800px wide else 2x2, 2x2, 3x2, 3x3; `fits` against a 480x240 minimum tile), `tileGridCapacity`, `sanitizeTileGridState`, `buildTilePickerSessions`, `dragTrackFractions`, `tileNeighbor`, `tileInDirection`, `cycleTile`, `TILE_SCROLLBACK` (10,000). The grid is a `<section class="tile-grid">` SIBLING of `.terminal-wrap`, swapped in by `.main.tiles-active` (no reparenting); `.main.webview-active .tile-grid` hides it like the single view.
|
||||
**Tile grid** (`showTileGridButton`, header Tiles button + `Ctrl+Shift+G`, default OFF, per-device: in `displayKeys`, stripped from the settings PUT, not in `SettingsUpdateSchema`; desktop-only at 1180px by a JS width check with a live media listener plus a `@media (max-width: 1179px)` backstop, never in a solo window). 1 to 6 live sessions side by side in one window, each a `TerminalTile` (terminal-tile.js), orchestrated by tile-grid.js (load order 7.6, `CodemanApp.prototype` methods like the split's). Pure helpers live in constants.js as `window.CodemanTileGrid`: `computeTileLayout` (1x1, 2x1, 3x1 on a grid area at least 1800px wide else 2x2, 2x2, 3x2, and 3x3 up to `TILE_LAYOUT_MAX` (9), unreachable today; `fits` against a 480x240 minimum tile), `tileGridCapacity` (never more than `TILE_GRID_MAX`), `sanitizeTileGridState` (truncates a stored grid to the cap, keeps focus only if it survives), `buildTilePickerSessions`, `dragTrackFractions`, `tileNeighbor`, `tileInDirection`, `cycleTile`, `TILE_SCROLLBACK` (10,000), and `TILE_GRID_MAX` (6), the ONE cap (owner decision 7: six tested smooth on a real desktop, nine missed the headless frame bar). ⚠️ Every limit reads the cap through `_tileGridLimit()` (tile-grid.js: the window's capacity, at most the cap), never a literal, and its texts say which binds ("at most 6 tiles" vs "what this window fits"). The grid is a `<section class="tile-grid">` SIBLING of `.terminal-wrap`, swapped in by `.main.tiles-active` (no reparenting); `.main.webview-active .tile-grid` hides it like the single view.
|
||||
|
||||
⚠️ **The main terminal is parked while the grid is open.** Opening runs `_cleanupPreviousSession()` ONCE (its snapshot is right at that moment, and it closes the main socket), and `activeSessionId` is always the FOCUSED tile's session, so everything keyed on it (files panel, git status, respawn and Ralph panels, subagent windows, voice, image paste, the tab highlight) follows focus. With the main socket closed `_wsReady` is false, so every SSE terminal handler would write the focused tile's output into the hidden xterm: `_tilesOwnTerminal()` turns `_onSessionTerminal`, `_onSessionClearTerminal`, `_onSessionNeedsRefresh` (returns `false`, which the drop recovery reads), `_scheduleDroppedOutputRecovery`, the `writeln` in `_onSessionCompletion`/`_onSessionError`, `sendResize`, `throttledResize`'s fit and `_maybeRefetchFullHistory` into no-ops; `retryConnection` and `handleInit` re-arm the TILES' sockets instead of the main one (`handleInit` keeps live tiles, drops dead ones through `_reconcileTileGrid`, and re-selects only when the focused tile is gone, so an SSE blip never hides an open web tab). ⚠️ The WebGL long-task observer watches the WHOLE page: it counts nothing while tiles own the terminal, or tile renders would write the sticky 7-day WebGL disable. The header connection dot reads the tile sockets (`_tileGridSocketState`; a tile stopped for good does not count). `_focusedPane()` answers with the focused tile even when DOM focus left every terminal, and `_forEachTile` reaches every grid tile (`{ grid: false }` skips them where tiles keep their own font size). Leaving the grid destroys every tile, resets `_lastResizeDims`, invalidates the main terminal's cached content for EVERY tiled id (`_xtermSnapshots`, `codeman-xs-<id>`, `terminalBufferCache`: written before the grid opened, and selectSession paints a snapshot as its first frame) and replays the focused session through `selectSession(id, { forceReload: true, auto: true })`.
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ or settled a question the spec left open. The invariants as built are in
|
||||
B too), and a refresh clears the screen at its turn in the queue, so a waiting tile keeps
|
||||
its last frame.
|
||||
- **4009 lands on the Attach overlay**, and 4003/4004/4010 remove the tile.
|
||||
- **The grid holds at most 6 tiles** (owner decision 7). `TILE_GRID_MAX` in constants.js is
|
||||
the one cap every limit reads; the layout table keeps 7 to 9 (`TILE_LAYOUT_MAX`), unreachable,
|
||||
so going back to nine is that one line. A stored grid with more ids comes back as its first
|
||||
six. Where this spec says nine, read six.
|
||||
- **"+ / New session in this case"** runs the normal Run for that case and joins through
|
||||
the same auto-join as any Run from this tab.
|
||||
- **A tile that joins before its pane exists resends its size when the pid appears**
|
||||
@@ -869,6 +873,12 @@ exits green. Use the browser runner for those files and read the file count.
|
||||
chord is inert while `showTileGridButton` is off (it passes through like any
|
||||
unbound key) and toggles the grid while it is on, so one setting governs both
|
||||
the button and the chord.
|
||||
7. **The tile cap.** Decided by the owner: at most 6 tiles for now. Six was
|
||||
tested and is smooth on the owner's desktop; nine missed the headless frame
|
||||
bar (p95 33 ms at 6 and 9 tiles under load, 16.8 ms at 4) and is untested on
|
||||
real hardware. The cap is one constant (`TILE_GRID_MAX`), the layout table
|
||||
keeps 7 to 9 working but unreachable, and the user-facing texts say "at most
|
||||
6 tiles" when the cap, not the window, is what limits the grid.
|
||||
|
||||
## Code anchors
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ The right side of the header. Almost all of these are off until you enable them
|
||||
| Cron ⏰ | Off | Scheduled jobs. |
|
||||
| Multi-monitor | Off, macOS | Opens a window spanning every display. |
|
||||
| Split | Off, desktop only | View a second session beside the active one, with a draggable divider. |
|
||||
| Tiles | Off, desktop only | Up to nine live sessions side by side. See [Tile Grid](Tile-Grid). |
|
||||
| Tiles | Off, desktop only | Up to six live sessions side by side. See [Tile Grid](Tile-Grid). |
|
||||
| Tunnel indicator | When a tunnel runs | Cloudflare tunnel status. |
|
||||
| Admin panel | Multi-user only | User administration. |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Tile Grid
|
||||
|
||||
Watch and drive up to nine sessions at once, side by side in one window. Each tile is a
|
||||
Watch and drive up to six sessions at once, side by side in one window. Each tile is a
|
||||
full live terminal: it reads, it takes your keystrokes, and it shows at a glance whether
|
||||
its agent is working, idle, or waiting on you.
|
||||
|
||||
@@ -32,7 +32,8 @@ button in the header, beside Split, and enables `Ctrl+Shift+G`.
|
||||
joins it. Sessions started elsewhere (an agent, another device, a cron job) do not.
|
||||
|
||||
The layout follows the tile count: 1x1, 2x1, three side by side on a wide screen (else a
|
||||
2x2 with one empty slot), 2x2, 3x2, 3x3.
|
||||
2x2 with one empty slot), 2x2, 3x2. The grid holds at most six tiles, fewer when the
|
||||
window is too small for six; the picker and a tile's + say which limit applies.
|
||||
|
||||
## A tile
|
||||
|
||||
|
||||
Reference in New Issue
Block a user