summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/project/project.ts31
-rw-r--r--packages/opencode/src/util/queue.ts13
2 files changed, 44 insertions, 0 deletions
diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts
index 0bf50e16c..b3b724005 100644
--- a/packages/opencode/src/project/project.ts
+++ b/packages/opencode/src/project/project.ts
@@ -5,6 +5,8 @@ import { $ } from "bun"
import { Storage } from "../storage/storage"
import { Log } from "../util/log"
import { Flag } from "@/flag/flag"
+import { Session } from "../session"
+import { work } from "../util/queue"
export namespace Project {
const log = Log.create({ service: "project" })
@@ -77,6 +79,10 @@ export namespace Project {
.text()
.then((x) => path.resolve(worktree, x.trim()))
const projectID = id || "global"
+ const existing = id ? await Storage.read<Info>(["project", id]).catch(() => undefined) : undefined
+ if (!existing) {
+ await migrateFromGlobal(projectID, worktree)
+ }
const project: Info = {
id: projectID,
worktree,
@@ -90,6 +96,31 @@ export namespace Project {
return project
}
+ async function migrateFromGlobal(newProjectID: string, worktree: string) {
+ const globalProject = await Storage.read<Info>(["project", "global"]).catch(() => undefined)
+ if (!globalProject) return
+
+ const globalSessions = await Storage.list(["session", "global"]).catch(() => [])
+ if (globalSessions.length === 0) return
+
+ log.info("migrating sessions from global", { newProjectID, worktree, count: globalSessions.length })
+ const worktreePrefix = worktree.endsWith(path.sep) ? worktree : worktree + path.sep
+
+ await work(10, globalSessions, async (key) => {
+ const sessionID = key[key.length - 1]
+ const session = await Storage.read<Session.Info>(key).catch(() => undefined)
+ if (!session) return
+ if (session.directory && session.directory !== worktree && !session.directory.startsWith(worktreePrefix)) return
+
+ session.projectID = newProjectID
+ log.info("migrating session", { sessionID, from: "global", to: newProjectID })
+ await Storage.write(["session", newProjectID, sessionID], session)
+ await Storage.remove(key)
+ }).catch((error) => {
+ log.error("failed to migrate sessions from global to project", { error, projectId: newProjectID })
+ })
+ }
+
export async function setInitialized(projectID: string) {
await Storage.update<Info>(["project", projectID], (draft) => {
draft.time.initialized = Date.now()
diff --git a/packages/opencode/src/util/queue.ts b/packages/opencode/src/util/queue.ts
index 259d785ce..a1af53fe8 100644
--- a/packages/opencode/src/util/queue.ts
+++ b/packages/opencode/src/util/queue.ts
@@ -17,3 +17,16 @@ export class AsyncQueue<T> implements AsyncIterable<T> {
while (true) yield await this.next()
}
}
+
+export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) {
+ const pending = [...items]
+ await Promise.all(
+ Array.from({ length: concurrency }, async () => {
+ while (true) {
+ const item = pending.pop()
+ if (item === undefined) return
+ await fn(item)
+ }
+ }),
+ )
+}