import yaml from "js-yaml"; type RepoRecord = { id: string; full_name: string; org: string; description: string; visibility: "public" | "private"; status: "active" | "archived" | "experimental" | "legacy"; primary_domain: string | null; home_pack: string; created_at: string; updated_at: string; tags: string[]; owner_handles: string[]; }; type GitHubRepo = { name: string; full_name: string; private: boolean; description: string | null; created_at: string; updated_at: string; }; const TOKEN = process.env.GITHUB_TOKEN; const ORGS = process.env.GITHUB_ORGS?.split(",").map((org) => org.trim()).filter(Boolean) ?? []; async function githubFetch(url: string) { const headers: Record = { Accept: "application/vnd.github+json", "User-Agent": "blackroad-os-archive" }; if (TOKEN) { headers.Authorization = `Bearer ${TOKEN}`; } const response = await fetch(url, { headers }); if (!response.ok) { throw new Error(`GitHub request failed: ${response.status} ${response.statusText} for ${url}`); } return response.json(); } async function fetchReposForOrg(org: string): Promise { const repos: RepoRecord[] = []; let page = 1; while (true) { const url = `https://api.github.com/orgs/${org}/repos?per_page=100&page=${page}`; const data: GitHubRepo[] = await githubFetch(url); if (!data.length) break; data.forEach((repo) => { let id: string; if (repo.name.startsWith("blackroad-os-")) { id = repo.name.replace(/^blackroad-os-/, ""); } else { id = `other-${repo.name}`; console.warn( `Repository '${repo.full_name}' does not start with 'blackroad-os-'. Assigned id: '${id}'.` ); } repos.push({ id, full_name: repo.full_name, org, description: repo.description ?? "", visibility: repo.private ? "private" : "public", status: "active", primary_domain: null, home_pack: "tbd", created_at: repo.created_at, updated_at: repo.updated_at, tags: [], owner_handles: [] }); }); if (data.length < 100) break; page += 1; } return repos; } export async function scanGithubRepos(): Promise { if (!ORGS.length) { throw new Error("GITHUB_ORGS env var is required (comma-separated list)."); } const results: RepoRecord[] = []; for (const org of ORGS) { const repos = await fetchReposForOrg(org); results.push(...repos); } return results; } async function main() { try { const repos = await scanGithubRepos(); const payload = { repos }; const yamlOutput = yaml.dump(payload, { lineWidth: 120 }); process.stdout.write(`# Generated by scan_github_repos.ts\n`); process.stdout.write(yamlOutput); } catch (error) { console.error((error as Error).message); process.exit(1); } } if (require.main === module) { main(); }