0e6521e433
- 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
121 lines
3.8 KiB
Markdown
121 lines
3.8 KiB
Markdown
# 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)
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
1. **Redundant clones**: Cloning the same repo N times wastes time and disk space.
|
|
2. **Slow instance startup**: Each clone adds 5-30 seconds depending on repo size.
|
|
3. **Inconsistent branch state**: Each entry independently checks out the branch — they could drift if the branch moves between clones.
|
|
4. **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/api`
|
|
- `packages/web` → needs to be at `/app/web`
|
|
- `packages/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/src`
|
|
- `docs/` → `/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.
|
|
|
|
```json
|
|
{
|
|
"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 + branch` combo
|
|
- Easy to understand
|
|
- Backward-compatible: legacy `source_path` + `target_path` can be treated as a single-entry `mappings` array
|
|
|
|
**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.
|
|
|
|
```json
|
|
[
|
|
{"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:
|
|
1. `git_repos` — list of repos to clone (with branch)
|
|
2. `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 `mappings` field to git_mount entries
|
|
- If `mappings` is absent, treat `source_path` + `target_path` as 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.
|