feat(projects): support multiple repositories - #6316
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Effect service conventions: findings on the two new workspace services and the new filesystem RPC errors. Details inline.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Two Effect service convention issues in the new server-side code. Everything flagged in the previous run (WorkspaceFile / WorkspaceGitScan service shape, make/layer naming, structured error attributes, catchTags) looks addressed.
Posted via Macroscope — Effect Service Conventions
Adds first-class support for multi-repo "workspaces" — a project that spans several independent git repos (a `.code-workspace` as the source of truth) without forcing them into a single monorepo. Checkpointing, turn/ thread diffs, VCS status, agent launches, @-mention search, file previews, worktrees, terminals, and the Source Control UI all fan out across every repo root, with isolated runs getting one worktree per repo. Squashed from 36 phased commits during rebase onto upstream pingdotgg/main (client connection architecture rewrite pingdotgg#2978 + server Services/Layers flattening). Original commits preserved in branch multi-repo-workspaces-backup. Squashed commits (oldest first): feat(project): multi-repo-root projects ("monorepo-like" without being a monorepo) chore(multi-repo-root): review fixes fix(multi-repo-root): repair 123-commit rebase drift fix(multi-repo-root): integrate scanGitRepos RPC with auth-scope feature fix(multi-repo-root): repair fork test failures chore: ignore .playwright-mcp tooling artifacts docs(multi-repo-root): design plan for multi-repo workspaces feat(multi-repo-root): .code-workspace as project source of truth (Phase 1b) feat(multi-repo-root): per-root checkpoint refs foundation (Phase 2a) feat(multi-repo-root): fan checkpoint capture out over all repo roots (Phase 2a) feat(multi-repo-root): aggregate turn/thread diffs across repo roots (Phase 2a) feat(multi-repo-root): fan checkpoint restore out over all repo roots (Phase 2a) feat(multi-repo-root): per-repo grouped turn-diff payload (Phase 2c) feat(multi-repo-root): render per-repo diff sections in DiffPanel (Phase 2c) feat(multi-repo-root): surface repoRoots on web Project model (Phase 2b) feat(multi-repo-root): grouped per-root VCS status hook (Phase 2b) feat(multi-repo-root): render per-repo git status in the chat header (Phase 2b) feat(multi-repo-root): don't flap thread branch across per-repo controls (Phase 2b) feat(multi-repo-root): launch agents with a per-root workspace manifest (Phase 3) feat(multi-repo-root): fan @-mention file search across every repo root (Phase 3) feat(multi-repo-root): resolve cross-root file previews in AssetAccess (Phase 3) feat(multi-repo-root): carry a per-root worktree map on threads (Phase 4) feat(multi-repo-root): fan worktrees out across every repo root (Phase 4) feat(multi-repo-root): resolve agent/diff/checkpoint to per-root worktrees (Phase 4) feat(multi-repo-root): remove every per-root worktree on thread delete (Phase 4) feat(multi-repo-root): hide bare *.git dirs from the file tree (Phase 5) feat(multi-repo-root): add filesystem.writeWorkspaceFile RPC round-tripping unknown keys (Phase 5) feat(multi-repo-root): add Manage folders dialog to round-trip the .code-workspace (Phase 5) feat(multi-repo-root): re-read .code-workspace on project load and reconcile roots (Phase 5) feat(multi-repo-root): browse files and resolve file links across all repo roots (pingdotgg#923) feat(multi-repo-root): consolidate per-repo git actions into one Source Control control feat(multi-repo-root): pick which repo to open a terminal in feat(diff): show all repos in multi-repo branch/working diff with repo filter fix(terminal): open per-repo terminal in that repo's worktree feat(diff): show working/branch diff for non-isolated multi-repo workspaces fix(diff): refresh diff panel on reopen to avoid stale cached patch Follow-up details (post-rebase work folded in): - Branch/working diff fans out per repo with a repo-filter dropdown (All repos / per repo), replacing the single-repo computation; the base-ref selector is hidden in multi-repo mode since one base ref isn't valid across repos. - Non-isolated `.code-workspace` projects (no per-repo worktrees, a container workspaceRoot that isn't a git repo) diff each project repoRoot directly instead of running `git diff` in the container and reporting "no changes". The WS handler passes allowedRepoRoots from the shell snapshot and ReviewService accepts them in its workspace-boundary check, since these repos can live anywhere on disk. - Per-repo terminals open in the targeted repo's worktree (resolved via the thread's worktree map), falling back to the plain repo root. - The diff panel refreshes on reopen (useRefreshOnReopen) so the stale-while-revalidate atoms don't serve a stale cached patch after the panel is unmounted and remounted.
The file preview is backed by a cached readFile query, so once a file is shown the preview kept rendering stale on-disk content after an agent turn rewrote it (there is no filesystem watcher to invalidate the cache). Refetch the open preview on the two signals observable from the renderer: agent turn completion (a new checkpoint lands or a revert trims the list) and window refocus (for edits made outside the app, e.g. a terminal). Adds a narrow useThreadCheckpoints subscription so the preview only re-renders on checkpoint changes, not on every streaming message.
"Open in" pointed every editor at the project's `workspaceRoot`, which for a `.code-workspace` project is only the anchor directory holding the file. VS Code opened it as a plain folder, so none of the repo roots appeared in the tree -- the multi-root workspace the project is defined by was never what got opened. Pass the `.code-workspace` file alongside the anchor directory and pick between them per editor. The choice is made server-side, in the launcher, because the target depends on which editor the user picks from the menu and that is not known when the picker renders. `supportsWorkspaceFile` on the editor registry marks the VS Code family; Zed and JetBrains would show the raw JSON and the file manager would hand it to the OS opener, so those keep getting the directory. Isolated runs keep getting their worktree. The fanned-out worktrees have no workspace file of their own, and the project's would open the original checkouts instead of the copies the thread is working in. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
New-worktree mode was unusable for any `.code-workspace` project. The base branch selector ran its ref queries against `workspaceRoot`, which for those projects is the anchor directory holding the workspace file and usually not a git repo, so every query reported `isRepo: false` and the selector came up empty. Sending then refused outright, by design, rather than silently falling back to local execution. Populating the selector alone would not have been enough. The server compared each `repoRoot` against the client's `projectCwd` to find the repo the chosen base ref belongs to; for a workspace-file project that comparison never matched, so the base ref was dropped for every root and each repo quietly branched off its own HEAD instead. `startFromOrigin` went further and ran `git fetch` in the anchor directory, which fails and aborts the whole send. `resolveAnchorRepoRoot` picks the repo root that stands in for the project in single-repo git flows: the anchor when the workspace file lists it, else the first root in file order. Single-repo projects resolve to exactly today's value. Both the selector and the worktree fan-out now go through it, so refs list, the chosen base lands on the anchor repo while cousins still branch off their own HEAD, and the origin fetch runs in a repo. The selector's existing auto-default picks the repo's `origin/HEAD` once refs load, so this works without the user opening the dropdown. Per-root base selection still needs a wider `prepareWorktree` contract and is left for follow-up. Also repairs a stale assertion in the bootstrap worktree test: it still expected the pre-fan-out `createWorktree` shape (`path: null`, `baseRefName`) and had been failing on this branch. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2055f38 to
2b2ab11
Compare
There was a problem hiding this comment.
Reviewed the changed Effect service code (new WorkspaceFile, WorkspaceGitScan, WorktreeFanout, ProjectionCheckpointRefs, plus touched AssetAccess, CheckpointDiffQuery, CheckpointReactor, ReviewService, RepositoryIdentityResolver, GitVcsDriver/GitWorkflowService, ws.ts). The previously flagged items are resolved: inline Context.Service interfaces, make/layer exports in the workspace modules, structured RPC errors in packages/contracts/src/filesystem.ts, environment acquisition in WorktreeFanout, and Effect.catchTags in AssetAccess.
Two remaining findings, both inline.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Effect service conventions: one finding — service-instance parameters in the new multi-repo helper modules bypass environment acquisition.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
Two new checkpointing helpers take live service instances as parameters instead of acquiring them from the Effect environment, so CheckpointStore / RuntimeReceiptBus never appear in their R channel. This mirrors the WorktreeFanout / ThreadWorktreeBootstrap pattern that was already converted to environment acquisition in this PR, so the same fix applies here.
Posted via Macroscope — Effect Service Conventions
Closes #1453
Adds multi-repository projects across agent context, search, diffs, checkpoints, isolated worktrees, and web/mobile project flows. Includes a guided project-name, source-folder, and primary-repository flow plus
.code-workspaceimport.Built with GPT-5.6 Sol via Codex harness.