anomalyco / anomalyco/opencode
Project added as non-git folder cannot show Git diff after git init (stale identity; Web UI remove doesn't clean server state)
@nexxeln is already working on this.
Since Aug 21, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Note: This issue was opened earlier with an incorrect root-cause analysis and was mistakenly withdrawn. It has been reopened with the corrected root cause (verified on the live server). The body below replaces the previous (wrong) content.
Summary
A folder that is (first) added to / resolved by the Web UI before it is a git repository becomes registered with project id global and worktree /. Even after the folder becomes a real git repository (e.g., git init, or cloning a repo into it), the server keeps resolving it to the stale global// identity, so Git diff / VCS status is never shown. Restarting the background service clears the in-memory cache and the folder is then correctly resolved as a git project.
Environment
- opencode version: 0.0.0-beta-17728
- OS: Linux 7.0.0-29-generic (Ubuntu) x86_64
- Terminal: TERM_PROGRAM=Orca TERM=xterm-256color COLORTERM=truecolor
- Shell: /bin/bash
- Install/channel: beta
- Server: background service http://0.0.0.0:49374
Reproduction
- Add a folder that is NOT a git repository as a project in the Web UI (or open a session in it so the server resolves the directory)
- Later make that folder a git repository (run
git init+ commit, or clone a real repo into it) - Re-open the project in the Web UI — Git diff / VCS state is not shown for it
- Remove the project from the sidebar and re-add it — still stale
- Restart the background service (
opencode2 service restart), then re-open — only then is it resolved as a git project
Expected Behavior
When a directory becomes a git repository, the project should be re-resolved (or the VCS state refreshed) so diffs appear without needing a server restart.
Actual Behavior
- The directory stays resolved as project id
globalwith worktree/until the server is restarted GET /api/vcs/status?location[directory]=<folder>returns the staleglobal//project with empty data even after the repo exists- Web UI "remove project" only hides the sidebar entry (client-side persistence) and does not dispose the server-side instance, so re-adding still uses the cached identity
Root Cause Analysis
-
Project identity is cached per directory in memory:
packages/opencode/src/project/instance-store.tskeepsconst cache = new Map<string, Entry>();get()returns the existing entry without re-resolving the project. The project (id / worktree / vcs) is resolved viaproject.fromDirectory()only on first creation of the instance for a directory. -
A non-git directory resolves to
global:packages/opencode/src/project/project.tssetsworktree = data.id === global && !data.vcs ? "/" : data.directory. While the directory has no.git, resolution returns{ id: "global", directory: "/" }. -
VCS/diff endpoints are instance/project-scoped:
/api/vcs,/api/vcs/status,/api/vcs/diffoperate on the current instance's project, whose worktree is/—so git state under the real folder is never inspected. -
Remove is client-side only:
packages/app/src/pages/home/home-projects-controller.tsxclose()callscloseHomeProject(...), which only mutates the persisted (localStorage) sidebar list. The server-side in-memory instance is not disposed.
Empirical confirmation
On the live server (beta-17728):
- Fresh non-git folder
/tmp/.../a:GET /api/vcs/status→project: { id: "global", directory: "/", canonical: "/" }, empty data - After
git init+ first commit in that folder: the same query still returnsglobal//with empty data - A folder that was already a git repo when first queried correctly resolves to a project id hashed from the git root commit / remote
- After
opencode2 service restart, the previously-stale folder resolves to a real git project id and VCS info is returned
Suggested fix direction
- On directory VCS change, re-resolve or invalidate the cached project identity (e.g., refresh the instance / re-run
fromDirectorywhen git is detected, or bust the per-directory cache when.gitappears) - Make the Web UI "remove project" (or add a dedicated action) dispose the server-side instance for that directory so re-adding re-resolves
- Give a freshly initialized git repo (no commits yet) a stable non-
globalidentity (e.g., hash of the worktree path) so it stops collapsing intoglobal
Workaround (for affected users)
Restart the background service (opencode2 service restart), then open the project / re-resolve the folder. The in-memory cache is cleared and the directory is resolved as a git project.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.