@open330/oac 2026.2.5 → 2026.220.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -169,6 +169,7 @@ async function resolveRepo(input) {
169
169
  git: {
170
170
  headSha,
171
171
  remoteUrl: repoData.clone_url ?? `https://github.com/${repoData.full_name}.git`,
172
+ sshUrl: repoData.ssh_url ?? `git@github.com:${repoData.full_name}.git`,
172
173
  isShallowClone: true
173
174
  }
174
175
  };
@@ -332,11 +333,13 @@ function resolveGitHubToken() {
332
333
 
333
334
  // src/repo/cloner.ts
334
335
  import { constants as fsConstants2 } from "fs";
335
- import { access as access2, mkdir as mkdir2 } from "fs/promises";
336
+ import { access as access2, mkdir as mkdir2, rm } from "fs/promises";
336
337
  import { homedir as homedir3 } from "os";
337
338
  import { dirname as dirname2, join as join3, resolve } from "path";
338
339
  import { simpleGit } from "simple-git";
339
340
  var CLONE_RETRY_BACKOFF_MS = [1e3, 4e3, 16e3];
341
+ var GIT_CLONE_TIMEOUT_MS = 3e5;
342
+ var GIT_FETCH_TIMEOUT_MS = 12e4;
340
343
  var DEFAULT_REPO_CACHE_DIR = join3(homedir3(), ".oac", "cache", "repos");
341
344
  async function cloneRepo(repo, cacheDir = DEFAULT_REPO_CACHE_DIR) {
342
345
  const cacheRoot = resolveCacheDir(cacheDir);
@@ -351,7 +354,7 @@ async function cloneRepo(repo, cacheDir = DEFAULT_REPO_CACHE_DIR) {
351
354
  } else {
352
355
  await cloneNewRepository(repo, localPath);
353
356
  }
354
- const git = simpleGit(localPath);
357
+ const git = createGit(localPath);
355
358
  repo.localPath = localPath;
356
359
  repo.worktreePath = join3(localPath, "..", ".oac-worktrees", repo.meta.defaultBranch);
357
360
  repo.git.headSha = (await git.revparse(["HEAD"])).trim();
@@ -360,24 +363,48 @@ async function cloneRepo(repo, cacheDir = DEFAULT_REPO_CACHE_DIR) {
360
363
  return localPath;
361
364
  }
362
365
  async function cloneNewRepository(repo, localPath) {
363
- const git = simpleGit();
364
- await retryGitOperation(
365
- () => git.clone(repo.git.remoteUrl, localPath, [
366
- "--depth",
367
- "1",
368
- "--branch",
369
- repo.meta.defaultBranch
370
- ]),
371
- `clone ${repo.fullName}`
372
- );
366
+ const git = createGit(void 0, GIT_CLONE_TIMEOUT_MS);
367
+ const cloneArgs = ["--depth", "1", "--branch", repo.meta.defaultBranch];
368
+ try {
369
+ await retryGitOperation(
370
+ () => git.clone(repo.git.remoteUrl, localPath, cloneArgs),
371
+ `clone ${repo.fullName}`
372
+ );
373
+ } catch (httpsError) {
374
+ if (!repo.git.sshUrl) throw httpsError;
375
+ await cleanPartialClone(localPath);
376
+ try {
377
+ await retryGitOperation(
378
+ () => git.clone(repo.git.sshUrl, localPath, cloneArgs),
379
+ `clone ${repo.fullName} (SSH fallback)`
380
+ );
381
+ } catch (sshError) {
382
+ throw new Error(
383
+ `Failed to clone "${repo.fullName}" via both HTTPS and SSH.
384
+ Ensure git credentials are configured: run \`gh auth login\` or set up SSH keys.
385
+ HTTPS error: ${httpsError instanceof Error ? httpsError.message : httpsError}
386
+ SSH error: ${sshError instanceof Error ? sshError.message : sshError}`,
387
+ { cause: sshError }
388
+ );
389
+ }
390
+ }
373
391
  }
374
392
  async function pullExistingClone(repo, localPath) {
375
- const git = simpleGit(localPath);
393
+ const git = createGit(localPath);
376
394
  await ensureOriginRemote(git, repo.git.remoteUrl);
377
- await retryGitOperation(
378
- () => git.fetch("origin", repo.meta.defaultBranch, ["--depth=1", "--prune"]),
379
- `fetch ${repo.fullName}`
380
- );
395
+ try {
396
+ await retryGitOperation(
397
+ () => git.fetch("origin", repo.meta.defaultBranch, ["--depth=1", "--prune"]),
398
+ `fetch ${repo.fullName}`
399
+ );
400
+ } catch (fetchError) {
401
+ if (!repo.git.sshUrl) throw fetchError;
402
+ await ensureOriginRemote(git, repo.git.sshUrl);
403
+ await retryGitOperation(
404
+ () => git.fetch("origin", repo.meta.defaultBranch, ["--depth=1", "--prune"]),
405
+ `fetch ${repo.fullName} (SSH fallback)`
406
+ );
407
+ }
381
408
  await checkoutDefaultBranch(git, repo.meta.defaultBranch);
382
409
  await retryGitOperation(
383
410
  () => hardSyncDefaultBranch(git, repo.meta.defaultBranch),
@@ -462,6 +489,18 @@ function sleep(ms) {
462
489
  setTimeout(resolvePromise, ms);
463
490
  });
464
491
  }
492
+ function createGit(baseDir, timeoutMs = GIT_FETCH_TIMEOUT_MS) {
493
+ return simpleGit({
494
+ ...baseDir ? { baseDir } : {},
495
+ timeout: { block: timeoutMs }
496
+ }).env({ ...process.env, GIT_TERMINAL_PROMPT: "0" });
497
+ }
498
+ async function cleanPartialClone(localPath) {
499
+ try {
500
+ await rm(localPath, { recursive: true, force: true });
501
+ } catch {
502
+ }
503
+ }
465
504
 
466
505
  export {
467
506
  DEFAULT_METADATA_CACHE_PATH,
@@ -472,4 +511,4 @@ export {
472
511
  DEFAULT_REPO_CACHE_DIR,
473
512
  cloneRepo
474
513
  };
475
- //# sourceMappingURL=chunk-CJAJ4MBO.js.map
514
+ //# sourceMappingURL=chunk-OS3XDHOJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/repo/resolver.ts","../src/repo/metadata-cache.ts","../src/repo/cloner.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Octokit } from \"@octokit/rest\";\nimport { MetadataCache } from \"./metadata-cache.js\";\nimport type { RepoPermissions, ResolvedRepo } from \"./types.js\";\n\nconst OWNER_REPO_PATTERN = /^(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\nconst GITHUB_SSH_PATTERN =\n /^git@github\\.com:(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\n\nexport type RepoResolutionErrorCode =\n | \"INVALID_INPUT\"\n | \"NOT_FOUND\"\n | \"FORBIDDEN\"\n | \"ARCHIVED\"\n | \"UNKNOWN\";\n\nexport class RepoResolutionError extends Error {\n public readonly code: RepoResolutionErrorCode;\n\n public constructor(message: string, code: RepoResolutionErrorCode, cause?: unknown) {\n super(message, { cause });\n this.name = \"RepoResolutionError\";\n this.code = code;\n }\n}\n\ninterface ParsedRepoInput {\n owner: string;\n name: string;\n}\n\nexport async function resolveRepo(input: string): Promise<ResolvedRepo> {\n const parsed = parseRepoInput(input);\n const cache = new MetadataCache();\n const cacheKey = `${parsed.owner}/${parsed.name}`;\n const cached = await cache.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const octokit = new Octokit({\n auth: resolveGitHubToken(),\n });\n\n const repoData = await fetchRepo(octokit, parsed.owner, parsed.name);\n if (repoData.archived) {\n throw new RepoResolutionError(\n `Repository \"${repoData.full_name}\" is archived and cannot be used for contributions.`,\n \"ARCHIVED\",\n );\n }\n\n const permissions = normalizePermissions(repoData.private, repoData.permissions);\n if (!permissions.pull) {\n throw new RepoResolutionError(\n `Missing pull permission for \"${repoData.full_name}\".`,\n \"FORBIDDEN\",\n );\n }\n\n const [languages, headSha] = await Promise.all([\n fetchLanguages(octokit, repoData.owner.login, repoData.name),\n fetchHeadSha(octokit, repoData.owner.login, repoData.name, repoData.default_branch),\n ]);\n\n const localPath = defaultLocalPath(repoData.owner.login, repoData.name);\n const resolved: ResolvedRepo = {\n fullName: repoData.full_name,\n owner: repoData.owner.login,\n name: repoData.name,\n localPath,\n worktreePath: join(localPath, \"..\", \".oac-worktrees\", repoData.default_branch),\n meta: {\n defaultBranch: repoData.default_branch,\n language: repoData.language,\n languages,\n size: repoData.size,\n stars: repoData.stargazers_count,\n openIssuesCount: repoData.open_issues_count,\n topics: repoData.topics ?? [],\n license: normalizeLicense(repoData.license?.spdx_id ?? null),\n isArchived: repoData.archived,\n isFork: repoData.fork,\n permissions,\n },\n git: {\n headSha,\n remoteUrl: repoData.clone_url ?? `https://github.com/${repoData.full_name}.git`,\n sshUrl: repoData.ssh_url ?? `git@github.com:${repoData.full_name}.git`,\n isShallowClone: true,\n },\n };\n\n await cache.set(resolved.fullName, resolved);\n return resolved;\n}\n\nfunction parseRepoInput(input: string): ParsedRepoInput {\n const normalized = input.trim();\n if (!normalized) {\n throw new RepoResolutionError(\"Repository input cannot be empty.\", \"INVALID_INPUT\");\n }\n\n const ownerRepoMatch = normalized.match(OWNER_REPO_PATTERN);\n if (ownerRepoMatch?.groups) {\n return {\n owner: ownerRepoMatch.groups.owner,\n name: ownerRepoMatch.groups.repo,\n };\n }\n\n const sshMatch = normalized.match(GITHUB_SSH_PATTERN);\n if (sshMatch?.groups) {\n return {\n owner: sshMatch.groups.owner,\n name: sshMatch.groups.repo,\n };\n }\n\n const normalizedUrlInput = normalized.startsWith(\"github.com/\")\n ? `https://${normalized}`\n : normalized;\n\n try {\n const url = new URL(normalizedUrlInput);\n if (!isGitHubHost(url.hostname)) {\n throw new RepoResolutionError(\n `Only github.com repository URLs are supported, received \"${url.hostname}\".`,\n \"INVALID_INPUT\",\n );\n }\n\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n if (pathParts.length < 2) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n const owner = pathParts[0];\n const name = stripGitSuffix(pathParts[1]);\n if (!owner || !name) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n return { owner, name };\n } catch (error) {\n if (error instanceof RepoResolutionError) {\n throw error;\n }\n\n throw new RepoResolutionError(\n `Expected \"owner/repo\" or a GitHub repository URL, received \"${input}\".`,\n \"INVALID_INPUT\",\n error,\n );\n }\n}\n\nasync function fetchRepo(octokit: Octokit, owner: string, repo: string) {\n try {\n return (await octokit.repos.get({ owner, repo })).data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchLanguages(\n octokit: Octokit,\n owner: string,\n repo: string,\n): Promise<Record<string, number>> {\n try {\n const response = await octokit.repos.listLanguages({ owner, repo });\n return response.data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchHeadSha(\n octokit: Octokit,\n owner: string,\n repo: string,\n defaultBranch: string,\n): Promise<string> {\n try {\n const branch = await octokit.repos.getBranch({\n owner,\n repo,\n branch: defaultBranch,\n });\n return branch.data.commit.sha;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nfunction toResolutionError(owner: string, repo: string, error: unknown): RepoResolutionError {\n const fullName = `${owner}/${repo}`;\n const status = isApiError(error) ? error.status : undefined;\n const message =\n typeof error === \"object\" && error && \"message\" in error\n ? String(error.message)\n : \"unknown error\";\n\n if (status === 404) {\n const hasToken = !!(process.env.GITHUB_TOKEN || process.env.GH_TOKEN);\n const hint = hasToken\n ? `If this is a private repo, ensure your token has the \"repo\" scope: gh auth refresh -s repo`\n : \"If this is a private repo, authenticate first: gh auth login\";\n return new RepoResolutionError(\n `Repository \"${fullName}\" was not found on GitHub. ${hint}`,\n \"NOT_FOUND\",\n error,\n );\n }\n\n if (status === 403) {\n return new RepoResolutionError(\n `Access denied for \"${fullName}\". Ensure your token has the \"repo\" scope: gh auth refresh -s repo`,\n \"FORBIDDEN\",\n error,\n );\n }\n\n return new RepoResolutionError(\n `Failed to resolve repository \"${fullName}\": ${message}`,\n \"UNKNOWN\",\n error,\n );\n}\n\nfunction normalizePermissions(\n isPrivateRepo: boolean,\n permissions:\n | {\n admin?: boolean;\n push?: boolean;\n pull?: boolean;\n }\n | undefined,\n): RepoPermissions {\n const pull = permissions?.pull ?? !isPrivateRepo;\n\n return {\n push: permissions?.push ?? false,\n pull,\n admin: permissions?.admin ?? false,\n };\n}\n\nfunction normalizeLicense(spdxId: string | null): string | null {\n if (!spdxId || spdxId === \"NOASSERTION\") {\n return null;\n }\n\n return spdxId;\n}\n\nfunction isGitHubHost(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return normalized === \"github.com\" || normalized === \"www.github.com\";\n}\n\nfunction stripGitSuffix(repo: string): string {\n return repo.replace(/\\.git$/i, \"\");\n}\n\nfunction isApiError(error: unknown): error is { status?: number } {\n return typeof error === \"object\" && error !== null && \"status\" in error;\n}\n\nfunction defaultLocalPath(owner: string, name: string): string {\n return join(homedir(), \".oac\", \"cache\", \"repos\", owner, name);\n}\n\nfunction resolveGitHubToken(): string | undefined {\n const githubToken = process.env.GITHUB_TOKEN?.trim();\n if (githubToken) {\n process.env.GITHUB_TOKEN = githubToken;\n return githubToken;\n }\n\n const ghToken = process.env.GH_TOKEN?.trim();\n if (ghToken) {\n process.env.GITHUB_TOKEN = ghToken;\n return ghToken;\n }\n\n try {\n const token = execFileSync(\"gh\", [\"auth\", \"token\"], {\n timeout: 5_000,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n\n if (token.length > 0) {\n process.env.GITHUB_TOKEN = token;\n return token;\n }\n } catch {\n // gh not installed or not authenticated\n }\n\n return undefined;\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { ResolvedRepo } from \"./types.js\";\n\ninterface MetadataCacheEntry {\n cachedAt: number;\n repo: ResolvedRepo;\n}\n\ninterface MetadataCacheFile {\n version: 1;\n entries: Record<string, MetadataCacheEntry>;\n}\n\nexport interface MetadataCacheOptions {\n filePath?: string;\n ttlMs?: number;\n now?: () => number;\n}\n\nexport const DEFAULT_METADATA_CACHE_PATH = join(homedir(), \".oac\", \"cache\", \"repos.json\");\n\nexport const DEFAULT_METADATA_CACHE_TTL_MS = 60 * 60 * 1000;\n\nconst EMPTY_CACHE: MetadataCacheFile = {\n version: 1,\n entries: {},\n};\n\nexport class MetadataCache {\n private readonly filePath: string;\n private readonly ttlMs: number;\n private readonly now: () => number;\n\n public constructor(options: MetadataCacheOptions = {}) {\n this.filePath = expandHomePath(options.filePath ?? DEFAULT_METADATA_CACHE_PATH);\n this.ttlMs = options.ttlMs ?? DEFAULT_METADATA_CACHE_TTL_MS;\n this.now = options.now ?? Date.now;\n }\n\n public async get(fullName: string): Promise<ResolvedRepo | null> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n const entry = cache.entries[key];\n\n if (!entry) {\n return null;\n }\n\n if (this.now() - entry.cachedAt > this.ttlMs) {\n delete cache.entries[key];\n await this.writeCache(cache);\n return null;\n }\n\n return entry.repo;\n }\n\n public async set(fullName: string, repo: ResolvedRepo): Promise<void> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n cache.entries[key] = {\n cachedAt: this.now(),\n repo,\n };\n await this.writeCache(cache);\n }\n\n public async invalidate(fullName?: string): Promise<void> {\n if (!fullName) {\n await this.writeCache(EMPTY_CACHE);\n return;\n }\n\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n if (!(key in cache.entries)) {\n return;\n }\n\n delete cache.entries[key];\n await this.writeCache(cache);\n }\n\n private async readCache(): Promise<MetadataCacheFile> {\n if (!(await pathExists(this.filePath))) {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<MetadataCacheFile>;\n\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\") {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n return {\n version: 1,\n entries: parsed.entries as Record<string, MetadataCacheEntry>,\n };\n } catch {\n return { ...EMPTY_CACHE, entries: {} };\n }\n }\n\n private async writeCache(cache: MetadataCacheFile): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true });\n const tempPath = `${this.filePath}.tmp`;\n await writeFile(tempPath, JSON.stringify(cache, null, 2), \"utf8\");\n await rename(tempPath, this.filePath);\n }\n}\n\nfunction normalizeCacheKey(fullName: string): string {\n return fullName.trim().toLowerCase();\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, rm } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport type { ResolvedRepo } from \"./types.js\";\n\nconst CLONE_RETRY_BACKOFF_MS = [1000, 4000, 16000] as const;\nconst GIT_CLONE_TIMEOUT_MS = 300_000; // 5 min rolling timeout for clone\nconst GIT_FETCH_TIMEOUT_MS = 120_000; // 2 min rolling timeout for fetch/sync\n\nexport const DEFAULT_REPO_CACHE_DIR = join(homedir(), \".oac\", \"cache\", \"repos\");\n\nexport async function cloneRepo(\n repo: ResolvedRepo,\n cacheDir: string = DEFAULT_REPO_CACHE_DIR,\n): Promise<string> {\n const cacheRoot = resolveCacheDir(cacheDir);\n const localPath = join(cacheRoot, repo.owner, repo.name);\n await mkdir(dirname(localPath), { recursive: true });\n\n if (await isGitRepository(localPath)) {\n await pullExistingClone(repo, localPath);\n } else if (await pathExists(localPath)) {\n throw new Error(\n `Cannot clone \"${repo.fullName}\" into \"${localPath}\" because the directory exists and is not a git repository.`,\n );\n } else {\n await cloneNewRepository(repo, localPath);\n }\n\n const git = createGit(localPath);\n repo.localPath = localPath;\n repo.worktreePath = join(localPath, \"..\", \".oac-worktrees\", repo.meta.defaultBranch);\n repo.git.headSha = (await git.revparse([\"HEAD\"])).trim();\n repo.git.isShallowClone = await isShallowClone(git);\n repo.git.remoteUrl = await getOriginUrl(git, repo.git.remoteUrl);\n\n return localPath;\n}\n\nasync function cloneNewRepository(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = createGit(undefined, GIT_CLONE_TIMEOUT_MS);\n const cloneArgs = [\"--depth\", \"1\", \"--branch\", repo.meta.defaultBranch];\n\n try {\n await retryGitOperation(\n () => git.clone(repo.git.remoteUrl, localPath, cloneArgs),\n `clone ${repo.fullName}`,\n );\n } catch (httpsError) {\n if (!repo.git.sshUrl) throw httpsError;\n\n // HTTPS failed — try SSH (e.g. user has SSH keys but no HTTPS credentials)\n await cleanPartialClone(localPath);\n try {\n await retryGitOperation(\n () => git.clone(repo.git.sshUrl!, localPath, cloneArgs),\n `clone ${repo.fullName} (SSH fallback)`,\n );\n } catch (sshError) {\n throw new Error(\n `Failed to clone \"${repo.fullName}\" via both HTTPS and SSH.\\n` +\n \"Ensure git credentials are configured: run `gh auth login` or set up SSH keys.\\n\" +\n `HTTPS error: ${httpsError instanceof Error ? httpsError.message : httpsError}\\n` +\n `SSH error: ${sshError instanceof Error ? sshError.message : sshError}`,\n { cause: sshError },\n );\n }\n }\n}\n\nasync function pullExistingClone(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = createGit(localPath);\n await ensureOriginRemote(git, repo.git.remoteUrl);\n\n try {\n await retryGitOperation(\n () => git.fetch(\"origin\", repo.meta.defaultBranch, [\"--depth=1\", \"--prune\"]),\n `fetch ${repo.fullName}`,\n );\n } catch (fetchError) {\n if (!repo.git.sshUrl) throw fetchError;\n\n // HTTPS fetch failed — switch remote to SSH and retry\n await ensureOriginRemote(git, repo.git.sshUrl);\n await retryGitOperation(\n () => git.fetch(\"origin\", repo.meta.defaultBranch, [\"--depth=1\", \"--prune\"]),\n `fetch ${repo.fullName} (SSH fallback)`,\n );\n }\n\n await checkoutDefaultBranch(git, repo.meta.defaultBranch);\n\n await retryGitOperation(\n () => hardSyncDefaultBranch(git, repo.meta.defaultBranch),\n `sync ${repo.fullName}`,\n );\n}\n\nasync function checkoutDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n try {\n await git.checkout(branchName);\n } catch {\n await git.raw([\"checkout\", \"-B\", branchName, `origin/${branchName}`]);\n }\n}\n\nasync function hardSyncDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n // The cache clone is disposable, so force-align it with origin to avoid stale divergence.\n await git.raw([\"reset\", \"--hard\", `origin/${branchName}`]);\n await git.raw([\"clean\", \"-fd\"]);\n}\n\nasync function ensureOriginRemote(git: SimpleGit, remoteUrl: string): Promise<void> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n\n if (!origin) {\n await git.addRemote(\"origin\", remoteUrl);\n return;\n }\n\n if (origin.refs.fetch !== remoteUrl && origin.refs.push !== remoteUrl) {\n await git.remote([\"set-url\", \"origin\", remoteUrl]);\n }\n}\n\nasync function getOriginUrl(git: SimpleGit, fallbackUrl: string): Promise<string> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n return origin?.refs.fetch ?? fallbackUrl;\n}\n\nasync function isShallowClone(git: SimpleGit): Promise<boolean> {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n}\n\nasync function retryGitOperation<T>(\n operation: () => Promise<T>,\n operationName: string,\n): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= CLONE_RETRY_BACKOFF_MS.length; attempt += 1) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n if (attempt === CLONE_RETRY_BACKOFF_MS.length) {\n break;\n }\n await sleep(CLONE_RETRY_BACKOFF_MS[attempt]);\n }\n }\n\n throw new Error(\n `Git operation failed after ${CLONE_RETRY_BACKOFF_MS.length + 1} attempts (${operationName}).`,\n { cause: lastError },\n );\n}\n\nfunction resolveCacheDir(cacheDir: string): string {\n const selected = cacheDir.trim().length > 0 ? cacheDir : DEFAULT_REPO_CACHE_DIR;\n return resolve(expandHomePath(selected));\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitRepository(path: string): Promise<boolean> {\n return pathExists(join(path, \".git\"));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolvePromise) => {\n setTimeout(resolvePromise, ms);\n });\n}\n\n/**\n * Create a `SimpleGit` instance with `GIT_TERMINAL_PROMPT=0` (prevents\n * silent credential prompts that hang forever) and a rolling timeout that\n * kills the spawned process if it produces no output for `timeoutMs`.\n *\n * NOTE: `simple-git`'s `.env(key, value)` **replaces** the entire process\n * environment. We must spread `process.env` so the child git process still\n * has `HOME`, `PATH`, `SSH_AUTH_SOCK`, etc.\n */\nfunction createGit(baseDir?: string, timeoutMs = GIT_FETCH_TIMEOUT_MS): SimpleGit {\n return simpleGit({\n ...(baseDir ? { baseDir } : {}),\n timeout: { block: timeoutMs },\n }).env({ ...process.env, GIT_TERMINAL_PROMPT: \"0\" });\n}\n\nasync function cleanPartialClone(localPath: string): Promise<void> {\n try {\n await rm(localPath, { recursive: true, force: true });\n } catch {\n /* best-effort cleanup before SSH retry */\n }\n}\n"],"mappings":"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","names":["homedir","join","join","homedir","fsConstants","access","mkdir","homedir","dirname","join","pathExists","expandHomePath"]}
package/dist/cli/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createCliProgram,
3
3
  runCli
4
- } from "../chunk-4IUL7ECC.js";
5
- import "../chunk-CJAJ4MBO.js";
4
+ } from "../chunk-7Y4LZUDP.js";
5
+ import "../chunk-OS3XDHOJ.js";
6
6
  import "../chunk-OTPXGXO7.js";
7
7
  import "../chunk-5GAUWC3L.js";
8
8
  import "../chunk-QPVNC7S4.js";
package/dist/cli/index.js CHANGED
@@ -4,8 +4,8 @@ import {
4
4
  EXIT_CONFIG_ERROR,
5
5
  EXIT_GENERAL_ERROR,
6
6
  runCli
7
- } from "../chunk-4IUL7ECC.js";
8
- import "../chunk-CJAJ4MBO.js";
7
+ } from "../chunk-7Y4LZUDP.js";
8
+ import "../chunk-OS3XDHOJ.js";
9
9
  import "../chunk-OTPXGXO7.js";
