Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Feature: Import/clone repositories from the connected GitHub account (workspace recovery) #20472

Description

@appweb514-svg

Feature: Import/clone repositories from the connected GitHub account (workspace recovery)

Summary

Orca only knows about local projects (folders already on disk or cloned
manually). The GitHub integration is per-repository: PRs, issues, checks and
GitHub Projects v2 are tied to a repo/worktree that is already registered.

As a result, when a user reinstalls Orca after switching machine or IDE, they
only see the repositories present on that disk and cannot recover their
working environment
from their GitHub account. There is no "all my repos"
view, and the existing "Choose a project" picker
(src/renderer/src/components/github-project/ProjectPicker.tsx) expects a
GitHub Project URL/number (owner/number), not a repository.

Proposal

Add a "Clone from GitHub" source to the add-project flow that lists the
repositories visible to the authenticated GitHub account (owned + organization
memberships + collaborator repos) and lets the user clone one or many of them
into Orca at once.

This directly enables workspace recovery after a machine/IDE change.

UX

Entry point: Add project → "Other ways to add" → "Clone from GitHub"
(HostSetupStartActions in
src/renderer/src/components/settings/repository-host-add-project-steps.tsx,
used by RepositoryHostSetupActions.tsx).

New HostSetupGitHubStep:

  1. Search field (client-side filter on owner/name, description, language).
  2. List sorted by recent activity (pushed_at desc), each row showing:
    • a checkbox (multi-select);
    • visibility (private/public), fork, language, last-activity date;
    • a "Already in Orca" badge when the repo matches a registered project.
  3. Already-added repos: disabled checkbox (never cloned), badge + Open
    action (focus the existing project).
  4. Destination: a single parent folder, pre-filled with Orca's default
    projects directory. Each repo clones to <parent>/<repoName>.
  5. "Clone selection (N)" action, disabled when the selection is empty.
  6. During the batch: per-repo progress (pending → cloning → added → failed
    with reason); failures do not stop the remaining clones; a summary is shown
    at the end.

Cloning reuses the existing flow
setupProjectClone({ projectId, hostId, url, destination, displayName }) with
projectId = github:<owner>/<repo> (same identity as orca project setup-clone).

Technical plan

Shared DTO

New src/shared/github/viewer-repository-types.ts:

export type GitHubViewerRepository = {
  id: number
  nameWithOwner: string
  owner: string
  name: string
  isPrivate: boolean
  isFork: boolean
  isArchived: boolean
  language: string | null
  defaultBranch: string
  pushedAt: string | null
  description: string | null
  httpsUrl: string
  sshUrl: string
  viewerPermission: string | null
}

export type ListViewerRepositoriesResult =
  | { ok: true; viewer: { login: string }; repositories: GitHubViewerRepository[] }
  | {
      ok: false
      error: string
      code?: 'gh_missing' | 'gh_unauthenticated' | 'rate_limited' | 'unknown'
    }

Main process

New src/main/github/client/list/list-viewer-repositories.ts, following the
src/main/github/client/list/list-work-items.ts pattern:

  • acquire() / release() from src/main/github/gh-utils.ts (GitHub
    concurrency slot).
  • ghExecFileAsync(['api', '/user/repos', '-X', 'GET', '-f', 'affiliation=owner,collaborator,organization_member', '-f', 'sort=updated', '-f', 'direction=desc', '-f', 'per_page=100', '--paginate']).
  • Defensive normalization/sort, de-duplication by id.
  • Errors classified via classifyGhError; gh missing/unauthenticated →
    gh_missing / gh_unauthenticated; 403/429 → rate_limited (reuse
    getRateLimit).

Export from the src/main/github/client.ts barrel.

IPC + preload

  • Handler in src/main/ipc/github-account-handlers.ts:
    ipcMain.handle('gh:listViewerRepositories', () => listAuthenticatedViewerRepositories()).
  • Preload bridge in src/preload/api/gh-bridge-pull-requests-and-work-items.ts:
    listViewerRepositories: () => ipcRenderer.invoke('gh:listViewerRepositories').
  • Add the channel to src/main/ipc/github-ipc-channel-parity.test.ts.

Renderer

  • repository-host-add-project-steps.tsx: add HostSetupGitHubStep and the
    entry in HostSetupStartActions.
  • RepositoryHostSetupActions.tsx: add the 'github' step, load the list on
    first open, orchestrate sequential cloning by reusing setupProjectClone per
    repo.
  • Batch state: Map<repoId, 'pending' | 'cloning' | 'done' | 'error'>.

"Already in Orca" detection

  • Match on canonical identity github.com/<owner>/<repo> (existing
    gitRemoteIdentity.canonicalKey) or project id github:<owner>/<repo>.
  • No new storage: the registered repo/project list is already available in the
    renderer store.

Auth, errors, limits

  • Orca's GitHub integration already uses the gh CLI
    (getAuthenticatedViewer()gh api user), so no new token is introduced.
  • Existing gh token scopes (repo, read:org) are sufficient for
    GET /user/repos.
  • If gh is missing/unauthenticated: empty state with a "Connect GitHub" CTA
    (reuse gh:diagnoseAuth).
  • per_page=100 + --paginate: most accounts fit in one page.

Data hygiene

  • No token or identity is introduced or logged; auth stays with the gh CLI and
    the feature is read-only.
  • GitHub responses are consumed on the fly and not persisted; only repos
    actually cloned create project entries.
  • No personal data (name, email, tokens, user paths) in code, logs, tests or
    fixtures.

i18n and quality gates

  • All strings via translate('auto.<component>.<hash>', '<default>').
  • Update localization catalogs as required by verify:localization-*, plus
    oxlint, typecheck and tests.

Testing

  • Client unit test (Vitest): mock ghExecFileAsync; cover pagination,
    normalization, forks/private repos, and error paths (gh missing,
    unauthenticated, rate-limited).
  • Component test: search/filter, multi-select, "Already in Orca" badge, required
    destination, progress and partial failure.
  • IPC parity test (github-ipc-channel-parity.test.ts).
  • Repo checks: pnpm test, pnpm typecheck, pnpm lint.

Alternatives considered

  • Minimal IPC only (gh api … --paginate with ad-hoc error handling) —
    smaller diff but weaker error/rate-limit/cache handling.
  • Dedicated "Repositories" sidebar view — larger UI surface and review, and
    outside the add-project flow.

Risks

  • GitHub load: a single paginated user/repos call, cached for the lifetime
    of the dialog in the renderer.
  • Name collisions across owners: clone to <parent>/<repoName>; on disk
    conflict, fail that repo with a reason (never overwrite).
  • Collaborator repos the user does not want to see: search filter + recent
    sort; a future owner selector can narrow this.

Open questions

  • Should there be a more visible entry point (Projects sidebar "+" → Import from
    GitHub, or onboarding) in addition to the add-project flow?
  • Default destination: hardcoded Orca projects dir, or the workspaceDir
    setting?
  • HTTPS vs SSH clone URL depending on the target host (SSH/runtime)?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions