fix(tabs): review-driven hardening for the tab-layout foundation and vertical rail

Post-merge follow-ups from the deep review of #334 and #335, so they ship in
the same release as the features.

Tab-layout foundation (#335):
- PUT /api/session-order drops unknown/foreign ids again instead of 400ing
  the whole write, in both the owner and the admin path (single-user requests
  are the synthetic admin, so that path is the one the browser hits). The
  frontend debounces its reorder push and swallows errors, so a session
  deleted inside the debounce window silently cost the user the entire
  reorder - and the endpoint sits on the stable /api/v1 surface, where the
  pre-layout server merged leniently.
- A failed mux restore no longer locks explicit deletions into 500s for the
  process lifetime: runSessionDeletion and webviewDeleted degrade to
  best-effort without layout coordination, while the automated stale sweep
  (runStaleSessionCleanup) stays fail-closed.
- sse-events doc comment: no 'suppressed' hook event exists; hooks stay 8.
- registerSessionWithLayout resolves its owner through ownerLayoutKey()
  instead of a hardcoded '@single'.

Vertical rail (#334) - all rail-awareness gaps in sidebar-only predicates,
unified behind the new _isVerticalTabList() (sidebar OR rail):
- Drag-reorder read the insertion side from clientX in the rail, so
  before/after was effectively arbitrary on vertical rows; the drag-over
  indicators now draw as top/bottom edges there like the sidebar's.
- The active tab is scrolled into view in the rail (Alt+N/palette selection
  used to leave the row below the fold).
- Floating subagent/ultracode windows anchor to the RIGHT of rail tabs, and
  the connector redraw gates (render tail + strip scroll) cover the rail.
- Server-seeded tabOrientation is applied when the async settings load
  resolves, not only at boot, so a fresh device shows the rail immediately.
- The pre-paint script stamps data-tab-orientation and --tab-rail-width
  (sidebar-wins and solo carve-outs included), removing the flash of the
  header strip on every vertical-mode load.
- The session name font defaults to 12px, the sidebar's historical 0.75rem
  size, so installs that never touch the new slider are not restyled.

Also documents the rail in CLAUDE.md (second #sessionTabs host, mover
ordering, the axis-predicate rule) and gives tab-rail-resize.js its
@dependency/@loadorder header. Full gate green (6093 tests); the excluded
browser suite was run by hand - only the known environmental failures
(opencode/codex binaries) remain, identical to pristine master.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer
2026-08-24 00:59:48 +02:00
parent f3c615b669
commit 7a340fe7bc
12 changed files with 174 additions and 55 deletions
+6 -4
View File
@@ -17173,11 +17173,11 @@ html[data-session-list="sidebar"] .session-sidebar .tab-name {
html[data-session-list='sidebar'] .session-sidebar .tab-name {
flex: 0 1 auto;
white-space: nowrap;
font-size: var(--session-sidebar-name-font-size, 14px);
font-size: var(--session-sidebar-name-font-size, 12px);
}
html[data-tab-orientation='vertical'] .tab-rail .session-tab .tab-name {
font-size: var(--session-sidebar-name-font-size, 14px);
font-size: var(--session-sidebar-name-font-size, 12px);
}
html[data-session-list='sidebar'] .session-sidebar .tab-actions,
@@ -17198,11 +17198,13 @@ html[data-session-list="sidebar"] .session-sidebar .session-tab.active .tab-clos
/* Drag-reorder indicators become horizontal edges. The class names stay
drag-over-left / drag-over-right (they read as before/after now) so app.js,
the base rules above and the generated gesture bundle need no renaming. */
html[data-session-list="sidebar"] .session-sidebar .session-tab.drag-over-left {
html[data-session-list="sidebar"] .session-sidebar .session-tab.drag-over-left,
html[data-tab-orientation='vertical'] .tab-rail .session-tab.drag-over-left {
box-shadow: 0 -2px 0 0 var(--accent);
}
html[data-session-list="sidebar"] .session-sidebar .session-tab.drag-over-right {
html[data-session-list="sidebar"] .session-sidebar .session-tab.drag-over-right,
html[data-tab-orientation='vertical'] .tab-rail .session-tab.drag-over-right {
box-shadow: 0 2px 0 0 var(--accent);
}