# Claude Code Web Interface
> A powerful web-based IDE for Claude Code CLI with session management, project organization, real-time chat, and AI-powered development tools.
[](https://nodejs.org/)
[](https://expressjs.com/)
[](https://www.sqlite.org/)
[](LICENSE)
[](https://github.rommark.dev/admin/ClaudeCLI-Web)
---
## Version History
### v1.2.0 (2026-01-20)
**🚀 Major Feature: CLI Session-Based Full Stack Mode**
This release introduces a simplified Full Stack mode using Claude Code CLI sessions instead of WebContainers, eliminating complex COOP/COEP header requirements and reducing bundle size by ~350KB.
#### Changes
**✨ New Features**
- **CLI Session-Based Terminal Mode** - Execute shell commands directly in Claude Code CLI sessions
- Spawns bash process for command execution
- Captures stdout, stderr, and exit codes
- Real-time output streaming via events
- No SharedArrayBuffer or special headers required
- **Shell Command API** - `POST /claude/api/shell-command` endpoint for executing commands
- **Smart Command Detection** - Automatically detects shell commands vs conversational messages
- Warns when conversational messages are sent in Terminal mode
- Auto-switches to Chat mode for non-shell commands
**🔧 Improvements**
- **Simplified Architecture** - Removes WebContainer dependency
- Faster startup (no 350KB bundle download)
- Better error handling
- Uses existing Claude Code infrastructure
- **Terminal Mode Reliability** - Fixed terminal creation failures
- Removed terminalManager reference errors
- Added fallback to native command execution
- **Project-Based Session Filtering** - Improved session filtering logic
- Path-based matching for accurate project assignment
- Better handling of nested directories
**🐛 Bug Fixes**
- Fixed terminal creation failure in Full Stack mode ("Failed to create terminal" error)
- Fixed WebContainer SharedArrayBuffer serialization errors
- Fixed session filtering showing unrelated sessions
- Fixed memory leaks from setInterval() calls
- Fixed XSS vulnerability in autocomplete (file names now escaped)
- Fixed sendMessage() undefined errors
**📝 Technical Details**
- `services/claude-service.js`:
- Added `executeShellCommand()` method for spawning bash processes
- Captures stdout/stderr with real-time event emission
- Returns Promise with exitCode, stdout, stderr
- `server.js`:
- Added `POST /claude/api/shell-command` endpoint
- Requires authentication via `requireAuth` middleware
- Validates sessionId and command parameters
- `public/claude-ide/chat-functions.js`:
- Rewrote `handleWebContainerCommand()` to use CLI sessions
- Added `sendShellCommand()` helper for API calls
- Smart command detection for shell vs conversational
- Auto-mode switching suggestions
**🔒 Security**
- All shell command endpoints require authentication
- Command injection protection via bash shell spawning
- Proper error handling for failed commands
**⚙️ Compatibility**
- Requires Claude Code CLI to be installed and accessible
- No special HTTP headers needed (removes COOP/COEP requirement)
- Maintains backward compatibility with Chat mode
---
### v1.1.0 (2026-01-19)
**🚀 Major Feature: HTTP Polling for Terminal Output**
This release addresses critical WebSocket connectivity issues in nginx reverse proxy configurations by implementing a robust HTTP polling mechanism for terminal output.
#### Changes
**✨ New Features**
- **HTTP Polling System** - Terminal output now uses HTTP polling instead of WebSocket for reliable data delivery
- Server buffers PTY output in memory with automatic cleanup
- Frontend polls every 100ms for new output entries
- Monotonically increasing index for efficient data retrieval
- Automatic cleanup of old output (5 minutes retention)
**🔧 Improvements**
- **Terminal Type Selection** - Added dropdown to choose between:
- Standard Shell (bash/zsh)
- Claude Code CLI (auto-launches with `--dangerously-skip-permissions`)
- **Debug Panel** - Always-visible debug panel for troubleshooting terminal issues
- **HTTP POST Input** - Commands sent via HTTP POST to bypass WebSocket send failures
- **Terminal Resize** - HTTP-based resize endpoint for terminal dimensions
**🐛 Bug Fixes**
- Fixed WebSocket closure with code 1006 (abnormal closure) in nginx configurations
- Fixed terminal command execution failing silently
- Fixed race condition in `switchToTerminal()` method
- Removed stabilization delays that caused WebSocket issues
- Fixed terminal type selector not appearing in modal
**📝 Technical Details**
- `services/terminal-service.js`:
- Added `bufferOutput()` method for capturing PTY data
- Added `getTerminalOutput()` for HTTP polling endpoint
- Added `resizeTerminal()` for HTTP resize handling
- Maintains WebSocket compatibility for legacy support
- `server.js`:
- `GET /claude/api/terminals/:id/output` - Poll for new output
- `POST /claude/api/terminals/:id/input` - Send command input
- `POST /claude/api/terminals/:id/resize` - Resize terminal
- `public/claude-ide/terminal.js`:
- Added `startPolling()` - 100ms interval polling
- Added `stopPolling()` - Clean polling termination
- Added `sendTerminalInput()` - HTTP POST for commands
- Added `sendTerminalResize()` - HTTP POST for resize
- Removed dependency on WebSocket for output display
**🔒 Security**
- All polling endpoints require authentication
- Output buffer size limited to 10,000 entries per terminal
- Automatic cleanup prevents memory exhaustion
**⚙️ Compatibility**
- Maintains backward compatibility with WebSocket connections
- Works seamlessly with nginx reverse proxy
- No configuration changes required
---
### v1.0.0 (Initial Release)
- Session management with real-time status tracking
- Project organization with smart suggestions
- WebSocket-based terminal integration
- XML tag system for file operations
- Obsidian vault integration
---
## Table of Contents
- [Features](#features)
- [Quick Start](#quick-start)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage Guide](#usage-guide)
- [API Reference](#api-reference)
- [Development](#development)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
---
## Features
### 🎯 Core Capabilities
- **Session Management** - Create, monitor, and control Claude Code sessions with real-time status tracking
- **Project Organization** - Group sessions into projects with smart suggestions and auto-assignment
- **Real-Time Chat** - WebSocket-powered communication with live command execution
- **File Browser** - Navigate, view, and edit files in your Obsidian vault
- **Terminal Integration** - Full terminal emulation with xterm.js and session picker
- **XML Tag System** - Structured AI operations for writing files, editing, and running commands
### 📦 What's New
#### Project Organization (Latest)
- ✨ Persistent projects as first-class entities
- ✨ Smart session assignment based on directory, recency, and name similarity
- ✨ Drag-and-drop session reassignment via context menu
- ✨ Soft delete with recycle bin (restore or permanent delete)
- ✨ Auto-assign new sessions to selected project
---
## Quick Start
### Prerequisites
- Node.js 18+ and npm
- Claude Code CLI installed
- Obsidian vault (optional, for session storage)
### 3-Minute Setup
```bash
# 1. Clone the repository
git clone https://github.rommark.dev/admin/ClaudeCLI-Web.git
cd ClaudeCLI-Web
# 2. Install dependencies
npm install
# 3. Start the server
npm start
# 4. Open your browser
# Navigate to http://localhost:3010/claude
# Login with: admin / !@#$q1w2e3r4!A
```
That's it! You're ready to use Claude Code through the web interface.
---
## Installation
### Production Deployment
#### Using Systemd (Recommended)
1. Copy the service file:
```bash
cp obsidian-web.service /etc/systemd/system/
```
2. Reload systemd and start:
```bash
sudo systemctl daemon-reload
sudo systemctl enable obsidian-web
sudo systemctl start obsidian-web
```
3. Configure Nginx reverse proxy (optional):
```bash
cp obsidian-nginx.conf /etc/nginx/sites-available/claude-web
sudo ln -s /etc/nginx/sites-available/claude-web /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```
#### Using PM2
```bash
npm install -g pm2
pm2 start server.js --name claude-web
pm2 save
pm2 startup
```
### Environment Variables
Create a `.env` file in the project root:
```bash
# Server Configuration
PORT=3010
SESSION_SECRET=your-secret-key-here
# Database
DB_PATH=./database.sqlite
# Claude Code
VAULT_PATH=/home/uroma/obsidian-vault
CLAUDE_CLI_PATH=claude # Path to claude command
```
---
## Configuration
### Server Settings
Edit `server.js` to customize:
- **PORT** (default: 3010) - Server port
- **VAULT_PATH** - Path to your Obsidian vault
- **SESSION_SECRET** - Session encryption key
### Authentication
Default credentials:
- Username: `admin`
- Password: `!@#$q1w2e3r4!A`
**⚠️ Change these in production!** Edit the `users` object in `server.js`:
```javascript
const users = {
admin: {
passwordHash: bcrypt.hashSync('your-secure-password', 10)
}
};
```
---
## Usage Guide
### Managing Sessions
#### Creating a Session
1. Click **"+ New Session"** on the landing page
2. Enter a working directory
3. (Optional) Select a project to auto-assign
4. Click **Create Session**
The session will start automatically and you can begin chatting with Claude.
#### Session Controls
- **Send Commands** - Type in the chat input and press Enter
- **View Output** - Real-time terminal output in the session panel
- **Terminate** - Click the stop button to end the session
- **Duplicate** - Clone a session with the same working directory
### Organizing Projects
#### Creating a Project
1. Navigate to **/projects** or click "Projects" in the header
2. Click **"+ New Project"**
3. Fill in the details:
- **Name** (required) - Project identifier
- **Path** (required) - Working directory
- **Description** - What this project is about
- **Icon** - Emoji for visual identification (📁, 🚀, etc.)
- **Color** - Theme color for the project card
4. Click **Save Project**
#### Assigning Sessions to Projects
**Automatic Assignment:**
- When creating a session, select a project from the dropdown
- The session will be automatically assigned to that project
**Manual Assignment:**
1. Go to the sessions landing page
2. Right-click on any session card
3. Select **"Move to Project"**
4. Choose from:
- 🎯 **Suggestions** - Smart recommendations based on directory, recency, and name
- 📂 **Show All Projects** - Full project list
- 📄 **Move to Unassigned** - Remove project association
#### Smart Suggestions
The system suggests projects based on:
- **Same directory** (90 points) - Exact path match
- **Subdirectory** (50 points) - Session path under project path
- **Used today** (20 points) - Active within last 24 hours
- **Used this week** (10 points) - Active within last 7 days
- **Similar name** (15 points) - Name overlap
Suggestions with 90+ points show 🎯, 50-89 show 📂, lower show 💡
#### Managing Projects
**Edit Project:**
- Right-click project card → Edit
- Modify description, icon, color, or path
- Save changes
**Delete Project:**
- Right-click project card → Move to Recycle Bin
- Project and all sessions are soft-deleted
- Can restore from recycle bin within 30 days
**Recycle Bin:**
- Click **"🗑️ Recycle Bin"** button on projects page
- Restore deleted projects (restores all sessions too)
- Permanently delete (cannot be undone)
### Using the Terminal
#### Opening a Terminal
1. Click **"+ New Terminal"** in the IDE
2. Select a working directory
3. The terminal will open with the Claude CLI ready
#### Session Picker
When creating a new terminal:
- Select from your last 10 sessions (web and local CLI sessions)
- Sessions are grouped by type:
- **Web Sessions** 💬 - Created through this interface
- **Local CLI Sessions** 💻 - Created using Claude Code CLI directly
- Click **"Create New Session"** to start fresh
#### Terminal Features
- **Tabbed Interface** - Multiple terminals open simultaneously
- **Status Indicators** - Running, Stopped, Error states
- **Session Attachment** - Click "🔗 Attach" to link terminal to a session
- **Auto-Focus** - Clicking a terminal automatically focuses it for keyboard input
### XML Tag System
Claude can use special XML tags to perform actions:
```xml
import React from 'react';
export default function Header() {
return
My App
;
}
export default function App() {
return
Old Content
;
}
export default function App() {
return
New Content
;
}
npm run dev
npm install @tanstack/react-query
```
These tags are automatically parsed and executed when Claude includes them in responses.
---
## API Reference
### Session Endpoints
#### Create Session
```http
POST /claude/api/claude/sessions
Content-Type: application/json
{
"workingDir": "/path/to/project",
"projectId": 1
}
```
#### List Sessions
```http
GET /claude/api/claude/sessions
```
#### Get Session Details
```http
GET /claude/api/claude/sessions/:id
```
#### Duplicate Session
```http
POST /claude/api/claude/sessions/:id/duplicate
```
#### Terminate Session
```http
DELETE /claude/api/claude/sessions/:id
```
### Project Endpoints
#### List Projects
```http
GET /api/projects
```
#### Create Project
```http
POST /api/projects
Content-Type: application/json
{
"name": "My API Project",
"path": "/home/uroma/my-api",
"description": "REST API development",
"icon": "🚀",
"color": "#4a9eff"
}
```
#### Update Project
```http
PUT /api/projects/:id
Content-Type: application/json
{
"description": "Updated description",
"icon": "⚡"
}
```
#### Delete Project (Soft Delete)
```http
DELETE /api/projects/:id
```
#### Restore Project
```http
POST /api/projects/:id/restore
```
#### Permanently Delete Project
```http
DELETE /api/projects/:id/permanent
```
#### Get Recycle Bin
```http
GET /api/recycle-bin
```
### Session Reassignment
#### Move Session to Project
```http
POST /claude/api/claude/sessions/:id/move
Content-Type: application/json
{
"projectId": 1
}
```
#### Get Project Suggestions for Session
```http
GET /api/projects/suggestions?sessionId=session-123
```
### WebSocket
#### Connect to Session
```javascript
const ws = new WebSocket('ws://localhost:3010/claude/api/claude/chat');
ws.onopen = () => {
ws.send(JSON.stringify({
type: 'auth',
sessionId: 'session-123',
token: 'your-session-token'
}));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'response') {
console.log(message.content);
}
};
```
---
## Development
### Project Structure
```
obsidian-web-interface/
├── services/
│ ├── claude-service.js # Claude Code CLI manager
│ ├── claude-workflow-service.js # Workflow orchestration
│ ├── terminal-service.js # Terminal (pty) management
│ ├── xml-parser.js # Custom XML tag processor
│ ├── response-processor.js # Response streaming
│ ├── tag-parser.js # Tag extraction
│ └── system-prompt.js # AI rules configuration
├── public/
│ ├── claude-ide/
│ │ ├── index.html # Main IDE interface
│ │ ├── ide.css # IDE styles
│ │ ├── ide.js # IDE JavaScript
│ │ ├── terminal.js # Terminal management
│ │ ├── terminal.css # Terminal styles
│ │ ├── chat-enhanced.js # Chat functionality
│ │ ├── preview-manager.js # Preview panel
│ │ └── sessions-landing.js # Sessions landing page
│ ├── css/ # Global styles
│ └── projects.html # Projects page
├── scripts/
│ └── migrate-to-projects.js # Database migration
├── server.js # Express + WebSocket server
├── package.json # Dependencies
└── database.sqlite # SQLite database (generated)
```
### Running in Development
```bash
# Install dependencies
npm install
# Start with hot-reload (if using nodemon)
npm run dev
# Or standard start
npm start
# Run database migration
npm run migrate:projects
```
### Database Schema
#### Projects Table
```sql
CREATE TABLE projects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
description TEXT,
icon TEXT DEFAULT '📁',
color TEXT DEFAULT '#4a9eff',
path TEXT NOT NULL,
createdAt TEXT NOT NULL,
lastActivity TEXT NOT NULL,
deletedAt TEXT NULL
);
```
#### Sessions Table
```sql
CREATE TABLE sessions (
id TEXT PRIMARY KEY,
projectId INTEGER NULL,
deletedAt TEXT NULL,
FOREIGN KEY (projectId) REFERENCES projects(id) ON DELETE SET NULL
);
```
### Adding New Features
1. **Backend** - Add endpoints to `server.js`
2. **Frontend** - Create components in `public/claude-ide/`
3. **Styles** - Add CSS to component-specific stylesheets
4. **Database** - Update schema in `services/database.js`
5. **Test** - Verify functionality and document API changes
---
## Troubleshooting
### Common Issues
#### Server won't start
```bash
# Check if port is in use
lsof -i :3010
# Kill existing process
kill -9
# Or change PORT in server.js
```
#### Claude CLI not found
```bash
# Verify claude is in PATH
which claude
# If not found, install Claude Code CLI
npm install -g @anthropic-ai/claude-code
```
#### Database errors
```bash
# Recreate database
rm database.sqlite
npm start # Will recreate automatically
```
#### WebSocket connection failed
- Check browser console for errors
- Verify server is running on correct port
- Ensure no firewall is blocking WebSocket connections
- Check CORS settings if using custom domain
#### Sessions not showing
- Verify `VAULT_PATH` points to correct directory
- Check file permissions on vault directory
- Ensure `Claude Sessions` folder exists
### Getting Help
- **Documentation** - Check `docs/` folder for detailed guides
- **Issues** - Report bugs on Gitea: https://github.rommark.dev/admin/ClaudeCLI-Web/issues
- **Logs** - Check server logs: `journalctl -u obsidian-web -f` (systemd) or console output
---
## Contributing
We welcome contributions! Here's how to get started:
### Development Workflow
1. **Fork** the repository on Gitea
2. **Clone** your fork: `git clone https://github.rommark.dev//ClaudeCLI-Web.git`
3. **Create a branch**: `git checkout -b feature/your-feature-name`
4. **Make changes** following the coding standards
5. **Test** thoroughly (manual and automated)
6. **Commit** with clear messages: `git commit -m "feat: add your feature"`
7. **Push** to your fork: `git push origin feature/your-feature-name`
8. **Create Pull Request** on Gitea
### Coding Standards
- Use ES6+ JavaScript features
- Follow existing code style and formatting
- Add comments for complex logic
- Update documentation for new features
- Test across browsers (Chrome, Firefox, Safari)
### Commit Message Format
```
():