From a6c05e182303c3aaa9d8eab44572cbc595a4e223 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Thu, 28 May 2026 14:42:28 +0900 Subject: [PATCH] fix(config): scan active opencode profile plugins --- src/shared/load-opencode-plugins.test.ts | 42 ++++++++++++++++++++++++ src/shared/load-opencode-plugins.ts | 9 ++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/shared/load-opencode-plugins.test.ts b/src/shared/load-opencode-plugins.test.ts index 9723c1cd3..97879570d 100644 --- a/src/shared/load-opencode-plugins.test.ts +++ b/src/shared/load-opencode-plugins.test.ts @@ -19,7 +19,12 @@ async function importFreshLoadOpencodePluginsModule(): Promise { + let originalOpencodeConfigDir: string | undefined + beforeEach(() => { + originalOpencodeConfigDir = process.env.OPENCODE_CONFIG_DIR + delete process.env.OPENCODE_CONFIG_DIR + existsSyncMock.mockReset() existsSyncMock.mockImplementation((_path: string) => true) readFileSyncMock.mockReset() @@ -35,6 +40,11 @@ describe("loadOpencodePlugins", () => { }) afterEach(() => { + if (originalOpencodeConfigDir === undefined) { + delete process.env.OPENCODE_CONFIG_DIR + } else { + process.env.OPENCODE_CONFIG_DIR = originalOpencodeConfigDir + } mock.restore() }) @@ -86,4 +96,36 @@ describe("loadOpencodePlugins", () => { }) }) }) + + describe("#given OPENCODE_CONFIG_DIR points at an active profile", () => { + describe("#when loading plugins for the project", () => { + it("#then includes plugin entries from the profile config directory", async () => { + // given + process.env.OPENCODE_CONFIG_DIR = "/tmp/opencode-profile" + existsSyncMock.mockImplementation((filePath: string) => ( + filePath === "/project/.opencode/opencode.json" + || filePath === "/tmp/opencode-profile/opencode.json" + )) + readFileSyncMock.mockImplementation((filePath: string, _encoding?: string) => { + if (filePath === "/project/.opencode/opencode.json") { + return JSON.stringify({ plugin: ["file:///repo/omo/src/index.ts"] }) + } + if (filePath === "/tmp/opencode-profile/opencode.json") { + return JSON.stringify({ plugin: ["oh-my-openagent@latest"] }) + } + return JSON.stringify({}) + }) + const { loadOpencodePlugins } = await importFreshLoadOpencodePluginsModule() + + // when + const result = loadOpencodePlugins("/project") + + // then + expect(result).toEqual([ + "file:///repo/omo/src/index.ts", + "oh-my-openagent@latest", + ]) + }) + }) + }) }) diff --git a/src/shared/load-opencode-plugins.ts b/src/shared/load-opencode-plugins.ts index 1d8664aa7..ff7352332 100644 --- a/src/shared/load-opencode-plugins.ts +++ b/src/shared/load-opencode-plugins.ts @@ -23,6 +23,13 @@ function getConfigPaths(directory: string): string[] { path.join(crossPlatformDir, "opencode", "opencode.jsonc"), ] + const customConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim() + if (customConfigDir) { + const resolvedCustomConfigDir = path.resolve(customConfigDir) + paths.push(path.join(resolvedCustomConfigDir, "opencode.json")) + paths.push(path.join(resolvedCustomConfigDir, "opencode.jsonc")) + } + if (process.platform === "win32") { const appdataDir = getWindowsAppdataDir() if (appdataDir) { @@ -31,7 +38,7 @@ function getConfigPaths(directory: string): string[] { } } - return paths + return Array.from(new Set(paths)) } export function loadOpencodePlugins(directory: string): string[] {