Tinker
Resources
Agent logs
Agent memories
Agent sessions
Agent terminal logs
Agents
Comments
Epics
Projects
Proposals
Tickets
Avo user
Resources
Agent logs
Agent memories
Agent sessions
Agent terminal logs
Agents
Comments
Epics
Projects
Proposals
Tickets
Avo user
Home
Agent memories
7
Details
7
Go back
Delete
Edit
Id
7
Ticket
Terminal App: WebSocket-to-Claude-Code Bridge
Agent
tinker-orchestrator
Content
# WebSocket Bridge Architecture Decision (2025-12-23) ## Problem Agents need to run as long-lived Claude Code sessions that can receive commands from Rails and respond autonomously. Current approach requires manual intervention. ## Solution: Terminal Bridge Application A Go-based bridge (`agent-bridge.go`) that: 1. Spawns Claude Code in a PTY (pseudo-terminal) for natural terminal interaction 2. Connects to Rails ActionCable WebSocket 3. Forwards Rails commands to Claude's stdin 4. Displays all Claude output for observability ## Technology Choices & Rationale ### Why Go? - Compiled to single binary - easy deployment in Docker - Excellent concurrency primitives (goroutines) - Good PTY and WebSocket libraries - Fast build times with Docker multi-stage builds ### Why PTY over subprocess? - Natural terminal emulation - Claude Code UI renders correctly - Proper handling of Tab completion, arrow keys, SIGWINCH - Raw terminal mode for interactive features - Subprocess would feel "broken" to Claude ### Why Environment Variables for config? - Docker-native (no file mounting needed) - Simple to override per-container - No complex YAML parsing in binary - Just 2 vars: `AGENT_TYPE` and `RAILS_WS_URL` ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Docker Container │ │ │ │ ┌──────────────┐ ┌─────────────┐ ┌───────────────┐ │ │ │ Rails │ ──▶│ agent-bridge│ ──▶│ Claude Code │ │ │ │ ActionCable │ │ (Go) │ │ (PTY) │ │ │ └──────────────┘ └─────────────┘ └───────────────┘ │ │ │ │ │ stdout │ │ │ ▼ │ │ [Observability] │ └─────────────────────────────────────────────────────────────┘ ``` ## Message Flow 1. Rails → WebSocket: `{"type": "command", "message": "Start work on #58"}` 2. agent-bridge receives via WebSocket subscription 3. Writes to Claude Code's stdin (blue `[RAILS COMMAND]` prefix) 4. Claude processes independently, uses MCP to update Rails 5. Full Claude output visible for monitoring ## Key Features - Auto-reconnect to WebSocket (5s backoff) - Terminal resize signal handling (SIGWINCH) - Color-coded status messages on stderr - Graceful shutdown on process exit ## Deployment - Multi-stage Dockerfile: Go builder → Node runtime - Binary at `/usr/local/bin/agent-bridge` - `run-claude-agent.rb` execs agent-bridge instead of claude directly - One container per agent type (worker, reviewer, orchestrator) ## Next Steps After #59 Approval 1. Implement Rails ActionCable `AgentChannel` 2. Define message protocol for agent commands 3. Add WebSocket broadcast when tickets assigned 4. Test end-to-end: Rails → agent-bridge → Claude → Rails ## Ticket #59 - PR #16 pending approval
Memory type
decision
Metadata
{"pr" => "16", "key_files" => ["agent-bridge.go", "Dockerfile.sandbox", "run-claude-agent.rb"], "technology" => "Go"}
Avo
· © 2026 AvoHQ ·
v3.27.0
Close modal
Are you sure?
Yes, I'm sure
No, cancel