




















@@ -1,11 +1,13 @@
11import fs from "node:fs";
22import path from "node:path";
33import type { OpenClawConfig } from "../config/types.js";
4+import { isBlockedObjectKey } from "../infra/prototype-keys.js";
45import {
56normalizeOptionalLowercaseString,
67normalizeOptionalString,
78} from "../shared/string-coerce.js";
89import { normalizeOptionalTrimmedStringList } from "../shared/string-normalization.js";
10+import { sanitizeForLog } from "../terminal/ansi.js";
911import { resolveUserPath } from "../utils.js";
1012import { resolveCompatibilityHostVersion } from "../version.js";
1113import { loadBundleManifest } from "./bundle-manifest.js";
@@ -306,26 +308,38 @@ function mergePackageChannelMetaIntoChannelConfigs(params: {
306308packageChannel?: OpenClawPackageManifest["channel"];
307309}): Record<string, PluginManifestChannelConfig> | undefined {
308310const channelId = params.packageChannel?.id?.trim();
309-if (!channelId || !params.channelConfigs?.[channelId]) {
311+if (
312+!channelId ||
313+isBlockedObjectKey(channelId) ||
314+!params.channelConfigs ||
315+!Object.prototype.hasOwnProperty.call(params.channelConfigs, channelId)
316+) {
310317return params.channelConfigs;
311318}
312319313320const existing = params.channelConfigs[channelId];
321+if (!existing) {
322+return params.channelConfigs;
323+}
314324const label = existing.label ?? normalizeOptionalString(params.packageChannel?.label) ?? "";
315325const description =
316326existing.description ?? normalizeOptionalString(params.packageChannel?.blurb) ?? "";
317327const preferOver =
318328existing.preferOver ?? normalizePreferredPluginIds(params.packageChannel?.preferOver);
319329320-return {
321- ...params.channelConfigs,
322-[channelId]: {
323- ...existing,
324- ...(label ? { label } : {}),
325- ...(description ? { description } : {}),
326- ...(preferOver?.length ? { preferOver } : {}),
327-},
330+const merged: Record<string, PluginManifestChannelConfig> = Object.create(null);
331+for (const [key, value] of Object.entries(params.channelConfigs)) {
332+if (!isBlockedObjectKey(key)) {
333+merged[key] = value;
334+}
335+}
336+merged[channelId] = {
337+ ...existing,
338+ ...(label ? { label } : {}),
339+ ...(description ? { description } : {}),
340+ ...(preferOver?.length ? { preferOver } : {}),
328341};
342+return merged;
329343}
330344331345function buildRecord(params: {
@@ -468,9 +482,9 @@ function pushProviderAuthEnvVarsCompatDiagnostic(params: {
468482}
469483params.diagnostics.push({
470484level: "warn",
471-pluginId: params.record.id,
472-source: params.record.manifestPath,
473-message: `providerAuthEnvVars is deprecated compatibility metadata for provider env-var lookup; mirror ${providerIds.join(", ")} env vars to setup.providers[].envVars before the deprecation window closes`,
485+pluginId: sanitizeForLog(params.record.id),
486+source: sanitizeForLog(params.record.manifestPath),
487+message: `providerAuthEnvVars is deprecated compatibility metadata for provider env-var lookup; mirror ${providerIds.map(sanitizeForLog).join(", ")} env vars to setup.providers[].envVars before the deprecation window closes`,
474488});
475489}
476490@@ -488,15 +502,18 @@ function pushNonBundledChannelConfigDescriptorDiagnostic(params: {
488502return;
489503}
490504const channelConfigs = params.record.channelConfigs ?? {};
491-const missingChannels = declaredChannels.filter((channelId) => !channelConfigs[channelId]);
505+const missingChannels = declaredChannels.filter(
506+(channelId) => !Object.prototype.hasOwnProperty.call(channelConfigs, channelId),
507+);
492508if (missingChannels.length === 0) {
493509return;
494510}
511+const safeMissingChannels = missingChannels.map(sanitizeForLog);
495512params.diagnostics.push({
496513level: "warn",
497-pluginId: params.record.id,
498-source: params.record.manifestPath,
499-message: `channel plugin manifest declares ${missingChannels.join(", ")} without channelConfigs metadata; add openclaw.plugin.json#channelConfigs so config schema and setup surfaces work before runtime loads`,
514+pluginId: sanitizeForLog(params.record.id),
515+source: sanitizeForLog(params.record.manifestPath),
516+message: `channel plugin manifest declares ${safeMissingChannels.join(", ")} without channelConfigs metadata; add openclaw.plugin.json#channelConfigs so config schema and setup surfaces work before runtime loads`,
500517});
501518}
502519此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。