Skip to content

Commit 2f91a07

Browse files
author
hclsys
committed
fix(qqbot): preserve data root for custom home media
1 parent 5f85c7a commit 2f91a07

2 files changed

Lines changed: 43 additions & 9 deletions

File tree

extensions/qqbot/src/engine/utils/platform.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import os from "node:os";
33
import path from "node:path";
44
import { afterEach, describe, expect, it, vi } from "vitest";
55
import {
6+
getQQBotDataPath,
67
getQQBotMediaPath,
78
getHomeDir,
89
resolveQQBotLocalMediaPath,
@@ -61,6 +62,29 @@ describe("qqbot local media path remapping", () => {
6162
expect(resolveQQBotPayloadLocalFilePath(mediaFile)).toBe(fs.realpathSync(mediaFile));
6263
});
6364

65+
it("keeps QQ Bot persisted data on the legacy home-derived root when OPENCLAW_HOME is configured", () => {
66+
const hostHome = fs.mkdtempSync(path.join(os.tmpdir(), "qqbot-platform-home-"));
67+
const openclawHome = fs.mkdtempSync(path.join(os.tmpdir(), "qqbot-platform-openclaw-home-"));
68+
createdPaths.push(hostHome, openclawHome);
69+
vi.stubEnv("HOME", hostHome);
70+
vi.stubEnv("OPENCLAW_HOME", openclawHome);
71+
72+
expect(getQQBotDataPath("sessions", "main.json")).toBe(
73+
path.join(getHomeDir(), ".openclaw", "qqbot", "sessions", "main.json"),
74+
);
75+
});
76+
77+
it("expands QQ Bot OPENCLAW_HOME media roots through HOME for tilde paths", () => {
78+
const hostHome = fs.mkdtempSync(path.join(os.tmpdir(), "qqbot-platform-home-"));
79+
createdPaths.push(hostHome);
80+
vi.stubEnv("HOME", hostHome);
81+
vi.stubEnv("OPENCLAW_HOME", "~/svc");
82+
83+
expect(getQQBotMediaPath("image.png")).toBe(
84+
path.join(hostHome, "svc", ".openclaw", "media", "qqbot", "image.png"),
85+
);
86+
});
87+
6488
it("remaps missing workspace media paths to the real media directory", () => {
6589
const { actualHome, testRootName, mediaFile } = createQqbotMediaFile("example.png");
6690

extensions/qqbot/src/engine/utils/platform.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ import { getPlatformAdapter } from "../adapter/index.js";
1313
import { formatErrorMessage } from "./format.js";
1414
import { debugLog, debugWarn } from "./log.js";
1515

16+
function normalizeEnvPath(value: string | undefined): string | undefined {
17+
const trimmed = value?.trim();
18+
if (!trimmed || trimmed === "undefined" || trimmed === "null") {
19+
return undefined;
20+
}
21+
return trimmed;
22+
}
23+
1624
/**
1725
* Resolve the current user's home directory safely across platforms.
1826
*
@@ -39,23 +47,25 @@ export function getHomeDir(): string {
3947
return getPlatformAdapter().getTempDir();
4048
}
4149

42-
function resolveOpenClawHomeDir(): string {
43-
const explicitHome = process.env.OPENCLAW_HOME?.trim();
50+
function resolveOpenClawMediaHomeDir(): string {
51+
const explicitHome = normalizeEnvPath(process.env.OPENCLAW_HOME);
4452
if (!explicitHome) {
4553
return getHomeDir();
4654
}
47-
if (explicitHome === "~") {
48-
return getHomeDir();
49-
}
5055
if (explicitHome.startsWith("~/") || explicitHome.startsWith("~\\")) {
51-
return path.join(getHomeDir(), explicitHome.slice(2));
56+
const envHome = normalizeEnvPath(process.env.HOME) ?? normalizeEnvPath(process.env.USERPROFILE);
57+
return envHome ? path.resolve(explicitHome.replace(/^~(?=$|[\\/])/, envHome)) : getHomeDir();
58+
}
59+
if (explicitHome === "~") {
60+
const envHome = normalizeEnvPath(process.env.HOME) ?? normalizeEnvPath(process.env.USERPROFILE);
61+
return envHome ? path.resolve(envHome) : getHomeDir();
5262
}
5363
return path.resolve(explicitHome);
5464
}
5565

5666
/** Return a path under `~/.openclaw/qqbot` without creating it. */
5767
export function getQQBotDataPath(...subPaths: string[]): string {
58-
return path.join(resolveOpenClawHomeDir(), ".openclaw", "qqbot", ...subPaths);
68+
return path.join(getHomeDir(), ".openclaw", "qqbot", ...subPaths);
5969
}
6070

6171
/** Return a path under `~/.openclaw/qqbot`, creating it on demand. */
@@ -74,7 +84,7 @@ export function getQQBotDataDir(...subPaths: string[]): string {
7484
* downloaded images and audio can be accessed by framework media tooling.
7585
*/
7686
export function getQQBotMediaPath(...subPaths: string[]): string {
77-
return path.join(resolveOpenClawHomeDir(), ".openclaw", "media", "qqbot", ...subPaths);
87+
return path.join(resolveOpenClawMediaHomeDir(), ".openclaw", "media", "qqbot", ...subPaths);
7888
}
7989

8090
/** Return a path under `~/.openclaw/media/qqbot`, creating it on demand. */
@@ -97,7 +107,7 @@ export function getQQBotMediaDir(...subPaths: string[]): string {
97107
* the check anchored to a single, well-known directory.
98108
*/
99109
function getOpenClawMediaDir(): string {
100-
return path.join(resolveOpenClawHomeDir(), ".openclaw", "media");
110+
return path.join(resolveOpenClawMediaHomeDir(), ".openclaw", "media");
101111
}
102112

103113
// ---- Basic platform information ----

0 commit comments

Comments
 (0)