export interface GitHubRelease { tag_name: string; body: string; html_url: string; published_at?: string | null; draft?: boolean; prerelease?: boolean; } export interface GitHubRepoMeta { stargazers_count: number; forks_count: number; archived: boolean; pushed_at: string | null; open_issues_count: number; created_at: string | null; license: { spdx_id: string | null; name: string | null; } | null; owner: { login: string; type: string; }; } export interface IssueStats { /** null when the Search API call failed (rate-limited or network error). */ open: number | null; /** null when the Search API call failed (rate-limited or network error). */ closed: number | null; /** closed / (open + closed); null when either count is unavailable. */ closeRatio: number | null; /** Median days-to-close over recent closed issues; null when unavailable. */ medianDaysToClose: number | null; } export interface GitHubUser { public_repos: number | null; created_at: string | null; } export declare class GitHubClient { private readonly headers; constructor(token?: string); fetchReleases(owner: string, repo: string): Promise; fetchChangelog(owner: string, repo: string): Promise; repoExists(owner: string, repo: string): Promise; /** Fetch repository metadata (stars, activity, license, owner). null on failure. */ fetchRepo(owner: string, repo: string): Promise; /** * Publisher/owner account signals: public-repo count and account creation * date, used to gauge maintainer scale and account age. null on failure * (non-fatal — repo metrics still stand without it). */ fetchUser(login: string): Promise; /** * Issue dynamics via the GitHub Search API: open vs closed counts, close * ratio, and median days-to-close over recent closed issues. Returns null * when both counts are unavailable (Search API is rate-limited more strictly * than the core API). PRs are excluded via `type:issue`. */ fetchIssueStats(owner: string, repo: string): Promise; private searchIssueCount; private medianDaysToCloseRecent; /** * Files > 1 MB come back with `content === ""` and a `download_url` pointing * at raw.githubusercontent.com. Fall back to fetching that raw URL so the * changelog isn't silently truncated to the empty string. */ private decodeChangelogContents; }