fix: break plugin command spec import cycle

(cherry picked from commit ced0e96cf2)
This commit is contained in:
Peter Steinberger
2026-04-26 08:46:02 +01:00
parent 197f95c94d
commit 8123db644b
5 changed files with 34 additions and 70 deletions

View File

@@ -77,8 +77,7 @@ export {
listSkillCommandsForWorkspace,
resolveSkillCommandInvocation,
} from "../auto-reply/skill-commands.js";
export { getPluginCommandSpecs } from "../plugins/command-specs.js";
export { listProviderPluginCommandSpecs } from "../plugins/command-registry-state.js";
export { getPluginCommandSpecs, listProviderPluginCommandSpecs } from "../plugins/command-specs.js";
export type { SkillCommandSpec } from "../agents/skills.js";
export {
buildModelsProviderData,

View File

@@ -8,7 +8,6 @@ import {
clearPluginCommands,
clearPluginCommandsForPlugin,
isPluginCommandRegistryLocked,
listProviderPluginCommandSpecs,
pluginCommands,
type RegisteredPluginCommand,
} from "./command-registry-state.js";
@@ -236,5 +235,5 @@ export function registerPluginCommand(
return { ok: true };
}
export { clearPluginCommands, clearPluginCommandsForPlugin, listProviderPluginCommandSpecs };
export { clearPluginCommands, clearPluginCommandsForPlugin };
export type { RegisteredPluginCommand };

View File

@@ -1,6 +1,3 @@
import { getLoadedChannelPlugin } from "../channels/plugins/index.js";
import { resolveReadOnlyChannelCommandDefaults } from "../channels/plugins/read-only-command-defaults.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { resolveGlobalSingleton } from "../shared/global-singleton.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import type { OpenClawPluginCommandDefinition } from "./types.js";
@@ -83,63 +80,3 @@ export function restorePluginCommands(commands: readonly RegisteredPluginCommand
pluginCommands.set(`/${name}`, command);
}
}
function resolvePluginNativeName(
command: OpenClawPluginCommandDefinition,
provider?: string,
): string {
const providerName = normalizeOptionalLowercaseString(provider);
const providerOverride = providerName ? command.nativeNames?.[providerName] : undefined;
if (typeof providerOverride === "string" && providerOverride.trim()) {
return providerOverride.trim();
}
const defaultOverride = command.nativeNames?.default;
if (typeof defaultOverride === "string" && defaultOverride.trim()) {
return defaultOverride.trim();
}
return command.name;
}
export function getPluginCommandSpecs(
provider?: string,
options: {
env?: NodeJS.ProcessEnv;
stateDir?: string;
workspaceDir?: string;
config?: OpenClawConfig;
} = {},
): Array<{
name: string;
description: string;
acceptsArgs: boolean;
}> {
const providerName = normalizeOptionalLowercaseString(provider);
const commandDefaults =
providerName && options.config
? resolveReadOnlyChannelCommandDefaults(providerName, {
...options,
config: options.config,
})
: undefined;
if (
providerName &&
(getLoadedChannelPlugin(providerName)?.commands ?? commandDefaults)
?.nativeCommandsAutoEnabled !== true
) {
return [];
}
return listProviderPluginCommandSpecs(provider);
}
/** Resolve plugin command specs for a provider's native naming surface without support gating. */
export function listProviderPluginCommandSpecs(provider?: string): Array<{
name: string;
description: string;
acceptsArgs: boolean;
}> {
return Array.from(pluginCommands.values()).map((cmd) => ({
name: resolvePluginNativeName(cmd, provider),
description: cmd.description,
acceptsArgs: cmd.acceptsArgs ?? false,
}));
}

View File

@@ -2,7 +2,24 @@ import { getLoadedChannelPlugin } from "../channels/plugins/index.js";
import { resolveReadOnlyChannelCommandDefaults } from "../channels/plugins/read-only-command-defaults.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
import { listProviderPluginCommandSpecs } from "./command-registry-state.js";
import { pluginCommands } from "./command-registry-state.js";
import type { OpenClawPluginCommandDefinition } from "./types.js";
function resolvePluginNativeName(
command: OpenClawPluginCommandDefinition,
provider?: string,
): string {
const providerName = normalizeOptionalLowercaseString(provider);
const providerOverride = providerName ? command.nativeNames?.[providerName] : undefined;
if (typeof providerOverride === "string" && providerOverride.trim()) {
return providerOverride.trim();
}
const defaultOverride = command.nativeNames?.default;
if (typeof defaultOverride === "string" && defaultOverride.trim()) {
return defaultOverride.trim();
}
return command.name;
}
export function getPluginCommandSpecs(
provider?: string,
@@ -34,3 +51,16 @@ export function getPluginCommandSpecs(
}
return listProviderPluginCommandSpecs(provider);
}
/** Resolve plugin command specs for a provider's native naming surface without support gating. */
export function listProviderPluginCommandSpecs(provider?: string): Array<{
name: string;
description: string;
acceptsArgs: boolean;
}> {
return Array.from(pluginCommands.values()).map((cmd) => ({
name: resolvePluginNativeName(cmd, provider),
description: cmd.description,
acceptsArgs: cmd.acceptsArgs ?? false,
}));
}

View File

@@ -14,7 +14,6 @@ import {
clearPluginCommands,
clearPluginCommandsForPlugin,
listPluginInvocationKeys,
listProviderPluginCommandSpecs,
registerPluginCommand,
validateCommandName,
validatePluginCommandDefinition,
@@ -24,7 +23,7 @@ import {
setPluginCommandRegistryLocked,
type RegisteredPluginCommand,
} from "./command-registry-state.js";
import { getPluginCommandSpecs } from "./command-specs.js";
import { getPluginCommandSpecs, listProviderPluginCommandSpecs } from "./command-specs.js";
import {
detachPluginConversationBinding,
getCurrentPluginConversationBinding,