diff options
| author | Aiden Cline <[email protected]> | 2025-12-04 22:49:07 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-12-05 00:49:07 -0600 |
| commit | f950de95ba3744dad248f51aaaa893afb3a22f4e (patch) | |
| tree | dda9037f0163bd468516748fc5eeb46fae3f6764 | |
| parent | a4e5a72c36db16dd89f55de7ce97a7b383feee66 (diff) | |
| download | opencode-f950de95ba3744dad248f51aaaa893afb3a22f4e.tar.gz opencode-f950de95ba3744dad248f51aaaa893afb3a22f4e.zip | |
fix: ensure projects that go from having no commits to having commits have sessions migrated (#5105)
Co-authored-by: GitHub Action <[email protected]>
| -rw-r--r-- | .github/workflows/review.yml | 4 | ||||
| -rw-r--r-- | packages/opencode/src/project/project.ts | 31 | ||||
| -rw-r--r-- | packages/opencode/src/util/queue.ts | 13 |
3 files changed, 46 insertions, 2 deletions
diff --git a/.github/workflows/review.yml b/.github/workflows/review.yml index c190bb44a..08fcc388d 100644 --- a/.github/workflows/review.yml +++ b/.github/workflows/review.yml @@ -48,7 +48,7 @@ jobs: OPENCODE_PERMISSION: '{ "bash": { "gh*": "allow", "gh pr review*": "deny", "*": "deny" } }' run: | PR_BODY=$(jq -r .body pr_data.json) - opencode run -m anthropic/claude-sonnet-4-5 "A new pull request has been created: '${{ steps.pr-details.outputs.title }}' + opencode run -m anthropic/claude-opus-4-5 "A new pull request has been created: '${{ steps.pr-details.outputs.title }}' <pr-number> ${{ steps.pr-number.outputs.number }} @@ -75,4 +75,4 @@ jobs: -f 'body=[summary of issue]' -f 'commit_id=${{ steps.pr-details.outputs.sha }}' -f 'path=[path-to-file]' -F \"line=[line]\" -f 'side=RIGHT' \`\`\` - Only create comments for actual violations. If the code follows all guidelines, comment 'lgtm' AND NOTHING ELSE!!!!." + Only create comments for actual violations. If the code follows all guidelines, comment on the issue using gh cli: 'lgtm' AND NOTHING ELSE!!!!." 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) + } + }), + ) +} |
