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
133 lines
5.1 KiB
Markdown
133 lines
5.1 KiB
Markdown
# Proposal: Workspace-Based Tool Instances
|
|
|
|
## Status
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Phase | **Proposal** |
|
|
| Based on | [Explore](explore.md) |
|
|
| Next | Spec |
|
|
|
|
## Decisions from Explore
|
|
|
|
| Decision | Value |
|
|
|---|---|
|
|
| **Name** | "Workspace" (supersedes existing workspace.md) |
|
|
| **Scope** | Unlimited workspaces per repository |
|
|
| **Auto-create** | No — explicit creation only |
|
|
| **Default branch** | Main/master or user-selected at creation time |
|
|
| **Delete with running instances** | Allowed with confirmation; stops and deletes all associated tool instances |
|
|
| **Name uniqueness** | Unique per project+repo (derived from project and repo names) |
|
|
| **Deleted remote branch** | On sync/update, detect and ask for confirmation to delete local workspace/branch |
|
|
|
|
## Problem Statement
|
|
|
|
The current tool instance creation requires users to choose between "mount" (read-only) and "clone" (writable but ephemeral) modes. This is confusing and leads to either:
|
|
- **Mount mode**: Tools open files read-only, frustrating editing
|
|
- **Clone mode**: Each instance clones the repo, wasting disk space and losing work on deletion
|
|
|
|
## Proposed Solution
|
|
|
|
Introduce **Workspaces** as first-class entities: persistent, writable local clones of a repository that exist independently of tool instances. Users create workspaces explicitly, then start tool instances *on* a workspace.
|
|
|
|
### Entity Relationship
|
|
|
|
```
|
|
Project
|
|
└── GitRepository (canonical source)
|
|
└── Workspace (writable clone, unlimited per repo)
|
|
└── ToolInstance (mounts workspace path)
|
|
```
|
|
|
|
### Key Behaviors
|
|
|
|
1. **Workspace Creation**: User selects a repository → picks a branch → names the workspace → clone is created on disk
|
|
2. **Tool Instance Creation**: User selects a workspace → picks a tool type → instance starts with workspace mounted
|
|
3. **Multiple Tools per Workspace**: Several tool instances can share the same workspace (e.g., terminal + code-server)
|
|
4. **Persistence**: Workspaces survive tool instance deletion
|
|
5. **No Auto-Create**: Users must explicitly create workspaces; no magic default workspace
|
|
|
|
### UI Changes
|
|
|
|
- **New sidebar entry**: "Workspaces" (between "Projects" and "Settings")
|
|
- **Workspaces page**: List of all workspaces with repo/branch/status info
|
|
- **Create workspace flow**: Repo picker → branch picker → name input
|
|
- **Start tool from workspace**: Tool picker modal from workspace card
|
|
- **Simplified tool creation**: Remove "clone mode" / "mount mode" toggle; always use workspace
|
|
|
|
### Database Changes
|
|
|
|
New table: `workspaces`
|
|
- `id` (UUID, PK)
|
|
- `name` (string, user-defined)
|
|
- `repo_id` (UUID, FK → git_repositories)
|
|
- `user_id` (UUID, FK → users)
|
|
- `branch` (string)
|
|
- `path` (string, absolute disk path)
|
|
- `status` (enum: ready, syncing, error)
|
|
- `created_at`, `updated_at`
|
|
|
|
Updated: `tool_instances`
|
|
- Add `workspace_id` (UUID, FK → workspaces, nullable for migration)
|
|
- Remove `clone_mode` (deprecated)
|
|
- Remove `branch` (moved to workspace)
|
|
|
|
### File System Layout
|
|
|
|
```
|
|
/data/working-copies/
|
|
└── {repo-id}/
|
|
└── {workspace-name}/
|
|
└── .git/
|
|
└── [repo files]
|
|
```
|
|
|
|
### Migration Strategy
|
|
|
|
Existing `clone_mode` instances:
|
|
- Extract cloned repo from instance directory
|
|
- Move to `/data/working-copies/{repo-id}/{instance-name}/`
|
|
- Create Workspace record
|
|
- Update instance to reference workspace
|
|
- Remove `clone_mode` flag
|
|
|
|
Existing `mount_mode` instances:
|
|
- On next start, create a workspace from the canonical repo
|
|
- Switch instance to use workspace
|
|
- Remove `clone_mode` flag
|
|
|
|
### Out of Scope
|
|
|
|
- Auto-sync with canonical repo
|
|
- Git push/pull/branch UI
|
|
- Workspace sharing between users
|
|
- Pre-created default workspaces
|
|
- Read-only workspace mode
|
|
|
|
## Risks
|
|
|
|
| Risk | Mitigation |
|
|
|---|---|
|
|
| Existing users with many clone_mode instances | One-time migration on instance restart |
|
|
| Disk space from many workspaces | User-managed; can delete workspaces |
|
|
| Workspace deleted while instances are running | Allowed with confirmation; cascade-delete tool instances |
|
|
| Name collisions for workspace names | Unique per project+repo; derived from project and repo names |
|
|
|
|
## Acceptance Criteria
|
|
|
|
- [ ] User can create a workspace from any repository
|
|
- [ ] User can create unlimited workspaces per repository
|
|
- [ ] Tool instances mount the workspace path, not the canonical repo path
|
|
- [ ] Multiple tool instances can share one workspace
|
|
- [ ] Workspaces persist after tool instance deletion
|
|
- [ ] Existing clone_mode instances migrate to workspace on restart
|
|
- [ ] UI no longer shows "mount vs clone" toggle
|
|
- [ ] New sidebar navigation "Workspaces" exists
|
|
|
|
## Open Questions for Spec
|
|
|
|
1. ~~Should workspace deletion cascade-delete associated tool instances, or block?~~ **Answered**: Allowed with confirmation; cascade-delete tool instances
|
|
2. ~~Should workspace names be unique per-repo or globally unique?~~ **Answered**: Unique per project+repo; derived from project and repo names
|
|
3. ~~How do we handle the case where a workspace's branch is deleted from the remote?~~ **Answered**: On sync/update, detect and ask for confirmation to delete local workspace/branch
|
|
4. Should we validate the repo path exists before creating a workspace?
|