diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 976f824..88694fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,37 +4,30 @@ Thanks for your interest in contributing to DiffKit! This guide will help you ge ## Development Setup -Follow the [Getting Started](README.md#getting-started) section in the README to set up your local environment. - -## Workflow - -1. **Fork the repo** and create your branch from `main` -2. **Make your changes** — keep commits focused and atomic -3. **Run checks** before pushing: - ```bash - pnpm check-types # Type checking - pnpm lint # Linting - pnpm format # Formatting - ``` -4. **Open a pull request** against `main` - -## Code Style - -This project uses [Biome](https://biomejs.dev/) for linting and formatting. Run `pnpm format` to auto-format your code. Pre-commit hooks via Husky and lint-staged will also catch issues before they're committed. - -A few conventions to keep in mind: - -- Prefer editing existing files over creating new ones -- Keep components in the appropriate package (`apps/dashboard` for app-specific, `packages/ui` for shared) +Follow the [Getting Started](README.md#getting-started) section in the README to set up your local environment. You'll need both a GitHub OAuth App and a GitHub App configured. ## Project Architecture DiffKit is a **pnpm monorepo** managed with **Turborepo**: -- **`apps/dashboard`** — The main web app built with TanStack Start, deployed to Cloudflare Workers -- **`packages/ui`** — Shared UI components (Radix UI primitives + Tailwind CSS) -- **`packages/icons`** — Icon wrapper package -- **`packages/typescript-config`** — Shared TypeScript configurations +``` +diffkit/ +├── apps/ +│ └── dashboard/ # Main web app (TanStack Start + Cloudflare Workers) +│ ├── src/ +│ │ ├── components/ # App-specific React components +│ │ ├── db/ # Drizzle ORM schema and database access +│ │ ├── lib/ # Auth, GitHub API clients, caching, utilities +│ │ └── routes/ # File-based routes (TanStack Router) +│ │ ├── api/ # API routes (auth callbacks, webhooks) +│ │ └── _protected/ # Auth-gated routes +│ └── drizzle/ # SQL migration files +├── packages/ +│ ├── ui/ # Shared UI components (Radix UI + Tailwind CSS) +│ ├── icons/ # Icon wrapper package +│ └── typescript-config/ # Shared TypeScript configurations +└── scripts/ # Migration runner and dev utilities +``` ### Key Technologies @@ -49,12 +42,15 @@ DiffKit is a **pnpm monorepo** managed with **Turborepo**: DiffKit uses a hybrid GitHub auth model: - The **GitHub OAuth App** signs users in and powers broad user-context reads, including public or external repositories where the GitHub App is not installed. -- The **GitHub App user token** powers installation discovery, including `GET /user/installations`. +- The **GitHub App user token** (`ghu_` prefix) powers installation discovery via `GET /user/installations`. - The **GitHub App installation token** is preferred for repo-scoped reads and writes when the app is installed for that owner. -Local development requires both app configs. The OAuth App callback is `/api/auth/callback/github`. The GitHub App user authorization callback is `/api/github/app/callback`, and the GitHub App setup URL is `/?show-org-setup=true` with **Redirect on update** enabled. +Auth callbacks: +- OAuth App: `/api/auth/callback/github` +- GitHub App user authorization: `/api/github/app/callback` +- GitHub App setup URL: `/?show-org-setup=true` (with **Redirect on update** enabled) -Required local variables are documented in `apps/dashboard/.dev.vars.example`. Do not commit real `.dev.vars` values or private keys. If a private key is exposed, revoke it in GitHub App settings and generate a replacement. +Environment variables are documented in `apps/dashboard/.dev.vars.example`. Do not commit real `.dev.vars` values or private keys. If a private key is exposed, revoke it in GitHub App settings and generate a replacement. ### Adding a New Route @@ -66,6 +62,29 @@ Protected routes go under `_protected/` which enforces authentication. Shared components go in `packages/ui/src/components/`. App-specific components go in `apps/dashboard/src/components/`. +## Workflow + +1. **Fork the repo** and create your branch from `main` +2. **Make your changes** — keep commits focused and atomic +3. **Run checks** before pushing: + ```bash + pnpm check-types # Type checking + pnpm lint # Linting + pnpm format # Formatting + ``` +4. **Open a pull request** against `main` + +## Code Style + +This project uses [Biome](https://biomejs.dev/) for linting and formatting. Run `pnpm format` to auto-format your code. Pre-commit hooks via Husky and lint-staged will also catch issues before they're committed. + +A few conventions: + +- Prefer editing existing files over creating new ones +- Keep components in the appropriate package (`apps/dashboard` for app-specific, `packages/ui` for shared) +- Use `cn()` for composing class names (not template literals) +- Use `flex` + `gap` for spacing (not `space-x` / `space-y`) + ## Pull Requests - Keep PRs focused — one feature or fix per PR diff --git a/README.md b/README.md index ad3a267..677bfb5 100644 --- a/README.md +++ b/README.md @@ -33,136 +33,160 @@ A fast, design-first GitHub dashboard for developers who want to stay on top of ### Prerequisites -- [Node.js](https://nodejs.org/) (v20+) -- [pnpm](https://pnpm.io/) (v10+) -- A [GitHub OAuth App](https://github.com/settings/developers) (for user authentication) -- A [GitHub App](https://github.com/settings/apps) (for webhooks and installation management) - -### Setup - -1. **Clone the repo** - +- [Node.js](https://nodejs.org/) v20+ +- [pnpm](https://pnpm.io/) v10+ + +### 1. Clone and install + +```bash +git clone https://github.com/stylessh/diffkit.git +cd diffkit +pnpm install +``` + +### 2. Create a GitHub OAuth App + +The OAuth App handles user login and broad-scope reads (`repo`, `read:org`, `user:email`). It's also the fallback for repositories where the GitHub App is not installed. + +1. Go to [GitHub OAuth App settings](https://github.com/settings/developers) and click **New OAuth App** +2. Fill in the form: + - **Application name**: DiffKit (local) + - **Homepage URL**: `http://localhost:3000` + - **Authorization callback URL**: `http://localhost:3000/api/auth/callback/github` +3. Click **Register application** +4. Copy the **Client ID** +5. Click **Generate a new client secret** and copy it + +You'll need both values for your `.dev.vars` file in step 5. + +### 3. Create a GitHub App + +The GitHub App provides installation tokens for repo-scoped access, webhook delivery, and user-to-server tokens for installation discovery. + +1. Go to [GitHub App settings](https://github.com/settings/apps) and click **New GitHub App** +2. Fill in the form: + - **GitHub App name**: DiffKit Dev (must be globally unique) + - **Homepage URL**: `http://localhost:3000` + - **Callback URL**: `http://localhost:3000/api/github/app/callback` + - **Setup URL**: `http://localhost:3000/?show-org-setup=true` + - Check **Redirect on update** + - Leave **Request user authorization (OAuth) during installation** **unchecked** + - **Webhook URL**: leave blank for now (see [Local webhook testing](#local-webhook-testing) below) + +3. Under **Permissions**, grant the following: + + | Category | Permission | Level | + |----------|-----------|-------| + | Repository | Metadata | Read-only | + | Repository | Pull requests | Read & write | + | Repository | Issues | Read & write | + | Repository | Checks | Read-only | + | Repository | Actions | Read-only | + | Repository | Contents | Read & write | + | Organization | Members | Read-only | + | Account | Email addresses | Read-only | + +4. Under **Subscribe to events**, enable: + - Check run + - Check suite + - Issue comment + - Issues + - Pull request + - Pull request review + - Pull request review comment + - Pull request review thread + +5. Click **Create GitHub App** + +6. On the app settings page, note down: + - **App ID** (numeric, shown at the top) + - **Client ID** (starts with `Iv1.`) + - The **slug** from the app URL (`https://github.com/apps/`) + +7. Generate credentials: + - Click **Generate a new client secret** and copy it + - Under **Private keys**, click **Generate a private key** — a `.pem` file will download + +8. Convert the private key to a single-line format for `.dev.vars`: ```bash - git clone https://github.com/stylessh/diffkit.git - cd diffkit + awk 'NF {printf "%s\\n", $0}' /path/to/downloaded-key.pem ``` + GitHub downloads PKCS#1 keys (`BEGIN RSA PRIVATE KEY`). DiffKit auto-converts to PKCS#8 at runtime. -2. **Install dependencies** +### 4. Install the GitHub App - ```bash - pnpm install - ``` +1. Go to your GitHub App's settings page → **Install App** +2. Choose the user or organization you want DiffKit to access +3. Select **All repositories** or pick specific ones +4. Click **Install** -3. **Configure environment variables** +### 5. Configure environment variables - Create a `.dev.vars` file in `apps/dashboard/`: +Copy the example file and fill in the values from steps 2–4: - ``` - GITHUB_OAUTH_CLIENT_ID=your_oauth_app_client_id - GITHUB_OAUTH_CLIENT_SECRET=your_oauth_app_client_secret - GITHUB_APP_CLIENT_ID=your_github_app_client_id - GITHUB_APP_CLIENT_SECRET=your_github_app_client_secret - GITHUB_APP_ID=your_numeric_github_app_id - GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n" - GITHUB_APP_SLUG=your_github_app_slug - GITHUB_WEBHOOK_SECRET=your_github_webhook_secret - BETTER_AUTH_SECRET=a_random_32_character_string - BETTER_AUTH_URL=http://localhost:3000 - ``` +```bash +cp apps/dashboard/.dev.vars.example apps/dashboard/.dev.vars +``` - > DiffKit also accepts the legacy `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` names as a fallback for the OAuth App credentials during migration. +Open `apps/dashboard/.dev.vars` and fill in: -4. **Create the GitHub OAuth App** (for user authentication) +``` +# From the OAuth App (step 2) +GITHUB_OAUTH_CLIENT_ID=your_oauth_client_id +GITHUB_OAUTH_CLIENT_SECRET=your_oauth_client_secret - In [OAuth App settings](https://github.com/settings/developers): +# From the GitHub App (step 3) +GITHUB_APP_CLIENT_ID=Iv1.your_app_client_id +GITHUB_APP_CLIENT_SECRET=your_app_client_secret +GITHUB_APP_ID=123456 +GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n" +GITHUB_APP_SLUG=your-app-slug - - Click **New OAuth App** - - Set the callback URL to `http://localhost:3000/api/auth/callback/github` - - Note the **Client ID** and generate a **Client Secret** +# Webhook secret (set the same value in your GitHub App settings) +GITHUB_WEBHOOK_SECRET=your_webhook_secret - The OAuth App handles user login and broad user-context reads. DiffKit requests `repo`, `read:org`, and `user:email` scopes. OAuth is also the fallback path for public or external repositories where the GitHub App is not installed, such as upstream open source repositories. +# Generate with: openssl rand -base64 32 +BETTER_AUTH_SECRET=your_random_secret_at_least_32_chars +BETTER_AUTH_URL=http://localhost:3000 +``` -5. **Create and install the GitHub App** (for webhooks and installations) +> DiffKit also accepts the legacy `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` names as a fallback for the OAuth App credentials. - In [GitHub App settings](https://github.com/settings/apps): +### 6. Run database migrations - - Set the callback URL to `http://localhost:3000/api/github/app/callback` - - Set the setup URL to `http://localhost:3000/?show-org-setup=true` - - Enable **Redirect on update** - - Leave **Request user authorization (OAuth) during installation** unchecked - - Note the **Client ID**, generate a **Client Secret**, note the numeric **App ID**, and generate a private key - - Install the app on the repositories or organizations you want DiffKit to access +```bash +pnpm --filter dashboard migrate +``` - The GitHub App user authorization flow stores a `ghu_` user-to-server token for installation discovery. Repo-scoped reads and writes prefer GitHub App installation tokens when the app is installed, and fall back to OAuth for external/public repositories. +### 7. Start the dev server - Store the downloaded private key as an escaped single-line value in `.dev.vars`. GitHub commonly downloads a PKCS#1 key with `BEGIN RSA PRIVATE KEY`; DiffKit normalizes it to the PKCS#8 format required by the GitHub App JWT library at runtime. +```bash +pnpm dev +``` - ```bash - printf 'GITHUB_APP_PRIVATE_KEY="' > /tmp/github-app-private-key.env - sed 's/$/\\n/' /path/to/github-app-private-key.pem | tr -d '\n' >> /tmp/github-app-private-key.env - printf '"\n' >> /tmp/github-app-private-key.env - cat /tmp/github-app-private-key.env - ``` +Open [http://localhost:3000](http://localhost:3000) in your browser. - Recommended GitHub App permissions derived from the current roadmap: - - | Roadmap area | Roadmap items | GitHub App permission | Level | Notes | - | --- | --- | --- | --- | --- | - | Auth | Sign in and identify the user | User `Email addresses` | Read-only | Required for Better Auth to resolve the user's email address. | - | Core dashboard | Overview, repo list, repo search, private repo access | Repository `Metadata` | Read-only | Required baseline permission for repository-aware reads. | - | Pull requests | View/edit PRs, update branch, request reviewers, review diffs, merge, close/reopen, link issues | Repository `Pull requests` | Read & write | Required now for existing PR mutations and future PR management. | - | Issues | View/create/edit/close issues, labels, milestones, comments | Repository `Issues` | Read & write | Required now for current label mutations and future issue workflows. | - | CI and review status | PR checks, CI-aware review flows, CI notification filtering | Repository `Checks` | Read-only | Required now for pull request status surfaces. | - | GitHub Actions | Workflow run history, job logs, artifacts, rerun/cancel/retry flows, Actions-focused UI | Repository `Actions` | Read & write | `Read` is enough for viewing workflow runs and logs. Use `Read & write` if the product should also rerun, cancel, delete, or otherwise manage workflow runs. | - | Collaborators and teams | Reviewer pickers, org team reviewer flows | Organization `Members` | Read-only | Required for org installs if reviewer assignment should include teams. | - | Repository content | File browser, README preview, branch/tag management, create PR from branches | Repository `Contents` | Read & write | Inference from the roadmap. Likely needed once repository browsing and branch operations ship. | - | Workflow files and policy | Editing `.github/workflows/*`, enabling/disabling workflows, workflow policy/config management | Repository `Workflows` | Read & write | Separate from `Actions`. Needed when the app modifies workflow definitions or workflow configuration, not just when it reads logs or manages runs. | - | Search | Global search across PRs, issues, and repos | No extra permission beyond the resources being searched | N/A | Search inherits access from `Metadata`, `Pull requests`, `Issues`, and likely `Contents`. | - | Notifications | Notification inbox, mark read/unread, filter by type | No matching GitHub App permission | N/A | GitHub's notifications REST endpoints do not support GitHub App user or installation tokens, so this roadmap area needs a different implementation strategy. | - - If we add new permissions after users have already installed the app, GitHub will require those installations to approve the expanded permission set. - - Recommended webhook events in GitHub App setup: - - | GitHub UI label | Enable now | Why | - | --- | --- | --- | - | `Check run` | Yes | Keeps PR status and check-derived cache fresh. | - | `Check suite` | Yes | Captures suite-level CI state changes for PR refreshes. | - | `Issue comment` | Yes | Refreshes issue and PR comment-related views. | - | `Issues` | Yes | Refreshes issue and PR metadata when titles, bodies, labels, or state change. | - | `Pull request` | Yes | Core PR invalidation event. | - | `Pull request review` | Yes | Refreshes review state and PR detail data. | - | `Pull request review comment` | Yes | Refreshes diff discussion and review comment data. | - | `Pull request review thread` | Yes | Refreshes review thread state changes. | - | `Workflow run` | Later | Recommended once the Actions dashboard ships. Useful for workflow-run level updates, logs, reruns, and run state transitions. | - | `Workflow job` | Later | Recommended once the Actions dashboard ships. Useful for job-level logs, timing, and per-job status updates. | - | `Push` | Later | Not used by the current invalidation code, but likely useful once branch-aware repo/activity features expand. | - | `Repository` | Later | Useful for repo settings and metadata changes if repository management surfaces expand. | - | `Create` | Later | Useful for branch/tag creation flows if repo management features ship. | - | `Delete` | Later | Useful for branch/tag deletion flows if repo management features ship. | - - `Workflow run` and `Workflow job` require at least repository `Actions: Read-only`. - - The current webhook invalidation route is wired for the first 8 events above. If you enable the `Later` events now, they are harmless, but the app will ignore them until we add handlers. - - Set the webhook URL to `/api/webhooks/github` on your deployed app. For local webhook testing, use a tunnel that forwards to `http://localhost:3000/api/webhooks/github`. - - For local Vite development, set `DEV_TUNNEL_URL` in `apps/dashboard/.dev.vars` to the full public tunnel URL, for example `https://your-subdomain.ngrok-free.app`. The dev server will use it to allow the tunnel host and configure HMR correctly. - -6. **Run database migrations** +### Local webhook testing - ```bash - pnpm --filter dashboard migrate - ``` - -7. **Start the dev server** +To receive GitHub webhooks locally, you need a public tunnel: +1. Start a tunnel (e.g. with [ngrok](https://ngrok.com/)): ```bash - pnpm dev + ngrok http 3000 ``` +2. Copy the public URL (e.g. `https://abc123.ngrok-free.app`) +3. Add it to `apps/dashboard/.dev.vars`: + ``` + DEV_TUNNEL_URL=https://abc123.ngrok-free.app + ``` +4. In your GitHub App settings, set **Webhook URL** to: + ``` + https://abc123.ngrok-free.app/api/webhooks/github + ``` +5. Generate a **Webhook secret** and set the same value in both GitHub and your `.dev.vars` +6. Restart the dev server - Open [http://localhost:3000](http://localhost:3000) in your browser. - +The dev server uses `DEV_TUNNEL_URL` to allow the tunnel host and configure HMR correctly. ## Scripts @@ -175,6 +199,62 @@ A fast, design-first GitHub dashboard for developers who want to stay on top of | `pnpm check-types` | Type-check all packages | | `pnpm format` | Format code with Biome | +### Dashboard-specific scripts + +| Command | Description | +|---------|------------| +| `pnpm --filter dashboard migrate` | Run D1 migrations (local) | +| `pnpm --filter dashboard migrate:remote` | Run D1 migrations (remote) | +| `pnpm --filter dashboard test` | Run tests | +| `pnpm --filter dashboard deploy` | Build and deploy to Cloudflare Workers | + +## GitHub App Permissions Reference + +Expanding permissions after users have installed the app will require those installations to approve the new permission set. + +
+Full permissions table with roadmap context + +| Roadmap area | Permission | Level | Notes | +|---|---|---|---| +| Auth | User `Email addresses` | Read-only | Resolves the user's email for Better Auth | +| Core dashboard | Repository `Metadata` | Read-only | Baseline for repository-aware reads | +| Pull requests | Repository `Pull requests` | Read & write | PR mutations, reviews, and management | +| Issues | Repository `Issues` | Read & write | Label mutations and issue workflows | +| CI status | Repository `Checks` | Read-only | PR status checks display | +| GitHub Actions | Repository `Actions` | Read-only | Workflow run history and logs (upgrade to Read & write for rerun/cancel) | +| Collaborators | Organization `Members` | Read-only | Reviewer pickers with team support | +| Repo content | Repository `Contents` | Read & write | File browser, branch operations | +| Workflow files | Repository `Workflows` | Read & write | Editing workflow definitions (future) | +| Search | — | N/A | Inherits from other permissions | +| Notifications | — | N/A | GitHub notifications API doesn't support App tokens; needs different strategy | + +
+ +
+Full webhook events table + +| Event | Enable now | Why | +|---|---|---| +| Check run | Yes | PR status and check cache freshness | +| Check suite | Yes | Suite-level CI state for PR refreshes | +| Issue comment | Yes | Issue and PR comment views | +| Issues | Yes | Issue metadata changes | +| Pull request | Yes | Core PR invalidation | +| Pull request review | Yes | Review state and PR detail | +| Pull request review comment | Yes | Diff discussion and review comments | +| Pull request review thread | Yes | Review thread state changes | +| Workflow run | Later | For Actions dashboard (workflow-run updates) | +| Workflow job | Later | For Actions dashboard (job-level logs) | +| Push | Later | Branch-aware activity features | +| Repository | Later | Repo settings and metadata changes | +| Create | Later | Branch/tag creation flows | +| Delete | Later | Branch/tag deletion flows | + +Events marked "Later" are harmless to enable now — the app will ignore them until handlers are added. + +
+ ## Roadmap ### Dashboard diff --git a/apps/dashboard/.dev.vars.example b/apps/dashboard/.dev.vars.example index 858759e..b1d4674 100644 --- a/apps/dashboard/.dev.vars.example +++ b/apps/dashboard/.dev.vars.example @@ -1,48 +1,101 @@ -# GitHub OAuth App credentials (used for user authentication) -# 1. Go to https://github.com/settings/developers > OAuth Apps > New OAuth App -# 2. Set the callback URL to http://localhost:3000/api/auth/callback/github -# 3. Note the Client ID and generate a Client Secret -# OAuth App tokens support scopes (repo, read:org, user:email) and don't expire. -# Used for login plus public/external repository reads where the GitHub App is not installed. +# ============================================================================= +# DiffKit — Local Development Environment Variables +# ============================================================================= +# Copy this file to .dev.vars and fill in the values. +# NEVER commit .dev.vars — it contains secrets. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# 1. GitHub OAuth App (user authentication) +# ----------------------------------------------------------------------------- +# Creates user sessions and provides broad-scope reads (repo, read:org, user:email). +# Also used as fallback for repositories where the GitHub App is not installed. +# +# How to get these: +# 1. Go to https://github.com/settings/developers → OAuth Apps → New OAuth App +# 2. Set "Authorization callback URL" to http://localhost:3000/api/auth/callback/github +# 3. Copy the Client ID below +# 4. Generate a Client Secret and copy it below GITHUB_OAUTH_CLIENT_ID= GITHUB_OAUTH_CLIENT_SECRET= -# GitHub App credentials (used for installation discovery and app-scoped repo access) -# 1. Go to https://github.com/settings/apps -# 2. Create a new GitHub App (or use an existing one) -# 3. Set the callback URL to http://localhost:3000/api/github/app/callback -# 4. Set the setup URL to http://localhost:3000/?show-org-setup=true -# 5. Enable "Redirect on update" -# 6. Leave "Request user authorization (OAuth) during installation" unchecked -# 7. Under Permissions & events, grant the permissions listed in the README -# 8. Install the app on the repositories or organizations you want DiffKit to access +# Legacy aliases — still supported as a fallback during migration. +# You only need to set one pair (GITHUB_OAUTH_* or GITHUB_*), not both. +GITHUB_CLIENT_ID= +GITHUB_CLIENT_SECRET= + +# ----------------------------------------------------------------------------- +# 2. GitHub App (webhooks, installation tokens, app-scoped repo access) +# ----------------------------------------------------------------------------- +# Provides installation tokens for repos where the app is installed, +# user-to-server tokens for installation discovery, and webhook delivery. +# +# How to get these: +# 1. Go to https://github.com/settings/apps → New GitHub App +# 2. Set "Callback URL" to http://localhost:3000/api/github/app/callback +# 3. Set "Setup URL" to http://localhost:3000/?show-org-setup=true +# 4. Check "Redirect on update" +# 5. Leave "Request user authorization (OAuth) during installation" UNCHECKED +# 6. Grant the permissions listed in the README +# 7. Subscribe to the webhook events listed in the README +# 8. Install the app on your repos or orgs + +# Client ID shown on the GitHub App settings page (starts with "Iv1.") GITHUB_APP_CLIENT_ID= + +# Client secret — generate one from the GitHub App settings page GITHUB_APP_CLIENT_SECRET= -# Numeric App ID from the GitHub App settings page + +# Numeric App ID shown at the top of the GitHub App settings page GITHUB_APP_ID= -# Private key generated from the GitHub App settings page. -# Store as a quoted value with escaped newlines: -# GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----\n" -# GitHub commonly downloads PKCS#1 ("BEGIN RSA PRIVATE KEY"); DiffKit normalizes it for Octokit at runtime. + +# Private key for signing JWTs to authenticate as the GitHub App. +# Generate one from the GitHub App settings page → "Private keys" → "Generate a private key". +# Store as a single-line value with literal \n for newlines: +# GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nMIIE...\n-----END RSA PRIVATE KEY-----\n" +# +# Quick conversion from the downloaded .pem file: +# awk 'NF {printf "%s\\n", $0}' /path/to/key.pem +# +# GitHub downloads PKCS#1 keys ("BEGIN RSA PRIVATE KEY"); DiffKit auto-converts +# to PKCS#8 at runtime — no manual conversion needed. GITHUB_APP_PRIVATE_KEY= -# The slug from your GitHub App URL (https://github.com/apps/) + +# The slug from your GitHub App URL: https://github.com/apps/ GITHUB_APP_SLUG= -# GitHub webhook secret used to verify deliveries to /api/webhooks/github -# For local development, point your GitHub App webhook URL at a tunnel that forwards here. +# ----------------------------------------------------------------------------- +# 3. Webhooks +# ----------------------------------------------------------------------------- +# Secret used to verify webhook payloads from GitHub (HMAC-SHA256). +# Set the same value in your GitHub App settings under "Webhook secret". +# +# Generate one with: openssl rand -hex 20 GITHUB_WEBHOOK_SECRET= -# Optional: full tunnel URL used by Vite dev server to allow webhook traffic and HMR -# Example: https://your-subdomain.ngrok-free.app -DEV_TUNNEL_URL= - -# Legacy OAuth-style names are still supported as a fallback for GITHUB_OAUTH_* during migration. -GITHUB_CLIENT_ID= -GITHUB_CLIENT_SECRET= - -# Random secret for encrypting sessions (at least 32 characters) +# ----------------------------------------------------------------------------- +# 4. Auth & sessions +# ----------------------------------------------------------------------------- +# Random secret used by Better Auth to encrypt session cookies. +# Must be at least 32 characters. +# # Generate one with: openssl rand -base64 32 BETTER_AUTH_SECRET= -# Base URL for the auth server +# Base URL where DiffKit is running. Used by Better Auth for redirects. BETTER_AUTH_URL=http://localhost:3000 + +# ----------------------------------------------------------------------------- +# 5. Local development (optional) +# ----------------------------------------------------------------------------- +# Public tunnel URL for receiving webhooks locally (e.g. ngrok, cloudflared). +# The dev server uses this to allow the tunnel host and configure HMR. +# +# Example: https://your-subdomain.ngrok-free.app +# +# To set up: +# 1. Run your tunnel: ngrok http 3000 +# 2. Copy the public URL here +# 3. Set the same URL as the webhook URL in your GitHub App settings, +# appending /api/webhooks/github +DEV_TUNNEL_URL=