From f8475649da1cd7a6d49f8f30ee2fad374c2f4fcc Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Thu, 12 Mar 2026 23:54:11 -0500 Subject: [PATCH] chore: cleanup migrate from global code (#17292) --- packages/opencode/src/project/project.ts | 33 +++++-------------- .../test/project/migrate-global.test.ts | 8 ++--- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts index 1e14e94d7..d6f7d5a7e 100644 --- a/packages/opencode/src/project/project.ts +++ b/packages/opencode/src/project/project.ts @@ -1,12 +1,11 @@ import z from "zod" import { Filesystem } from "../util/filesystem" import path from "path" -import { Database, eq } from "../storage/db" +import { and, Database, eq } from "../storage/db" import { ProjectTable } from "./project.sql" import { SessionTable } from "../session/session.sql" import { Log } from "../util/log" import { Flag } from "@/flag/flag" -import { work } from "../util/queue" import { fn } from "@opencode-ai/util/fn" import { BusEvent } from "@/bus/bus-event" import { iife } from "@/util/iife" @@ -276,7 +275,13 @@ export namespace Project { // Runs on every startup because sessions created before git init // accumulate under "global" and need migrating whenever they appear. if (data.id !== ProjectID.global) { - await migrateFromGlobal(data.id, data.worktree) + Database.use((db) => + db + .update(SessionTable) + .set({ project_id: data.id }) + .where(and(eq(SessionTable.project_id, ProjectID.global), eq(SessionTable.directory, data.worktree))) + .run(), + ) } GlobalBus.emit("event", { payload: { @@ -311,28 +316,6 @@ export namespace Project { return } - async function migrateFromGlobal(id: ProjectID, worktree: string) { - const row = Database.use((db) => db.select().from(ProjectTable).where(eq(ProjectTable.id, ProjectID.global)).get()) - if (!row) return - - const sessions = Database.use((db) => - db.select().from(SessionTable).where(eq(SessionTable.project_id, ProjectID.global)).all(), - ) - if (sessions.length === 0) return - - log.info("migrating sessions from global", { newProjectID: id, worktree, count: sessions.length }) - - await work(10, sessions, async (row) => { - // Skip sessions that belong to a different directory - if (row.directory && row.directory !== worktree) return - - log.info("migrating session", { sessionID: row.id, from: ProjectID.global, to: id }) - Database.use((db) => db.update(SessionTable).set({ project_id: id }).where(eq(SessionTable.id, row.id)).run()) - }).catch((error) => { - log.error("failed to migrate sessions from global to project", { error, projectId: id }) - }) - } - export function setInitialized(id: ProjectID) { Database.use((db) => db diff --git a/packages/opencode/test/project/migrate-global.test.ts b/packages/opencode/test/project/migrate-global.test.ts index 77e0a1d77..b66653f70 100644 --- a/packages/opencode/test/project/migrate-global.test.ts +++ b/packages/opencode/test/project/migrate-global.test.ts @@ -100,14 +100,15 @@ describe("migrateFromGlobal", () => { expect(row!.project_id).toBe(project.id) }) - test("migrates sessions with empty directory", async () => { + test("does not claim sessions with empty directory", async () => { await using tmp = await tmpdir({ git: true }) const { project } = await Project.fromDirectory(tmp.path) expect(project.id).not.toBe(ProjectID.global) ensureGlobal() - // Legacy sessions may lack a directory value + // Legacy sessions may lack a directory value. + // Without a matching origin directory, they should remain global. const id = uid() seed({ id, dir: "", project: ProjectID.global }) @@ -115,8 +116,7 @@ describe("migrateFromGlobal", () => { const row = Database.use((db) => db.select().from(SessionTable).where(eq(SessionTable.id, id)).get()) expect(row).toBeDefined() - // Empty directory means "no known origin" — should be claimed - expect(row!.project_id).toBe(project.id) + expect(row!.project_id).toBe(ProjectID.global) }) test("does not steal sessions from unrelated directories", async () => {