Document web terminal feature across all docs

Adds web terminal documentation to README (architecture, key files),
HOW-TO-USE (setup guide, usage, security tips), TECHNICAL (system
diagram, communication flow, dependencies, project structure), and
CLAUDE.md (backend structure).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-17 20:09:05 -07:00
parent 9ee0d34c19
commit 6369f7e0a8
4 changed files with 94 additions and 7 deletions

View File

@@ -62,7 +62,7 @@ docker exec stdout → tokio task → emit("terminal-output-{sessionId}") → li
- **`components/terminal/TerminalView.tsx`** — xterm.js integration with WebGL rendering, URL detection for OAuth flow - **`components/terminal/TerminalView.tsx`** — xterm.js integration with WebGL rendering, URL detection for OAuth flow
- **`components/layout/`** — TopBar (tabs + status), Sidebar (project list), StatusBar - **`components/layout/`** — TopBar (tabs + status), Sidebar (project list), StatusBar
- **`components/projects/`** — ProjectCard, ProjectList, AddProjectDialog - **`components/projects/`** — ProjectCard, ProjectList, AddProjectDialog
- **`components/settings/`** — Settings panels for API keys, Docker, AWS - **`components/settings/`** — Settings panels for API keys, Docker, AWS, Web Terminal
### Backend Structure (`app/src-tauri/src/`) ### Backend Structure (`app/src-tauri/src/`)
@@ -72,7 +72,11 @@ docker exec stdout → tokio task → emit("terminal-output-{sessionId}") → li
- `container.rs` — Container lifecycle (create, start, stop, remove, inspect) - `container.rs` — Container lifecycle (create, start, stop, remove, inspect)
- `exec.rs` — PTY exec sessions with bidirectional stdin/stdout streaming - `exec.rs` — PTY exec sessions with bidirectional stdin/stdout streaming
- `image.rs` — Image build/pull with progress streaming - `image.rs` — Image build/pull with progress streaming
- **`models/`** — Serde structs (`Project`, `Backend`, `BedrockConfig`, `OllamaConfig`, `OpenAiCompatibleConfig`, `ContainerInfo`, `AppSettings`). These define the IPC contract with the frontend. - **`web_terminal/`** — Remote terminal access via axum HTTP+WebSocket server:
- `server.rs` — Axum server lifecycle (start/stop), serves embedded HTML and handles WS upgrades
- `ws_handler.rs` — Per-connection WebSocket handler with JSON protocol, session management, cleanup on disconnect
- `terminal.html` — Self-contained xterm.js web UI embedded via `include_str!()`
- **`models/`** — Serde structs (`Project`, `Backend`, `BedrockConfig`, `OllamaConfig`, `OpenAiCompatibleConfig`, `ContainerInfo`, `AppSettings`, `WebTerminalSettings`). These define the IPC contract with the frontend.
- **`storage/`** — Persistence: `projects_store.rs` (JSON file with atomic writes), `secure.rs` (OS keychain via `keyring` crate), `settings_store.rs` - **`storage/`** — Persistence: `projects_store.rs` (JSON file with atomic writes), `secure.rs` (OS keychain via `keyring` crate), `settings_store.rs`
### Container (`container/`) ### Container (`container/`)

View File

