Files
openclaw/src/cli/plugins-list-format.ts
T
Peter Steinberger f4387b7a5e feat(plugins): support the Agent Plugins bundle format (#120115)
* feat(plugins): support the Agent Plugins bundle format

* docs(plugins): document the Agent Plugins bundle format

* test(agents): preserve agent bundle runtime discovery

* fix(plugins): isolate Agent Plugins data-dir failures and align MCP support reporting

* docs(plugins): list Agent Plugins in the canonical plugin-format guides

* fix(plugins): gate Agent Plugins detection on schema, pure inspection, root-relative cwd

* fix(plugins): record Agent Plugins data-dir ownership explicitly

* docs(plugins): cover Agent Plugins in the CLI install detection guide

* fix(plugins): carry Agent Plugins data-dir and transport contracts through external MCP projections
2026-08-07 02:55:08 -07:00

77 lines
2.9 KiB
TypeScript

// Text formatter for plugin list rows and verbose plugin details.
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js";
import { theme } from "../../packages/terminal-core/src/theme.js";
import type { PluginBundleFormat } from "../plugins/manifest-types.js";
import type { PluginRecord } from "../plugins/registry.js";
import { shortenHomeInString } from "../utils.js";
export function formatPluginBundleFormat(bundleFormat: PluginBundleFormat): string {
return bundleFormat === "agent" ? "agent (Agent Plugins)" : bundleFormat;
}
export function formatPluginLine(plugin: PluginRecord, verbose = false): string {
const status =
plugin.status === "error"
? theme.error("error")
: plugin.enabled
? theme.success("enabled")
: theme.warn("disabled");
const name = theme.command(plugin.name || plugin.id);
const idSuffix = plugin.name && plugin.name !== plugin.id ? theme.muted(` (${plugin.id})`) : "";
const desc = plugin.description
? theme.muted(
plugin.description.length > 60
? `${truncateUtf16Safe(plugin.description, 57)}...`
: plugin.description,
)
: theme.muted("(no description)");
const format = plugin.format ?? "openclaw";
if (!verbose) {
return `${name}${idSuffix} ${status} ${theme.muted(`[${format}]`)} - ${desc}`;
}
const parts = [
`${name}${idSuffix} ${status}`,
` format: ${format}`,
` source: ${theme.muted(shortenHomeInString(plugin.source))}`,
` origin: ${plugin.origin}`,
];
if (plugin.bundleFormat) {
parts.push(` bundle format: ${formatPluginBundleFormat(plugin.bundleFormat)}`);
}
if (plugin.version) {
parts.push(` version: ${plugin.version}`);
}
if (plugin.activated !== undefined) {
parts.push(` activated: ${plugin.activated ? "yes" : "no"}`);
}
if (plugin.imported !== undefined) {
parts.push(` imported: ${plugin.imported ? "yes" : "no"}`);
}
if (plugin.explicitlyEnabled !== undefined) {
parts.push(` explicitly enabled: ${plugin.explicitlyEnabled ? "yes" : "no"}`);
}
if (plugin.activationSource) {
parts.push(` activation source: ${plugin.activationSource}`);
}
if (plugin.activationReason) {
parts.push(` activation reason: ${sanitizeTerminalText(plugin.activationReason)}`);
}
if (plugin.providerIds.length > 0) {
parts.push(` providers: ${plugin.providerIds.join(", ")}`);
}
if (plugin.activated !== undefined || plugin.activationSource || plugin.activationReason) {
const activationSummary =
plugin.activated === false
? "inactive"
: (plugin.activationSource ?? (plugin.activated ? "active" : "inactive"));
parts.push(` activation: ${activationSummary}`);
}
if (plugin.error) {
parts.push(theme.error(` error: ${plugin.error}`));
}
return parts.join("\n");
}