openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
234 lines (233 loc) • 13.1 kB
JavaScript
import { f as asSafeIntegerInRange } from "./number-coercion-CLj0HTDM.js";
import { a as getPluginCache, c as getPluginMetadataSnapshotCache, f as withPluginCache, l as getProcessPluginCache, u as getScopedPluginCache } from "./plugin-cache-DGWspMEc.js";
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { a as getProcessGatewayPluginMetadataSnapshot } from "./current-plugin-metadata-state-B1UoAr4G.js";
import { n as MANIFEST_KEY } from "./legacy-names-NIXaj2oi.js";
import { o as parseRegistryNpmSpec } from "./npm-registry-spec-CM_p1_uq.js";
import { t as parseClawHubPluginSpec } from "./clawhub-spec-Er3Np6VI.js";
import { b as resolveOfficialExternalPluginInstallSources, h as loadConfiguredHostedOfficialExternalPluginCatalogEntries, o as getOfficialExternalPluginCatalogManifest, p as listOfficialExternalPluginCatalogEntries, v as resolveOfficialExternalPluginId, y as resolveOfficialExternalPluginInstall } from "./official-external-plugin-catalog-Dzu7dwBN.js";
import { a as resolveTrustedOfficialClawHubPackageName, l as resolveTrustedSourceLinkedOfficialNpmSpec, s as resolveTrustedSourceLinkedOfficialClawHubSpec } from "./official-external-install-records-DClkub0e.js";
//#region src/plugins/management-catalog.ts
function getManagedPluginCache(metadata) {
if (metadata) return getPluginMetadataSnapshotCache(metadata);
const scoped = getScopedPluginCache();
if (scoped?.kind === "operation") return scoped;
const candidate = getProcessPluginCache().desiredMetadata;
if (candidate && candidate.boot === getProcessGatewayPluginMetadataSnapshot()) return candidate.cache;
return getPluginCache();
}
function withManagedPluginCache(run) {
return (params) => withPluginCache(getManagedPluginCache(params.metadata), () => run(params));
}
/** Clear the process-stable hosted catalog snapshot after an explicit owner reload. */
function clearManagedPluginOfficialCatalogCache() {
getManagedPluginCache().officialCatalog = void 0;
}
function mergeCatalogMetadata(hosted, bundled, options) {
const hostedManifest = getOfficialExternalPluginCatalogManifest(hosted);
const bundledManifest = getOfficialExternalPluginCatalogManifest(bundled);
const bundledCatalog = bundledManifest?.catalog;
const bundledPlugin = bundledManifest?.plugin;
const bundledName = normalizeOptionalString(bundled.name);
const bundledDescription = normalizeOptionalString(bundled.description);
const bundledKind = normalizeOptionalString(bundled.kind);
const bundledSource = normalizeOptionalString(bundled.source);
const hostedFeatured = typeof hosted.featured === "boolean" ? hosted.featured : false;
const mergedCatalog = bundledCatalog || hostedManifest?.catalog || options.hostedFeaturedAuthoritative && hostedFeatured ? {
...hostedManifest?.catalog,
...bundledCatalog,
...options.hostedFeaturedAuthoritative ? { featured: hostedFeatured } : {}
} : void 0;
if (!mergedCatalog && !bundledPlugin) return hosted;
return {
...hosted,
...!normalizeOptionalString(hosted.name) && bundledName ? { name: bundledName } : {},
...!normalizeOptionalString(hosted.description) && bundledDescription ? { description: bundledDescription } : {},
...!normalizeOptionalString(hosted.kind) && bundledKind ? { kind: bundledKind } : {},
...!normalizeOptionalString(hosted.source) && bundledSource ? { source: bundledSource } : {},
[MANIFEST_KEY]: {
...hostedManifest,
...bundledPlugin ? { plugin: {
...hostedManifest?.plugin,
...bundledPlugin
} } : {},
...mergedCatalog ? { catalog: mergedCatalog } : {}
}
};
}
function prepareCatalogEntry(entry) {
const install = resolveOfficialExternalPluginInstall(entry);
const sources = resolveOfficialExternalPluginInstallSources(entry, { resolvedInstall: install });
const clawhubSpec = sources.find((source) => source.source === "clawhub")?.spec;
const npmSpec = sources.find((source) => source.source === "npm")?.spec;
return {
entry,
install,
selectedSource: sources[0],
clawhub: clawhubSpec ? parseClawHubPluginSpec(clawhubSpec) : void 0,
npmPackage: npmSpec ? parseRegistryNpmSpec(npmSpec)?.name : void 0
};
}
function prepareCatalogEntries(entries) {
let prepared;
return () => prepared ??= entries.map(prepareCatalogEntry);
}
/**
* Overlay local runtime identity and ordering after an exact package/source match.
* Hosted curation wins; bundled Featured state survives only in fallback mode.
*/
function overlayBundledOfficialPluginCatalogMetadata(entries, bundledEntries = listOfficialExternalPluginCatalogEntries(), options = { hostedFeaturedAuthoritative: false }) {
const bundledFacts = entries.length > 0 ? bundledEntries.map(prepareCatalogEntry) : [];
return entries.map((entry) => {
const { clawhub, npmPackage } = prepareCatalogEntry(entry);
const matches = bundledFacts.filter((bundled) => clawhub && bundled.clawhub?.name === clawhub.name || npmPackage && bundled.npmPackage === npmPackage);
const bundled = matches.length === 1 ? matches[0]?.entry : void 0;
if (bundled) return mergeCatalogMetadata(entry, bundled, options);
if (!options.hostedFeaturedAuthoritative) return entry;
const hostedManifest = getOfficialExternalPluginCatalogManifest(entry);
if (entry.featured !== true && !hostedManifest?.catalog) return entry;
return {
...entry,
[MANIFEST_KEY]: {
...hostedManifest,
catalog: {
...hostedManifest?.catalog,
featured: entry.featured === true
}
}
};
});
}
async function loadOfficialCatalog() {
const cache = getManagedPluginCache();
if (!cache.officialCatalog) {
const promise = Promise.resolve().then(() => loadConfiguredHostedOfficialExternalPluginCatalogEntries());
cache.officialCatalog = promise;
promise.catch(() => {
if (cache.officialCatalog === promise) cache.officialCatalog = void 0;
});
}
const result = await cache.officialCatalog;
const hostedFeaturedAuthoritative = result.source === "hosted" || result.source === "hosted-snapshot";
return {
entries: overlayBundledOfficialPluginCatalogMetadata(result.entries, void 0, { hostedFeaturedAuthoritative }),
hostedFeaturedAuthoritative,
..."error" in result ? { error: result.error } : {}
};
}
function normalizeKinds(kind) {
const values = (typeof kind === "string" ? [kind] : kind ?? []).map((value) => value.trim()).filter(Boolean);
return values.length > 0 ? [...new Set(values)] : void 0;
}
function normalizeCatalogMetadata(value) {
if (!isRecord(value)) return;
const featured = typeof value.featured === "boolean" ? value.featured : void 0;
const order = typeof value.order === "number" && Number.isFinite(value.order) ? value.order : void 0;
return featured === void 0 && order === void 0 ? void 0 : {
...featured !== void 0 ? { featured } : {},
...order !== void 0 ? { order } : {}
};
}
function normalizeFeaturedAt(value) {
return asSafeIntegerInRange(value, { min: 0 });
}
/** Coarse manifest-derived grouping so catalog UIs can shelve a large inventory. */
function derivePluginCategory(manifest) {
if (!manifest) return;
if (manifest.channels.length > 0 || Object.keys(manifest.channelConfigs ?? {}).length > 0) return "channel";
const mediaProvider = Object.keys(manifest.imageGenerationProviderMetadata ?? {}).length > 0 || Object.keys(manifest.videoGenerationProviderMetadata ?? {}).length > 0 || Object.keys(manifest.musicGenerationProviderMetadata ?? {}).length > 0 || Object.keys(manifest.mediaUnderstandingProviderMetadata ?? {}).length > 0;
if (manifest.providers.length > 0 || manifest.providerEndpoints?.length || manifest.modelCatalog || mediaProvider) return "provider";
const kinds = normalizeKinds(manifest.kind);
if (kinds?.includes("memory")) return "memory";
if (kinds?.includes("context-engine")) return "context-engine";
if (manifest.contracts?.tools?.length || Object.keys(manifest.toolMetadata ?? {}).length > 0 || manifest.skills.length > 0) return "tool";
}
function firstPluginError(diagnostics, pluginId) {
return diagnostics.find((diagnostic) => diagnostic.level === "error" && diagnostic.pluginId === pluginId)?.message;
}
function compareCatalogEntries(left, right) {
const featured = Number(Boolean(right.featured)) - Number(Boolean(left.featured));
if (featured !== 0) return featured;
if (left.featured && right.featured) {
const leftFeaturedAt = left.featuredAt;
const rightFeaturedAt = right.featuredAt;
if (leftFeaturedAt !== void 0 || rightFeaturedAt !== void 0) {
if (leftFeaturedAt === void 0) return 1;
if (rightFeaturedAt === void 0) return -1;
if (leftFeaturedAt !== rightFeaturedAt) return rightFeaturedAt - leftFeaturedAt;
}
}
const order = (left.order ?? Number.MAX_SAFE_INTEGER) - (right.order ?? Number.MAX_SAFE_INTEGER);
return order !== 0 ? order : left.name.localeCompare(right.name);
}
function resolveInstalledOfficialCatalogEntry(params) {
if (!params.packageName) return;
const matches = params.entries().filter(({ clawhub, npmPackage }) => (params.source === "clawhub" ? clawhub?.name : npmPackage) === params.packageName);
return matches.length === 1 ? matches[0] : void 0;
}
function resolveInstalledPluginPresentation(params) {
const { record, manifest, officialEntry, hostedListingAuthoritative } = params;
const localName = (manifest?.name !== record.packageName ? manifest?.name : void 0) ?? manifest?.channelCatalogMeta?.label ?? record.pluginId;
const localDescription = manifest?.description ?? manifest?.channelCatalogMeta?.blurb ?? manifest?.packageDescription;
const name = (hostedListingAuthoritative ? normalizeOptionalString(officialEntry?.title) : void 0) ?? localName;
const description = (hostedListingAuthoritative ? normalizeOptionalString(officialEntry?.description) : void 0) ?? localDescription;
const version = record.packageVersion ?? manifest?.version;
return {
name,
...description ? { description } : {},
...version ? { version } : {}
};
}
function resolveInstalledHostedOfficialEntry(params) {
const identityPluginId = params.installOwner ?? params.record.pluginId;
const trustedOfficialClawHubSpec = params.installRecord ? resolveTrustedSourceLinkedOfficialClawHubSpec({
pluginId: identityPluginId,
record: params.installRecord
}) : void 0;
const trustedOfficialNpmSpec = params.installRecord ? resolveTrustedSourceLinkedOfficialNpmSpec({
pluginId: identityPluginId,
record: params.installRecord
}) : void 0;
const sourceLinkedOfficialClawHubPackage = trustedOfficialClawHubSpec ? parseClawHubPluginSpec(trustedOfficialClawHubSpec)?.name : void 0;
const currentOfficialClawHubPackage = params.installRecord ? resolveTrustedOfficialClawHubPackageName(params.installRecord) : void 0;
const trustedOfficialNpmPackage = trustedOfficialNpmSpec ? parseRegistryNpmSpec(trustedOfficialNpmSpec)?.name : void 0;
const bundledPublishedEntry = params.record.origin === "bundled" ? resolveInstalledOfficialCatalogEntry({
entries: params.bundledOfficialEntries,
packageName: params.record.packageName,
source: "npm"
}) : void 0;
const installedOfficialIdentity = sourceLinkedOfficialClawHubPackage ? {
source: "clawhub",
packageName: sourceLinkedOfficialClawHubPackage
} : trustedOfficialNpmPackage ? {
source: "npm",
packageName: trustedOfficialNpmPackage
} : currentOfficialClawHubPackage && (!params.record.packageName || params.record.packageName === currentOfficialClawHubPackage) ? {
source: "clawhub",
packageName: currentOfficialClawHubPackage
} : bundledPublishedEntry && params.record.packageName ? {
source: "npm",
packageName: params.record.packageName
} : void 0;
const hasInstalledOfficialProvenance = Boolean(installedOfficialIdentity && (!params.record.packageName || params.record.packageName === installedOfficialIdentity.packageName));
const bundledOfficialEntry = bundledPublishedEntry ?? resolveInstalledOfficialCatalogEntry({
entries: params.bundledOfficialEntries,
packageName: hasInstalledOfficialProvenance ? installedOfficialIdentity?.packageName : void 0,
source: installedOfficialIdentity?.source ?? "clawhub"
});
const hostedPackageName = installedOfficialIdentity?.source === "npm" ? bundledOfficialEntry?.clawhub?.name : installedOfficialIdentity?.packageName;
return {
entry: resolveInstalledOfficialCatalogEntry({
entries: params.officialEntries,
packageName: hasInstalledOfficialProvenance ? hostedPackageName : void 0,
source: "clawhub"
})?.entry,
clawhubPackage: hasInstalledOfficialProvenance ? hostedPackageName : void 0
};
}
function resolveOfficialEntryById(entries, pluginId) {
return entries.find((entry) => resolveOfficialExternalPluginId(entry) === pluginId);
}
//#endregion
export { getManagedPluginCache as a, normalizeFeaturedAt as c, prepareCatalogEntry as d, resolveInstalledHostedOfficialEntry as f, withManagedPluginCache as h, firstPluginError as i, normalizeKinds as l, resolveOfficialEntryById as m, compareCatalogEntries as n, loadOfficialCatalog as o, resolveInstalledPluginPresentation as p, derivePluginCategory as r, normalizeCatalogMetadata as s, clearManagedPluginOfficialCatalogCache as t, prepareCatalogEntries as u };