SQLite-first docs, fix Postgres workflow_runs default, rebuild combined schema

- Fix workflow_runs.status DEFAULT from 'running' to 'pending' in Postgres
  (migration 018) to match SQLite and actual code flow
- Rebuild 000_combined.sql as clean final schema (7 tables, no stale columns,
  correct defaults, all indexes)
- Update all docs to present SQLite as the default, zero-setup option
- Mark PostgreSQL as optional/advanced in README, CLAUDE.md, and guides

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Cole Medin 2026-02-17 11:23:59 -06:00
parent 2953bb0275
commit f2a0d029e7
13 changed files with 182 additions and 156 deletions

View file

@ -160,11 +160,13 @@ archon version
```
Should show:
- `Database: postgresql` or `Database: sqlite` based on selection
- `Database: sqlite` (default, zero setup) or `Database: postgresql` (if DATABASE_URL was configured)
- No errors about missing configuration
### 5d: Run Database Migrations (PostgreSQL only)
**SQLite users: skip this step.** SQLite is auto-initialized on first run with zero setup.
If the user selected PostgreSQL, run migrations:
```bash

View file

@ -1,6 +1,6 @@
## Project Overview
**Remote Agentic Coding Platform**: Control AI coding assistants (Claude Code SDK, Codex SDK) remotely from Slack, Telegram, and GitHub. Built with **Bun + TypeScript + PostgreSQL/SQLite**, single-developer tool for practitioners of the Dynamous Agentic Coding Course. Architecture prioritizes simplicity, flexibility, and user control.
**Remote Agentic Coding Platform**: Control AI coding assistants (Claude Code SDK, Codex SDK) remotely from Slack, Telegram, and GitHub. Built with **Bun + TypeScript + SQLite/PostgreSQL**, single-developer tool for practitioners of the Dynamous Agentic Coding Course. Architecture prioritizes simplicity, flexibility, and user control.
## Core Principles
@ -181,13 +181,13 @@ if (!steps) {
### Database
**Auto-Detection:**
- **With `DATABASE_URL` set**: Uses PostgreSQL
- **Without `DATABASE_URL`**: Uses SQLite at `~/.archon/archon.db` (auto-initialized)
**Auto-Detection (SQLite is the default — zero setup):**
- **Without `DATABASE_URL`**: Uses SQLite at `~/.archon/archon.db` (auto-initialized, recommended for most users)
- **With `DATABASE_URL` set**: Uses PostgreSQL (optional, for cloud/advanced deployments)
```bash
# PostgreSQL: Run SQL migrations (manual)
psql $DATABASE_URL < migrations/001_initial_schema.sql
# PostgreSQL only: Run SQL migrations (manual)
psql $DATABASE_URL < migrations/000_combined.sql
```
### Docker (Production)

View file

@ -212,7 +212,7 @@ cp .env.example .env
| Variable | Purpose | How to Get |
|----------|---------|------------|
| `DATABASE_URL` | PostgreSQL connection (optional) | See database options below. Omit to use SQLite |
| `DATABASE_URL` | PostgreSQL connection (optional) | Omit for SQLite (default, zero setup). See database options below |
| `GH_TOKEN` | Repository cloning | [Generate token](https://github.com/settings/tokens) with `repo` scope |
| `GITHUB_TOKEN` | Same as `GH_TOKEN` | Use same token value |
| `PORT` | HTTP server port | Default: `3090` (optional) |
@ -232,9 +232,9 @@ GITHUB_TOKEN=ghp_your_token_here # Same value
**Note:** Repository clones are stored in `~/.archon/workspaces/` by default (or `/.archon/workspaces/` in Docker). Set `ARCHON_HOME` to override the base directory.
**Database Setup - Choose One:**
**Database Setup — SQLite is the default (zero setup, recommended for most users):**
<details>
<details open>
<summary><b>Option A: SQLite (Default - No Setup Required)</b></summary>
Simply **omit the `DATABASE_URL` variable** from your `.env` file. The app will automatically:
@ -254,7 +254,7 @@ Simply **omit the `DATABASE_URL` variable** from your `.env` file. The app will
</details>
<details>
<summary><b>Option B: Remote PostgreSQL (Supabase, Neon)</b></summary>
<summary><b>Option B: Remote PostgreSQL — Advanced (Supabase, Neon)</b></summary>
Set your remote connection string:
@ -292,7 +292,7 @@ psql $DATABASE_URL < migrations/011_partial_unique_constraint.sql
</details>
<details>
<summary><b>Option C: Local PostgreSQL (via Docker)</b></summary>
<summary><b>Option C: Local PostgreSQL — Advanced (via Docker)</b></summary>
Use the `with-db` profile for automatic PostgreSQL setup:
@ -765,9 +765,20 @@ The bot responds to:
### 4. Start the Application
Choose the Docker Compose profile based on your database setup:
Choose how to start the application based on your setup:
**Option A: With Remote PostgreSQL (Supabase, Neon, etc.)**
**Option A: Local Development (Recommended — SQLite, No Docker)**
Run directly with Bun. SQLite is the default — no database setup needed:
```bash
bun install # First time only
bun run dev # Starts server + Web UI with hot reload
# Web UI: http://localhost:5173
# API: http://localhost:3090
```
**Option B: With Remote PostgreSQL (Supabase, Neon, etc.)**
Starts only the app container (requires `DATABASE_URL` set to remote database in `.env`):
@ -779,7 +790,7 @@ docker compose --profile external-db up -d --build
docker compose logs -f app
```
**Option B: With Local PostgreSQL (Docker)**
**Option C: With Local PostgreSQL (Docker)**
Starts both the app and PostgreSQL containers:
@ -793,17 +804,6 @@ docker compose logs -f app-with-db
# Database tables are created automatically via init script
```
**Option C: Local Development (No Docker)**
Run directly with Bun. Uses SQLite by default (no database setup needed), or set `DATABASE_URL` for PostgreSQL:
```bash
bun install # First time only
bun run dev # Starts server + Web UI with hot reload
# Web UI: http://localhost:5173
# API: http://localhost:3090
```
**Stop the application:**
```bash

View file

@ -2,9 +2,12 @@
# Copy to .env and fill in your values
# ============================================
# Required: Database
# Database (Optional — SQLite is the default for local dev)
# ============================================
# Use a managed PostgreSQL (Supabase, Neon, etc.)
# For local development, omit DATABASE_URL entirely — SQLite at ~/.archon/archon.db
# is auto-initialized with zero setup.
#
# For cloud/production deployments, use a managed PostgreSQL (Supabase, Neon, etc.):
DATABASE_URL=postgresql://user:password@host:5432/dbname
# Or uncomment postgres service in docker-compose.yml and use:

View file

@ -19,7 +19,8 @@ services:
sysctls:
- net.ipv6.conf.all.disable_ipv6=1
# Use this for local Docker database
# Use this for local Docker database (only needed when using PostgreSQL)
# SQLite is the default for local dev — no database container required.
# Command: docker-compose --profile with-db up
app-with-db:
profiles: ["with-db"]

View file

@ -45,10 +45,10 @@ The Remote Coding Agent is a **platform-agnostic AI coding assistant orchestrato
└───────────────┼───────────────────┘
┌─────────────────────────────────────────────┐
PostgreSQL/SQLite (8 Tables)
SQLite (default) / PostgreSQL (7 Tables)
│ • Codebases • Conversations • Sessions │
│ • Command Templates • Isolation Envs
│ • Workflow Runs • Workflow Events • Messages│
│ • Isolation Envs • Workflow Runs
│ • Workflow Events • Messages
└─────────────────────────────────────────────┘
```
@ -1005,7 +1005,7 @@ export function formatToolCall(toolName: string, toolInput?: Record<string, unkn
## Database Schema
The platform uses an 8-table schema with `remote_agent_` prefix.
The platform uses a 7-table schema with `remote_agent_` prefix. SQLite is the default (zero setup); PostgreSQL is optional for cloud/advanced deployments.
### Schema Overview

View file

@ -299,6 +299,7 @@ Worktrees stored at: `~/.archon/worktrees/<repo>/<branch-slug>/`
- Connection opened on first database call
- Always closed in `finally` block after command completes
- Auto-detects PostgreSQL (`DATABASE_URL`) or SQLite (`~/.archon/archon.db`)
- **Default: SQLite** at `~/.archon/archon.db` (zero setup, auto-initialized)
- **Optional: PostgreSQL** when `DATABASE_URL` is set (for cloud/advanced deployments)
**Code:** `packages/cli/src/cli.ts:229-241`

View file

@ -139,10 +139,10 @@ Auto-enables global Claude auth if no explicit tokens are set.
## Database
- **With `DATABASE_URL`:** Uses PostgreSQL
- **Without:** Uses SQLite at `~/.archon/archon.db`
- **Without `DATABASE_URL` (default):** Uses SQLite at `~/.archon/archon.db` — zero setup, auto-initialized on first run
- **With `DATABASE_URL`:** Uses PostgreSQL (optional, for cloud/advanced deployments)
Both work transparently. SQLite is auto-initialized on first run.
Both work transparently. Most users never need to configure a database.
## Examples

View file

@ -273,8 +273,10 @@ ARCHON_HOME=/tmp/archon # Override base directory (optional)
**Database Options:**
> **Note:** SQLite is the default for local development and requires zero setup. For cloud deployments, PostgreSQL is recommended for reliability and network accessibility.
<details>
<summary><b>Recommended: Remote Managed PostgreSQL</b></summary>
<summary><b>Recommended for Cloud: Remote Managed PostgreSQL</b></summary>
Use a managed database service for easier backups and scaling.

View file

@ -121,7 +121,7 @@ Environment variables override all other configuration:
| Variable | Description | Default |
| ------------------------------ | -------------------------- | ------------- |
| `DATABASE_URL` | PostgreSQL connection (optional) | SQLite at `~/.archon/archon.db` (recommended for single-developer use) |
| `DATABASE_URL` | PostgreSQL connection (optional — omit for SQLite) | SQLite at `~/.archon/archon.db` (default, zero setup, recommended) |
| `ARCHON_HOME` | Base directory for Archon | `~/.archon` |
| `DEFAULT_AI_ASSISTANT` | Default AI assistant | `claude` |
| `TELEGRAM_STREAMING_MODE` | Telegram streaming | `stream` |

View file

@ -103,15 +103,17 @@ TRUNCATE remote_agent_codebases CASCADE;
After a fresh start, the app defaults are loaded **automatically at runtime** - no manual steps needed.
> **Note:** SQLite is the default database and requires zero setup. The PostgreSQL steps below are only needed if you've set `DATABASE_URL`.
**1. Start the app:**
```bash
# Development (with hot reload)
docker-compose --profile with-db up -d postgres
# Development (with hot reload) — SQLite is used by default, no database setup needed
bun run dev
# Or production
docker-compose --profile with-db up -d
# Optional: Use PostgreSQL instead
docker-compose --profile with-db up -d postgres
# Set DATABASE_URL in .env, then: bun run dev
```
**2. Verify defaults are available:**

View file

@ -1,12 +1,28 @@
-- Remote Coding Agent - Combined Schema
-- Version: Combined (includes migrations 001-015)
-- Version: Combined (final state after migrations 001-018)
-- Description: Complete database schema (idempotent - safe to run multiple times)
--
-- 7 Tables:
-- 1. remote_agent_codebases
-- 2. remote_agent_conversations
-- 3. remote_agent_sessions
-- 4. remote_agent_isolation_environments
-- 5. remote_agent_workflow_runs
-- 6. remote_agent_workflow_events
-- 7. remote_agent_messages
--
-- Dropped tables (via migrations):
-- - remote_agent_command_templates (017)
--
-- Dropped columns (via migrations):
-- - conversations.worktree_path (007)
-- - conversations.isolation_env_id_legacy (007)
-- - conversations.isolation_provider (007)
-- ============================================================================
-- Migration 001: Initial Schema
-- ============================================================================
-- Table 1: Codebases
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_codebases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
@ -18,29 +34,48 @@ CREATE TABLE IF NOT EXISTS remote_agent_codebases (
updated_at TIMESTAMP DEFAULT NOW()
);
COMMENT ON TABLE remote_agent_codebases IS
'Repository metadata: name, URL, working directory, AI assistant type, and command paths (JSONB)';
-- ============================================================================
-- Table 2: Conversations
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_conversations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
platform_type VARCHAR(20) NOT NULL,
platform_conversation_id VARCHAR(255) NOT NULL,
codebase_id UUID REFERENCES remote_agent_codebases(id),
codebase_id UUID REFERENCES remote_agent_codebases(id) ON DELETE SET NULL,
cwd VARCHAR(500),
ai_assistant_type VARCHAR(20) DEFAULT 'claude',
isolation_env_id UUID, -- FK added after isolation_environments table exists
title VARCHAR(255),
deleted_at TIMESTAMP WITH TIME ZONE,
hidden BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(platform_type, platform_conversation_id)
);
CREATE INDEX IF NOT EXISTS idx_remote_agent_conversations_codebase ON remote_agent_conversations(codebase_id);
CREATE INDEX IF NOT EXISTS idx_remote_agent_conversations_codebase
ON remote_agent_conversations(codebase_id);
CREATE INDEX IF NOT EXISTS idx_conversations_hidden
ON remote_agent_conversations(hidden);
CREATE INDEX IF NOT EXISTS idx_conversations_codebase
ON remote_agent_conversations(codebase_id) WHERE deleted_at IS NULL;
COMMENT ON COLUMN remote_agent_conversations.isolation_env_id IS
'UUID reference to isolation_environments table (the only isolation reference)';
-- ============================================================================
-- Table 3: Sessions
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
conversation_id UUID REFERENCES remote_agent_conversations(id) ON DELETE CASCADE,
codebase_id UUID REFERENCES remote_agent_codebases(id),
codebase_id UUID REFERENCES remote_agent_codebases(id) ON DELETE SET NULL,
ai_assistant_type VARCHAR(20) NOT NULL,
assistant_session_id VARCHAR(255),
active BOOLEAN DEFAULT true,
@ -52,29 +87,24 @@ CREATE TABLE IF NOT EXISTS remote_agent_sessions (
ended_at TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_remote_agent_sessions_conversation ON remote_agent_sessions(conversation_id, active);
CREATE INDEX IF NOT EXISTS idx_remote_agent_sessions_codebase ON remote_agent_sessions(codebase_id);
CREATE INDEX IF NOT EXISTS idx_remote_agent_sessions_conversation
ON remote_agent_sessions(conversation_id, active);
CREATE INDEX IF NOT EXISTS idx_remote_agent_sessions_codebase
ON remote_agent_sessions(codebase_id);
CREATE INDEX IF NOT EXISTS idx_sessions_parent
ON remote_agent_sessions(parent_session_id);
CREATE INDEX IF NOT EXISTS idx_sessions_conversation_started
ON remote_agent_sessions(conversation_id, started_at DESC);
COMMENT ON COLUMN remote_agent_sessions.parent_session_id IS
'Links to the previous session in this conversation (for audit trail)';
COMMENT ON COLUMN remote_agent_sessions.transition_reason IS
'Why this session was created: plan-to-execute, isolation-changed, reset-requested, etc.';
COMMENT ON COLUMN remote_agent_sessions.ended_reason IS
'Why this session was deactivated: reset-requested, cwd-changed, conversation-closed, etc.';
-- ============================================================================
-- Migration 003: Add Worktree Support
-- ============================================================================
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS worktree_path VARCHAR(500);
COMMENT ON COLUMN remote_agent_conversations.worktree_path IS
'Path to git worktree for this conversation. If set, AI works here instead of cwd.';
-- ============================================================================
-- Migration 004: Worktree Sharing Index
-- ============================================================================
CREATE INDEX IF NOT EXISTS idx_remote_agent_conversations_worktree
ON remote_agent_conversations(worktree_path)
WHERE worktree_path IS NOT NULL;
-- ============================================================================
-- Migration 006: Isolation Environments
-- Table 4: Isolation Environments
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_isolation_environments (
@ -97,8 +127,6 @@ CREATE TABLE IF NOT EXISTS remote_agent_isolation_environments (
-- Cross-reference metadata (for linking)
metadata JSONB DEFAULT '{}'
-- Note: uniqueness enforced via partial index below (only active environments)
);
-- Partial unique index: only active environments need uniqueness
@ -114,16 +142,11 @@ CREATE INDEX IF NOT EXISTS idx_isolation_env_status
CREATE INDEX IF NOT EXISTS idx_isolation_env_workflow
ON remote_agent_isolation_environments(workflow_type, workflow_id);
-- Add FK to conversations
-- Add FK from conversations to isolation_environments (deferred to avoid circular dependency)
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS isolation_env_id UUID
REFERENCES remote_agent_isolation_environments(id) ON DELETE SET NULL;
-- Add last_activity_at for staleness detection
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW();
-- Create index for FK lookups
CREATE INDEX IF NOT EXISTS idx_conversations_isolation_env_id
ON remote_agent_conversations(isolation_env_id);
@ -135,7 +158,7 @@ COMMENT ON COLUMN remote_agent_isolation_environments.workflow_id IS
'Identifier for the work (issue number, PR number, thread hash, etc.)';
-- ============================================================================
-- Migration 008: Workflow Runs
-- Table 5: Workflow Runs
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_workflow_runs (
@ -143,66 +166,33 @@ CREATE TABLE IF NOT EXISTS remote_agent_workflow_runs (
workflow_name VARCHAR(255) NOT NULL,
conversation_id UUID REFERENCES remote_agent_conversations(id) ON DELETE CASCADE,
codebase_id UUID REFERENCES remote_agent_codebases(id) ON DELETE SET NULL,
current_step_index INTEGER DEFAULT 0,
status VARCHAR(20) NOT NULL DEFAULT 'running', -- running, completed, failed
current_step_index INTEGER,
status VARCHAR(20) NOT NULL DEFAULT 'pending', -- pending, running, completed, failed
user_message TEXT NOT NULL,
metadata JSONB DEFAULT '{}',
parent_conversation_id UUID REFERENCES remote_agent_conversations(id) ON DELETE SET NULL,
started_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
completed_at TIMESTAMP WITH TIME ZONE
completed_at TIMESTAMP WITH TIME ZONE,
last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_workflow_runs_conversation
ON remote_agent_workflow_runs(conversation_id);
CREATE INDEX IF NOT EXISTS idx_workflow_runs_status
ON remote_agent_workflow_runs(status);
CREATE INDEX IF NOT EXISTS idx_workflow_runs_parent_conv
ON remote_agent_workflow_runs(parent_conversation_id);
-- Partial index for efficient staleness queries on running workflows
CREATE INDEX IF NOT EXISTS idx_workflow_runs_last_activity
ON remote_agent_workflow_runs(last_activity_at)
WHERE status = 'running';
COMMENT ON TABLE remote_agent_workflow_runs IS
'Tracks workflow execution state for resumption and observability';
-- ============================================================================
-- Migration 009: Workflow Last Activity
-- ============================================================================
ALTER TABLE remote_agent_workflow_runs
ADD COLUMN IF NOT EXISTS last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW();
-- Partial index for efficient staleness queries on running workflows
CREATE INDEX IF NOT EXISTS idx_workflow_runs_last_activity
ON remote_agent_workflow_runs(last_activity_at)
WHERE status = 'running';
-- ============================================================================
-- Migration 010: Immutable Sessions (parent linkage + transition tracking)
-- ============================================================================
ALTER TABLE remote_agent_sessions
ADD COLUMN IF NOT EXISTS parent_session_id UUID REFERENCES remote_agent_sessions(id);
ALTER TABLE remote_agent_sessions
ADD COLUMN IF NOT EXISTS transition_reason TEXT;
CREATE INDEX IF NOT EXISTS idx_sessions_parent ON remote_agent_sessions(parent_session_id);
CREATE INDEX IF NOT EXISTS idx_sessions_conversation_started
ON remote_agent_sessions(conversation_id, started_at DESC);
COMMENT ON COLUMN remote_agent_sessions.parent_session_id IS
'Links to the previous session in this conversation (for audit trail)';
COMMENT ON COLUMN remote_agent_sessions.transition_reason IS
'Why this session was created: plan-to-execute, isolation-changed, reset-requested, etc.';
-- ============================================================================
-- Migration 011: Partial Unique Constraint Fix
-- ============================================================================
-- Drop the existing full constraint (if it exists from older migrations)
ALTER TABLE remote_agent_isolation_environments
DROP CONSTRAINT IF EXISTS unique_workflow;
-- Partial unique index already created in Migration 006 above (unique_active_workflow)
-- ============================================================================
-- Migration 012: Workflow Events
-- Table 6: Workflow Events
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_workflow_events (
@ -224,19 +214,7 @@ COMMENT ON TABLE remote_agent_workflow_events IS
'Lean UI-relevant workflow events for observability (step transitions, artifacts, errors)';
-- ============================================================================
-- Migration 013: Conversation Titles + Soft Delete
-- ============================================================================
-- title and deleted_at already included in conversations CREATE TABLE above.
-- ALTER statements kept for idempotent upgrades from older schemas:
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS title VARCHAR(255);
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP WITH TIME ZONE;
-- ============================================================================
-- Migration 014: Message History
-- Table 7: Messages
-- ============================================================================
CREATE TABLE IF NOT EXISTS remote_agent_messages (
@ -252,29 +230,58 @@ CREATE INDEX IF NOT EXISTS idx_messages_conversation_id
ON remote_agent_messages(conversation_id, created_at ASC);
-- ============================================================================
-- Migration 015: Background Dispatch
-- Cleanup: Drop legacy objects from older schemas
-- ============================================================================
-- Drop command_templates table (replaced by file-based commands in .archon/commands)
DROP TABLE IF EXISTS remote_agent_command_templates;
DROP INDEX IF EXISTS idx_remote_agent_command_templates_name;
-- Drop legacy columns from conversations (if upgrading from older schema)
ALTER TABLE remote_agent_conversations DROP COLUMN IF EXISTS worktree_path;
ALTER TABLE remote_agent_conversations DROP COLUMN IF EXISTS isolation_env_id_legacy;
ALTER TABLE remote_agent_conversations DROP COLUMN IF EXISTS isolation_provider;
DROP INDEX IF EXISTS idx_conversations_isolation;
-- Drop legacy constraint from isolation_environments (if upgrading from older schema)
ALTER TABLE remote_agent_isolation_environments
DROP CONSTRAINT IF EXISTS unique_workflow;
-- ============================================================================
-- Idempotent ALTER statements for upgrading existing databases
-- (These are no-ops on fresh installs since columns exist in CREATE TABLE above)
-- ============================================================================
-- From migration 006: isolation_env_id + last_activity_at on conversations
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS isolation_env_id UUID
REFERENCES remote_agent_isolation_environments(id) ON DELETE SET NULL;
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW();
-- From migration 009: last_activity_at on workflow_runs
ALTER TABLE remote_agent_workflow_runs
ADD COLUMN IF NOT EXISTS last_activity_at TIMESTAMP WITH TIME ZONE DEFAULT NOW();
-- From migration 010: parent_session_id + transition_reason on sessions
ALTER TABLE remote_agent_sessions
ADD COLUMN IF NOT EXISTS parent_session_id UUID REFERENCES remote_agent_sessions(id);
ALTER TABLE remote_agent_sessions
ADD COLUMN IF NOT EXISTS transition_reason TEXT;
-- From migration 013: title + deleted_at on conversations
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS title VARCHAR(255);
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP WITH TIME ZONE;
-- From migration 015: parent_conversation_id + hidden
ALTER TABLE remote_agent_workflow_runs
ADD COLUMN IF NOT EXISTS parent_conversation_id UUID
REFERENCES remote_agent_conversations(id) ON DELETE SET NULL;
REFERENCES remote_agent_conversations(id) ON DELETE SET NULL;
ALTER TABLE remote_agent_conversations
ADD COLUMN IF NOT EXISTS hidden BOOLEAN DEFAULT FALSE;
CREATE INDEX IF NOT EXISTS idx_workflow_runs_parent_conv
ON remote_agent_workflow_runs(parent_conversation_id);
CREATE INDEX IF NOT EXISTS idx_conversations_hidden
ON remote_agent_conversations(hidden);
CREATE INDEX IF NOT EXISTS idx_conversations_codebase
ON remote_agent_conversations(codebase_id) WHERE deleted_at IS NULL;
-- ============================================================================
-- Migration 016: Session ended_reason
-- ============================================================================
-- From migration 016: ended_reason on sessions
ALTER TABLE remote_agent_sessions
ADD COLUMN IF NOT EXISTS ended_reason TEXT;
COMMENT ON COLUMN remote_agent_sessions.ended_reason IS
'Why this session was deactivated: reset-requested, cwd-changed, conversation-closed, etc.';

View file

@ -0,0 +1,8 @@
-- Fix workflow_runs.status default to match SQLite and actual code flow
-- Version: 18.0
-- Description: The executor creates workflow runs as 'pending' then explicitly
-- sets them to 'running'. Migration 008 incorrectly set DEFAULT 'running'.
-- SQLite adapter already uses DEFAULT 'pending'. This aligns PostgreSQL.
ALTER TABLE remote_agent_workflow_runs
ALTER COLUMN status SET DEFAULT 'pending';