openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
339 lines (338 loc) • 16.1 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-1VuiLaaR.mjs";
import { d as pathExists } from "./fs-safe-BUXBSN-4.mjs";
import { c as readFileDescriptorBoundedSync, o as openRootFileSync } from "./boundary-file-read-CCth2Hwg.mjs";
import { t as formatErrorMessage } from "./errors-O33D01XW.mjs";
import { v as resolveClawHubBaseUrl } from "./clawhub-client-D-mEumEV.mjs";
import { r as CLAWHUB_SKILLS_SH_TRUST_STATE, u as searchClawHubSkills } from "./clawhub-skills-BFN100ff.mjs";
import { n as resolveWorkspaceSkillInstallDir, r as validateRequestedSkillSlug, t as normalizeTrackedSkillSlug } from "./install-paths-CdlkBGI2.mjs";
import { a as normalizeSkillFileLock, c as readClawHubSkillOrigin, d as readClawHubSkillsLockfile, f as readClawHubSkillsLockfileStatusSync, g as resolveWorkspaceClawHubSkills, l as readClawHubSkillOriginStatusSync, o as normalizeStoredRegistry, r as normalizeDownloadedArtifactLock, s as parseRequestedClawHubSkillRef, u as readClawHubSkillOriginStrict } from "./clawhub-store-mPse6L69.mjs";
import fs from "node:fs";
import path from "node:path";
//#region src/skills/lifecycle/clawhub-status.ts
const LOCAL_SKILL_CARD_FILENAME = "skill-card.md";
const LOCAL_SKILL_CARD_MAX_BYTES = 262144;
function readRealPathSync(candidate) {
try {
return fs.realpathSync.native(candidate);
} catch {
return;
}
}
function invalidLink(reason, details) {
return {
status: "invalid",
valid: false,
reason,
...details
};
}
function resolveClawHubSkillStatusLinkSync(params) {
const originRead = readClawHubSkillOriginStatusSync(params.skillDir);
const lockRead = params.lockRead ?? readClawHubSkillsLockfileStatusSync(params.workspaceDir);
const lockfileLabel = `${params.lockfileScope ?? "workspace"} ClawHub lockfile`;
if (originRead.kind === "missing") {
let trackedSlug;
try {
trackedSlug = normalizeTrackedSkillSlug(params.skillKey);
} catch {
return;
}
const locked = lockRead.kind === "found" ? lockRead.lock.skills[trackedSlug] : void 0;
if (!locked) return;
return invalidLink(`Skill "${trackedSlug}" is tracked by the ${lockfileLabel} but is missing local ClawHub origin metadata.`, {
slug: trackedSlug,
installedVersion: locked.version,
installedAt: locked.installedAt,
registry: normalizeStoredRegistry(locked.registry ?? resolveClawHubBaseUrl()),
lockPath: lockRead.kind === "found" ? lockRead.path : void 0
});
}
if (originRead.kind === "malformed") return invalidLink(`Malformed ClawHub origin metadata at ${originRead.path}: ${originRead.error}`, {
originPath: originRead.path,
lockPath: lockRead.kind === "found" ? lockRead.path : void 0
});
const originDetails = {
registry: originRead.origin.registry,
installedVersion: originRead.origin.installedVersion,
installedAt: originRead.origin.installedAt,
originPath: originRead.path
};
let trackedSlug;
try {
trackedSlug = normalizeTrackedSkillSlug(originRead.origin.slug);
} catch (err) {
return invalidLink(`Invalid ClawHub origin slug "${originRead.origin.slug}": ${formatErrorMessage(err)}`, {
...originDetails,
slug: originRead.origin.slug,
lockPath: lockRead.kind === "found" ? lockRead.path : void 0
});
}
if (lockRead.kind === "missing") return invalidLink(`Skill "${trackedSlug}" has ClawHub origin metadata but is not tracked by the ${lockfileLabel}.`, {
...originDetails,
slug: trackedSlug
});
if (lockRead.kind === "malformed") return invalidLink(`Malformed ${lockfileLabel} at ${lockRead.path}: ${lockRead.error}`, {
...originDetails,
slug: trackedSlug,
lockPath: lockRead.path
});
const locked = lockRead.lock.skills[trackedSlug];
if (!locked) return invalidLink(`Skill "${trackedSlug}" has ClawHub origin metadata but is not tracked by the ${lockfileLabel}.`, {
...originDetails,
slug: trackedSlug,
lockPath: lockRead.path
});
const expectedSkillDir = readRealPathSync(resolveWorkspaceSkillInstallDir(params.workspaceDir, trackedSlug));
if (!expectedSkillDir || readRealPathSync(params.skillDir) !== expectedSkillDir) return invalidLink(`Skill "${trackedSlug}" ClawHub origin metadata is not in the expected ClawHub install directory.`, {
...originDetails,
slug: trackedSlug,
lockPath: lockRead.path
});
const originRegistry = normalizeStoredRegistry(originRead.origin.registry);
const lockedRegistry = locked.registry === void 0 ? originRegistry : normalizeStoredRegistry(locked.registry);
const sourceUrl = normalizeOptionalString(locked.sourceUrl);
const ownerHandle = normalizeOptionalString(locked.ownerHandle);
const requestedReference = normalizeOptionalString(locked.requestedReference);
const trustState = locked.trustState === "not-scanned-by-clawhub" ? CLAWHUB_SKILLS_SH_TRUST_STATE : void 0;
const artifact = normalizeDownloadedArtifactLock(locked.artifact);
const skillFile = normalizeSkillFileLock(locked.skillFile);
const fileTreeSha256 = normalizeOptionalString(locked.fileTreeSha256);
const provenanceMatches = originRead.origin.ownerHandle === ownerHandle && originRead.origin.requestedReference === requestedReference && originRead.origin.trustState === trustState && originRead.origin.sourceUrl === sourceUrl && originRead.origin.artifact?.kind === artifact?.kind && originRead.origin.artifact?.sha256 === artifact?.sha256 && originRead.origin.artifact?.integrity === artifact?.integrity && originRead.origin.skillFile?.path === skillFile?.path && originRead.origin.skillFile?.sha256 === skillFile?.sha256 && originRead.origin.fileTreeSha256 === fileTreeSha256;
if (locked.version !== originRead.origin.installedVersion || locked.installedAt !== originRead.origin.installedAt || lockedRegistry !== originRegistry || !provenanceMatches) return invalidLink(`Skill "${trackedSlug}" ClawHub origin metadata does not match the ${lockfileLabel}.`, {
...originDetails,
registry: lockedRegistry,
slug: trackedSlug,
lockPath: lockRead.path
});
return {
status: "linked",
valid: true,
registry: lockedRegistry,
slug: trackedSlug,
...ownerHandle ? { ownerHandle } : {},
...requestedReference ? { requestedReference } : {},
...trustState ? { trustState } : {},
installedVersion: locked.version,
installedAt: locked.installedAt,
originPath: originRead.path,
lockPath: lockRead.path,
...sourceUrl ? { sourceUrl } : {},
...artifact ? { artifact } : {},
...skillFile ? { skillFile } : {},
...fileTreeSha256 ? { fileTreeSha256 } : {}
};
}
function readLocalSkillCardSync(skillDir, includeContent = false) {
const cardPath = path.join(skillDir, LOCAL_SKILL_CARD_FILENAME);
let fd;
try {
const opened = openRootFileSync({
absolutePath: cardPath,
rootPath: skillDir,
boundaryLabel: "skill directory",
maxBytes: LOCAL_SKILL_CARD_MAX_BYTES,
rejectHardlinks: false
});
if (!opened.ok) return;
fd = opened.fd;
const result = {
present: true,
path: cardPath,
sizeBytes: opened.stat.size
};
if (includeContent) result.content = readFileDescriptorBoundedSync(fd, LOCAL_SKILL_CARD_MAX_BYTES).toString("utf8");
return result;
} catch {
return;
} finally {
if (fd !== void 0) try {
fs.closeSync(fd);
} catch {}
}
}
function resolveLocalSkillCardStatusSync(skillDir) {
return readLocalSkillCardSync(skillDir);
}
function readLocalSkillCardContentSync(skillDir) {
return readLocalSkillCardSync(skillDir, true)?.content;
}
async function searchSkillsFromClawHub(params) {
return await searchClawHubSkills({
query: params.query?.trim() ?? "",
limit: params.limit,
baseUrl: params.baseUrl
});
}
async function resolveClawHubSkillVerificationTarget(params) {
try {
const tracking = resolveWorkspaceClawHubSkills(params.workspaceDir);
if (tracking) return await tracking.resolveClawHubSkillVerificationTarget({
...params,
baseUrl: resolveClawHubBaseUrl(params.baseUrl)
});
const version = normalizeOptionalString(params.version);
const tag = normalizeOptionalString(params.tag);
if (version && tag) return {
ok: false,
error: "Use either --version or --tag."
};
const requestedRef = parseRequestedClawHubSkillRef(params.slug);
if (requestedRef.requestedReference && (version || tag)) return {
ok: false,
error: "--version and --tag are not supported for skills-sh references."
};
const trackedSlug = requestedRef.slug;
const skillDir = resolveWorkspaceSkillInstallDir(params.workspaceDir, trackedSlug);
const originRead = await readClawHubSkillOriginStrict(skillDir);
if (originRead.kind === "malformed") return {
ok: false,
error: `Malformed ClawHub origin metadata at ${originRead.path}: ${originRead.error}`
};
if (originRead.kind === "found") {
const locked = (await readClawHubSkillsLockfile(params.workspaceDir)).skills[trackedSlug];
if (!locked) return {
ok: false,
error: `Skill "${trackedSlug}" has ClawHub origin metadata but is not tracked by the workspace ClawHub lockfile. Reinstall it from ClawHub before verifying it as an installed ClawHub skill.`
};
if (normalizeTrackedSkillSlug(originRead.origin.slug) !== trackedSlug) return {
ok: false,
error: `Skill "${trackedSlug}" has ClawHub origin metadata for "${originRead.origin.slug}". Reinstall it from ClawHub before verifying it as an installed ClawHub skill.`
};
const originRegistry = normalizeStoredRegistry(originRead.origin.registry);
const lockedRegistry = locked.registry === void 0 ? originRegistry : normalizeStoredRegistry(locked.registry);
const ownerHandle = normalizeOptionalString(locked.ownerHandle);
const requestedReference = normalizeOptionalString(locked.requestedReference);
const trustState = locked.trustState === "not-scanned-by-clawhub" ? CLAWHUB_SKILLS_SH_TRUST_STATE : void 0;
if (locked.version !== originRead.origin.installedVersion || locked.installedAt !== originRead.origin.installedAt || lockedRegistry !== originRegistry || originRead.origin.ownerHandle !== ownerHandle || originRead.origin.requestedReference !== requestedReference || originRead.origin.trustState !== trustState) return {
ok: false,
error: `Skill "${trackedSlug}" ClawHub origin metadata does not match the workspace ClawHub lockfile. Reinstall it from ClawHub before verifying it as an installed ClawHub skill.`
};
if (requestedReference && (version || tag)) return {
ok: false,
error: "--version and --tag are not supported for skills-sh references."
};
if (requestedRef.ownerHandle && ownerHandle !== requestedRef.ownerHandle) return {
ok: false,
error: `Skill "${trackedSlug}" is tracked as ${ownerHandle ? `@${ownerHandle}/${trackedSlug}` : trackedSlug}, not @${requestedRef.ownerHandle}/${trackedSlug}.`
};
if (requestedRef.requestedReference && requestedReference !== requestedRef.requestedReference) return {
ok: false,
error: `Skill "${trackedSlug}" is not tracked from ${requestedRef.requestedReference}.`
};
const selector = version ? "version" : tag ? "tag" : "installed-version";
const verificationVersion = requestedReference ? void 0 : version ?? (tag ? void 0 : locked.version);
return {
ok: true,
slug: trackedSlug,
...ownerHandle ? { ownerHandle } : {},
...requestedReference ? { requestedReference } : {},
...trustState ? { trustState } : {},
baseUrl: lockedRegistry,
version: verificationVersion,
tag: requestedReference ? void 0 : tag,
resolution: {
source: "installed",
selector,
registry: lockedRegistry,
skillDir,
installedVersion: locked.version
}
};
}
const lockRead = readClawHubSkillsLockfileStatusSync(params.workspaceDir);
if (lockRead.kind === "malformed") return {
ok: false,
error: `Malformed workspace ClawHub lockfile at ${lockRead.path}: ${lockRead.error}`
};
if (lockRead.kind === "found" && lockRead.lock.skills[trackedSlug]) return {
ok: false,
error: `Skill "${trackedSlug}" is tracked by the workspace ClawHub lockfile but is missing ClawHub origin metadata. Reinstall it from ClawHub before verifying it as an installed ClawHub skill.`
};
const registry = resolveClawHubBaseUrl(params.baseUrl);
const selector = version ? "version" : tag ? "tag" : "latest";
return {
ok: true,
slug: requestedRef.slug,
...requestedRef.ownerHandle ? { ownerHandle: requestedRef.ownerHandle } : {},
...requestedRef.requestedReference ? { requestedReference: requestedRef.requestedReference } : {},
...requestedRef.trustState ? { trustState: requestedRef.trustState } : {},
baseUrl: registry,
version,
tag,
resolution: {
source: "registry",
selector,
registry,
skillDir: void 0,
installedVersion: void 0
}
};
} catch (err) {
return {
ok: false,
error: formatErrorMessage(err)
};
}
}
async function preflightSkillOwnerState(params) {
const targetDir = resolveWorkspaceSkillInstallDir(params.workspaceDir, params.requested.slug);
if (!await pathExists(targetDir)) return {
ok: true,
action: "install",
integrity: params.integrity
};
const status = resolveClawHubSkillStatusLinkSync({
workspaceDir: params.workspaceDir,
skillDir: targetDir,
skillKey: params.requested.slug
});
if (status?.status === "linked" && status.installedVersion === params.version && status.ownerHandle === params.requested.ownerHandle && status.artifact?.integrity === params.integrity) return {
ok: true,
action: "reuse",
integrity: params.integrity
};
return {
ok: false,
code: "skill_version_conflict",
error: `Skill ${params.requestedLabel}@${params.version} conflicts with the existing workspace skill at ${targetDir}.`
};
}
async function resolveRequestedUpdateSlug(params) {
const requested = params.requestedSlug.trim();
const requestedRef = requested.startsWith("@") || requested.startsWith("skills-sh:") ? parseRequestedClawHubSkillRef(requested) : { slug: normalizeTrackedSkillSlug(requested) };
const trackedSlug = requestedRef.slug;
const trackedOrigin = await readClawHubSkillOrigin(resolveWorkspaceSkillInstallDir(params.workspaceDir, trackedSlug));
const trackedLockEntry = params.lock.skills[trackedSlug];
if (!trackedOrigin && !trackedLockEntry) return validateRequestedSkillSlug(requestedRef.slug);
const trackedOwnerHandle = trackedOrigin?.ownerHandle ?? trackedLockEntry?.ownerHandle;
if (requestedRef.ownerHandle && trackedOwnerHandle !== requestedRef.ownerHandle) {
const trackedRef = trackedOwnerHandle ? `@${trackedOwnerHandle}/${trackedSlug}` : trackedSlug;
throw new Error(`Skill "${trackedSlug}" is tracked as ${trackedRef}, not @${requestedRef.ownerHandle}/${trackedSlug}.`);
}
const trackedRequestedReference = trackedOrigin?.requestedReference ?? trackedLockEntry?.requestedReference;
if (requestedRef.requestedReference && trackedRequestedReference !== requestedRef.requestedReference) throw new Error(`Skill "${trackedSlug}" is not tracked from ${requestedRef.requestedReference}.`);
return trackedSlug;
}
async function resolveTrackedUpdateTarget(params) {
const origin = await readClawHubSkillOrigin(resolveWorkspaceSkillInstallDir(params.workspaceDir, params.slug));
const lockEntry = params.lock.skills[params.slug];
if (!origin && !lockEntry) return {
ok: false,
slug: params.slug,
error: `Skill "${params.slug}" is not tracked as a ClawHub install.`
};
const ownerHandle = origin?.ownerHandle ?? lockEntry?.ownerHandle;
const requestedReference = origin?.requestedReference ?? lockEntry?.requestedReference;
const trustState = origin?.trustState ?? lockEntry?.trustState;
return {
ok: true,
slug: params.slug,
...ownerHandle ? { ownerHandle } : {},
...requestedReference ? { requestedReference } : {},
...trustState ? { trustState } : {},
baseUrl: origin?.registry ?? params.baseUrl,
previousVersion: origin?.installedVersion ?? lockEntry?.version ?? null
};
}
//#endregion
export { resolveLocalSkillCardStatusSync as a, searchSkillsFromClawHub as c, resolveClawHubSkillVerificationTarget as i, readLocalSkillCardContentSync as n, resolveRequestedUpdateSlug as o, resolveClawHubSkillStatusLinkSync as r, resolveTrackedUpdateTarget as s, preflightSkillOwnerState as t };