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
+74 -50
View File
@@ -13,20 +13,16 @@ The Headquarter backend is built with **FastAPI** and follows a layered architec
│ Middleware: CORS → Request Logging → Exception Logging │
├─────────────────────────────────────────────────────────────┤
│ API Layer (src/api/) │
│ ┌─────────┐ ┌─────────┐ ┌────────┐ ┌──────────┐ │
│ │ Auth │ │ Projects │ │ Users │ │ Git │ │
│ │ Routes │ │ Routes │ │ Routes │ │ Repos │ │
│ └────┬────┘ └────┬────┘ └───┬────┘ └────┬─────┘ │
│ ┌──────────┐ ┌──────────┐ │
│ ToolInst │ │ Events │ │
│ Routes │ │ Routes
└────┬─────┘ └────┬─────┘
├───────┼───────────┼───────────┼───────────┼─────────────────┤
│ │ │ │ │ │
│ Auth │ Project │ User │ Git │ │
│ Layer │ Service │ Service │ Service │ │
│ │ │ │ │ │
├───────┴───────────┴───────────┴───────────┴─────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌────────┐ ┌──────────┐
│ │ Auth │ │Terminal │ │Projects│ │ Git │
│ │ Routes │ │ WS │ │ Routes │ │ Repos │
│ └────┬────┘ └────┬────┘ └───┬────┘ └────┬─────┘
──────────────────┼──────────┼───────────┼──────────────────┤
Auth │ Terminal │ ProjectGit
Layer │ Manager │ Service │ Service
│ │ + Session│ │ │ │
├───────┴───────────┴──────────┴───────────┴──────────────────┤
│ Data Layer │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Models │ │ Database │ │ Config │ │
@@ -41,13 +37,12 @@ The Headquarter backend is built with **FastAPI** and follows a layered architec
src/
├── api/ # API Routes
│ ├── auth.py # Authentication endpoints
│ ├── terminal.py # WebSocket terminal endpoint
│ ├── projects.py # Project endpoints
│ ├── git_repositories.py # Repository endpoints
│ ├── users.py # User endpoints
│ ├── tool_types.py # Tool type endpoints
│ ├── tool_instances.py # Tool instance endpoints
│ ├── ssh_keys.py # SSH key endpoints
│ ├── events.py # SSE streaming endpoint
│ └── dashboard.py # Dashboard endpoints
├── auth/ # Authentication
│ ├── session.py # Session management
@@ -60,15 +55,12 @@ src/
│ ├── git_repository.py # Repository model
│ ├── tool_type.py # Tool type model
│ ├── ssh_key.py # SSH key model
│ ├── instance_event.py # Instance event audit model
│ ├── health_check.py # Health check snapshot model
│ └── user_config.py # User config model
├── services/ # Services
│ ├── docker.py # Docker operations
├── services/ # Business Logic
│ ├── terminal_manager.py # Terminal session manager
│ ├── event_bus.py # Instance event bus (pub/sub)
│ ├── health_monitor.py # Background health monitoring
│ └── lifecycle_hooks.py # Instance lifecycle events
│ ├── terminal_session.py # PTY + docker exec session
│ ├── docker.py # Docker operations
│ └── profile_resolver.py # Profile resolution
├── utils/ # Utilities
│ ├── git_url_parser.py # URL parsing
│ ├── git_files.py # Git file operations
@@ -78,6 +70,65 @@ src/
└── main.py # Application entry point
```
## Terminal System
The terminal system provides interactive shell access to running tool instances via WebSocket.
### Architecture
```
Client (WebSocket)
terminal.py (FastAPI WS endpoint)
├─ Auth validation (session cookie)
├─ Instance ownership check
├─ Session lifecycle (create / monitor / cleanup)
└─ Echo state detection (termios)
TerminalManager
├─ create_session() → spawns TerminalSession
├─ _read_loop() → batches PTY output → WebSocket
├─ _write_loop() → WebSocket input → PTY
└─ _heartbeat_loop() → closes idle connections (60s)
TerminalSession
├─ start() → pty.openpty() + docker exec
├─ read_output() → select.select() + os.read()
├─ write_input() → os.write() to PTY master
├─ resize() → TIOCSWINSZ ioctl
└─ check_echo_state() → termios.ECHO flag
```
### Protocol
**Binary frames**: Raw terminal I/O (hot path)
**Text (JSON) frames**: Control messages
**Control messages:**
| Direction | Type | Purpose |
|-----------|------|---------|
| Client → Server | `ping` | Heartbeat (every 15s idle) |
| Server → Client | `pong` | Heartbeat response |
| Client → Server | `resize` | Terminal dimensions changed |
| Server → Client | `set_echo_state` | Enable/disable local echo |
| Server → Client | `session_ended` | Container process exited |
### Message Batching
The read loop batches small PTY reads into single WebSocket frames:
- Buffer accumulates data for up to 16ms
- Flushed immediately when no new data is available
- Reduces WebSocket frame overhead for rapid output
### Reconnect Behavior
The server cannot resume a `docker exec` PTY across connections. On reconnect:
1. Old session is terminated
2. New `docker exec` is spawned
3. Client restores scrollback from `sessionStorage`
4. New shell appears seamlessly to the user
## Layers
### 1. API Layer (`src/api/`)
@@ -207,33 +258,6 @@ Errors are handled at multiple levels:
- **Integration tests**: PostgreSQL with transaction rollback
- **Fixtures**: Shared in `conftest.py`
## Monitoring & Notifications
The backend includes a real-time monitoring system:
### Components
- **InstanceEventBus** (`services/event_bus.py`): Typed pub/sub singleton for instance lifecycle events
- **HealthMonitor** (`services/health_monitor.py`): Asyncio background task polling container health every 15s
- **SSE Endpoint** (`api/events.py`): Server-Sent Events streaming for real-time frontend updates
- **Lifecycle Hooks** (`services/lifecycle_hooks.py`): Publishes events on create/start/stop/restart/delete
### Event Flow
```
Container Action → Lifecycle Hook → EventBus → SSE Stream → Frontend Toast
```
### Event Types
| Event | When Fired |
|-------|-----------|
| `instance.created` | After DB insert |
| `instance.starting` | Before docker compose up |
| `instance.running` | After readiness probe succeeds |
| `instance.error` | Build fail, crash, or probe fail |
| `instance.stopped` | After docker compose stop |
## Technology Stack
| Component | Technology | Version |