Skip to main content
Glama
anaylyser.ts3.52 kB
import { execFileSync } from "node:child_process" import path from "node:path" import { createGithubClient, getRepositoryString } from "@repo/github" import type { AnalyserJson } from "@specfy/stack-analyser" import fs from "fs-extra" if (!process.env.REPO_DIR) { throw new Error("REPO_DIR is not set") } const getRepoInfo = (url: string) => { const repo = getRepositoryString(url) console.log("[api] [inngest] [anaylyser.ts] [getRepoInfo] Getting repo info: ", process.env.REPO_DIR) const repoDir = path.join(process.env.REPO_DIR!, ".repositories", repo) if (!fs.pathExistsSync(repoDir)) { fs.ensureDirSync(path.dirname(repoDir)) } const outputFile = path.join(repoDir, "output", `output-${repo.replace("/", "-")}.json`) if (!fs.pathExistsSync(outputFile)) { fs.ensureDirSync(path.dirname(outputFile)) } return { repo, repoDir, outputFile } } const cloneRepository = async (repo: string, repoDir: string) => { console.time("Cloning repository") console.log("[api] [inngest] [anaylyser.ts] [cloneRepository] Cloning repository: ", repo, repoDir) try { if (fs.pathExistsSync(repoDir)) { await fs.remove(repoDir) } fs.ensureDirSync(repoDir) execFileSync("git", ["clone", `${repo}`, repoDir]) } catch (error) { console.error(`Error cloning ${repo}:`, error) throw new Error(`Error cloning ${repo}`) } finally { console.timeEnd("Cloning repository") } } const analyzeStack = async (repo: string, repoDir: string, outputFile: string) => { console.time("Analyzing stack") try { execFileSync("bun", ["x", "@specfy/stack-analyser", repoDir, "--flat", "-o", outputFile]) const output = fs.readFileSync(outputFile, "utf-8") return JSON.parse(output) as AnalyserJson } catch (error) { console.error(`Error analyzing stack for ${repo}:`, error) throw error } finally { console.timeEnd("Analyzing stack") } } const cleanupDirectories = async (repo: string, repoDir: string, outputFile: string) => { console.time("Cleaning up directories") try { await fs.remove(repoDir) await fs.remove(outputFile) } catch (error) { console.error(`Cleanup error for ${repo}:`, error) throw error } finally { console.timeEnd("Cleaning up directories") } } const readReadme = async (repoDir: string) => { let readmeFile = path.join(repoDir, "README_CN.md") if (!fs.pathExistsSync(readmeFile)) { readmeFile = path.join(repoDir, "README.md") } if (!fs.pathExistsSync(readmeFile)) { return "" } const readme = fs.readFileSync(readmeFile, "utf-8") if (readmeFile.endsWith("README.md")) { // TODO: 这里需要添加翻译逻辑 // 可以使用翻译API或翻译服务 return readme } return readme } export const analyzeRepositoryStack = async (url: string) => { const { repo, repoDir, outputFile } = getRepoInfo(url) const githubClient = createGithubClient(process.env.GITHUB_TOKEN || "") const repoUrl = repo.startsWith("https://github.com") ? repo : `https://github.com/${repo}`; try { await cloneRepository(repoUrl, repoDir) const [readme, { childs }, repository] = await Promise.all([ readReadme(repoDir), // Get analysis analyzeStack(repo, repoDir, outputFile), // Get repository githubClient.queryRepository(repoUrl), ]) return { stack: [...new Set(childs.flatMap(({ techs }) => techs))], repository, readme } } finally { // await cleanupDirectories(repo, repoDir, outputFile).catch(() => { }) } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/metacode0602/open-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server