Skip to content

Commit 48dd1f6

Browse files
authored
Merge pull request #12 from MohMaya/01-01-mcp-not-found
2 parents 02b44f2 + 0b81963 commit 48dd1f6

3 files changed

Lines changed: 87 additions & 6 deletions

File tree

src/cli.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { mkdirSync, writeFileSync, readFileSync, existsSync } from "node:fs";
33
import { join } from "node:path";
44
import { homedir } from "node:os";
55
import * as readline from "node:readline";
6+
import { stripJsoncComments } from "./services/jsonc.js";
67

78
const OPENCODE_CONFIG_DIR = join(homedir(), ".config", "opencode");
89
const OPENCODE_COMMAND_DIR = join(OPENCODE_CONFIG_DIR, "command");
@@ -200,8 +201,7 @@ function addPluginToConfig(configPath: string): boolean {
200201
return true;
201202
}
202203

203-
// Parse JSONC (strip comments for parsing)
204-
const jsonContent = content.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
204+
const jsonContent = stripJsoncComments(content);
205205
let config: Record<string, unknown>;
206206

207207
try {

src/config.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { existsSync, readFileSync } from "node:fs";
22
import { join } from "node:path";
33
import { homedir } from "node:os";
4+
import { stripJsoncComments } from "./services/jsonc.js";
45

56
const CONFIG_DIR = join(homedir(), ".config", "opencode");
67
const CONFIG_FILES = [
@@ -34,10 +35,7 @@ function loadConfig(): SupermemoryConfig {
3435
if (existsSync(path)) {
3536
try {
3637
const content = readFileSync(path, "utf-8");
37-
// Strip comments for JSONC
38-
const json = content
39-
.replace(/\/\/.*$/gm, "")
40-
.replace(/\/\*[\s\S]*?\*\//g, "");
38+
const json = stripJsoncComments(content);
4139
return JSON.parse(json) as SupermemoryConfig;
4240
} catch {
4341
// Invalid config, use defaults

src/services/jsonc.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Strips comments from JSONC content while respecting string boundaries.
3+
* Handles // and /* comments, URLs in strings, and escaped quotes.
4+
*/
5+
export function stripJsoncComments(content: string): string {
6+
let result = "";
7+
let i = 0;
8+
let inString = false;
9+
let inSingleLineComment = false;
10+
let inMultiLineComment = false;
11+
12+
while (i < content.length) {
13+
const char = content[i];
14+
const nextChar = content[i + 1];
15+
16+
if (!inSingleLineComment && !inMultiLineComment) {
17+
if (char === '"') {
18+
// Count consecutive backslashes before this quote
19+
let backslashCount = 0;
20+
let j = i - 1;
21+
while (j >= 0 && content[j] === "\\") {
22+
backslashCount++;
23+
j--;
24+
}
25+
// Quote is escaped only if preceded by ODD number of backslashes
26+
// e.g., \" = escaped, \\" = not escaped (escaped backslash + quote)
27+
if (backslashCount % 2 === 0) {
28+
inString = !inString;
29+
}
30+
result += char;
31+
i++;
32+
continue;
33+
}
34+
}
35+
36+
if (inString) {
37+
result += char;
38+
i++;
39+
continue;
40+
}
41+
42+
if (!inSingleLineComment && !inMultiLineComment) {
43+
if (char === "/" && nextChar === "/") {
44+
inSingleLineComment = true;
45+
i += 2;
46+
continue;
47+
}
48+
49+
if (char === "/" && nextChar === "*") {
50+
inMultiLineComment = true;
51+
i += 2;
52+
continue;
53+
}
54+
}
55+
56+
if (inSingleLineComment) {
57+
if (char === "\n") {
58+
inSingleLineComment = false;
59+
result += char;
60+
}
61+
i++;
62+
continue;
63+
}
64+
65+
if (inMultiLineComment) {
66+
if (char === "*" && nextChar === "/") {
67+
inMultiLineComment = false;
68+
i += 2;
69+
continue;
70+
}
71+
if (char === "\n") {
72+
result += char;
73+
}
74+
i++;
75+
continue;
76+
}
77+
78+
result += char;
79+
i++;
80+
}
81+
82+
return result;
83+
}

0 commit comments

Comments
 (0)