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>
This commit is contained in:
394
docs/plans/2025-01-19-web-terminal-integration.md
Normal file
394
docs/plans/2025-01-19-web-terminal-integration.md
Normal file
@@ -0,0 +1,394 @@
|
||||
# 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
|
||||
|
||||
```bash
|
||||
npm install xterm xterm-addon-fit xterm-addon-web-links node-pty @ws/websocket
|
||||
```
|
||||
|
||||
### Backend Files
|
||||
|
||||
**`/services/terminal-service.js`** - Core terminal management
|
||||
```javascript
|
||||
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
|
||||
```javascript
|
||||
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`:**
|
||||
```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`:
|
||||
```json
|
||||
{"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
|
||||
|
||||
```json
|
||||
{
|
||||
"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)
|
||||
Reference in New Issue
Block a user