MCPcopy
hub / github.com/cursor/community-plugins / cloneRepo

Function cloneRepo

apps/cursor/src/lib/plugins/scan.ts:356–425  ·  view source on GitHub ↗
(
  owner: string,
  repo: string,
  tag: string,
)

Source from the content-addressed store, hash-verified

354}
355
356async function cloneRepo(
357 owner: string,
358 repo: string,
359 tag: string,
360): Promise<{ cwd: string; cleanup: () => Promise<void> }> {
361 const root = await mkdtemp(path.join(tmpdir(), "plugin-scan-"));
362 const cwd = path.join(root, "repo");
363 const archivePath = path.join(root, "repo.tar.gz");
364 const cleanup = () =>
365 rm(root, { recursive: true, force: true }).catch(() => {});
366 const startedAt = Date.now();
367 const archiveUrl = `https://api.github.com/repos/${owner}/${repo}/tarball/HEAD`;
368 logInfo(tag, "GitHub archive download start", { owner, repo, cwd });
369 try {
370 await mkdir(cwd);
371 // GITHUB_TOKEN (when configured) lifts the 60 req/hr anonymous rate limit
372 // shared across all tenants of the function's egress IP.
373 const response = await fetchWithRateLimit(archiveUrl, {
374 headers: {
375 Accept: "application/vnd.github+json",
376 "User-Agent": "cursor-directory-plugin-scan",
377 ...githubAuthHeaders(),
378 },
379 maxWaitMs: 30_000,
380 });
381
382 if ([404, 410, 451].includes(response.status)) {
383 throw new UnscannableRepoError(
384 `GitHub returned ${response.status} for ${owner}/${repo} — the repository does not exist or is not public.`,
385 );
386 }
387
388 if (!response.ok || !response.body) {
389 throw new Error(
390 `GitHub archive request failed with ${response.status} ${response.statusText}`,
391 );
392 }
393
394 const contentLength = response.headers.get("content-length");
395 if (
396 contentLength &&
397 Number.parseInt(contentLength, 10) > REPO_ARCHIVE_MAX_BYTES
398 ) {
399 throw new UnscannableRepoError(
400 `Repository archive advertised ${contentLength} bytes, above the ${REPO_ARCHIVE_MAX_BYTES}-byte scan limit.`,
401 );
402 }
403
404 await pipeline(
405 Readable.fromWeb(response.body as never),
406 archiveSizeGuard(tag),
407 createWriteStream(archivePath),
408 );
409
410 await extractTar({
411 file: archivePath,
412 cwd,
413 strip: 1,

Callers 1

runSecurityAgentFunction · 0.85

Calls 6

fetchWithRateLimitFunction · 0.90
githubAuthHeadersFunction · 0.90
archiveSizeGuardFunction · 0.85
cleanupFunction · 0.85
logInfoFunction · 0.70
logErrorFunction · 0.70

Tested by

no test coverage detected