惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

U
Unit 42
A
About on SuperTechFans
J
Java Code Geeks
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Stack Overflow Blog
Stack Overflow Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
F
Fortinet All Blogs
Blog — PlanetScale
Blog — PlanetScale
MongoDB | Blog
MongoDB | Blog
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
H
Help Net Security
月光博客
月光博客
博客园 - Franky
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
T
Tailwind CSS Blog
Jina AI
Jina AI
有赞技术团队
有赞技术团队
博客园_首页

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
fix: reject unowned CLI roots before plugin load (#76379)...
neilofneils4 · 2026-05-04 · via Recent Commits to openclaw:main
11

import { collectUniqueCommandDescriptors } from "../cli/program/command-descriptor-utils.js";

22

import type { OpenClawConfig } from "../config/types.openclaw.js";

3+

import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";

34

import { resolveManifestActivationPluginIds } from "./activation-planner.js";

45

import { createPluginCliGatewayNodesRuntime } from "./cli-gateway-nodes-runtime.js";

56

import type { PluginLoadOptions } from "./loader.js";

67

import { loadOpenClawPluginCliRegistry, loadOpenClawPlugins } from "./loader.js";

8+

import { createEmptyPluginRegistry } from "./registry-empty.js";

79

import type { PluginRegistry } from "./registry.js";

810

import {

911

buildPluginRuntimeLoadOptions,

@@ -53,20 +55,24 @@ function buildPluginCliLoaderParams(

5355

params?: { primaryCommand?: string },

5456

loaderOptions?: PluginCliLoaderOptions,

5557

) {

56-

const onlyPluginIds = resolvePrimaryCommandPluginIds(context, params?.primaryCommand);

58+

const onlyPluginIds = resolvePrimaryCommandManifestPluginIds(context, params?.primaryCommand);

5759

return buildPluginRuntimeLoadOptions(context, {

5860

...loaderOptions,

59-

...(onlyPluginIds.length > 0 ? { onlyPluginIds } : {}),

61+

...(onlyPluginIds && onlyPluginIds.length > 0 ? { onlyPluginIds } : {}),

6062

});

6163

}

626463-

function resolvePrimaryCommandPluginIds(

65+

function normalizePluginCliRootName(value: string | undefined): string {

66+

return normalizeLowercaseStringOrEmpty(value);

67+

}

68+69+

function resolvePrimaryCommandManifestPluginIds(

6470

context: PluginCliLoadContext,

6571

primaryCommand: string | undefined,

66-

): string[] {

67-

const normalizedPrimary = primaryCommand?.trim();

72+

): string[] | undefined {

73+

const normalizedPrimary = normalizePluginCliRootName(primaryCommand);

6874

if (!normalizedPrimary) {

69-

return [];

75+

return undefined;

7076

}

7177

return resolveManifestActivationPluginIds({

7278

trigger: {

@@ -79,6 +85,47 @@ function resolvePrimaryCommandPluginIds(

7985

});

8086

}

818788+

function listPluginCliRootOwnerIds(registry: PluginRegistry, primaryCommand: string): string[] {

89+

const normalizedPrimary = normalizePluginCliRootName(primaryCommand);

90+

if (!normalizedPrimary) {

91+

return [];

92+

}

93+

return [

94+

...new Set(

95+

registry.cliRegistrars

96+

.filter((entry) => {

97+

const roots = [

98+

...entry.commands,

99+

...entry.descriptors.map((descriptor) => descriptor.name),

100+

].map(normalizePluginCliRootName);

101+

return roots.includes(normalizedPrimary);

102+

})

103+

.map((entry) => entry.pluginId),

104+

),

105+

];

106+

}

107+108+

async function resolvePrimaryCommandPluginIds(

109+

context: PluginCliLoadContext,

110+

primaryCommand: string | undefined,

111+

loaderOptions?: PluginCliLoaderOptions,

112+

): Promise<string[] | undefined> {

113+

const normalizedPrimary = normalizePluginCliRootName(primaryCommand);

114+

if (!normalizedPrimary) {

115+

return undefined;

116+

}

117+

const manifestPluginIds = resolvePrimaryCommandManifestPluginIds(context, normalizedPrimary);

118+

if (manifestPluginIds && manifestPluginIds.length > 0) {

119+

return manifestPluginIds;

120+

}

121+

const { registry } = await loadPluginCliMetadataRegistryWithContext(

122+

context,

123+

{ primaryCommand: normalizedPrimary },

124+

loaderOptions,

125+

);

126+

return listPluginCliRootOwnerIds(registry, normalizedPrimary);

127+

}

128+82129

export function resolvePluginCliLoadContext(params: {

83130

cfg?: OpenClawConfig;

84131

env?: NodeJS.ProcessEnv;

@@ -109,13 +156,28 @@ export async function loadPluginCliCommandRegistryWithContext(params: {

109156

primaryCommand?: string;

110157

loaderOptions?: PluginCliLoaderOptions;

111158

}): Promise<PluginCliRegistryLoadResult> {

112-

const onlyPluginIds = resolvePrimaryCommandPluginIds(params.context, params.primaryCommand);

159+

let onlyPluginIds: string[] | undefined;

160+

try {

161+

onlyPluginIds = await resolvePrimaryCommandPluginIds(

162+

params.context,

163+

params.primaryCommand,

164+

params.loaderOptions,

165+

);

166+

} catch {

167+

onlyPluginIds = resolvePrimaryCommandManifestPluginIds(params.context, params.primaryCommand);

168+

}

169+

if (onlyPluginIds && onlyPluginIds.length === 0) {

170+

return {

171+

...params.context,

172+

registry: createEmptyPluginRegistry(),

173+

};

174+

}

113175

return {

114176

...params.context,

115177

registry: loadOpenClawPlugins(

116178

buildPluginRuntimeLoadOptions(params.context, {

117179

...params.loaderOptions,

118-

...(onlyPluginIds.length > 0 ? { onlyPluginIds } : {}),

180+

...(onlyPluginIds && onlyPluginIds.length > 0 ? { onlyPluginIds } : {}),

119181

activate: false,

120182

cache: false,

121183

runtimeOptions: {

@@ -196,6 +258,24 @@ export async function loadPluginCliRegistrationEntries(params: {

196258

});

197259

}

198260261+

export async function resolvePluginCliRootOwnerIds(

262+

params: PluginCliPublicLoadParams,

263+

): Promise<string[] | null> {

264+

const primaryCommand = normalizePluginCliRootName(params.primaryCommand);

265+

if (!primaryCommand) {

266+

return null;

267+

}

268+

const logger = resolvePluginCliLogger(params.logger);

269+

const context = resolvePluginCliLoadContext({

270+

cfg: params.cfg,

271+

env: params.env,

272+

logger,

273+

});

274+

return (

275+

(await resolvePrimaryCommandPluginIds(context, primaryCommand, params.loaderOptions)) ?? null

276+

);

277+

}

278+199279

export async function loadPluginCliRegistrationEntriesWithDefaults(

200280

params: PluginCliPublicLoadParams,

201281

): Promise<PluginCliCommandGroupEntry[]> {