Submatter/.convoys/repo-discovery-onboarding/brief-1-api.md

3.7 KiB

brief convoy role title status priority slice_dependencies recommended_model model_tier workspace_id
1 repo-discovery-onboarding role-implementer Forge account repository discovery API ready P1
qwen-coder local global

Brief 1 — Forge account repository discovery API

Goal

A workspace admin can request a normalized, paginated list of repositories visible to either their linked GitHub identity or a configured Forgejo/Gitea instance. Already-connected repositories are identified without exposing credentials to the client.

Backlog task: plans/Plan-automation-foundation/Epic-repo-discovery-onboarding/Task-forge-discovery-api.md.

Security and product contract

  • Do not accept or return raw access tokens in tRPC input/output.
  • GitHub credentials come from the current user's accounts row for provider='github'; never use another workspace member's account.
  • Update the existing GitHub provider authorization parameters to request repository discovery scopes. Return a typed reauthorization_required state when the stored account lacks the required scope instead of treating it as a forge API failure.
  • Forgejo/Gitea discovery uses a workspace-admin-supplied instance descriptor and tokenEnvVar; resolve the token only on the server with the existing readToken pattern.
  • Only workspace owner/admin may call discovery. All connected-repo comparisons filter by workspace_id.
  • Keep the existing paste-URL flow working.

Files

  • packages/shared/src/connected-repos/schemas.ts — add zod schemas/types for discovery source, normalized remote repository summary, pagination cursor/page, and typed connection state; export through packages/shared/src/connected-repos/index.ts.
  • apps/web/lib/auth.ts — configure GitHub authorization scopes while preserving the existing sign-in and account-linking flow.
  • apps/web/server/lib/forge/adapters.ts — add a discovery context separate from repo-specific ForgeAdapterContext; implement paginated GitHub /user/repos and Forgejo/Gitea /user/repos mapping. Preserve fetchRepoMetadata and createPullRequest behavior.
  • apps/web/server/routers/connected-repos.ts — add admin-only listAvailable; resolve credentials server-side, call the selected adapter, and mark an item connected using the unique tuple (workspace_id, api_base_url, owner, repo_name).
  • Add focused tests for response validation, pagination, missing credentials/scopes, private repository mapping, and already-connected matching. If web tests require missing infrastructure, add the smallest Vitest setup consistent with existing package configs.

Acceptance

  • GitHub and Forgejo/Gitea payloads map to one zod-validated result containing stable remote ID, name/full name, owner, HTTPS clone URL, web URL, default branch, privacy flag, description, and updated time.
  • Pagination is explicit; the implementation does not silently truncate accounts with more than 100 repositories.
  • A credentials or scope problem returns a typed connection state suitable for UI remediation and does not leak a token or provider response body.
  • Existing connected repos are marked accurately within the current workspace only.
  • Existing manual connect/test/update/disconnect procedures continue to work.
  • pnpm --filter @tasks/shared test, pnpm --filter @tasks/web lint, and pnpm --filter @tasks/web type-check pass.

Prompt for implementer

Implement only Brief 1. Read AGENTS.md, the matching backlog task, apps/web/lib/auth.ts, apps/web/server/lib/forge/adapters.ts, and apps/web/server/routers/connected-repos.ts before editing. Use TDD for adapter normalization and credential-state behavior. Do not build the picker UI, batch connection, document ingestion, or agent configuration in this brief. Do not persist plaintext PATs.