## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work. > - Projects give tasks a common source repository and execution context. > - The current project form asks for a raw URL and unrelated metadata. > - Teams need to select several repos from GitHub connections they can use. > - This pull request implements the reviewed project form and repository editor. > - The server checks credential ownership and shared audiences before discovery. > - Existing workspace URLs and runtime identity rules remain compatible. ## Linked Issues or Issue Description **Problem or motivation** Project creation accepts one raw repository URL. It does not help users select repos from their usable GitHub connections or attach several repos together. **Proposed solution** Add a shared GitHub repository picker to project creation and Configuration. Support multiple selections, transactional persistence, and the existing GitHub setup flow. Simplify the project form and Configuration tab as reviewed. **Alternatives considered** Keep a raw URL field or add a separate repository table. The existing workspace collection already supports several repositories and keeps legacy URLs compatible. **Roadmap alignment** This builds on the shipped MCP Tool Gateway and Apps capability. It does not change runtime credential delegation. Related work: #11662 addresses the existing dialog's viewport limits. #4552 addresses generic Git URLs; this change preserves those URLs in existing workspaces. ## What Changed - Add company-scoped repository discovery from usable personal and shared GitHub grants, with provider-ID deduplication, PAT pagination, and partial failure handling. - Document the repository endpoints and board access requirements in OpenAPI. - Validate new selections and save projects with multiple repository workspaces in one transaction. Preserve legacy URLs and existing selections whose access was lost. - Implement the reviewed Create project dialog, shared repository editor, scrolling, and mobile layout. - Move repositories above environment variables, remove Status and Goals controls and env help paragraphs, move Created to the bottom, and redirect Overview to Configuration. - Reuse GitHub setup in dialogs, preserve project drafts, and verify popup completion through the API. - Replace the configuration story's DOM adapter with explicit production composition. Keep the reviewed mobile and short-viewport stories. ## Verification - Passed: `pnpm build`, `pnpm -r typecheck`, `pnpm build-storybook`, and `pnpm check:token-gates`. - Passed: focused repository access, database persistence, configuration, and connection setup tests. - Passed: `pnpm exec playwright test --config tests/e2e/playwright.config.ts tests/e2e/project-repositories.spec.ts`. - The browser tests use a real temporary server/database. They cover create, forty persisted repos, mobile scrolling, save/reload, legacy URL editing, and rejection without a partial project. - GitHub responses and popup completion use deterministic fixtures. No real GitHub account was authorized by the test suite. - All CI general, serialized server, and browser test shards pass on the final commit. - The local full-suite run overlapped review edits and was stopped; fresh repository, OpenAPI, UI/CLI, and connection tests pass. Unrelated local worker, built-in-agent, and routine timing/socket failures passed isolated reruns. - Final commit `1b3308dca`: all CI gates pass, including build, runner verification, typecheck, canary dry run, and security checks. Greptile is 5/5 with no unresolved review threads. - Storybook visual regression is opt-in and was skipped by CI; the Storybook build passed locally. ## Risks - Repository discovery depends on provider availability. Failed connections are reported while successful results stay usable. - Selections identify source workspaces; they do not grant agents new credentials. The existing primary-workspace and responsible-user identity rules still apply. - No database migration is needed. Existing API status, goals, dates, and manual workspace URLs remain supported. ## Model Used OpenAI Codex, based on GPT-6, with repository inspection, code execution, and browser tools. The runtime does not expose a more specific model deployment ID or context-window size. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have either (a) linked existing issues with `Fixes: #` / `Closes #` / `Refs #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented any risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
4.1 KiB
Project source repositories
The Create project dialog accepts a name and optional GitHub repository selections.
It uses the same RepositoryEditor as project Configuration. Description remains
editable in Configuration. Status, goal links, and target dates remain supported by
the API but are omitted from creation; Status and Goals are omitted from Configuration.
Old Overview URLs and saved Overview preferences redirect to Configuration.
API and persistence
GET /api/companies/:companyId/project-repositoriesreturnsrepositories,connectionCount, andfailedConnectionCount. Repository IDs are GitHub's stable numeric IDs represented as strings. Results are deduplicated across accessible grants and sorted by full name. Connection labels are display provenance only.POST /api/companies/:companyId/projectsaccepts optionalrepositoryIds. The server resolves new selections through the caller's authorized GitHub grants before creating the project and all repository workspaces in a transaction. The existingworkspaceinput remains supported; it cannot be combined withrepositoryIds.PUT /api/projects/:id/repositoriesaccepts the selectedrepositoryIdsarray. Accessible retained IDs refresh their canonical name and URL after renames or transfers; unavailable retained IDs keep their saved metadata. Replacement is transactional. Existing selections may be retained or removed even if their GitHub connection becomes unavailable. New identities require current access. Legacy URL workspaces are preserved, and matching legacy URLs are adopted without creating a duplicate workspace. Local/remote workspace locations survive detaching their repository.
No schema migration is required. Selected repositories are normal project workspaces
with metadata.githubRepositoryId. Existing manual repoUrl workspaces remain
editable through Configuration and the workspace API. One workspace remains primary;
additional repositories do not change the existing runtime workspace-selection or
responsible-user credential rules. A repository selection never delegates credentials.
Discovery and setup
The server checks company membership, grant ownership/status, and organization-grant
audiences before loading provider metadata. Connection managers receive no bypass to
another person's personal repositories. Managed GitHub grants refresh installation
access; PAT connections use paginated /user/repos. Provider failures are reported
without exposing provider error bodies or credential material. Successful connections
remain selectable when another connection fails.
ConnectionSetupFlow owns provider setup in both Apps and project dialogs. Task
intents retain their existing callback protocol. Standalone dialogs verify the saved
connection through the API after the sign-in popup returns to the instance. Project
name and repository drafts stay mounted across setup and cancellation.
UI review and verification
Proposals/Project repos contains the reviewed states, including loading, failure,
empty search, disconnected GitHub, multiple repos, legacy URLs, forty selections,
mobile, and short viewports. The configuration story composes the production page
properties through an explicit repositories slot. Story setup and saves use fixtures.
- Shared visual control:
ui/src/components/RepositoryEditor.tsx. - Data and error handling:
ProjectRepositoryInput.tsx. - Configuration persistence and legacy editing:
ProjectRepositories.tsxandLegacyProjectRepository.tsx. - Production dialog:
NewProjectDialog.tsx. - Server tests:
project-repositories.test.tsandproject-repositories-persistence.test.ts. - Browser acceptance:
tests/e2e/project-repositories.spec.ts.
The browser suite uses a real temporary server and database. It verifies creation, forty persisted repos, mobile scrolling, removal/save/reload, legacy URL editing, and rejection without a partial project. Provider discovery is simulated in the picker rejection test. GitHub network and popup behavior use deterministic fixtures in integration/component tests; the suite does not authorize a real GitHub account.