From e0563b035b09c1347a6bfeb068edc63e79d513a8 Mon Sep 17 00:00:00 2001 From: Daniil Pokrovsky Date: Mon, 17 Aug 2026 15:20:59 +0700 Subject: [PATCH 1/3] docs(code): clarify GitHub token vs App credentials GITHUB_TOKEN and GitHub App credentials are complementary, not interchangeable. Update env examples and docs so it is obvious which each is required for, and that precedence differs between CLI (token-first) and worker --listen (App-first). --- docs/code/configuration.md | 36 +++++++++++++---- docs/code/github-integration.md | 4 +- docs/code/github-issues-integration.md | 6 ++- docs/code/worker.md | 4 +- docs/code/workspaces.md | 4 +- packages/code/.env.example | 51 ++++++++++++++----------- packages/code/CLAUDE.md | 5 ++- packages/code/ENV_SETUP.md | 42 ++++++++++++++------ packages/code/USAGE.md | 10 ++--- packages/code/src/lib/init-scaffold.ts | 44 ++++++++++++--------- packages/code/src/lib/workspace/init.ts | 5 ++- 11 files changed, 134 insertions(+), 77 deletions(-) diff --git a/docs/code/configuration.md b/docs/code/configuration.md index 56d3f60..b2cb5f3 100644 --- a/docs/code/configuration.md +++ b/docs/code/configuration.md @@ -4,7 +4,7 @@ sidebarLabel: "Configuration" description: "Environment variables, settings.json, tracker credentials, and agent harness options for @devintern/code." section: "Code" order: 2 -dateModified: 2026-08-08 +dateModified: 2026-08-17 --- # @devintern/code Configuration @@ -81,37 +81,57 @@ MARKDOWN_TASKS_DIR=/path/to/tasks You can also pass file paths directly as arguments without setting `TASK_TRACKER=markdown` at all. In that mode no `.devintern-code/.env` is needed for tracker credentials. See the [Markdown File Tasks guide](./markdown-tasks.md) for details. -## Optional PR Integration +## GitHub authentication -Choose one authentication method for pull request creation: +`GITHUB_TOKEN` (a personal access token) and GitHub App credentials (`GITHUB_APP_ID` plus a private key) are complementary. They are not drop-in replacements for each other. + +| What you want | Need | +| --- | --- | +| Implement tickets and open PRs from the CLI | `GITHUB_TOKEN` **or** a GitHub App | +| Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | +| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | +| `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | +| Commits attributed to `slug[bot]` | GitHub App | + +Set both when you run mention-driven automation and also use GitHub Issues as a tracker. See [GitHub Issues Integration](./github-issues-integration.md) and [GitHub Integration](./github-integration.md). + +**Precedence when both are set:** + +- CLI and PR creation use `GITHUB_TOKEN` +- `devintern worker --listen` and the webhook server prefer the App so the bot identity (`slug[bot]`) resolves + +Do not set `GITHUB_APP_ID` without `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_PRIVATE_KEY_BASE64`. The ID alone is ignored for auth, but the worker treats it as "GitHub credentials present." ### GitHub Personal Access Token -For individual users: +For individual users and for `TASK_TRACKER=github`: ```bash GITHUB_TOKEN=your-github-token ``` - **Classic token**: Requires `repo` scope -- **Fine-grained token** (recommended): Requires `Pull requests: Read and write` and `Contents: Read` permissions +- **Fine-grained token** (recommended): Requires `Pull requests: Read and write` and `Contents: Read` permissions. Add `Issues: Read and write` when `TASK_TRACKER=github` - Create at: [https://github.com/settings/tokens](https://github.com/settings/tokens) ### GitHub App Authentication -For organizations: +For organizations, and for anyone who wants `@mention` matching or `slug[bot]` commit attribution: ```bash GITHUB_APP_ID=123456 GITHUB_APP_PRIVATE_KEY_PATH=/secure/path/to/your-app.private-key.pem ``` +Both the ID and a private key are required. + **Benefits:** -- No individual tokens needed +- No individual tokens needed for PR creation - Fine-grained permissions - Centralized control - Audit trail +- Resolves the bot identity required for `@mention` matching **Setup steps:** @@ -122,7 +142,7 @@ GITHUB_APP_PRIVATE_KEY_PATH=/secure/path/to/your-app.private-key.pem 3. Generate and save a private key 4. Install the App on your repositories -> These permissions cover task implementation and PR creation. If you also run the webhook server to auto-address PR feedback, that App needs additional **Pull request review comments** and **Issue comments** permissions plus event subscriptions; see [GitHub Integration](./github-integration.md#update-app-permissions). +> These permissions cover task implementation and PR creation. If you also run the webhook server or mention sweep to auto-address PR feedback, that App needs additional **Pull request review comments** and **Issue comments** permissions plus event subscriptions; see [GitHub Integration](./github-integration.md#update-app-permissions). For CI/CD environments, you can use a base64-encoded key: diff --git a/docs/code/github-integration.md b/docs/code/github-integration.md index 98bee47..6c716f2 100644 --- a/docs/code/github-integration.md +++ b/docs/code/github-integration.md @@ -3,7 +3,7 @@ title: "GitHub Integration" description: "Deploy the @devintern/code webhook server for automated PR review handling" section: "Server Automation" order: 4 -dateModified: 2026-07-03 +dateModified: 2026-08-17 --- # GitHub Integration Guide @@ -69,7 +69,7 @@ Inline review comments are processed _as a batch_ with their parent review — t ## Prerequisites -1. **GitHub App** configured with webhook permissions +1. **GitHub App** (`GITHUB_APP_ID` + private key) configured with webhook permissions — required for `@mention` matching and `slug[bot]` commit attribution. A `GITHUB_TOKEN` alone still lets the server call the API, but mention-gated triggers will not fire. See [Configuration](./configuration.md#github-authentication). 2. **Webhook Secret** - a random string for request verification 3. **Agent Harness CLI** installed and configured 4. **Git credentials** with push access to target repositories diff --git a/docs/code/github-issues-integration.md b/docs/code/github-issues-integration.md index 9e3bab1..d13b454 100644 --- a/docs/code/github-issues-integration.md +++ b/docs/code/github-issues-integration.md @@ -4,7 +4,7 @@ sidebarLabel: "GitHub Issues Integration" description: "Fetch GitHub issues, track status labels, implement with your coding agent, and open the PR in the same repository." section: "Code" order: 5 -dateModified: 2026-07-23 +dateModified: 2026-08-17 tags: ["github", "github-issues", "devintern/code", "integration"] --- @@ -39,6 +39,8 @@ GITHUB_REPO=owner/repo The same `GITHUB_TOKEN` used for pull request creation works here. It needs the `repo` scope (classic token) or `Issues: Read and write` plus `Pull requests: Read and write` (fine-grained token). `GITHUB_REPO` is the repository whose issues you want to implement, in `owner/repo` form. +GitHub App credentials (`GITHUB_APP_ID` + private key) cannot substitute for this tracker. The Issues client only accepts `GITHUB_TOKEN`. Keep the App as well if you want `@mention` matching or `slug[bot]` commit attribution; see [Configuration](./configuration.md#github-authentication). + ### 3. Configure status labels GitHub has no built-in workflow states, so @devintern/code maps statuses to labels. Create the labels in your repository, then configure them in `.devintern-code/settings.json` using `owner/repo` as the project key: @@ -111,7 +113,7 @@ GitHub Issues has no estimation field, so `--estimate` runs in comment-only mode **"Missing required GitHub environment variables"** -Ensure `GITHUB_TOKEN` and `GITHUB_REPO` are set in `.devintern-code/.env`. +Ensure `GITHUB_TOKEN` and `GITHUB_REPO` are set in `.devintern-code/.env`. A GitHub App ID and private key are not enough for this tracker. **"Label \"In Progress\" not found in the repository"** diff --git a/docs/code/worker.md b/docs/code/worker.md index e4a3f9e..b8385c5 100644 --- a/docs/code/worker.md +++ b/docs/code/worker.md @@ -3,7 +3,7 @@ title: "Worker Daemon" description: "Run devintern as a single long-running worker that reacts to PR reviews and tracker changes" section: "Server Automation" order: 0 -dateModified: 2026-08-04 +dateModified: 2026-08-17 --- # Worker Daemon @@ -106,7 +106,7 @@ Guardrails apply before the agent acts: - The worker never force-pushes; if a human pushed to the branch meanwhile, the push is rejected instead of overwriting. - Mentions posted before the worker first started are not dug up. -Mention matching requires a resolvable bot identity, so this feature needs GitHub App auth (the same requirement as webhook mention handling). +Mention matching requires a resolvable bot identity, so this feature needs GitHub App auth (`GITHUB_APP_ID` plus a private key — the same requirement as webhook mention handling). A `GITHUB_TOKEN` alone is enough for review polling on the agent's own PRs, but not for `@mentions` on other people's PRs. See [Configuration](./configuration.md#github-authentication). ## How events are handled diff --git a/docs/code/workspaces.md b/docs/code/workspaces.md index 88c8c88..1619a4c 100644 --- a/docs/code/workspaces.md +++ b/docs/code/workspaces.md @@ -3,7 +3,7 @@ title: "Workspaces (Multi-Repo Fleet)" description: "Drive many repositories with one devintern worker: a single workspace.toml, routing rules, and per-task worktrees" section: "Server Automation" order: 1 -dateModified: 2026-07-04 +dateModified: 2026-08-17 --- # Workspaces (Multi-Repo Fleet) @@ -78,7 +78,7 @@ devintern workspace import ## Environment -Secrets live in one shared `~/.devintern/.env` (tracker credentials, `GITHUB_TOKEN`, agent settings). Each repo can layer more on top: +Secrets live in one shared `~/.devintern/.env` (tracker credentials, `GITHUB_TOKEN` and/or GitHub App credentials, agent settings). Each repo can layer more on top: 1. Shared workspace `.env` 2. The repo's `env_file` (if set) diff --git a/packages/code/.env.example b/packages/code/.env.example index 25745fa..1fd4d24 100644 --- a/packages/code/.env.example +++ b/packages/code/.env.example @@ -26,9 +26,10 @@ JIRA_API_TOKEN=your-api-token-here # LINEAR_API_KEY=lin_api_xxxxxxxxxxxx # GitHub Issues Configuration (required when TASK_TRACKER=github) -# Reuses GITHUB_TOKEN from the Pull Request Integration section below -# (the token needs the 'repo' scope, or 'Issues: Read and write' for -# fine-grained tokens). Additionally set the target repository: +# Needs a personal access token — GitHub App credentials cannot substitute. +# The same GITHUB_TOKEN is used for pull request creation below +# (classic: 'repo' scope; fine-grained: Issues + Pull requests Read/write). +# GITHUB_TOKEN=your-github-token-here # GITHUB_REPO=owner/repo # Optional: comma-separated status label names treated as mutually exclusive. # When transitioning an issue, other labels in this list are removed. @@ -104,32 +105,38 @@ AGENT_HARNESS=claude-code # Optional: Enable verbose logging by default # VERBOSE=true -# Optional: Pull Request Integration +# Optional: GitHub authentication (PRs, worker reviews, @mentions) # -# Option 1: GitHub Personal Access Token (for individual users) -# Create at: https://github.com/settings/tokens -# Required permissions: -# - Classic token: 'repo' scope (or 'public_repo' for public repos only) -# - Fine-grained token (recommended): 'Pull requests: Read and write' + 'Contents: Read' -# GITHUB_TOKEN=your-github-token-here +# GITHUB_TOKEN and GitHub App credentials are complementary, not alternatives. # -# Option 2: GitHub App Authentication (for organizations) -# Each organization creates their own GitHub App for centralized control. -# Create at: https://github.com/settings/apps (or your org's settings) -# Required App permissions: -# - Repository permissions: -# - Contents: Read (to check branches) -# - Pull requests: Read and write (to create PRs) -# After creating the App, generate a private key and install the App on your repositories. +# GITHUB_TOKEN (personal access token) +# Required for TASK_TRACKER=github (Issues). App credentials cannot substitute. +# Enough for CLI task implementation, --create-pr, and worker review +# polling on the agent's own PRs. +# Create at: https://github.com/settings/tokens +# Classic: 'repo' scope (or 'public_repo' for public repos only) +# Fine-grained: 'Pull requests: Read and write' + 'Contents: Read' +# (add 'Issues: Read and write' when TASK_TRACKER=github) +# GITHUB_TOKEN=your-github-token-here # +# GitHub App (GITHUB_APP_ID + private key) +# Required for @mention matching on any PR (worker mention sweep and +# webhook / `devintern worker --listen`) and for slug[bot] commit attribution. +# Also creates PRs when no GITHUB_TOKEN is set. +# Both GITHUB_APP_ID and a private key are required; ID alone is ignored. +# Create at: https://github.com/settings/apps (or your org's settings) +# Install the App on your repositories after generating a private key. +# Permissions: Contents (Read), Pull requests (Read and write). +# Mentions/webhooks also need review-comment + issue-comment permissions: +# https://devintern.com/docs/code/github-integration # GITHUB_APP_ID=123456 -# Private key can be provided as a file path: # GITHUB_APP_PRIVATE_KEY_PATH=/path/to/your-app.private-key.pem -# Or as base64-encoded content (useful for CI/CD environments): -# To encode: base64 -i your-key.pem (macOS) or base64 -w 0 your-key.pem (Linux) +# Or base64 (CI/CD): base64 -i your-key.pem (macOS) / base64 -w 0 (Linux) # GITHUB_APP_PRIVATE_KEY_BASE64=LS0tLS1CRUdJTi4uLg== # -# Note: If both GITHUB_TOKEN and GitHub App credentials are set, GITHUB_TOKEN takes precedence. +# Precedence when both are set: +# CLI / PR creation: GITHUB_TOKEN is used. +# worker --listen / webhook server: the App is used (bot identity). # Bitbucket app password for creating pull requests # Create at: https://bitbucket.org/account/settings/app-passwords/ diff --git a/packages/code/CLAUDE.md b/packages/code/CLAUDE.md index 3d8a5f9..0696021 100644 --- a/packages/code/CLAUDE.md +++ b/packages/code/CLAUDE.md @@ -30,12 +30,13 @@ This file provides guidance to Claude Code when working with this repository. - `ASANA_API_TOKEN` - Asana personal access token (required when `TASK_TRACKER=asana`); optional `ASANA_DEFAULT_PROJECT_GID`, `ASANA_STORY_POINTS_FIELD` - `AZURE_DEVOPS_ORG`, `AZURE_DEVOPS_PAT`, `AZURE_DEVOPS_PROJECT` - Azure DevOps credentials (required when `TASK_TRACKER=azure-devops`) - `LINEAR_API_KEY` - Linear personal API key (required when `TASK_TRACKER=linear`) -- `GITHUB_REPO` - Target `owner/repo` for GitHub Issues (required when `TASK_TRACKER=github`; reuses `GITHUB_TOKEN`) +- `GITHUB_REPO` - Target `owner/repo` for GitHub Issues (required when `TASK_TRACKER=github`; requires `GITHUB_TOKEN`, App credentials cannot substitute) - `GITHUB_STATUS_LABELS` - Optional comma-separated mutually-exclusive status label names for GitHub transitions - `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` - JIRA credentials - `TRELLO_API_KEY`, `TRELLO_API_TOKEN` - Trello credentials (required when `TASK_TRACKER=trello`) - `TRELLO_DEFAULT_BOARD_ID` - Optional Trello board ID for settings lookup and status transitions -- `GITHUB_TOKEN` or `GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY_PATH` - GitHub auth +- `GITHUB_TOKEN` - GitHub PAT (required for `TASK_TRACKER=github`; enough for CLI PRs and own-PR review polling) +- `GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_PRIVATE_KEY_BASE64` - GitHub App (required for `@mention` matching and `slug[bot]` commits; CLI uses token first, worker `--listen` uses App first) - `BITBUCKET_TOKEN` - Bitbucket auth - `WEBHOOK_SECRET` - GitHub webhook verification - `DEVINTERN_OUTPUT_DIR` - Output directory (default: `/tmp/devintern-tasks`) diff --git a/packages/code/ENV_SETUP.md b/packages/code/ENV_SETUP.md index 5ebe336..e282157 100644 --- a/packages/code/ENV_SETUP.md +++ b/packages/code/ENV_SETUP.md @@ -49,13 +49,32 @@ Configure status transitions in `.devintern-code/settings.json` using the board } ``` -## Optional Environment Variables (PR Integration) +## Optional Environment Variables (GitHub / PR Integration) + +`GITHUB_TOKEN` (a personal access token) and GitHub App credentials (`GITHUB_APP_ID` plus a private key) are complementary. They are not drop-in replacements. + +| What you want | Need | +| --- | --- | +| Implement tickets and open PRs from the CLI | `GITHUB_TOKEN` **or** a GitHub App | +| Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | +| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | +| `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | +| Commits attributed to `slug[bot]` | GitHub App | + +Set both when you run mention-driven automation and also use GitHub Issues as a tracker. + +**Precedence when both are set:** + +- CLI and PR creation use `GITHUB_TOKEN` +- `devintern worker --listen` and the webhook server prefer the App so the bot identity resolves + +Do not set `GITHUB_APP_ID` without `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_PRIVATE_KEY_BASE64`. The ID alone is ignored for auth, but the worker treats it as "GitHub credentials present." ```bash -# Option 1: GitHub Personal Access Token (for individual users) +# Personal access token (required for TASK_TRACKER=github) GITHUB_TOKEN=your-github-token-here -# Option 2: GitHub App Authentication (for organizations) +# GitHub App (required for @mentions / slug[bot] attribution) GITHUB_APP_ID=123456 GITHUB_APP_PRIVATE_KEY_PATH=/path/to/private-key.pem # Or base64-encoded: GITHUB_APP_PRIVATE_KEY_BASE64=LS0tLS1CRUdJTi4uLg== @@ -66,7 +85,7 @@ BITBUCKET_TOKEN=your-bitbucket-token # For Bitbucket PR creation **Note:** Task tracker status transitions are configured per-project in `settings.json`. The file supports tracker-specific sections (e.g., `jira`, `linear`, `trello`) based on the `TASK_TRACKER` environment variable. -### Option 1: GitHub Personal Access Token +### GitHub Personal Access Token When creating a GitHub personal access token, you need the following permissions: @@ -79,6 +98,7 @@ When creating a GitHub personal access token, you need the following permissions - **Pull requests**: Read and write - **Contents**: Read (needed to read branch info for the PR) +- **Issues**: Read and write (only when `TASK_TRACKER=github`) To create a GitHub token: @@ -88,23 +108,25 @@ To create a GitHub token: 4. Grant the permissions listed above 5. Set the token as `GITHUB_TOKEN` in your `.env` file -### Option 2: GitHub App Authentication +### GitHub App Authentication -For organizations that want centralized control, create a GitHub App instead of using individual tokens. +For organizations that want centralized control, or anyone running mention-driven worker/webhook automation, create a GitHub App. -**Required App permissions:** +**Required App permissions (PR creation):** - **Contents**: Read (to check branches) - **Pull requests**: Read and write (to create PRs) +Mention matching and the webhook server also need **Pull request review comments** and **Issue comments**. See [GitHub Integration](https://devintern.com/docs/code/github-integration). + **Setup steps:** 1. Go to your organization's Settings → Developer settings → GitHub Apps → New GitHub App 2. Set repository permissions: Contents (Read), Pull requests (Read and write) -3. Disable webhooks (not needed) +3. Disable webhooks unless you are running `devintern worker --listen` 4. Generate a private key after creating the App 5. Install the App on your repositories -6. Configure in your `.env`: +6. Configure **both** the ID and the key in your `.env`: ```bash GITHUB_APP_ID=123456 GITHUB_APP_PRIVATE_KEY_PATH=/path/to/private-key.pem @@ -119,8 +141,6 @@ GITHUB_APP_PRIVATE_KEY_BASE64=LS0tLS1CRUdJTi4uLg== To encode: `base64 -i your-key.pem` (macOS) or `base64 -w 0 your-key.pem` (Linux) -**Note:** If both `GITHUB_TOKEN` and GitHub App credentials are set, `GITHUB_TOKEN` takes precedence. - ### Bitbucket Token Permissions When creating a Bitbucket app password: diff --git a/packages/code/USAGE.md b/packages/code/USAGE.md index 219393e..3121e94 100644 --- a/packages/code/USAGE.md +++ b/packages/code/USAGE.md @@ -54,10 +54,10 @@ JIRA_EMAIL=your-email@company.com JIRA_API_TOKEN=your-api-token-here # Optional: only set if the agent CLI is not on your PATH # AGENT_CLI_PATH=/custom/path/to/claude -# Optional: For automatic PR creation (see ENV_SETUP.md for details) -# Option 1: Personal access token +# Optional: GitHub auth (see ENV_SETUP.md — token and App are not interchangeable) +# GITHUB_TOKEN is required for TASK_TRACKER=github; enough for CLI PRs. +# GitHub App is required for @mentions / worker --listen (ID + private key). GITHUB_TOKEN=your-github-token-here -# Option 2: GitHub App (for organizations) # GITHUB_APP_ID=123456 # GITHUB_APP_PRIVATE_KEY_PATH=/path/to/private-key.pem # Bitbucket @@ -402,7 +402,7 @@ devintern MYAPP-456 - Detects repository platform from git remote URL - PR title format: `[TASK-123] Task Summary` - PR body includes Claude's implementation details and links back to JIRA -- GitHub: Requires `GITHUB_TOKEN` or GitHub App authentication (see ENV_SETUP.md) +- GitHub: Requires `GITHUB_TOKEN` or GitHub App authentication for PR creation (see ENV_SETUP.md). `@mention` matching on any PR needs the App. - Bitbucket: Requires `BITBUCKET_TOKEN` (`Repositories: Write`), workspace auto-detected from git remote - Can be enabled with `--create-pr` flag - Target branch can be specified with `--pr-target-branch` (defaults to 'main') @@ -501,7 +501,7 @@ The same idea works for Linear using a JSON `IssueFilter`. Wrap the JSON in sing 7. **"PR creation failed"** - Ensure you have the correct token configured: - - GitHub: `GITHUB_TOKEN` or GitHub App (`GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY_PATH`) + - GitHub: `GITHUB_TOKEN` or GitHub App (`GITHUB_APP_ID` + private key). `TASK_TRACKER=github` requires the token; `@mention` matching requires the App - Bitbucket: `BITBUCKET_TOKEN` - Check token/App permissions: - GitHub classic token: needs `repo` scope diff --git a/packages/code/src/lib/init-scaffold.ts b/packages/code/src/lib/init-scaffold.ts index 1b9ee09..c4a7227 100644 --- a/packages/code/src/lib/init-scaffold.ts +++ b/packages/code/src/lib/init-scaffold.ts @@ -172,32 +172,38 @@ AGENT_HARNESS=claude-code # Optional: Enable verbose logging by default # VERBOSE=true -# Optional: Pull Request Integration +# Optional: GitHub authentication (PRs, worker reviews, @mentions) # -# Option 1: GitHub Personal Access Token (for individual users) -# Create at: https://github.com/settings/tokens -# Required permissions: -# - Classic token: 'repo' scope (or 'public_repo' for public repos only) -# - Fine-grained token (recommended): 'Pull requests: Read and write' + 'Contents: Read' -# GITHUB_TOKEN=your-github-token-here +# GITHUB_TOKEN and GitHub App credentials are complementary, not alternatives. # -# Option 2: GitHub App Authentication (for organizations) -# Each organization creates their own GitHub App for centralized control. -# Create at: https://github.com/settings/apps (or your org's settings) -# Required App permissions: -# - Repository permissions: -# - Contents: Read (to check branches) -# - Pull requests: Read and write (to create PRs) -# After creating the App, generate a private key and install the App on your repositories. +# GITHUB_TOKEN (personal access token) +# Required for TASK_TRACKER=github (Issues). App credentials cannot substitute. +# Enough for CLI task implementation, --create-pr, and worker review +# polling on the agent's own PRs. +# Create at: https://github.com/settings/tokens +# Classic: 'repo' scope (or 'public_repo' for public repos only) +# Fine-grained: 'Pull requests: Read and write' + 'Contents: Read' +# (add 'Issues: Read and write' when TASK_TRACKER=github) +# GITHUB_TOKEN=your-github-token-here # +# GitHub App (GITHUB_APP_ID + private key) +# Required for @mention matching on any PR (worker mention sweep and +# webhook / devintern worker --listen) and for slug[bot] commit attribution. +# Also creates PRs when no GITHUB_TOKEN is set. +# Both GITHUB_APP_ID and a private key are required; ID alone is ignored. +# Create at: https://github.com/settings/apps (or your org's settings) +# Install the App on your repositories after generating a private key. +# Permissions: Contents (Read), Pull requests (Read and write). +# Mentions/webhooks also need review-comment + issue-comment permissions: +# https://devintern.com/docs/code/github-integration # GITHUB_APP_ID=123456 -# Private key can be provided as a file path: # GITHUB_APP_PRIVATE_KEY_PATH=/path/to/your-app.private-key.pem -# Or as base64-encoded content (useful for CI/CD environments): -# To encode: base64 -i your-key.pem (macOS) or base64 -w 0 your-key.pem (Linux) +# Or base64 (CI/CD): base64 -i your-key.pem (macOS) / base64 -w 0 (Linux) # GITHUB_APP_PRIVATE_KEY_BASE64=LS0tLS1CRUdJTi4uLg== # -# Note: If both GITHUB_TOKEN and GitHub App credentials are set, GITHUB_TOKEN takes precedence. +# Precedence when both are set: +# CLI / PR creation: GITHUB_TOKEN is used. +# worker --listen / webhook server: the App is used (bot identity). # Bitbucket app password for creating pull requests # Create at: https://bitbucket.org/account/settings/app-passwords/ diff --git a/packages/code/src/lib/workspace/init.ts b/packages/code/src/lib/workspace/init.ts index bc9af36..39fbc8a 100644 --- a/packages/code/src/lib/workspace/init.ts +++ b/packages/code/src/lib/workspace/init.ts @@ -48,8 +48,9 @@ default_branch = "main" # labels = ["backend"] # any-of; AND-ed with the other criteria `; -const ENV_TEMPLATE = `# Shared workspace environment: tracker credentials, GITHUB_TOKEN, agent -# settings. Per-repo overrides go in [repos.env] in workspace.toml. +const ENV_TEMPLATE = `# Shared workspace environment: tracker credentials, GITHUB_TOKEN and/or +# GitHub App (GITHUB_APP_ID + private key), agent settings. +# Per-repo overrides go in [repos.env] in workspace.toml. `; /** Values that should never migrate into the shared workspace env. */ From 634226d47ce2903476722c5a42e5fa1a5a7e5bc8 Mon Sep 17 00:00:00 2001 From: Daniil Pokrovsky Date: Mon, 17 Aug 2026 15:24:29 +0700 Subject: [PATCH 2/3] docs(code): frame GitHub token as personal, App as team/automation Lead GitHub auth docs with the product split that matches pricing: GITHUB_TOKEN for free interactive CLI use, GitHub App for team and unattended automation. Keep the capability table so Issues still requires a token and LICENSE_KEY stays the automation license gate. --- docs/code/configuration.md | 12 ++++++++---- docs/code/github-integration.md | 2 +- docs/code/github-issues-integration.md | 2 +- docs/code/worker.md | 2 +- packages/code/.env.example | 19 ++++++++++++------- packages/code/CLAUDE.md | 4 ++-- packages/code/ENV_SETUP.md | 12 ++++++++---- packages/code/USAGE.md | 8 ++++---- packages/code/src/lib/init-scaffold.ts | 16 ++++++++++------ 9 files changed, 47 insertions(+), 30 deletions(-) diff --git a/docs/code/configuration.md b/docs/code/configuration.md index b2cb5f3..0d810a8 100644 --- a/docs/code/configuration.md +++ b/docs/code/configuration.md @@ -83,11 +83,15 @@ You can also pass file paths directly as arguments without setting `TASK_TRACKER ## GitHub authentication -`GITHUB_TOKEN` (a personal access token) and GitHub App credentials (`GITHUB_APP_ID` plus a private key) are complementary. They are not drop-in replacements for each other. +**Personal / interactive:** a `GITHUB_TOKEN` (personal access token). That is enough for free CLI use from your terminal (`devintern TICKET-123`, `--create-pr`). + +**Team / unattended automation:** a GitHub App (`GITHUB_APP_ID` plus a private key). That is what `@mention` matching, `devintern worker --listen` / webhooks, and `slug[bot]` commit attribution need so the bot has a shared team identity. Unattended runs also need a `LICENSE_KEY`. See [Pricing](https://devintern.com/pricing/). + +The two credentials are complementary, not drop-in replacements. A team setup that also uses GitHub Issues as the tracker still needs `GITHUB_TOKEN`. | What you want | Need | | --- | --- | -| Implement tickets and open PRs from the CLI | `GITHUB_TOKEN` **or** a GitHub App | +| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` **or** a GitHub App | | Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | | Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | | `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | @@ -104,7 +108,7 @@ Do not set `GITHUB_APP_ID` without `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_ ### GitHub Personal Access Token -For individual users and for `TASK_TRACKER=github`: +For personal / interactive CLI use, and for `TASK_TRACKER=github`: ```bash GITHUB_TOKEN=your-github-token @@ -116,7 +120,7 @@ GITHUB_TOKEN=your-github-token ### GitHub App Authentication -For organizations, and for anyone who wants `@mention` matching or `slug[bot]` commit attribution: +For team / unattended automation (`@mention` matching, webhook / `worker --listen`, `slug[bot]` commit attribution): ```bash GITHUB_APP_ID=123456 diff --git a/docs/code/github-integration.md b/docs/code/github-integration.md index 6c716f2..a22cdea 100644 --- a/docs/code/github-integration.md +++ b/docs/code/github-integration.md @@ -69,7 +69,7 @@ Inline review comments are processed _as a batch_ with their parent review — t ## Prerequisites -1. **GitHub App** (`GITHUB_APP_ID` + private key) configured with webhook permissions — required for `@mention` matching and `slug[bot]` commit attribution. A `GITHUB_TOKEN` alone still lets the server call the API, but mention-gated triggers will not fire. See [Configuration](./configuration.md#github-authentication). +1. **GitHub App** (`GITHUB_APP_ID` + private key) configured with webhook permissions — the team / unattended-automation credential, required for `@mention` matching and `slug[bot]` commit attribution. A personal `GITHUB_TOKEN` still lets the server call the API, but mention-gated triggers will not fire. See [Configuration](./configuration.md#github-authentication) and [Pricing](https://devintern.com/pricing/). 2. **Webhook Secret** - a random string for request verification 3. **Agent Harness CLI** installed and configured 4. **Git credentials** with push access to target repositories diff --git a/docs/code/github-issues-integration.md b/docs/code/github-issues-integration.md index d13b454..db1d708 100644 --- a/docs/code/github-issues-integration.md +++ b/docs/code/github-issues-integration.md @@ -39,7 +39,7 @@ GITHUB_REPO=owner/repo The same `GITHUB_TOKEN` used for pull request creation works here. It needs the `repo` scope (classic token) or `Issues: Read and write` plus `Pull requests: Read and write` (fine-grained token). `GITHUB_REPO` is the repository whose issues you want to implement, in `owner/repo` form. -GitHub App credentials (`GITHUB_APP_ID` + private key) cannot substitute for this tracker. The Issues client only accepts `GITHUB_TOKEN`. Keep the App as well if you want `@mention` matching or `slug[bot]` commit attribution; see [Configuration](./configuration.md#github-authentication). +GitHub App credentials (`GITHUB_APP_ID` + private key) cannot substitute for this tracker. The Issues client only accepts `GITHUB_TOKEN`. Use a token for personal / interactive CLI use; add the App for team / unattended automation (`@mention` matching, `slug[bot]` commits). See [Configuration](./configuration.md#github-authentication) and [Pricing](https://devintern.com/pricing/). ### 3. Configure status labels diff --git a/docs/code/worker.md b/docs/code/worker.md index b8385c5..21b12c9 100644 --- a/docs/code/worker.md +++ b/docs/code/worker.md @@ -106,7 +106,7 @@ Guardrails apply before the agent acts: - The worker never force-pushes; if a human pushed to the branch meanwhile, the push is rejected instead of overwriting. - Mentions posted before the worker first started are not dug up. -Mention matching requires a resolvable bot identity, so this feature needs GitHub App auth (`GITHUB_APP_ID` plus a private key — the same requirement as webhook mention handling). A `GITHUB_TOKEN` alone is enough for review polling on the agent's own PRs, but not for `@mentions` on other people's PRs. See [Configuration](./configuration.md#github-authentication). +Mention matching requires a resolvable bot identity, so this team/automation feature needs GitHub App auth (`GITHUB_APP_ID` plus a private key — the same requirement as webhook mention handling). A personal `GITHUB_TOKEN` is enough for review polling on the agent's own PRs, but not for `@mentions` on other people's PRs. See [Configuration](./configuration.md#github-authentication) and [Pricing](https://devintern.com/pricing/). ## How events are handled diff --git a/packages/code/.env.example b/packages/code/.env.example index 1fd4d24..8e4363e 100644 --- a/packages/code/.env.example +++ b/packages/code/.env.example @@ -26,7 +26,8 @@ JIRA_API_TOKEN=your-api-token-here # LINEAR_API_KEY=lin_api_xxxxxxxxxxxx # GitHub Issues Configuration (required when TASK_TRACKER=github) -# Needs a personal access token — GitHub App credentials cannot substitute. +# Needs a personal access token (personal / interactive) — GitHub App +# credentials cannot substitute. # The same GITHUB_TOKEN is used for pull request creation below # (classic: 'repo' scope; fine-grained: Issues + Pull requests Read/write). # GITHUB_TOKEN=your-github-token-here @@ -107,12 +108,15 @@ AGENT_HARNESS=claude-code # Optional: GitHub authentication (PRs, worker reviews, @mentions) # -# GITHUB_TOKEN and GitHub App credentials are complementary, not alternatives. +# Personal / interactive (free CLI): GITHUB_TOKEN +# Team / unattended automation: GitHub App (GITHUB_APP_ID + private key) +# See https://devintern.com/pricing/ +# Complementary, not alternatives. Unattended runs also need LICENSE_KEY. # # GITHUB_TOKEN (personal access token) -# Required for TASK_TRACKER=github (Issues). App credentials cannot substitute. -# Enough for CLI task implementation, --create-pr, and worker review -# polling on the agent's own PRs. +# Personal / interactive CLI use, and required for TASK_TRACKER=github +# (Issues). App credentials cannot substitute. +# Enough for --create-pr and worker review polling on the agent's own PRs. # Create at: https://github.com/settings/tokens # Classic: 'repo' scope (or 'public_repo' for public repos only) # Fine-grained: 'Pull requests: Read and write' + 'Contents: Read' @@ -120,8 +124,9 @@ AGENT_HARNESS=claude-code # GITHUB_TOKEN=your-github-token-here # # GitHub App (GITHUB_APP_ID + private key) -# Required for @mention matching on any PR (worker mention sweep and -# webhook / `devintern worker --listen`) and for slug[bot] commit attribution. +# Team / unattended automation: @mention matching on any PR (worker +# mention sweep and webhook / `devintern worker --listen`) and slug[bot] +# commit attribution. # Also creates PRs when no GITHUB_TOKEN is set. # Both GITHUB_APP_ID and a private key are required; ID alone is ignored. # Create at: https://github.com/settings/apps (or your org's settings) diff --git a/packages/code/CLAUDE.md b/packages/code/CLAUDE.md index 0696021..bda1227 100644 --- a/packages/code/CLAUDE.md +++ b/packages/code/CLAUDE.md @@ -35,8 +35,8 @@ This file provides guidance to Claude Code when working with this repository. - `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` - JIRA credentials - `TRELLO_API_KEY`, `TRELLO_API_TOKEN` - Trello credentials (required when `TASK_TRACKER=trello`) - `TRELLO_DEFAULT_BOARD_ID` - Optional Trello board ID for settings lookup and status transitions -- `GITHUB_TOKEN` - GitHub PAT (required for `TASK_TRACKER=github`; enough for CLI PRs and own-PR review polling) -- `GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_PRIVATE_KEY_BASE64` - GitHub App (required for `@mention` matching and `slug[bot]` commits; CLI uses token first, worker `--listen` uses App first) +- `GITHUB_TOKEN` - Personal / interactive GitHub PAT (required for `TASK_TRACKER=github`; enough for free CLI PRs and own-PR review polling) +- `GITHUB_APP_ID` + `GITHUB_APP_PRIVATE_KEY_PATH` or `GITHUB_APP_PRIVATE_KEY_BASE64` - Team / unattended-automation GitHub App (required for `@mention` matching and `slug[bot]` commits; CLI uses token first, worker `--listen` uses App first). See https://devintern.com/pricing/ - `BITBUCKET_TOKEN` - Bitbucket auth - `WEBHOOK_SECRET` - GitHub webhook verification - `DEVINTERN_OUTPUT_DIR` - Output directory (default: `/tmp/devintern-tasks`) diff --git a/packages/code/ENV_SETUP.md b/packages/code/ENV_SETUP.md index e282157..aeadd32 100644 --- a/packages/code/ENV_SETUP.md +++ b/packages/code/ENV_SETUP.md @@ -51,11 +51,15 @@ Configure status transitions in `.devintern-code/settings.json` using the board ## Optional Environment Variables (GitHub / PR Integration) -`GITHUB_TOKEN` (a personal access token) and GitHub App credentials (`GITHUB_APP_ID` plus a private key) are complementary. They are not drop-in replacements. +**Personal / interactive:** a `GITHUB_TOKEN` (personal access token). Enough for free CLI use from your terminal. + +**Team / unattended automation:** a GitHub App (`GITHUB_APP_ID` plus a private key). Needed for `@mention` matching, `devintern worker --listen` / webhooks, and `slug[bot]` commit attribution. Unattended runs also need a `LICENSE_KEY`. See [Pricing](https://devintern.com/pricing/). + +The two credentials are complementary, not drop-in replacements. A team setup that also uses GitHub Issues as the tracker still needs `GITHUB_TOKEN`. | What you want | Need | | --- | --- | -| Implement tickets and open PRs from the CLI | `GITHUB_TOKEN` **or** a GitHub App | +| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` **or** a GitHub App | | Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | | Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | | `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | @@ -87,7 +91,7 @@ BITBUCKET_TOKEN=your-bitbucket-token # For Bitbucket PR creation ### GitHub Personal Access Token -When creating a GitHub personal access token, you need the following permissions: +For personal / interactive CLI use. When creating a GitHub personal access token, you need the following permissions: **Classic Personal Access Token:** @@ -110,7 +114,7 @@ To create a GitHub token: ### GitHub App Authentication -For organizations that want centralized control, or anyone running mention-driven worker/webhook automation, create a GitHub App. +For team / unattended automation (mention-driven worker, webhook / `worker --listen`, `slug[bot]` attribution), create a GitHub App. **Required App permissions (PR creation):** diff --git a/packages/code/USAGE.md b/packages/code/USAGE.md index 3121e94..e0c7cd2 100644 --- a/packages/code/USAGE.md +++ b/packages/code/USAGE.md @@ -54,9 +54,9 @@ JIRA_EMAIL=your-email@company.com JIRA_API_TOKEN=your-api-token-here # Optional: only set if the agent CLI is not on your PATH # AGENT_CLI_PATH=/custom/path/to/claude -# Optional: GitHub auth (see ENV_SETUP.md — token and App are not interchangeable) -# GITHUB_TOKEN is required for TASK_TRACKER=github; enough for CLI PRs. -# GitHub App is required for @mentions / worker --listen (ID + private key). +# Optional: GitHub auth (see ENV_SETUP.md) +# Personal / interactive (free CLI): GITHUB_TOKEN +# Team / unattended automation: GitHub App — https://devintern.com/pricing/ GITHUB_TOKEN=your-github-token-here # GITHUB_APP_ID=123456 # GITHUB_APP_PRIVATE_KEY_PATH=/path/to/private-key.pem @@ -501,7 +501,7 @@ The same idea works for Linear using a JSON `IssueFilter`. Wrap the JSON in sing 7. **"PR creation failed"** - Ensure you have the correct token configured: - - GitHub: `GITHUB_TOKEN` or GitHub App (`GITHUB_APP_ID` + private key). `TASK_TRACKER=github` requires the token; `@mention` matching requires the App + - GitHub: personal `GITHUB_TOKEN` or team/automation GitHub App (`GITHUB_APP_ID` + private key). `TASK_TRACKER=github` requires the token; `@mention` matching requires the App - Bitbucket: `BITBUCKET_TOKEN` - Check token/App permissions: - GitHub classic token: needs `repo` scope diff --git a/packages/code/src/lib/init-scaffold.ts b/packages/code/src/lib/init-scaffold.ts index c4a7227..5c341a0 100644 --- a/packages/code/src/lib/init-scaffold.ts +++ b/packages/code/src/lib/init-scaffold.ts @@ -174,12 +174,15 @@ AGENT_HARNESS=claude-code # Optional: GitHub authentication (PRs, worker reviews, @mentions) # -# GITHUB_TOKEN and GitHub App credentials are complementary, not alternatives. +# Personal / interactive (free CLI): GITHUB_TOKEN +# Team / unattended automation: GitHub App (GITHUB_APP_ID + private key) +# See https://devintern.com/pricing/ +# Complementary, not alternatives. Unattended runs also need LICENSE_KEY. # # GITHUB_TOKEN (personal access token) -# Required for TASK_TRACKER=github (Issues). App credentials cannot substitute. -# Enough for CLI task implementation, --create-pr, and worker review -# polling on the agent's own PRs. +# Personal / interactive CLI use, and required for TASK_TRACKER=github +# (Issues). App credentials cannot substitute. +# Enough for --create-pr and worker review polling on the agent's own PRs. # Create at: https://github.com/settings/tokens # Classic: 'repo' scope (or 'public_repo' for public repos only) # Fine-grained: 'Pull requests: Read and write' + 'Contents: Read' @@ -187,8 +190,9 @@ AGENT_HARNESS=claude-code # GITHUB_TOKEN=your-github-token-here # # GitHub App (GITHUB_APP_ID + private key) -# Required for @mention matching on any PR (worker mention sweep and -# webhook / devintern worker --listen) and for slug[bot] commit attribution. +# Team / unattended automation: @mention matching on any PR (worker +# mention sweep and webhook / devintern worker --listen) and slug[bot] +# commit attribution. # Also creates PRs when no GITHUB_TOKEN is set. # Both GITHUB_APP_ID and a private key are required; ID alone is ignored. # Create at: https://github.com/settings/apps (or your org's settings) From 5541c54cf26dc87afa040b9c4ab621e7837cd3f8 Mon Sep 17 00:00:00 2001 From: Daniil Pokrovsky Date: Mon, 17 Aug 2026 15:40:01 +0700 Subject: [PATCH 3/3] docs(code): personal CLI PRs need a token, not an App The capability table listed GitHub App as a personal-use option because the CLI can fall back to App auth. That is a team-setup side effect, not the path to recommend for interactive use. --- docs/code/configuration.md | 6 +++--- packages/code/ENV_SETUP.md | 4 ++-- packages/code/USAGE.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/code/configuration.md b/docs/code/configuration.md index 0d810a8..c86d525 100644 --- a/docs/code/configuration.md +++ b/docs/code/configuration.md @@ -91,9 +91,9 @@ The two credentials are complementary, not drop-in replacements. A team setup th | What you want | Need | | --- | --- | -| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` **or** a GitHub App | +| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` | | Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | -| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | +| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` (solo) or GitHub App (if already configured) | | `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | | Commits attributed to `slug[bot]` | GitHub App | @@ -131,7 +131,7 @@ Both the ID and a private key are required. **Benefits:** -- No individual tokens needed for PR creation +- Can create PRs without a personal token (team/automation setups) - Fine-grained permissions - Centralized control - Audit trail diff --git a/packages/code/ENV_SETUP.md b/packages/code/ENV_SETUP.md index aeadd32..075ffd9 100644 --- a/packages/code/ENV_SETUP.md +++ b/packages/code/ENV_SETUP.md @@ -59,9 +59,9 @@ The two credentials are complementary, not drop-in replacements. A team setup th | What you want | Need | | --- | --- | -| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` **or** a GitHub App | +| Implement tickets and open PRs from the CLI (personal) | `GITHUB_TOKEN` | | Use GitHub Issues as the task tracker (`TASK_TRACKER=github`) | `GITHUB_TOKEN` (the App cannot substitute) | -| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` **or** a GitHub App | +| Worker review polling on the agent's own PRs | `GITHUB_TOKEN` (solo) or GitHub App (if already configured) | | `@mention` the bot on any PR (worker sweep or webhook) | GitHub App (`GITHUB_APP_ID` + private key) | | Commits attributed to `slug[bot]` | GitHub App | diff --git a/packages/code/USAGE.md b/packages/code/USAGE.md index e0c7cd2..83e1a33 100644 --- a/packages/code/USAGE.md +++ b/packages/code/USAGE.md @@ -402,7 +402,7 @@ devintern MYAPP-456 - Detects repository platform from git remote URL - PR title format: `[TASK-123] Task Summary` - PR body includes Claude's implementation details and links back to JIRA -- GitHub: Requires `GITHUB_TOKEN` or GitHub App authentication for PR creation (see ENV_SETUP.md). `@mention` matching on any PR needs the App. +- GitHub: Requires `GITHUB_TOKEN` for personal CLI PR creation (see ENV_SETUP.md). A team GitHub App can also create PRs; `@mention` matching on any PR needs the App. - Bitbucket: Requires `BITBUCKET_TOKEN` (`Repositories: Write`), workspace auto-detected from git remote - Can be enabled with `--create-pr` flag - Target branch can be specified with `--pr-target-branch` (defaults to 'main')