GitHub Integration MVP
Read-only GitHub integration for Relay: when a worktree's origin points to github.com, show a visually expressive CI status badge next to the branch name (SF Symbols + color + pulse for running). Click the badge to open a popover with workflow groups → jobs; clicking a job opens the GitHub Actions run in the browser. Authentication via standalone OAuth Web Flow + PKCE through ASWebAuthenticationSession, token stored in Keychain.
Primary JTBD
«Узнать о failing CI в моей ветке без переключения контекста из терминала».
Value Statement
Single concrete advantage over the browser / GitHub Desktop / gh CLI: learn about failing CI ~30 seconds earlier, without switching context from the editor/terminal, with visual attachment to the specific worktree row.
Product Decisions (Q1–Q8 confirmed)
| Q |
Decision |
| Q1 OAuth flow |
OAuth Web Flow + PKCE via ASWebAuthenticationSession. OAuth App under org androidbroadcast. |
| Q2 OAuth App vs GitHub App |
OAuth App for MVP (scope repo). Migration to GitHub App — when Relay backend exists. |
| Q3 Primary JTBD |
«Know about failing CI without context switch». |
| Q4 Multi-account |
Defer. Keychain API account-keyed, UI switcher — later. |
| Q5 Popover content |
List of jobs with icons; click → web. |
| Q6 Visual polish |
SF Symbols + semantic colors + pulse for running. |
| Q7 Multiple workflows |
Worst-status aggregate; groups by workflow name. |
| Q8 Rate limit |
No hard-cap now (single-user); tracked as future. |
| — |
GHE — out of scope. Host hardcoded api.github.com. |
| — |
Branches without PR: show CI of latest commit. |
| — |
Sandbox: com.apple.security.network.client entitlement. |
MVP Scope (17 tasks, 7 waves)
Wave 1
Wave 2 (parallel)
Wave 3
Wave 4
Wave 5 (parallel)
Wave 6
Wave 7
Dependency Graph
T-1 (#215) ────────→ T-4 (#218) ────────────┐
│
T-2 (#216) ───┬───→ T-3 (#217) ───┐ │
│ T-5 (#219) ────┼───→ T-7 (#222) ┼→ T-8a (#224) ─┬──→ T-8b (#225) ┐
│ T-6 (#220) ────┘ ↑ │ │ │
│ T-15 (#221) │ │ ├──→ T-9 (#226) │
│ │ │ │ ├→ T-12 (#229) → T-16 (#230) ┐
└────→ T-14 (#223) ──────┘ │ ├──→ T-10 (#227) │ │
│ │ │ ├→ T-13 (#231)
│ └──→ T-11 (#228) ┘
Critical path: T-2 (#216) → T-5 (#219) → T-7 (#222) → T-8a (#224) → T-8b (#225) → T-12 (#229) → T-16 (#230) → T-13 (#231) (8 steps).
Constraints
- macOS 26+, Apple Silicon only
- Swift 6 strict concurrency, Sendable at API boundaries
- TCA; reuse
CloudClient/RelayRESTClient + ServerKeychainStore patterns
- Zero new external dependencies
- No backend; OAuth App (not GitHub App)
- Host hardcoded
api.github.com
- MVP read-only
- Polling-only, no webhooks
- One-account MVP (API account-keyed for future)
- English UI strings only
Won't (explicit)
- Create PR (neither inline nor deep link inside app)
- Rerun / cancel workflows
- Streaming job logs
- Multi-account UI switcher
- GHE Server
- GitHub App (requires backend)
- PR review actions (approve, comment, request changes)
- Inline file diff
- Webhooks / push notifications
- Issues integration
- GraphQL optimization
- Fork PR from fork-repo
Estimate
3 weeks (2 core + 1 OAuth infra + 30% buffer).
Relationships
Acceptance criteria (epic-level)
GitHub Integration MVP
Read-only GitHub integration for Relay: when a worktree's
originpoints to github.com, show a visually expressive CI status badge next to the branch name (SF Symbols + color + pulse for running). Click the badge to open a popover with workflow groups → jobs; clicking a job opens the GitHub Actions run in the browser. Authentication via standalone OAuth Web Flow + PKCE throughASWebAuthenticationSession, token stored in Keychain.Primary JTBD
«Узнать о failing CI в моей ветке без переключения контекста из терминала».
Value Statement
Single concrete advantage over the browser / GitHub Desktop / gh CLI: learn about failing CI ~30 seconds earlier, without switching context from the editor/terminal, with visual attachment to the specific worktree row.
Product Decisions (Q1–Q8 confirmed)
ASWebAuthenticationSession. OAuth App under organdroidbroadcast.repo). Migration to GitHub App — when Relay backend exists.api.github.com.com.apple.security.network.cliententitlement.MVP Scope (17 tasks, 7 waves)
Wave 1
GitRemotevalue type + parser in SharedModelsGitHubIntegrationSPM package skeletonWave 2 (parallel)
GitCLI.listRemotes+WorktreeFeature.State.remotes(cap 20)GitHubClientHTTP foundation (ETag, DTO, typed errors)GitHubCredentialStore— Keychain account-keyedos.LoggerWave 3
GitHubAuthServiceWave 4
GitHubFeaturestate model + basic reducerWave 5 (parallel)
Wave 6
GitHubFeatureintoWorktreeFeature+ badge inWorktreeRowViewWave 7
CLAUDE.md+docs/architecture+ testplan + CI)Dependency Graph
Critical path: T-2 (#216) → T-5 (#219) → T-7 (#222) → T-8a (#224) → T-8b (#225) → T-12 (#229) → T-16 (#230) → T-13 (#231) (8 steps).
Constraints
CloudClient/RelayRESTClient+ServerKeychainStorepatternsapi.github.comWon't (explicit)
Estimate
3 weeks (2 core + 1 OAuth infra + 30% buffer).
Relationships
Acceptance criteria (epic-level)
swiftlint lint --strictgreenxcodebuild buildandxcodebuild testfor Relay scheme — greenCLAUDE.md,docs/architecture/github-integration.md,docs/testplans/15-github-integration.md, coverage-matrix, new package README)