Archon/docs/getting-started.md
Rasmus Widing a28e695aee
feat: Phase 3 - Database abstraction layer and CLI isolation (#314)
* feat: Phase 3 - Database abstraction layer and CLI isolation

Part A: Database Abstraction Layer
- Add IDatabase interface supporting PostgreSQL and SQLite
- Create PostgresAdapter wrapping pg Pool with same interface
- Create SqliteAdapter using bun:sqlite with auto-schema init
- Add SqlDialect helpers for database-specific SQL generation
- Update connection.ts with auto-detection (DATABASE_URL → Postgres, else SQLite)
- Update isolation-environments.ts to use dialect helpers
- CLI now works without DATABASE_URL (uses ~/.archon/archon.db)

Part B: CLI Isolation Integration
- Add --branch/-b flag to create/reuse worktrees for workflows
- Add --no-worktree flag to run on branch directly without isolation
- Add isolation list command to show all active worktrees
- Add isolation cleanup command to remove stale environments
- Auto-register codebase when using --branch from git repo

New git utilities:
- findRepoRoot: Find git repository root from any path
- getRemoteUrl: Get origin remote URL
- checkout: Checkout branch (creating if needed)

* docs: Update documentation for Phase 3 - SQLite support and CLI isolation

* fix: Address all PR review issues for database abstraction

Critical fixes:
- Use dialect helpers (now(), jsonMerge, jsonArrayContains) in all DB operations
- Replace hardcoded PostgreSQL NOW(), ::jsonb, and JSON operators
- Add rowCount validation to updateStatus() and updateMetadata()
- Improve PostgreSQL pool error logging with structured context

Important fixes:
- Add explicit null check in getDialect() instead of non-null assertion
- Add warning for unsupported UPDATE/DELETE RETURNING in SQLite
- Throw error in extractTableName() on parse failure instead of empty string
- Track codebaseLookupError to provide clearer errors when --branch fails
- Couple IDatabase with SqlDialect via readonly sql property

Code simplifications:
- Extract loadWorkflows() helper to DRY duplicate error handling
- Fix N+1 query in getCodebases() by including repository_url in JOIN
- Cache sql.toUpperCase() to avoid redundant calls

All changes verified with:
- Type-check passes
- All 1082 tests pass
- CLI commands tested with both SQLite and PostgreSQL

* docs: Add SQLite support to getting-started, configuration, and architecture guides

* refactor: Simplify Phase 3 code for clarity and maintainability

- sqlite.ts: Remove unused UPDATE branch from extractTableName, consolidate
  RETURNING clause handling into single condition
- isolation.ts: Extract CodebaseInfo interface to reduce type duplication
- workflow.ts: Extract actualBranchName variable for clearer intent
- isolation-environments.ts: Rename variables for semantic clarity
  (staleActivityThreshold/staleCreationThreshold vs nowMinusDays1/2)

* fix: Address all remaining PR review issues

- SQLite: Throw error for UPDATE/DELETE RETURNING instead of warning
- SQLite: Replace deprecated db.exec() with db.run()
- Worktree: Throw for fatal errors (permission denied, not a git repo)
- Types: Add import type for type-only imports in 4 db modules
- Codebases: Add null check validation to createCodebase return
- WorkflowRunOptions: Add JSDoc documenting constraint behavior
- QueryResult: Add comment noting fields should be treated as readonly
- Connection: Improve getDialect() error message with actionable details

* fix: Complete type safety improvements for Phase 3

- QueryResult: Make rows and rowCount readonly to prevent mutation
- WorkflowRunOptions: Use discriminated union to prevent invalid states
  (noWorktree can only be set when branchName is provided)
- Update all database functions to return readonly arrays
- Fix CLI call site to properly construct options object

* fix: Add getDialect mock to database tests

Tests were failing because they expected hardcoded PostgreSQL SQL
(NOW(), metadata || $1::jsonb) but the code now uses dialect helpers.

- Add mockPostgresDialect to test/mocks/database.ts
- Update all db test files to mock getDialect() returning PostgreSQL dialect
- Tests now properly verify the SQL generated by dialect helpers
2026-01-21 10:38:57 +02:00

5.1 KiB

Getting Started

This guide walks you through setting up the Remote Coding Agent from scratch.

Prerequisites

Before you begin, you'll need:

  1. Docker (recommended) or Bun runtime
  2. Database - SQLite (default, zero-config) or PostgreSQL (optional, for multi-container deployments)
  3. AI Assistant credentials (Claude or Codex)
  4. Platform credentials (Telegram, Discord, Slack, or GitHub)

Step 1: Choose Your Setup Method

Method Best For Time
Docker Quick Start Trying it out, production ~10 min
Local Development Contributing, customizing ~15 min
Cloud Deployment 24/7 self-hosted ~30 min

Docker Quick Start

1.1 Get the Files

mkdir remote-agent && cd remote-agent

# Download docker-compose and env template
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/deploy/docker-compose.yml -o docker-compose.yml
curl -fsSL https://raw.githubusercontent.com/dynamous-community/remote-coding-agent/main/deploy/.env.example -o .env

1.2 Get Your Credentials

Database

Option A: Use a managed database (recommended)

  1. Create a free database at Supabase or Neon
  2. Copy the connection string

Option B: Run PostgreSQL locally

  • Uncomment the postgres service in docker-compose.yml
  • Use: postgresql://postgres:postgres@postgres:5432/remote_coding_agent

AI Assistant

Claude (recommended):

  1. Install Claude Code CLI: https://docs.anthropic.com/claude-code
  2. Run: claude setup-token
  3. Copy the token (starts with sk-ant-oat01-)

Codex:

  1. Run: codex login
  2. Copy credentials from ~/.codex/auth.json

Platform (choose at least one)

Telegram:

  1. Message @BotFather on Telegram
  2. Send /newbot and follow prompts
  3. Copy the bot token

Discord:

  1. Go to Discord Developer Portal
  2. Create New Application > Bot > Reset Token
  3. Enable MESSAGE CONTENT INTENT in Bot settings
  4. Copy the bot token

Slack:

  1. Go to Slack API
  2. Create New App > From Scratch
  3. See Slack Setup Guide for detailed steps

GitHub Webhooks:

  1. Generate a webhook secret: openssl rand -hex 32
  2. Add webhook to your repo (Settings > Webhooks)
  3. Set URL: https://your-server/webhooks/github
  4. See README GitHub Webhooks section for detailed steps

1.3 Configure

Edit .env with your credentials:

nano .env

At minimum, set:

  • DATABASE_URL (optional - omit to use SQLite at ~/.archon/archon.db)
  • One AI assistant (CLAUDE_CODE_OAUTH_TOKEN or Codex credentials)
  • One platform (TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, etc.)

1.4 Start

docker compose up -d

1.5 Verify

# Check health
curl http://localhost:3000/health
# Expected: {"status":"ok"}

# Check database
curl http://localhost:3000/health/db
# Expected: {"status":"ok","database":"connected"}

1.6 Test Your Bot

Send a message to your bot:

  • Telegram: Message your bot with /help
  • Discord: Mention your bot with @botname /help
  • Slack: Message your bot with /help

Local Development

2.1 Clone and Install

git clone https://github.com/dynamous-community/remote-coding-agent
cd remote-coding-agent
bun install

2.2 Configure

cp .env.example .env
nano .env  # Add your credentials (same as Docker method)

2.3 Start Database

docker compose --profile with-db up -d postgres

2.4 Run Migrations

psql $DATABASE_URL < migrations/000_combined.sql

2.5 Validate Setup

bun run setup:check

2.6 Start Development Server

bun run dev

The server starts with hot reload. Changes to code automatically restart.

Next Steps

Troubleshooting

"Database connection failed"

  1. Using SQLite (default): No configuration needed - database auto-created at ~/.archon/archon.db
  2. Using PostgreSQL: Check DATABASE_URL is correct
  3. For managed DB: Ensure IP is whitelisted
  4. For local: Ensure postgres container is running: docker compose ps

"No AI assistant credentials found"

Set at least one of:

  • CLAUDE_CODE_OAUTH_TOKEN (recommended)
  • CLAUDE_API_KEY
  • CODEX_ID_TOKEN + CODEX_ACCESS_TOKEN + CODEX_REFRESH_TOKEN

"Bot not responding"

  1. Check logs: docker compose logs -f app or terminal output for bun run dev
  2. Verify bot token is correct
  3. For Discord: Ensure MESSAGE CONTENT INTENT is enabled
  4. For Slack: Ensure Socket Mode is enabled

Archon Directory Not Created

The ~/.archon/ directory is created automatically on first use. To create manually:

mkdir -p ~/.archon/workspaces ~/.archon/worktrees