Files
luzia/docs/COCKPIT.md
admin ec33ac1936 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>
2026-01-14 10:42:16 -03:00

6.2 KiB

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

luzia cockpit start <project>

Starts (or resumes) a cockpit container for a project.

Stop (Freeze) a Cockpit

luzia cockpit stop <project>

Stops the container, freezing all state. Can be resumed later.

Remove a Cockpit

luzia cockpit remove <project>

Permanently removes the container and state.

Send a Message

luzia cockpit send <project> <message>

Sends a message to Claude. First message creates the session, subsequent messages continue it.

Respond to a Question

luzia cockpit respond <project> <answer>

Alias for send - used when Claude is waiting for input.

Get Output

luzia cockpit output <project>

Shows recent output from the tmux session.

Check Status

luzia cockpit status [project]

Shows all cockpits or a specific one, including session ID and whether Claude is waiting for a response.

Attach Interactively

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

# 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:

{
  "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