merge: align dev branch with main

This commit is contained in:
Developer
2026-06-03 08:51:02 +00:00
parent 51a399c775
commit b39d6ce5f4
319 changed files with 30221 additions and 9221 deletions
+60 -30
View File
@@ -26,27 +26,26 @@ apps/web/src/
│ ├── ssh_keys.ts # SSH key API
│ ├── tool_types.ts # Tool type API
│ ├── users.ts # User API
│ ├── events.ts # SSE events API
│ ├── sessions.ts # Tool instance sessions API
│ └── settings.ts # Settings API
├── components/ # Reusable components
│ ├── app-shell.tsx # Main app layout
│ ├── terminal.tsx # xterm.js terminal component
│ ├── protected-route.tsx # Auth guard
│ ├── event-toast-bridge.tsx # Events → toasts
│ └── [more...]
├── state/ # Global state
── auth.tsx # Auth state management
│ ├── events.tsx # Event provider (SSE)
│ └── toast.tsx # Toast notifications
├── context/ # React contexts
── auth.tsx # Auth state management
├── hooks/ # Custom hooks
│ ├── use-auth.ts # Auth hook
│ ├── use-theme.ts # Theme hook
│ └── use-events.ts # SSE events hook
│ └── use-terminal-connection.ts # Terminal WebSocket lifecycle
├── pages/ # Page components (routes)
│ ├── dashboard.tsx # Dashboard
│ ├── projects.tsx # Project list
│ ├── repo-workspace.tsx # Repository workspace
│ ├── git-history.tsx # Git history
│ ├── git-repositories.tsx # Repository management
│ ├── terminal.tsx # Web terminal
│ ├── profile.tsx # User profile
│ ├── settings.tsx # User settings
│ ├── tool-types.tsx # Tool types
@@ -160,28 +159,6 @@ interface AuthState {
}
```
### Real-Time Events (SSE)
The frontend receives real-time instance events via Server-Sent Events:
```
EventSource → useEvents() hook → EventProvider → EventToastBridge → ToastContainer
```
**Components:**
- `useEvents()`: Manages SSE connection with auto-reconnect
- `EventProvider`: Shares event stream across components
- `EventToastBridge`: Maps events to toast notifications
- `ToastContainer`: Displays and manages toast stack
**Event-to-Toast Mapping:**
| Event | Toast Severity | Auto-dismiss |
|-------|---------------|--------------|
| `instance.starting` | Info | 3s |
| `instance.running` | Success | 3s |
| `instance.error` | Error | Persistent |
| `instance.stopped` | Info | 3s |
### 5. Routing Structure
```typescript
@@ -191,6 +168,7 @@ EventSource → useEvents() hook → EventProvider → EventToastBridge → Toas
<Route path="/projects/:projectId" element={<RepoWorkspace />} />
<Route path="/projects/:projectId/repositories" element={<GitRepositories />} />
<Route path="/projects/:projectId/repositories/:repoId/history" element={<GitHistory />} />
<Route path="/terminal/:instanceId" element={<TerminalPage />} />
<Route path="/profile" element={<ProfilePage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/ssh-keys" element={<SSHKeysPage />} />
@@ -296,12 +274,64 @@ test('renders file list', () => {
4. **Caching**: Browser caches API responses (ETags)
5. **Optimistic UI**: Immediate feedback before API response
## Terminal Architecture
The web terminal is the most complex component in the frontend. It bridges a browser-based terminal emulator with a server-side PTY session.
### Component Stack
```
TerminalPage (route)
└── TerminalComponent
├── Status bar (connection state, latency, actions)
├── Session-ended overlay (reconnect / go back)
├── Reconnect banner (spinner + countdown)
└── xterm.js (terminal emulator)
├── FitAddon (auto-resize to container)
├── SerializeAddon (scrollback serialization)
└── WebLinksAddon (clickable URLs)
```
### Connection Hook
`useTerminalConnection` manages the full WebSocket lifecycle:
```
CONNECTING
→ onopen → CONNECTED → heartbeat every 15s
→ onclose (unexpected) → RECONNECTING
→ backoff: 1s → 2s → 4s → 8s → 16s → 30s max
→ up to 10 attempts
→ onopen → restore scrollback → CONNECTED
→ onclose (expected) → DISCONNECTED
```
**Key behaviors:**
- **Local echo**: Printable ASCII chars appear instantly; server echo is deduplicated
- **Resize**: Debounced 200ms, throttled to 1 message per 500ms
- **Scrollback**: Serialized to `sessionStorage` on disconnect, restored on reconnect
- **Keyboard**: `Ctrl+Shift+R` triggers manual reconnect
### Data Flow
```
User types 'a'
→ xterm onData event
→ useTerminalConnection.sendInput('a')
→ local echo writes 'a' to xterm immediately
→ WebSocket sends 'a' to server
→ server PTY echoes 'a' back
→ client receives 'a' via binary frame
→ deduplicates against pending echo buffer
→ (no-op if matched, or writes remaining chars)
```
## Future Improvements
- [x] Implement real-time updates (SSE)
- [ ] Add React Query for server state management
- [ ] Implement virtual scrolling for large file trees
- [ ] Add service worker for offline support
- [x] Implement real-time updates (WebSocket) — Terminal done
- [ ] Add error boundary components
## Development Workflow