Files
SuperCharged-Claude-Code-Up…/docs/plans/2025-01-19-web-terminal-integration.md
uroma 0dd2083556 Initial commit: Obsidian Web Interface for Claude Code
- Full IDE with terminal integration using xterm.js
- Session management with local and web sessions
- HTML preview functionality
- Multi-terminal support with session picker

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 16:29:44 +00:00

13 KiB

Web-Based Terminal Integration for Claude Code CLI

Date: 2025-01-19 Status: Designed Author: Claude (with user collaboration)

Overview

Add full-featured web-based terminals to the Claude Code web interface, allowing users to open multiple terminal tabs that can run independently or attach to Claude Code sessions. Users get full interactive shell access with xterm.js, powered by node-pty and WebSocket communication.

Design Philosophy

Power + Simplicity: Provide full shell capabilities (as user already has SSH access) with intelligent defaults and easy restoration. No artificial restrictions - the user is the developer and knows what they're doing.

Core Features

1. Terminal Panel

  • Location: Dedicated "🖥️ Terminal" tab in IDE navbar (next to Chat, Files, etc.)
  • Multi-tab: Open unlimited terminals, switch between them
  • Tab information: Shows session ID, mode, current directory
  • Controls: New terminal, close, mode toggle, clear screen

2. Terminal Modes

  • Session Mode (🔵): View Claude Code CLI output (stdio/stderr from session process)
  • Shell Mode (🟢): Independent shell for running commands
  • Mixed Mode (🟡): Both session output AND shell access (default)

3. Directory Selection

  • Modal picker when creating new terminal
  • Shows recent directories (last 5 used)
  • Custom path input
  • All terminals inherit chosen working directory

4. Session Attachment

  • Attach any terminal to a Claude Code session
  • See what Claude "sees" - file operations, tool output
  • Switch between viewing session and running commands
  • Perfect for debugging and understanding Claude's actions

5. Auto-Restore

  • Always saves terminal setup automatically
  • On page reload/refresh: all terminals close
  • Shows: "📝 Previous session: 3 terminal(s) [Restore All] [Dismiss]"
  • One-click restore recreates terminals with same configuration
  • Fresh PTY processes, but same directories/sessions/modes

6. Security & Safety

  • Warning modal on first terminal use (can be dismissed)
  • Full shell access - no artificial restrictions (user has SSH anyway)
  • All commands logged to .claude-ide/terminal-logs.jsonl
  • No sudo blocking - user controls their own system
  • Processes killed on page close (no orphans)

Architecture

Frontend Components

Terminal View (new tab)
  ├── Terminal Header
  │   ├── Terminal Tabs (list of open terminals)
  │   └── [+ New Terminal] button
  └── Active Terminal Container
      ├── Terminal Toolbar
      │   ├── Terminal info (ID, path, mode)
      │   └── Controls (mode toggle, clear, close)
      └── xterm.js Container

Backend Architecture

Frontend (xterm.js)
    ↓ WebSocket
TerminalController (Node.js)
    ↓ spawn + pty
Pseudo-terminal (node-pty)
    ↓ bidirectional I/O
    ├── Shell Process (bash/zsh)
    └── OR Claude Session Process

Data Flow

Creating a Terminal:

  1. User clicks "+ New Terminal"
  2. Directory picker modal shows
  3. User selects directory
  4. POST /claude/api/terminals with { workingDir, sessionId?, mode }
  5. Backend creates PTY with shell in working directory
  6. Returns terminal ID
  7. Frontend opens WebSocket: ws://host/claude/api/terminals/{id}/ws
  8. xterm.js initializes, begins receiving/sending I/O
  9. If attached to session, pipe session output to PTY

Terminal I/O Loop:

User types in xterm.js
    ↓ WebSocket send
Backend receives message
    ↓ Write to PTY
Shell/Claude process executes
    ↓ PTY emits data
Backend reads PTY output
    ↓ WebSocket send
xterm.js displays data

Technical Implementation

New Dependencies

npm install xterm xterm-addon-fit xterm-addon-web-links node-pty @ws/websocket

Backend Files

