Lane 5, PR 4a: Table mode's frame and the GM's board (#731; D111, D117, D118, D125–D130) #829

Merged
claude-bot merged 10 commits from build/lane5-p4a-board into main 2026-09-26 09:29:34 +00:00
Collaborator

Table mode, the GM's face (TABLE-1). This ports the old SessionShelf into the drawn board, built in lane 0's kit and D110's frame.

Routing (D111)

  • /sessions/:id/table is Table mode for everyone:
    • a GM of the campaign gets the board;
    • anyone else, or ?view=players, gets the players' face (today's SessionTable inside the Table frame; PR 6 redraws it).
  • /shelf redirects there and keeps its query.
  • "Players' view ↗" opens in a new tab.
  • This fixes a bug on main: every "Open the table" link used to land a GM on the players' read-only view.

The frame

  • Table mode replaces the Book: its own bar, no Contents, no footer, no live bar.
  • A skip link, and focus on arrival (#780).
  • The tab title names the campaign (#796).

The board

  • Cards: lore, generated, note and rule faces (#827's kinds), with pronouns and today's stat block.
  • Pin, reveal, promote: reveal targets per D36, with players, plus Discord where connected (D125).
  • Removal with Undo (D12, via restore).
  • Scenes: the scene bar and filing. "Add a card" (D119): Find something… or Write a note.
  • The stage: Previously on, the stage (D127), "Shown to the table", and the sweep ported into the kit Modal.

Keyboard (D117)

  • Move and Resize are in each card's menu: arrows move, Shift moves further, Enter drops, Esc cancels, and each move is announced.
  • The 1–9, [ and ] shortcuts work only on the board or stage; Ctrl K stays global.

Scaling (D118): stored px geometry is drawn in rems, so the board scales with D110's type.

Backend: the shelf's session label says "Session N" (D86), and promote's 422 carries entry_id.

Decisions: D125–D130 are the owner's yes to this PR's six departures, recorded in intro.md, with the catalogue rebuilt and every coverage script clean.

Deleted: SessionShelf.jsx and its tests.

Tests

  • Frontend: 176 files and 2409 tests, plus the tab-title test. eslint has 0 errors.
  • Backend: the shelf modules, 51.
  • Journeys: a full run gave 65 passed and 4 skipped.
  • Render check: 2560, 1440, 1024 and 390, light and dark, against TABLE-1's stills.

Still to come in lane 5:

  • 4b: the Scenes panel, the canvas and the quick note (built, on its branch).
  • 5: Find.
  • 6: the players' face, phone faces, the sweep's redraw, and the recording controls with the D123 window.
  • 7: J4.
  • 8: the demo seed.

🤖 Generated with Claude Code

**Table mode, the GM's face (TABLE-1).** This ports the old `SessionShelf` into the drawn board, built in lane 0's kit and D110's frame. **Routing (D111)** - `/sessions/:id/table` is Table mode for everyone: - a GM of the campaign gets the board; - anyone else, or `?view=players`, gets the players' face (today's `SessionTable` inside the Table frame; PR 6 redraws it). - `/shelf` redirects there and keeps its query. - **"Players' view ↗"** opens in a new tab. - **This fixes a bug on main:** every "Open the table" link used to land a GM on the players' read-only view. **The frame** - Table mode replaces the Book: its own bar, no Contents, no footer, no live bar. - A skip link, and focus on arrival (#780). - The tab title names the campaign (#796). **The board** - **Cards:** lore, generated, note and rule faces (#827's kinds), with pronouns and today's stat block. - **Pin, reveal, promote:** reveal targets per D36, with players, plus Discord where connected (D125). - **Removal with Undo** (D12, via `restore`). - **Scenes:** the scene bar and filing. **"Add a card" (D119):** Find something… or Write a note. - **The stage:** Previously on, the stage (D127), "Shown to the table", and the sweep ported into the kit `Modal`. **Keyboard (D117)** - Move and Resize are in each card's menu: arrows move, Shift moves further, Enter drops, Esc cancels, and each move is announced. - The 1–9, `[` and `]` shortcuts work only on the board or stage; Ctrl K stays global. **Scaling (D118):** stored px geometry is drawn in rems, so the board scales with D110's type. **Backend:** the shelf's session label says "Session N" (D86), and promote's 422 carries `entry_id`. **Decisions:** D125–D130 are the owner's yes to this PR's six departures, recorded in `intro.md`, with the catalogue rebuilt and every coverage script clean. **Deleted:** `SessionShelf.jsx` and its tests. **Tests** - **Frontend:** 176 files and 2409 tests, plus the tab-title test. `eslint` has 0 errors. - **Backend:** the shelf modules, 51. - **Journeys:** a full run gave 65 passed and 4 skipped. - **Render check:** 2560, 1440, 1024 and 390, light and dark, against TABLE-1's stills. **Still to come in lane 5:** - 4b: the Scenes panel, the canvas and the quick note (built, on its branch). - 5: Find. - 6: the players' face, phone faces, the sweep's redraw, and the recording controls with the D123 window. - 7: J4. - 8: the demo seed. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two leftovers from lane 5's PR 2, for the page PR that uses them:

- _session_label, which names the session in the wiki's harvest and unpin
  blocks, says "Session 14" (D86) rather than the title or the date; both
  stay as fallbacks.
- POST /shelf/{card}/promote's 422 is {detail, entry_id}: the entry whose
  open draft is in the way, so the sweep can offer to open it. A wiki card
  whose entry has gone is refused with entry_id null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D111: /sessions/:id/table is Table mode for everyone - the board for a GM
of the campaign, the players' face otherwise or with ?view=players (the
GM's Players' view, in a new tab). /shelf redirects there with its query;
Sweep the shelf opens ?sweep=1. Table mode is a frame of its own outside
the Book (no Contents, footer or live bar) with its own bar, skip link and
focus on arrival (#780), which the Book now honours coming back too.

The board ports SessionShelf into the drawing (TABLE-1): cold open, the
stage, the shelf head, the scene bar on PR 1's scenes, and cards with an
always-visible control row, a menu (scene, new scene, Move, Resize, take
it off with Undo via PR 2's restore), faces by kind (TB-087-097), pronouns
and today's stat block. Add a card (D119), reveal targets per D36, keys
only on the board and stage and Move/Resize from the keyboard (D117), and
rem-drawn geometry so the board scales with D110's type (D118).

SessionShelf.jsx and its test are deleted; the sweep moved with it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found by the render check: the card's own overflow cut its menu off, and
without a viewport height the body did not scroll under the bar. The
players' face, until PR 6, fills the frame with no gutter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merge remote-tracking branch 'origin/main' into build/lane5-p4a-board
All checks were successful
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 2m47s
CI / Backend lint (ruff) (pull_request) Successful in 1m16s
CI / Bot tests and audit (pull_request) Successful in 2m2s
CI / Bot/backend version sync (pull_request) Successful in 29s
CI / Does this change touch the recording path? (pull_request) Successful in 33s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Feedback site tests (pull_request) Successful in 2m7s
CI / Docker image build (pull_request) Successful in 3m12s
CI / Backend migration, tests, and audit (pull_request) Successful in 13m26s
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Successful in 14m5s
CI / Frontend tests, audit, and build (pull_request) Successful in 33m56s
b83cea9868
# Conflicts:
#	CHANGELOG.md
Sign in to join this conversation.
No description provided.