Files
openclaw/scripts/lib/plugin-inventory-doc.mts
T
Peter Steinberger c70aee247e refactor(scripts): migrate JavaScript tools to TypeScript (#121005)
* refactor(scripts): migrate JavaScript tools to TypeScript

* fix(ci): keep changed-scope preflight zero-install

* fix(ci): preserve zero-install script owners

* fix(ci): complete script migration follow-through

* fix(release): keep stable closeout zero-install

* fix(scripts): preserve standalone execution boundaries

* fix(scripts): repair standalone loader boundaries

* fix(scripts): normalize gateway observation ids

* fix(scripts): keep Docker packager standalone

* test(scripts): preserve rebase cleanup helpers

* test(sessions): use tracked temp directory
2026-08-09 07:21:35 -07:00

65 lines
2.2 KiB
TypeScript

type PluginSurfaceManifest = {
id?: string;
channels?: string[];
providers?: string[];
contracts?: Record<string, unknown>;
dashboard?: Partial<Record<"actionVerbs" | "dataBindings", Array<{ id?: string }>>>;
skills?: unknown[];
};
function formatIdentifiers(values: string[]) {
return values.map((value) => `\`${value}\``).join(", ");
}
function encodeDashboardPluginIdSegment(pluginId: string) {
return pluginId.replaceAll("%", "%25").replaceAll(".", "%2E");
}
function resolveDashboardCapabilityIds(
manifest: PluginSurfaceManifest,
field: "dataBindings" | "actionVerbs",
) {
if (typeof manifest.id !== "string" || !Array.isArray(manifest.dashboard?.[field])) {
return [];
}
const pluginIdSegment = encodeDashboardPluginIdSegment(manifest.id);
return manifest.dashboard[field]
.map((entry) =>
typeof entry?.id === "string" && entry.id.length > 0
? `${pluginIdSegment}.${entry.id}`
: null,
)
.filter((value) => value !== null);
}
export function resolvePluginSurface(manifest: PluginSurfaceManifest) {
const parts = [];
if (Array.isArray(manifest.channels) && manifest.channels.length > 0) {
parts.push(`channels: ${formatIdentifiers(manifest.channels)}`);
}
if (Array.isArray(manifest.providers) && manifest.providers.length > 0) {
parts.push(`providers: ${formatIdentifiers(manifest.providers)}`);
}
const contracts = Object.keys(manifest.contracts ?? {}).toSorted((left, right) =>
left.localeCompare(right),
);
if (contracts.length > 0) {
parts.push(`contracts: ${formatIdentifiers(contracts)}`);
}
const dashboardDataBindings = resolveDashboardCapabilityIds(manifest, "dataBindings");
if (dashboardDataBindings.length > 0) {
parts.push(`dashboard data bindings: ${formatIdentifiers(dashboardDataBindings)}`);
}
const dashboardActionVerbs = resolveDashboardCapabilityIds(manifest, "actionVerbs");
if (dashboardActionVerbs.length > 0) {
parts.push(`dashboard action verbs: ${formatIdentifiers(dashboardActionVerbs)}`);
}
if (Array.isArray(manifest.skills) && manifest.skills.length > 0) {
parts.push("skills");
}
if (parts.length === 0) {
return "plugin";
}
return parts.join("; ");
}