UNPKG

@agentforce/adk

Version:

AgentForce Agent Development Kit - A powerful framework for building AI agents and servers

242 lines (221 loc) 9.19 kB
import type { ToolImplementation } from "../types"; import { executeGitHubCLI } from "../utils/exec"; /** * GitHub list repositories tool * Lists repositories using the GitHub CLI (gh) */ export const gh_list_repos: ToolImplementation = { definition: { type: "function", function: { name: "gh_list_repos", description: "List GitHub repositories using the GitHub CLI. Can list repositories for a user/organization or search repositories.", parameters: { type: "object", properties: { owner: { type: "string", description: "GitHub username or organization name to list repositories for (optional, defaults to authenticated user)", }, limit: { type: "number", description: "Maximum number of repositories to return (default: 30, max: 100)", }, visibility: { type: "string", description: "Repository visibility filter", enum: ["public", "private", "internal"], }, type: { type: "string", description: "Repository type filter", enum: ["all", "owner", "member"], }, sort: { type: "string", description: "Sort repositories by", enum: ["created", "updated", "pushed", "full_name"], }, direction: { type: "string", description: "Sort direction", enum: ["asc", "desc"], }, language: { type: "string", description: "Filter repositories by primary language", }, topic: { type: "string", description: "Filter repositories by topic", }, archived: { type: "boolean", description: "Include archived repositories (default: false)", }, fork: { type: "boolean", description: "Include forked repositories (default: true)", }, }, required: [], }, }, }, execute: async (args: Record<string, any>) => { const { owner, limit = 30, visibility, type = "all", sort = "updated", direction = "desc", language, topic, archived = false, fork = true, } = args; try { // Validate limit const validLimit = Math.min(Math.max(1, limit), 100); // Build gh repo list command arguments const ghArgs = ["repo", "list"]; // Add owner if specified if (owner) { ghArgs.push(owner); } // Add options ghArgs.push("--limit", validLimit.toString()); ghArgs.push("--json", "name,nameWithOwner,owner,description,url,sshUrl,createdAt,updatedAt,pushedAt,isPrivate,isFork,isArchived,primaryLanguage,repositoryTopics,stargazerCount,forkCount,diskUsage"); // Add filters if (visibility) { ghArgs.push("--visibility", visibility); } if (type !== "all") { ghArgs.push("--source"); } if (language) { ghArgs.push("--language", language); } if (topic) { ghArgs.push("--topic", topic); } if (!archived) { ghArgs.push("--no-archived"); } // Execute the GitHub CLI command const result = await executeGitHubCLI(ghArgs); if (!result.success) { return { success: false, error: result.error || result.stderr || "Failed to list repositories", command: result.command, exitCode: result.exitCode, }; } // Parse JSON response let repositories = []; try { repositories = JSON.parse(result.stdout); } catch (parseError) { return { success: false, error: "Failed to parse GitHub CLI response", rawOutput: result.stdout, }; } // Apply additional filtering let filteredRepos = repositories; // Filter forks if requested if (!fork) { filteredRepos = filteredRepos.filter((repo: any) => !repo.isFork); } // Sort repositories if (sort) { filteredRepos.sort((a: any, b: any) => { let aValue: any, bValue: any; switch (sort) { case "created": aValue = new Date(a.createdAt); bValue = new Date(b.createdAt); break; case "updated": aValue = new Date(a.updatedAt); bValue = new Date(b.updatedAt); break; case "pushed": aValue = new Date(a.pushedAt); bValue = new Date(b.pushedAt); break; case "full_name": aValue = `${a.owner.login}/${a.name}`; bValue = `${b.owner.login}/${b.name}`; break; default: aValue = a[sort]; bValue = b[sort]; } if (direction === "desc") { return aValue > bValue ? -1 : aValue < bValue ? 1 : 0; } else { return aValue < bValue ? -1 : aValue > bValue ? 1 : 0; } }); } // Process and format repository data const processedRepos = filteredRepos.map((repo: any) => ({ name: repo.name, fullName: repo.nameWithOwner || `${repo.owner.login}/${repo.name}`, owner: repo.owner.login, description: repo.description || "", url: repo.url, sshUrl: repo.sshUrl, isPrivate: repo.isPrivate, isFork: repo.isFork, isArchived: repo.isArchived, language: repo.primaryLanguage?.name || "Unknown", topics: repo.repositoryTopics?.map((t: any) => t.topic?.name).filter(Boolean) || [], stars: repo.stargazerCount || 0, forks: repo.forkCount || 0, size: repo.diskUsage || 0, createdAt: repo.createdAt, updatedAt: repo.updatedAt, pushedAt: repo.pushedAt, })); // Generate summary statistics const stats = { totalRepos: processedRepos.length, publicRepos: processedRepos.filter((repo: any) => !repo.isPrivate).length, privateRepos: processedRepos.filter((repo: any) => repo.isPrivate).length, forkedRepos: processedRepos.filter((repo: any) => repo.isFork).length, archivedRepos: processedRepos.filter((repo: any) => repo.isArchived).length, totalStars: processedRepos.reduce((sum: number, repo: any) => sum + repo.stars, 0), totalForks: processedRepos.reduce((sum: number, repo: any) => sum + repo.forks, 0), languages: [...new Set(processedRepos.map((repo: any) => repo.language).filter(Boolean))], }; return { success: true, owner: owner || "authenticated user", repositories: processedRepos, statistics: stats, filters: { limit: validLimit, visibility, type, sort, direction, language, topic, includeArchived: archived, includeForks: fork, }, }; } catch (error: any) { return { success: false, error: `GitHub CLI execution failed: ${error.message}`, owner: owner || "authenticated user", }; } }, };