Skip to content

Commit 1a193b2

Browse files
committed
fix: scope cold plugin manifests to index
1 parent f8a677b commit 1a193b2

48 files changed

Lines changed: 316 additions & 335 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Docs: https://docs.openclaw.ai
3030
- Plugins/startup: normalize startup and provider plugin enablement through registry aliases so boot paths do not need the legacy manifest alias scan. Thanks @vincentkoc.
3131
- Providers/plugins: resolve provider ownership, provider discovery scopes, and catalog-hook provider ids from the cold plugin registry instead of rescanning manifests on those paths. Thanks @vincentkoc.
3232
- Plugins/registry: keep installed plugin index records focused on install/state/load paths and resolve plugin capabilities from manifests scoped to indexed plugins. Thanks @shakkernerd.
33+
- Plugins/registry: route cold manifest and capability lookups through the installed plugin index so setup, channels, config, secrets, doctor, and provider metadata paths avoid broad plugin-root scans before runtime execution. Thanks @shakkernerd.
3334
- Plugins/chat commands: refresh the persisted plugin registry after `/plugins enable` and `/plugins disable`, matching the CLI mutation path. Thanks @vincentkoc.
3435
- Plugins/compat: mark `OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY` as a deprecated break-glass switch and point operators at registry repair instead. Thanks @vincentkoc.
3536
- 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.

src/agents/model-auth-markers.ts

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { SecretRefSource } from "../config/types.secrets.js";
2-
import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js";
3-
import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js";
2+
import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js";
43
import { listKnownProviderEnvApiKeyNames } from "./model-auth-env-vars.js";
54

65
export const MINIMAX_OAUTH_MARKER = "minimax-oauth";
@@ -45,20 +44,14 @@ function listKnownEnvApiKeyMarkers(): Set<string> {
4544
}
4645

4746
export function listKnownNonSecretApiKeyMarkers(): string[] {
48-
knownNonSecretApiKeyMarkersCache ??= (() => {
49-
const index = loadPluginRegistrySnapshot({});
50-
return [
51-
...new Set([
52-
...CORE_NON_SECRET_API_KEY_MARKERS,
53-
...loadPluginManifestRegistryForInstalledIndex({
54-
index,
55-
includeDisabled: true,
56-
}).plugins.flatMap((plugin) =>
57-
plugin.origin === "bundled" ? (plugin.nonSecretAuthMarkers ?? []) : [],
58-
),
59-
]),
60-
];
61-
})();
47+
knownNonSecretApiKeyMarkersCache ??= [
48+
...new Set([
49+
...CORE_NON_SECRET_API_KEY_MARKERS,
50+
...loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true }).plugins.flatMap(
51+
(plugin) => (plugin.origin === "bundled" ? (plugin.nonSecretAuthMarkers ?? []) : []),
52+
),
53+
]),
54+
];
6255
return [...knownNonSecretApiKeyMarkersCache];
6356
}
6457

src/agents/pi-project-settings-snapshot.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import {
1010
normalizePluginsConfigWithResolver,
1111
resolveEffectivePluginActivationState,
1212
} from "../plugins/config-policy.js";
13-
import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js";
1413
import type { PluginManifestRegistry } from "../plugins/manifest-registry.js";
15-
import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js";
14+
import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js";
1615
import { isRecord } from "../utils.js";
1716
import { loadEmbeddedPiMcpConfig } from "./embedded-pi-mcp.js";
1817

