mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-18 00:02:45 +00:00
feat(coding-agent): add SSH URL support for git packages
Use hosted-git-info library for robust parsing of SSH URLs (git@host:path and ssh://) in addition to HTTPS. SSH and HTTPS URLs for the same repo are now properly deduplicated.
This commit is contained in:
parent
0404a93e33
commit
fba9a8aece
9 changed files with 576 additions and 48 deletions
|
|
@ -1,6 +1,71 @@
|
|||
const GIT_HOSTS = ["github.com", "gitlab.com", "bitbucket.org", "codeberg.org"];
|
||||
import hostedGitInfo from "hosted-git-info";
|
||||
|
||||
export function looksLikeGitUrl(source: string): boolean {
|
||||
const normalized = source.replace(/^https?:\/\//, "");
|
||||
return GIT_HOSTS.some((host) => normalized.startsWith(`${host}/`));
|
||||
/**
|
||||
* Parsed git URL information.
|
||||
*/
|
||||
export type GitSource = {
|
||||
/** Always "git" for git sources */
|
||||
type: "git";
|
||||
/** Clone URL (always valid for git clone, without ref suffix) */
|
||||
repo: string;
|
||||
/** Git host domain (e.g., "github.com") */
|
||||
host: string;
|
||||
/** Repository path (e.g., "user/repo") */
|
||||
path: string;
|
||||
/** Git ref (branch, tag, commit) if specified */
|
||||
ref?: string;
|
||||
/** True if ref was specified (package won't be auto-updated) */
|
||||
pinned: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse any git URL (SSH or HTTPS) into a GitSource.
|
||||
*/
|
||||
export function parseGitUrl(source: string): GitSource | null {
|
||||
let url = source.startsWith("git:") ? source.slice(4).trim() : source;
|
||||
|
||||
// Try hosted-git-info, converting @ref to #ref if needed
|
||||
let info = hostedGitInfo.fromUrl(url);
|
||||
const lastAt = url.lastIndexOf("@");
|
||||
if ((info?.project?.includes("@") || !info) && lastAt > 0) {
|
||||
info = hostedGitInfo.fromUrl(`${url.slice(0, lastAt)}#${url.slice(lastAt + 1)}`) ?? info;
|
||||
url = url.slice(0, lastAt); // strip ref from url for repo field
|
||||
}
|
||||
|
||||
// Try with https:// prefix for shorthand URLs
|
||||
if (!info) {
|
||||
info = hostedGitInfo.fromUrl(`https://${url}`);
|
||||
if (info) url = `https://${url}`; // make repo a valid clone URL
|
||||
}
|
||||
|
||||
if (info) {
|
||||
return {
|
||||
type: "git",
|
||||
repo: url,
|
||||
host: info.domain || "",
|
||||
path: `${info.user}/${info.project}`,
|
||||
ref: info.committish || undefined,
|
||||
pinned: Boolean(info.committish),
|
||||
};
|
||||
}
|
||||
|
||||
// Fallback for codeberg (not in hosted-git-info)
|
||||
const normalized = url.replace(/^https?:\/\//, "").replace(/@[^/]*$/, "");
|
||||
const codebergHost = "codeberg.org";
|
||||
if (normalized.startsWith(`${codebergHost}/`)) {
|
||||
const ref = url.match(/@([^/]+)$/)?.[1];
|
||||
const repoUrl = ref ? url.slice(0, url.lastIndexOf("@")) : url;
|
||||
// Ensure repo is a valid clone URL
|
||||
const cloneableRepo = repoUrl.startsWith("http") ? repoUrl : `https://${repoUrl}`;
|
||||
return {
|
||||
type: "git",
|
||||
repo: cloneableRepo,
|
||||
host: codebergHost,
|
||||
path: normalized.slice(codebergHost.length + 1).replace(/\.git$/, ""),
|
||||
ref,
|
||||
pinned: Boolean(ref),
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue