feat(plugins): add setupGuide field for post-install guidance

Plugins can now include a setupGuide field in clawdbot.plugin.json
that will be displayed after installation, helping users with
configuration steps.

Changes:
- Add setupGuide field to PluginManifest type
- Parse setupGuide from plugin manifest
- Display setupGuide after successful plugin installation
This commit is contained in:
CoderMageFox 2026-01-27 19:27:04 +08:00
parent f4004054ab
commit aa44ea27bf
2 changed files with 17 additions and 0 deletions

View File

@ -7,6 +7,7 @@ import type { ClawdbotConfig } from "../config/config.js";
import { resolveArchiveKind } from "../infra/archive.js";
import { installPluginFromNpmSpec, installPluginFromPath } from "../plugins/install.js";
import { recordPluginInstall } from "../plugins/installs.js";
import { loadPluginManifest } from "../plugins/manifest.js";
import { applyExclusiveSlotSelection } from "../plugins/slots.js";
import type { PluginRecord } from "../plugins/registry.js";
import { buildPluginStatusReport } from "../plugins/status.js";
@ -32,6 +33,16 @@ export type PluginUpdateOptions = {
dryRun?: boolean;
};
function printSetupGuideIfPresent(targetDir: string): void {
const manifestResult = loadPluginManifest(targetDir);
if (manifestResult.ok && manifestResult.manifest.setupGuide) {
defaultRuntime.log("");
defaultRuntime.log(theme.heading("Setup Guide:"));
defaultRuntime.log(manifestResult.manifest.setupGuide);
defaultRuntime.log("");
}
}
function formatPluginLine(plugin: PluginRecord, verbose = false): string {
const status =
plugin.status === "loaded"
@ -379,6 +390,7 @@ export function registerPluginsCli(program: Command) {
await writeConfigFile(next);
logSlotWarnings(slotResult.warnings);
defaultRuntime.log(`Installed plugin: ${result.pluginId}`);
printSetupGuideIfPresent(result.targetDir);
defaultRuntime.log(`Restart the gateway to load plugins.`);
return;
}
@ -442,6 +454,7 @@ export function registerPluginsCli(program: Command) {
await writeConfigFile(next);
logSlotWarnings(slotResult.warnings);
defaultRuntime.log(`Installed plugin: ${result.pluginId}`);
printSetupGuideIfPresent(result.targetDir);
defaultRuntime.log(`Restart the gateway to load plugins.`);
});

View File

@ -16,6 +16,7 @@ export type PluginManifest = {
description?: string;
version?: string;
uiHints?: Record<string, PluginConfigUiHint>;
setupGuide?: string;
};
export type PluginManifestLoadResult =
@ -75,6 +76,8 @@ export function loadPluginManifest(rootDir: string): PluginManifestLoadResult {
uiHints = raw.uiHints as Record<string, PluginConfigUiHint>;
}
const setupGuide = typeof raw.setupGuide === "string" ? raw.setupGuide.trim() : undefined;
return {
ok: true,
manifest: {
@ -88,6 +91,7 @@ export function loadPluginManifest(rootDir: string): PluginManifestLoadResult {
description,
version,
uiHints,
setupGuide,
},
manifestPath,
};