Skip to content

fix: web terminal resize + mobile menu + session management#460

Open
dandelin wants to merge 13 commits intoasheshgoplani:mainfrom
dandelin:fix/web-terminal-resize
Open

fix: web terminal resize + mobile menu + session management#460
dandelin wants to merge 13 commits intoasheshgoplani:mainfrom
dandelin:fix/web-terminal-resize

Conversation

@dandelin
Copy link
Copy Markdown

@dandelin dandelin commented Mar 29, 2026

Summary

  • Terminal resize: Web terminal was not resizing because tmux attach -f ignore-size excludes the client from window size calculation. Added explicit tmux resize-window call after pty.Setsize() so programs inside the session observe updated dimensions.
  • Mobile menu: On Galaxy Fold and similar devices, the hamburger menu opened then immediately closed. Root cause was the virtual keyboard appearing (from xterm.js textarea focus) which triggered viewport-shift detection that closed the menu. Fixed by blurring the active element on menu open and adding grace-period guards to closeMenuForMobile() and the backdrop click handler.
  • Session management from web UI: Added two new API endpoints and corresponding UI controls:
    • POST /api/session/quick-create — creates a new session under a group with auto-generated name and Claude as default tool (mirrors TUI "N" shortcut)
    • POST /api/session/{id}/stop — kills the tmux session and removes it from the session list
    • "+" button on group rows for quick-create
    • "×" button on session rows for delete
  • Service worker cache: Bumped cache version to ensure clients pick up frontend changes.

Files changed

  • internal/web/terminal_bridge.go — explicit tmux resize-window on PTY resize
  • internal/web/handlers_session_mgmt.go — new quick-create and stop/delete handlers
  • internal/web/handlers_menu.go — session API router
  • internal/web/server.go — route registration
  • internal/web/static/app.js — mobile menu fix, API calls, action buttons
  • internal/web/static/styles.css — action button styles
  • internal/web/static/sw.js — cache version bump

Test plan

  • Open a session in the web terminal, resize browser window → terminal cols/rows update (tput cols; tput lines)
  • On a mobile device (Galaxy Fold or similar), tap hamburger menu → menu stays open, keyboard does not appear
  • Click "+" on a group → new Claude Code session is created and appears in the menu
  • Click "×" on a session → session is killed and removed from the list
  • Verify read-only mode blocks session creation/deletion

🤖 Generated with Claude Code

dan-tl and others added 8 commits March 29, 2026 16:45
The web terminal resize was not working because the tmux attach uses
ignore-size, which excludes this client from the window size calculation.
Add an explicit tmux resize-window call after pty.Setsize() so programs
inside the session observe the updated dimensions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the hamburger menu opens on mobile, it auto-focuses the filter
input after 60ms. On devices like Galaxy Fold, this triggers the
virtual keyboard, which fires a visualViewport resize event that
detects keyboard-open state and calls closeMenuForMobile().

Fix by focusing the first menu item (a button) instead of the filter
input, avoiding the keyboard trigger entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three issues combined to make the hamburger menu unusable on mobile:

1. Opening the menu did not blur the active element (often xterm.js's
   hidden textarea), so the virtual keyboard stayed up or reappeared,
   triggering a viewport-shift that was mis-detected as a keyboard
   event and closed the menu via closeMenuForMobile().

2. closeMenuForMobile() had no grace period, so any viewport jitter
   within the first few hundred milliseconds of the menu opening
   (toolbar hide, keyboard dismiss animation) could close it.

3. The backdrop click handler could fire from the same touch gesture
   that opened the menu on some Android browsers.

Fix by blurring the active element on menu open, adding a 400ms guard
to closeMenuForMobile(), a 300ms guard to backdrop clicks, and bumping
the service-worker cache version to ensure clients pick up the changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add two new API endpoints for session management from the web console:

- POST /api/session/quick-create: creates a new session under a group
  with auto-generated name and Claude as default tool, mirroring the
  TUI "N" (quick-create) shortcut.
- POST /api/session/{id}/stop: kills the tmux session for a running
  session.

Frontend changes:
- "+" button on group rows to quick-create a session in that group
- Stop button (■) on running session rows, visible on hover
- Both buttons respect read-only mode via backend enforcement

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Without setting inst.Command = tool, buildClaudeCommand receives an
empty base command and falls through to a shell-only start.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The stop button should remove the session entirely from the list,
not leave it in an idle/stopped state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Emoji wastebasket (U+1F5D1) renders as a square on some mobile
browsers. Use × (multiplication sign, U+00D7) which is universally
supported.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dandelin dandelin changed the title fix: propagate web terminal resize to tmux window fix: web terminal resize + mobile menu + session management Mar 29, 2026
dan-tl and others added 5 commits March 30, 2026 09:33
Add POST /api/session/{id}/start endpoint that calls Instance.Restart(),
mirroring the TUI Enter-key behaviour on error/stopped/exited sessions.
Includes WebSocket reconnection after start and state persistence.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
POST /api/session/restart-all endpoint restarts all non-running sessions.
Button appears in sidebar when error sessions exist, hidden otherwise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When all sessions in a group are deleted and a new one is created via +,
use GroupTree.DefaultPathForGroup() to resolve the project path from
group metadata instead of falling back to /tmp.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Forces browser to invalidate cached static assets (app.js, styles.css)
so restart-all button and quick-create path fix are picked up.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When deleting the last session in a group, save its ProjectPath as the
group's DefaultPath so subsequent quick-create inherits the correct
workspace. Also add fallback: infer path from group name as ~/name
when no DefaultPath or sessions exist.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

2 participants