Skip to content

Commit f950de9

Browse files
fix: ensure projects that go from having no commits to having commits have sessions migrated (anomalyco#5105)
Co-authored-by: GitHub Action <action@github.com>
1 parent a4e5a72 commit f950de9

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

.github/workflows/review.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
OPENCODE_PERMISSION: '{ "bash": { "gh*": "allow", "gh pr review*": "deny", "*": "deny" } }'
4949
run: |
5050
PR_BODY=$(jq -r .body pr_data.json)
51-
opencode run -m anthropic/claude-sonnet-4-5 "A new pull request has been created: '${{ steps.pr-details.outputs.title }}'
51+
opencode run -m anthropic/claude-opus-4-5 "A new pull request has been created: '${{ steps.pr-details.outputs.title }}'
5252
5353
<pr-number>
5454
${{ steps.pr-number.outputs.number }}
@@ -75,4 +75,4 @@ jobs:
7575
-f 'body=[summary of issue]' -f 'commit_id=${{ steps.pr-details.outputs.sha }}' -f 'path=[path-to-file]' -F \"line=[line]\" -f 'side=RIGHT'
7676
\`\`\`
7777
78-
Only create comments for actual violations. If the code follows all guidelines, comment 'lgtm' AND NOTHING ELSE!!!!."
78+
Only create comments for actual violations. If the code follows all guidelines, comment on the issue using gh cli: 'lgtm' AND NOTHING ELSE!!!!."

packages/opencode/src/project/project.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { $ } from "bun"
55
import { Storage } from "../storage/storage"
66
import { Log } from "../util/log"
77
import { Flag } from "@/flag/flag"
8+
import { Session } from "../session"
9+
import { work } from "../util/queue"
810

911
export namespace Project {
1012
const log = Log.create({ service: "project" })
@@ -77,6 +79,10 @@ export namespace Project {
7779
.text()
7880
.then((x) => path.resolve(worktree, x.trim()))
7981
const projectID = id || "global"
82+
const existing = id ? await Storage.read<Info>(["project", id]).catch(() => undefined) : undefined
83+
if (!existing) {
84+
await migrateFromGlobal(projectID, worktree)
85+
}
8086
const project: Info = {
8187
id: projectID,
8288
worktree,
@@ -90,6 +96,31 @@ export namespace Project {
9096
return project
9197
}
9298

99+
async function migrateFromGlobal(newProjectID: string, worktree: string) {
100+
const globalProject = await Storage.read<Info>(["project", "global"]).catch(() => undefined)
101+
if (!globalProject) return
102+
103+
const globalSessions = await Storage.list(["session", "global"]).catch(() => [])
104+
if (globalSessions.length === 0) return
105+
106+
log.info("migrating sessions from global", { newProjectID, worktree, count: globalSessions.length })
107+
const worktreePrefix = worktree.endsWith(path.sep) ? worktree : worktree + path.sep
108+
109+
await work(10, globalSessions, async (key) => {
110+
const sessionID = key[key.length - 1]
111+
const session = await Storage.read<Session.Info>(key).catch(() => undefined)
112+
if (!session) return
113+
if (session.directory && session.directory !== worktree && !session.directory.startsWith(worktreePrefix)) return
114+
115+
session.projectID = newProjectID
116+
log.info("migrating session", { sessionID, from: "global", to: newProjectID })
117+
await Storage.write(["session", newProjectID, sessionID], session)
118+
await Storage.remove(key)
119+
}).catch((error) => {
120+
log.error("failed to migrate sessions from global to project", { error, projectId: newProjectID })
121+
})
122+
}
123+
93124
export async function setInitialized(projectID: string) {
94125
await Storage.update<Info>(["project", projectID], (draft) => {
95126
draft.time.initialized = Date.now()

packages/opencode/src/util/queue.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,16 @@ export class AsyncQueue<T> implements AsyncIterable<T> {
1717
while (true) yield await this.next()
1818
}
1919
}
20+
21+
export async function work<T>(concurrency: number, items: T[], fn: (item: T) => Promise<void>) {
22+
const pending = [...items]
23+
await Promise.all(
24+
Array.from({ length: concurrency }, async () => {
25+
while (true) {
26+
const item = pending.pop()
27+
if (item === undefined) return
28+
await fn(item)
29+
}
30+
}),
31+
)
32+
}

0 commit comments

Comments
 (0)