feat(core): add directory projects - #45107
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
OpenCode currently assigns every directory without a Git or Mercurial repository to the same
globalproject. Unrelated directories therefore share project identity, and sessions opened beforegit initneed to remain attached to the repository once it appears.What Changes
Directories without repository markers become their own projects. The nearest Git or Mercurial marker still determines repository identity, including mixed nested repositories.
~/notes~/notes~/notes/drafts~/notes/drafts~/app/packages/ui~/app/.git~/app~/app/vendor/lib/src~/app/vendor/lib/.hg~/app/vendor/libDirectory project IDs remain opaque, deterministic hashes of normalized absolute paths. Existing Git and Mercurial identities, unborn repositories, and the compatibility
globalproject retain their existing behavior.flowchart TD A[Resolve working directory] --> B{Nearest Git or Mercurial marker?} B -->|Git| C[Use Git repository project] B -->|Mercurial| D[Use Mercurial repository project] B -->|None| E[Use normalized directory project]Repository Adoption
When a directory project becomes a repository, the existing durable
worktree.resolvedevent explicitly records the directory project IDs the repository supersedes. Both the server projector and connected clients use that same fact to adopt existing local sessions immediately.sequenceDiagram participant Resolver as Project resolver participant Event as worktree.resolved participant Server as Session projector participant Client as Connected client Resolver->>Resolver: Find superseded directory projects outside the write transaction Resolver->>Event: Record repository ID and adopted project IDs Event->>Server: Reassign matching local sessions atomically Event->>Client: Update cached session ownership immediatelyIndependent nested repositories and sessions placed in explicit remote workspaces are not adopted. Connected clients use the prior project's canonical directory to handle aliases consistently, and refresh authoritative session state when that project is not cached. Session locations, history, timestamps, execution state, and pending inbox items remain unchanged. The new event field is optional, so previously persisted version-1 events remain valid.
Scope
This PR owns directory-project resolution, explicit local session adoption, live client coherence, and the corresponding generated event type. Queued-move reclassification, historical migration, stale-project visibility, and navigation changes remain separate follow-ups.
Verification