Skip to content

Commit 9d2d433

Browse files
Opencode jsonc resolution (#226)
Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Aiden Bai <aidenybai@users.noreply.github.com>
1 parent 6bd2c60 commit 9d2d433

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

packages/cli/src/utils/install-mcp.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,16 @@ const getZedConfigPath = (): string => {
4848
return path.join(os.homedir(), ".config", "zed", "settings.json");
4949
};
5050

51+
export const getOpenCodeConfigPath = (): string => {
52+
const configDir = path.join(getXdgConfigHome(), "opencode");
53+
const jsoncPath = path.join(configDir, "opencode.jsonc");
54+
const jsonPath = path.join(configDir, "opencode.json");
55+
56+
if (fs.existsSync(jsoncPath)) return jsoncPath;
57+
if (fs.existsSync(jsonPath)) return jsonPath;
58+
return jsoncPath;
59+
};
60+
5161
const getClients = (): ClientDefinition[] => {
5262
const homeDir = os.homedir();
5363
const baseDir = getBaseDir();
@@ -84,7 +94,7 @@ const getClients = (): ClientDefinition[] => {
8494
},
8595
{
8696
name: "OpenCode",
87-
configPath: path.join(getXdgConfigHome(), "opencode", "opencode.json"),
97+
configPath: getOpenCodeConfigPath(),
8898
configKey: "mcp",
8999
format: "json",
90100
serverConfig: {

packages/cli/test/install-mcp.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
installJsonClient,
99
installTomlClient,
1010
getMcpClientNames,
11+
getOpenCodeConfigPath,
1112
} from "../src/utils/install-mcp.js";
1213

1314
let tempDir: string;
@@ -185,6 +186,50 @@ describe("upsertIntoJsonc", () => {
185186
});
186187
});
187188

189+
describe("getOpenCodeConfigPath", () => {
190+
let originalXdgConfigHome: string | undefined;
191+
192+
beforeEach(() => {
193+
originalXdgConfigHome = process.env.XDG_CONFIG_HOME;
194+
process.env.XDG_CONFIG_HOME = tempDir;
195+
});
196+
197+
afterEach(() => {
198+
if (originalXdgConfigHome === undefined) {
199+
delete process.env.XDG_CONFIG_HOME;
200+
} else {
201+
process.env.XDG_CONFIG_HOME = originalXdgConfigHome;
202+
}
203+
});
204+
205+
it("should prefer opencode.jsonc when both files exist", () => {
206+
const opencodeDir = path.join(tempDir, "opencode");
207+
fs.mkdirSync(opencodeDir, { recursive: true });
208+
fs.writeFileSync(path.join(opencodeDir, "opencode.json"), "{}");
209+
fs.writeFileSync(path.join(opencodeDir, "opencode.jsonc"), "{}");
210+
211+
const result = getOpenCodeConfigPath();
212+
213+
expect(result).toBe(path.join(opencodeDir, "opencode.jsonc"));
214+
});
215+
216+
it("should use opencode.json when only it exists", () => {
217+
const opencodeDir = path.join(tempDir, "opencode");
218+
fs.mkdirSync(opencodeDir, { recursive: true });
219+
fs.writeFileSync(path.join(opencodeDir, "opencode.json"), "{}");
220+
221+
const result = getOpenCodeConfigPath();
222+
223+
expect(result).toBe(path.join(opencodeDir, "opencode.json"));
224+
});
225+
226+
it("should default to opencode.jsonc when neither file exists", () => {
227+
const result = getOpenCodeConfigPath();
228+
229+
expect(result).toBe(path.join(tempDir, "opencode", "opencode.jsonc"));
230+
});
231+
});
232+
188233
describe("installTomlClient", () => {
189234
it("should create a new TOML file when none exists", () => {
190235
const client = makeTomlClient();

0 commit comments

Comments
 (0)