




















@@ -19,6 +19,12 @@ type CandidateDir = {
19192020const OPENCLAW_PACKAGE_ROOT = fileURLToPath(new URL("../..", import.meta.url));
2121const PLUGIN_MANIFEST_FILENAME = "openclaw.plugin.json";
22+let manifestMetadataCache:
23+| {
24+key: string;
25+records: PluginManifestMetadataRecord[];
26+}
27+| undefined;
22282329function isRecord(value: unknown): value is Record<string, unknown> {
2430return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -106,6 +112,16 @@ function readManifestObject(pluginDir: string): Record<string, unknown> | undefi
106112return readJsonObject(path.join(pluginDir, PLUGIN_MANIFEST_FILENAME));
107113}
108114115+function manifestFileFingerprint(pluginDir: string): string {
116+const manifestPath = path.join(pluginDir, PLUGIN_MANIFEST_FILENAME);
117+try {
118+const stat = fs.statSync(manifestPath);
119+return `${manifestPath}:${stat.mtimeMs}:${stat.size}`;
120+} catch {
121+return `${manifestPath}:missing`;
122+}
123+}
124+109125function listPersistedIndexPluginDirs(env: NodeJS.ProcessEnv, startOrder: number): CandidateDir[] {
110126const index = readJsonObject(path.join(resolveStateDir(env), "plugins", "installs.json"));
111127if (!index || !Array.isArray(index.plugins)) {
@@ -167,9 +183,23 @@ export function listOpenClawPluginManifestMetadata(
167183 ...listChildPluginDirs(path.join(resolveStateDir(env), "extensions"), 4, order, "global"),
168184);
169185186+const uniqueCandidates = uniqueCandidateDirs(candidates);
187+const cacheKey = JSON.stringify(
188+uniqueCandidates.map((candidate) => [
189+candidate.pluginDir,
190+candidate.rank,
191+candidate.order,
192+candidate.origin ?? "",
193+manifestFileFingerprint(candidate.pluginDir),
194+]),
195+);
196+if (manifestMetadataCache?.key === cacheKey) {
197+return manifestMetadataCache.records.slice();
198+}
199+170200const byManifestId = new Map<string, CandidateDir>();
171201const records: PluginManifestMetadataRecord[] = [];
172-for (const candidate of uniqueCandidateDirs(candidates)) {
202+for (const candidate of uniqueCandidates) {
173203const manifest = readManifestObject(candidate.pluginDir);
174204if (!manifest) {
175205continue;
@@ -184,5 +214,6 @@ export function listOpenClawPluginManifestMetadata(
184214}
185215records.push({ pluginDir: candidate.pluginDir, manifest, origin: candidate.origin });
186216}
217+manifestMetadataCache = { key: cacheKey, records };
187218return records;
188219}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。