# How to Integrate GitHub Repositories as Virtual Workspaces in Routa

> Learn how to integrate GitHub repositories as virtual workspaces in Routa. Easily clone and link your GitHub code for seamless access with agents and Kanban boards.

- Repository: [Fengda Huang/routa](https://github.com/phodal/routa)
- Tags: how-to-guide
- Published: 2026-05-26

---

**Routa treats each workspace as a container for Git repositories, allowing you to clone GitHub repos into `.routa/repos` and link them via the RepoPicker component so agents and Kanban boards can access the codebase.**

Routa is an AI-powered workspace platform that seamlessly integrates version control into its collaborative environment. By connecting GitHub repositories to workspaces, you enable file-aware agents, diff visualizations, and branch-aware task management directly within the phodal/routa ecosystem.

## Understanding the Workspace-Repository Architecture

Routa implements a two-layer architecture that abstracts Git operations into workspace-scoped resources. A **workspace** serves as the logical container, while the **repository** provides the underlying file tree and version history.

The system relies on a lightweight association model. When you link a repository, Routa stores a `RepoSelection` object containing the repository name, absolute path, and current branch in the workspace record. This path points to the local clone directory—by default `.routa/repos/owner--repo`—where all Git utilities operate.

- **Front-end layer**: The `RepoPicker` component ([`src/client/components/repo-picker.tsx`](https://github.com/phodal/routa/blob/main/src/client/components/repo-picker.tsx)) handles UI interactions, URL validation, and branch selection
- **Back-end layer**: REST endpoints under `/api/clone` manage cloning, progress streaming, and branch operations, delegating to utilities in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts)

This architecture ensures that whether Routa runs as a web service or Tauri desktop application, the same Git logic applies uniformly.

## Step-by-Step Integration Process

Integrating a GitHub repository requires cloning the source code and persisting the association in your workspace configuration.

1. **Open or create a workspace** from the Routa home page.

2. **Launch the RepoPicker** by clicking the repository selector in the workspace header or settings (`src/app/workspace/[workspaceId]/workspace-settings-tab.tsx`).

3. **Select the Clone tab** and paste a GitHub URL or `owner/repo` shorthand. The picker's `isGitHubInput` helper validates the format before enabling the clone action.

4. **Initiate cloning** via the UI. The front-end POSTs to `/api/clone` with the repository URL.

5. **Server-side processing**: The [`src/app/api/clone/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/route.ts) handler parses the URL using `parseGitHubUrl`, then clones the repository into `<clone-base>/owner--repo`. If the environment lacks `git` binaries, the system automatically falls back to `importGitHubZipFallback` (defined in [`src/core/github/github.ts`](https://github.com/phodal/routa/blob/main/src/core/github/github.ts)) to fetch the zipball.

6. **Monitor progress**: The UI subscribes to `/api/clone/progress` for Server-Sent Events (SSE) updates during the clone operation.

7. **Select the repository** from the Existing repositories list. This updates the workspace model with the `RepoSelection` data.

8. **Verify integration**: The workspace now displays branch selectors, file status badges, and enables file search and diff views powered by [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts).

## Programmatic Integration Examples

Beyond the UI, you can integrate repositories programmatically using React components or direct API calls.

### Using the RepoPicker React Component

Embed the repository selector directly in custom workspace views:

```tsx
import { RepoPicker, type RepoSelection } from "@/client/components/repo-picker";
import { useState } from "react";

function WorkspaceHeader() {
  const [selectedRepo, setSelectedRepo] = useState<RepoSelection | null>(null);

  return (
    <div className="flex items-center gap-2">
      <RepoPicker
        value={selectedRepo}
        onChange={setSelectedRepo}
        allowClone={true}
        pathDisplay="inline"
      />
      {/* Selected repo path available via selectedRepo.path */}
    </div>
  );
}

```

The `allowClone` prop enables the GitHub import tab, while `onChange` receives the full `RepoSelection` object including `name`, `path`, and `branch`.

### Manual API Integration

Clone repositories via HTTP requests for automation or external tooling:

```bash

# Clone a GitHub repository

curl -X POST https://my-routa-instance.com/api/clone \
  -H "Content-Type: application/json" \
  -d '{"url":"https://github.com/microsoft/TypeScript"}'

# List all cloned repositories

curl https://my-routa-instance.com/api/clone

```

The listing endpoint returns structured metadata:

```json
{
  "repos": [
    {
      "name": "microsoft/TypeScript",
      "path": "/home/user/.routa/repos/microsoft--TypeScript",
      "branch": "main",
      "branches": ["main", "dev", "release-4.9"],
      "status": {
        "clean": false,
        "ahead": 2,
        "behind": 0,
        "modified": 3,
        "untracked": 1
      }
    }
  ]
}

```

This response derives from the `listClonedRepos()` function in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts).

### Switching Branches Programmatically

Change the active branch for a workspace-linked repository:

```tsx
await fetch("/api/clone/branches", {
  method: "PATCH",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ 
    repoPath: selectedRepo.path, 
    branch: "feature/new-api" 
  })
});

```

The back-end handler in [`src/app/api/clone/branches/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/branches/route.ts) calls `checkoutBranch()` from the Git utilities, handling edge cases such as bare repositories and non-existent branches by creating them as needed.

