summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/config/config.ts5
-rw-r--r--packages/opencode/test/config/config.test.ts38
2 files changed, 42 insertions, 1 deletions
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index 1574c644d..5a2e086bf 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -1115,6 +1115,7 @@ export namespace Config {
}
async function load(text: string, configFilepath: string) {
+ const original = text
text = text.replace(/\{env:([^}]+)\}/g, (_, varName) => {
return process.env[varName] || ""
})
@@ -1184,7 +1185,9 @@ export namespace Config {
if (parsed.success) {
if (!parsed.data.$schema) {
parsed.data.$schema = "https://opencode.ai/config.json"
- await Bun.write(configFilepath, JSON.stringify(parsed.data, null, 2)).catch(() => {})
+ // Write the $schema to the original text to preserve variables like {env:VAR}
+ const updated = original.replace(/^\s*\{/, '{\n "$schema": "https://opencode.ai/config.json",')
+ await Bun.write(configFilepath, updated).catch(() => {})
}
const data = parsed.data
if (data.plugin) {
diff --git a/packages/opencode/test/config/config.test.ts b/packages/opencode/test/config/config.test.ts
index 86cadca5d..0463d29d7 100644
--- a/packages/opencode/test/config/config.test.ts
+++ b/packages/opencode/test/config/config.test.ts
@@ -127,6 +127,44 @@ test("handles environment variable substitution", async () => {
}
})
+test("preserves env variables when adding $schema to config", async () => {
+ const originalEnv = process.env["PRESERVE_VAR"]
+ process.env["PRESERVE_VAR"] = "secret_value"
+
+ try {
+ await using tmp = await tmpdir({
+ init: async (dir) => {
+ // Config without $schema - should trigger auto-add
+ await Bun.write(
+ path.join(dir, "opencode.json"),
+ JSON.stringify({
+ theme: "{env:PRESERVE_VAR}",
+ }),
+ )
+ },
+ })
+ await Instance.provide({
+ directory: tmp.path,
+ fn: async () => {
+ const config = await Config.get()
+ expect(config.theme).toBe("secret_value")
+
+ // Read the file to verify the env variable was preserved
+ const content = await Bun.file(path.join(tmp.path, "opencode.json")).text()
+ expect(content).toContain("{env:PRESERVE_VAR}")
+ expect(content).not.toContain("secret_value")
+ expect(content).toContain("$schema")
+ },
+ })
+ } finally {
+ if (originalEnv !== undefined) {
+ process.env["PRESERVE_VAR"] = originalEnv
+ } else {
+ delete process.env["PRESERVE_VAR"]
+ }
+ }
+})
+
test("handles file inclusion substitution", async () => {
await using tmp = await tmpdir({
init: async (dir) => {