import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it } from "vitest"; import { captureEnv } from "../../test-utils/env.js"; import { ensureDevGatewayConfig } from "./dev.js"; const ENV_KEYS = [ "HOME", "OPENSKYNET_HOME", "OPENSKYNET_PROFILE", "OPENSKYNET_STATE_DIR", "OPENSKYNET_CONFIG_PATH", "CLAWDBOT_STATE_DIR", "CLAWDBOT_CONFIG_PATH", ] as const; describe("ensureDevGatewayConfig", () => { const envSnapshot = captureEnv([...ENV_KEYS]); afterEach(() => { envSnapshot.restore(); }); it("seeds dev main auth-profiles from the default profile store", async () => { const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-dev-gateway-")); try { const homeDir = path.join(tempRoot, "home"); const mainAuthPath = path.join( homeDir, ".openskynet", "agents", "main", "agent", "auth-profiles.json", ); const devStateDir = path.join(homeDir, ".openskynet-dev"); const devAuthPath = path.join(devStateDir, "agents", "main", "agent", "auth-profiles.json"); const devModelsPath = path.join(devStateDir, "agents", "main", "agent", "models.json"); await fs.mkdir(path.dirname(mainAuthPath), { recursive: true }); await fs.writeFile( mainAuthPath, `${JSON.stringify( { version: 1, profiles: { "anthropic:default": { type: "api_key", provider: "anthropic", key: "main-anthropic-key", }, }, }, null, 2, )}\n`, "utf8", ); await fs.mkdir(path.dirname(devModelsPath), { recursive: true }); await fs.writeFile( devModelsPath, `${JSON.stringify( { providers: { ollama: { models: [{ id: "gpt-oss-safeguard:20b" }], }, }, }, null, 2, )}\n`, "utf8", ); process.env.HOME = homeDir; process.env.OPENSKYNET_PROFILE = "dev"; process.env.OPENSKYNET_STATE_DIR = devStateDir; process.env.OPENSKYNET_CONFIG_PATH = path.join(devStateDir, "openclaw.json"); delete process.env.OPENSKYNET_HOME; delete process.env.CLAWDBOT_STATE_DIR; delete process.env.CLAWDBOT_CONFIG_PATH; await ensureDevGatewayConfig({}); const copied = JSON.parse(await fs.readFile(devAuthPath, "utf8")) as { profiles?: Record; }; const config = JSON.parse( await fs.readFile(path.join(devStateDir, "openclaw.json"), "utf8"), ) as { agents?: { defaults?: { model?: { primary?: string } } } }; expect(copied.profiles?.["anthropic:default"]?.key).toBe("main-anthropic-key"); expect(config.agents?.defaults?.model?.primary).toBe("ollama/gpt-oss-safeguard:20b"); } finally { await fs.rm(tempRoot, { recursive: true, force: true }); } }); it("does not overwrite an existing dev main auth store", async () => { const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-dev-gateway-")); try { const homeDir = path.join(tempRoot, "home"); const mainAuthPath = path.join( homeDir, ".openskynet", "agents", "main", "agent", "auth-profiles.json", ); const devStateDir = path.join(homeDir, ".openskynet-dev"); const devAuthPath = path.join(devStateDir, "agents", "main", "agent", "auth-profiles.json"); const devModelsPath = path.join(devStateDir, "agents", "main", "agent", "models.json"); await fs.mkdir(path.dirname(mainAuthPath), { recursive: true }); await fs.mkdir(path.dirname(devAuthPath), { recursive: true }); await fs.writeFile( mainAuthPath, `${JSON.stringify( { version: 1, profiles: { "anthropic:default": { type: "api_key", provider: "anthropic", key: "main-anthropic-key", }, }, }, null, 2, )}\n`, "utf8", ); await fs.writeFile( devAuthPath, `${JSON.stringify( { version: 1, profiles: { "anthropic:default": { type: "api_key", provider: "anthropic", key: "dev-anthropic-key", }, }, }, null, 2, )}\n`, "utf8", ); await fs.writeFile( devModelsPath, `${JSON.stringify( { providers: { ollama: { models: [{ id: "gpt-oss-safeguard:20b" }], }, }, }, null, 2, )}\n`, "utf8", ); process.env.HOME = homeDir; process.env.OPENSKYNET_PROFILE = "dev"; process.env.OPENSKYNET_STATE_DIR = devStateDir; process.env.OPENSKYNET_CONFIG_PATH = path.join(devStateDir, "openclaw.json"); delete process.env.OPENSKYNET_HOME; delete process.env.CLAWDBOT_STATE_DIR; delete process.env.CLAWDBOT_CONFIG_PATH; await ensureDevGatewayConfig({}); const copied = JSON.parse(await fs.readFile(devAuthPath, "utf8")) as { profiles?: Record; }; const config = JSON.parse( await fs.readFile(path.join(devStateDir, "openclaw.json"), "utf8"), ) as { agents?: { defaults?: { model?: { primary?: string } } } }; expect(copied.profiles?.["anthropic:default"]?.key).toBe("dev-anthropic-key"); expect(config.agents?.defaults?.model?.primary).toBe("ollama/gpt-oss-safeguard:20b"); } finally { await fs.rm(tempRoot, { recursive: true, force: true }); } }); });