mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
* fix(paths): respect OPENCLAW_HOME for all internal path resolution (#11995) Add home-dir module (src/infra/home-dir.ts) that centralizes home directory resolution with precedence: OPENCLAW_HOME > HOME > USERPROFILE > os.homedir(). Migrate all path-sensitive callsites: config IO, agent dirs, session transcripts, pairing store, cron store, doctor, CLI profiles. Add envHomedir() helper in config/paths.ts to reduce lambda noise. Document OPENCLAW_HOME in docs/help/environment.md. * fix(paths): handle OPENCLAW_HOME '~' fallback (#12091) (thanks @sebslight) * docs: mention OPENCLAW_HOME in install and getting started (#12091) (thanks @sebslight) * fix(status): show OPENCLAW_HOME in shortened paths (#12091) (thanks @sebslight) * docs(changelog): clarify OPENCLAW_HOME and HOME precedence (#12091) (thanks @sebslight)
142 lines
4.7 KiB
TypeScript
142 lines
4.7 KiB
TypeScript
import path from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { resolveStateDir } from "../config/paths.js";
|
|
import { resolveRunWorkspaceDir } from "./workspace-run.js";
|
|
import { resolveDefaultAgentWorkspaceDir } from "./workspace.js";
|
|
|
|
describe("resolveRunWorkspaceDir", () => {
|
|
it("resolves explicit workspace values without fallback", () => {
|
|
const explicit = path.join(process.cwd(), "tmp", "workspace-run-explicit");
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: explicit,
|
|
sessionKey: "agent:main:subagent:test",
|
|
});
|
|
|
|
expect(result.usedFallback).toBe(false);
|
|
expect(result.agentId).toBe("main");
|
|
expect(result.workspaceDir).toBe(path.resolve(explicit));
|
|
});
|
|
|
|
it("falls back to configured per-agent workspace when input is missing", () => {
|
|
const defaultWorkspace = path.join(process.cwd(), "tmp", "workspace-default-main");
|
|
const researchWorkspace = path.join(process.cwd(), "tmp", "workspace-research");
|
|
const cfg = {
|
|
agents: {
|
|
defaults: { workspace: defaultWorkspace },
|
|
list: [{ id: "research", workspace: researchWorkspace }],
|
|
},
|
|
} satisfies OpenClawConfig;
|
|
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: undefined,
|
|
sessionKey: "agent:research:subagent:test",
|
|
config: cfg,
|
|
});
|
|
|
|
expect(result.usedFallback).toBe(true);
|
|
expect(result.fallbackReason).toBe("missing");
|
|
expect(result.agentId).toBe("research");
|
|
expect(result.workspaceDir).toBe(path.resolve(researchWorkspace));
|
|
});
|
|
|
|
it("falls back to default workspace for blank strings", () => {
|
|
const defaultWorkspace = path.join(process.cwd(), "tmp", "workspace-default-main");
|
|
const cfg = {
|
|
agents: {
|
|
defaults: { workspace: defaultWorkspace },
|
|
},
|
|
} satisfies OpenClawConfig;
|
|
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: " ",
|
|
sessionKey: "agent:main:subagent:test",
|
|
config: cfg,
|
|
});
|
|
|
|
expect(result.usedFallback).toBe(true);
|
|
expect(result.fallbackReason).toBe("blank");
|
|
expect(result.agentId).toBe("main");
|
|
expect(result.workspaceDir).toBe(path.resolve(defaultWorkspace));
|
|
});
|
|
|
|
it("falls back to built-in main workspace when config is unavailable", () => {
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: null,
|
|
sessionKey: "agent:main:subagent:test",
|
|
config: undefined,
|
|
});
|
|
|
|
expect(result.usedFallback).toBe(true);
|
|
expect(result.fallbackReason).toBe("missing");
|
|
expect(result.agentId).toBe("main");
|
|
expect(result.workspaceDir).toBe(path.resolve(resolveDefaultAgentWorkspaceDir(process.env)));
|
|
});
|
|
|
|
it("throws for malformed agent session keys", () => {
|
|
expect(() =>
|
|
resolveRunWorkspaceDir({
|
|
workspaceDir: undefined,
|
|
sessionKey: "agent::broken",
|
|
config: undefined,
|
|
}),
|
|
).toThrow("Malformed agent session key");
|
|
});
|
|
|
|
it("uses explicit agent id for per-agent fallback when config is unavailable", () => {
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: undefined,
|
|
sessionKey: "definitely-not-a-valid-session-key",
|
|
agentId: "research",
|
|
config: undefined,
|
|
});
|
|
|
|
expect(result.agentId).toBe("research");
|
|
expect(result.agentIdSource).toBe("explicit");
|
|
expect(result.workspaceDir).toBe(
|
|
path.resolve(resolveStateDir(process.env), "workspace-research"),
|
|
);
|
|
});
|
|
|
|
it("throws for malformed agent session keys even when config has a default agent", () => {
|
|
const mainWorkspace = path.join(process.cwd(), "tmp", "workspace-main-default");
|
|
const researchWorkspace = path.join(process.cwd(), "tmp", "workspace-research-default");
|
|
const cfg = {
|
|
agents: {
|
|
defaults: { workspace: mainWorkspace },
|
|
list: [
|
|
{ id: "main", workspace: mainWorkspace },
|
|
{ id: "research", workspace: researchWorkspace, default: true },
|
|
],
|
|
},
|
|
} satisfies OpenClawConfig;
|
|
|
|
expect(() =>
|
|
resolveRunWorkspaceDir({
|
|
workspaceDir: undefined,
|
|
sessionKey: "agent::broken",
|
|
config: cfg,
|
|
}),
|
|
).toThrow("Malformed agent session key");
|
|
});
|
|
|
|
it("treats non-agent legacy keys as default, not malformed", () => {
|
|
const fallbackWorkspace = path.join(process.cwd(), "tmp", "workspace-default-legacy");
|
|
const cfg = {
|
|
agents: {
|
|
defaults: { workspace: fallbackWorkspace },
|
|
},
|
|
} satisfies OpenClawConfig;
|
|
|
|
const result = resolveRunWorkspaceDir({
|
|
workspaceDir: undefined,
|
|
sessionKey: "custom-main-key",
|
|
config: cfg,
|
|
});
|
|
|
|
expect(result.agentId).toBe("main");
|
|
expect(result.agentIdSource).toBe("default");
|
|
expect(result.workspaceDir).toBe(path.resolve(fallbackWorkspace));
|
|
});
|
|
});
|