UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

65 lines (64 loc) • 2.26 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. import * as childProcess from "node:child_process"; export const GITHUB_API_BASE = "https://api.github.com"; const GITHUB_TOKEN_DOMAINS = new Set(["api.github.com", "github.com", "uploads.github.com"]); function readGithubTokenFromEnv() { if (process.env.GITHUB_TOKEN !== undefined) { return process.env.GITHUB_TOKEN.trim(); } if (process.env.GH_TOKEN !== undefined) { return process.env.GH_TOKEN.trim(); } return undefined; } function readGithubTokenFromGhCli() { const result = childProcess.spawnSync("gh", ["auth", "token", "--hostname", "github.com"], { encoding: "utf8", timeout: 5_000, stdio: ["ignore", "pipe", "ignore"], }); if (result.status !== 0) return undefined; const token = result.stdout.trim(); return token || undefined; } function resolveGithubToken() { const token = readGithubTokenFromEnv(); return token !== undefined ? token || undefined : readGithubTokenFromGhCli(); } /** * Build headers for GitHub API requests. * When a `url` is provided, the Authorization header is only included if the * URL points to a known GitHub domain, preventing token leakage on redirects * to third-party hosts. */ export function githubHeaders(url) { const token = resolveGithubToken(); const headers = { Accept: "application/vnd.github+json", "User-Agent": "akm-registry", }; if (token) { let includeToken = true; if (url) { try { const hostname = new URL(url).hostname; includeToken = GITHUB_TOKEN_DOMAINS.has(hostname); } catch { includeToken = false; } } if (includeToken) headers.Authorization = `Bearer ${token}`; } return headers; } export function asRecord(value) { return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {}; } export function asString(value) { return typeof value === "string" && value ? value : undefined; }