@@ -105,12 +104,7 @@ export function loadEnabledBundlePiSettingsSnapshot(params: {
105104
if (!workspaceDir) {
106105
return {};
107106
}
108-
const index = loadPluginRegistrySnapshot({
109-
workspaceDir,
110-
config: params.cfg,
111-
});
112-
const registry = loadPluginManifestRegistryForInstalledIndex({
113-
index,
107+
const registry = loadPluginManifestRegistryForPluginRegistry({
114108
workspaceDir,
115109
config: params.cfg,
116110
includeDisabled: true,

src/agents/pi-project-settings.bundle.test.ts

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,39 @@ vi.mock("../plugins/manifest-registry-installed.js", async () => {
4545
};
4646
});
4747

48-
vi.mock("../plugins/plugin-registry.js", () => ({
49-
loadPluginRegistrySnapshot: () => ({ plugins: [] }),
50-
}));
48+
vi.mock("../plugins/plugin-registry.js", async () => {
49+
const fs = await import("node:fs");
50+
const path = await import("node:path");
51+
const loadRegistry = (params: { workspaceDir?: string }) => {
52+
const rootDir = path.join(
53+
params.workspaceDir ?? "",
54+
".openclaw",
55+
"extensions",
56+
"claude-bundle",
57+
);
58+
if (!fs.existsSync(path.join(rootDir, ".claude-plugin", "plugin.json"))) {
59+
return { plugins: [], diagnostics: [] };
60+
}
61+
const resolvedRootDir = fs.realpathSync(rootDir);
62+
return {
63+
diagnostics: [],
64+
plugins: [
65+
{
66+
id: "claude-bundle",
67+
origin: "workspace",
68+
format: "bundle",
69+
bundleFormat: "claude",
70+
settingsFiles: ["settings.json"],
71+
rootDir: resolvedRootDir,
72+
},
73+
],
74+
};
75+
};
76+
return {
77+
loadPluginManifestRegistryForPluginRegistry: loadRegistry,
78+
loadPluginRegistrySnapshot: () => ({ plugins: [] }),
79+
};
80+
});
5181

5282
vi.mock("./embedded-pi-mcp.js", async () => {
5383
const fs = await import("node:fs");

src/agents/provider-attribution.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js";
2-
import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js";
1+
import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js";
32
import {
43
normalizeOptionalLowercaseString,
54
normalizeOptionalString,
@@ -209,11 +208,7 @@ function isManifestProviderEndpointClass(value: string): value is ProviderEndpoi
209208

210209
function loadManifestProviderEndpointCache(): ManifestProviderEndpointCacheEntry[] {
211210
if (!manifestProviderEndpointCache) {
212-
const index = loadPluginRegistrySnapshot({ cache: true });
213-
const registry = loadPluginManifestRegistryForInstalledIndex({
214-
index,
215-
includeDisabled: true,
216-
});
211+
const registry = loadPluginManifestRegistryForPluginRegistry({ includeDisabled: true });
217212
const entries: ManifestProviderEndpointCacheEntry[] = [];
218213
for (const plugin of registry.plugins) {
219214
for (const endpoint of plugin.providerEndpoints ?? []) {

src/agents/provider-auth-aliases.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
import { describe, expect, it, vi } from "vitest";
22

3-
const pluginRegistryMocks = vi.hoisted(() => ({
4-
loadPluginManifestRegistryForInstalledIndex: vi.fn(),
5-
loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })),
6-
}));
3+
const pluginRegistryMocks = vi.hoisted(() => {
4+
const loadManifestRegistry = vi.fn();
5+
return {
6+
loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry,
7+
loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry,
8+
loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })),
9+
};
10+
});
711

812
vi.mock("../plugins/manifest-registry-installed.js", () => ({
913
loadPluginManifestRegistryForInstalledIndex:
1014
pluginRegistryMocks.loadPluginManifestRegistryForInstalledIndex,
1115
}));
1216

1317
vi.mock("../plugins/plugin-registry.js", () => ({
18+
loadPluginManifestRegistryForPluginRegistry:
19+
pluginRegistryMocks.loadPluginManifestRegistryForPluginRegistry,
1420
loadPluginRegistrySnapshot: pluginRegistryMocks.loadPluginRegistrySnapshot,
1521
}));
1622

src/agents/provider-auth-aliases.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import type { OpenClawConfig } from "../config/types.openclaw.js";
2-
import { loadPluginManifestRegistryForInstalledIndex } from "../plugins/manifest-registry-installed.js";
32
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
43
import {
54
isWorkspacePluginAllowedByConfig,
65
normalizePluginConfigId,
76
} from "../plugins/plugin-config-trust.js";
87
import type { PluginOrigin } from "../plugins/plugin-origin.types.js";
9-
import { loadPluginRegistrySnapshot } from "../plugins/plugin-registry.js";
8+
import { loadPluginManifestRegistryForPluginRegistry } from "../plugins/plugin-registry.js";
109
import { normalizeProviderId } from "./provider-id.js";
1110

1211
export type ProviderAuthAliasLookupParams = {
@@ -84,13 +83,7 @@ function setPreferredAlias(params: {
8483
export function resolveProviderAuthAliasMap(
8584
params?: ProviderAuthAliasLookupParams,
8685
): Record<string, string> {
87-
const index = loadPluginRegistrySnapshot({
88-
config: params?.config,
89-
workspaceDir: params?.workspaceDir,
90-
env: params?.env,
91-
});
92-
const registry = loadPluginManifestRegistryForInstalledIndex({
93-
index,
86+
const registry = loadPluginManifestRegistryForPluginRegistry({
9487
config: params?.config,
9588
workspaceDir: params?.workspaceDir,
9689
env: params?.env,

src/agents/skills/plugin-skills.test.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,21 @@ import type { OpenClawConfig } from "../../config/config.js";
55
import type { PluginManifestRegistry } from "../../plugins/manifest-registry.js";
66
import { createTrackedTempDirs } from "../../test-utils/tracked-temp-dirs.js";
77

8-
const hoisted = vi.hoisted(() => ({
9-
loadPluginManifestRegistryForInstalledIndex: vi.fn(),
10-
loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })),
11-
}));
8+
const hoisted = vi.hoisted(() => {
9+
const loadManifestRegistry = vi.fn();
10+
return {
11+
loadPluginManifestRegistryForInstalledIndex: loadManifestRegistry,
12+
loadPluginManifestRegistryForPluginRegistry: loadManifestRegistry,
13+
loadPluginRegistrySnapshot: vi.fn(() => ({ plugins: [] })),
14+
};
15+
});
1216

1317
vi.mock("../../plugins/manifest-registry-installed.js", () => ({
1418
loadPluginManifestRegistryForInstalledIndex: hoisted.loadPluginManifestRegistryForInstalledIndex,
1519
}));
1620

1721
vi.mock("../../plugins/plugin-registry.js", () => ({
22+
loadPluginManifestRegistryForPluginRegistry: hoisted.loadPluginManifestRegistryForPluginRegistry,
1823
loadPluginRegistrySnapshot: hoisted.loadPluginRegistrySnapshot,
1924
}));
2025

src/agents/skills/plugin-skills.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import {
77
resolveEffectivePluginActivationState,
88
resolveMemorySlotDecision,
99
} from "../../plugins/config-policy.js";
10-
import { loadPluginManifestRegistryForInstalledIndex } from "../../plugins/manifest-registry-installed.js";
1110
import type { PluginManifestRegistry } from "../../plugins/manifest-registry.js";
12-
import { loadPluginRegistrySnapshot } from "../../plugins/plugin-registry.js";
11+
import { loadPluginManifestRegistryForPluginRegistry } from "../../plugins/plugin-registry.js";
1312
import { hasKind } from "../../plugins/slots.js";
1413
import { isPathInsideWithRealpath } from "../../security/scan-paths.js";
1514

@@ -50,12 +49,7 @@ export function resolvePluginSkillDirs(params: {
5049
if (!workspaceDir) {
5150
return [];
5251
}
53-
const index = loadPluginRegistrySnapshot({
54-
workspaceDir,
55-
config: params.config,
56-
});
57-
const registry = loadPluginManifestRegistryForInstalledIndex({
58-
index,
52+
const registry = loadPluginManifestRegistryForPluginRegistry({
5953
workspaceDir,
6054
config: params.config,
6155
includeDisabled: true,

src/channels/plugins/read-only.ts

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ import {
77
resolveDiscoverableScopedChannelPluginIds,
88
} from "../../plugins/channel-plugin-ids.js";
99
import { loadOpenClawPlugins } from "../../plugins/loader.js";
10-
import { loadPluginManifestRegistryForInstalledIndex } from "../../plugins/manifest-registry-installed.js";
1110
import type { PluginManifestRecord } from "../../plugins/manifest-registry.js";
12-
import { loadPluginRegistrySnapshot } from "../../plugins/plugin-registry.js";
11+
import { loadPluginManifestRegistryForPluginRegistry } from "../../plugins/plugin-registry.js";
1312
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../../routing/session-key.js";
1413
import { sanitizeForLog } from "../../terminal/ansi.js";
1514
import { getBundledChannelSetupPlugin } from "./bundled.js";
@@ -521,17 +520,11 @@ export function resolveReadOnlyChannelPluginsForConfig(
521520
): ReadOnlyChannelPluginResolution {
522521
const env = options.env ?? process.env;
523522
const workspaceDir = resolveReadOnlyWorkspaceDir(cfg, options);
524-
const pluginIndex = loadPluginRegistrySnapshot({
523+
const manifestRecords = loadPluginManifestRegistryForPluginRegistry({
525524
config: cfg,
526525
workspaceDir,
527526
env,
528527
cache: options.cache,
529-
});
530-
const manifestRecords = loadPluginManifestRegistryForInstalledIndex({
531-
index: pluginIndex,
532-
config: cfg,
533-
workspaceDir,
534-
env,
535528
includeDisabled: true,
536529
}).plugins;
537530
const externalManifestRecords = listExternalChannelManifestRecords(manifestRecords);

0 commit comments

Comments
 (0)