/services/terminal-service.js - Core terminal management

class TerminalService {
    constructor()
    createServer(server)              // Setup WebSocket server
    createTerminal(options)            // Create PTY with shell
    handleConnection(terminalId, ws)  // WebSocket I/O handling
    attachToSession(terminal, session) // Pipe session output to PTY
    closeTerminal(terminalId)          // Kill PTY process
}

New API Endpoints:

  • POST /claude/api/terminals - Create terminal
  • DELETE /claude/api/terminals/:id - Close terminal
  • GET /claude/api/terminals - List active terminals
  • POST /claude/api/terminals/:id/attach - Attach to session
  • GET /claude/api/claude/terminal-restore - Get saved state
  • GET /claude/api/files/recent-dirs - Get recent directories

Frontend Files

/public/claude-ide/terminal.js - Terminal manager

class TerminalManager {
    loadXTerm()                      // Load xterm CSS dynamically
    createTerminal(options)          // Create terminal UI + WebSocket
    switchToTerminal(id)             // Switch active terminal
    closeTerminal(id)                 // Close terminal
    setMode(id, mode)                // Change session/shell/mixed mode
    restoreTerminals(savedState)      // Restore previous session
}

Modifications to /public/claude-ide/ide.js:

  • Add terminal view handling
  • Add restore prompt logic
  • Integrate with existing navigation

Modifications to /public/claude-ide/index.html:

  • Add Terminal tab to navbar
  • Add terminal-view div to main content

Key Features Detail

Mode Switching

Session Mode:

  • Shows only Claude Code CLI output
  • Read-only view into what Claude does
  • Useful for debugging tool usage, file operations

Shell Mode:

  • Independent bash/zsh shell
  • User types commands directly
  • No session output shown
  • Like opening a terminal anywhere else

Mixed Mode (Default):

  • Shows both session output AND shell commands
  • User can type commands while seeing Claude's work
  • Perfect for development workflow
  • Toggle which output is visible

Session Attachment

When attaching terminal to a session:

  • Backend creates pipe from session.stdout to PTY input
  • Session.stderr shown in red color
  • Session messages appear interleaved with shell output
  • User can interact with both simultaneously

Directory Picker

Shows recently used directories:

  • Current session's working directory
  • Last 5 directories used in any terminal
  • Obsidian vault paths
  • User can type custom path

State Persistence

Saved in .claude-ide/terminal-state.json:

{
  "timestamp": "2025-01-19T14:30:00Z",
  "terminals": [
    {
      "id": "term-1",
      "workingDir": "/home/uroma/obsidian-vault",
      "sessionId": "session-abc",
      "mode": "mixed",
      "order": 0
    }
  ]
}

Restoration:

  • On page load, check for saved state
  • If found, show non-intrusive toast
  • "Restore All" recreates terminals (new PTY processes)
  • "Dismiss" ignores saved state
  • Toast auto-dismisses after 30 seconds

Security Considerations

Logging

All commands logged to /home/uroma/obsidian-vault/.claude-ide/terminal-logs.jsonl:

{"timestamp":"2025-01-19T14:30:00Z","terminalId":"term-1","command":"ls -la","user":"uroma"}

First-Time Warning

Modal shown on first terminal use:

⚠️ Terminal Access
You're about to open a full shell terminal.
This gives you complete command-line access.

[ ] Don't show this warning again

[Cancel]  [Open Terminal]

Resource Limits

  • No hard limit on terminal count (practical limit ~10)
  • Each terminal ~10-20MB memory
  • All terminals killed on:
    • Page close
    • Browser crash
    • Server restart
    • User logout

UI Design

Terminal Panel Layout

┌─────────────────────────────────────────────────────────┐
│ 🖥️ Terminals                              [+ New]       │
├─────────────────────────────────────────────────────────┤
│ ┌───────────────────────────────────────────────────┐  │
│ │ session-abc123 │ ▀ │ 🟡 Mixed │ ~/obsidian-vault │  │
│ │ [Close] [Split]                                  │  │
│ ├───────────────────────────────────────────────────┤  │
│ │ $ npm test                                        │  │
│ │ Tests running...                                  │  │
│ │ ✓ Test 1 passed                                   │  │
│ │ ✓ Test 2 passed                                   │  │
│ │                                                   │  │
│ └───────────────────────────────────────────────────┘  │
│                                                         │
│ [Terminal Tab 2] [Terminal Tab 3]                      │
└─────────────────────────────────────────────────────────┘

