diff --git a/packages/app/src/add-project-flow/model.ts b/packages/app/src/add-project-flow/model.ts index 16b80e9c4..3cfd7691a 100644 --- a/packages/app/src/add-project-flow/model.ts +++ b/packages/app/src/add-project-flow/model.ts @@ -14,7 +14,6 @@ export interface GithubRepositoryChoice { cloneUrl: string; cloneProtocol?: "https" | "ssh"; description: string | null; - visibility: string | null; updatedAt: string | null; } diff --git a/packages/app/src/add-project-flow/options.ts b/packages/app/src/add-project-flow/options.ts index 1c9fec5bf..c1d6ce9e4 100644 --- a/packages/app/src/add-project-flow/options.ts +++ b/packages/app/src/add-project-flow/options.ts @@ -101,7 +101,6 @@ export function buildManualGithubRepositoryChoices(query: string): GithubReposit nameWithOwner: identity?.repo ?? remoteName, cloneUrl: repo, description: "Clone this repository URL", - visibility: null, updatedAt: null, }, ]; @@ -116,7 +115,6 @@ export function buildManualGithubRepositoryChoices(query: string): GithubReposit cloneUrl: nameWithOwner, cloneProtocol, description: `Clone owner/repo via ${cloneProtocol.toUpperCase()}`, - visibility: null, updatedAt: null, })); } diff --git a/packages/app/src/components/add-project-flow.tsx b/packages/app/src/components/add-project-flow.tsx index 3078062a7..45425fde8 100644 --- a/packages/app/src/components/add-project-flow.tsx +++ b/packages/app/src/components/add-project-flow.tsx @@ -644,7 +644,7 @@ export function AddProjectFlow({ request, onClose }: AddProjectFlowProps) { title: repository.cloneProtocol ? `${repository.nameWithOwner} via ${repository.cloneProtocol.toUpperCase()}` : repository.nameWithOwner, - subtitle: repository.description ?? repository.visibility, + subtitle: repository.description, icon: Github, testID: `add-project-flow-repository-${repository.id}`, select: () => diff --git a/packages/server/src/services/github-repository-search.test.ts b/packages/server/src/services/github-repository-search.test.ts index 94e2ee068..d324aab16 100644 --- a/packages/server/src/services/github-repository-search.test.ts +++ b/packages/server/src/services/github-repository-search.test.ts @@ -30,7 +30,7 @@ describe("GitHub repository search", () => { name: " paseo ", nameWithOwner: " getpaseo/paseo ", description: null, - visibility: "PUBLIC", + isPrivate: false, updatedAt: "2026-07-15T12:00:00Z", sshUrl: " git@github.com:getpaseo/paseo.git ", url: "https://github.com/getpaseo/paseo", @@ -62,7 +62,7 @@ describe("GitHub repository search", () => { "repo", "list", "--json", - "id,name,nameWithOwner,description,visibility,updatedAt,sshUrl,url", + "id,name,nameWithOwner,description,isPrivate,updatedAt,sshUrl,url", "--limit", "8", ], @@ -83,7 +83,7 @@ describe("GitHub repository search", () => { name: "private-repo", fullName: "octo/private-repo", description: "Private project", - visibility: "PRIVATE", + isPrivate: true, updatedAt: "2026-07-14T08:00:00Z", url: "https://github.com/octo/private-repo", }, @@ -115,7 +115,7 @@ describe("GitHub repository search", () => { "repos", "private project", "--json", - "id,name,fullName,description,visibility,updatedAt,url", + "id,name,fullName,description,isPrivate,updatedAt,url", "--sort", "updated", "--order", diff --git a/packages/server/src/services/github-service.ts b/packages/server/src/services/github-service.ts index e2d82db88..d43916cb6 100644 --- a/packages/server/src/services/github-service.ts +++ b/packages/server/src/services/github-service.ts @@ -147,7 +147,7 @@ const GitHubRepositoryListItemSchema = z.object({ name: z.string(), nameWithOwner: z.string(), description: z.string().nullable().optional(), - visibility: z.string(), + isPrivate: z.boolean(), updatedAt: z.string(), sshUrl: z.string(), url: z.string(), @@ -158,7 +158,7 @@ const GitHubRepositorySearchItemSchema = z.object({ name: z.string(), fullName: z.string(), description: z.string().nullable().optional(), - visibility: z.string(), + isPrivate: z.boolean(), updatedAt: z.string(), url: z.string(), }); @@ -1287,7 +1287,7 @@ export function createGitHubService(options: CreateGitHubServiceOptions = {}): G "repo", "list", "--json", - "id,name,nameWithOwner,description,visibility,updatedAt,sshUrl,url", + "id,name,nameWithOwner,description,isPrivate,updatedAt,sshUrl,url", "--limit", String(limit), ], @@ -1305,7 +1305,7 @@ export function createGitHubService(options: CreateGitHubServiceOptions = {}): G "repos", query, "--json", - "id,name,fullName,description,visibility,updatedAt,url", + "id,name,fullName,description,isPrivate,updatedAt,url", "--sort", "updated", "--order", @@ -2315,7 +2315,7 @@ function normalizeRepositorySummary(repository: { name: string; nameWithOwner: string; description?: string | null; - visibility: string; + isPrivate: boolean; updatedAt: string; cloneUrl: string; }): GitHubRepositorySummary { @@ -2328,20 +2328,15 @@ function normalizeRepositorySummary(repository: { name: repository.name.trim(), nameWithOwner, description: repository.description ?? null, - visibility: normalizeRepositoryVisibility(repository.visibility), + // We query isPrivate, not visibility: `gh repo list --json visibility` is unsupported before + // gh 2.28 (Debian Bookworm ships 2.23), while isPrivate works on every version. The wire schema + // requires the visibility enum, so old clients still get a value they can parse. + visibility: repository.isPrivate ? "private" : "public", updatedAt: repository.updatedAt, cloneUrl: repository.cloneUrl.trim(), }; } -function normalizeRepositoryVisibility(visibility: string): GitHubRepositorySummary["visibility"] { - const normalized = visibility.toLowerCase(); - if (normalized === "public" || normalized === "private" || normalized === "internal") { - return normalized; - } - throw new Error(`Unknown GitHub repository visibility: ${visibility}`); -} - function toPullRequestCheckoutTarget( parsed: z.infer, ): PullRequestCheckoutTarget {