@@ -16,6 +16,7 @@ Triple-C (Claude-Code-Container) is a desktop application that runs Claude Code
- [Ollama Configuration](#ollama-configuration) - [Ollama Configuration](#ollama-configuration)
- [OpenAI Compatible Configuration](#openai-compatible-configuration) - [OpenAI Compatible Configuration](#openai-compatible-configuration)
- [Settings](#settings) - [Settings](#settings)
- [Web Terminal (Remote Access)](#web-terminal-remote-access)
- [Terminal Features](#terminal-features) - [Terminal Features](#terminal-features)
- [Scheduled Tasks (Inside the Container)](#scheduled-tasks-inside-the-container) - [Scheduled Tasks (Inside the Container)](#scheduled-tasks-inside-the-container)
- [What's Inside the Container](#whats-inside-the-container) - [What's Inside the Container](#whats-inside-the-container)
@@ -480,6 +481,17 @@ Instructions applied to **all** projects. Written to `~/.claude/CLAUDE.md` in ev
Environment variables applied to **all** project containers. Per-project variables with the same key take precedence. Environment variables applied to **all** project containers. Per-project variables with the same key take precedence.
### Web Terminal
Enable remote access to your project terminals from any device on the local network (tablets, phones, other computers).
- **Toggle** — Click ON/OFF to start or stop the web terminal server.
- **URL** — When running, shows the full URL including the access token. Click **Copy URL** to copy it to your clipboard, then open it in a browser on your tablet or phone.
- **Token** — An access token is auto-generated on first enable. Click **Copy** to copy the token, or **Regenerate** to create a new one (this disconnects existing web sessions).
- **Port** — Defaults to 7681. Configurable in `settings.json` if needed.
The web terminal server auto-starts on app launch if it was previously enabled, and stops when the app closes.
### Updates ### Updates
- **Current Version** — The installed version of Triple-C. - **Current Version** — The installed version of Triple-C.
@@ -490,6 +502,43 @@ When an update is available, a pulsing **Update** button appears in the top bar.
--- ---
## Web Terminal (Remote Access)
The web terminal lets you access your running project terminals from a tablet, phone, or any other device on the local network — no app installation required, just a web browser.
### Setup
1. Go to **Settings** in the sidebar.
2. Find the **Web Terminal** section and click the toggle to **ON**.
3. A URL appears (e.g., `http://192.168.1.100:7681?token=...`). Click **Copy URL**.
4. Open the URL in a browser on your tablet or other device.
### Using the Web Terminal
The web terminal UI mirrors the desktop app's terminal experience:
- **Project picker** — Select a running project from the dropdown at the top.
- **Claude / Bash buttons** — Open a new Claude Code or bash session for the selected project.
- **Tab bar** — Switch between multiple open sessions. Click the **x** on a tab to close it.
- **Input bar** — A text input at the bottom optimized for mobile/tablet keyboards. Characters are sent immediately without waiting for autocomplete. Helper buttons for **Enter**, **Tab**, and **^C** (Ctrl+C) are provided for keys that are awkward on virtual keyboards.
- **Scroll to bottom** — A floating arrow button appears when you scroll up, letting you jump back to the latest output.
### Security
- Access requires a token in the URL query string. Without the correct token, connections are rejected.
- The token is auto-generated (32 bytes, base64url-encoded) and can be regenerated at any time from Settings.
- The server only listens on port 7681 (configurable) — make sure this port is not exposed to the public internet.
- All sessions opened from a browser tab are automatically cleaned up when the tab is closed or the WebSocket disconnects.
### Tips
- **Bookmark the URL** on your tablet for quick access.
- The web terminal works best in landscape orientation on tablets.
- If the connection drops (e.g., Wi-Fi interruption), the web terminal auto-reconnects after 2 seconds.
- Regenerating the token invalidates all existing browser sessions — you'll need to update bookmarks with the new URL.
---
## Terminal Features ## Terminal Features
### Multiple Sessions ### Multiple Sessions

View File

@@ -85,6 +85,18 @@ Triple-C supports [Model Context Protocol (MCP)](https://modelcontextprotocol.io
Optional per-project integration with [Flight Control](https://github.com/msieurthenardier/mission-control) — an AI-first development methodology. When enabled, the repo is cloned into the container, skills are installed, and workflow instructions are injected into CLAUDE.md. Optional per-project integration with [Flight Control](https://github.com/msieurthenardier/mission-control) — an AI-first development methodology. When enabled, the repo is cloned into the container, skills are installed, and workflow instructions are injected into CLAUDE.md.
### Web Terminal (Remote Access)
Triple-C includes an optional web terminal server for accessing project terminals from tablets, phones, or other devices on the local network. When enabled in Settings, an axum HTTP+WebSocket server starts inside the Tauri process, serving a standalone xterm.js-based terminal UI.
- **URL**: `http://<LAN_IP>:7681?token=...` (port configurable)
- **Authentication**: Token-based (auto-generated, copyable from Settings)
- **Protocol**: JSON over WebSocket with base64-encoded terminal data
- **Features**: Project picker, multiple tabs (Claude + bash sessions), mobile-optimized input bar, scroll-to-bottom button
- **Session cleanup**: All terminal sessions are closed when the browser disconnects
The web terminal shares the existing `ExecSessionManager` via `Arc`-wrapped stores — same Docker exec sessions, different transport (WebSocket instead of Tauri IPC events).
### Docker Socket Path ### Docker Socket Path
The socket path is OS-aware: The socket path is OS-aware:
@@ -108,7 +120,8 @@ Users can override this in Settings via the global `docker_socket_path` option.
| `app/src/components/projects/ContainerProgressModal.tsx` | Real-time container operation progress | | `app/src/components/projects/ContainerProgressModal.tsx` | Real-time container operation progress |
| `app/src/components/mcp/McpPanel.tsx` | MCP server library (global configuration) | | `app/src/components/mcp/McpPanel.tsx` | MCP server library (global configuration) |
| `app/src/components/mcp/McpServerCard.tsx` | Individual MCP server configuration card | | `app/src/components/mcp/McpServerCard.tsx` | Individual MCP server configuration card |
| `app/src/components/settings/SettingsPanel.tsx` | Docker, AWS, timezone, and global settings | | `app/src/components/settings/SettingsPanel.tsx` | Docker, AWS, timezone, web terminal, and global settings |
| `app/src/components/settings/WebTerminalSettings.tsx` | Web terminal toggle, URL, token management |
| `app/src/components/terminal/TerminalView.tsx` | xterm.js terminal with WebGL, URL detection, OSC 52 clipboard, image paste | | `app/src/components/terminal/TerminalView.tsx` | xterm.js terminal with WebGL, URL detection, OSC 52 clipboard, image paste |
| `app/src/components/terminal/TerminalTabs.tsx` | Tab bar for multiple terminal sessions (claude + bash) | | `app/src/components/terminal/TerminalTabs.tsx` | Tab bar for multiple terminal sessions (claude + bash) |
| `app/src/hooks/useTerminal.ts` | Terminal session management (claude and bash modes) | | `app/src/hooks/useTerminal.ts` | Terminal session management (claude and bash modes) |
@@ -124,7 +137,11 @@ Users can override this in Settings via the global `docker_socket_path` option.
| `app/src-tauri/src/commands/mcp_commands.rs` | MCP server CRUD Tauri commands | | `app/src-tauri/src/commands/mcp_commands.rs` | MCP server CRUD Tauri commands |
| `app/src-tauri/src/models/project.rs` | Project struct (backend, Docker access, MCP servers, Mission Control) | | `app/src-tauri/src/models/project.rs` | Project struct (backend, Docker access, MCP servers, Mission Control) |
| `app/src-tauri/src/models/mcp_server.rs` | MCP server struct (transport, Docker image, env vars) | | `app/src-tauri/src/models/mcp_server.rs` | MCP server struct (transport, Docker image, env vars) |
| `app/src-tauri/src/models/app_settings.rs` | Global settings (image source, Docker socket, AWS, microphone) | | `app/src-tauri/src/models/app_settings.rs` | Global settings (image source, Docker socket, AWS, web terminal) |
| `app/src-tauri/src/web_terminal/server.rs` | Axum HTTP+WS server for remote terminal access |
| `app/src-tauri/src/web_terminal/ws_handler.rs` | WebSocket connection handler and session management |
| `app/src-tauri/src/web_terminal/terminal.html` | Embedded web UI (xterm.js, project picker, tabs) |
| `app/src-tauri/src/commands/web_terminal_commands.rs` | Web terminal start/stop/status Tauri commands |
| `app/src-tauri/src/storage/mcp_store.rs` | MCP server persistence (JSON with atomic writes) | | `app/src-tauri/src/storage/mcp_store.rs` | MCP server persistence (JSON with atomic writes) |
| `container/Dockerfile` | Ubuntu 24.04 sandbox image with Claude Code + dev tools + clipboard/audio shims | | `container/Dockerfile` | Ubuntu 24.04 sandbox image with Claude Code + dev tools + clipboard/audio shims |
| `container/entrypoint.sh` | UID/GID remap, SSH setup, Docker group config, MCP injection, Mission Control setup | | `container/entrypoint.sh` | UID/GID remap, SSH setup, Docker group config, MCP injection, Mission Control setup |

View File

@@ -100,9 +100,13 @@ Tauri uses a Rust backend paired with a web-based frontend rendered by the OS-na
│ │ Project Management │◄─┤ ProjectsStore │ │ │ │ Project Management │◄─┤ ProjectsStore │ │
│ │ Settings UI │ │ bollard Docker Client │ │ │ │ Settings UI │ │ bollard Docker Client │ │
│ │ │ │ keyring Credential Mgr │ │ │ │ │ │ keyring Credential Mgr │ │
│ └───────────┬───────────┘ └────────────┬─────────────┘ │ └───────────┬───────────┘ │ Web Terminal Server │
│ │ └────────────┬─────────────┘ │
│ │ Tauri IPC (invoke/emit) │ │ │ │ Tauri IPC (invoke/emit) │ │
│ └───────────┬───────────────┘ │ │ └───────────┬───────────────┘ │
│ ▲ │
│ axum HTTP+WS│(port 7681) │
│ │ │
└──────────────────────────┼───────────────────────────────┘ └──────────────────────────┼───────────────────────────────┘
│ Docker Socket │ Docker Socket
@@ -129,6 +133,8 @@ The application uses two IPC mechanisms between the React frontend and Rust back
**Request/Response** (`invoke()`): Used for discrete operations — starting containers, saving settings, listing projects. The frontend calls `invoke("command_name", { args })` and awaits a typed result. **Request/Response** (`invoke()`): Used for discrete operations — starting containers, saving settings, listing projects. The frontend calls `invoke("command_name", { args })` and awaits a typed result.
**WebSocket Streaming** (Web Terminal): Used for remote terminal access from browsers on the local network. An axum HTTP+WebSocket server runs inside the Tauri process, sharing the same `ExecSessionManager` via `Arc`-wrapped stores. The WebSocket uses a JSON protocol with base64-encoded terminal data. Each browser connection can open multiple terminal sessions; all sessions are cleaned up when the WebSocket disconnects.
**Event Streaming** (`emit()`/`listen()`): Used for continuous data — terminal I/O. When a terminal session is opened, the Rust backend spawns two tokio tasks: **Event Streaming** (`emit()`/`listen()`): Used for continuous data — terminal I/O. When a terminal session is opened, the Rust backend spawns two tokio tasks:
1. **Output reader** — Reads from the Docker exec stdout stream and emits `terminal-output-{sessionId}` events to the frontend. 1. **Output reader** — Reads from the Docker exec stdout stream and emits `terminal-output-{sessionId}` events to the frontend.
2. **Input writer** — Listens on an `mpsc::unbounded_channel` for data sent from the frontend via `invoke("terminal_input")` and writes it to the Docker exec stdin. 2. **Input writer** — Listens on an `mpsc::unbounded_channel` for data sent from the frontend via `invoke("terminal_input")` and writes it to the Docker exec stdin.
@@ -263,7 +269,7 @@ triple-c/
│ ├── projects/ # ProjectCard, ProjectList, AddProjectDialog, │ ├── projects/ # ProjectCard, ProjectList, AddProjectDialog,
│ │ # FileManagerModal, ContainerProgressModal, modals │ │ # FileManagerModal, ContainerProgressModal, modals
│ ├── settings/ # SettingsPanel, DockerSettings, AwsSettings, │ ├── settings/ # SettingsPanel, DockerSettings, AwsSettings,
│ │ # UpdateDialog │ │ # WebTerminalSettings, UpdateDialog
│ └── terminal/ # TerminalView (xterm.js), TerminalTabs, UrlToast │ └── terminal/ # TerminalView (xterm.js), TerminalTabs, UrlToast
└── src-tauri/ # Rust backend └── src-tauri/ # Rust backend
@@ -282,7 +288,13 @@ triple-c/
│ ├── project_commands.rs # Start/stop/rebuild containers │ ├── project_commands.rs # Start/stop/rebuild containers
│ ├── settings_commands.rs # Settings CRUD │ ├── settings_commands.rs # Settings CRUD
│ ├── terminal_commands.rs # Terminal I/O, resize │ ├── terminal_commands.rs # Terminal I/O, resize
── update_commands.rs # App update checking ── update_commands.rs # App update checking
│ └── web_terminal_commands.rs # Web terminal start/stop/status
├── web_terminal/ # Remote terminal access
│ ├── mod.rs # Module root
│ ├── server.rs # Axum HTTP+WS server lifecycle
│ ├── ws_handler.rs # WebSocket connection handler
│ └── terminal.html # Embedded xterm.js web UI
├── docker/ # Docker API layer ├── docker/ # Docker API layer
│ ├── client.rs # bollard singleton connection │ ├── client.rs # bollard singleton connection
│ ├── container.rs # Create, start, stop, remove, fingerprinting │ ├── container.rs # Create, start, stop, remove, fingerprinting
@@ -323,6 +335,11 @@ triple-c/
| `tar` | 0.4 | In-memory tar archives for Docker build context | | `tar` | 0.4 | In-memory tar archives for Docker build context |
| `dirs` | 6.x | Cross-platform app data directory paths | | `dirs` | 6.x | Cross-platform app data directory paths |
| `serde` / `serde_json` | 1.x | Serialization for IPC and persistence | | `serde` / `serde_json` | 1.x | Serialization for IPC and persistence |
| `axum` | 0.8 | HTTP+WebSocket server for web terminal |
| `tower-http` | 0.6 | CORS middleware for web terminal |
| `base64` | 0.22 | Terminal data encoding over WebSocket |
| `rand` | 0.9 | Access token generation |
| `local-ip-address` | 0.6 | LAN IP detection for web terminal URL |
### JavaScript (Frontend) ### JavaScript (Frontend)