Skip to content

feat: pin a session; clicking no longer reorders the list; bigger work-row marks on iOS - #653

Merged
jonwiggins merged 2 commits into
mainfrom
feat/pin-sessions
Oct 7, 2026
Merged

jonwiggins merged 2 commits into
mainfrom
feat/pin-sessions

Conversation

@jonwiggins

@jonwiggins jonwiggins commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

What

Pin a session. In the sessions rail a thumbtack appears at the top right of a session card on hover, beside the "open side by side" button, which moves over to make room. Click it and the pin turns solid; the session jumps to the top of its group and stays there, across reloads and devices, until you click it again.

Also, from the same ask: the iOS work rows' harness, trigger and run-location marks were too small and are now readable.

How

  • Server: pinned_at on local_terminals (migration 1792000000_local_terminal_pins), pinnedAt on the shared LocalTerminal type (Swift and Kotlin regenerated), POST / DELETE /api/local/terminals/:id/pin answering the updated row (404 when not yours), pinTerminal / unpinTerminal idempotent and publishing local:changed so other tabs and the apps re-sort.
  • Web: session-order.ts puts pinned sessions first within the live and finished sections (their own usual order among themselves); the rail's row gains the pin button (session-pin-<id>, aria-pressed), optimistic so the row moves at once and the feed's next refresh agrees; the split button keeps its behaviour. The pinned glyph is the heading colour with a filled icon, so it reads solid white on the dark theme and solid dark on the light one.
  • iOS: pinned-first ordering in the Work feed and the Overview's needs-you list, Pin / Unpin as a leading swipe and a context-menu entry on session rows, a small filled pin on pinned rows. Work-row marks (when / where / who / then) go from a 12pt box with 11pt brand marks to a 17pt box with 17pt brand marks and 15pt SF symbols, spacing 4 → 6pt; the detail headers' inline harness mark 12 → 17pt. Dynamic Type scaling kept.
  • Android: the same ordering in the machine page's groups and the Work feed's ranks, Pin to top / Unpin in the row's long-press menu and the terminal screen's overflow menu, a filled pin on pinned rows.
  • Docs: docs/optio-local.md; CHANGELOG.

Also: clicking a session no longer moves it

Jon noticed sessions still jumping in the rail. Lists order sessions by when you last typed into them, but the server counted every input frame as typing. The browser's terminal sends more than keystrokes on that path: the focus-in report a click produces when the program has focus reporting on (Claude Code does), mouse reports, and the emulator's own answers to the program's queries. Opening or clicking a session therefore stamped it as "just typed into" and jumped it to the top. isTerminalTyping in @optio/shared (query replies, mouse and focus reports excluded; escape-prefixed keys, pastes and ⌃F3 kept) now gates the interaction stamp in ws/local-terminal-stream.ts; the web's pointer-report classifier moved to the shared module so both sides agree. Tests: 7 shared cases, the web's 11 stream-policy cases.

Tests

  • Playwright e2e/session-pin.spec.ts: two live shells on one fake daemon; hover → pin → the row is first and aria-pressed; the server row has pinnedAt; a reload keeps the order; unpin restores it (passes, 25 s).
  • Web unit: session-order.test.ts +3 (pinned first within a section, pinned finished rows, null vs missing); web tier 739 / 739.
  • API: integration local-terminal-pin.int.test.ts (pin, idempotent pin time, unpin, re-unpin); unit tier 2960 / 2960; OpenAPI dump valid with the two routes.
  • iOS: build + 216 unit tests (+2 for ordering and the optimistic toggle). Android: assembleDebug + unit tests green (+6 test classes touched).
  • pnpm turbo typecheck 13 / 13, Prettier clean, migration prefix check clean.

@jonwiggins jonwiggins changed the title feat: pin a session to the top of the sessions list; bigger work-row marks on iOS feat: pin a session; clicking no longer reorders the list; bigger work-row marks on iOS Oct 7, 2026
@jonwiggins
jonwiggins merged commit 4857756 into main Oct 7, 2026
11 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant