fix(opencode): preserve orphan sessions on project id drift#30682
fix(opencode): preserve orphan sessions on project id drift#30682JochenYang wants to merge 2 commits into
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
|
The following comment was made by an LLM, it may be inaccurate: Related PRs FoundI found two PRs that are related to your current PR (#30682) on project ID and worktree handling:
These are related to the broader problem space of project ID stability and worktree management, but don't appear to be exact duplicates of the current orphan session recovery PR. |
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
45c3e4d to
0405723
Compare
Issue for this PR
Closes #30683
Type of change
What does this PR do?
For git projects that have no remote URL, the project id is derived from the root commit SHA1. When users rewrite history (
rebase --root,filter-repo,filter-branch) and the<git-common-dir>/opencodecache file is lost at the same time,Project.resolve()returns a new project id on the next startup, while the old project row and its sessions are stranded.Project.migrateProjectIdpreviously early-returned onoldID === undefined, andfromDirectory'sglobal->specificfallback only handledproject_id = "global", so non-global orphan projects were unreachable fromSession.listafter restart.The fix scans
project.worktreeto recover orphan projects whose worktree matches the current directory, and migratessession,workspace,permission, andproject_directoryrows before deleting the old project row. All four tables cascade-delete on project removal, so the FK-owned rows must be re-homed first to avoid silently dropping the user's saved permissions and directory metadata.projectV2.commitfailure path now logs a warning instead of being silently swallowed.The new
opts.directoryparameter onmigrateProjectIdis optional, so the explicit-cache-hit path is unchanged.fromDirectoryis the only caller and is updated to pass the directory.How did you verify your code works?
packages/opencode/test/project/project.test.ts:migrates orphan projects whose worktree matches the current directorydoes not migrate anything when no project matches the current directorymigrates every orphan project whose worktree matches the current directorycandidates with global id are excludedpermission and project_directory rows are preservedlogs warning and continues when writing the opencode cache failsend-to-end: recaptures orphan sessions when project id drifts after history rewriteit.live(real git, real DB, realfromDirectory): start a project, simulate a root commit rewrite viagit commit --amend, drop the cache, callfromDirectoryagain, and assert the orphan session is recaptured under the new project id. I ran the same test against the unpatched code first to confirm it fails as expected, then against the patched code to confirm it passes.tsgo --noEmit)%LOCALAPPDATA%\opencode\opencode.dbon Windows): 186 sessions stranded across 4 project_ids for one project (Maxcode), 13 across 2 project_ids for another (iScrcpy). Wrote a separate one-off SQL repair script to recover them, which is not part of this PR.Screenshots / recordings
Not applicable (no UI change).
Checklist
Out of scope
The investigation also surfaced other "session not visible" causes (path = "" filter edge case in
listByProject, 30-day hardcoded TUI window,applyUsagenot refreshingtime_updated). I am not addressing those here. They are separate bugs that the reporter has not observed and should be tracked as follow-up issues if desired.