rdev/ai-lookup/features/command-execution.md
jordan 39df51defd feat: Add multi-provider code agent interface with Claude Code and OpenCode adapters
Implements weeks 1-4 of the multi-provider architecture:

Week 1 - Foundation:
- Add domain models (AgentProvider, AgentRequest, AgentEvent, AgentResult)
- Define CodeAgent port interface with Execute, Cancel, Capabilities
- Create thread-safe provider registry with first-registered default

Week 2 - Claude Code Adapter:
- Extract kubectl exec logic into CodeAgent implementation
- Parse stream-json output format (init, message, tool_use, result)
- Support session continuation via --resume flag

Week 3 - OpenCode Adapter:
- HTTP/SSE client for opencode serve API
- Session management (create, send message, abort)
- Event streaming with documented buffer rationale

Week 4 - Quality & Polish:
- Fix race condition in OpenCode Cancel method
- Add AgentRequest.Validate() with ErrPromptRequired, ErrInvalidTimeout
- Document DefaultAvailabilityTimeout constants
- Add HTTP error context for debugging

Also includes:
- Work queue system with PostgreSQL adapter
- Credential store for infrastructure secrets
- Project templates with Woodpecker CI integration
- Comprehensive test coverage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 09:25:51 -07:00

1.6 KiB

Command Execution

Last Updated: 2025-01 Confidence: High

Summary

rdev executes commands (Claude, shell, git) in Kubernetes pods via kubectl exec. Commands can run synchronously or be queued for async processing with SSE output streaming.

Key Facts:

  • Commands run in pods with label rdev.orchard9.ai/project=true
  • Three types: claude, shell, git
  • Async queue with status tracking (pending → running → completed/failed)
  • Output streamed via SSE to /projects/{id}/events/{stream_id}
  • All commands logged to audit trail

File Pointers:

  • Executor: internal/adapter/kubernetes/executor.go
  • Queue: internal/adapter/postgres/queue.go
  • Worker: internal/worker/queue.go
  • Handler: internal/handlers/projects.go

Command Flow

Handler → Service → Queue (postgres)
                        ↓
                    Worker polls
                        ↓
                    Executor (kubectl exec)
                        ↓
                    StreamPublisher (SSE)
                        ↓
                    Webhook dispatch

Request/Response

POST /projects/{id}/claude
Body: { "prompt": "write a hello world" }

Response:
{
    "command_id": "cmd-abc123",
    "stream_url": "/projects/my-project/events/stream-xyz"
}

Status Transitions

Status Description
pending In queue, not started
running Currently executing
completed Finished successfully (exit 0)
failed Error or non-zero exit