🤖 feat: add multi-project workspace support - #2759
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 212c278739
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed all 3 review comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e03a8da7d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed both round-2 comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc2bd02e71
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed the remaining comment: rename failure catch block now recreates the old container (with original symlinks) after rolling back per-project renames, ensuring the workspace cwd remains functional even when container recreation fails. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4ee3291978
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed both comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7a7835cc3d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed both comments:
|
a82cb1f to
18adf5b
Compare
|
@codex review Rebased on main and resolved conflicts. All previous Codex comments have been addressed and threads resolved. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 18adf5b857
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed both comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e03c7f3444
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cbf1cf41cd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed both comments:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ca6f4a93da
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed both P2 comments:
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 638d12bfaf
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Fixed both P1 comments:
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d731b5012a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
d731b50 to
3928517
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3928517835
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review Addressed both new findings:
|
Keep findWorkspace.projectPath aligned with the stored config key for multi-project workspaces so mutation callers still work under _multi, and thread a separate attribution path to stream-end analytics ingestion. Add focused regressions for both the config semantics and analytics attribution behavior.
Mark queued tasks interrupted when trust is revoked before dequeue, including secondary projects in multi-project task metadata. Add focused TaskService coverage for primary and secondary trust revocations so queued tasks do not retry forever.
Aggregate git file completions per project for multi-project workspaces and add focused regression coverage.
Concatenate every matching Tool section within a single instruction source so flattened multi-project AGENTS content keeps each repo's tool rules. Add focused markdown and system-message regressions covering ordered multi-match extraction and context-over-global precedence.
dad775e to
22cd89e
Compare
|
@codex review Rebased |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1dc605d7fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Normalize repo-root project path matching in WorkspaceService and return '.' for project-root repo-relative selections, with focused regression coverage.
|
@codex review Addressed the remaining repo-root path handling issues:
Local validation:
|
|
@codex review Resolved the lingering repo-root path thread after landing the normalization fix. Re-running Codex/CI readiness checks now. |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
…oder#4486) ## Summary Deletes dead helpers under `src/node` and `src/common` whose only callers were their own tests (WS2 sweep of production exports with zero production callers). ## Removed | Symbol | Evidence | | --- | --- | | `snapshotTranscriptAnchor` (+ module, 2 tests) | Only production caller removed in coder#3816 | | `createLatestValueQueue` (+ 3 tests) | Last caller replaced by Effect streams in coder#4039 | | `withQueueHeartbeat` (+ module, test file) | Same (coder#4039). `SUBSCRIPTION_HEARTBEAT_INTERVAL_MS` moved to `src/constants/orpcSubscriptions.ts` (used by `streamBridge.ts`) | | `createWorktree`, `pruneWorktrees` (`git.ts`, + 2 tests, unused types/imports) | Worktree creation moved to `WorktreeManager` (coder#457); `pruneWorktrees` had no references at all. The `listLocalBranches` test stays | | `discoverGitRoots` (+ module, test file) | Added in coder#2759, never wired in | | `listSessionWorkspaceIdsWithHistory`, `listArchivedSubagentWorkspaceIds` | Analytics uses `discoverAllWorkspaces` since coder#2665. The unreadable-transcript-dir and missing-`chat.jsonl` cases were moved onto `discoverAllWorkspaces`, which has the same branches and no other test for them | | `hasUserPreferenceEntry` | No production caller; tests now read keys via `entriesFromUserPreferences`, as `UserPreferencesContext` does | | `AgentPluginInstallsSchema` (+ barrel re-export) | No references anywhere (`plugins.json` is parsed as a record in the registry) | ## Validation - Mutation check: making `discoverAllWorkspaces` rethrow unreadable transcript-dir errors fails the moved test. - Every name `git grep`-checked across the repo (src, tests, scripts, vscode, docs). - `make static-check` on the stack top; affected suites pass. Stack: 4/5. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$4.45`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=4.45 -->
Summary
Adds VS Code-style multi-root workspace support to Mux. A user can create a single workspace spanning multiple projects (e.g.,
mux+mux-md). The agent gets onecwd— a container directory with symlinks to per-project worktrees — and works across all projects in a single session. Each project retains its own git identity.Background
Multi-project workflows are common — an agent fixing a library and its consumer simultaneously, updating docs alongside source code, etc. Today each project gets its own workspace, forcing users to coordinate across separate sessions. This PR enables a single session to span multiple repos.
Implementation
Architecture
~/.mux/src/_workspaces/<name>/contains symlinks (mux/→ worktree,mux-md/→ worktree)RuntimeConfig(mixed runtimes deferred)New/Changed Components (12 commits)
ProjectRefSchema,projectsfield on metadata,isMultiProject()/getProjects()helperssrc/common/orpc/schemas/workspace.ts,src/common/utils/multiProject.tssrc/node/multiProject/containerManager.tssrc/node/runtime/multiProjectRuntime.tscreateMultiProject(), extendedremove()/rename(), IPC routesrc/node/services/workspaceService.tsdiscoverGitRoots()for multi-root workspacessrc/node/multiProject/gitRootDiscovery.tsFileChangeTrackercanonicalizes paths viarealpath()src/node/services/utils/fileChangeTracker.tssrc/node/services/utils/forkOrchestrator.tssrc/node/services/tools/bash.tssrc/browser/components/ProjectSidebar/,MultiProjectWorkspaceCreateModal/MULTI_PROJECT_CONFIG_KEYconstantsrc/common/constants/multiProject.tsConfig Storage
Multi-project workspaces are stored under a synthetic
"_multi"key inconfig.json:{ "projects": { "/path/to/mux": { "workspaces": [...] }, "_multi": { "workspaces": [{ "id": "abc1234567", "name": "my-feature", "projects": [ { "projectPath": "/path/to/mux", "projectName": "mux" }, { "projectPath": "/path/to/mux-md", "projectName": "mux-md" } ] }] } } }Validation
make static-checkpasses clean (typecheck + lint + formatting + docs links)Risks
"_multi"key: new convention that config loading/filtering must handle. Existing workspaces unaffected (theprojectsfield is optional).discoverGitRoots()utility but integration intogitPatchArtifactServiceandgitStatusis deferred.📋 Implementation Plan
Phase 1 — Data Model & Helpers
ProjectRefSchemawithprojectPath+projectNameprojectsarray onWorkspaceMetadataSchemaandWorkspaceConfigSchemaisMultiProject()andgetProjects()utility functionsPhase 2 — Container Directory Management
ContainerManagerclass:createContainer(),removeContainer(),getContainerPath(){srcBaseDir}/_workspaces/{workspaceName}/Phase 3 — MultiProjectRuntime Wrapper
RuntimeinterfacePhase 4 — Workspace Lifecycle
createMultiProject()on WorkspaceService with rollback on partial failureremove()to clean up all per-project workspaces + containerrename()to rename all per-project workspaces + recreate containerworkspace.createMultiProjectPhase 5 — Git Multi-Root Awareness
discoverGitRoots()— scans workspace for.gitdirs in childrenPhase 6 — FileChangeTracker Symlink Fix
realpath()canonicalization for file path storagePhase 7 — Sub-Agent Support
orchestrateForkfor multi-project parentsprojectsarrayPhase 8 — Agent Context
buildBashToolDescription()lists project directories for multi-project workspacesPhase 9 — UI
Phase 10 — Refactor
MULTI_PROJECT_CONFIG_KEYconstantGenerated with
mux• Model:anthropic:claude-opus-4-6• Thinking:xhigh• Cost:$32.73