# Spec: Workspace-First UI Refresh

## Status

| Field | Value |
|---|---|
| Phase | **Spec** |
| Based on | [Proposal](proposal.md) |
| Next | Design |

## Overview

Replace the old "Repository Workspace" (direct repo file browser) with a **Workspace-First** model. The workspace detail page becomes the primary work surface. Projects page shows inline repos + workspaces. Old `repo-workspace.tsx` is deleted.

## Decisions

| # | Question | Answer |
|---|---|---|
| 1 | URL structure | `/workspaces/:id` (flat) |
| 2 | Sidebar nav order | Workspaces → Projects |
| 3 | New Workspace flow | Inline form on project page |
| 4 | Branch switching | Dropdown in workspace header |
| 5 | Empty tool state | "Start a tool" prompt card |
| 6 | Mobile tabs | Files / Git / Tools / Settings |
| 7 | Git toolbar | Collapsible top bar on Files tab |
| 8 | Git tab content | History, diff, full commit log |

## User Flows

### Flow 1: Open a Project

1. User clicks "Projects" in sidebar
2. Sees project cards with inline repositories
3. Each repo shows its workspaces as clickable cards
4. User clicks a workspace → navigates to `/workspaces/:id`

### Flow 2: Work in a Workspace

1. User is on `/workspaces/:id`
2. **Files tab** (default): File tree (left) + file viewer/editor (right). Git toolbar at top.
3. User edits a file, commits via git toolbar
4. **Git tab**: Full history, diff view, detailed commit log
5. **Tools tab**: See running instances, click "Start Tool" → inline modal
6. **Settings tab**: Sync workspace, rename, delete

### Flow 3: Create a Workspace

1. User on Projects page, expands a repo
2. Clicks "+ New Workspace" next to a repo
3. Inline form appears: name input, branch dropdown
4. Submits → workspace created, appears in list

### Flow 4: Start a Tool

1. User on workspace detail, Tools tab
2. If no instances: "Start a tool on this workspace" card
3. If instances: list of cards + "Start Another" button
4. Click → inline modal: tool type picker, config profile (optional)
5. Submit → instance created, appears in list with status

## Backend API

### New Endpoints (workspace-scoped)

All endpoints operate on the workspace clone path (`workspace.path`).

```
# Files
GET    /workspaces/{workspace_id}/files?path=&branch=
       → List directory entries
GET    /workspaces/{workspace_id}/files/content?path=&branch=
       → Get file content
POST   /workspaces/{workspace_id}/files/content
       Body: { path, content, message }
       → Commit file change

# Git
GET    /workspaces/{workspace_id}/git/status
       → { modified, added, deleted, untracked, branch }
GET    /workspaces/{workspace_id}/git/branches
       → { branches, default_branch, current_branch }
POST   /workspaces/{workspace_id}/git/commit
       Body: { message, files? }
       → Commit staged changes
POST   /workspaces/{workspace_id}/git/push
       → Push current branch
POST   /workspaces/{workspace_id}/git/pull
       → Pull current branch
POST   /workspaces/{workspace_id}/git/fetch
       → Fetch from origin
POST   /workspaces/{workspace_id}/git/checkout
       Body: { branch }
       → Switch branch
GET    /workspaces/{workspace_id}/git/history
       Query: ?path=&limit=50
       → Commit history for file or entire repo

# Tools (instances on this workspace)
GET    /workspaces/{workspace_id}/instances
       → List tool instances using this workspace
POST   /workspaces/{workspace_id}/instances
       Body: { tool_type_id, display_name?, config_profile_id? }
       → Create instance on this workspace
```

### Existing Endpoints (unchanged)

```
GET    /workspaces/
POST   /workspaces/ (body: { repo_id, name, branch })
DELETE /workspaces/{id}
POST   /workspaces/{id}/sync
PATCH  /workspaces/{id}
```

Note: `POST /workspaces/` now accepts `repo_id` directly instead of nested under `/projects/{pid}/repositories/{rid}/workspaces`.

### Modified Endpoints

```
GET /projects/
    → Now includes `repositories` array with `workspaces` sub-array
```

