mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 12:11:20 +00:00
fix(agents): respect overridden home for personal skills
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
||||
import { withEnv } from "../test-utils/env.js";
|
||||
import { withPathResolutionEnv } from "../test-utils/env.js";
|
||||
import { createFixtureSuite } from "../test-utils/fixture-suite.js";
|
||||
import { writeSkill } from "./skills.e2e-test-helpers.js";
|
||||
import { buildWorkspaceSkillSnapshot, buildWorkspaceSkillsPrompt } from "./skills.js";
|
||||
@@ -40,7 +40,7 @@ afterAll(async () => {
|
||||
});
|
||||
|
||||
function withWorkspaceHome<T>(workspaceDir: string, cb: () => T): T {
|
||||
return withEnv({ HOME: workspaceDir, PATH: "" }, cb);
|
||||
return withPathResolutionEnv(workspaceDir, { PATH: "" }, () => cb());
|
||||
}
|
||||
|
||||
function buildSnapshot(
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { withPathResolutionEnv } from "../test-utils/env.js";
|
||||
import { writeSkill } from "./skills.e2e-test-helpers.js";
|
||||
import { loadWorkspaceSkillEntries } from "./skills.js";
|
||||
import { readSkillFrontmatterSafe } from "./skills/local-loader.js";
|
||||
@@ -15,6 +16,10 @@ async function createTempWorkspaceDir() {
|
||||
return workspaceDir;
|
||||
}
|
||||
|
||||
function withWorkspaceHome<T>(workspaceDir: string, cb: () => T): T {
|
||||
return withPathResolutionEnv(workspaceDir, { PATH: "" }, () => cb());
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all(
|
||||
tempDirs.splice(0, tempDirs.length).map((dir) => fs.rm(dir, { recursive: true, force: true })),
|
||||
@@ -59,10 +64,12 @@ describe("loadWorkspaceSkillEntries", () => {
|
||||
const managedDir = path.join(workspaceDir, ".managed");
|
||||
await fs.mkdir(managedDir, { recursive: true });
|
||||
|
||||
const entries = loadWorkspaceSkillEntries(workspaceDir, {
|
||||
managedSkillsDir: managedDir,
|
||||
bundledSkillsDir: path.join(workspaceDir, ".bundled"),
|
||||
});
|
||||
const entries = withWorkspaceHome(workspaceDir, () =>
|
||||
loadWorkspaceSkillEntries(workspaceDir, {
|
||||
managedSkillsDir: managedDir,
|
||||
bundledSkillsDir: path.join(workspaceDir, ".bundled"),
|
||||
}),
|
||||
);
|
||||
|
||||
expect(entries).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
setRuntimeConfigSnapshot,
|
||||
type OpenClawConfig,
|
||||
} from "../config/config.js";
|
||||
import { withPathResolutionEnv } from "../test-utils/env.js";
|
||||
import { createFixtureSuite } from "../test-utils/fixture-suite.js";
|
||||
import { createTempHomeEnv, type TempHomeEnv } from "../test-utils/temp-home.js";
|
||||
import { writeSkill } from "./skills.e2e-test-helpers.js";
|
||||
@@ -30,6 +31,10 @@ const resolveTestSkillDirs = (workspaceDir: string) => ({
|
||||
const makeWorkspace = async () => await fixtureSuite.createCaseDir("workspace");
|
||||
const apiKeyField = ["api", "Key"].join("");
|
||||
|
||||
function withWorkspaceHome<T>(workspaceDir: string, cb: () => T): T {
|
||||
return withPathResolutionEnv(workspaceDir, { PATH: "" }, () => cb());
|
||||
}
|
||||
|
||||
const withClearedEnv = <T>(
|
||||
keys: string[],
|
||||
run: (original: Record<string, string | undefined>) => T,
|
||||
@@ -109,10 +114,12 @@ describe("buildWorkspaceSkillCommandSpecs", () => {
|
||||
frontmatterExtra: "user-invocable: false",
|
||||
});
|
||||
|
||||
const commands = buildWorkspaceSkillCommandSpecs(workspaceDir, {
|
||||
...resolveTestSkillDirs(workspaceDir),
|
||||
reservedNames: new Set(["help"]),
|
||||
});
|
||||
const commands = withWorkspaceHome(workspaceDir, () =>
|
||||
buildWorkspaceSkillCommandSpecs(workspaceDir, {
|
||||
...resolveTestSkillDirs(workspaceDir),
|
||||
reservedNames: new Set(["help"]),
|
||||
}),
|
||||
);
|
||||
|
||||
const names = commands.map((entry) => entry.name).toSorted();
|
||||
expect(names).toEqual(["hello_world", "hello_world_2", "help_2"]);
|
||||
@@ -247,7 +254,9 @@ describe("buildWorkspaceSkillsPrompt", () => {
|
||||
it("returns empty prompt when skills dirs are missing", async () => {
|
||||
const workspaceDir = await makeWorkspace();
|
||||
|
||||
const prompt = buildWorkspaceSkillsPrompt(workspaceDir, resolveTestSkillDirs(workspaceDir));
|
||||
const prompt = withWorkspaceHome(workspaceDir, () =>
|
||||
buildWorkspaceSkillsPrompt(workspaceDir, resolveTestSkillDirs(workspaceDir)),
|
||||
);
|
||||
|
||||
expect(prompt).toBe("");
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { isPathInside } from "../../infra/path-guards.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { normalizeOptionalString } from "../../shared/string-coerce.js";
|
||||
import { CONFIG_DIR, resolveUserPath } from "../../utils.js";
|
||||
import { CONFIG_DIR, resolveHomeDir, resolveUserPath } from "../../utils.js";
|
||||
import { resolveSandboxPath } from "../sandbox-paths.js";
|
||||
import { resolveEffectiveAgentSkillFilter } from "./agent-filter.js";
|
||||
import { resolveBundledSkillsDir } from "./bundled-dir.js";
|
||||
@@ -37,7 +37,7 @@ const skillsLogger = createSubsystemLogger("skills");
|
||||
* Saves ~5–6 tokens per skill path × N skills ≈ 400–600 tokens total.
|
||||
*/
|
||||
function compactSkillPaths(skills: Skill[]): Skill[] {
|
||||
const home = os.homedir();
|
||||
const home = resolveHomeDir() ?? os.homedir();
|
||||
if (!home) return skills;
|
||||
const prefix = home.endsWith(path.sep) ? home : home + path.sep;
|
||||
return skills.map((s) => ({
|
||||
@@ -435,7 +435,11 @@ function loadSkillEntries(
|
||||
dir: managedSkillsDir,
|
||||
source: "openclaw-managed",
|
||||
});
|
||||
const personalAgentsSkillsDir = path.resolve(os.homedir(), ".agents", "skills");
|
||||
const personalAgentsSkillsDir = path.resolve(
|
||||
resolveHomeDir() ?? os.homedir(),
|
||||
".agents",
|
||||
"skills",
|
||||
);
|
||||
const personalAgentsSkills = loadSkills({
|
||||
dir: personalAgentsSkillsDir,
|
||||
source: "agents-skills-personal",
|
||||
|
||||
Reference in New Issue
Block a user