@probelabs/probe 0.6.0-rc106 → 0.6.0-rc107

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.
@@ -32364,11 +32364,19 @@ ${decodedContent}
32364
32364
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32365
32365
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32366
32366
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32367
+ const innerContent = content.trim().slice(1, -1);
32368
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32369
+ wasFixed = true;
32370
+ const decodedContent = decodeHtmlEntities(innerContent);
32371
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32372
+ return `["${safeContent}"]`;
32373
+ }
32367
32374
  return match;
32368
32375
  }
32369
32376
  if (needsQuoting(content)) {
32370
32377
  wasFixed = true;
32371
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32378
+ const decodedContent = decodeHtmlEntities(content);
32379
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32372
32380
  return `["${safeContent}"]`;
32373
32381
  }
32374
32382
  return match;
@@ -32377,11 +32385,19 @@ ${decodedContent}
32377
32385
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32378
32386
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32379
32387
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32388
+ const innerContent = content.trim().slice(1, -1);
32389
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32390
+ wasFixed = true;
32391
+ const decodedContent = decodeHtmlEntities(innerContent);
32392
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32393
+ return `{"${safeContent}"}`;
32394
+ }
32380
32395
  return match;
32381
32396
  }
32382
32397
  if (needsQuoting(content)) {
32383
32398
  wasFixed = true;
32384
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32399
+ const decodedContent = decodeHtmlEntities(content);
32400
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32385
32401
  return `{"${safeContent}"}`;
32386
32402
  }
32387
32403
  return match;
@@ -32547,11 +32563,19 @@ ${fixedContent}
32547
32563
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32548
32564
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32549
32565
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32566
+ const innerContent = content.trim().slice(1, -1);
32567
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32568
+ wasFixed = true;
32569
+ const decodedContent = decodeHtmlEntities(innerContent);
32570
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32571
+ return `["${safeContent}"]`;
32572
+ }
32550
32573
  return match;
32551
32574
  }
32552
32575
  if (needsQuoting(content)) {
32553
32576
  wasFixed = true;
32554
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32577
+ const decodedContent = decodeHtmlEntities(content);
32578
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32555
32579
  return `["${safeContent}"]`;
32556
32580
  }
32557
32581
  return match;
@@ -32560,11 +32584,19 @@ ${fixedContent}
32560
32584
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32561
32585
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32562
32586
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32587
+ const innerContent = content.trim().slice(1, -1);
32588
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32589
+ wasFixed = true;
32590
+ const decodedContent = decodeHtmlEntities(innerContent);
32591
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32592
+ return `{"${safeContent}"}`;
32593
+ }
32563
32594
  return match;
32564
32595
  }
32565
32596
  if (needsQuoting(content)) {
32566
32597
  wasFixed = true;
32567
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32598
+ const decodedContent = decodeHtmlEntities(content);
32599
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32568
32600
  return `{"${safeContent}"}`;
32569
32601
  }
32570
32602
  return match;
