diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 8f0f583ea3d6..2fbfc986563f 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -175,8 +175,8 @@ export namespace Config { } // Inline config content overrides all non-managed config sources. - if (Flag.OPENCODE_CONFIG_CONTENT) { - result = mergeConfigConcatArrays(result, JSON.parse(Flag.OPENCODE_CONFIG_CONTENT)) + if (process.env.OPENCODE_CONFIG_CONTENT) { + result = mergeConfigConcatArrays(result, await load(process.env.OPENCODE_CONFIG_CONTENT, path.join(Instance.directory, ""))) log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT") } diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts index 91b87f6498c4..836a3f5d152d 100644 --- a/packages/opencode/test/config/config.test.ts +++ b/packages/opencode/test/config/config.test.ts @@ -1800,3 +1800,66 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => { } }) }) + +describe("OPENCODE_CONFIG_CONTENT token substitution", () => { + test("substitutes {env:} tokens in OPENCODE_CONFIG_CONTENT", async () => { + const originalEnv = process.env["OPENCODE_CONFIG_CONTENT"] + const originalTestVar = process.env["TEST_CONFIG_VAR"] + process.env["TEST_CONFIG_VAR"] = "test_api_key_12345" + process.env["OPENCODE_CONFIG_CONTENT"] = JSON.stringify({ + $schema: "https://opencode.ai/config.json", + theme: "{env:TEST_CONFIG_VAR}", + }) + + try { + await using tmp = await tmpdir() + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.theme).toBe("test_api_key_12345") + }, + }) + } finally { + if (originalEnv !== undefined) { + process.env["OPENCODE_CONFIG_CONTENT"] = originalEnv + } else { + delete process.env["OPENCODE_CONFIG_CONTENT"] + } + if (originalTestVar !== undefined) { + process.env["TEST_CONFIG_VAR"] = originalTestVar + } else { + delete process.env["TEST_CONFIG_VAR"] + } + } + }) + + test("substitutes {file:} tokens in OPENCODE_CONFIG_CONTENT", async () => { + const originalEnv = process.env["OPENCODE_CONFIG_CONTENT"] + + try { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, "api_key.txt"), "secret_key_from_file") + process.env["OPENCODE_CONFIG_CONTENT"] = JSON.stringify({ + $schema: "https://opencode.ai/config.json", + theme: "{file:./api_key.txt}", + }) + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const config = await Config.get() + expect(config.theme).toBe("secret_key_from_file") + }, + }) + } finally { + if (originalEnv !== undefined) { + process.env["OPENCODE_CONFIG_CONTENT"] = originalEnv + } else { + delete process.env["OPENCODE_CONFIG_CONTENT"] + } + } + }) +})