Claude parsed view:
- Tables now require a real column-border row (┌┬┐/├┼┤); welcome/notice boxes
(rounded ╭╰, single │ column) no longer render as garbled tables
- Tighten code detection so log lines / prose with parentheses aren't boxed as code
- Status bar no longer eats prose/question lines containing a "·"; pull ctx%/model
from combined statuslines
- Renderer hashes full block content, so streaming updates re-render instead of
freezing ("parsed, then not")
- Left-normalize TUI lines shoved to the right on wide panes (text/response/tool
output only; code/tables/diffs untouched)
Scroll history:
- Stop the loader flash-loop once scrollback is exhausted (noMoreHistory guard)
- Keep the reading position on load; older content is revealed by scrolling up
further (preserve-position)
ngrok:
- No-cache pass-through service worker adds the ngrok-skip-browser-warning header
to navigations so the free-tier interstitial is skipped on revisits
(replaces the old caching SW; sw-unregister removed)
Send:
- Server awaits send_text before pressing Enter so the submit can't race the
bracketed paste (fixes "had to press Enter twice")
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The periodic Claude-mode re-check (setInterval 8s) called
setClaudeMode(false) on plain/codex surfaces, which ran
claudeRenderer.clear() unconditionally. clear() empties the shared
output element (this.el), blanking live terminal/codex content until
the next repaint — perceived as text fading out then back every 8s.
- app.js: remove the 8s claude re-check interval
- terminal-view.js: only clear the renderer on an actual mode
transition (changed), so redundant setClaudeMode/setCodexMode(false)
no longer wipes the shared output
- index.html: bump terminal-view.js v12, app.js v21
Verified deterministically in Playwright: pre-fix the output wiped
48->0 ~350ms after each 8s /api/claude-surfaces fetch; post-fix 18s
window shows 0 fetches and content intact.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Scrolling:
- Fix snap-back race: render() read a stale autoScroll cache (updated only
on async scroll events), yanking scrolled-up users back to the bottom
during live output. Now measure the real bottom position from the DOM at
render time and gate auto-follow on an explicit autoScroll flag.
- Restore scroll-to-top history loading; add a wheel-up handler so desktop
(no touch, screen fits viewport → no scroll room → no scroll event) can
still load scrollback. Resume live updates on scroll-to-bottom.
- Remove the auto-load-when-fits path that permanently froze live updates.
- terminal-container: touch-action pan-y, overflow-y scroll, overscroll
contain; drop terminal-output min-height:100%; desktop app-container
explicit 100dvh height.
- gestures.js touchmove → passive (let Safari composite child scroll).
Claude-mode detection:
- Match node-wrapped `claude` processes (check all ps args tokens).
- Enumerate ALL workspaces via `cmux tree --all`, not just the active
window that the workspace.list socket returns.
- Don't cache empty results; keep last-known-good to survive transient
ps/socket failures. Periodic client-side re-check.
Misc:
- Desktop: Enter sends, Shift/Cmd+Enter newline (mobile unchanged).
- Keyboard area touch-action:none (no vertical drift), key row pan-x.
- claude-parser _stripAnsi also strips C0/C1 control chars.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2 months ago
19 changed files with 331 additions and 186 deletions