### Querying Repository Status from Tasks

Access file changes directly within agent tasks or automation scripts:

```typescript
import { getRepoChanges } from "@/core/git/git-utils";

const changes = getRepoChanges(workspace.repoPath);
console.log(changes.files.map(f => `${f.status}: ${f.path}`));

```

The `getRepoChanges` function performs cached `git status` and `git diff --numstat` operations for efficient file statistics, enabling agents to respond to code modifications without expensive re-indexing.

## Key Implementation Files

Understanding these source files helps when extending or debugging the integration:

- **[`src/client/components/repo-picker.tsx`](https://github.com/phodal/routa/blob/main/src/client/components/repo-picker.tsx)**: React component providing the clone UI, GitHub URL detection, and branch selection dropdown
- **[`src/app/api/clone/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/route.ts)**: Next.js API route handling clone requests and zipball fallbacks
- **[`src/app/api/clone/progress/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/progress/route.ts)**: SSE endpoint for real-time clone progress updates
- **[`src/app/api/clone/branches/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/branches/route.ts)**: Branch listing and switching endpoint
- **[`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts)**: Core library exposing `listClonedRepos`, `checkoutBranch`, `getRepoChanges`, and repository detection utilities
- **[`src/core/github/github.ts`](https://github.com/phodal/routa/blob/main/src/core/github/github.ts)**: GitHub API wrapper for zipball imports when native git is unavailable

## Summary

- Routa integrates GitHub repositories by cloning them into `.routa/repos` and storing the path in workspace records
- The **RepoPicker** component ([`src/client/components/repo-picker.tsx`](https://github.com/phodal/routa/blob/main/src/client/components/repo-picker.tsx)) provides the primary UI for cloning and selection
- **API endpoints** under `/api/clone` handle repository management, with fallback support for zipball imports in serverless environments
- Git operations are centralized in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts), exposing uniform methods for status checks, branch switching, and diff generation
- Once linked, repositories enable file-aware agents, Kanban task references, and inline diff visualizations throughout the workspace

## Frequently Asked Questions

### Can I connect private GitHub repositories to Routa?

Yes, provided your Routa instance has authentication credentials configured. The [`src/app/api/clone/route.ts`](https://github.com/phodal/routa/blob/main/src/app/api/clone/route.ts) handler uses standard git protocols; for private repos, ensure your deployment has SSH keys or HTTPS credentials configured for the runtime environment. The Git utility layer in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts) executes standard git commands that respect the host's credential store.

### What happens if the server environment does not have git installed?

Routa falls back to a zipball import mechanism. When `parseGitHubUrl` detects a public GitHub repository but `git` is unavailable, the system calls `importGitHubZipFallback` from [`src/core/github/github.ts`](https://github.com/phodal/routa/blob/main/src/core/github/github.ts) to download and extract the repository as a static snapshot. This ensures functionality in serverless or restricted environments, though branch switching and history traversal will be limited compared to full git clones.

### How does Routa handle switching between branches?

Branch switching occurs through the `PATCH /api/clone/branches` endpoint, which invokes `checkoutBranch()` in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts). This utility safely handles working directory changes, creates missing branches when specified, and validates that the target repository path exists within the allowed clone base directory. The UI reflects changes immediately by re-fetching the `RepoSelection` state.

### Where does Routa physically store cloned repositories?

Repositories are stored in the clone base directory—by default `.routa/repos` relative to the working directory—using a sanitized naming convention of `owner--repo`. This path structure is defined in [`src/core/git/git-utils.ts`](https://github.com/phodal/routa/blob/main/src/core/git/git-utils.ts) and ensures valid filesystem names while maintaining uniqueness across different namespaces. All Git utilities reference repositories by this absolute path, stored in the workspace's `RepoSelection` record.