@probelabs/probe 0.6.0-rc145 → 0.6.0-rc146

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.
@@ -38,6 +38,364 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
38
38
  mod
39
39
  ));
40
40
 
41
+ // node_modules/dotenv/package.json
42
+ var require_package = __commonJS({
43
+ "node_modules/dotenv/package.json"(exports2, module2) {
44
+ module2.exports = {
45
+ name: "dotenv",
46
+ version: "16.6.1",
47
+ description: "Loads environment variables from .env file",
48
+ main: "lib/main.js",
49
+ types: "lib/main.d.ts",
50
+ exports: {
51
+ ".": {
52
+ types: "./lib/main.d.ts",
53
+ require: "./lib/main.js",
54
+ default: "./lib/main.js"
55
+ },
56
+ "./config": "./config.js",
57
+ "./config.js": "./config.js",
58
+ "./lib/env-options": "./lib/env-options.js",
59
+ "./lib/env-options.js": "./lib/env-options.js",
60
+ "./lib/cli-options": "./lib/cli-options.js",
61
+ "./lib/cli-options.js": "./lib/cli-options.js",
62
+ "./package.json": "./package.json"
63
+ },
64
+ scripts: {
65
+ "dts-check": "tsc --project tests/types/tsconfig.json",
66
+ lint: "standard",
67
+ pretest: "npm run lint && npm run dts-check",
68
+ test: "tap run --allow-empty-coverage --disable-coverage --timeout=60000",
69
+ "test:coverage": "tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
70
+ prerelease: "npm test",
71
+ release: "standard-version"
72
+ },
73
+ repository: {
74
+ type: "git",
75
+ url: "git://github.com/motdotla/dotenv.git"
76
+ },
77
+ homepage: "https://github.com/motdotla/dotenv#readme",
78
+ funding: "https://dotenvx.com",
79
+ keywords: [
80
+ "dotenv",
81
+ "env",
82
+ ".env",
83
+ "environment",
84
+ "variables",
85
+ "config",
86
+ "settings"
87
+ ],
88
+ readmeFilename: "README.md",
89
+ license: "BSD-2-Clause",
90
+ devDependencies: {
91
+ "@types/node": "^18.11.3",
92
+ decache: "^4.6.2",
93
+ sinon: "^14.0.1",
94
+ standard: "^17.0.0",
95
+ "standard-version": "^9.5.0",
96
+ tap: "^19.2.0",
97
+ typescript: "^4.8.4"
98
+ },
99
+ engines: {
100
+ node: ">=12"
101
+ },
102
+ browser: {
103
+ fs: false
104
+ }
105
+ };
106
+ }
107
+ });
108
+
109
+ // node_modules/dotenv/lib/main.js
110
+ var require_main = __commonJS({
111
+ "node_modules/dotenv/lib/main.js"(exports2, module2) {
112
+ var fs6 = __require("fs");
113
+ var path7 = __require("path");
114
+ var os3 = __require("os");
115
+ var crypto = __require("crypto");
116
+ var packageJson = require_package();
117
+ var version = packageJson.version;
118
+ var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
119
+ function parse6(src) {
120
+ const obj = {};
121
+ let lines = src.toString();
122
+ lines = lines.replace(/\r\n?/mg, "\n");
123
+ let match2;
124
+ while ((match2 = LINE.exec(lines)) != null) {
125
+ const key = match2[1];
126
+ let value = match2[2] || "";
127
+ value = value.trim();
128
+ const maybeQuote = value[0];
129
+ value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
130
+ if (maybeQuote === '"') {
131
+ value = value.replace(/\\n/g, "\n");
132
+ value = value.replace(/\\r/g, "\r");
133
+ }
134
+ obj[key] = value;
135
+ }
136
+ return obj;
137
+ }
138
+ function _parseVault(options) {
139
+ options = options || {};
140
+ const vaultPath = _vaultPath(options);
141
+ options.path = vaultPath;
142
+ const result = DotenvModule.configDotenv(options);
143
+ if (!result.parsed) {
144
+ const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
145
+ err.code = "MISSING_DATA";
146
+ throw err;
147
+ }
148
+ const keys2 = _dotenvKey(options).split(",");
149
+ const length = keys2.length;
150
+ let decrypted;
151
+ for (let i = 0; i < length; i++) {
152
+ try {
153
+ const key = keys2[i].trim();
154
+ const attrs = _instructions(result, key);
155
+ decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
156
+ break;
157
+ } catch (error) {
158
+ if (i + 1 >= length) {
159
+ throw error;
160
+ }
161
+ }
162
+ }
163
+ return DotenvModule.parse(decrypted);
164
+ }
165
+ function _warn(message) {
166
+ console.log(`[dotenv@${version}][WARN] ${message}`);
167
+ }
168
+ function _debug(message) {
169
+ console.log(`[dotenv@${version}][DEBUG] ${message}`);
170
+ }
171
+ function _log(message) {
172
+ console.log(`[dotenv@${version}] ${message}`);
173
+ }
174
+ function _dotenvKey(options) {
175
+ if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
176
+ return options.DOTENV_KEY;
177
+ }
178
+ if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
179
+ return process.env.DOTENV_KEY;
180
+ }
181
+ return "";
182
+ }
183
+ function _instructions(result, dotenvKey) {
184
+ let uri;
185
+ try {
186
+ uri = new URL(dotenvKey);
187
+ } catch (error) {
188
+ if (error.code === "ERR_INVALID_URL") {
189
+ const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
190
+ err.code = "INVALID_DOTENV_KEY";
191
+ throw err;
192
+ }
193
+ throw error;
194
+ }
195
+ const key = uri.password;
196
+ if (!key) {
197
+ const err = new Error("INVALID_DOTENV_KEY: Missing key part");
198
+ err.code = "INVALID_DOTENV_KEY";
199
+ throw err;
200
+ }
201
+ const environment = uri.searchParams.get("environment");
202
+ if (!environment) {
203
+ const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
204
+ err.code = "INVALID_DOTENV_KEY";
205
+ throw err;
206
+ }
207
+ const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
208
+ const ciphertext = result.parsed[environmentKey];
209
+ if (!ciphertext) {
210
+ const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
211
+ err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
212
+ throw err;
213
+ }
214
+ return { ciphertext, key };
215
+ }
216
+ function _vaultPath(options) {
217
+ let possibleVaultPath = null;
218
+ if (options && options.path && options.path.length > 0) {
219
+ if (Array.isArray(options.path)) {
220
+ for (const filepath of options.path) {
221
+ if (fs6.existsSync(filepath)) {
222
+ possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
223
+ }
224
+ }
225
+ } else {
226
+ possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
227
+ }
228
+ } else {
229
+ possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
230
+ }
231
+ if (fs6.existsSync(possibleVaultPath)) {
232
+ return possibleVaultPath;
233
+ }
234
+ return null;
235
+ }
236
+ function _resolveHome(envPath) {
237
+ return envPath[0] === "~" ? path7.join(os3.homedir(), envPath.slice(1)) : envPath;
238
+ }
239
+ function _configVault(options) {
240
+ const debug = Boolean(options && options.debug);
241
+ const quiet = options && "quiet" in options ? options.quiet : true;
242
+ if (debug || !quiet) {
243
+ _log("Loading env from encrypted .env.vault");
244
+ }
245
+ const parsed = DotenvModule._parseVault(options);
246
+ let processEnv = process.env;
247
+ if (options && options.processEnv != null) {
248
+ processEnv = options.processEnv;
249
+ }
250
+ DotenvModule.populate(processEnv, parsed, options);
251
+ return { parsed };
252
+ }
253
+ function configDotenv(options) {
254
+ const dotenvPath = path7.resolve(process.cwd(), ".env");
255
+ let encoding = "utf8";
256
+ const debug = Boolean(options && options.debug);
257
+ const quiet = options && "quiet" in options ? options.quiet : true;
258
+ if (options && options.encoding) {
259
+ encoding = options.encoding;
260
+ } else {
261
+ if (debug) {
262
+ _debug("No encoding is specified. UTF-8 is used by default");
263
+ }
264
+ }
265
+ let optionPaths = [dotenvPath];
266
+ if (options && options.path) {
267
+ if (!Array.isArray(options.path)) {
268
+ optionPaths = [_resolveHome(options.path)];
269
+ } else {
270
+ optionPaths = [];
271
+ for (const filepath of options.path) {
272
+ optionPaths.push(_resolveHome(filepath));
273
+ }
274
+ }
275
+ }
276
+ let lastError;
277
+ const parsedAll = {};
278
+ for (const path8 of optionPaths) {
279
+ try {
280
+ const parsed = DotenvModule.parse(fs6.readFileSync(path8, { encoding }));
281
+ DotenvModule.populate(parsedAll, parsed, options);
282
+ } catch (e) {
283
+ if (debug) {
284
+ _debug(`Failed to load ${path8} ${e.message}`);
285
+ }
286
+ lastError = e;
287
+ }
288
+ }
289
+ let processEnv = process.env;
290
+ if (options && options.processEnv != null) {
291
+ processEnv = options.processEnv;
292
+ }
293
+ DotenvModule.populate(processEnv, parsedAll, options);
294
+ if (debug || !quiet) {
295
+ const keysCount = Object.keys(parsedAll).length;
296
+ const shortPaths = [];
297
+ for (const filePath of optionPaths) {
298
+ try {
299
+ const relative = path7.relative(process.cwd(), filePath);
300
+ shortPaths.push(relative);
301
+ } catch (e) {
302
+ if (debug) {
303
+ _debug(`Failed to load ${filePath} ${e.message}`);
304
+ }
305
+ lastError = e;
306
+ }
307
+ }
308
+ _log(`injecting env (${keysCount}) from ${shortPaths.join(",")}`);
309
+ }
310
+ if (lastError) {
311
+ return { parsed: parsedAll, error: lastError };
312
+ } else {
313
+ return { parsed: parsedAll };
314
+ }
315
+ }
316
+ function config(options) {
317
+ if (_dotenvKey(options).length === 0) {
318
+ return DotenvModule.configDotenv(options);
319
+ }
320
+ const vaultPath = _vaultPath(options);
321
+ if (!vaultPath) {
322
+ _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
323
+ return DotenvModule.configDotenv(options);
324
+ }
325
+ return DotenvModule._configVault(options);
326
+ }
327
+ function decrypt(encrypted, keyStr) {
328
+ const key = Buffer.from(keyStr.slice(-64), "hex");
329
+ let ciphertext = Buffer.from(encrypted, "base64");
330
+ const nonce = ciphertext.subarray(0, 12);
331
+ const authTag = ciphertext.subarray(-16);
332
+ ciphertext = ciphertext.subarray(12, -16);
333
+ try {
334
+ const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
335
+ aesgcm.setAuthTag(authTag);
336
+ return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
337
+ } catch (error) {
338
+ const isRange = error instanceof RangeError;
339
+ const invalidKeyLength = error.message === "Invalid key length";
340
+ const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
341
+ if (isRange || invalidKeyLength) {
342
+ const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
343
+ err.code = "INVALID_DOTENV_KEY";
344
+ throw err;
345
+ } else if (decryptionFailed) {
346
+ const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
347
+ err.code = "DECRYPTION_FAILED";
348
+ throw err;
349
+ } else {
350
+ throw error;
351
+ }
352
+ }
353
+ }
354
+ function populate(processEnv, parsed, options = {}) {
355
+ const debug = Boolean(options && options.debug);
356
+ const override = Boolean(options && options.override);
357
+ if (typeof parsed !== "object") {
358
+ const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
359
+ err.code = "OBJECT_REQUIRED";
360
+ throw err;
361
+ }
362
+ for (const key of Object.keys(parsed)) {
363
+ if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
364
+ if (override === true) {
365
+ processEnv[key] = parsed[key];
366
+ }
367
+ if (debug) {
368
+ if (override === true) {
369
+ _debug(`"${key}" is already defined and WAS overwritten`);
370
+ } else {
371
+ _debug(`"${key}" is already defined and was NOT overwritten`);
372
+ }
373
+ }
374
+ } else {
375
+ processEnv[key] = parsed[key];
376
+ }
377
+ }
378
+ }
379
+ var DotenvModule = {
380
+ configDotenv,
381
+ _configVault,
382
+ _parseVault,
383
+ config,
384
+ decrypt,
385
+ parse: parse6,
386
+ populate
387
+ };
388
+ module2.exports.configDotenv = DotenvModule.configDotenv;
389
+ module2.exports._configVault = DotenvModule._configVault;
390
+ module2.exports._parseVault = DotenvModule._parseVault;
391
+ module2.exports.config = DotenvModule.config;
392
+ module2.exports.decrypt = DotenvModule.decrypt;
393
+ module2.exports.parse = DotenvModule.parse;
394
+ module2.exports.populate = DotenvModule.populate;
395
+ module2.exports = DotenvModule;
396
+ }
397
+ });
398
+
41
399
  // node_modules/gpt-tokenizer/esm/bpeRanks/o200k_base.js
