diff --git a/src/agents/skills.agents-skills-directory.test.ts b/src/agents/skills.agents-skills-directory.test.ts index 260e4a2a342..98be711ba21 100644 --- a/src/agents/skills.agents-skills-directory.test.ts +++ b/src/agents/skills.agents-skills-directory.test.ts @@ -1,9 +1,14 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { buildWorkspaceSkillsPrompt } from "./skills.js"; import { writeSkill } from "./skills.test-helpers.js"; +import { + restoreMockSkillsHomeEnv, + setMockSkillsHomeEnv, + type SkillsHomeEnvSnapshot, +} from "./skills/home-env.test-support.js"; const tempDirs: string[] = []; @@ -31,43 +36,21 @@ async function createWorkspaceSkillDirs() { describe("buildWorkspaceSkillsPrompt — .agents/skills/ directories", () => { let fakeHome: string; - let previousHome: string | undefined; - let previousOpenClawHome: string | undefined; - let previousUserProfile: string | undefined; + let envSnapshot: SkillsHomeEnvSnapshot; beforeEach(async () => { fakeHome = await createTempDir("openclaw-home-"); - previousHome = process.env.HOME; - previousOpenClawHome = process.env.OPENCLAW_HOME; - previousUserProfile = process.env.USERPROFILE; - process.env.HOME = fakeHome; - delete process.env.OPENCLAW_HOME; - delete process.env.USERPROFILE; - vi.spyOn(os, "homedir").mockReturnValue(fakeHome); + envSnapshot = setMockSkillsHomeEnv(fakeHome); }); afterEach(async () => { - vi.restoreAllMocks(); - if (previousHome === undefined) { - delete process.env.HOME; - } else { - process.env.HOME = previousHome; - } - if (previousOpenClawHome === undefined) { - delete process.env.OPENCLAW_HOME; - } else { - process.env.OPENCLAW_HOME = previousOpenClawHome; - } - if (previousUserProfile === undefined) { - delete process.env.USERPROFILE; - } else { - process.env.USERPROFILE = previousUserProfile; - } - await Promise.all( - tempDirs - .splice(0, tempDirs.length) - .map((dir) => fs.rm(dir, { recursive: true, force: true })), - ); + await restoreMockSkillsHomeEnv(envSnapshot, async () => { + await Promise.all( + tempDirs + .splice(0, tempDirs.length) + .map((dir) => fs.rm(dir, { recursive: true, force: true })), + ); + }); }); it("loads project .agents/skills/ above managed and below workspace", async () => { diff --git a/src/agents/skills/compact-format.test.ts b/src/agents/skills/compact-format.test.ts index b1a6ab87ec3..ff1e1bd7d72 100644 --- a/src/agents/skills/compact-format.test.ts +++ b/src/agents/skills/compact-format.test.ts @@ -1,8 +1,13 @@ import os from "node:os"; import { formatSkillsForPrompt as upstreamFormatSkillsForPrompt } from "@mariozechner/pi-coding-agent"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; import type { OpenClawConfig } from "../../config/config.js"; import { createCanonicalFixtureSkill } from "../skills.test-helpers.js"; +import { + restoreMockSkillsHomeEnv, + setMockSkillsHomeEnv, + type SkillsHomeEnvSnapshot, +} from "./home-env.test-support.js"; import { formatSkillsForPrompt, type Skill } from "./skill-contract.js"; import type { SkillEntry } from "./types.js"; import { @@ -100,38 +105,13 @@ describe("formatSkillsCompact", () => { }); describe("applySkillsPromptLimits (via buildWorkspaceSkillsPrompt)", () => { - let previousHome: string | undefined; - let previousOpenClawHome: string | undefined; - let previousUserProfile: string | undefined; + let envSnapshot: SkillsHomeEnvSnapshot; beforeEach(() => { - previousHome = process.env.HOME; - previousOpenClawHome = process.env.OPENCLAW_HOME; - previousUserProfile = process.env.USERPROFILE; - process.env.HOME = "/Users/openclaw-test-user"; - delete process.env.OPENCLAW_HOME; - delete process.env.USERPROFILE; - vi.spyOn(os, "homedir").mockReturnValue("/Users/openclaw-test-user"); + envSnapshot = setMockSkillsHomeEnv("/Users/openclaw-test-user"); }); - afterEach(() => { - vi.restoreAllMocks(); - if (previousHome === undefined) { - delete process.env.HOME; - } else { - process.env.HOME = previousHome; - } - if (previousOpenClawHome === undefined) { - delete process.env.OPENCLAW_HOME; - } else { - process.env.OPENCLAW_HOME = previousOpenClawHome; - } - if (previousUserProfile === undefined) { - delete process.env.USERPROFILE; - } else { - process.env.USERPROFILE = previousUserProfile; - } - }); + afterEach(() => restoreMockSkillsHomeEnv(envSnapshot)); it("respects explicit exposure metadata before compact formatting", () => { const hidden = makeEntry({ ...makeSkill("hidden"), disableModelInvocation: true }); diff --git a/src/agents/skills/home-env.test-support.ts b/src/agents/skills/home-env.test-support.ts new file mode 100644 index 00000000000..089fdbcda1f --- /dev/null +++ b/src/agents/skills/home-env.test-support.ts @@ -0,0 +1,44 @@ +import os from "node:os"; +import { vi } from "vitest"; + +export type SkillsHomeEnvSnapshot = { + previousHome: string | undefined; + previousOpenClawHome: string | undefined; + previousUserProfile: string | undefined; +}; + +export function setMockSkillsHomeEnv(fakeHome: string): SkillsHomeEnvSnapshot { + const snapshot: SkillsHomeEnvSnapshot = { + previousHome: process.env.HOME, + previousOpenClawHome: process.env.OPENCLAW_HOME, + previousUserProfile: process.env.USERPROFILE, + }; + process.env.HOME = fakeHome; + delete process.env.OPENCLAW_HOME; + delete process.env.USERPROFILE; + vi.spyOn(os, "homedir").mockReturnValue(fakeHome); + return snapshot; +} + +export async function restoreMockSkillsHomeEnv( + snapshot: SkillsHomeEnvSnapshot, + cleanup?: () => Promise | void, +) { + vi.restoreAllMocks(); + if (snapshot.previousHome === undefined) { + delete process.env.HOME; + } else { + process.env.HOME = snapshot.previousHome; + } + if (snapshot.previousOpenClawHome === undefined) { + delete process.env.OPENCLAW_HOME; + } else { + process.env.OPENCLAW_HOME = snapshot.previousOpenClawHome; + } + if (snapshot.previousUserProfile === undefined) { + delete process.env.USERPROFILE; + } else { + process.env.USERPROFILE = snapshot.previousUserProfile; + } + await cleanup?.(); +}