mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-10 05:24:03 +00:00
Add marketplace feed entries command (#96158)
Merged via squash.
Prepared head SHA: 1289a25156
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Co-authored-by: giodl73-repo <235387111+giodl73-repo@users.noreply.github.com>
Reviewed-by: @giodl73-repo
This commit is contained in:
@@ -18,6 +18,7 @@ import { defaultRuntime } from "../runtime.js";
|
||||
import { shortenHomeInString } from "../utils.js";
|
||||
import { formatMissingPluginMessage } from "./error-format.js";
|
||||
import type {
|
||||
PluginMarketplaceEntriesOptions,
|
||||
PluginMarketplaceListOptions,
|
||||
PluginMarketplaceRefreshOptions,
|
||||
PluginRegistryOptions,
|
||||
@@ -468,6 +469,22 @@ type MarketplaceRefreshPayload = {
|
||||
error?: string;
|
||||
};
|
||||
|
||||
type MarketplaceEntryPayload = {
|
||||
id?: string;
|
||||
label: string;
|
||||
kind?: string;
|
||||
name?: string;
|
||||
version?: string;
|
||||
install?: {
|
||||
defaultChoice?: string;
|
||||
clawhubSpec?: string;
|
||||
npmSpec?: string;
|
||||
localPath?: string;
|
||||
expectedIntegrity?: string;
|
||||
minHostVersion?: string;
|
||||
};
|
||||
};
|
||||
|
||||
function buildMarketplaceRefreshPayload(
|
||||
result: Awaited<
|
||||
ReturnType<
|
||||
@@ -545,6 +562,21 @@ function sanitizeMarketplaceRefreshPayload(
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
function formatMarketplaceEntryInstall(entry: MarketplaceEntryPayload): string | undefined {
|
||||
if (entry.install?.defaultChoice === "npm") {
|
||||
return entry.install.npmSpec ?? entry.install.clawhubSpec ?? entry.install.localPath;
|
||||
}
|
||||
return entry.install?.clawhubSpec ?? entry.install?.npmSpec ?? entry.install?.localPath;
|
||||
}
|
||||
|
||||
function formatMarketplaceEntryLine(entry: MarketplaceEntryPayload): string {
|
||||
const id = entry.id ?? entry.name ?? entry.label;
|
||||
const install = formatMarketplaceEntryInstall(entry);
|
||||
const suffix = install ? " " + theme.muted(install) : "";
|
||||
const label = entry.label !== id ? " " + theme.muted(entry.label) : "";
|
||||
return theme.command(id) + label + suffix;
|
||||
}
|
||||
|
||||
function formatMarketplaceRefreshSource(source: MarketplaceRefreshPayload["source"]): string {
|
||||
if (source === "hosted") {
|
||||
return theme.success("hosted");
|
||||
@@ -581,6 +613,80 @@ function formatPinnedMarketplaceRefreshFailure(payload: MarketplaceRefreshPayloa
|
||||
return `Pinned marketplace feed refresh did not accept a fresh hosted payload (source: ${payload.source}).`;
|
||||
}
|
||||
|
||||
/** List entries from the configured OpenClaw marketplace feed. */
|
||||
export async function runPluginMarketplaceEntriesCommand(
|
||||
opts: PluginMarketplaceEntriesOptions,
|
||||
): Promise<void> {
|
||||
const catalog = await import("../plugins/official-external-plugin-catalog.js");
|
||||
const cfg = getRuntimeConfig();
|
||||
const result = await catalog.loadConfiguredHostedOfficialExternalPluginCatalogEntries(cfg, {
|
||||
...(opts.feedProfile ? { feedProfile: opts.feedProfile } : {}),
|
||||
...(opts.feedUrl ? { feedUrl: opts.feedUrl } : {}),
|
||||
...(opts.offline ? { offline: true } : {}),
|
||||
});
|
||||
const summary = sanitizeMarketplaceRefreshPayload(buildMarketplaceRefreshPayload(result), {
|
||||
feedUrl: opts.feedUrl,
|
||||
});
|
||||
const entries: MarketplaceEntryPayload[] = result.entries.map((entry) => {
|
||||
const id = catalog.resolveOfficialExternalPluginId(entry);
|
||||
const install =
|
||||
catalog.resolveOfficialExternalPluginInstall(entry, { catalogConfig: cfg.marketplaces }) ??
|
||||
undefined;
|
||||
const payload: MarketplaceEntryPayload = {
|
||||
label: catalog.resolveOfficialExternalPluginLabel(entry),
|
||||
};
|
||||
if (id) {
|
||||
payload.id = id;
|
||||
}
|
||||
if (entry.kind) {
|
||||
payload.kind = entry.kind;
|
||||
}
|
||||
if (entry.name) {
|
||||
payload.name = entry.name;
|
||||
}
|
||||
if (entry.version) {
|
||||
payload.version = entry.version;
|
||||
}
|
||||
if (install) {
|
||||
payload.install = install;
|
||||
}
|
||||
return payload;
|
||||
});
|
||||
|
||||
if (opts.json) {
|
||||
defaultRuntime.writeJson({ ...summary, entries, entryCount: entries.length });
|
||||
return;
|
||||
}
|
||||
|
||||
const lines = [
|
||||
theme.muted("Source:") + " " + formatMarketplaceRefreshSource(summary.source),
|
||||
theme.muted("Entries:") + " " + String(entries.length),
|
||||
];
|
||||
if (summary.feed) {
|
||||
lines.push(
|
||||
theme.muted("Feed:") +
|
||||
" " +
|
||||
summary.feed.id +
|
||||
" " +
|
||||
theme.muted("sequence " + String(summary.feed.sequence)),
|
||||
);
|
||||
}
|
||||
if (summary.metadata?.url) {
|
||||
lines.push(theme.muted("URL:") + " " + summary.metadata.url);
|
||||
}
|
||||
if (summary.snapshot?.savedAt) {
|
||||
lines.push(theme.muted("Snapshot:") + " " + summary.snapshot.savedAt);
|
||||
}
|
||||
if (summary.error) {
|
||||
lines.push(theme.muted("Fallback reason:") + " " + summary.error);
|
||||
}
|
||||
if (entries.length > 0) {
|
||||
lines.push("");
|
||||
lines.push(...entries.map(formatMarketplaceEntryLine));
|
||||
}
|
||||
defaultRuntime.log(lines.join("\n"));
|
||||
}
|
||||
|
||||
/** Refresh the configured OpenClaw marketplace feed snapshot. */
|
||||
export async function runPluginMarketplaceRefreshCommand(
|
||||
opts: PluginMarketplaceRefreshOptions,
|
||||
|
||||
Reference in New Issue
Block a user