- Add mappings array support to git_mount entries - Clone repository once per git_mount entry, mount multiple subdirectories - Normalize legacy source_path+target_path to mappings on read - Update _merge_git_mounts to dedup by (remote_url, branch) and concatenate mappings - Add _normalize_git_mount, _clone_git_repo, _resolve_git_mount_mappings helpers - Update GitMountItem Pydantic model with GitMountMapping and model_validator - Update frontend GitMountEditor component with mappings UI - Auto-convert legacy git mount entries to mappings format on load - Add 15 backend unit tests for normalization, resolution, and glob expansion - Update existing config profile resolver tests for new merge behavior Quality gates: pytest 167 passed, frontend typecheck clean Addresses: config-profile-multi-repo-mounts
3.8 KiB
Exploration: Config Profile Multi-Repo Mounts
Problem
Config Profiles support git_mounts — cloning repositories and mounting them into containers. However, each git_mount entry clones one source path from one repo. If a user wants to mount multiple directories from the same repository (e.g., a monorepo), they must add multiple git_mount entries, which results in cloning the same repository multiple times.
Current git_mount schema (one mapping per entry)
{
"remote_url": "https://github.com/user/monorepo.git",
"source_path": "packages/backend",
"target_path": "/app/backend",
"branch": "main"
}
To mount 3 directories from the same monorepo, the profile needs 3 entries, each triggering a separate clone of the full repository.
Pain Points
- Redundant clones: Cloning the same repo N times wastes time and disk space.
- Slow instance startup: Each clone adds 5-30 seconds depending on repo size.
- Inconsistent branch state: Each entry independently checks out the branch — they could drift if the branch moves between clones.
- Poor monorepo support: Monorepos are common; users expect to mount multiple packages.
Scenarios
Scenario A: Monorepo with multiple packages
User has a monorepo corp/monorepo with:
packages/api→ needs to be at/app/apipackages/web→ needs to be at/app/webpackages/shared→ needs to be at/app/shared
They want to mount all three into a single tool instance.
Scenario B: Docs + Code sidecar
User wants to mount both:
src/→/workspace/srcdocs/→/workspace/docs
from the same repo.
Scenario C: Backward compatibility
Existing profiles with single source_path/target_path should continue working without migration.
Design Directions
Direction A: mappings array on git_mount entry
Add a mappings array to each git_mount entry. The repo is cloned once, and each mapping creates a separate bind mount.
{
"remote_url": "https://github.com/user/monorepo.git",
"branch": "main",
"mappings": [
{"source_path": "packages/api", "target_path": "/app/api"},
{"source_path": "packages/web", "target_path": "/app/web"}
]
}
Pros:
- Clean, explicit grouping
- Single clone per
remote_url + branchcombo - Easy to understand
- Backward-compatible: legacy
source_path+target_pathcan be treated as a single-entrymappingsarray
Cons:
- Slightly more verbose JSON
- Frontend form needs a nested list UI
Direction B: Auto-dedup by remote_url + branch
Keep the flat list format, but internally group entries by remote_url + branch and clone once.
[
{"remote_url": "...", "source_path": "a", "target_path": "/a", "branch": "main"},
{"remote_url": "...", "source_path": "b", "target_path": "/b", "branch": "main"}
]
Pros:
- No schema change
- Transparent to users
Cons:
- Magic behavior (not obvious why clones are shared)
- Harder to reason about branch conflicts (what if same repo, different branches?)
- Frontend doesn't show the grouping
Direction C: Repo references + mount definitions split
Split into two concepts:
git_repos— list of repos to clone (with branch)git_mounts— reference a repo by name and specify source/target
Pros:
- Very explicit
- Supports advanced scenarios (SSH keys per repo)
Cons:
- Breaking schema change
- Overkill for the current use case
- Heavy migration burden
Recommendation
Direction A (mappings array) with backward-compatibility shim:
- Add optional
mappingsfield to git_mount entries - If
mappingsis absent, treatsource_path+target_pathas a single mapping - Clone once per
remote_url + branch, apply all mappings from the same entry - No migration needed for existing data
This balances clarity, functionality, and backward compatibility.