Skip to content

feat: remote web terminal#161

Open
PrisedRabbit wants to merge 24 commits intojamesrochabrun:mainfrom
PrisedRabbit:feature/web-terminal-mvp
Open

feat: remote web terminal#161
PrisedRabbit wants to merge 24 commits intojamesrochabrun:mainfrom
PrisedRabbit:feature/web-terminal-mvp

Conversation

@PrisedRabbit
Copy link
Copy Markdown
Contributor

@PrisedRabbit PrisedRabbit commented Mar 3, 2026

Web Terminal — embedded web http server for AgentHub sessions

Adds a fully self-contained web terminal server to AgentHub. When enabled, AgentHub starts a local HTTP + WebSocket server that serves an xterm.js-powered page,
letting you view and interact with any focused terminal session from any browser on the same network — including mobile.

What's included

Server (Swift)

  • AgentHubWebServer — raw NIO-based TCP listener, zero external dependencies. Handles HTTP (static files + /api/sessions JSON) and WebSocket upgrades (RFC 6455) in
    a single actor.
  • TerminalStreamProxy — main-actor bridge that pipes PTY output to all WebSocket clients watching a session, and forwards keyboard input and resize events back to
    the PTY.
  • TerminalListener protocol extended with onResize(cols:rows:) so the web client stays in sync when the Mac terminal window is resized.
  • Server starts/stops in AppDelegate, controlled by a UserDefaults toggle (default: off).

Web client (single HTML file, xterm.js)

  • Session list sidebar (desktop) / top-sliding drawer (mobile)
  • Live PTY streaming over WebSocket — text input, Ctrl+C, Esc, Tab
  • Directional resize: App → browser
  • Dark/light theme toggle, persisted in localStorage
  • CSS scale system: desktop renders at 100%, mobile auto-fits width with user-adjustable zoom (30–250%)
  • Mobile toolbar (Esc / Tab / Ctrl+C / zoom) hidden on desktop
  • Session ID persisted in URL hash — page refresh reconnects to the last session automatically
  • iOS safe-area insets, visualViewport keyboard handling, touch scroll

Settings

  • New "Web Terminal" section in Settings: on/off toggle, port stepper (1024–65535), live connection URL with copy button, "restart to apply changes" hint
  • Local WiFi IP resolved via getifaddrs for easy mobile access

How to use

  1. Settings → Web Terminal → enable toggle
  2. Restart the app
  3. Open the displayed URL in any browser

photo_2026-03-04 13 50 38

…TY resize

- index.html: mobile-responsive layout with bottom drawer, dark/light theme toggle,
  session name sync, short project path display, iOS touch fixes
- TerminalStreamProxy: 512KB scrollback buffer with replay on connect, resize() method
- ManagedLocalProcessTerminalView: resizePTY(cols:rows:) for web client resize requests
…ixes

- Add bottom toolbar with Esc, Tab, Ctrl+C keys for mobile
- Zoom controls moved to toolbar with clean 10% steps (default 180%)
- Fix CSS scale: use correct xterm.js API path (css.cell.width)
- Fix touch scroll with custom handler (CSS scale breaks xterm internals)
- Toolbar buttons preserve keyboard focus state via touchstart preventDefault
- Session drawer slides from top on mobile
- Sync custom session names to web client via WebSessionInfo.customName
- Anchor terminal to bottom (input line always visible)
- Clip scaled terminal with outer wrapper to eliminate dead scroll space
…ersistence

- Add "Web Terminal" section to Settings with on/off toggle (default off),
  port stepper, local IP connection info with copy button
- Change web server default to off (false)
- Hide mobile toolbar (Esc/Tab/Ctrl+C/zoom) on desktop, show only on mobile
- Desktop always renders terminal at 100% scale, no zoom transform
- Persist selected session ID in URL hash; auto-reconnect on page refresh
- Web client: intercept compositionend on xterm textarea to track
  chars since last word boundary; prepend backspaces before composed
  replacement so Android/iOS autocorrect doesn't duplicate text
- Debug builds now use port 8081, release stays on 8080
- Fix "connecting" forever bug: pending sessions configured with sessionId:nil
  were never registered in TerminalStreamProxy; add registerWithProxy(sessionId:)
  called from transferTerminal when pending→real transition completes
- Add POST /api/sessions/{id}/focus endpoint: clicking a session in web client
  now focuses it in the Mac app (updates primarySessionId, NSApp.activate)
- Fix provider-prefixed item ID format: ProviderMonitoringItem.id uses
  "claude-{sessionId}" format, set webFocusedSessionId with correct prefix
@PrisedRabbit PrisedRabbit changed the title Feature/web terminal mvp feat: web terminal mvp Mar 9, 2026
@PrisedRabbit PrisedRabbit changed the title feat: web terminal mvp feat: remote web terminal Mar 9, 2026
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