Files
headquarter/openspec/changes/working-copies/explore.md
T
alex d567225bf7 feat: workspace backend foundation (PR-1)
- 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
2026-05-31 23:02:45 +02:00

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