UNPKG

github-pr-automation

Version:

MCP server and CLI for automated GitHub PR management, review resolution, and workflow optimization

272 lines 11.5 kB
import { Octokit } from "@octokit/rest"; import type { PRIdentifier } from "../types/index.js"; /** * GitHub API client wrapper with authentication and error handling. * * This class provides a high-level interface to the GitHub API with built-in * authentication, error handling, and token validation. It wraps the Octokit * client and adds application-specific functionality. * * ## Features * * - **Authentication**: Automatic token validation and scope checking * - **Error Handling**: Normalized GitHub API errors with context * - **Token Validation**: Support for both classic PATs and fine-grained tokens * - **Rate Limiting**: Built-in rate limit monitoring * - **Testing Support**: Dependency injection for testing * * ## Authentication * * The client requires a GitHub Personal Access Token (PAT) with appropriate * scopes. It supports both: * - **Classic PATs**: With `repo` scope for full repository access * - **Fine-grained tokens**: With repository-specific permissions * * ## Error Handling * * All API calls are wrapped with error handling that: * - Normalizes GitHub API errors into consistent format * - Provides context about the failed operation * - Throws structured errors with operation details * * @example * ```typescript * // Initialize with environment token * const client = new GitHubClient(); * * // Initialize with explicit token * const client = new GitHubClient('ghp_your_token_here'); * * // Initialize for testing * const client = new GitHubClient(undefined, mockOctokit); * ``` */ export declare class GitHubClient { private octokit; /** * Initialize GitHub client with authentication token or inject Octokit instance. * * The constructor handles authentication setup and validates that a token * is available. It supports both explicit tokens and environment variables, * as well as dependency injection for testing. * * ## Token Resolution Order * * 1. **Explicit Token**: If provided as parameter * 2. **Environment Variable**: `GITHUB_TOKEN` from process.env * 3. **Error**: If no token found, throws descriptive error * * ## Testing Support * * When `octokitInstance` is provided, the client skips token validation * and uses the provided instance directly. This enables easy mocking * in unit tests. * * @param token - GitHub Personal Access Token (optional, falls back to GITHUB_TOKEN env var) * @param octokitInstance - Pre-configured Octokit instance for testing (optional) * @throws Error if no token is found and no octokitInstance is provided */ constructor(token?: string, octokitInstance?: Octokit); /** * Validate GitHub token and check permissions. * * This method performs a lightweight authentication check by calling the * GitHub API to verify the token is valid and has appropriate permissions. * It supports both classic Personal Access Tokens and fine-grained tokens. * * ## Token Types Supported * * ### Classic Personal Access Tokens (PATs) * - Include `x-oauth-scopes` header with comma-separated scopes * - Require `repo` or `public_repo` scope for repository access * - Full repository access when properly scoped * * ### Fine-grained Personal Access Tokens * - Do not include `x-oauth-scopes` header * - Have repository-specific permissions * - More granular access control * * ## Validation Process * * 1. **API Call**: Call `GET /user` to verify token validity * 2. **Scope Parsing**: Extract scopes from response headers * 3. **Permission Check**: Verify `repo` scope for classic tokens * 4. **Fine-grained Handling**: Skip scope check for fine-grained tokens * * @returns Promise resolving to validation result with user info and scopes * * @example * ```typescript * const validation = await client.validateToken(); * if (validation.valid) { * console.log(`Authenticated as: ${validation.user}`); * console.log(`Scopes: ${validation.scopes.join(', ')}`); * } else { * console.error(`Token invalid: ${validation.error}`); * } * ``` */ validateToken(): Promise<{ valid: boolean; error: string; user?: undefined; scopes?: undefined; } | { valid: boolean; user: string; scopes: string[]; error?: undefined; }>; /** * Get pull request details by identifier. * * Fetches comprehensive pull request information from the GitHub API, * including metadata, diff stats, and status information. All errors * are normalized and include context about the failed operation. * * @param pr - PR identifier containing owner, repo, and number * @returns Promise resolving to complete PR data from GitHub API * @throws Error with normalized GitHub API errors and operation context * * @example * ```typescript * const pr = await client.getPullRequest({ owner: 'microsoft', repo: 'vscode', number: 12345 }); * console.log(`PR Title: ${pr.title}`); * console.log(`State: ${pr.state}`); * ``` */ getPullRequest(pr: PRIdentifier): Promise<{ url: string; id: number; node_id: string; html_url: string; diff_url: string; patch_url: string; issue_url: string; commits_url: string; review_comments_url: string; review_comment_url: string; comments_url: string; statuses_url: string; number: number; state: "open" | "closed"; locked: boolean; title: string; user: import("@octokit/openapi-types").components["schemas"]["simple-user"]; body: string | null; labels: { id: number; node_id: string; url: string; name: string; description: string | null; color: string; default: boolean; }[]; milestone: import("@octokit/openapi-types").components["schemas"]["nullable-milestone"]; active_lock_reason?: string | null; created_at: string; updated_at: string; closed_at: string | null; merged_at: string | null; merge_commit_sha: string | null; assignee: import("@octokit/openapi-types").components["schemas"]["nullable-simple-user"]; assignees?: import("@octokit/openapi-types").components["schemas"]["simple-user"][] | null; requested_reviewers?: import("@octokit/openapi-types").components["schemas"]["simple-user"][] | null; requested_teams?: import("@octokit/openapi-types").components["schemas"]["team-simple"][] | null; head: { label: string; ref: string; repo: import("@octokit/openapi-types").components["schemas"]["repository"]; sha: string; user: import("@octokit/openapi-types").components["schemas"]["simple-user"]; }; base: { label: string; ref: string; repo: import("@octokit/openapi-types").components["schemas"]["repository"]; sha: string; user: import("@octokit/openapi-types").components["schemas"]["simple-user"]; }; _links: { comments: import("@octokit/openapi-types").components["schemas"]["link"]; commits: import("@octokit/openapi-types").components["schemas"]["link"]; statuses: import("@octokit/openapi-types").components["schemas"]["link"]; html: import("@octokit/openapi-types").components["schemas"]["link"]; issue: import("@octokit/openapi-types").components["schemas"]["link"]; review_comments: import("@octokit/openapi-types").components["schemas"]["link"]; review_comment: import("@octokit/openapi-types").components["schemas"]["link"]; self: import("@octokit/openapi-types").components["schemas"]["link"]; }; author_association: import("@octokit/openapi-types").components["schemas"]["author-association"]; auto_merge: import("@octokit/openapi-types").components["schemas"]["auto-merge"]; draft?: boolean; merged: boolean; mergeable: boolean | null; rebaseable?: boolean | null; mergeable_state: string; merged_by: import("@octokit/openapi-types").components["schemas"]["nullable-simple-user"]; comments: number; review_comments: number; maintainer_can_modify: boolean; commits: number; additions: number; deletions: number; changed_files: number; }>; /** * Get current GitHub API rate limit status. * * Retrieves the current rate limit information for the authenticated token, * including remaining requests, reset time, and limit details. This is useful * for monitoring API usage and implementing rate limit-aware logic. * * @returns Promise resolving to rate limit information * @throws Error with normalized GitHub API errors * * @example * ```typescript * const rateLimit = await client.getRateLimit(); * console.log(`Remaining requests: ${rateLimit.remaining}/${rateLimit.limit}`); * console.log(`Resets at: ${new Date(rateLimit.reset * 1000)}`); * ``` */ getRateLimit(): Promise<{ resources: { core: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; graphql?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; search: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; code_search?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; source_import?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; integration_manifest?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; code_scanning_upload?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; actions_runner_registration?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; scim?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; dependency_snapshots?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; dependency_sbom?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; code_scanning_autofix?: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; }; rate: import("@octokit/openapi-types").components["schemas"]["rate-limit"]; }>; /** * Get the underlying Octokit instance for direct API access. * * This method provides access to the raw Octokit client for advanced * operations that aren't covered by the high-level methods. Use this * when you need direct access to GitHub API endpoints. * * @returns Octokit instance for advanced GitHub API operations * * @example * ```typescript * const octokit = client.getOctokit(); * const { data: issues } = await octokit.issues.listForRepo({ * owner: 'microsoft', * repo: 'vscode', * state: 'open' * }); * ``` */ getOctokit(): Octokit; } //# sourceMappingURL=client.d.ts.map