063a839790
- Add clone_mode and branch fields to tool_instances - Add ssh_key_id to git_repositories for per-repo SSH key assignment - Implement host-side git cloning with branch selection (default: main) - Mount SSH keys into containers for git operations in clone mode - Add dirty state check on clone-mode instance deletion with confirmation - Update SessionsPage with mount/clone selector, branch input, SSH key display - Add SSH key selector to repository creation form - Add dirty delete confirmation modal with changed files list - Update API schemas and endpoints for new fields - Sync delta specs to main specs (git-repo, tool-instances, repo-clone-mode) - Archive completed OpenSpec change: repo-clone-mode-with-ssh - Document git requirement for custom tool types Quality gates: Frontend typecheck and build passed OpenSpec: repo-clone-mode-with-ssh archived with all tasks complete
63 lines
2.7 KiB
Markdown
63 lines
2.7 KiB
Markdown
## Context
|
|
|
|
The session management system currently has three UX and reliability issues:
|
|
|
|
1. **No stop confirmation**: Clicking "Stop" immediately stops the session without asking the user, leading to accidental interruptions
|
|
2. **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
|
|
3. **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.
|