## Database Schema

No changes. Existing `workspaces` table is sufficient.

## Frontend Routes

```
/                     → Dashboard (unchanged)
/workspaces           → All workspaces list (refreshed)
/workspaces/:id       → Workspace detail (NEW, replaces repo-workspace)
/projects             → Projects list (refreshed)
/projects/:id         → Project detail with repos + workspaces (NEW)
/sessions             → Sessions list (unchanged)
/settings             → Settings (unchanged)
```

## UI Components

### WorkspaceDetailPage (`/workspaces/:id`)

```
┌──────────────────────────────────────────────────────────────┐
│ Breadcrumb: Projects > {project} > {repo} > {workspace}      │
│ [Branch ▼ main]  [Sync]  [Start Tool]  [Settings]           │
├──────────────────────────────────────────────────────────────┤
│ Tab bar: [Files] [Git] [Tools] [Settings]                   │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  {Active Tab Content}                                       │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

#### Files Tab (default)

```
┌──────────────────────────────────────────────────────────────┐
│ Git Toolbar (collapsible)                                    │
│ [Modified: 3] [Staged: 2]  [Commit ▼] [Push] [Pull] [Fetch] │
├──────────────┬───────────────────────────────────────────────┤
│              │                                               │
│  File Tree   │  File Viewer / Editor                         │
│  (workspace  │                                               │
│   path)      │  Breadcrumbs: src > utils > helpers.ts        │
│              │                                               │
│  📁 src/     │  [Edit] [History]                             │
│  📄 README   │                                               │
│              │  export function ...                          │
│              │                                               │
└──────────────┴───────────────────────────────────────────────┘
```

**Git Toolbar**: Collapsible bar above file content. Shows:
- Status counters: Modified, Added, Deleted, Untracked
- Commit button (with message input when expanded)
- Push, Pull, Fetch buttons
- Branch selector dropdown

#### Git Tab

```
┌──────────────────────────────────────────────────────────────┐
│ Branch: [main ▼]  [New Branch]  [Merge]  [Compare]          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  Commit History                                              │
│  ┌────────────────────────────────────────────────────┐     │
│  │ ● abc123 Fix auth middleware                        │     │
│  │ ● def456 Add user profile page                      │     │
│  │ ● 789abc Initial commit                             │     │
│  └────────────────────────────────────────────────────┘     │
│                                                              │
│  [Show Diff] [Checkout] [Revert]                           │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

#### Tools Tab

```
┌──────────────────────────────────────────────────────────────┐
│ Active Tool Instances                                        │
│                                                              │
│  ┌─────────────┐  ┌─────────────┐  [+ Start Tool]          │
│  │ Code Server │  │ Terminal    │                            │
│  │ ● Running   │  │ ● Stopped   │                            │
│  │ [Open] [Stop│  │ [Start] [×] │                            │
│  └─────────────┘  └─────────────┘                            │
│                                                              │
│  ─ or ─                                                      │
│                                                              │
│  ┌────────────────────────────────────────────────────┐     │
│  │  No tools running on this workspace                │     │
│  │  Start a tool to begin coding                      │     │
│  │            [Start Tool]                            │     │
│  └────────────────────────────────────────────────────┘     │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

#### Settings Tab

```
┌──────────────────────────────────────────────────────────────┐
│ Workspace Settings                                           │
│                                                              │
│  Name: [my-feature-branch        ]                          │
│  Branch: main (tracks origin/main)                          │
│  Path: /data/working-copies/{repo-id}/{name}                │
│  Created: 2024-01-15                                        │
│  Last Sync: 2024-01-20 14:32                                │
│                                                              │
│  [Rename] [Sync Now] [Delete Workspace]                     │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

### ProjectsPage (`/projects`)

