diff --git a/plugin/core/claude/sdk-adapter.ts b/plugin/core/claude/sdk-adapter.ts index 7ded254..c4f4b74 100644 --- a/plugin/core/claude/sdk-adapter.ts +++ b/plugin/core/claude/sdk-adapter.ts @@ -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 diff --git a/plugin/web/server.ts b/plugin/web/server.ts index 167a95c..6568197 100644 --- a/plugin/web/server.ts +++ b/plugin/web/server.ts @@ -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::" 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 | null; - // Construct a canonical session key so memory tools can resolve the agentId from it. - // Format: "agent::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)