- Add inline confirmation dialog before stopping instances - Delete instances from state immediately without page reload - Add health check polling every 30s for running instances - Show tunnel error badge when tunnel is unreachable - Add 'Fix Tunnel' button to recreate broken tunnels - Update API client with health check and tunnel recreation endpoints
2.7 KiB
Context
The session management system currently has three UX and reliability issues:
- No stop confirmation: Clicking "Stop" immediately stops the session without asking the user, leading to accidental interruptions
- Stale state after delete: When a session is deleted, the frontend React state is not updated, so the deleted session remains visible until the page is manually reloaded
- No tunnel recovery: If a temporary Cloudflare tunnel breaks (e.g., cloudflared process dies), there's no way to recreate it without stopping and restarting the entire instance
The system uses temporary Cloudflare tunnels (cloudflared tunnel --url) which run as background processes inside the API container. These tunnels can fail silently.
Goals / Non-Goals
Goals:
- Prevent accidental session stops with a confirmation dialog
- Update frontend state immediately after successful deletion
- Monitor tunnel health by checking HTTP responses
- Allow tunnel recreation without instance restart
- Display tunnel health status to users
Non-Goals:
- Persistent tunnels (we're keeping temporary tunnels)
- Auto-recovery of broken tunnels (manual button only)
- Changing the Docker compose architecture
- Adding WebSocket health checks
Decisions
1. Frontend confirmation dialog
- Use a simple inline confirmation (not a modal) to match existing patterns in the codebase
- Show "Confirm stop? [Cancel] [Stop]" when stop is clicked
- Reuse existing CSS button styles
2. Frontend state update after delete
- Filter out the deleted session from local React state immediately after delete API call succeeds
- Don't wait for the next polling cycle
3. Tunnel health check
- Poll tunnel health every 30 seconds via HEAD request to the tunnel URL
- Check only running instances (status === "running")
- Mark as "error" if response is not 2xx or request fails
- Show error badge next to session name
4. Tunnel recreation
- New backend endpoint:
POST /instances/{id}/recreate-tunnel - Kills old cloudflared process (if any) via stored PID
- Starts new cloudflared process with
start_cloudflared_tunnel() - Updates instance.url and instance.tunnel_id in database
- Frontend button: "Recreate Tunnel" appears when tunnel is in error state
Risks / Trade-offs
[Risk] Health check adds network overhead → Mitigation: Only check every 30s, only for running instances [Risk] Recreating tunnel while user is connected → Mitigation: User-initiated action, brief downtime (5-10s) [Risk] PID reuse could kill wrong process → Mitigation: Check process name before killing (optional enhancement)
Migration Plan
No migration needed. These are UI/UX improvements on existing data model.
Open Questions
None.