

























@@ -46,6 +46,8 @@ import { checkMinHostVersion } from "./min-host-version.js";
4646import {
4747getOfficialExternalPluginCatalogEntryForPackage,
4848getOfficialExternalPluginCatalogManifest,
49+resolveOfficialExternalPluginId,
50+resolveOfficialExternalPluginInstall,
4951} from "./official-external-plugin-catalog.js";
5052import { isPathInside, safeRealpathSync } from "./path-safety.js";
5153import type { PluginKind } from "./plugin-kind.types.js";
@@ -140,6 +142,7 @@ export type PluginManifestRecord = {
140142packageOptionalDependencies?: PluginDependencySpecMap;
141143packageChannel?: PluginPackageChannel;
142144packageInstall?: PluginPackageInstall;
145+trustedOfficialInstall?: boolean;
143146qaRunners?: PluginManifestQaRunner[];
144147skills: string[];
145148settingsFiles?: string[];
@@ -365,6 +368,7 @@ function buildRecord(params: {
365368schemaCacheKey?: string;
366369configSchema?: Record<string, unknown>;
367370bundledChannelConfigCollector?: BundledChannelConfigCollector;
371+trustedOfficialInstall?: boolean;
368372}): PluginManifestRecord {
369373const manifestChannelConfigs =
370374params.candidate.origin === "bundled" && params.bundledChannelConfigCollector
@@ -434,6 +438,7 @@ function buildRecord(params: {
434438packageOptionalDependencies: params.candidate.packageOptionalDependencies,
435439packageChannel: params.candidate.packageManifest?.channel,
436440packageInstall: params.candidate.packageManifest?.install,
441+trustedOfficialInstall: params.trustedOfficialInstall === true ? true : undefined,
437442qaRunners: params.manifest.qaRunners,
438443skills: params.manifest.skills ?? [],
439444settingsFiles: [],
@@ -634,7 +639,7 @@ function matchesInstalledPluginRecord(params: {
634639env: NodeJS.ProcessEnv;
635640installRecords: Record<string, PluginInstallRecord>;
636641}): boolean {
637-if (params.candidate.origin !== "global") {
642+if (params.candidate.origin !== "global" && params.candidate.origin !== "config") {
638643return false;
639644}
640645const record = params.installRecords[params.pluginId];
@@ -653,6 +658,72 @@ function matchesInstalledPluginRecord(params: {
653658});
654659}
655660661+function npmSpecMatchesPackage(value: string | undefined, packageName: string): boolean {
662+const normalized = value?.trim();
663+if (!normalized) {
664+return false;
665+}
666+if (normalized === packageName) {
667+return true;
668+}
669+return normalized.startsWith(`${packageName}@`);
670+}
671+672+function isTrustedOfficialPluginInstall(params: {
673+pluginId: string;
674+candidate: PluginCandidate;
675+env: NodeJS.ProcessEnv;
676+installRecords: Record<string, PluginInstallRecord>;
677+}): boolean {
678+if (
679+(params.candidate.origin !== "global" && params.candidate.origin !== "config") ||
680+!matchesInstalledPluginRecord({
681+pluginId: params.pluginId,
682+candidate: params.candidate,
683+env: params.env,
684+installRecords: params.installRecords,
685+})
686+) {
687+return false;
688+}
689+const packageName = params.candidate.packageName?.trim();
690+if (!packageName) {
691+return false;
692+}
693+const catalogEntry = getOfficialExternalPluginCatalogEntryForPackage(packageName);
694+if (!catalogEntry || resolveOfficialExternalPluginId(catalogEntry) !== params.pluginId) {
695+return false;
696+}
697+const officialInstall = resolveOfficialExternalPluginInstall(catalogEntry);
698+const installRecord = params.installRecords[params.pluginId];
699+if (!installRecord) {
700+return false;
701+}
702+if (
703+installRecord.source === "npm" &&
704+officialInstall?.npmSpec === packageName &&
705+[
706+installRecord.resolvedName,
707+installRecord.spec,
708+installRecord.resolvedSpec,
709+params.candidate.packageName,
710+].some((value) => npmSpecMatchesPackage(value, packageName))
711+) {
712+return true;
713+}
714+if (
715+installRecord.source === "clawhub" &&
716+officialInstall?.clawhubSpec &&
717+installRecord.clawhubChannel === "official" &&
718+(installRecord.clawhubPackage === packageName ||
719+installRecord.spec === officialInstall.clawhubSpec ||
720+installRecord.resolvedSpec === officialInstall.clawhubSpec)
721+) {
722+return true;
723+}
724+return false;
725+}
726+656727function resolveDuplicatePrecedenceRank(params: {
657728pluginId: string;
658729candidate: PluginCandidate;
@@ -858,6 +929,12 @@ export function loadPluginManifestRegistry(
858929manifestPath: manifestRes.manifestPath,
859930 schemaCacheKey,
860931 configSchema,
932+trustedOfficialInstall: isTrustedOfficialPluginInstall({
933+pluginId: manifest.id,
934+ candidate,
935+ env,
936+installRecords: getInstallRecords(),
937+}),
861938 ...(params.bundledChannelConfigCollector
862939 ? { bundledChannelConfigCollector: params.bundledChannelConfigCollector }
863940 : {}),
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。