d567225bf7
- Add workspaces table migration (2026_06_01_add_workspaces) - Create Workspace model with repo_id, user_id, branch, path, status - Add workspace_id nullable FK to ToolInstance - Create GitService for clone/fetch/pull/branch_exists_remotely - Create WorkspaceManager for create/delete/sync lifecycle - Create workspace CRUD API with 409 handling for duplicates and instances - Wire workspace routes into FastAPI app - 17 tests passing (8 unit + 9 integration), 1 skipped Quality gates: ruff clean
104 lines
5.0 KiB
Markdown
104 lines
5.0 KiB
Markdown
# Explore: Working Copies
|
|
|
|
## Problem Statement
|
|
|
|
Currently, tool instances mount repositories directly. Each tool instance either:
|
|
- **Mount mode**: Bind-mounts the shared repo path (`/data/repos/<repo>`) read-only
|
|
- **Clone mode**: Clones the repo into the instance directory
|
|
|
|
This has several problems:
|
|
1. **Mount mode**: Read-only, so users can't edit files in the tool
|
|
2. **Clone mode**: Creates a full copy per instance, wasting disk space
|
|
3. **UI complexity**: The create-instance form must ask "mount or clone?" and handle branch selection
|
|
4. **No persistence**: Clone-mode repos live inside the instance directory and are lost on delete
|
|
5. **Race conditions**: Multiple instances mounting the same repo can conflict
|
|
|
|
## Proposed Solution: Working Copies
|
|
|
|
Introduce a **Workspace** as a first-class entity: a persistent, writable local clone of a repository that lives independently of any tool instance. Tool instances are then *started on* a working copy, which is mounted into the container.
|
|
|
|
### Naming Candidates
|
|
|
|
| Name | Pros | Cons |
|
|
|---|---|---|
|
|
| Workspace | Common in IDEs; implies a working area | Conflicts with existing docs/features/workspace.md |
|
|
| **Workspace** | Common in IDEs (VS Code, JetBrains); implies a working area | May conflict with existing "workspace" terminology in docs |
|
|
| **Checkout** | Git-native term; implies a working tree | Too specific to git; implies a single commit/branch |
|
|
| **Sandbox** | Implies isolation and experimentation | Suggests throwaway/ephemeral, not persistent |
|
|
| **Dev Copy** | Simple and descriptive | Informal; "copy" still implies duplication |
|
|
| **Project Clone** | Clear relationship to project+repo | Clunky; two words |
|
|
| **Branch** | Git-native; each working copy is effectively a branch workspace | Too git-specific; may confuse with git branches |
|
|
|
|
**Decision: "Workspace"** — chosen by user despite existing docs/features/workspace.md. The existing workspace.md will be superseded/renamed to avoid confusion. — it's the most precise term. In SVN/Git parlance, a "working copy" is exactly what we want: a local, writable copy of a repository that you work on. The term is established enough that developers understand it, but not so overloaded in our domain that it conflicts.
|
|
|
|
### Entity Model
|
|
|
|
```
|
|
Project
|
|
└── GitRepository (the canonical repo, read-only source)
|
|
└── WorkingCopy (writable local clone, 1+ per repo)
|
|
└── ToolInstance (mounts the working copy)
|
|
```
|
|
|
|
A Workspace:
|
|
- Has a `name` (auto-generated or user-defined)
|
|
- Has a `path` on disk (under `/data/working-copies/<repo-id>/<copy-name>`)
|
|
- Has a `branch` (the branch it's currently on)
|
|
- Has a `status` (ready, syncing, error)
|
|
- Belongs to a `GitRepository`
|
|
- Belongs to a `User`
|
|
- Has many `ToolInstance`s
|
|
|
|
### User Flow
|
|
|
|
1. User navigates to **Working Copies** in the sidebar
|
|
2. Sees list of working copies (or creates one from a repo)
|
|
3. Clicks "New Workspace" → selects repo + branch → named copy created
|
|
4. From a working copy, clicks "Start Tool" → selects tool type → instance starts with working copy mounted
|
|
5. Multiple tool instances can share the same working copy (e.g., terminal + code-server side by side)
|
|
|
|
### Benefits
|
|
|
|
1. **Writable by default**: Working copies are clones, so tools can edit files
|
|
2. **Shared across instances**: Multiple tools can mount the same working copy
|
|
3. **Persistent**: Survives instance deletion
|
|
4. **Simplified UI**: No more "mount vs clone" decision; tool creation is just "pick a working copy"
|
|
5. **Git operations**: Working copies can support git push/pull/branch from the UI
|
|
6. **Disk efficient**: One clone per working copy, not one per instance
|
|
|
|
### Open Questions
|
|
|
|
1. Should working copies auto-sync with the canonical repo?
|
|
2. Should we support multiple working copies per repo (e.g., one per branch)?
|
|
3. How do we handle merge conflicts if the canonical repo changes?
|
|
4. Should working copies be scoped to a user or to a project?
|
|
5. What happens to tool instances when a working copy is deleted?
|
|
6. Should we pre-create a default working copy when a repo is added?
|
|
|
|
### Migration Path
|
|
|
|
Existing tool instances that use clone_mode can be migrated:
|
|
- On first access, extract the cloned repo from the instance directory
|
|
- Move it to `/data/working-copies/...`
|
|
- Create a WorkingCopy record pointing to it
|
|
- Update the instance to mount the working copy path
|
|
|
|
Mount-mode instances can be converted on restart:
|
|
- Create a working copy from the canonical repo
|
|
- Switch the instance to mount the working copy instead
|
|
|
|
### Scope for This Change
|
|
|
|
This change focuses on:
|
|
- [ ] Creating the WorkingCopy entity and database table
|
|
- [ ] Adding a Working Copies section to the UI (sidebar nav + list view)
|
|
- [ ] Updating tool instance creation to select a working copy instead of repo+clone_mode
|
|
- [ ] Updating compose generation to mount the working copy path
|
|
- [ ] Migrating existing clone_mode instances to use working copies
|
|
|
|
Out of scope (future changes):
|
|
- [ ] Auto-sync with canonical repo
|
|
- [ ] Git operations UI (push/pull/branch)
|
|
- [ ] Working copy sharing between users
|
|
- [ ] Pre-create default working copies
|