42
400
  var c0, c1, bpe, o200k_base_default;
43
401
  var init_o200k_base = __esm({
@@ -16641,9 +16999,11 @@ var init_hooks = __esm({
16641
16999
  });
16642
17000
 
16643
17001
  // src/index.js
17002
+ var import_dotenv;
16644
17003
  var init_index = __esm({
16645
17004
  "src/index.js"() {
16646
17005
  "use strict";
17006
+ import_dotenv = __toESM(require_main(), 1);
16647
17007
  init_search();
16648
17008
  init_query();
16649
17009
  init_extract();
@@ -16663,6 +17023,7 @@ var init_index = __esm({
16663
17023
  init_probeTool();
16664
17024
  init_storage();
16665
17025
  init_hooks();
17026
+ import_dotenv.default.config();
16666
17027
  }
16667
17028
  });
16668
17029
 
@@ -28746,8 +29107,8 @@ var init_parser2 = __esm({
28746
29107
  { ALT: () => this.CONSUME(Identifier) },
28747
29108
  { ALT: () => this.CONSUME(Text) },
28748
29109
  { ALT: () => this.CONSUME(NumberLiteral) },
28749
- { ALT: () => this.CONSUME(RoundOpen) },
28750
- { ALT: () => this.CONSUME(RoundClose) },
29110
+ // Note: RoundOpen and RoundClose (parentheses) are NOT allowed in unquoted labels
29111
+ // to match Mermaid's behavior - use quoted labels like ["text (with parens)"] instead
28751
29112
  // Allow HTML-like tags (e.g., <br/>) inside labels
28752
29113
  { ALT: () => this.CONSUME(AngleLess) },
28753
29114
  { ALT: () => this.CONSUME(AngleOpen) },
@@ -28836,7 +29197,17 @@ var init_parser2 = __esm({
28836
29197
  this.OR([
28837
29198
  { ALT: () => this.CONSUME(Identifier) },
28838
29199
  { ALT: () => this.CONSUME(Text) },
28839
- { ALT: () => this.CONSUME(NumberLiteral) }
29200
+ { ALT: () => this.CONSUME(NumberLiteral) },
29201
+ // Allow HTML-like angle brackets and slashes for <br/>, <i>, etc.
29202
+ { ALT: () => this.CONSUME(AngleLess) },
29203
+ { ALT: () => this.CONSUME(AngleOpen) },
29204
+ { ALT: () => this.CONSUME(ForwardSlash) },
29205
+ { ALT: () => this.CONSUME(Backslash) },
29206
+ // Allow common punctuation seen in labels
29207
+ { ALT: () => this.CONSUME(Comma) },
29208
+ { ALT: () => this.CONSUME(Colon) },
29209
+ { ALT: () => this.CONSUME(Ampersand) },
29210
+ { ALT: () => this.CONSUME(Semicolon) }
28840
29211
  ]);
28841
29212
  });
28842
29213
  });
@@ -29448,7 +29819,7 @@ var init_semantics = __esm({
29448
29819
  this.ctx.errors.push({
29449
29820
  line: q.startLine ?? 1,
29450
29821
  column: col,
29451
- severity: "warning",
29822
+ severity: "error",
29452
29823
  code: "FL-LABEL-CURLY-IN-QUOTED",
29453
29824
  message: "Curly braces inside quoted label text may be parsed as a shape by Mermaid. Replace { and } with HTML entities.",
29454
29825
  hint: 'Use &#123; and &#125; for { and } inside quoted text, e.g., "tyk-trace-&#123;id&#125;".',
@@ -29578,6 +29949,8 @@ var init_semantics = __esm({
29578
29949
  this.ctx.errors.push({
29579
29950
  line: tk.startLine ?? 1,
29580
29951
  column: col,
29952
+ // Treat backticks in quoted labels as errors (CLI rejects in many cases);
29953
+ // outside quotes, surface as a warning.
29581
29954
  severity: inQuoted ? "error" : "warning",
29582
29955
  code: "FL-LABEL-BACKTICK",
29583
29956
  message: "Backticks (`\u2026`) inside node labels are not supported by Mermaid.",
@@ -30862,7 +31235,7 @@ function validateFlowchart(text, options = {}) {
30862
31235
  code: "FL-LABEL-ESCAPED-QUOTE",
30863
31236
  message: 'Escaped quotes (\\") in node labels are accepted by Mermaid, but using &quot; is preferred for portability.',
30864
31237
  hint: 'Prefer &quot; inside quoted labels, e.g., A["He said &quot;Hi&quot;"]'
30865
- }).map((e) => ({ ...e, severity: "warning" }));
31238
+ }).map((e) => ({ ...e, severity: "error" }));
30866
31239
  const seenDoubleLines = new Set(prevErrors.filter((e) => e.code === "FL-LABEL-DOUBLE-IN-DOUBLE").map((e) => e.line));
30867
31240
  const escapedLinesAll = new Set(detectEscapedQuotes(tokens, { code: "x" }).map((e) => e.line));
30868
31241
  const dbl = detectDoubleInDouble(tokens, {
@@ -33141,11 +33514,85 @@ function computeFixes(text, errors, level = "safe") {
33141
33514
  const patchedLines = /* @__PURE__ */ new Set();
33142
33515
  const seen = /* @__PURE__ */ new Set();
33143
33516
  const piQuoteClosedLines = /* @__PURE__ */ new Set();
33517
+ function sanitizeAllQuotedSegmentsInShapes(lineText, lineNo) {
33518
+ const shapes = [
33519
+ { open: "[[", close: "]]" },
33520
+ { open: "((", close: "))" },
33521
+ { open: "{{", close: "}}" },
33522
+ { open: "[(", close: ")]" },
33523
+ { open: "([", close: "])" },
33524
+ { open: "{", close: "}" },
33525
+ { open: "[", close: "]" },
33526
+ { open: "(", close: ")" }
33527
+ ];
33528
+ let idx = 0;
33529
+ let produced = 0;
33530
+ while (idx < lineText.length) {
33531
+ let found = null;
33532
+ for (const s of shapes) {
33533
+ const i = lineText.indexOf(s.open, idx);
33534
+ if (i !== -1 && (found === null || i < found.i))
33535
+ found = { ...s, i };
33536
+ }
33537
+ if (!found)
33538
+ break;
33539
+ const contentStart = found.i + found.open.length;
33540
+ const closeIdx = lineText.indexOf(found.close, contentStart);
33541
+ if (closeIdx === -1) {
33542
+ idx = contentStart;
33543
+ continue;
33544
+ }
33545
+ let q1 = -1;
33546
+ for (let i = contentStart; i < closeIdx; i++) {
33547
+ if (lineText[i] === '"' && lineText[i - 1] !== "\\") {
33548
+ q1 = i;
33549
+ break;
33550
+ }
33551
+ }
33552
+ if (q1 !== -1) {
33553
+ let q2 = -1;
33554
+ for (let j = closeIdx - 1; j > q1; j--) {
33555
+ if (lineText[j] === '"' && lineText[j - 1] !== "\\") {
33556
+ q2 = j;
33557
+ break;
33558
+ }
33559
+ }
33560
+ if (q2 !== -1) {
33561
+ const inner = lineText.slice(q1 + 1, q2);
33562
+ const replaced = sanitizeQuotedInner(inner);
33563
+ if (replaced !== inner) {
33564
+ edits.push({ start: { line: lineNo, column: q1 + 2 }, end: { line: lineNo, column: q2 + 1 }, newText: replaced });
33565
+ produced++;
33566
+ }
33567
+ }
33568
+ }
33569
+ idx = closeIdx + found.close.length;
33570
+ }
33571
+ return produced;
33572
+ }
33573
+ function sanitizeQuotedInner(inner) {
33574
+ const SENT_Q = "\0__Q__";
33575
+ let out = inner.split("&quot;").join(SENT_Q);
33576
+ out = out.replace(/`/g, "");
33577
+ out = out.replace(/\\\"/g, "&quot;");
33578
+ out = out.replace(/\"/g, "&quot;");
33579
+ out = out.replace(/"/g, "&quot;");
33580
+ out = out.split(SENT_Q).join("&quot;");
33581
+ return out;
33582
+ }
33144
33583
  for (const e of errors) {
33145
33584
  const key = `${e.code}@${e.line}:${e.column}:${e.length ?? 1}`;
33146
33585
  if (seen.has(key))
33147
33586
  continue;
33148
33587
  seen.add(key);
33588
+ if ((e.code === "FL-LABEL-ESCAPED-QUOTE" || e.code === "FL-LABEL-CURLY-IN-QUOTED" || e.code === "FL-LABEL-DOUBLE-IN-DOUBLE" || e.code === "FL-LABEL-BACKTICK") && !patchedLines.has(e.line)) {
33589
+ const lineText = lineTextAt(text, e.line);
33590
+ const produced = sanitizeAllQuotedSegmentsInShapes(lineText, e.line);
33591
+ patchedLines.add(e.line);
33592
+ if (produced > 0) {
33593
+ continue;
33594
+ }
33595
+ }
33149
33596
  if (is("FL-ARROW-INVALID", e)) {
33150
33597
  edits.push(replaceRange(text, at(e), e.length ?? 2, "-->"));
33151
33598
  continue;
@@ -33250,6 +33697,8 @@ function computeFixes(text, errors, level = "safe") {
33250
33697
  continue;
33251
33698
  }
33252
33699
  if (is("FL-LABEL-ESCAPED-QUOTE", e)) {
33700
+ if (patchedLines.has(e.line))
33701
+ continue;
33253
33702
  const lineText = lineTextAt(text, e.line);
33254
33703
  const caret0 = Math.max(0, e.column - 1);
33255
33704
  const opens = [
@@ -33272,17 +33721,10 @@ function computeFixes(text, errors, level = "safe") {
33272
33721
  const q2 = lineText.lastIndexOf('"', closeIdx - 1);
33273
33722
  if (q1 !== -1 && q2 !== -1 && q2 > q1) {
33274
33723
  const inner = lineText.slice(q1 + 1, q2);
33275
- if (inner.includes('\\"')) {
33276
- const replaced = inner.split('\\"').join("&quot;");
33724
+ const replaced = sanitizeQuotedInner(inner);
33725
+ if (replaced !== inner) {
33277
33726
  edits.push({ start: { line: e.line, column: q1 + 2 }, end: { line: e.line, column: q2 + 1 }, newText: replaced });
33278
33727
  continue;
33279
- if (is("FL-META-UNSUPPORTED", e)) {
33280
- if (level === "all") {
33281
- const lineText2 = lineTextAt(text, e.line);
33282
- edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line + 1, column: 1 }, newText: "" });
33283
- }
33284
- continue;
33285
- }
33286
33728
  }
33287
33729
  }
33288
33730
  }
@@ -33292,11 +33734,12 @@ function computeFixes(text, errors, level = "safe") {
33292
33734
  }
33293
33735
  if (is("FL-META-UNSUPPORTED", e)) {
33294
33736
  if (level === "all") {
33737
+ const lineText = lineTextAt(text, e.line);
33295
33738
  edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line + 1, column: 1 }, newText: "" });
33296
33739
  }
33297
33740
  continue;
33298
33741
  }
33299
- if (is("FL-LABEL-BACKTICK", e)) {
33742
+ if (is("FL-LABEL-BACKTICK", e) && e.severity === "warning") {
33300
33743
  edits.push(replaceRange(text, at(e), e.length ?? 1, ""));
33301
33744
  continue;
33302
33745
  }
@@ -33306,13 +33749,13 @@ function computeFixes(text, errors, level = "safe") {
33306
33749
  let qOpenIdx = -1;
33307
33750
  let qChar = null;
33308
33751
  for (let i = caret0; i >= 0; i--) {
33309
- const ch2 = lineText[i];
33310
- const code = ch2 ? ch2.charCodeAt(0) : -1;
33752
+ const ch = lineText[i];
33753
+ const code = ch ? ch.charCodeAt(0) : -1;
33311
33754
  if (code === 34 || code === 39) {
33312
33755
  const bs = i > 0 && lineText[i - 1] === "\\";
33313
33756
  if (!bs) {
33314
33757
  qOpenIdx = i;
33315
- qChar = ch2;
33758
+ qChar = ch;
33316
33759
  break;
33317
33760
  }
33318
33761
  }
@@ -33320,8 +33763,8 @@ function computeFixes(text, errors, level = "safe") {
33320
33763
  if (qOpenIdx !== -1 && qChar) {
33321
33764
  let qCloseIdx = -1;
33322
33765
  for (let j = qOpenIdx + 1; j < lineText.length; j++) {
33323
- const ch2 = lineText[j];
33324
- const code = ch2 ? ch2.charCodeAt(0) : -1;
33766
+ const ch = lineText[j];
33767
+ const code = ch ? ch.charCodeAt(0) : -1;
33325
33768
  if (code === (qChar ? qChar.charCodeAt(0) : -1)) {
33326
33769
  const bs = lineText[j - 1] === "\\";
33327
33770
  if (!bs) {
@@ -33332,17 +33775,13 @@ function computeFixes(text, errors, level = "safe") {
33332
33775
  }
33333
33776
  if (qCloseIdx > qOpenIdx) {
33334
33777
  const inner = lineText.slice(qOpenIdx + 1, qCloseIdx);
33335
- const replaced = inner.replace(/\{/g, "&#123;").replace(/\}/g, "&#125;");
33778
+ const replaced = sanitizeQuotedInner(inner);
33336
33779
  if (replaced !== inner) {
33337
33780
  edits.push({ start: { line: e.line, column: qOpenIdx + 2 }, end: { line: e.line, column: qCloseIdx + 1 }, newText: replaced });
33338
33781
  continue;
33339
33782
  }
33340
33783
  }
33341
33784
  }
33342
- const ch = lineText[caret0] || "";
33343
- const rep = ch === "{" ? "&#123;" : ch === "}" ? "&#125;" : ch;
33344
- if (rep !== ch)
33345
- edits.push(replaceRange(text, at(e), e.length ?? 1, rep));
33346
33785
  continue;
33347
33786
  }
33348
33787
  if (is("FL-END-WITHOUT-SUBGRAPH", e)) {
@@ -33354,6 +33793,11 @@ function computeFixes(text, errors, level = "safe") {
33354
33793
  if (is("FL-LABEL-DOUBLE-IN-DOUBLE", e)) {
33355
33794
  const lineText = lineTextAt(text, e.line);
33356
33795
  const caret0 = Math.max(0, e.column - 1);
33796
+ const rawDqCount = (lineText.match(/\"/g) || []).length;
33797
+ const unescapedDqCount = (lineText.replace(/\\\"/g, "").match(/\"/g) || []).length;
33798
+ if (rawDqCount + unescapedDqCount > 8 && level !== "all") {
33799
+ continue;
33800
+ }
33357
33801
  const opens = [
33358
33802
  { tok: "[[", idx: lineText.lastIndexOf("[[", caret0) },
33359
33803
  { tok: "((", idx: lineText.lastIndexOf("((", caret0) },
@@ -33377,7 +33821,7 @@ function computeFixes(text, errors, level = "safe") {
33377
33821
  const q2 = lineText.lastIndexOf('"', closeIdx - 1);
33378
33822
  if (q1 !== -1 && q2 !== -1 && q2 > q1) {
33379
33823
  const inner = lineText.slice(q1 + 1, q2);
33380
- const replaced = inner.split("&quot;").join("\0").split('"').join("&quot;").split("\0").join("&quot;");
33824
+ const replaced = sanitizeQuotedInner(inner);
33381
33825
  if (replaced !== inner) {
33382
33826
  const start = { line: e.line, column: q1 + 2 };
33383
33827
  const end = { line: e.line, column: q2 + 1 };
@@ -33739,6 +34183,10 @@ function computeFixes(text, errors, level = "safe") {
33739
34183
  if (level === "safe" || level === "all") {
33740
34184
  const lineText = lineTextAt(text, e.line);
33741
34185
  const caret0 = Math.max(0, e.column - 1);
34186
+ const dq = (lineText.replace(/\\\"/g, "").match(/\"/g) || []).length;
34187
+ if (lineText.length > 600 || dq > 8) {
34188
+ continue;
34189
+ }
33742
34190
  const openPairs = [
33743
34191
  { open: "[[", close: "]]", idx: lineText.lastIndexOf("[[", caret0), delta: 2 },
33744
34192
  { open: "((", close: "))", idx: lineText.lastIndexOf("((", caret0), delta: 2 },
@@ -33789,6 +34237,24 @@ function computeFixes(text, errors, level = "safe") {
33789
34237
  { open: "[", close: "]" },
33790
34238
  { open: "(", close: ")" }
33791
34239
  ];
34240
+ const findMatchingCloser = (text2, openIdx, opener, closer) => {
34241
+ let pos = openIdx + opener.length;
34242
+ let depth = 1;
34243
+ while (pos < text2.length && depth > 0) {
34244
+ if (text2.slice(pos, pos + opener.length) === opener) {
34245
+ depth++;
34246
+ pos += opener.length;
34247
+ } else if (text2.slice(pos, pos + closer.length) === closer) {
34248
+ depth--;
34249
+ if (depth === 0)
34250
+ return pos;
34251
+ pos += closer.length;
34252
+ } else {
34253
+ pos++;
34254
+ }
34255
+ }
34256
+ return -1;
34257
+ };
33792
34258
  for (const shape of shapes) {
33793
34259
  let searchStart = 0;
33794
34260
  while (true) {
@@ -33796,7 +34262,7 @@ function computeFixes(text, errors, level = "safe") {
33796
34262
  if (openIdx === -1)
33797
34263
  break;
33798
34264
  const contentStart = openIdx + shape.open.length;
33799
- const closeIdx = lineText.indexOf(shape.close, contentStart);
34265
+ const closeIdx = shape.open === "(" && shape.close === ")" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
33800
34266
  if (closeIdx === -1)
33801
34267
  break;
33802
34268
  if (openIdx <= caret0 && caret0 < closeIdx) {
@@ -33814,10 +34280,11 @@ function computeFixes(text, errors, level = "safe") {
33814
34280
  const left = core.slice(0, 1);
33815
34281
  const right = core.slice(-1);
33816
34282
  const isSlashPair = (l, r) => l === "/" && r === "/" || l === "\\" && r === "\\" || l === "/" && r === "\\" || l === "\\" && r === "/";
33817
- if (core.length >= 2 && isSlashPair(left, right)) {
33818
- break;
34283
+ const isParallelogramShape = core.length >= 2 && isSlashPair(left, right);
34284
+ let replaced = inner.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
34285
+ if (isParallelogramShape) {
34286
+ replaced = replaced.replace(/"/g, "&quot;");
33819
34287
  }
33820
- const replaced = inner.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
33821
34288
  if (replaced !== inner) {
33822
34289
  edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
33823
34290
  patchedLines.add(e.line);
@@ -43937,7 +44404,7 @@ ${baseGroup}
43937
44404
  return out;
43938
44405
  }
43939
44406
  htmlDecode(s) {
43940
- return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&#39;/g, "'");
44407
+ return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&#96;/g, "`").replace(/&#123;/g, "{").replace(/&#125;/g, "}").replace(/&#40;/g, "(").replace(/&#41;/g, ")");
43941
44408
  }
43942
44409
  generateEdge(edge, padX, padY, nodeMap) {
43943
44410
  if (!edge.points || edge.points.length < 2) {
@@ -48656,10 +49123,11 @@ import { EventEmitter as EventEmitter3 } from "events";
48656
49123
  import { existsSync as existsSync5 } from "fs";
48657
49124
  import { readFile, stat } from "fs/promises";
48658
49125
  import { resolve as resolve3, isAbsolute, dirname as dirname4 } from "path";
48659
- var MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
49126
+ var import_dotenv2, MAX_TOOL_ITERATIONS, MAX_HISTORY_MESSAGES, SUPPORTED_IMAGE_EXTENSIONS, MAX_IMAGE_FILE_SIZE, ProbeAgent;
48660
49127
  var init_ProbeAgent = __esm({
48661
49128
  "src/agent/ProbeAgent.js"() {
48662
49129
  "use strict";
49130
+ import_dotenv2 = __toESM(require_main(), 1);
48663
49131
  init_tokenCounter();
48664
49132
  init_InMemoryStorageAdapter();
48665
49133
  init_HookManager();
@@ -48671,6 +49139,7 @@ var init_ProbeAgent = __esm({
48671
49139
  init_schemaUtils();
48672
49140
  init_xmlParsingUtils();
48673
49141
  init_mcp();
49142
+ import_dotenv2.default.config();
48674
49143
  MAX_TOOL_ITERATIONS = parseInt(process.env.MAX_TOOL_ITERATIONS || "30", 10);
48675
49144
  MAX_HISTORY_MESSAGES = 100;
48676
49145
  SUPPORTED_IMAGE_EXTENSIONS = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
@@ -50576,6 +51045,7 @@ Convert your previous response content into actual JSON data that follows this s
50576
51045
  });
50577
51046
 
50578
51047
  // src/agent/index.js
51048
+ var import_dotenv3 = __toESM(require_main(), 1);
50579
51049
  init_ProbeAgent();
50580
51050
  init_simpleTelemetry();
50581
51051
  init_schemaUtils();
@@ -51258,6 +51728,7 @@ var ACPServer = class {
51258
51728
  import { randomUUID as randomUUID6 } from "crypto";
51259
51729
 
51260
51730
  // src/agent/index.js
51731
+ import_dotenv3.default.config();
51261
51732
  function readInputContent(input) {
51262
51733
  if (!input) return null;
51263
51734
  try {