@takara-ai/miru-code 1.2.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/installer/config.ts +100 -12
package/package.json
CHANGED
package/src/installer/config.ts
CHANGED
|
@@ -260,26 +260,114 @@ function removeJsonMemberText(text: string, sectionKey: string, memberKey: strin
|
|
|
260
260
|
return `${text.slice(0, removeStart)}${text.slice(removeEnd)}`;
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
/** True only when // or /* appear outside of strings (URLs like https:// must not match). */
|
|
263
264
|
function hasJsoncSyntax(text: string): boolean {
|
|
264
|
-
|
|
265
|
+
let inString = false;
|
|
266
|
+
let quote = "";
|
|
267
|
+
for (let i = 0; i < text.length; i++) {
|
|
268
|
+
const ch = text[i] ?? "";
|
|
269
|
+
const next = text[i + 1] ?? "";
|
|
270
|
+
if (inString) {
|
|
271
|
+
if (ch === "\\") {
|
|
272
|
+
i++;
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (ch === quote) {
|
|
276
|
+
inString = false;
|
|
277
|
+
}
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (ch === '"' || ch === "'") {
|
|
281
|
+
inString = true;
|
|
282
|
+
quote = ch;
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (ch === "/" && next === "/") {
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
if (ch === "/" && next === "*") {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
265
293
|
}
|
|
266
294
|
|
|
295
|
+
/**
|
|
296
|
+
* Locate a section object at the document root only.
|
|
297
|
+
* Nested keys with the same name (e.g. Claude Code projects.*.mcpServers) are ignored.
|
|
298
|
+
*/
|
|
267
299
|
function findSectionRange(
|
|
268
300
|
text: string,
|
|
269
301
|
sectionKey: string,
|
|
270
302
|
): { openBrace: number; closeBrace: number; indent: string } | null {
|
|
271
|
-
const
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
303
|
+
const keyPrefix = new RegExp(`^"${escapeRegExp(sectionKey)}"\\s*:\\s*\\{`);
|
|
304
|
+
let depth = 0;
|
|
305
|
+
let inString = false;
|
|
306
|
+
let quote = "";
|
|
307
|
+
let inLineComment = false;
|
|
308
|
+
let inBlockComment = false;
|
|
309
|
+
|
|
310
|
+
for (let i = 0; i < text.length; i++) {
|
|
311
|
+
const ch = text[i] ?? "";
|
|
312
|
+
const next = text[i + 1] ?? "";
|
|
313
|
+
if (inLineComment) {
|
|
314
|
+
if (ch === "\n") inLineComment = false;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (inBlockComment) {
|
|
318
|
+
if (ch === "*" && next === "/") {
|
|
319
|
+
inBlockComment = false;
|
|
320
|
+
i++;
|
|
321
|
+
}
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
if (inString) {
|
|
325
|
+
if (ch === "\\") {
|
|
326
|
+
i++;
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (ch === quote) {
|
|
330
|
+
inString = false;
|
|
331
|
+
}
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (ch === "/" && next === "/") {
|
|
335
|
+
inLineComment = true;
|
|
336
|
+
i++;
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
if (ch === "/" && next === "*") {
|
|
340
|
+
inBlockComment = true;
|
|
341
|
+
i++;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
if (depth === 1 && ch === '"') {
|
|
345
|
+
const match = keyPrefix.exec(text.slice(i));
|
|
346
|
+
if (match) {
|
|
347
|
+
const lineStart = text.lastIndexOf("\n", i) + 1;
|
|
348
|
+
const indent = /^[ \t]*/.exec(text.slice(lineStart, i))?.[0] ?? "";
|
|
349
|
+
const openBrace = i + match[0].length - 1;
|
|
350
|
+
const closeBrace = findMatchingBrace(text, openBrace);
|
|
351
|
+
if (closeBrace < 0) {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
return { openBrace, closeBrace, indent };
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (ch === '"' || ch === "'") {
|
|
358
|
+
inString = true;
|
|
359
|
+
quote = ch;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
if (ch === "{") {
|
|
363
|
+
depth++;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
if (ch === "}") {
|
|
367
|
+
depth--;
|
|
368
|
+
}
|
|
281
369
|
}
|
|
282
|
-
return
|
|
370
|
+
return null;
|
|
283
371
|
}
|
|
284
372
|
|
|
285
373
|
function findMatchingBrace(text: string, openIndex: number): number {
|