• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

agentic-dev-library / thumbcode / 21330358259

25 Jan 2026 09:26AM UTC coverage: 17.054% (-6.0%) from 23.03%
21330358259

Pull #64

github

web-flow
Merge aabe9ef79 into 057514a46
Pull Request #64: [Long-Running] Production UI/UX: Research, Brand Alignment, and Implementation

252 of 2071 branches covered (12.17%)

Branch coverage included in aggregate %.

0 of 363 new or added lines in 15 files covered. (0.0%)

183 existing lines in 12 files now uncovered.

584 of 2831 relevant lines covered (20.63%)

1.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/core/src/github/GitHubApiService.ts
1
import { API_URLS } from '@thumbcode/config';
2
import type { Repository } from '@thumbcode/types';
3
import { CredentialService } from '../credentials';
4

5
interface GitHubRepoResponse {
6
  id: number;
7
  name: string;
8
  full_name: string;
9
  owner: { login: string };
10
  private: boolean;
11
  description: string | null;
12
  default_branch: string;
13
  clone_url: string;
14
  stargazers_count: number;
15
  forks_count: number;
16
  language: string | null;
17
  updated_at: string;
18
}
19

20
class GitHubApiServiceClass {
21
  private async getToken(): Promise<string> {
NEW
22
    const { secret } = await CredentialService.retrieve('github');
×
NEW
23
    if (!secret) {
×
NEW
24
      throw new Error('Missing GitHub credential. Connect GitHub first.');
×
25
    }
NEW
26
    return secret;
×
27
  }
28

29
  private async request<T>(path: string, init: RequestInit = {}): Promise<T> {
×
NEW
30
    const token = await this.getToken();
×
NEW
31
    const url = `${API_URLS.github}${path}`;
×
NEW
32
    const res = await fetch(url, {
×
33
      ...init,
34
      headers: {
35
        Accept: 'application/vnd.github.v3+json',
36
        Authorization: `Bearer ${token}`,
37
        ...init.headers,
38
      },
39
    });
40

NEW
41
    if (!res.ok) {
×
NEW
42
      const text = await res.text().catch(() => '');
×
NEW
43
      throw new Error(`GitHub API error: ${res.status} ${text}`.trim());
×
44
    }
45

NEW
46
    return (await res.json()) as T;
×
47
  }
48

49
  async listRepositories(options?: {
50
    perPage?: number;
51
    sort?: 'updated' | 'created' | 'pushed' | 'full_name';
52
    affiliation?: string;
53
  }): Promise<Repository[]> {
NEW
54
    const perPage = options?.perPage ?? 100;
×
NEW
55
    const sort = options?.sort ?? 'updated';
×
NEW
56
    const affiliation = options?.affiliation ?? 'owner,collaborator,organization_member';
×
57

NEW
58
    const repos = await this.request<GitHubRepoResponse[]>(
×
59
      `/user/repos?per_page=${perPage}&sort=${sort}&direction=desc&affiliation=${encodeURIComponent(affiliation)}`
60
    );
61

NEW
62
    return repos.map((r) => ({
×
63
      provider: 'github',
64
      owner: r.owner.login,
65
      name: r.name,
66
      fullName: r.full_name,
67
      defaultBranch: r.default_branch,
68
      cloneUrl: r.clone_url,
69
      isPrivate: r.private,
70
      description: r.description ?? undefined,
×
71
      language: r.language ?? undefined,
×
72
      stars: r.stargazers_count,
73
      forks: r.forks_count,
74
      updatedAt: r.updated_at,
75
    }));
76
  }
77
}
78

NEW
79
export const GitHubApiService = new GitHubApiServiceClass();
×
80

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc