merge: integrate main restructuring into dev

- Resolve 57 merge conflicts from codebase restructure
- Port dev feature code to new directory structure:
  * Update import paths to use @/ aliases
  * Add backward-compatible API signatures (createInstance, startInstance, deleteInstance)
  * Add missing type exports (ProjectWithRepos, InstanceHealth, Branch, BranchesResponse)
  * Extend Session and GitRepository types for dev features
  * Extend TerminalComponent props for mobile terminal wrapper
  * Add missing icon names (bell, drag, undo)

Quality gates: tsc pass (0 errors), build pass, 127/131 tests pass
(4 pre-existing failures unrelated to merge)
This commit is contained in:
Developer
2026-06-03 09:23:06 +00:00
279 changed files with 24254 additions and 21693 deletions
+13 -8
View File
@@ -22,25 +22,30 @@ The Projects page displays all your projects in a card layout showing:
- Creation date
- Associated repositories count
Each project card provides quick actions:
- **Settings** — Navigate to the project settings page
- **Delete** — Delete the project with confirmation
- **Open Workspace** — Open the project's workspace (rightmost action)
### Opening a Project Workspace
Click on any project card to open its **workspace**. The workspace is the default view for a project and shows:
Click the **"Open Workspace"** button on any project card to open its **workspace**. The workspace is the default view for a project and shows:
- Repository file browser
- Branch selector
- File viewer
### Editing a Project
1. From the Projects page, click the **menu icon** (⋮) on a project card
2. Select **"Edit"**
3. Update the name or description
4. Click **"Save"**
1. From the Projects page, click the **"Settings"** link on a project card
2. On the project settings page, update the **name** or **description**
3. Click **"Save Changes"**
The settings page also provides access to repository management and member settings.
### Deleting a Project
1. From the Projects page, click the **menu icon** (⋮) on a project card
2. Select **"Delete"**
3. Confirm the deletion
1. From the Projects page, click the **"Delete"** button on a project card
2. Confirm the deletion
**Note:** Deleting a project also deletes all associated repositories and their data. This action cannot be undone.
+180 -68
View File
@@ -1,104 +1,216 @@
# Terminal Sessions
# Web Terminal
Terminal sessions provide interactive shell access to your running tool instances directly in the browser.
## Overview
## Persistent Sessions
The web terminal provides an interactive shell session inside running tool instances directly from your browser. It uses xterm.js to render a full terminal emulator connected via WebSocket to a PTY-backed docker exec session.
Terminal sessions are **persistent** - they survive browser refreshes, network interruptions, and tab switches.
The terminal is designed to feel as close to a local terminal as possible, with features for network resilience, low-latency typing, and session continuity.
### How It Works
## How to Use
- When you open a terminal, a shell session starts inside the tool instance container
- If you close the browser or lose connection, the session keeps running
- When you reconnect, you reattach to the same session with all previous output preserved
- Sessions automatically clean up after 30 minutes of inactivity
### Opening a Terminal
1. Navigate to a **project** and select a **repository**
2. Go to the repository **workspace**
3. Start or select a **tool instance** that supports the terminal interface
4. Click the **"Open Terminal"** button
The terminal opens in full-page mode with a status bar at the top.
### Terminal Layout
```
┌─────────────────────────────────────────────┐
│ ● Connected [Reconnect] [×] │
├─────────────────────────────────────────────┤
│ │
│ user@container:~$ ls -la │
│ total 128 │
│ drwxr-xr-x 5 user user 4096 May 27 10:00 │
│ ... │
│ │
└─────────────────────────────────────────────┘
```
**Status bar (top):**
- **Connection dot** — color indicates connection health
- **Status text** — shows current state and latency
- **Reconnect button** — appears when disconnected
- **Close button** — returns to the previous page
### Connection States
| Indicator | Meaning | Action |
|-----------|---------|--------|
| 🟡 **Yellow dot** + "Connecting..." | Opening WebSocket | Wait or check network |
| 🟢 **Green dot** + "Connected" | Healthy connection (<100ms) | Ready to use |
| 🟡 **Yellow dot** + "Slow (150ms)" | Elevated latency | Connection usable but laggy |
| 🟡 **Yellow dot** + "Reconnecting (2)" | Connection lost, retrying | Wait for auto-reconnect |
| ⚪ **Gray dot** + "Disconnected" | Max retries exceeded | Click Reconnect or refresh |
**Hover the status dot** to see the current round-trip latency in milliseconds.
### Typing
Type normally as you would in a local terminal. The terminal supports:
- **Printable characters** appear instantly (local echo)
- **Special keys** (Tab, Enter, Ctrl+C, arrow keys) are sent to the server
- **Password prompts** automatically suppress local echo
- **Unicode** input and output
### Reconnecting
If your connection drops:
1. The terminal shows "Reconnecting..." status
2. The client automatically attempts to reconnect with exponential backoff
3. On successful reconnection, buffered output is replayed
4. You can continue working where you left off
The terminal **automatically reconnects** if the WebSocket drops:
## Resetting the Terminal
- Brief disconnects (WiFi hiccups, proxy timeouts) are recovered within 15 seconds
- Up to **10 reconnection attempts** with exponential backoff
- **Scrollback is preserved** across reconnects
- A visual divider (`--- Reconnected ---`) separates old and new output
If your terminal becomes unresponsive or you want a fresh start:
**Manual reconnect:**
- Click the **Reconnect** button in the status bar
- Or press **Ctrl+Shift+R** anywhere in the terminal page
1. Click the **Reset** button in the terminal header
2. Confirm the reset action
3. The current shell is killed and a new one starts
4. All terminal history is cleared
### Session Ended
**Note:** Resetting only affects the terminal session, not the tool instance itself. Any files you've created remain intact.
When the container process exits (e.g., you run `exit` or the container stops), the terminal shows an overlay:
## Mobile Terminal
```
┌─────────────────────────┐
│ Session Ended │
│ The container process │
│ has exited. │
│ │
│ [Reconnect] [Go Back] │
└─────────────────────────┘
```
On mobile devices, the terminal includes:
- Special keys panel (Ctrl, Alt, Tab, arrows, etc.)
- Font size controls
- Auto-hiding header for maximum screen space
- Touch-friendly interface
- **Reconnect** — spawns a new shell session in the same container
- **Go Back** — returns to the workspace page
## Keyboard Shortcuts
Standard terminal shortcuts work as expected:
- `Ctrl+C`: Send interrupt signal
- `Ctrl+D`: Send EOF (close shell if empty)
- `Ctrl+L`: Clear screen
- `Ctrl+Z`: Suspend process
| Shortcut | Action |
|----------|--------|
| `Ctrl+Shift+R` | Force reconnect (bypasses backoff) |
| Standard terminal shortcuts | `Ctrl+C`, `Ctrl+D`, `Ctrl+L`, Tab completion, etc. |
Special keys can be accessed via the special keys panel on mobile or by using modifier combinations.
## Technical Details
## Container Monitoring & Notifications
### WebSocket Protocol
The platform monitors your tool instances in real-time and notifies you of important events:
The terminal communicates over a binary WebSocket with mixed JSON control messages.
### What You'll See
**Connection:**
```
ws://api.example.com/ws/tool-instances/{instance_id}/terminal
```
- **Starting:** When a container begins starting
- **Running:** When a container is ready
- **Error:** When a build fails, container crashes, or tunnel fails
- **Stopped:** When a container stops
**Binary frames** carry raw terminal I/O. **Text (JSON) frames** carry control messages:
Notifications appear as toast messages at the top of the screen. Errors persist until dismissed; other notifications auto-dismiss after a few seconds.
**Client → Server:**
- `{"type":"ping","id":n}` — heartbeat ping
- `{"type":"resize","cols":120,"rows":40}` — terminal resize
- Raw bytes — keystroke input
### Real-Time Status
**Server → Client:**
- `{"type":"pong","id":n}` — heartbeat response
- `{"type":"status","status":"connected"}` — session ready
- `{"type":"set_echo_state","enabled":false}` — disable local echo
- `{"type":"session_ended","reason":"process_exit"}` — session ended
- Raw bytes — terminal output
Instance status badges update in real-time via Server-Sent Events (SSE) — no page refresh needed.
### Architecture
```
Browser Backend
┌──────────────────────┐ ┌─────────────────────────────┐
│ TerminalComponent │ │ terminal.py (WS endpoint) │
│ ├─ xterm.js │◄───────►│ ├─ auth + session mgmt │
│ ├─ FitAddon │ WS │ └─ echo state detection │
│ ├─ SerializeAddon │ │ │
│ └─ useTerminalConn. │ │ TerminalManager │
│ ├─ heartbeat │ │ ├─ read_loop (batching) │
│ ├─ reconnect │ │ ├─ write_loop │
│ ├─ local echo │ │ └─ heartbeat_loop │
│ └─ resize throttle│ │ │
│ │ │ TerminalSession │
│ sessionStorage │ │ ├─ PTY + docker exec │
│ (scrollback backup) │ │ └─ termios echo detection │
└──────────────────────┘ └─────────────────────────────┘
```
### Reconnect Behavior
On disconnect:
1. The client serializes terminal scrollback to `sessionStorage`
2. Backoff timer starts (1s, 2s, 4s, 8s, 16s, then caps at 30s)
3. On reconnect, scrollback is restored + divider line
4. A new `docker exec` session is spawned transparently
**Note:** The underlying docker exec PTY is not resumable. Reconnect creates a new shell, but scrollback continuity makes this transparent.
### Performance
- **Local echo** makes printable characters appear in <1ms
- **Message batching** on the backend reduces WebSocket frame overhead
- **Resize debouncing** (200ms) + throttling (500ms) prevents server spam
- **Heartbeat interval** is 15s to balance detection speed with server load
## Troubleshooting
### Connection Issues
### "Connecting..." stays yellow
**"Connection closed" error:**
- The tool instance may have stopped - check the instance status
- Network issues - the client will auto-reconnect
- Session timeout - sessions expire after 30 minutes of inactivity
**Issue:** WebSocket cannot open
**Check:**
1. Is the API server running?
2. Is the tool instance in "running" status?
3. Check browser console for connection errors
4. Verify the `VITE_API_BASE_URL` points to the correct API
**"Container not found" error (4004):**
- The Docker container no longer exists (e.g., after host restart)
- Restart the tool instance to recreate the container
### "Reconnecting" loops forever
**Terminal not responding:**
- Try resetting the terminal using the Reset button
- Check if the tool instance is still running
- Refresh the page to force reconnection
**Issue:** Max reconnection attempts exceeded
**Check:**
1. Is the container still running? (`docker ps`)
2. Did the container crash or get stopped?
3. Check server logs for `Terminal session error`
### Display Issues
### Typing feels slow
**Text not visible:**
- Adjust font size using +/- buttons
- Check if the terminal has focus (click inside it)
- Try resizing the browser window
**Issue:** High latency or no local echo
**Check:**
1. Hover the status dot — latency >100ms is shown as "Slow"
2. Local echo only works for printable ASCII characters
3. Password prompts intentionally disable echo
4. Very high latency may indicate a congested network
**Characters not appearing:**
- Ensure the terminal has focus
- Check if a modifier key is stuck (Ctrl, Alt)
- Reset the terminal if stuck
### Terminal is blank after reconnect
## Session Limits
**Issue:** Scrollback not restored
**Check:**
1. `sessionStorage` may have been cleared (new browser session)
2. The scrollback cap is 10,000 lines — very long sessions may truncate
3. Browser privacy settings may block `sessionStorage`
- **One connection per terminal:** Only one browser tab can connect to a terminal session at a time. Opening a new connection closes the old one.
- **30-minute idle timeout:** Sessions without activity are automatically cleaned up
- **Buffer size:** Up to 10KB of output is buffered for replay on reconnection
### "Session Ended" immediately
**Issue:** Container process exits right away
**Check:**
1. The container's default command may have finished
2. Check the tool type's Docker Compose template
3. Some tools (like one-off scripts) are not meant for persistent terminal sessions
## Configuration
No additional configuration is required. The terminal adapts automatically to:
- Browser window size (via ResizeObserver)
- System light/dark theme preference
- Network conditions (reconnect backoff)
## Related Features
- [Workspace](workspace.md) — Open the terminal from the repository workspace
- [Tool Types](tool-types.md) — Configure which tools expose a terminal interface
- [SSH Keys](ssh-keys.md) — Manage SSH keys for repository access from within the terminal