GitHubService handles GitHub authentication, repository management, and pull request operations in Emdash. It uses OAuth Device Flow for authentication and the gh CLI for Git/GitHub operations.
Overview
Key features:- OAuth Device Flow: Browser-based authentication with automatic background polling
- gh CLI integration: Leverages GitHub CLI for repository and PR operations
- Secure token storage: Stores OAuth tokens in OS keychain (via keytar)
- Automatic re-auth: Detects auth failures and re-authenticates gh CLI
- Issue search: Search and view GitHub issues
- PR management: List, checkout, and create pull requests
- Request device code from GitHub
- Display code to user (browser opens to GitHub)
- Poll for token in background
- Store token in keychain
- Authenticate gh CLI with token
Authentication
startDeviceFlowAuth
Start OAuth Device Flow authentication with automatic background polling.Whether device code request succeeded
Device code for polling (internal use)
Code for user to enter on GitHub (e.g.,
A1B2-C3D4)GitHub verification URL (e.g.,
https://github.com/login/device)Seconds until code expires (typically 900)
Seconds between polling attempts (typically 5)
Error message (if request failed)
- Stops any existing polling loop
- Requests device code from GitHub
- Emits
github:auth:device-codeevent to renderer (with 100ms delay) - Starts background polling loop
- Returns device code result immediately
github:auth:device-code: Device code ready for displaygithub:auth:polling: Still waiting for user authorizationgithub:auth:slow-down: GitHub requested slower pollinggithub:auth:success: Authentication succeeded (token acquired)github:auth:error: Authentication failed or expiredgithub:auth:cancelled: User cancelled authentication
pollDeviceToken
Poll for access token using device code (called automatically by background loop).Device code from
requestDeviceCodePolling interval in seconds
authorization_pending: User hasn’t authorized yet (continue polling)slow_down: GitHub wants slower polling (increase interval by 5s)expired_token: Device code expired (stop polling)access_denied: User denied authorization (stop polling)
- Stores token in keychain
- Authenticates gh CLI with token
- Fetches user info from GitHub API
- Emits
github:auth:successevent to renderer
cancelAuth
Cancel the authentication flow.isAuthenticated
Check if user is authenticated (checks gh CLI and keychain).logout
Logout and clear stored token.- Logs out from gh CLI:
gh auth logout --hostname github.com - Removes token from keychain
User Information
getCurrentUser
Get the authenticated user’s information.getOwners
Get available owners (user + organizations).Repository Operations
getRepositories
Get the user’s repositories (up to 100).OAuth token (unused, kept for API compatibility)
Repository ID
Repository name
Owner/name (e.g.,
user/repo)Repository description
GitHub repository URL
HTTPS clone URL
SSH clone URL
Default branch name (e.g.,
main)Whether repository is private
Last update timestamp
Primary language
Star count
Fork count
createRepository
Create a new GitHub repository.Repository name (validated via
validateRepositoryName)Repository description
Owner login (user or organization)
Whether repository should be private
validateRepositoryName
Validate a repository name against GitHub rules.- Required (non-empty)
- Max 100 characters
- Alphanumeric, hyphens, underscores, dots only
- Cannot start/end with hyphen, dot, or underscore
- Cannot be all dots
- Cannot be a reserved name (e.g.,
con,prn,aux)
checkRepositoryExists
Check if a repository exists.cloneRepository
Clone a repository to a local path.HTTPS or SSH clone URL
Absolute path to clone destination
initializeNewProject
Initialize a new project with README and initial commit.Repository URL
Local project path
Project name
Project description
- Creates
README.mdwith name and description - Runs
git add README.md - Commits with message “Initial commit”
- Pushes to
origin/main(ororigin/masterfallback)
Pull Request Operations
getPullRequests
List open pull requests for a repository.Absolute path to Git repository
PR number
PR title
Head branch name
Base branch name
GitHub PR URL
Whether PR is a draft
Last update timestamp
Head commit SHA
PR author metadata
Head repository owner
Head repository metadata
ensurePullRequestBranch
Checkout a pull request branch locally (creates or updates).Repository path
PR number
Local branch name (defaults to
pr/{number} if empty)- Saves current branch
- Runs
gh pr checkout {prNumber} --branch {branchName} --force - Restores previous branch
Issue Operations
listIssues
List open issues for a repository.Repository path
Max issues to return (1-200, default: 50)
searchIssues
Search open issues in a repository.Search query
getIssue
Get a single issue with body (for enrichment).Security
Token Storage
OAuth tokens are stored in the OS keychain via keytar:- macOS: Keychain Access
- Linux: libsecret (GNOME Keyring, KWallet)
- Windows: Credential Vault
emdash-github
Account name: github-token
gh CLI Authentication
Tokens are passed to gh CLI via stdin (not shell interpolation) to prevent command injection:Automatic Re-authentication
TheexecGH method detects auth failures and re-authenticates:
PrGenerationService
ThePrGenerationService is a companion service that generates PR titles and descriptions using CLI agents or heuristics.
Source: src/main/services/PrGenerationService.ts
generatePrContent
Generate PR title and description based on git changes.Worktree or repository path
Base branch to compare against (default:
main)Optional provider ID to try first (e.g., from
task.agentId)- Preferred provider (if specified and available)
- Claude (most reliable for structured output)
- Remaining providers (codex, qwen, etc.)
- Fallback to heuristics (commit messages + file analysis)
Location
Source:src/main/services/GitHubService.ts
PR Generation: src/main/services/PrGenerationService.ts
IPC Handlers: src/main/ipc/githubIpc.ts
Singleton export:
Related Services
- GitService (
src/main/services/GitService.ts): Low-level Git operations - WorktreeService (
src/main/services/WorktreeService.ts): Worktree management - ErrorTracking (
src/main/errorTracking.ts): Telemetry and error capture
See Also
- GitHub OAuth Device Flow - OAuth documentation
- GitHub CLI Manual - gh CLI reference
- PR Generation Service - PR content generation