# Tool Instances - Design ## Architecture ``` Tool Instance System ├── Backend │ ├── ToolInstance Model │ ├── Session API (CRUD + lifecycle) │ ├── Docker Service (compose execution) │ └── Status Polling ├── Frontend │ ├── SessionStore (active sessions) │ ├── AppShell Integration (nav entries) │ ├── Instance Manager (repo page) │ └── Session Launcher (create dialog) └── Docker ├── Compose Template Rendering ├── Container Execution └── Volume Management ``` ## Data Model ### ToolInstance ```python class ToolInstance(Base): id: UUID name: str # Generated: "vscode-myrepo-abc123" display_name: str # User-friendly name tool_type_id: UUID -> ToolType repository_id: UUID -> GitRepository project_id: UUID -> Project owner_id: UUID -> User status: str # pending, building, running, stopped, error container_id: str | None compose_path: str | None # Path to rendered compose file url: str | None # Access URL port: int | None last_started_at: datetime | None last_stopped_at: datetime | None created_at: datetime updated_at: datetime ``` ## API Design ### Endpoints ``` POST /projects/{id}/repositories/{id}/instances GET /projects/{id}/repositories/{id}/instances GET /projects/{id}/repositories/{id}/instances/{id} PUT /projects/{id}/repositories/{id}/instances/{id} DELETE /projects/{id}/repositories/{id}/instances/{id} POST /projects/{id}/repositories/{id}/instances/{id}/start POST /projects/{id}/repositories/{id}/instances/{id}/stop POST /projects/{id}/repositories/{id}/instances/{id}/restart GET /projects/{id}/repositories/{id}/instances/{id}/status GET /projects/{id}/repositories/{id}/instances/{id}/logs GET /users/me/sessions # Active sessions for nav ``` ## Docker Integration ### Compose Template Rendering ```yaml # Template variables: # {{REPO_PATH}} - Absolute path to repo # {{INSTANCE_NAME}} - Unique instance name # {{TOOL_PORT}} - Exposed port services: {{INSTANCE_NAME}}: image: codercom/code-server:latest volumes: - {{REPO_PATH}}:/workspace ports: - "{{TOOL_PORT}}:8080" environment: - PASSWORD={{INSTANCE_NAME}} ``` ### Execution Flow 1. Create instance directory: `data/instances/{instance_id}/` 2. Render compose file to `docker-compose.yml` 3. Run `docker compose -f {path} up -d` 4. Capture container ID from output 5. Poll status until running or error ## Frontend Integration ### Session Store ```typescript interface Session { id: string; name: string; displayName: string; toolType: string; toolIcon: string; repositoryId: string; projectId: string; status: "pending" | "running" | "stopped" | "error"; url: string | null; } const useSessions = () => { const sessions = useAtom(sessionsAtom); const addSession = (session: Session) => { ... }; const removeSession = (id: string) => { ... }; const updateStatus = (id: string, status: string) => { ... }; return { sessions, addSession, removeSession, updateStatus }; }; ``` ### AppShell Navigation - Add "Sessions" section in nav - Show active sessions with tool icons - Session status indicator (green dot for running) - Click opens tool in new tab - Dropdown for managing sessions ### Repository Page - "Launch Tool" button - Dialog to select tool type - Instance list with status/actions - Quick actions: start/stop/delete ## State Machine ``` [create] -> pending -> [docker up] -> building -> [container running] -> running | v [docker error] -> error [running] -> [stop] -> stopped [stopped] -> [start] -> pending -> building -> running [any] -> [delete] -> [docker down] -> deleted ``` ## Security - Only repository owner can create instances - Instances run in isolated Docker networks - No privileged containers - Resource limits (CPU, memory) on containers