```
┌──────────────────────────────────────────────────────────────┐
│ Projects                                    [+ New Project] │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌────────────────────────────────────────────────────┐     │
│  │ My Web App                                         │     │
│  │ A full-stack application                           │     │
│  ├────────────────────────────────────────────────────┤     │
│  │ Repositories:                                      │     │
│  │                                                    │     │
│  │ ▼ frontend (git@github.com:me/frontend.git)        │     │
│  │   ┌──────────┐ ┌─────────────┐ [+ New Workspace]  │     │
│  │   │ main     │ │ feature-ui  │                    │     │
│  │   │ ● 2 inst │ │ ● 0 inst    │                    │     │
│  │   └──────────┘ └─────────────┘                    │     │
│  │                                                    │     │
│  │ ▶ backend (git@github.com:me/backend.git)          │     │
│  │   ┌──────────┐ [+ New Workspace]                   │     │
│  │   │ main     │                                     │     │
│  │   │ ● 1 inst │                                     │     │
│  │   └──────────┘                                     │     │
│  │                                                    │     │
│  │ [Edit Project] [Delete]                            │     │
│  └────────────────────────────────────────────────────┘     │
│                                                              │
└──────────────────────────────────────────────────────────────┘
```

**Workspace Card**: Small card showing:
- Name
- Status badge (ready/syncing/error)
- Instance count (dot + number)
- Click navigates to `/workspaces/:id`

**New Workspace Button**: Inline form on click:
```
[Name: __________] [Branch: main ▼] [Create] [Cancel]
```

### Mobile Layout

Bottom tab bar (4 tabs, always visible):

```
┌────────────────────────────────────┐
│ {Tab Content - full screen}        │
│                                    │
│                                    │
│                                    │
├────────────────────────────────────┤
│ 📁 Files  🔀 Git  🛠 Tools  ⚙ Settings│
└────────────────────────────────────┘
```

**Files tab**: File tree full screen, tap file → viewer overlay
**Git tab**: Commit history list, tap commit → diff overlay
**Tools tab**: Instance cards stacked vertically
**Settings tab**: Same as desktop settings, scrollable

## State & Data Flow

### Workspace Detail Page

```
useWorkspace(workspaceId) → fetch /workspaces/{id}
useWorkspaceFiles(workspaceId, path?, branch?) → fetch /workspaces/{id}/files
useWorkspaceGitStatus(workspaceId) → fetch /workspaces/{id}/git/status
useWorkspaceInstances(workspaceId) → fetch /workspaces/{id}/instances
```

All hooks poll/refetch on:
- Tab switch
- User action (commit, push, etc.)
- 30s background refresh

### Projects Page

```
useProjects() → fetch /projects/
useProjectWorkspaces(projectId) → derived from project.repositories.workspaces
```

## Error Handling

| Scenario | UX |
|---|---|
| Workspace not found | 404 page with "Workspace not found" + link to workspaces |
| Git operation fails | Toast with git stderr, retry button |
| File read fails | "File not found" in viewer, check if on correct branch |
| No tool types available | "No tools configured" + link to Tool Workshop |
| Workspace path missing | "Workspace files not found — try syncing" |

## Accessibility

- Tab bar: `role="tablist"`, keyboard arrow navigation
- File tree: `role="tree"`, arrow key expansion
- Git toolbar: All buttons have `aria-label`
- Focus management: Modal traps focus, returns on close

## Performance

- File tree: Virtualized for repos > 1000 files
- Git history: Paginated (50 commits per page)
- Image files: Lazy loaded in viewer
- Polling: 30s for instances, 10s for git status when visible

## Acceptance Criteria

- [ ] `repo-workspace.tsx` and related components deleted
- [ ] `/projects/:id` route shows project detail, not file browser
- [ ] `/workspaces/:id` route shows workspace detail page
- [ ] File browser reads from workspace clone path
- [ ] File viewer/editor works on workspace files
- [ ] Git toolbar on Files tab supports commit/push/pull/fetch
- [ ] Git tab shows commit history with diff
- [ ] Tools tab lists instances + spawn modal
- [ ] Settings tab shows workspace info + rename/sync/delete
- [ ] Projects page shows inline repos + workspace cards
- [ ] Inline "New Workspace" form on project page
- [ ] Mobile: 4-tab bottom navigation
- [ ] All existing tests pass or updated
- [ ] ruff clean, TypeScript clean, eslint clean
