Files
headquarter/openspec/changes/archive/2026-05-19-repo-workspace/design.md
T
Fusion 875594d66d feat: add commit panel and file status indicators to repo workspace
- Add CommitPanel component for viewing changed files and committing
- Show file status indicators (M/A/D/?) in file tree
- Integrate git status with workspace for real-time updates
- Add CSS styles for commit panel and status badges

Part of git-control change implementation.
2026-05-19 15:00:25 +02:00

7.9 KiB

Repository Workspace - Design

Architecture

Project List
    ↓ (click project)
Repo Workspace (default view)
    ├─ Sidebar (200px)
    │   ├─ Repo Selector (dropdown)
    │   ├─ Branch Selector (dropdown)
    │   └─ File Tree (scrollable)
    │       ├─ 📁 src/
    │       │   └─ 📄 main.py
    │       ├─ 📁 tests/
    │       └─ 📄 README.md
    │
    └─ Main Content
        ├─ Breadcrumbs: src > main.py
        ├─ Toolbar: [Edit] [Raw] [History]
        └─ Content Area
            ├─ File View (syntax highlighted)
            └─ Edit View (textarea with save)

Page Layout

Route: /projects/:projectId

This replaces the current placeholder and becomes the default project view.

Layout Structure

┌─────────────────────────────────────────────────────────────┐
│  App Shell (Header + Nav)                                    │
├─────────────────────────────────────────────────────────────┤
│  Project Header                                              │
│  "My Project"                    [Repos] [History] [Settings]│
├─────────────────┬───────────────────────────────────────────┤
│                 │                                           │
│  Sidebar        │  Main Content                             │
│  ┌───────────┐  │  ┌─────────────────────────────────────┐  │
│  │ Repo ▼    │  │  │ Breadcrumbs: src > components       │  │
│  ├───────────┤  │  ├─────────────────────────────────────┤  │
│  │ Branch ▼  │  │  │ [Edit] [History] [Blame]            │  │
│  ├───────────┤  │  ├─────────────────────────────────────┤  │
│  │ 📁 src/   │  │  │                                     │  │
│  │ 📁 tests/ │  │  │ function hello() {                  │  │
│  │ 📄 README │  │  │   return "world";                   │  │
│  │ ...       │  │  │ }                                   │  │
│  │           │  │  │                                     │  │
│  └───────────┘  │  └─────────────────────────────────────┘  │
│                 │                                           │
└─────────────────┴───────────────────────────────────────────┘

Data Flow

1. Page Load

Load /projects/:id
→ Fetch project details
→ Fetch repositories list
→ Fetch default branch file tree (first repo)
→ Render workspace

2. Repository Switch

Select repo from dropdown
→ Fetch branches list
→ Fetch default branch file tree
→ Reset file viewer

3. Branch Switch

Select branch from dropdown
→ Fetch file tree for branch
→ If viewing a file: re-fetch file content for branch

4. File Navigation

Click file in tree
→ Fetch file content (with syntax highlighting hint)
→ Show in viewer
→ Update breadcrumbs

API Endpoints

GET /projects/{project_id}/repositories/{repo_id}/files

List files at a path (like ls for git).

Query Parameters:

  • branch: Branch name (default: repo's default branch)
  • path: Directory path (default: root)

Response:

{
  "path": "src",
  "branch": "main",
  "entries": [
    {
      "name": "components",
      "type": "directory",
      "path": "src/components"
    },
    {
      "name": "main.py",
      "type": "file",
      "path": "src/main.py",
      "size": 1234,
      "last_commit": {
        "hash": "abc123",
        "message": "Initial commit",
        "date": "2024-01-01T00:00:00Z"
      }
    }
  ]
}

GET /projects/{project_id}/repositories/{repo_id}/files/content

Get file content.

Query Parameters:

  • branch: Branch name
  • path: File path

Response:

{
  "path": "src/main.py",
  "branch": "main",
  "content": "function hello() {\n  return 'world';\n}",
  "size": 42,
  "encoding": "utf-8",
  "language": "python"
}

GET /projects/{project_id}/repositories/{repo_id}/branches

List branches.

Response:

{
  "branches": [
    {
      "name": "main",
      "is_default": true,
      "last_commit": "abc123"
    },
    {
      "name": "feature/new-thing",
      "is_default": false,
      "last_commit": "def456"
    }
  ],
  "default_branch": "main"
}

POST /projects/{project_id}/repositories/{repo_id}/files/content

Update file content (for quick edits).

Request Body:

{
  "path": "src/main.py",
  "branch": "main",
  "content": "function hello() {\n  return 'world!!!';\n}",
  "commit_message": "Quick edit: update greeting",
  "author_name": "User Name",
  "author_email": "user@example.com"
}

Components

RepoWorkspace (Page)

  • Orchestrates layout: sidebar + main content
  • Manages repo/branch/file state
  • Handles URL params (projectId, optional repoId)

FileTree (Sidebar Component)

  • Recursive tree view
  • Expandable folders
  • File icons based on extension
  • Active file highlight
  • Click to open file

RepoSelector (Component)

  • Dropdown of project repositories
  • Shows active repo name
  • Switch triggers repo change

BranchSelector (Component)

  • Dropdown of branches
  • Shows active branch
  • Switch triggers branch change

FileViewer (Component)

  • Syntax highlighted content
  • Line numbers
  • View/Edit toggle
  • Breadcrumb navigation

Breadcrumbs (Component)

  • Path segments as clickable links
  • Shows current file location

State Management

URL State

/projects/:projectId?repo=:repoId&branch=:branch&path=:path
  • repo: selected repository ID
  • branch: active branch name
  • path: current file/directory path

React State (per workspace)

interface WorkspaceState {
  projectId: string;
  selectedRepoId: string | null;
  selectedBranch: string;
  currentPath: string;
  selectedFile: string | null;
  fileContent: string | null;
  isEditing: boolean;
  fileTree: FileTreeEntry[];
  branches: Branch[];
  repositories: Repository[];
}

Implementation Order

  1. Backend file APIs - List files, get content, list branches
  2. Backend update API - Save file changes (commit)
  3. Project list clickable - Link to workspace
  4. Workspace page shell - Layout with sidebar + main
  5. File tree component - Recursive directory listing
  6. File viewer component - Content display
  7. Repo/branch selectors - Dropdowns with state
  8. Edit mode - Toggle + save
  9. URL state sync - Sync selections to URL
  10. Polish - Icons, syntax highlighting, error handling

Error Handling

  • Repo not found: Show error, allow selecting another
  • Branch not found: Show error, default to main
  • File not found: Show 404 in viewer
  • Permission denied: Show auth error
  • Binary files: Show "Binary file, cannot display" message
  • Large files: Show warning, offer download

Performance Considerations

  • Lazy load file tree: Only expand directories when clicked
  • Cache file content: Don't re-fetch if file hasn't changed
  • Debounce tree loading: When switching branches, debounce
  • Virtual scrolling: For large directories (100+ files)
  • Syntax highlighting: Use lightweight highlighter, async load