@@ -32789,6 +32821,8 @@ var init_schemaUtils = __esm({
32789
32821
  "&": "&",
32790
32822
  """: '"',
32791
32823
  "'": "'",
32824
+ "'": "'",
32825
+ // Also handle XML/HTML5 apostrophe entity
32792
32826
  " ": " "
32793
32827
  };
32794
32828
  MermaidFixingAgent = class {
@@ -14,6 +14,7 @@ const HTML_ENTITY_MAP = {
14
14
  '&': '&',
15
15
  '"': '"',
16
16
  ''': "'",
17
+ ''': "'", // Also handle XML/HTML5 apostrophe entity
17
18
  ' ': ' '
18
19
  };
19
20
 
@@ -1183,8 +1184,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1183
1184
  // Enhanced auto-fixing for square bracket nodes [...]
1184
1185
  if (trimmedLine.match(/\[[^\]]*\]/)) {
1185
1186
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
1186
- // Skip if already properly quoted
1187
+ // Check if already properly quoted with outer quotes
1187
1188
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1189
+ // Extract the inner content (between the outer quotes)
1190
+ const innerContent = content.trim().slice(1, -1);
1191
+ // Check if inner content has unescaped quotes that need escaping
1192
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1193
+ wasFixed = true;
1194
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1195
+ const decodedContent = decodeHtmlEntities(innerContent);
1196
+ const safeContent = decodedContent
1197
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1198
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1199
+ return `["${safeContent}"]`;
1200
+ }
1188
1201
  return match;
1189
1202
  }
1190
1203
 
@@ -1195,7 +1208,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1195
1208
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1196
1209
  // - HTML entities are the official way to escape quotes in Mermaid
1197
1210
  // - Always use double quotes with square brackets ["..."] for node labels
1198
- const safeContent = content
1211
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1212
+ const decodedContent = decodeHtmlEntities(content);
1213
+ const safeContent = decodedContent
1199
1214
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1200
1215
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1201
1216
  return `["${safeContent}"]`;
@@ -1208,8 +1223,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1208
1223
  // Enhanced auto-fixing for diamond nodes {...}
1209
1224
  if (trimmedLine.match(/\{[^{}]*\}/)) {
1210
1225
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
1211
- // Skip if already properly quoted
1226
+ // Check if already properly quoted with outer quotes
1212
1227
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1228
+ // Extract the inner content (between the outer quotes)
1229
+ const innerContent = content.trim().slice(1, -1);
1230
+ // Check if inner content has unescaped quotes that need escaping
1231
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1232
+ wasFixed = true;
1233
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1234
+ const decodedContent = decodeHtmlEntities(innerContent);
1235
+ const safeContent = decodedContent
1236
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1237
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1238
+ return `{"${safeContent}"}`;
1239
+ }
1213
1240
  return match;
1214
1241
  }
1215
1242
 
@@ -1220,7 +1247,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1220
1247
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1221
1248
  // - HTML entities are the official way to escape quotes in Mermaid
1222
1249
  // - Always use double quotes with curly brackets {"..."} for diamond nodes
1223
- const safeContent = content
1250
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1251
+ const decodedContent = decodeHtmlEntities(content);
1252
+ const safeContent = decodedContent
1224
1253
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1225
1254
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1226
1255
  return `{"${safeContent}"}`;
@@ -1448,8 +1477,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1448
1477
  // Look for any node labels that contain special characters and aren't already quoted
1449
1478
  if (trimmedLine.match(/\[[^\]]*\]/)) {
1450
1479
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
1451
- // Skip if already properly quoted
1480
+ // Check if already properly quoted with outer quotes
1452
1481
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1482
+ // Extract the inner content (between the outer quotes)
1483
+ const innerContent = content.trim().slice(1, -1);
1484
+ // Check if inner content has unescaped quotes that need escaping
1485
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1486
+ wasFixed = true;
1487
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1488
+ const decodedContent = decodeHtmlEntities(innerContent);
1489
+ const safeContent = decodedContent
1490
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1491
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1492
+ return `["${safeContent}"]`;
1493
+ }
1453
1494
  return match;
1454
1495
  }
1455
1496
 
@@ -1460,7 +1501,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1460
1501
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1461
1502
  // - HTML entities are the official way to escape quotes in Mermaid
1462
1503
  // - Always use double quotes with square brackets ["..."] for node labels
1463
- const safeContent = content
1504
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1505
+ const decodedContent = decodeHtmlEntities(content);
1506
+ const safeContent = decodedContent
1464
1507
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1465
1508
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1466
1509
  return `["${safeContent}"]`;
@@ -1473,8 +1516,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1473
1516
  // Enhanced auto-fixing for diamond nodes {...}
1474
1517
  if (trimmedLine.match(/\{[^{}]*\}/)) {
1475
1518
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
1476
- // Skip if already properly quoted
1519
+ // Check if already properly quoted with outer quotes
1477
1520
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1521
+ // Extract the inner content (between the outer quotes)
1522
+ const innerContent = content.trim().slice(1, -1);
1523
+ // Check if inner content has unescaped quotes that need escaping
1524
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1525
+ wasFixed = true;
1526
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1527
+ const decodedContent = decodeHtmlEntities(innerContent);
1528
+ const safeContent = decodedContent
1529
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1530
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1531
+ return `{"${safeContent}"}`;
1532
+ }
1478
1533
  return match;
1479
1534
  }
1480
1535
 
@@ -1485,7 +1540,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1485
1540
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1486
1541
  // - HTML entities are the official way to escape quotes in Mermaid
1487
1542
  // - Always use double quotes with curly brackets {"..."} for diamond nodes
1488
- const safeContent = content
1543
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1544
+ const decodedContent = decodeHtmlEntities(content);
1545
+ const safeContent = decodedContent
1489
1546
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1490
1547
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1491
1548
  return `{"${safeContent}"}`;
@@ -32086,11 +32086,19 @@ ${decodedContent}
32086
32086
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32087
32087
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32088
32088
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32089
+ const innerContent = content.trim().slice(1, -1);
32090
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32091
+ wasFixed = true;
32092
+ const decodedContent = decodeHtmlEntities(innerContent);
32093
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32094
+ return `["${safeContent}"]`;
32095
+ }
32089
32096
  return match;
32090
32097
  }
32091
32098
  if (needsQuoting(content)) {
32092
32099
  wasFixed = true;
32093
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32100
+ const decodedContent = decodeHtmlEntities(content);
32101
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32094
32102
  return `["${safeContent}"]`;
32095
32103
  }
32096
32104
  return match;
@@ -32099,11 +32107,19 @@ ${decodedContent}
32099
32107
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32100
32108
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32101
32109
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32110
+ const innerContent = content.trim().slice(1, -1);
32111
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32112
+ wasFixed = true;
32113
+ const decodedContent = decodeHtmlEntities(innerContent);
32114
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32115
+ return `{"${safeContent}"}`;
32116
+ }
32102
32117
  return match;
32103
32118
  }
32104
32119
  if (needsQuoting(content)) {
32105
32120
  wasFixed = true;
32106
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32121
+ const decodedContent = decodeHtmlEntities(content);
32122
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32107
32123
  return `{"${safeContent}"}`;
32108
32124
  }
32109
32125
  return match;
@@ -32269,11 +32285,19 @@ ${fixedContent}
32269
32285
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32270
32286
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32271
32287
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32288
+ const innerContent = content.trim().slice(1, -1);
32289
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32290
+ wasFixed = true;
32291
+ const decodedContent = decodeHtmlEntities(innerContent);
32292
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32293
+ return `["${safeContent}"]`;
32294
+ }
32272
32295
  return match;
32273
32296
  }
32274
32297
  if (needsQuoting(content)) {
32275
32298
  wasFixed = true;
32276
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32299
+ const decodedContent = decodeHtmlEntities(content);
32300
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32277
32301
  return `["${safeContent}"]`;
32278
32302
  }
32279
32303
  return match;
@@ -32282,11 +32306,19 @@ ${fixedContent}
32282
32306
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32283
32307
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32284
32308
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32309
+ const innerContent = content.trim().slice(1, -1);
32310
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32311
+ wasFixed = true;
32312
+ const decodedContent = decodeHtmlEntities(innerContent);
32313
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32314
+ return `{"${safeContent}"}`;
32315
+ }
32285
32316
  return match;
32286
32317
  }
32287
32318
  if (needsQuoting(content)) {
32288
32319
  wasFixed = true;
32289
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32320
+ const decodedContent = decodeHtmlEntities(content);
32321
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32290
32322
  return `{"${safeContent}"}`;
32291
32323
  }
32292
32324
  return match;
@@ -32511,6 +32543,8 @@ var init_schemaUtils = __esm({
32511
32543
  "&": "&",
32512
32544
  """: '"',
32513
32545
  "'": "'",
32546
+ "'": "'",
32547
+ // Also handle XML/HTML5 apostrophe entity
32514
32548
  " ": " "
32515
32549
  };
32516
32550
  MermaidFixingAgent = class {
package/cjs/index.cjs CHANGED
@@ -32231,11 +32231,19 @@ ${decodedContent}
32231
32231
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32232
32232
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32233
32233
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32234
+ const innerContent = content.trim().slice(1, -1);
32235
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32236
+ wasFixed = true;
32237
+ const decodedContent = decodeHtmlEntities(innerContent);
32238
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32239
+ return `["${safeContent}"]`;
32240
+ }
32234
32241
  return match;
32235
32242
  }
