github.ts•4.21 kB
import { BaseApiClient } from "../../core/base-api.js";
import { loadConfig } from "../../core/config.js";
import { ToolRegistration } from "../../core/types.js";
class GitHubClient extends BaseApiClient {
constructor(private readonly token: string) {
super("https://api.github.com", {
Authorization: `Bearer ${token}`,
Accept: "application/vnd.github+json",
});
}
searchRepositories(query: string, language?: string) {
const q = language ? `${query} language:${language}` : query;
return this.request("/search/repositories", { query: { q } });
}
getRepository(owner: string, repo: string) {
return this.request(`/repos/${owner}/${repo}`);
}
createIssue(owner: string, repo: string, title: string, body?: string) {
return this.request(`/repos/${owner}/${repo}/issues`, {
method: "POST",
body: { title, body },
});
}
listCommits(owner: string, repo: string) {
return this.request(`/repos/${owner}/${repo}/commits`);
}
}
export function registerGitHub(): ToolRegistration {
const cfg = loadConfig();
const client = new GitHubClient(cfg.githubToken || "");
return {
tools: [
{
name: "search_repositories",
description: "Search GitHub repositories",
inputSchema: {
type: "object",
properties: {
query: { type: "string" },
language: { type: "string" },
},
required: ["query"],
},
},
{
name: "get_repository_info",
description: "Get GitHub repository details",
inputSchema: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
},
required: ["owner", "repo"],
},
},
{
name: "create_issue",
description: "Create an issue in a repository",
inputSchema: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
title: { type: "string" },
body: { type: "string" },
},
required: ["owner", "repo", "title"],
},
},
{
name: "list_commits",
description: "List recent commits for a repository",
inputSchema: {
type: "object",
properties: {
owner: { type: "string" },
repo: { type: "string" },
},
required: ["owner", "repo"],
},
},
],
handlers: {
async search_repositories(args: Record<string, unknown>) {
if (!cfg.githubToken) throw new Error("GITHUB_TOKEN is not configured");
const query = String(args.query || "");
const language = args.language ? String(args.language) : undefined;
if (!query) throw new Error("query is required");
return client.searchRepositories(query, language);
},
async get_repository_info(args: Record<string, unknown>) {
if (!cfg.githubToken) throw new Error("GITHUB_TOKEN is not configured");
const owner = String(args.owner || "");
const repo = String(args.repo || "");
if (!owner || !repo) throw new Error("owner and repo are required");
return client.getRepository(owner, repo);
},
async create_issue(args: Record<string, unknown>) {
if (!cfg.githubToken) throw new Error("GITHUB_TOKEN is not configured");
const owner = String(args.owner || "");
const repo = String(args.repo || "");
const title = String(args.title || "");
const body = args.body ? String(args.body) : undefined;
if (!owner || !repo || !title) throw new Error("owner, repo and title are required");
return client.createIssue(owner, repo, title, body);
},
async list_commits(args: Record<string, unknown>) {
if (!cfg.githubToken) throw new Error("GITHUB_TOKEN is not configured");
const owner = String(args.owner || "");
const repo = String(args.repo || "");
if (!owner || !repo) throw new Error("owner and repo are required");
return client.listCommits(owner, repo);
},
},
};
}