10
10
  import "../chunk-5GAUWC3L.js";
11
11
  import "../chunk-QPVNC7S4.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  cloneRepo,
3
3
  resolveRepo
4
- } from "../chunk-CJAJ4MBO.js";
4
+ } from "../chunk-OS3XDHOJ.js";
5
5
  import {
6
6
  CompositeScanner,
7
7
  GitHubIssuesScanner,
@@ -1,5 +1,5 @@
1
1
  import { h as TaskSource, T as Task, g as TaskComplexity, E as Epic } from '../types-Ck7IucqK.js';
2
- import { R as ResolvedRepo } from '../types-CYCwgojB.js';
2
+ import { R as ResolvedRepo } from '../types-3_IAAxh5.js';
3
3
  import { O as OacConfig } from '../config-DequKoFA.js';
4
4
  import 'zod';
5
5
 
@@ -1,5 +1,5 @@
1
- import { R as ResolvedRepo } from '../types-CYCwgojB.js';
2
- export { a as RepoPermissions, b as ResolvedRepoGitState, c as ResolvedRepoMeta } from '../types-CYCwgojB.js';
1
+ import { R as ResolvedRepo } from '../types-3_IAAxh5.js';
2
+ export { a as RepoPermissions, b as ResolvedRepoGitState, c as ResolvedRepoMeta } from '../types-3_IAAxh5.js';
3
3
 
4
4
  type RepoResolutionErrorCode = "INVALID_INPUT" | "NOT_FOUND" | "FORBIDDEN" | "ARCHIVED" | "UNKNOWN";
5
5
  declare class RepoResolutionError extends Error {
@@ -6,7 +6,7 @@ import {
6
6
  RepoResolutionError,
7
7
  cloneRepo,
8
8
  resolveRepo
9
- } from "../chunk-CJAJ4MBO.js";
9
+ } from "../chunk-OS3XDHOJ.js";
10
10
  export {
11
11
  DEFAULT_METADATA_CACHE_PATH,
12
12
  DEFAULT_METADATA_CACHE_TTL_MS,
@@ -19,6 +19,7 @@ interface ResolvedRepoMeta {
19
19
  interface ResolvedRepoGitState {
20
20
  headSha: string;
21
21
  remoteUrl: string;
22
+ sshUrl?: string;
22
23
  isShallowClone: boolean;
23
24
  }
24
25
  interface ResolvedRepo {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open330/oac",
3
- "version": "2026.2.5",
3
+ "version": "2026.220.1",
4
4
  "description": "Open Agent Contribution - automate open source contributions with AI agents",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,6 +36,19 @@
36
36
  "engines": {
37
37
  "node": ">=20.0.0"
38
38
  },
39
+ "packageManager": "pnpm@9.15.4",
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "test": "vitest run",
43
+ "test:coverage": "vitest run --coverage",
44
+ "lint": "biome check .",
45
+ "lint:fix": "biome check --write .",
46
+ "format": "biome format --write .",
47
+ "typecheck": "tsc --noEmit",
48
+ "dev:dashboard": "tsx src/dashboard/dev.ts",
49
+ "clean": "rm -rf dist coverage",
50
+ "prepublishOnly": "pnpm build && pnpm test"
51
+ },
39
52
  "dependencies": {
40
53
  "@fastify/cors": "^10.0.2",
41
54
  "@fastify/static": "^8.1.0",
@@ -67,16 +80,5 @@
67
80
  "tsx": "^4.19.0",
68
81
  "typescript": "^5.7.3",
69
82
  "vitest": "^3.0.5"
70
- },
71
- "scripts": {
72
- "build": "tsup",
73
- "test": "vitest run",
74
- "test:coverage": "vitest run --coverage",
75
- "lint": "biome check .",
76
- "lint:fix": "biome check --write .",
77
- "format": "biome format --write .",
78
- "typecheck": "tsc --noEmit",
79
- "dev:dashboard": "tsx src/dashboard/dev.ts",
80
- "clean": "rm -rf dist coverage"
81
83
  }
82
- }
84
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/repo/resolver.ts","../src/repo/metadata-cache.ts","../src/repo/cloner.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { Octokit } from \"@octokit/rest\";\nimport { MetadataCache } from \"./metadata-cache.js\";\nimport type { RepoPermissions, ResolvedRepo } from \"./types.js\";\n\nconst OWNER_REPO_PATTERN = /^(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\nconst GITHUB_SSH_PATTERN =\n /^git@github\\.com:(?<owner>[A-Za-z0-9_.-]+)\\/(?<repo>[A-Za-z0-9_.-]+?)(?:\\.git)?$/;\n\nexport type RepoResolutionErrorCode =\n | \"INVALID_INPUT\"\n | \"NOT_FOUND\"\n | \"FORBIDDEN\"\n | \"ARCHIVED\"\n | \"UNKNOWN\";\n\nexport class RepoResolutionError extends Error {\n public readonly code: RepoResolutionErrorCode;\n\n public constructor(message: string, code: RepoResolutionErrorCode, cause?: unknown) {\n super(message, { cause });\n this.name = \"RepoResolutionError\";\n this.code = code;\n }\n}\n\ninterface ParsedRepoInput {\n owner: string;\n name: string;\n}\n\nexport async function resolveRepo(input: string): Promise<ResolvedRepo> {\n const parsed = parseRepoInput(input);\n const cache = new MetadataCache();\n const cacheKey = `${parsed.owner}/${parsed.name}`;\n const cached = await cache.get(cacheKey);\n\n if (cached) {\n return cached;\n }\n\n const octokit = new Octokit({\n auth: resolveGitHubToken(),\n });\n\n const repoData = await fetchRepo(octokit, parsed.owner, parsed.name);\n if (repoData.archived) {\n throw new RepoResolutionError(\n `Repository \"${repoData.full_name}\" is archived and cannot be used for contributions.`,\n \"ARCHIVED\",\n );\n }\n\n const permissions = normalizePermissions(repoData.private, repoData.permissions);\n if (!permissions.pull) {\n throw new RepoResolutionError(\n `Missing pull permission for \"${repoData.full_name}\".`,\n \"FORBIDDEN\",\n );\n }\n\n const [languages, headSha] = await Promise.all([\n fetchLanguages(octokit, repoData.owner.login, repoData.name),\n fetchHeadSha(octokit, repoData.owner.login, repoData.name, repoData.default_branch),\n ]);\n\n const localPath = defaultLocalPath(repoData.owner.login, repoData.name);\n const resolved: ResolvedRepo = {\n fullName: repoData.full_name,\n owner: repoData.owner.login,\n name: repoData.name,\n localPath,\n worktreePath: join(localPath, \"..\", \".oac-worktrees\", repoData.default_branch),\n meta: {\n defaultBranch: repoData.default_branch,\n language: repoData.language,\n languages,\n size: repoData.size,\n stars: repoData.stargazers_count,\n openIssuesCount: repoData.open_issues_count,\n topics: repoData.topics ?? [],\n license: normalizeLicense(repoData.license?.spdx_id ?? null),\n isArchived: repoData.archived,\n isFork: repoData.fork,\n permissions,\n },\n git: {\n headSha,\n remoteUrl: repoData.clone_url ?? `https://github.com/${repoData.full_name}.git`,\n isShallowClone: true,\n },\n };\n\n await cache.set(resolved.fullName, resolved);\n return resolved;\n}\n\nfunction parseRepoInput(input: string): ParsedRepoInput {\n const normalized = input.trim();\n if (!normalized) {\n throw new RepoResolutionError(\"Repository input cannot be empty.\", \"INVALID_INPUT\");\n }\n\n const ownerRepoMatch = normalized.match(OWNER_REPO_PATTERN);\n if (ownerRepoMatch?.groups) {\n return {\n owner: ownerRepoMatch.groups.owner,\n name: ownerRepoMatch.groups.repo,\n };\n }\n\n const sshMatch = normalized.match(GITHUB_SSH_PATTERN);\n if (sshMatch?.groups) {\n return {\n owner: sshMatch.groups.owner,\n name: sshMatch.groups.repo,\n };\n }\n\n const normalizedUrlInput = normalized.startsWith(\"github.com/\")\n ? `https://${normalized}`\n : normalized;\n\n try {\n const url = new URL(normalizedUrlInput);\n if (!isGitHubHost(url.hostname)) {\n throw new RepoResolutionError(\n `Only github.com repository URLs are supported, received \"${url.hostname}\".`,\n \"INVALID_INPUT\",\n );\n }\n\n const pathParts = url.pathname.split(\"/\").filter(Boolean);\n if (pathParts.length < 2) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n const owner = pathParts[0];\n const name = stripGitSuffix(pathParts[1]);\n if (!owner || !name) {\n throw new RepoResolutionError(`Invalid GitHub repository URL \"${input}\".`, \"INVALID_INPUT\");\n }\n\n return { owner, name };\n } catch (error) {\n if (error instanceof RepoResolutionError) {\n throw error;\n }\n\n throw new RepoResolutionError(\n `Expected \"owner/repo\" or a GitHub repository URL, received \"${input}\".`,\n \"INVALID_INPUT\",\n error,\n );\n }\n}\n\nasync function fetchRepo(octokit: Octokit, owner: string, repo: string) {\n try {\n return (await octokit.repos.get({ owner, repo })).data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchLanguages(\n octokit: Octokit,\n owner: string,\n repo: string,\n): Promise<Record<string, number>> {\n try {\n const response = await octokit.repos.listLanguages({ owner, repo });\n return response.data;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nasync function fetchHeadSha(\n octokit: Octokit,\n owner: string,\n repo: string,\n defaultBranch: string,\n): Promise<string> {\n try {\n const branch = await octokit.repos.getBranch({\n owner,\n repo,\n branch: defaultBranch,\n });\n return branch.data.commit.sha;\n } catch (error) {\n throw toResolutionError(owner, repo, error);\n }\n}\n\nfunction toResolutionError(owner: string, repo: string, error: unknown): RepoResolutionError {\n const fullName = `${owner}/${repo}`;\n const status = isApiError(error) ? error.status : undefined;\n const message =\n typeof error === \"object\" && error && \"message\" in error\n ? String(error.message)\n : \"unknown error\";\n\n if (status === 404) {\n const hasToken = !!(process.env.GITHUB_TOKEN || process.env.GH_TOKEN);\n const hint = hasToken\n ? `If this is a private repo, ensure your token has the \"repo\" scope: gh auth refresh -s repo`\n : \"If this is a private repo, authenticate first: gh auth login\";\n return new RepoResolutionError(\n `Repository \"${fullName}\" was not found on GitHub. ${hint}`,\n \"NOT_FOUND\",\n error,\n );\n }\n\n if (status === 403) {\n return new RepoResolutionError(\n `Access denied for \"${fullName}\". Ensure your token has the \"repo\" scope: gh auth refresh -s repo`,\n \"FORBIDDEN\",\n error,\n );\n }\n\n return new RepoResolutionError(\n `Failed to resolve repository \"${fullName}\": ${message}`,\n \"UNKNOWN\",\n error,\n );\n}\n\nfunction normalizePermissions(\n isPrivateRepo: boolean,\n permissions:\n | {\n admin?: boolean;\n push?: boolean;\n pull?: boolean;\n }\n | undefined,\n): RepoPermissions {\n const pull = permissions?.pull ?? !isPrivateRepo;\n\n return {\n push: permissions?.push ?? false,\n pull,\n admin: permissions?.admin ?? false,\n };\n}\n\nfunction normalizeLicense(spdxId: string | null): string | null {\n if (!spdxId || spdxId === \"NOASSERTION\") {\n return null;\n }\n\n return spdxId;\n}\n\nfunction isGitHubHost(hostname: string): boolean {\n const normalized = hostname.toLowerCase();\n return normalized === \"github.com\" || normalized === \"www.github.com\";\n}\n\nfunction stripGitSuffix(repo: string): string {\n return repo.replace(/\\.git$/i, \"\");\n}\n\nfunction isApiError(error: unknown): error is { status?: number } {\n return typeof error === \"object\" && error !== null && \"status\" in error;\n}\n\nfunction defaultLocalPath(owner: string, name: string): string {\n return join(homedir(), \".oac\", \"cache\", \"repos\", owner, name);\n}\n\nfunction resolveGitHubToken(): string | undefined {\n const githubToken = process.env.GITHUB_TOKEN?.trim();\n if (githubToken) {\n process.env.GITHUB_TOKEN = githubToken;\n return githubToken;\n }\n\n const ghToken = process.env.GH_TOKEN?.trim();\n if (ghToken) {\n process.env.GITHUB_TOKEN = ghToken;\n return ghToken;\n }\n\n try {\n const token = execFileSync(\"gh\", [\"auth\", \"token\"], {\n timeout: 5_000,\n encoding: \"utf-8\",\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n }).trim();\n\n if (token.length > 0) {\n process.env.GITHUB_TOKEN = token;\n return token;\n }\n } catch {\n // gh not installed or not authenticated\n }\n\n return undefined;\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir, readFile, rename, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport type { ResolvedRepo } from \"./types.js\";\n\ninterface MetadataCacheEntry {\n cachedAt: number;\n repo: ResolvedRepo;\n}\n\ninterface MetadataCacheFile {\n version: 1;\n entries: Record<string, MetadataCacheEntry>;\n}\n\nexport interface MetadataCacheOptions {\n filePath?: string;\n ttlMs?: number;\n now?: () => number;\n}\n\nexport const DEFAULT_METADATA_CACHE_PATH = join(homedir(), \".oac\", \"cache\", \"repos.json\");\n\nexport const DEFAULT_METADATA_CACHE_TTL_MS = 60 * 60 * 1000;\n\nconst EMPTY_CACHE: MetadataCacheFile = {\n version: 1,\n entries: {},\n};\n\nexport class MetadataCache {\n private readonly filePath: string;\n private readonly ttlMs: number;\n private readonly now: () => number;\n\n public constructor(options: MetadataCacheOptions = {}) {\n this.filePath = expandHomePath(options.filePath ?? DEFAULT_METADATA_CACHE_PATH);\n this.ttlMs = options.ttlMs ?? DEFAULT_METADATA_CACHE_TTL_MS;\n this.now = options.now ?? Date.now;\n }\n\n public async get(fullName: string): Promise<ResolvedRepo | null> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n const entry = cache.entries[key];\n\n if (!entry) {\n return null;\n }\n\n if (this.now() - entry.cachedAt > this.ttlMs) {\n delete cache.entries[key];\n await this.writeCache(cache);\n return null;\n }\n\n return entry.repo;\n }\n\n public async set(fullName: string, repo: ResolvedRepo): Promise<void> {\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n cache.entries[key] = {\n cachedAt: this.now(),\n repo,\n };\n await this.writeCache(cache);\n }\n\n public async invalidate(fullName?: string): Promise<void> {\n if (!fullName) {\n await this.writeCache(EMPTY_CACHE);\n return;\n }\n\n const cache = await this.readCache();\n const key = normalizeCacheKey(fullName);\n if (!(key in cache.entries)) {\n return;\n }\n\n delete cache.entries[key];\n await this.writeCache(cache);\n }\n\n private async readCache(): Promise<MetadataCacheFile> {\n if (!(await pathExists(this.filePath))) {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n try {\n const raw = await readFile(this.filePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<MetadataCacheFile>;\n\n if (parsed.version !== 1 || typeof parsed.entries !== \"object\") {\n return { ...EMPTY_CACHE, entries: {} };\n }\n\n return {\n version: 1,\n entries: parsed.entries as Record<string, MetadataCacheEntry>,\n };\n } catch {\n return { ...EMPTY_CACHE, entries: {} };\n }\n }\n\n private async writeCache(cache: MetadataCacheFile): Promise<void> {\n await mkdir(dirname(this.filePath), { recursive: true });\n const tempPath = `${this.filePath}.tmp`;\n await writeFile(tempPath, JSON.stringify(cache, null, 2), \"utf8\");\n await rename(tempPath, this.filePath);\n }\n}\n\nfunction normalizeCacheKey(fullName: string): string {\n return fullName.trim().toLowerCase();\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n","import { constants as fsConstants } from \"node:fs\";\nimport { access, mkdir } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport type { ResolvedRepo } from \"./types.js\";\n\nconst CLONE_RETRY_BACKOFF_MS = [1000, 4000, 16000] as const;\n\nexport const DEFAULT_REPO_CACHE_DIR = join(homedir(), \".oac\", \"cache\", \"repos\");\n\nexport async function cloneRepo(\n repo: ResolvedRepo,\n cacheDir: string = DEFAULT_REPO_CACHE_DIR,\n): Promise<string> {\n const cacheRoot = resolveCacheDir(cacheDir);\n const localPath = join(cacheRoot, repo.owner, repo.name);\n await mkdir(dirname(localPath), { recursive: true });\n\n if (await isGitRepository(localPath)) {\n await pullExistingClone(repo, localPath);\n } else if (await pathExists(localPath)) {\n throw new Error(\n `Cannot clone \"${repo.fullName}\" into \"${localPath}\" because the directory exists and is not a git repository.`,\n );\n } else {\n await cloneNewRepository(repo, localPath);\n }\n\n const git = simpleGit(localPath);\n repo.localPath = localPath;\n repo.worktreePath = join(localPath, \"..\", \".oac-worktrees\", repo.meta.defaultBranch);\n repo.git.headSha = (await git.revparse([\"HEAD\"])).trim();\n repo.git.isShallowClone = await isShallowClone(git);\n repo.git.remoteUrl = await getOriginUrl(git, repo.git.remoteUrl);\n\n return localPath;\n}\n\nasync function cloneNewRepository(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = simpleGit();\n await retryGitOperation(\n () =>\n git.clone(repo.git.remoteUrl, localPath, [\n \"--depth\",\n \"1\",\n \"--branch\",\n repo.meta.defaultBranch,\n ]),\n `clone ${repo.fullName}`,\n );\n}\n\nasync function pullExistingClone(repo: ResolvedRepo, localPath: string): Promise<void> {\n const git = simpleGit(localPath);\n await ensureOriginRemote(git, repo.git.remoteUrl);\n\n await retryGitOperation(\n () => git.fetch(\"origin\", repo.meta.defaultBranch, [\"--depth=1\", \"--prune\"]),\n `fetch ${repo.fullName}`,\n );\n\n await checkoutDefaultBranch(git, repo.meta.defaultBranch);\n\n await retryGitOperation(\n () => hardSyncDefaultBranch(git, repo.meta.defaultBranch),\n `sync ${repo.fullName}`,\n );\n}\n\nasync function checkoutDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n try {\n await git.checkout(branchName);\n } catch {\n await git.raw([\"checkout\", \"-B\", branchName, `origin/${branchName}`]);\n }\n}\n\nasync function hardSyncDefaultBranch(git: SimpleGit, branchName: string): Promise<void> {\n // The cache clone is disposable, so force-align it with origin to avoid stale divergence.\n await git.raw([\"reset\", \"--hard\", `origin/${branchName}`]);\n await git.raw([\"clean\", \"-fd\"]);\n}\n\nasync function ensureOriginRemote(git: SimpleGit, remoteUrl: string): Promise<void> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n\n if (!origin) {\n await git.addRemote(\"origin\", remoteUrl);\n return;\n }\n\n if (origin.refs.fetch !== remoteUrl && origin.refs.push !== remoteUrl) {\n await git.remote([\"set-url\", \"origin\", remoteUrl]);\n }\n}\n\nasync function getOriginUrl(git: SimpleGit, fallbackUrl: string): Promise<string> {\n const remotes = await git.getRemotes(true);\n const origin = remotes.find((remote) => remote.name === \"origin\");\n return origin?.refs.fetch ?? fallbackUrl;\n}\n\nasync function isShallowClone(git: SimpleGit): Promise<boolean> {\n const output = await git.raw([\"rev-parse\", \"--is-shallow-repository\"]);\n return output.trim() === \"true\";\n}\n\nasync function retryGitOperation<T>(\n operation: () => Promise<T>,\n operationName: string,\n): Promise<T> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= CLONE_RETRY_BACKOFF_MS.length; attempt += 1) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n if (attempt === CLONE_RETRY_BACKOFF_MS.length) {\n break;\n }\n await sleep(CLONE_RETRY_BACKOFF_MS[attempt]);\n }\n }\n\n throw new Error(\n `Git operation failed after ${CLONE_RETRY_BACKOFF_MS.length + 1} attempts (${operationName}).`,\n { cause: lastError },\n );\n}\n\nfunction resolveCacheDir(cacheDir: string): string {\n const selected = cacheDir.trim().length > 0 ? cacheDir : DEFAULT_REPO_CACHE_DIR;\n return resolve(expandHomePath(selected));\n}\n\nfunction expandHomePath(path: string): string {\n if (path === \"~\") {\n return homedir();\n }\n\n if (path.startsWith(\"~/\")) {\n return join(homedir(), path.slice(2));\n }\n\n return path;\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path, fsConstants.F_OK);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function isGitRepository(path: string): Promise<boolean> {\n return pathExists(join(path, \".git\"));\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolvePromise) => {\n setTimeout(resolvePromise, ms);\n });\n}\n"],"mappings":"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","names":["homedir","join","join","homedir","fsConstants","access","mkdir","homedir","dirname","join","pathExists","expandHomePath"]}