From 2e1b5407ddfa1ce35289c49b16e7432750ad2b97 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 13 Apr 2026 10:50:52 +0100 Subject: [PATCH] fix: preserve qmd command paths --- CHANGELOG.md | 1 + src/memory-host-sdk/host/backend-config.test.ts | 4 ++-- src/memory-host-sdk/host/backend-config.ts | 10 +--------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84a6e8d12aa..153352951b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ Docs: https://docs.openclaw.ai - iMessage: retry transient `watch.subscribe` startup failures before tearing down the monitor, and sanitize startup error logging so brief local transport stalls do not immediately bounce the channel or leak raw imsg RPC payloads into logs. (#65393) Thanks @vincentkoc. - CLI/audio providers: report env-authenticated providers as configured in `openclaw infer audio providers --json`, while keeping trusted workspace provider env lookup defaults stable during auth setup. (#65491) - Plugins/install: reinstall bundled runtime packages when the matching platform native optional child is missing, so packaged Windows installs can recover dependencies that were packed on another host OS. +- Memory/QMD: preserve explicit `memory.qmd.command` paths when resolving the QMD backend, so service and gateway environments can use Homebrew installs without falling back to builtin search. ## 2026.4.11 diff --git a/src/memory-host-sdk/host/backend-config.test.ts b/src/memory-host-sdk/host/backend-config.test.ts index 3cf22622512..d8f539cc887 100644 --- a/src/memory-host-sdk/host/backend-config.test.ts +++ b/src/memory-host-sdk/host/backend-config.test.ts @@ -89,7 +89,7 @@ describe("resolveMemoryBackendConfig", () => { expect(resolved.qmd?.command).toBe("/Applications/QMD Tools/qmd"); }); - it("normalizes stale homebrew qmd paths to the portable command", () => { + it("preserves explicit homebrew qmd paths for service environments", () => { const cfg = { agents: { defaults: { workspace: "/tmp/memory-test" } }, memory: { @@ -100,7 +100,7 @@ describe("resolveMemoryBackendConfig", () => { }, } as OpenClawConfig; const resolved = resolveMemoryBackendConfig({ cfg, agentId: "main" }); - expect(resolved.qmd?.command).toBe("qmd"); + expect(resolved.qmd?.command).toBe("/opt/homebrew/bin/qmd"); }); it("resolves custom paths relative to workspace", () => { diff --git a/src/memory-host-sdk/host/backend-config.ts b/src/memory-host-sdk/host/backend-config.ts index 1ab57c346a8..ae6a2da55d3 100644 --- a/src/memory-host-sdk/host/backend-config.ts +++ b/src/memory-host-sdk/host/backend-config.ts @@ -244,14 +244,6 @@ function resolveSearchTool(raw?: MemoryQmdConfig["searchTool"]): string | undefi return value ? value : undefined; } -function normalizeQmdCommand(command: string): string { - const normalized = path.normalize(command); - if (normalized === "/opt/homebrew/bin/qmd" || normalized === "/usr/local/bin/qmd") { - return "qmd"; - } - return command; -} - function resolveSessionConfig( cfg: MemoryQmdConfig["sessions"], workspaceDir: string, @@ -405,7 +397,7 @@ export function resolveMemoryBackendConfig(params: { const rawCommand = normalizeOptionalString(qmdCfg?.command) || "qmd"; const parsedCommand = splitShellArgs(rawCommand); - const command = normalizeQmdCommand(parsedCommand?.[0] || rawCommand.split(/\s+/)[0] || "qmd"); + const command = parsedCommand?.[0] || rawCommand.split(/\s+/)[0] || "qmd"; const resolved: ResolvedQmdConfig = { command, mcporter: resolveMcporterConfig(qmdCfg?.mcporter),