Refactor cockpit to use DockerTmuxController pattern
Based on claude-code-tools TmuxCLIController, this refactor: - Added DockerTmuxController class for robust tmux session management - Implements send_keys() with configurable delay_enter - Implements capture_pane() for output retrieval - Implements wait_for_prompt() for pattern-based completion detection - Implements wait_for_idle() for content-hash-based idle detection - Implements wait_for_shell_prompt() for shell prompt detection Also includes workflow improvements: - Pre-task git snapshot before agent execution - Post-task commit protocol in agent guidelines Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
167
docs/COCKPIT.md
Normal file
167
docs/COCKPIT.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# Luzia Cockpit - Human-in-the-Loop Claude Sessions
|
||||
|
||||
## Overview
|
||||
|
||||
Cockpit provides **pausable Claude agent sessions** using Docker containers with tmux.
|
||||
The key innovation is that `docker stop/start` freezes/resumes the entire session state,
|
||||
and Claude sessions persist via `--session-id` and `--resume` flags.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ luzia cockpit │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ Docker Container │ │
|
||||
│ │ ┌──────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ tmux session │ │ │
|
||||
│ │ │ ┌──────────────────────────────────────────┐ │ │ │
|
||||
│ │ │ │ Claude CLI │ │ │ │
|
||||
│ │ │ │ --session-id / --resume │ │ │ │
|
||||
│ │ │ └──────────────────────────────────────────┘ │ │ │
|
||||
│ │ └──────────────────────────────────────────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ Mounts: │ │
|
||||
│ │ - /workspace → project home │ │
|
||||
│ │ - ~/.claude → credentials + sessions │ │
|
||||
│ │ - /var/cockpit → state files │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ docker stop → FREEZE (all state preserved) │
|
||||
│ docker start → RESUME (continue conversation) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
### Start a Cockpit
|
||||
```bash
|
||||
luzia cockpit start <project>
|
||||
```
|
||||
Starts (or resumes) a cockpit container for a project.
|
||||
|
||||
### Stop (Freeze) a Cockpit
|
||||
```bash
|
||||
luzia cockpit stop <project>
|
||||
```
|
||||
Stops the container, freezing all state. Can be resumed later.
|
||||
|
||||
### Remove a Cockpit
|
||||
```bash
|
||||
luzia cockpit remove <project>
|
||||
```
|
||||
Permanently removes the container and state.
|
||||
|
||||
### Send a Message
|
||||
```bash
|
||||
luzia cockpit send <project> <message>
|
||||
```
|
||||
Sends a message to Claude. First message creates the session,
|
||||
subsequent messages continue it.
|
||||
|
||||
### Respond to a Question
|
||||
```bash
|
||||
luzia cockpit respond <project> <answer>
|
||||
```
|
||||
Alias for send - used when Claude is waiting for input.
|
||||
|
||||
### Get Output
|
||||
```bash
|
||||
luzia cockpit output <project>
|
||||
```
|
||||
Shows recent output from the tmux session.
|
||||
|
||||
### Check Status
|
||||
```bash
|
||||
luzia cockpit status [project]
|
||||
```
|
||||
Shows all cockpits or a specific one, including session ID and
|
||||
whether Claude is waiting for a response.
|
||||
|
||||
### Attach Interactively
|
||||
```bash
|
||||
luzia cockpit attach <project>
|
||||
```
|
||||
Shows the command to attach to the tmux session for interactive work.
|
||||
|
||||
## Session Persistence
|
||||
|
||||
Claude sessions are stored in the mounted `~/.claude/` directory:
|
||||
```
|
||||
~/.claude/projects/{workspace-path}/{session-id}.jsonl
|
||||
```
|
||||
|
||||
The cockpit tracks:
|
||||
- `session_id` - UUID for the Claude conversation
|
||||
- `session_started` - Whether first message has been sent
|
||||
- `awaiting_response` - If Claude asked a question (detected by "?" at end)
|
||||
- `last_question` - The question Claude asked
|
||||
|
||||
## Example Workflow
|
||||
|
||||
```bash
|
||||
# Start a cockpit for musica project
|
||||
luzia cockpit start musica
|
||||
# → Started cockpit, Session: abc-123-def
|
||||
|
||||
# Send a task
|
||||
luzia cockpit send musica "Fix the track component loading bug"
|
||||
# → Claude analyzes and responds
|
||||
|
||||
# Claude asks a question - FREEZE the session
|
||||
luzia cockpit stop musica
|
||||
# → Container paused, queue can continue with other projects
|
||||
|
||||
# Later, human comes back with answer - RESUME
|
||||
luzia cockpit start musica
|
||||
luzia cockpit respond musica "Use lazy loading, target is 200ms"
|
||||
# → Claude continues with the answer
|
||||
```
|
||||
|
||||
## Integration with Queue
|
||||
|
||||
When Claude is waiting for human input:
|
||||
1. Set project queue to `awaiting_human` status
|
||||
2. Other projects continue processing
|
||||
3. On human response, resume project queue
|
||||
|
||||
## Docker Image
|
||||
|
||||
Built from `/opt/server-agents/orchestrator/docker/cockpit/Dockerfile`:
|
||||
- Base: `debian:bookworm-slim`
|
||||
- Node.js 20 LTS
|
||||
- Claude CLI (`@anthropic-ai/claude-code`)
|
||||
- tmux with 50000 line history
|
||||
- Mouse support for human attach
|
||||
|
||||
## State Files
|
||||
|
||||
```
|
||||
/var/lib/luz-orchestrator/cockpits/
|
||||
├── admin.json
|
||||
├── musica.json
|
||||
└── overbits.json
|
||||
```
|
||||
|
||||
Each JSON file contains:
|
||||
```json
|
||||
{
|
||||
"project": "musica",
|
||||
"session_id": "abc-123-def",
|
||||
"status": "running",
|
||||
"session_started": true,
|
||||
"awaiting_response": false,
|
||||
"last_question": null
|
||||
}
|
||||
```
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **True Pause/Resume** - `docker stop/start` freezes everything
|
||||
2. **Conversation Memory** - Claude remembers via session persistence
|
||||
3. **Non-blocking Queue** - Projects don't block each other
|
||||
4. **Human Attachment** - Can attach tmux for direct interaction
|
||||
5. **Credential Isolation** - Each project uses shared credentials safely
|
||||
Reference in New Issue
Block a user