






















@@ -1,18 +1,22 @@
11import fs from "node:fs/promises";
22import path from "node:path";
3-import { listChannelPlugins } from "../channels/plugins/index.js";
3+import { listReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js";
4+import type { ChannelPlugin } from "../channels/plugins/types.plugin.js";
45import { inspectReadOnlyChannelAccount } from "../channels/read-only-account-inspect.js";
56import { resolveNativeSkillsEnabled } from "../config/commands.js";
67import type { OpenClawConfig } from "../config/config.js";
78import type { AgentToolsConfig } from "../config/types.tools.js";
89import { readInstalledPackageVersion } from "../infra/package-update-utils.js";
9-import { normalizePluginId, normalizePluginsConfig } from "../plugins/config-state.js";
10+import { normalizePluginsConfig } from "../plugins/config-state.js";
1011import { loadInstalledPluginIndexInstallRecords } from "../plugins/installed-plugin-index-record-reader.js";
12+import {
13+createPluginRegistryIdNormalizer,
14+loadPluginRegistrySnapshot,
15+} from "../plugins/plugin-registry.js";
1116import { normalizeOptionalLowercaseString } from "../shared/string-coerce.js";
1217import type { SecurityAuditFinding } from "./audit.types.js";
13181419type SandboxToolPolicy = import("../agents/sandbox/types.js").SandboxToolPolicy;
15-type ChannelPlugin = ReturnType<typeof listChannelPlugins>[number];
16201721type PluginTrustPolicyDeps = {
1822isToolAllowedByPolicies: typeof import("../agents/tool-policy-match.js").isToolAllowedByPolicies;
@@ -282,17 +286,24 @@ export async function collectPluginsTrustFindings(params: {
282286283287if (allowConfigured) {
284288const installedPluginIds = new Set(pluginDirs.map((dir) => path.basename(dir).toLowerCase()));
285-const bundledPluginIds = new Set(listChannelPlugins().map((p) => p.id.toLowerCase()));
289+const pluginIndex = loadPluginRegistrySnapshot({
290+config: params.cfg,
291+stateDir: params.stateDir,
292+});
293+const normalizePluginId = createPluginRegistryIdNormalizer(pluginIndex);
294+const indexedPluginIds = new Set(
295+pluginIndex.plugins.map((plugin) => plugin.pluginId.toLowerCase()),
296+);
286297const phantomEntries = allow.filter((entry) => {
287298if (typeof entry !== "string" || entry === "group:plugins") {
288299return false;
289300}
290301const lower = entry.toLowerCase();
291-if (installedPluginIds.has(lower) || bundledPluginIds.has(lower)) {
302+if (installedPluginIds.has(lower) || indexedPluginIds.has(lower)) {
292303return false;
293304}
294305const canonicalId = normalizeOptionalLowercaseString(normalizePluginId(entry)) ?? "";
295-return !canonicalId || !bundledPluginIds.has(canonicalId);
306+return !canonicalId || !indexedPluginIds.has(canonicalId);
296307});
297308if (phantomEntries.length > 0) {
298309findings.push({
@@ -309,9 +320,12 @@ export async function collectPluginsTrustFindings(params: {
309320}
310321311322if (!allowConfigured) {
323+const channelPlugins = listReadOnlyChannelPluginsForConfig(params.cfg, {
324+stateDir: params.stateDir,
325+});
312326const skillCommandsLikelyExposed = (
313327await Promise.all(
314-listChannelPlugins().map(async (plugin) => {
328+channelPlugins.map(async (plugin) => {
315329if (
316330plugin.capabilities.nativeCommands !== true &&
317331plugin.commands?.nativeSkillsAutoEnabled !== true
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。