Files
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

5.2 KiB

Tasks: Workspace-Based Tool Instances

Status

Field Value
Phase Tasks
Based on Design
Next Apply

PR Breakdown

PR-1: Backend Foundation

Scope: Database migration, models, services, API endpoints for workspaces Est. lines: ~800 backend, ~300 tests Files touched: 8 new, 2 modified

Tasks:

  1. Create Alembic migration for workspaces table + workspace_id on tool_instances
  2. Create Workspace model (apps/api/src/models/workspace.py)
  3. Add workspace_id to ToolInstance model (nullable FK)
  4. Create GitService (apps/api/src/services/git_service.py) — clone, fetch, pull, branch_exists_remotely
  5. Create WorkspaceManager (apps/api/src/services/workspace_manager.py) — create, delete, sync
  6. Create workspace API router (apps/api/src/api/workspaces.py) — CRUD + sync endpoints
  7. Add workspace routes to FastAPI app (apps/api/src/main.py)
  8. Write unit tests for GitService
  9. Write integration tests for workspace CRUD
  10. Write integration tests for delete-with-instances (409 behavior)
  11. Write integration tests for sync-with-deleted-branch (409 behavior)

PR-2: Backend Integration

Scope: Tool instance creation/start uses workspace instead of repo path Est. lines: ~400 backend, ~200 tests Files touched: 3 modified

Tasks:

  1. Update create_instance endpoint to accept workspace_id instead of clone_mode
  2. Update start_instance to mount workspace path (workspace.path) instead of repo path
  3. Update compose generation to use WORKSPACE_PATH variable
  4. Update tool_instances.py compose template rendering
  5. Write integration tests for instance creation with workspace
  6. Write integration tests for instance start with workspace mount
  7. Verify old mount_mode instances still work (backward compat)

PR-3: Frontend Core

Scope: Workspaces UI — list, create, card, actions Est. lines: ~1,200 frontend, ~400 tests Files touched: 10 new, 2 modified

Tasks:

  1. Create workspace types (apps/web/src/types/workspace.ts)
  2. Create workspace API client (apps/web/src/api/workspaces.ts)
  3. Create useWorkspaces hook (apps/web/src/hooks/use-workspaces.ts)
  4. Create useWorkspaceActions hook (apps/web/src/hooks/use-workspace-actions.ts)
  5. Create WorkspaceCard component (apps/web/src/components/workspace-card.tsx)
  6. Create WorkspaceCreateForm component (apps/web/src/components/workspace-create-form.tsx)
  7. Create StartToolModal component (apps/web/src/components/start-tool-modal.tsx)
  8. Create WorkspacesPage (apps/web/src/pages/workspaces.tsx)
  9. Update Sidebar to add Workspaces nav item
  10. Update router/routes to include /workspaces
  11. Write component tests for WorkspaceCard
  12. Write hook tests for useWorkspaceActions
  13. Write tests for create form validation

PR-4: Frontend Integration

Scope: Update existing flows to use workspaces, dashboard integration Est. lines: ~600 frontend, ~200 tests Files touched: 5 modified

Tasks:

  1. Update CreateSessionForm to use workspace picker instead of repo+clone_mode
  2. Update SessionsPage dashboard to show workspaces section
  3. Update SessionCard to show workspace name instead of clone mode
  4. Update useInstanceActions to pass workspace_id on create
  5. Remove clone_mode/mount_mode UI toggles
  6. Update types to remove deprecated clone_mode field
  7. Write integration tests for full create-workspace → start-tool flow
  8. Write tests for dashboard workspaces section

Acceptance Criteria (All PRs)

  • User can create a workspace from any repository
  • User can create unlimited workspaces per repository
  • Workspace names are unique per repo
  • Tool instances mount the workspace path
  • Multiple tool instances can share one workspace
  • Workspaces persist after tool instance deletion
  • Deleting a workspace with running instances shows confirmation, stops and deletes instances
  • Syncing a workspace with a deleted remote branch shows confirmation
  • UI no longer shows "mount vs clone" toggle
  • New sidebar navigation "Workspaces" exists
  • All existing tests still pass
  • ruff clean
  • TypeScript compilation clean

Implementation Order

PR-1 (Backend Foundation)
  → PR-2 (Backend Integration)
    → PR-3 (Frontend Core)
      → PR-4 (Frontend Integration)

Each PR depends on the previous. No parallel work.

Verification Steps per PR

PR-1

cd apps/api
alembic upgrade head
pytest tests/unit/test_git_service.py tests/integration/test_workspaces.py -v
python -m ruff check src/services/git_service.py src/services/workspace_manager.py src/api/workspaces.py

PR-2

cd apps/api
pytest tests/integration/test_tool_instances_with_workspace.py -v
python -m ruff check src/api/tool_instances.py

PR-3

cd apps/web
npm run test -- --run workspaces
npx tsc --noEmit
npx eslint src/pages/workspaces.tsx src/components/workspace-*.tsx

PR-4

cd apps/web
npm run test -- --run sessions create-session
npx tsc --noEmit
npx eslint src/pages/sessions.tsx src/components/create-session-form.tsx