diff --git a/packages/core/src/database/migration/20260410174513_workspace-name.ts b/packages/core/src/database/migration/20260410174513_workspace-name.ts index 18483e1cf089..8a8557ec7aa1 100644 --- a/packages/core/src/database/migration/20260410174513_workspace-name.ts +++ b/packages/core/src/database/migration/20260410174513_workspace-name.ts @@ -5,6 +5,9 @@ export default { id: "20260410174513_workspace-name", up(tx) { return Effect.gen(function* () { + const columns = yield* tx.all<{ name: string }>(`PRAGMA table_info(\`workspace\`)`) + const name = columns.some((column) => column.name === "name") ? "`name`" : "''" + yield* tx.run(`PRAGMA foreign_keys=OFF;`) yield* tx.run(` CREATE TABLE \`__new_workspace\` ( @@ -19,7 +22,7 @@ export default { ); `) yield* tx.run( - `INSERT INTO \`__new_workspace\`(\`id\`, \`type\`, \`branch\`, \`name\`, \`directory\`, \`extra\`, \`project_id\`) SELECT \`id\`, \`type\`, \`branch\`, \`name\`, \`directory\`, \`extra\`, \`project_id\` FROM \`workspace\`;`, + `INSERT INTO \`__new_workspace\`(\`id\`, \`type\`, \`branch\`, \`name\`, \`directory\`, \`extra\`, \`project_id\`) SELECT \`id\`, \`type\`, \`branch\`, ${name}, \`directory\`, \`extra\`, \`project_id\` FROM \`workspace\`;`, ) yield* tx.run(`DROP TABLE \`workspace\`;`) yield* tx.run(`ALTER TABLE \`__new_workspace\` RENAME TO \`workspace\`;`) diff --git a/packages/core/test/database-migration.test.ts b/packages/core/test/database-migration.test.ts index b381cc7418a3..2e943872fac1 100644 --- a/packages/core/test/database-migration.test.ts +++ b/packages/core/test/database-migration.test.ts @@ -8,6 +8,7 @@ import { Effect, Layer } from "effect" import { eq, inArray, sql } from "drizzle-orm" import { DatabaseMigration } from "@opencode-ai/core/database/migration" import { migrations } from "@opencode-ai/core/database/migration.gen" +import workspaceNameMigration from "@opencode-ai/core/database/migration/20260410174513_workspace-name" import sessionUsageMigration from "@opencode-ai/core/database/migration/20260510033149_session_usage" import normalizeStoragePathsMigration from "@opencode-ai/core/database/migration/20260601010001_normalize_storage_paths" import sessionMessageProjectionOrderMigration from "@opencode-ai/core/database/migration/20260603040000_session_message_projection_order" @@ -319,6 +320,37 @@ describe("DatabaseMigration", () => { ) }) + test("defaults missing workspace names during legacy workspace rebuild", async () => { + await run( + Effect.gen(function* () { + const db = yield* makeDb + yield* db.run(sql` + CREATE TABLE workspace ( + id text PRIMARY KEY, + type text NOT NULL, + branch text, + directory text, + extra text, + project_id text NOT NULL + ) + `) + yield* db.run(sql` + INSERT INTO workspace (id, type, branch, directory, extra, project_id) + VALUES ('wrk_legacy', 'remote', 'main', '/repo', '{}', 'proj_legacy') + `) + + yield* DatabaseMigration.applyOnly(db, [workspaceNameMigration]) + + expect(yield* db.get(sql`SELECT id, name, directory, extra FROM workspace`)).toEqual({ + id: "wrk_legacy", + name: "", + directory: "/repo", + extra: "{}", + }) + }), + ) + }) + test("resets incompatible projected Session messages before adding sequence order", async () => { await run( Effect.gen(function* () {