fix: support root execution and factory-registered tool lookup
- Replace --dangerously-skip-permissions with --allowedTools whitelist to support running Claude Code as root (root blocks the former flag) - Fix /mcp/execute tool lookup for plugins that register tools via factory functions (e.g. padded-cell pcexec) where the global registry names array is empty — now falls back to instantiating factories and matching by returned tool name Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -98,7 +98,7 @@ export async function* dispatchToClaude(
|
||||
workspace,
|
||||
agentId = "",
|
||||
resumeSessionId,
|
||||
permissionMode = "bypassPermissions",
|
||||
permissionMode = "default",
|
||||
openclawTools,
|
||||
bridgePort = 18800,
|
||||
bridgeApiKey = "",
|
||||
@@ -112,8 +112,7 @@ export async function* dispatchToClaude(
|
||||
prompt,
|
||||
"--output-format", "stream-json",
|
||||
"--verbose",
|
||||
"--permission-mode", permissionMode,
|
||||
"--dangerously-skip-permissions",
|
||||
"--allowedTools", "Bash Edit Write Read Glob Grep WebFetch WebSearch NotebookEdit Monitor TodoWrite mcp__openclaw__*",
|
||||
];
|
||||
|
||||
// --append-system-prompt appends to Claude Code's built-in system prompt rather
|
||||
|
||||
@@ -321,21 +321,8 @@ export function createBridgeServer(config: BridgeServerConfig): http.Server {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the tool registration by name
|
||||
const toolReg = pluginRegistry.tools.find((t) => t.names.includes(toolName));
|
||||
if (!toolReg) {
|
||||
sendJson(res, 200, { error: `Tool '${toolName}' not registered in OpenClaw plugin registry` });
|
||||
return;
|
||||
}
|
||||
|
||||
// Build tool execution context.
|
||||
// config is required by memory tools (resolveMemoryToolContext checks it).
|
||||
// Read from globalThis where index.ts stores api.config on every registration.
|
||||
// sessionKey must be in OpenClaw's canonical format "agent:<agentId>:<rest>" so that
|
||||
// parseAgentSessionKey() can extract the agentId for memory tool context resolution.
|
||||
// Build tool execution context (needed before tool lookup for factory instantiation).
|
||||
const liveConfig = (_G["_contractorOpenClawConfig"] ?? null) as Record<string, unknown> | null;
|
||||
// Construct a canonical session key so memory tools can resolve the agentId from it.
|
||||
// Format: "agent:<agentId>:direct:bridge"
|
||||
const canonicalSessionKey = execAgentId ? `agent:${execAgentId}:direct:bridge` : undefined;
|
||||
const toolCtx = {
|
||||
config: liveConfig ?? undefined,
|
||||
@@ -345,6 +332,28 @@ export function createBridgeServer(config: BridgeServerConfig): http.Server {
|
||||
sessionKey: canonicalSessionKey,
|
||||
};
|
||||
|
||||
// Find tool by name. Some plugins register tools via factory functions without
|
||||
// declaring names upfront (names array is empty). For those, instantiate the
|
||||
// factory and match by the returned tool's .name property.
|
||||
let toolReg = pluginRegistry.tools.find((t) => t.names.includes(toolName));
|
||||
if (!toolReg) {
|
||||
for (const candidate of pluginRegistry.tools) {
|
||||
if (candidate.names.length > 0) continue;
|
||||
try {
|
||||
const inst = candidate.factory(toolCtx);
|
||||
const items = Array.isArray(inst) ? inst : [inst];
|
||||
if (items.some((t) => (t as { name?: string }).name === toolName)) {
|
||||
toolReg = candidate;
|
||||
break;
|
||||
}
|
||||
} catch { /* skip */ }
|
||||
}
|
||||
}
|
||||
if (!toolReg) {
|
||||
sendJson(res, 200, { error: `Tool '${toolName}' not registered in OpenClaw plugin registry` });
|
||||
return;
|
||||
}
|
||||
|
||||
// Instantiate the tool via its factory
|
||||
const toolOrTools = toolReg.factory(toolCtx);
|
||||
const toolInstance = Array.isArray(toolOrTools)
|
||||
|
||||
Reference in New Issue
Block a user