From a503a2dec15eeb25fbe154b46f59c8030150dd4a Mon Sep 17 00:00:00 2001 From: Rasmus Widing Date: Wed, 8 Apr 2026 15:04:24 +0300 Subject: [PATCH] fix(sqlite): add allow_env_keys column to codebases schema + migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #983 added the allow_env_keys consent bit via PostgreSQL migrations (migrations/000_combined.sql and migrations/021_*.sql) but did not update packages/core/src/db/adapters/sqlite.ts, which has its own independent schema bootstrap path. Result: every SQLite database has been broken since #983 landed: - Fresh installs: createSchema() creates remote_agent_codebases without the column, and POST /api/codebases fails on every call with "table remote_agent_codebases has no column named allow_env_keys". - Existing installs upgraded from v0.2.x: CREATE TABLE IF NOT EXISTS is a no-op on the existing table and migrateColumns() never adds the column, same failure. Cole's deployed server at archon-youtube.smartcode.diy hit this live — every "add project" request returned 500 because the VPS runs docker-compose with the SQLite default (no separate postgres service). Two surgical changes to packages/core/src/db/adapters/sqlite.ts: 1. createSchema(): add `allow_env_keys INTEGER DEFAULT 0` to the remote_agent_codebases CREATE TABLE block so fresh databases get the column. SQLite has no true BOOLEAN — INTEGER with 0/1 matches the existing pattern used for `hidden` on conversations. 2. migrateColumns(): add a new idempotent try/catch block that PRAGMA-checks the codebases table for `allow_env_keys` and ALTERs it in if missing. Pattern matches the existing migration blocks for Conversations, Workflow runs, and Sessions columns. The JavaScript read path in db/codebases.ts and the clients already uses truthy checks (`if (!codebase?.allow_env_keys)`), which works for both SQLite integer (0/1) and JS boolean (false/true) storage. No other changes needed. Fixes the live incident blocking Cole's demo and unblocks v0.3.1. --- packages/core/src/db/adapters/sqlite.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/core/src/db/adapters/sqlite.ts b/packages/core/src/db/adapters/sqlite.ts index 485706d040..2864e4fc43 100644 --- a/packages/core/src/db/adapters/sqlite.ts +++ b/packages/core/src/db/adapters/sqlite.ts @@ -215,6 +215,22 @@ export class SqliteAdapter implements IDatabase { } catch (e: unknown) { getLog().warn({ err: e as Error }, 'db.sqlite_migration_session_columns_failed'); } + + // Codebases columns (added in #983 — env-leak gate consent bit) + try { + const cbCols = this.db.prepare("PRAGMA table_info('remote_agent_codebases')").all() as { + name: string; + }[]; + const cbColNames = new Set(cbCols.map(c => c.name)); + + if (!cbColNames.has('allow_env_keys')) { + this.db.run( + 'ALTER TABLE remote_agent_codebases ADD COLUMN allow_env_keys INTEGER DEFAULT 0' + ); + } + } catch (e: unknown) { + getLog().warn({ err: e as Error }, 'db.sqlite_migration_codebases_columns_failed'); + } } /** @@ -236,6 +252,7 @@ export class SqliteAdapter implements IDatabase { default_cwd TEXT NOT NULL, default_branch TEXT DEFAULT 'main', ai_assistant_type TEXT DEFAULT 'claude', + allow_env_keys INTEGER DEFAULT 0, commands TEXT DEFAULT '{}', created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now'))