* chore: remove dead/unreferenced files across ui, vscode Remove 59 unused source files (components, hooks, lib utils, stores, barrels, and orphaned vscode github modules) that are not imported by any entry-reachable code. Also drop a stale test mock for the removed execCommands module. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * refactor: remove unused exported symbols (types, functions, consts, hooks) Remove exported symbols whose identifier is referenced nowhere in the repository (verified via repo-wide search), across ui types/contracts, lib utilities, sync layer, stores, and components. Also drop the few imports/private helpers orphaned by these removals. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * refactor: remove more unused exports (desktop, shortcuts, worktree, vscode) Continue removing repo-wide unreferenced exported functions, consts and types across lib/desktop, shortcuts, worktreeSessionCreator, sync, and vscode gitService, with cascading orphaned helpers/imports cleaned up. Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> * chore: add dead-code cleanup tooling * refactor: checkpoint dead-code cleanup * refactor: remove dead-code suppressions --------- Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
93 lines
3.5 KiB
JavaScript
93 lines
3.5 KiB
JavaScript
const GITHUB_HOST = 'github.com';
|
|
const CLAWDHUB_SOURCE_PREFIX = 'clawdhub:';
|
|
|
|
|
|
function normalizeGitOwnerRepo(owner, repo) {
|
|
const normalizedOwner = String(owner || '').trim();
|
|
const normalizedRepo = String(repo || '').trim().replace(/\.git$/i, '');
|
|
if (!normalizedOwner || !normalizedRepo) {
|
|
return null;
|
|
}
|
|
return { owner: normalizedOwner, repo: normalizedRepo };
|
|
}
|
|
|
|
|
|
export function parseSkillRepoSource(input, options = {}) {
|
|
const raw = typeof input === 'string' ? input.trim() : '';
|
|
if (!raw) {
|
|
return { ok: false, error: { kind: 'invalidSource', message: 'Repository source is required' } };
|
|
}
|
|
const explicitSubpath = typeof options.subpath === 'string' && options.subpath.trim() ? options.subpath.trim() : null;
|
|
|
|
const urlFormat = raw.startsWith('https://') ? 'https' : raw.startsWith('git@') ? 'ssh' : 'shorthand';
|
|
const gitHost = urlFormat === 'https' ? raw.split('/')[2] : urlFormat === 'ssh' ? raw.split('@')[1].split(':')[0] : null;
|
|
|
|
if (gitHost === null && urlFormat !== 'shorthand') {
|
|
return { ok: false, error: { kind: 'invalidSource', message: 'Invalid repository URL format' } };
|
|
}
|
|
|
|
const pathSegments = urlFormat === 'https'
|
|
? raw.split('/').slice(3).filter(Boolean)
|
|
: urlFormat === 'ssh'
|
|
? (raw.split('@')[1].split(':')[1] ?? '').split('/').filter(Boolean)
|
|
: null;
|
|
|
|
const repoName = pathSegments && pathSegments.length > 0
|
|
? pathSegments[pathSegments.length - 1].replace(/\.git$/i, '')
|
|
: null;
|
|
|
|
const gitOwner = pathSegments && pathSegments.length > 1
|
|
? pathSegments.slice(0, -1).join('/')
|
|
: (pathSegments && pathSegments.length === 1 ? pathSegments[0] : null);
|
|
|
|
|
|
// SSH git@host:owner/repo(.git) or HTTPS https://host/owner/repo(.git)
|
|
if (urlFormat === 'ssh' || urlFormat === 'https') {
|
|
const parsed = normalizeGitOwnerRepo(gitOwner, repoName);
|
|
if (!parsed) {
|
|
return { ok: false, error: { kind: 'invalidSource', message: `Invalid ${urlFormat} repository URL` } };
|
|
}
|
|
|
|
return {
|
|
ok: true,
|
|
host: gitHost,
|
|
owner: parsed.owner,
|
|
repo: parsed.repo,
|
|
cloneUrlSsh: `git@${gitHost}:${parsed.owner}/${parsed.repo}.git`,
|
|
cloneUrlHttps: `https://${gitHost}/${parsed.owner}/${parsed.repo}.git`,
|
|
// For SSH URLs, subpath is only accepted via options.subpath
|
|
effectiveSubpath: explicitSubpath,
|
|
normalizedRepo: `${parsed.owner}/${parsed.repo}`,
|
|
};
|
|
}
|
|
|
|
// Shorthand: owner/repo[/subpath...]
|
|
const shorthandMatch = raw.match(/^([^/\s]+)\/([^/\s]+)(?:\/(.+))?$/);
|
|
if (shorthandMatch) {
|
|
const parsed = normalizeGitOwnerRepo(shorthandMatch[1], shorthandMatch[2]);
|
|
if (!parsed) {
|
|
return { ok: false, error: { kind: 'invalidSource', message: 'Invalid repository source' } };
|
|
}
|
|
|
|
const shorthandSubpath = typeof shorthandMatch[3] === 'string' && shorthandMatch[3].trim() ? shorthandMatch[3].trim() : null;
|
|
const effectiveSubpath = explicitSubpath || shorthandSubpath;
|
|
|
|
return {
|
|
ok: true,
|
|
host: GITHUB_HOST,
|
|
owner: parsed.owner,
|
|
repo: parsed.repo,
|
|
cloneUrlSsh: `git@github.com:${parsed.owner}/${parsed.repo}.git`,
|
|
cloneUrlHttps: `https://github.com/${parsed.owner}/${parsed.repo}.git`,
|
|
effectiveSubpath,
|
|
normalizedRepo: `${parsed.owner}/${parsed.repo}`,
|
|
};
|
|
}
|
|
|
|
return { ok: false, error: { kind: 'invalidSource', message: 'Unsupported repository source format' } };
|
|
}
|
|
|
|
export function isClawdHubSource(input) {
|
|
return typeof input === 'string' && input.trim().toLowerCase().startsWith(CLAWDHUB_SOURCE_PREFIX);
|
|
}
|