8 Commits (1f50014296150e90fac77ffff7bd2246f8f743b6)
 

Author SHA1 Message Date
I Luk Kim 1f50014296 fix: scroll reliability, Claude-mode detection, desktop send
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
I Luk Kim 577b4d749b feat: fix one-press send, add Codex parsed view
Send button:
- submitText() sends text without trailing "\n", then a discrete Enter
  key event after 100ms. cmux delivers send_text as a bracketed paste,
  so a trailing newline became a literal newline in the Claude/Codex
  input box instead of submitting — this required a second (empty)
  press to actually send. Now one press = the full type-then-Enter
  sequence. Fixes Codex always needing two presses and Claude 4+ line
  messages not sending / rendering mid-state.
- data-text shortcut keys now type then send Enter separately
- mousedown.preventDefault keeps soft keyboard up so first tap submits
- Remove IME composition Enter handler (textarea Enter = newline now)

Codex view:
- New codex-parser.js / codex-renderer.js for OpenAI Codex CLI surfaces
- /api/codex-surfaces endpoint; generalize surface-ref lookup into
  _getSurfaceRefsForProcess() (claude + codex)
- app.js updateCodexMode(), terminal.setCodexMode(), codex-mode body
  class (mutually exclusive with claude-mode)

Claude mode:
- Auto-load scrollback when content fits the viewport
- Trim claude-keyboard.js scaffolding; parser/renderer/CSS tweaks

Bump virtual-keyboard.js?v=9 cache-bust.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3 months ago
I Luk Kim efb0be7896 feat: Claude mode UI improvements and stability enhancements
Claude mode view:
- Context-aware action row replaces all-keys row in Claude mode
  (mode pill, stop button, arrows; selection→option buttons; thinking→pulsing stop)
- Thinking block detection and pulse animation
- Response/text blocks preserve ANSI colors via ansiToHtml()
- Tool-use body collapsible for long outputs (>5 lines)
- Context usage progress bar in status bar (green/yellow/red)
- Mode pill group shows all 3 modes with active highlight + pop animation
- Selection options show focused state and keyboard shortcut hint
- Prompt turn boundaries with visual spacing

Stability:
- WebSocket heartbeat (app-level ping/pong, 15s timeout)
- WS max payload 1MB limit
- Auth rate-limit map periodic cleanup
- Socket connection timeout (10s)
- Terminal line buffer cap (10,000 lines)
- Password masking in console output

UX:
- Scrollback loading indicator
- Code/diff/tool-result copy buttons
- Collapsible tool results (>8 lines)
- Modifier key box-shadow transition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 months ago
I Luk Kim a3a607d1f4 chore: clean up project, add README, consolidate duplicate code
- Remove debug artifacts (debug-surface15.png, .playwright-mcp/, dev-notes.md)
- Add .playwright-mcp/ to .gitignore
- Add comprehensive README.md with architecture docs
- Consolidate duplicate _parseStatus() into Sidebar.parseStatus() static method
- Consolidate duplicate ANSI stripping into ClaudeRenderer._stripAnsi()
- Fix ANSI regex to handle OSC sequences in renderer
- Add ║ (U+2551) to box-drawing character sets in parser/renderer
- Guard scrollback handler against empty terminal state
- Remove duplicate process.noDeprecation from src/index.ts
- Remove debug console.log from scroll-request handler

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 months ago
I Luk Kim e411ab38db feat: auto-load scrollback on scroll-to-top, CLI packaging, misc fixes
- Auto-request scrollback history when user scrolls to top of terminal
- Preserve scroll position when prepending scrollback content
- Add files/prepublishOnly to package.json for npm install -g support
- Suppress url.parse() deprecation warning from Express internals
- Fix reconnect: re-subscribe to surface after auth-ok on reconnect
- Improve iOS background recovery with visibility API + elapsed check
- Harden ANSI stripping to handle OSC and other escape sequences

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 months ago
I Luk Kim 5b9780fafb feat: Claude mode UI, status indicators, IME fix, tunnel support
- Add Claude Code parsed view with block-based rendering (prompt, tool-use,
  tool-result, code, diff, table, selection options, status bar)
- Add session status dots in sidebar and top bar (idle=yellow, working=green
  with pulse animation) parsed from terminal title characters
- Differentiate active input prompt vs previous submitted prompts with
  distinct background colors
- Fix Korean IME composition issue (last character on next line on Enter)
- Fix CSP inline script violation by moving to external sw-unregister.js
- Add per-block DOM diffing to prevent layout shifts on re-render
- Strip box-drawing borders from tool-result blocks for stable layout
- Add ngrok tunnel support, replace qrcode with qrcode-terminal
- Add Claude-specific keyboard action bar with mode toggle and shortcuts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 months ago
I Luk Kim 239c6d2ef6 feat: add Shift modifier key and fix keyboard toggle behavior
- Add Shift modifier button (⇧) alongside Ctrl/Alt with tap/double-tap lock support
- Server-side Shift key parsing (Shift-Tab → shift+tab, etc.)
- Keyboard toggle now only hides key rows, keeping text input always visible
- Fix shortcut-keys row: horizontal scroll instead of wrapping

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 months ago
I Luk Kim 8bcd7eacd8 feat: initial commit with UX improvements
Add full project including 12 UX improvements: wider gesture edge zone (50px),
prefers-reduced-motion support, additional shortcut keys (^A ^E ^R ^W ^U) and
PageDown, Escape to close sidebar, haptic feedback, key repeat for arrow keys,
sidebar loading/empty state, login loading state, reconnect status indicator,
terminal dim on disconnect, QR modal focus management, and desktop keyboard toggle.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
5 months ago