--- brief: 2 convoy: repo-discovery-onboarding role: role-implementer title: Repository picker and batch connection status: ready priority: P1 slice_dependencies: [1] recommended_model: qwen-coder model_tier: local workspace_id: global --- # Brief 2 — Repository picker and batch connection ## Goal Workspace admins can search discovered repositories, select multiple entries, and connect them to the current workspace in one idempotent operation while retaining the existing paste-URL workflow. Backlog task: `plans/Plan-automation-foundation/Epic-repo-discovery-onboarding/Task-repo-picker-modal.md`. ## Files - `apps/web/server/routers/connected-repos.ts` — add zod-validated, admin-only `batchConnect`. Re-resolve or validate selected remote IDs server-side; do not trust client-supplied owner, URLs, forge type, or token references. Insert with workspace scoping and conflict-safe behavior against `connected_repos_workspace_repo_unique`. - `apps/web/app/(app)/[workspaceSlug]/settings/repos/page.tsx` — retain manual connection and add a discovery entry point with source/connection-state handling. - `apps/web/components/settings/repo-picker-dialog.tsx` (new only if extraction improves the existing page) — search, pagination/load-more, multi-select, connected/disabled states, loading/error/empty states, and import progress using existing UI primitives. ## Acceptance - The picker supports GitHub and Forgejo/Gitea connection states returned by Brief 1 and gives actionable reauthorization/configuration messages. - Search matches full name and description without discarding selection when paging. - Already-connected repos cannot be selected. - `batchConnect` is atomic for valid selections, idempotent for duplicates, tenant-scoped, and returns per-repo connected/already-connected results. - A stale or forged client selection cannot connect an arbitrary URL. - Successful import invalidates `connectedRepos.list` and `listAvailable` and leaves the manual paste-URL dialog usable. - Lint and type-check pass; cover server-side validation and selection-state helpers with tests where feasible. ## Prompt for implementer Implement only Brief 2 after Brief 1 is complete. Read the matching backlog task and existing repo settings page before editing. Reuse Radix and `components/ui`; do not implement repository document ingestion or agent setup. Never send forge credentials to a client component.