diff --git a/src/plugin-config.test.ts b/src/plugin-config.test.ts index f532108de..8c442d188 100644 --- a/src/plugin-config.test.ts +++ b/src/plugin-config.test.ts @@ -1,5 +1,8 @@ +import { mkdtempSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; import { describe, expect, it } from "bun:test"; -import { mergeConfigs } from "./plugin-config"; +import { loadPluginConfig, mergeConfigs } from "./plugin-config"; import type { OhMyOpenCodeConfig } from "./config"; describe("mergeConfigs", () => { @@ -117,3 +120,43 @@ describe("mergeConfigs", () => { }); }); }); + +describe("loadPluginConfig", () => { + it("loads the active legacy oh-my-openagent user config", () => { + // #given + const previousConfigDir = process.env.OPENCODE_CONFIG_DIR; + const configDir = mkdtempSync(join(tmpdir(), "omo-config-")); + process.env.OPENCODE_CONFIG_DIR = configDir; + writeFileSync( + join(configDir, "oh-my-openagent.json"), + JSON.stringify({ + agents: { + sisyphus: { + model: "anthropic/claude-opus-4-7", + }, + }, + categories: { + quick: { + model: "openai/gpt-5.4-mini-fast", + }, + }, + }) + ); + + try { + // #when + const result = loadPluginConfig(configDir, {}); + + // #then + expect(result.agents?.sisyphus?.model).toBe("anthropic/claude-opus-4-7"); + expect(result.categories?.quick?.model).toBe("openai/gpt-5.4-mini-fast"); + } finally { + if (previousConfigDir === undefined) { + delete process.env.OPENCODE_CONFIG_DIR; + } else { + process.env.OPENCODE_CONFIG_DIR = previousConfigDir; + } + rmSync(configDir, { recursive: true, force: true }); + } + }); +}); diff --git a/src/plugin-config.ts b/src/plugin-config.ts index bc1e5dc7e..33ba0b34e 100644 --- a/src/plugin-config.ts +++ b/src/plugin-config.ts @@ -11,6 +11,20 @@ import { migrateConfigFile, } from "./shared"; +const CONFIG_BASENAMES = ["oh-my-opencode", "oh-my-openagent"] as const; + +function resolvePluginConfigPath(directory: string): string { + for (const basename of CONFIG_BASENAMES) { + const basePath = path.join(directory, basename); + const detected = detectConfigFile(basePath); + if (detected.format !== "none") { + return detected.path; + } + } + + return path.join(directory, "oh-my-opencode.json"); +} + export function loadConfigFromPath( configPath: string, ctx: unknown @@ -94,28 +108,16 @@ export function loadPluginConfig( directory: string, ctx: unknown ): OhMyOpenCodeConfig { - // User-level config path - prefer .jsonc over .json const configDir = getOpenCodeConfigDir({ binary: "opencode" }); - const userBasePath = path.join(configDir, "oh-my-opencode"); - const userDetected = detectConfigFile(userBasePath); - const userConfigPath = - userDetected.format !== "none" - ? userDetected.path - : userBasePath + ".json"; + const userConfigPath = resolvePluginConfigPath(configDir); - // Project-level config path - prefer .jsonc over .json - const projectBasePath = path.join(directory, ".opencode", "oh-my-opencode"); - const projectDetected = detectConfigFile(projectBasePath); - const projectConfigPath = - projectDetected.format !== "none" - ? projectDetected.path - : projectBasePath + ".json"; + const projectConfigPath = resolvePluginConfigPath( + path.join(directory, ".opencode") + ); - // Load user config first (base) let config: OhMyOpenCodeConfig = loadConfigFromPath(userConfigPath, ctx) ?? {}; - // Override with project config const projectConfig = loadConfigFromPath(projectConfigPath, ctx); if (projectConfig) { config = mergeConfigs(config, projectConfig);