Files
WeHub Mirror abf0e694a2
Hetzner Agent E2E / Provision + deploy + healthcheck (push) Has been cancelled
Hetzner Agent E2E / Teardown (push) Has been cancelled
Scenario PR E2E / Classify changed paths (push) Has been cancelled
Scenario PR E2E / Zero-Key unit + UI coverage (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser core (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser view lifecycle (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser all-pages (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser feature interactions (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser cloud keyless (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser ratcheted (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser auto-discovered specs (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser dashboard device matrix (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser Pixel-7 real-touch lane (push) Has been cancelled
Scenario PR E2E / Zero-Key app browser WebKit lane (push) Has been cancelled
Scenario PR E2E / Zero-Key accounts UI e2e (real API + pool + disk) (push) Has been cancelled
Scenario PR E2E / Zero-Key full-walkthrough (mock lane) (push) Has been cancelled
Scenario PR E2E / Zero-Key app diagnostics (push) Has been cancelled
Scenario PR E2E / Zero-Key scenario runner E2E (push) Has been cancelled
Scenario PR E2E / Zero-Key Deterministic E2E (push) Has been cancelled
Docker CI Smoke / Classify changed paths (push) Has been cancelled
Docker CI Smoke / Build production Docker image (+ smoke boot) (push) Has been cancelled
Build libelizainference (Android, FFI) / prepare-matrix (push) Has been cancelled
Chat shell gestures / Chat shell gesture + parity e2e (push) Has been cancelled
Cloud Gateway Discord / Test (push) Has been cancelled
Cloud Gateway Webhook / Test (push) Has been cancelled
Cloud Tests / lint-and-types (push) Has been cancelled
Cloud Tests / unit-tests (push) Has been cancelled
Build Agent Image / build-and-push (push) Has been cancelled
Electrobun Submodule Guard / electrobun gitlink is fetchable (push) Has been cancelled
gitleaks / gitleaks (push) Has been cancelled
Markdown Links / Relative Markdown Links (push) Has been cancelled
Orchestrator multi-account / multi-account selection e2e (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / verify_version (push) Has been cancelled
Quality (Extended) / Homepage Build (PR smoke) (push) Has been cancelled
Quality (Extended) / Comment-only diff guard (push) Has been cancelled
Quality (Extended) / Format (push) Has been cancelled
Quality (Extended) / Develop Gate (secret scan + UI determinism) (push) Has been cancelled
Quality (Extended) / Develop Gate (lint) (push) Has been cancelled
Sandbox Live Smoke / Sandbox live smoke (push) Has been cancelled
Snap Build & Test / Build Snap (amd64) (push) Has been cancelled
Snap Build & Test / Build Snap (arm64) (push) Has been cancelled
Tests / Classify changed paths (push) Has been cancelled
UI Extended Fixture E2E / fixture-e2e (push) Has been cancelled
Cloud Tests / integration-tests (push) Has been cancelled
CUDA Coverage Continuity / Fail-closed manifest contracts (push) Has been cancelled
CUDA Coverage Continuity / Exact-head CUDA fixtures + runtime graph (push) Has been cancelled
Deploy Apps Worker (Product 2) / Determine environment (push) Has been cancelled
Deploy Eliza Provisioning Worker / Determine environment (push) Has been cancelled
Deploy Homepage / build-and-deploy (push) Has been cancelled
Dev Smoke / Classify changed paths (push) Has been cancelled
Tests / Remote Capability Provider Live E2E (push) Has been cancelled
Training Stack / CPU smoke (lint + import) (push) Has been cancelled
Training Stack / GPU build (QJL nvcc + Triton JIT) (push) Has been cancelled
UI Core Fixture E2E / ui-core-fixture-e2e (push) Has been cancelled
vault-ci / app-core wiring tests (push) Has been cancelled
verify-patches / verify patches/CHECKSUMS.sha256 (push) Has been cancelled
UI Story Gate / story-gate (push) Has been cancelled
vault-ci / test (macos-latest) (push) Has been cancelled
vault-ci / test (ubuntu-latest) (push) Has been cancelled
vault-ci / test (windows-latest) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/app-core test bun run --cwd packages/elizaos test bun run --cwd packages/cloud/shared test], app-and-cli) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/core typecheck bun run --cwd packages/shared typecheck bun run --cwd packages/cloud/shared typecheck bun run --cwd packages/core test bun run --cwd packages/shared test], core-runtime, 75) (push) Has been cancelled
Windows CI / windows ([bun run --cwd packages/scenario-runner test bun run --cwd packages/vault test bun run --cwd plugins/plugin-coding-tools test], framework-packages) (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-coding-tools build node packages/scripts/run-turbo.mjs run build --filter=@elizaos/core --filter=@elizaos/shared --filter=@elizaos/agent --concurrency=1 node packages/scripts/run-python.mjs --version node packages… (push) Has been cancelled
Windows CI / windows ([bun run --cwd plugins/plugin-elizacloud test bun run --cwd plugins/plugin-discord test bun run --cwd plugins/plugin-anthropic test bun run --cwd plugins/plugin-openai test bun run --cwd plugins/plugin-app-control test bun run --cwd plugins/pl… (push) Has been cancelled
Cloud Tests / e2e-tests (push) Has been cancelled
Deploy Apps Worker (Product 2) / Deploy apps worker to apps-control host (${{ needs.determine-env.outputs.environment }}) (push) Has been cancelled
Deploy Eliza Provisioning Worker / Deploy worker to Hetzner host (${{ needs.determine-env.outputs.environment }} @ ${{ needs.determine-env.outputs.deployment_sha }}) (push) Has been cancelled
Dev Smoke / bun run dev onboarding chat (push) Has been cancelled
Dev Smoke / Vite HMR dependency-level smoke (push) Has been cancelled
Publish @elizaos/plugin-elizacloud / publish_npm (push) Has been cancelled
Tests / Test-runner vacuous-green guard (push) Has been cancelled
Tests / Server Tests (push) Has been cancelled
Tests / Client Tests (push) Has been cancelled
Tests / Plugin Tests (1/4) (push) Has been cancelled
Tests / Plugin Tests (2/4) (push) Has been cancelled
Tests / Plugin Tests (3/4) (push) Has been cancelled
Tests / Plugin Tests (4/4) (push) Has been cancelled
Tests / Plugin Tests (push) Has been cancelled
Tests / Integration Lane (personal-assistant) (push) Has been cancelled
Tests / Electrobun Desktop Contract (push) Has been cancelled
Tests / Zero-Key unit + UI coverage (push) Has been cancelled
Tests / Zero-Key app browser (push) Has been cancelled
Tests / Zero-Key diagnostics (push) Has been cancelled
Tests / Zero-Key scenario runner (push) Has been cancelled
Tests / Zero-Key harness E2E (push) Has been cancelled
Tests / Zero-Key Deterministic E2E (push) Has been cancelled
Build libelizainference (Android, FFI) / ${{ matrix.abi }} (push) Has been cancelled
Tests / Cloud Live E2E (Eliza Cloud) (push) Has been cancelled
Tests / Remote Capability GitHub Live Artifact Validator (push) Has been cancelled
Tests / Script Tests (Linux) (push) Has been cancelled
Tests / Merge Queue Quality Gate (push) Has been cancelled
Tests / ci-ok (push) Has been cancelled
WeHub snapshot of 9298cb46af86e1bd3a40a60e135ea855d70f229a
2026-08-07 16:49:07 +08:00

10 KiB

@elizaos/plugin-github

GitHub integration for Eliza agents: pull request listing and review, issue lifecycle management, and notification triage via the GitHub REST API.

Purpose / role

Adds GitHub capabilities to any Eliza agent. The plugin is opt-in — add "@elizaos/plugin-github" to the agent's plugin list. It registers a GitHubService (Octokit REST client pool), three exposed action handlers promoted under one umbrella GITHUB action, five API routes for credential management (PAT paste + OAuth device sign-in — the guided setup step behind the Settings → Coding Agents GitHub card, #15796), and a search category for PR lookup.

Plugin surface

Actions (registered via promoteSubactionsToActions(githubAction))

The umbrella action GITHUB dispatches to three sub-actions based on the action parameter:

Action name Constant Sub-actions / ops Default identity Confirmation
GITHUB umbrella routes to all ops below per op per op
GITHUB_ISSUE GitHubActions.GITHUB_ISSUE_OP create, assign, close, reopen, comment, label agent required (requireConfirmation)
GITHUB_PR GitHubActions.GITHUB_PR_OP list, review agent (list) / user (review) required for review
GITHUB_NOTIFICATION_TRIAGE GitHubActions.GITHUB_NOTIFICATION_TRIAGE reads + scores unread notifications user none (read-only)

All actions gate on contextGate: { anyOf: ["code", "tasks", "connectors", "automation"] } and roleGate: { minRole: "USER" }.

Services

Service class serviceType Purpose
GitHubService "github" Octokit client pool — resolves clients by role (user/agent) or explicit accountId

Routes

Registered at plugin init on the agent's HTTP server:

Method Path Purpose
GET /api/github/token Returns { connected, deviceFlowAvailable, username?, scopes?, savedAt? } — token never returned
POST /api/github/token Body { token }. Validates against GitHub /user, persists to <state-dir>/credentials/github.json, applies to the live runtime's per-agent settings (setSetting("GITHUB_TOKEN", …, true))
DELETE /api/github/token Clears saved credential (disk + live runtime settings)
POST /api/github/device/start Starts a GitHub OAuth device flow (needs the GITHUB_OAUTH_CLIENT_ID setting; 409 with an owner-setup message otherwise). Returns { flowId, userCode, verificationUri, intervalSeconds, expiresInSeconds } — the GitHub device_code never leaves the server
POST /api/github/device/poll Body { flowId }. One poll: 200 { status: "pending" | "denied" | "expired" } or, on grant, validates + persists like the PAT route and returns { status: "complete", …connected status }. Flows are scoped to the agent that started them

Search category

github_pull_requests — registered at init via registerGitHubSearchCategory. Filters: query, repo, state, author, as, accountId, limit. Contexts: code, automation.

Connector account provider

Registers with ConnectorAccountManager at init to expose GitHub accounts (PAT and OAuth) through the generic connector CRUD + OAuth flow surfaces. OAuth requires GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRET, GITHUB_OAUTH_REDIRECT_URI.

Layout

src/
  index.ts                     Plugin export, route wiring, plugin object
  register-routes.ts           App-route plugin loader — registers githubPlugin via registerAppRoutePluginLoader
  types.ts                     GitHubIdentity, GitHubOctokitClient, GitHubActions, result types
  accounts.ts                  Account config reading (env + character settings + connector store)
  action-helpers.ts            Shared: service lookup, client resolution, param helpers
  rate-limit.ts                Rate-limit detection and formatting
  github-credentials.ts        Local PAT store: load/save/clear at <state-dir>/credentials/github.json
  device-flow.ts               GitHub OAuth device-flow state machine (start/poll; per-agent scoped; device_code stays server-side)
  search-category.ts           github_pull_requests search category registration
  connector-account-provider.ts  ConnectorAccountManager bridge (PAT + OAuth flows)
  connector-credential-refs.ts   Credential ref persistence helpers
  actions/
    github.ts                  GITHUB umbrella action — dispatches by action= param
    issue-op.ts                GITHUB_ISSUE action (create/assign/close/reopen/comment/label)
    pr-op.ts                   GITHUB_PR action (list/review)
    notification-triage.ts     GITHUB_NOTIFICATION_TRIAGE action + scoreNotification export
  services/
    github-service.ts          GitHubService — Octokit client pool, account resolution
  routes/
    github-routes.ts           Pure handleGitHubRoutes dispatcher for PAT CRUD endpoints

Commands

bun run --cwd plugins/plugin-github build       # tsup ESM build + .d.ts
bun run --cwd plugins/plugin-github test        # vitest run
bun run --cwd plugins/plugin-github typecheck   # tsc --noEmit
bun run --cwd plugins/plugin-github clean       # rm dist .turbo

Config / env vars

Env var Required Purpose
GITHUB_ACCOUNTS No (preferred) JSON array/object of { accountId, role, token } records — supports multiple accounts
GITHUB_TOKEN No Bootstrap PAT — if already set in the environment, it takes precedence over any locally saved credential; the plugin also writes the saved credential here at startup so that spawned processes (e.g. gh/git) see the same value
GITHUB_USER_PAT No (legacy) PAT for the user role (acting on behalf of the human)
GITHUB_AGENT_PAT No (legacy) PAT for the agent role (acting on behalf of the agent)
GITHUB_USER_ACCOUNT_ID No Override account ID for the legacy user slot (default: "user")
GITHUB_AGENT_ACCOUNT_ID No Override account ID for the legacy agent slot (default: "agent")
ELIZA_E2E_GITHUB_USER_PAT No E2E fallback for GITHUB_USER_PAT
ELIZA_E2E_GITHUB_AGENT_PAT No E2E fallback for GITHUB_AGENT_PAT
GITHUB_OAUTH_CLIENT_ID OAuth only GitHub OAuth app client ID — also enables the device sign-in path on the settings card (/api/github/device/*)
GITHUB_OAUTH_CLIENT_SECRET OAuth only GitHub OAuth app client secret
GITHUB_OAUTH_REDIRECT_URI OAuth only OAuth redirect URI registered on the GitHub app

At least one account source — GITHUB_ACCOUNTS, GITHUB_USER_PAT, GITHUB_AGENT_PAT, or a character.settings.github.accounts entry — must be set for the plugin's actions to resolve a client. A bare GITHUB_TOKEN is not itself an account source: it bootstraps gh/git subprocess auth (and takes precedence over any locally saved credential) but does not register a user/agent account on its own. A missing user or agent account causes that role's operations to be rejected at runtime (logged as [GitHubService] no GitHub <role> account configured).

Character-level config is also supported under character.settings.github.accounts (array or object keyed by account ID).

How to extend

Add a new action:

  1. Create src/actions/my-op.ts exporting a typed Action with name, contexts, contextGate, roleGate, validate, and handler.
  2. Use buildResolvedClient(runtime, selection) from action-helpers.ts to get an authenticated Octokit client.
  3. Call requireConfirmation from @elizaos/core for any write op.
  4. Register the new action in src/actions/github.ts by extending GITHUB_ACTIONS and adding a dispatch branch in the umbrella handler, OR add it directly to the actions array in src/index.ts.

Add a new provider/evaluator: Export from src/index.ts and add to the githubPlugin object's providers or evaluators arrays.

Add a new route: Add an entry to githubRoutes in src/index.ts and a handler in src/routes/github-routes.ts. Routes use raw http.IncomingMessage / http.ServerResponse — no Express.

Conventions / gotchas

  • Confirmation is not optional for write ops. All write actions use requireConfirmation from @elizaos/core. The confirmed: true parameter in the action schema is vestigial — the runtime confirmation gate is authoritative. isConfirmed in action-helpers.ts always returns false and is deprecated.
  • Two identity roles, two PATs. user = human acting; agent = the Eliza agent acting. Operations that affect the repo on behalf of the agent use agent; operations that respond as the user (reviews, notifications) default to user.
  • Account precedence: GITHUB_ACCOUNTS JSON > GITHUB_USER_PAT/GITHUB_AGENT_PAT legacy env vars. Character settings are layered in before env vars. ConnectorAccountManager credentials (OAuth) overlay everything by accountId.
  • No test harness for route auth. handleGitHubRoutes is a pure dispatcher with no auth. The agent's server layer is expected to authenticate before calling the route handler.
  • Rate limits surface cleanly. inspectRateLimit in rate-limit.ts detects GitHub rate-limit responses (HTTP 403 with x-ratelimit-remaining: 0); formatRateLimitMessage renders a human-readable message with the reset time from x-ratelimit-reset.
  • PAT storage is local-first. <state-dir>/credentials/github.json (mode 0600). Written atomically via a tmp-rename. The token is never returned to the browser via the GET route.
  • GitHubOctokitClient is a structural interface, not the full Octokit class — tests can inject a mock without depending on the real Octokit.
  • tsup builds two entry points: src/index.ts and src/register-routes.ts. register-routes.ts is an app-route plugin loader that calls registerAppRoutePluginLoader("@elizaos/plugin-github", ...) — it registers the full githubPlugin, it is not a route-only subset.

Verification

Follow the repository-wide verification and evidence standard in the root CLAUDE.md. Run the package's relevant build, typecheck, lint, and test commands, then exercise the real integration boundary changed by the work. Inspect the produced domain artifacts and failure behavior; do not substitute mocked success for the system under test.