32236
32243
  if (needsQuoting(content)) {
32237
32244
  wasFixed = true;
32238
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32245
+ const decodedContent = decodeHtmlEntities(content);
32246
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32239
32247
  return `["${safeContent}"]`;
32240
32248
  }
32241
32249
  return match;
@@ -32244,11 +32252,19 @@ ${decodedContent}
32244
32252
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32245
32253
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32246
32254
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32255
+ const innerContent = content.trim().slice(1, -1);
32256
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32257
+ wasFixed = true;
32258
+ const decodedContent = decodeHtmlEntities(innerContent);
32259
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32260
+ return `{"${safeContent}"}`;
32261
+ }
32247
32262
  return match;
32248
32263
  }
32249
32264
  if (needsQuoting(content)) {
32250
32265
  wasFixed = true;
32251
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32266
+ const decodedContent = decodeHtmlEntities(content);
32267
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32252
32268
  return `{"${safeContent}"}`;
32253
32269
  }
32254
32270
  return match;
@@ -32414,11 +32430,19 @@ ${fixedContent}
32414
32430
  if (trimmedLine.match(/\[[^\]]*\]/)) {
32415
32431
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
32416
32432
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32433
+ const innerContent = content.trim().slice(1, -1);
32434
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32435
+ wasFixed = true;
32436
+ const decodedContent = decodeHtmlEntities(innerContent);
32437
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32438
+ return `["${safeContent}"]`;
32439
+ }
32417
32440
  return match;
