diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ae84756193..184488c8324 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai - Plugins/compat: mark `OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY` as a deprecated break-glass switch and point operators at registry repair instead. Thanks @vincentkoc. - Plugins/compat: expand the central compatibility registry with dated owners, replacements, and removal targets for legacy SDK, manifest, setup, registry-migration, and agent-runtime surfaces. Thanks @vincentkoc. - Plugins/registry: ignore stale persisted registry reads when plugin policy no longer matches current config, and stamp generated registry files with a do-not-edit warning. Thanks @vincentkoc. +- Config/plugins: keep plugin command-alias validation on cold manifest metadata instead of importing the runtime alias resolver. Thanks @vincentkoc. - Diagnostics/OTEL: surface provider request identifiers as bounded hashes on model-call diagnostics and span events, without exporting raw request IDs or metric labels. Thanks @Lidang-Jiang and @vincentkoc. - Plugins/diagnostics: add metadata-only `model_call_started` and `model_call_ended` hooks for provider/model call telemetry without exposing prompts, responses, headers, request bodies, or raw provider request IDs. Thanks @vincentkoc. - Diagnostics/OTEL: emit bounded context assembly diagnostics and export `openclaw.context.assembled` spans with prompt/history sizes but no prompt, history, response, or session-key content. Thanks @vincentkoc. diff --git a/src/config/config.web-search-provider.test.ts b/src/config/config.web-search-provider.test.ts index f749200e436..7858089e6d8 100644 --- a/src/config/config.web-search-provider.test.ts +++ b/src/config/config.web-search-provider.test.ts @@ -14,10 +14,6 @@ vi.mock("../plugin-sdk/telegram-command-config.js", () => ({ resolveTelegramCustomCommands: () => ({ commands: [], issues: [] }), })); -vi.mock("../plugins/manifest-command-aliases.runtime.js", () => ({ - resolveManifestCommandAliasOwner: () => undefined, -})); - const getScopedWebSearchCredential = (key: string) => (search?: Record) => (search?.[key] as { apiKey?: unknown } | undefined)?.apiKey; const getConfiguredPluginWebSearchConfig = diff --git a/src/config/validation.cold-imports.test.ts b/src/config/validation.cold-imports.test.ts new file mode 100644 index 00000000000..85ca0999599 --- /dev/null +++ b/src/config/validation.cold-imports.test.ts @@ -0,0 +1,16 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { describe, expect, it } from "vitest"; + +const repoRoot = fileURLToPath(new URL("../..", import.meta.url)); + +describe("config validation cold imports", () => { + it("keeps validation command-alias guidance on manifest metadata", () => { + const source = fs.readFileSync(path.join(repoRoot, "src/config/validation.ts"), "utf8"); + + expect(source).not.toMatch(/\bfrom\s+["'][^"']*manifest-command-aliases\.runtime\.js["']/); + expect(source).not.toMatch(/\bfrom\s+["'][^"']*providers\.runtime\.js["']/); + expect(source).not.toMatch(/\bfrom\s+["'][^"']*loader\.js["']/); + }); +}); diff --git a/src/config/validation.ts b/src/config/validation.ts index caa3ef4369e..26e86849285 100644 --- a/src/config/validation.ts +++ b/src/config/validation.ts @@ -12,7 +12,7 @@ import { collectRelevantDoctorPluginIdsForTouchedPaths, listPluginDoctorLegacyConfigRules, } from "../plugins/doctor-contract-registry.js"; -import { resolveManifestCommandAliasOwner } from "../plugins/manifest-command-aliases.runtime.js"; +import { resolveManifestCommandAliasOwnerInRegistry } from "../plugins/manifest-command-aliases.js"; import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js"; import { validateJsonSchemaValue } from "../plugins/schema-validator.js"; @@ -1119,7 +1119,7 @@ function validateConfigObjectWithPluginsBase( continue; } if (!knownIds.has(pluginId)) { - const commandAlias = resolveManifestCommandAliasOwner({ + const commandAlias = resolveManifestCommandAliasOwnerInRegistry({ command: pluginId, registry, });