Keyboard Shortcuts

  • Ctrl+Shift+T - Open new terminal
  • Ctrl+Shift+W - Close current terminal
  • Ctrl+Tab - Next terminal tab
  • Ctrl+Shift+Tab - Previous terminal tab
  • Ctrl+Shift+M - Toggle terminal mode

Color Scheme

xterm.js theme matching existing IDE:

  • Background: #1a1a1a
  • Foreground: #e0e0e0
  • Cursor: #4a9eff
  • Selection: rgba(74, 158, 255, 0.3)
  • Session stderr: Red \x1b[31m

Implementation Plan

Phase 1: Backend Setup

  1. Install dependencies: xterm, node-pty, ws
  2. Create terminal-service.js
  3. Add API endpoints to server.js
  4. Implement WebSocket server
  5. Test terminal creation and I/O

Phase 2: Frontend Terminal Panel

  1. Add terminal view to index.html
  2. Implement terminal.js with xterm.js integration
  3. Create directory picker modal
  4. Implement tab management
  5. Add keyboard shortcuts

Phase 3: Session Integration

  1. Implement session attachment logic
  2. Add mode switching (session/shell/mixed)
  3. Pipe session output to PTY
  4. Test with active Claude Code sessions

Phase 4: Polish & Features

  1. Implement auto-save/restore
  2. Add first-time warning modal
  3. Implement command logging
  4. Add recent directories tracking
  5. Test edge cases

Phase 5: Testing

  1. Test multiple terminals simultaneously
  2. Test session attachment
  3. Test mode switching
  4. Test restore after page refresh
  5. Test with various commands (vim, htop, etc.)

Success Criteria

  1. Can open unlimited terminal tabs
  2. Each terminal runs in chosen directory
  3. Can attach terminal to Claude Code session
  4. Can switch between session/shell/mixed modes
  5. Terminal I/O is responsive (no lag)
  6. Terminals restore after page refresh
  7. All commands are logged
  8. Works with existing sessions
  9. Keyboard shortcuts work correctly
  10. No memory leaks or orphaned processes

Future Enhancements (Not in MVP)

  • Split terminals - Divide terminal panes vertically/horizontally
  • Terminal sharing - Share terminal URL with collaborators
  • Command history - Show history of commands across terminals
  • Search in terminal - Search/backscroll through output
  • Download output - Save terminal output to file
  • Multiple shells - Support zsh, fish, pwsh, etc.
  • Custom fonts/themes - User-configurable appearance

Files to Create

  1. /services/terminal-service.js - Terminal backend logic
  2. /public/claude-ide/terminal.js - Terminal frontend manager
  3. /public/claude-ide/terminal.css - Terminal panel styles
  4. /home/uroma/obsidian-vault/.claude-ide/terminal-logs.jsonl - Command log

Files to Modify

  1. /server.js - Add terminal API endpoints
  2. /public/claude-ide/index.html - Add Terminal tab and view
  3. /public/claude-ide/ide.js - Add terminal view navigation

Dependencies

{
  "xterm": "^5.3.0",
  "xterm-addon-fit": "^0.8.0",
  "xterm-addon-web-links": "^0.9.0",
  "node-pty": "^1.0.0",
  "ws": "^8.16.0"
}

Notes

  • PTY processes cannot be serialized, so restoration creates new processes
  • WebSocket reconnection is supported if network drops temporarily
  • Process cleanup happens automatically on page close/navigation
  • Memory usage per terminal is ~10-20MB (practical limit ~50 terminals)
  • CPU usage is minimal when terminals are idle
  • Security is maintained by session-based authentication
  • Logging is for debugging and auditing, not surveillance

Design Status: Complete and approved Ready for Implementation: Yes Estimated Implementation Time: 3-4 days (5 phases)