32418
32441
  }
32419
32442
  if (needsQuoting(content)) {
32420
32443
  wasFixed = true;
32421
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32444
+ const decodedContent = decodeHtmlEntities(content);
32445
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32422
32446
  return `["${safeContent}"]`;
32423
32447
  }
32424
32448
  return match;
@@ -32427,11 +32451,19 @@ ${fixedContent}
32427
32451
  if (trimmedLine.match(/\{[^{}]*\}/)) {
32428
32452
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
32429
32453
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
32454
+ const innerContent = content.trim().slice(1, -1);
32455
+ if (innerContent.includes('"') || innerContent.includes("'")) {
32456
+ wasFixed = true;
32457
+ const decodedContent = decodeHtmlEntities(innerContent);
32458
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32459
+ return `{"${safeContent}"}`;
32460
+ }
32430
32461
  return match;
32431
32462
  }
32432
32463
  if (needsQuoting(content)) {
32433
32464
  wasFixed = true;
32434
- const safeContent = content.replace(/"/g, """).replace(/'/g, "'");
32465
+ const decodedContent = decodeHtmlEntities(content);
32466
+ const safeContent = decodedContent.replace(/"/g, """).replace(/'/g, "'");
32435
32467
  return `{"${safeContent}"}`;
32436
32468
  }
32437
32469
  return match;
@@ -32656,6 +32688,8 @@ var init_schemaUtils = __esm({
32656
32688
  "&": "&",
32657
32689
  """: '"',
32658
32690
  "'": "'",
32691
+ "'": "'",
32692
+ // Also handle XML/HTML5 apostrophe entity
32659
32693
  " ": " "
32660
32694
  };
32661
32695
  MermaidFixingAgent = class {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc106",
3
+ "version": "0.6.0-rc107",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -72,6 +72,8 @@
72
72
  "@ai-sdk/anthropic": "^2.0.8",
73
73
  "@ai-sdk/google": "^2.0.14",
74
74
  "@ai-sdk/openai": "^2.0.10",
75
+ "@mermaid-js/mermaid-cli": "^11.12.0",
76
+ "@mermaid-js/parser": "^0.6.2",
75
77
  "@modelcontextprotocol/sdk": "^1.0.0",
76
78
  "@opentelemetry/api": "^1.9.0",
77
79
  "@opentelemetry/core": "^1.30.1",
@@ -82,9 +84,14 @@
82
84
  "@opentelemetry/semantic-conventions": "^1.36.0",
83
85
  "ai": "^5.0.0",
84
86
  "axios": "^1.8.3",
87
+ "chalk": "^5.6.2",
88
+ "dompurify": "^3.2.7",
85
89
  "dotenv": "^16.4.7",
86
90
  "fs-extra": "^11.1.1",
87
91
  "glob": "^10.3.10",
92
+ "isomorphic-dompurify": "^2.28.0",
93
+ "jsdom": "^27.0.0",
94
+ "mermaid": "^11.12.0",
88
95
  "tar": "^6.2.0",
89
96
  "tiktoken": "^1.0.20",
90
97
  "zod": "^3.24.2"
@@ -14,6 +14,7 @@ const HTML_ENTITY_MAP = {
14
14
  '&': '&',
15
15
  '"': '"',
16
16
  ''': "'",
17
+ ''': "'", // Also handle XML/HTML5 apostrophe entity
17
18
  ' ': ' '
18
19
  };
19
20
 
@@ -1183,8 +1184,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1183
1184
  // Enhanced auto-fixing for square bracket nodes [...]
1184
1185
  if (trimmedLine.match(/\[[^\]]*\]/)) {
1185
1186
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
1186
- // Skip if already properly quoted
1187
+ // Check if already properly quoted with outer quotes
1187
1188
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1189
+ // Extract the inner content (between the outer quotes)
1190
+ const innerContent = content.trim().slice(1, -1);
1191
+ // Check if inner content has unescaped quotes that need escaping
1192
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1193
+ wasFixed = true;
1194
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1195
+ const decodedContent = decodeHtmlEntities(innerContent);
1196
+ const safeContent = decodedContent
1197
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1198
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1199
+ return `["${safeContent}"]`;
1200
+ }
1188
1201
  return match;
1189
1202
  }
1190
1203
 
@@ -1195,7 +1208,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1195
1208
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1196
1209
  // - HTML entities are the official way to escape quotes in Mermaid
1197
1210
  // - Always use double quotes with square brackets ["..."] for node labels
1198
- const safeContent = content
1211
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1212
+ const decodedContent = decodeHtmlEntities(content);
1213
+ const safeContent = decodedContent
1199
1214
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1200
1215
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1201
1216
  return `["${safeContent}"]`;
@@ -1208,8 +1223,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1208
1223
  // Enhanced auto-fixing for diamond nodes {...}
1209
1224
  if (trimmedLine.match(/\{[^{}]*\}/)) {
1210
1225
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
1211
- // Skip if already properly quoted
1226
+ // Check if already properly quoted with outer quotes
1212
1227
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1228
+ // Extract the inner content (between the outer quotes)
1229
+ const innerContent = content.trim().slice(1, -1);
1230
+ // Check if inner content has unescaped quotes that need escaping
1231
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1232
+ wasFixed = true;
1233
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1234
+ const decodedContent = decodeHtmlEntities(innerContent);
1235
+ const safeContent = decodedContent
1236
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1237
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1238
+ return `{"${safeContent}"}`;
1239
+ }
1213
1240
  return match;
1214
1241
  }
1215
1242
 
@@ -1220,7 +1247,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1220
1247
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1221
1248
  // - HTML entities are the official way to escape quotes in Mermaid
1222
1249
  // - Always use double quotes with curly brackets {"..."} for diamond nodes
1223
- const safeContent = content
1250
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1251
+ const decodedContent = decodeHtmlEntities(content);
1252
+ const safeContent = decodedContent
1224
1253
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1225
1254
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1226
1255
  return `{"${safeContent}"}`;
@@ -1448,8 +1477,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1448
1477
  // Look for any node labels that contain special characters and aren't already quoted
1449
1478
  if (trimmedLine.match(/\[[^\]]*\]/)) {
1450
1479
  modifiedLine = modifiedLine.replace(/\[([^\]]*)\]/g, (match, content) => {
1451
- // Skip if already properly quoted
1480
+ // Check if already properly quoted with outer quotes
1452
1481
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1482
+ // Extract the inner content (between the outer quotes)
1483
+ const innerContent = content.trim().slice(1, -1);
1484
+ // Check if inner content has unescaped quotes that need escaping
1485
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1486
+ wasFixed = true;
1487
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1488
+ const decodedContent = decodeHtmlEntities(innerContent);
1489
+ const safeContent = decodedContent
1490
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1491
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1492
+ return `["${safeContent}"]`;
1493
+ }
1453
1494
  return match;
1454
1495
  }
1455
1496
 
@@ -1460,7 +1501,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1460
1501
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1461
1502
  // - HTML entities are the official way to escape quotes in Mermaid
1462
1503
  // - Always use double quotes with square brackets ["..."] for node labels
1463
- const safeContent = content
1504
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1505
+ const decodedContent = decodeHtmlEntities(content);
1506
+ const safeContent = decodedContent
1464
1507
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1465
1508
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1466
1509
  return `["${safeContent}"]`;
@@ -1473,8 +1516,20 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1473
1516
  // Enhanced auto-fixing for diamond nodes {...}
1474
1517
  if (trimmedLine.match(/\{[^{}]*\}/)) {
1475
1518
  modifiedLine = modifiedLine.replace(/\{([^{}]*)\}/g, (match, content) => {
1476
- // Skip if already properly quoted
1519
+ // Check if already properly quoted with outer quotes
1477
1520
  if (content.trim().startsWith('"') && content.trim().endsWith('"')) {
1521
+ // Extract the inner content (between the outer quotes)
1522
+ const innerContent = content.trim().slice(1, -1);
1523
+ // Check if inner content has unescaped quotes that need escaping
1524
+ if (innerContent.includes('"') || innerContent.includes("'")) {
1525
+ wasFixed = true;
1526
+ // Decode any existing HTML entities first, then re-encode ALL quotes
1527
+ const decodedContent = decodeHtmlEntities(innerContent);
1528
+ const safeContent = decodedContent
1529
+ .replace(/"/g, '"') // Replace ALL double quotes with HTML entity
1530
+ .replace(/'/g, '''); // Replace ALL single quotes with HTML entity
1531
+ return `{"${safeContent}"}`;
1532
+ }
1478
1533
  return match;
1479
1534
  }
1480
1535
 
@@ -1485,7 +1540,9 @@ export async function validateAndFixMermaidResponse(response, options = {}) {
1485
1540
  // - GitHub doesn't support single quotes in node labels (causes 'got PS' error)
1486
1541
  // - HTML entities are the official way to escape quotes in Mermaid
1487
1542
  // - Always use double quotes with curly brackets {"..."} for diamond nodes
1488
- const safeContent = content
1543
+ // IMPORTANT: Decode any existing HTML entities first to avoid double-encoding
1544
+ const decodedContent = decodeHtmlEntities(content);
1545
+ const safeContent = decodedContent
1489
1546
  .replace(/"/g, '"') // Replace double quotes with HTML entity
1490
1547
  .replace(/'/g, '''); // Replace single quotes with HTML entity
1491
1548
  return `{"${safeContent}"}`;