@probelabs/probe 0.6.0-rc126 → 0.6.0-rc127

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/cjs/index.cjs CHANGED
@@ -53934,7 +53934,6 @@ var init_parser2 = __esm({
53934
53934
  this.linkStyleStatement = this.RULE("linkStyleStatement", () => {
53935
53935
  this.CONSUME(LinkStyleKeyword);
53936
53936
  this.SUBRULE(this.linkStyleIndexList);
53937
- this.OPTION1(() => this.CONSUME1(Newline));
53938
53937
  this.SUBRULE(this.linkStylePairs);
53939
53938
  this.OPTION2(() => this.CONSUME2(Newline));
53940
53939
  });
@@ -54398,7 +54397,7 @@ var init_semantics = __esm({
54398
54397
  }
54399
54398
  const fnTok = ch.fn?.[0];
54400
54399
  if (!fnTok) {
54401
- this.ctx.errors.push({ line: modeTok2?.startLine ?? 1, column: modeTok2?.startColumn ?? 1, severity: "error", code: "FL-CLICK-CALL-NAME-MISSING", message: "'click \u2026 call' requires a function name.", hint: 'Example: click A call doThing() "Tooltip"' });
54400
+ this.ctx.errors.push({ line: modeTok2?.startLine ?? 1, column: modeTok2?.startColumn ?? 1, severity: "error", code: "FL-CLICK-CALL-NAME-MISSING", message: "'click \u2026 call' requires a function name.", hint: "Example: click A call doThing()" });
54402
54401
  }
54403
54402
  const tipTok = ch.tooltip?.[0];
54404
54403
  if (tipTok) {
@@ -54455,7 +54454,7 @@ var init_semantics = __esm({
54455
54454
  severity: "error",
54456
54455
  code: "FL-CLICK-CALL-NAME-MISSING",
54457
54456
  message: "'click \u2026 call' requires a function name.",
54458
- hint: 'Example: click A call doThing() "Tooltip"'
54457
+ hint: "Example: click A call doThing()"
54459
54458
  });
54460
54459
  }
54461
54460
  return;
@@ -54536,6 +54535,8 @@ var init_semantics = __esm({
54536
54535
  const linksHere = Array.isArray(ctx.link) ? ctx.link.length : 0;
54537
54536
  if (linksHere > 0)
54538
54537
  this.edgeCount += linksHere;
54538
+ if (ctx.link)
54539
+ ctx.link.forEach((ln) => this.visit(ln));
54539
54540
  }
54540
54541
  // Edge attribute object statements must target a known edge id
54541
54542
  // Edge attribute statements are parsed as nodeStatements with a typed attrObject and no links.
@@ -54595,7 +54596,7 @@ var init_semantics = __esm({
54595
54596
  severity: "error",
54596
54597
  code: "FL-TYPED-SHAPE-UNKNOWN",
54597
54598
  message: `Unknown shape '${v3}' in '@{ shape: \u2026 }'.`,
54598
- hint: "Use one of: rect, round, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, lean-l, lean-r, icon, image"
54599
+ hint: 'Use one of: rect, rounded, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, "lean-l", "lean-r", icon, image'
54599
54600
  });
54600
54601
  } else {
54601
54602
  const supportedByCli = /* @__PURE__ */ new Set(["rect", "round", "rounded", "diamond", "circle", "cylinder", "stadium", "subroutine", "lean-l", "lean-r"]);
@@ -54797,8 +54798,8 @@ var init_semantics = __esm({
54797
54798
  column: t3.startColumn ?? 1,
54798
54799
  severity: "error",
54799
54800
  code: "FL-LABEL-PARENS-UNQUOTED",
54800
- message: "Parentheses inside an unquoted label are not supported by Mermaid. Wrap the label in quotes.",
54801
- hint: 'Example: A["Calls func(arg)"]'
54801
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
54802
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and )'
54802
54803
  });
54803
54804
  }
54804
54805
  }
@@ -54846,6 +54847,29 @@ var init_semantics = __esm({
54846
54847
  }
54847
54848
  }
54848
54849
  }
54850
+ // Validate link specifics that Mermaid CLI enforces but our grammar may parse loosely
54851
+ link(ctx) {
54852
+ const inline = ctx.linkTextInline?.[0];
54853
+ if (inline) {
54854
+ const ch = inline.children || {};
54855
+ const parts = [].concat(ch.Identifier || []).concat(ch.Text || []).concat(ch.NumberLiteral || []).concat(ch.Pipe || []);
54856
+ if (parts.length) {
54857
+ const raw = parts.map((t3) => String(t3.image || "")).join("").trim();
54858
+ if (raw === "x" || raw === "o") {
54859
+ const p3 = parts[0];
54860
+ this.ctx.errors.push({
54861
+ line: p3.startLine ?? 1,
54862
+ column: p3.startColumn ?? 1,
54863
+ severity: "error",
54864
+ code: "FL-LINK-UNSUPPORTED-MARKER",
54865
+ message: `Unsupported one-sided link marker '${raw}'. Use symmetric '${raw}--${raw}' or a plain arrow with a label.`,
54866
+ hint: raw === "x" ? "Example: A x--x B (or) A --> B and label it: A --|Skipped|--> B" : "Example: A o--o B (or) A --> B",
54867
+ length: p3.image?.length ?? 1
54868
+ });
54869
+ }
54870
+ }
54871
+ }
54872
+ }
54849
54873
  checkBackticksInContent(contentNodes) {
54850
54874
  if (!contentNodes)
54851
54875
  return;
@@ -55197,6 +55221,31 @@ function mapFlowchartParserError(err, text) {
55197
55221
  }
55198
55222
  }
55199
55223
  }
55224
+ if (isInRule(err, "linkStylePairs") && tokType === "Newline") {
55225
+ const nextLine = Math.min(allLines.length, line + 1);
55226
+ const nxt = allLines[nextLine - 1] || "";
55227
+ const first2 = (nxt.match(/\S/) || { index: 0 }).index || 0;
55228
+ return {
55229
+ line: nextLine,
55230
+ column: Math.max(1, first2 + 1),
55231
+ severity: "error",
55232
+ code: "FL-LINKSTYLE-MULTILINE",
55233
+ message: "'linkStyle' styles must be on the same line as the indices.",
55234
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55235
+ length: 1
55236
+ };
55237
+ }
55238
+ if ((isInRule(err, "linkStyleIndexList") || isInRule(err, "linkStyleStatement")) && tokType === "Colon") {
55239
+ return {
55240
+ line,
55241
+ column,
55242
+ severity: "error",
55243
+ code: "FL-LINKSTYLE-RANGE-NOT-SUPPORTED",
55244
+ message: "Ranges in 'linkStyle' indices are not supported. Use comma-separated indices.",
55245
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55246
+ length: len
55247
+ };
55248
+ }
55200
55249
  if (tokType === "QuotedString") {
55201
55250
  const context = err?.context;
55202
55251
  const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
@@ -55243,6 +55292,17 @@ function mapFlowchartParserError(err, text) {
55243
55292
  }
55244
55293
  if (isInRule(err, "nodeShape") && err.name === "MismatchedTokenException") {
55245
55294
  if (expecting(err, "SquareClose")) {
55295
+ if (tokType === "RoundOpen" || tokType === "RoundClose") {
55296
+ return {
55297
+ line,
55298
+ column,
55299
+ severity: "error",
55300
+ code: "FL-LABEL-PARENS-UNQUOTED",
55301
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
55302
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
55303
+ length: len
55304
+ };
55305
+ }
55246
55306
  if (tokType === "QuotedString") {
55247
55307
  return {
55248
55308
  line,
@@ -55738,6 +55798,32 @@ ${br.example}`,
55738
55798
  break;
55739
55799
  }
55740
55800
  }
55801
+ if (blk.label === "box" && openIdx !== -1) {
55802
+ let endIdx = -1;
55803
+ for (let i3 = openIdx + 1; i3 < lines2.length; i3++) {
55804
+ const raw = lines2[i3] || "";
55805
+ const ind = raw.match(/^(\s*)/)?.[1] || "";
55806
+ if (/^\s*end\s*$/.test(raw) && ind.length <= openIndent.length) {
55807
+ endIdx = i3;
55808
+ break;
55809
+ }
55810
+ }
55811
+ if (endIdx !== -1) {
55812
+ const body = lines2.slice(openIdx + 1, endIdx).map((s3) => (s3 || "").trim());
55813
+ const hasMsgWithActivation = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
55814
+ if (hasMsgWithActivation) {
55815
+ return {
55816
+ line: openIdx + 1,
55817
+ column: 1,
55818
+ severity: "error",
55819
+ code: "SE-BOX-EMPTY",
55820
+ message: "Box block has no participant/actor declarations. Use 'rect' to group messages visually.",
55821
+ hint: "Replace 'box' with 'rect' if you want to group messages:\nrect rgb(240, 240, 255)\n A->>B: Message\n Note over A: Info\nend",
55822
+ length: 3
55823
+ };
55824
+ }
55825
+ }
55826
+ }
55741
55827
  let caretLine = line;
55742
55828
  if (openIdx !== -1) {
55743
55829
  caretLine = lines2.length;
@@ -57077,7 +57163,7 @@ var init_validate3 = __esm({
57077
57163
  function tokenize4(text) {
57078
57164
  return ClassLexer.tokenize(text);
57079
57165
  }
57080
- var Identifier3, NumberLiteral4, ClassDiagramKeyword, DirectionKw, Direction2, ClassKw, AsKw, NoteKw, ForKw, RelCompToAgg, RelAggToComp, RelCompBoth, RelAggBoth, LollipopLeft, LollipopRight, RelExtends, RelComposition, RelAggregation, RelDependency, RelRealization, RelAssociation, RelDependencyLeft, RelRealizationLeft, RelExtendsRight, InvalidRelArrow, LCurly, RCurly, LParen2, RParen2, Colon4, Comma3, Visibility, LTlt, GTgt, GenericAngle, QuotedString4, BacktickName, SquareOpen2, SquareClose2, Comment4, WhiteSpace4, Newline4, allTokens4, ClassLexer;
57166
+ var Identifier3, NumberLiteral4, ClassDiagramKeyword, DirectionKw, Direction2, TitleKw, NamespaceKw, ClassKw, InterfaceKw, AsKw, NoteKw, ForKw, RelCompToAgg, RelAggToComp, RelCompBoth, RelAggBoth, LollipopLeft, LollipopRight, RelExtends, RelComposition, RelAggregation, RelDependency, RelRealization, RelAssociation, RelDependencyLeft, RelRealizationLeft, RelExtendsRight, InvalidRelArrow, LCurly, RCurly, LParen2, RParen2, Colon4, Comma3, Visibility, LTlt, GTgt, GenericAngle, QuotedString4, BacktickName, SquareOpen2, SquareClose2, Comment4, WhiteSpace4, Newline4, allTokens4, ClassLexer;
57081
57167
  var init_lexer5 = __esm({
57082
57168
  "node_modules/@probelabs/maid/out/diagrams/class/lexer.js"() {
57083
57169
  init_api5();
@@ -57086,7 +57172,10 @@ var init_lexer5 = __esm({
57086
57172
  ClassDiagramKeyword = createToken({ name: "ClassDiagramKeyword", pattern: /classDiagram/, longer_alt: Identifier3 });
57087
57173
  DirectionKw = createToken({ name: "DirectionKw", pattern: /direction/, longer_alt: Identifier3 });
57088
57174
  Direction2 = createToken({ name: "Direction", pattern: /LR|RL|TB|BT|TD/, longer_alt: Identifier3 });
57175
+ TitleKw = createToken({ name: "TitleKw", pattern: /title/, longer_alt: Identifier3 });
57176
+ NamespaceKw = createToken({ name: "NamespaceKw", pattern: /namespace/, longer_alt: Identifier3 });
57089
57177
  ClassKw = createToken({ name: "ClassKw", pattern: /class/, longer_alt: Identifier3 });
57178
+ InterfaceKw = createToken({ name: "InterfaceKw", pattern: /interface\b/, longer_alt: Identifier3 });
57090
57179
  AsKw = createToken({ name: "AsKw", pattern: /as/, longer_alt: Identifier3 });
57091
57180
  NoteKw = createToken({ name: "NoteKw", pattern: /note/, longer_alt: Identifier3 });
57092
57181
  ForKw = createToken({ name: "ForKw", pattern: /for/, longer_alt: Identifier3 });
@@ -57129,6 +57218,9 @@ var init_lexer5 = __esm({
57129
57218
  // Keywords
57130
57219
  ClassDiagramKeyword,
57131
57220
  DirectionKw,
57221
+ TitleKw,
57222
+ NamespaceKw,
57223
+ InterfaceKw,
57132
57224
  ClassKw,
57133
57225
  AsKw,
57134
57226
  NoteKw,
@@ -57197,8 +57289,11 @@ var init_parser5 = __esm({
57197
57289
  });
57198
57290
  this.statement = this.RULE("statement", () => {
57199
57291
  this.OR([
57292
+ { ALT: () => this.SUBRULE(this.titleStmt) },
57200
57293
  { ALT: () => this.SUBRULE(this.directionStmt) },
57294
+ { ALT: () => this.SUBRULE(this.namespaceStmt) },
57201
57295
  { ALT: () => this.SUBRULE(this.classLine) },
57296
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
57202
57297
  { ALT: () => this.SUBRULE(this.relationStmt) },
57203
57298
  { ALT: () => this.SUBRULE(this.noteStmt) },
57204
57299
  { ALT: () => this.SUBRULE(this.memberAssignStmt) },
@@ -57210,6 +57305,43 @@ var init_parser5 = __esm({
57210
57305
  this.CONSUME(Direction2);
57211
57306
  this.OPTION(() => this.CONSUME(Newline4));
57212
57307
  });
57308
+ this.titleStmt = this.RULE("titleStmt", () => {
57309
+ this.CONSUME(TitleKw);
57310
+ this.OR([
57311
+ { ALT: () => this.CONSUME(QuotedString4) },
57312
+ {
57313
+ ALT: () => {
57314
+ this.AT_LEAST_ONE(() => {
57315
+ this.OR2([
57316
+ { ALT: () => this.CONSUME(Identifier3) },
57317
+ { ALT: () => this.CONSUME(NumberLiteral4) }
57318
+ ]);
57319
+ });
57320
+ }
57321
+ }
57322
+ ]);
57323
+ this.OPTION(() => this.CONSUME(Newline4));
57324
+ });
57325
+ this.namespaceStmt = this.RULE("namespaceStmt", () => {
57326
+ this.CONSUME(NamespaceKw);
57327
+ this.OR([
57328
+ { ALT: () => this.CONSUME(QuotedString4) },
57329
+ { ALT: () => this.CONSUME(Identifier3) }
57330
+ ]);
57331
+ this.CONSUME(LCurly);
57332
+ this.MANY(() => {
57333
+ this.OR2([
57334
+ { ALT: () => this.CONSUME(Newline4) },
57335
+ { ALT: () => this.SUBRULE(this.classLine) },
57336
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
57337
+ { ALT: () => this.SUBRULE(this.relationStmt) },
57338
+ { ALT: () => this.SUBRULE(this.noteStmt) },
57339
+ { ALT: () => this.SUBRULE(this.memberAssignStmt) }
57340
+ ]);
57341
+ });
57342
+ this.CONSUME(RCurly);
57343
+ this.OPTION(() => this.CONSUME2(Newline4));
57344
+ });
57213
57345
  this.classLine = this.RULE("classLine", () => {
57214
57346
  this.CONSUME(ClassKw);
57215
57347
  this.SUBRULE(this.classRef);
@@ -57248,6 +57380,44 @@ var init_parser5 = __esm({
57248
57380
  }
57249
57381
  ]);
57250
57382
  });
57383
+ this.interfaceLine = this.RULE("interfaceLine", () => {
57384
+ this.CONSUME(InterfaceKw);
57385
+ this.SUBRULE(this.classRef);
57386
+ this.OR([
57387
+ {
57388
+ ALT: () => {
57389
+ this.CONSUME(LCurly);
57390
+ this.MANY(() => {
57391
+ this.OR2([
57392
+ { ALT: () => this.CONSUME3(Newline4) },
57393
+ { ALT: () => this.SUBRULE(this.memberLineStmt) }
57394
+ ]);
57395
+ });
57396
+ this.CONSUME(RCurly);
57397
+ this.OPTION(() => this.CONSUME(Newline4));
57398
+ }
57399
+ },
57400
+ {
57401
+ ALT: () => {
57402
+ this.OPTION1(() => {
57403
+ this.CONSUME(SquareOpen2);
57404
+ this.CONSUME(QuotedString4);
57405
+ this.CONSUME(SquareClose2);
57406
+ });
57407
+ this.OPTION2(() => {
57408
+ this.CONSUME(LTlt);
57409
+ this.CONSUME2(Identifier3);
57410
+ this.CONSUME(GTgt);
57411
+ });
57412
+ this.OPTION3(() => {
57413
+ this.CONSUME(AsKw);
57414
+ this.CONSUME3(Identifier3);
57415
+ });
57416
+ this.OPTION4(() => this.CONSUME2(Newline4));
57417
+ }
57418
+ }
57419
+ ]);
57420
+ });
57251
57421
  this.memberAssignStmt = this.RULE("memberAssignStmt", () => {
57252
57422
  this.SUBRULE(this.classRef);
57253
57423
  this.CONSUME(Colon4);
@@ -57417,6 +57587,31 @@ function validateClass(text, _options = {}) {
57417
57587
  length: b3.image?.length ?? 1
57418
57588
  });
57419
57589
  }
57590
+ if (a3.tokenType === NamespaceKw && b3.tokenType === QuotedString4) {
57591
+ errs.push({
57592
+ line: b3.startLine ?? 1,
57593
+ column: b3.startColumn ?? 1,
57594
+ severity: "error",
57595
+ code: "CL-NAMESPACE-NAME-QUOTED",
57596
+ message: "Quoted namespace names are not supported by mermaid.js. Use an unquoted identifier.",
57597
+ hint: 'Change: namespace "ProbeAgent Core" { ... } \u2192 namespace ProbeAgentCore { ... }',
57598
+ length: b3.image?.length ?? 1
57599
+ });
57600
+ }
57601
+ if (a3.tokenType === InterfaceKw) {
57602
+ const prevToken = i3 > 0 ? tokList[i3 - 1] : null;
57603
+ if (!prevToken || prevToken.tokenType !== LTlt) {
57604
+ errs.push({
57605
+ line: a3.startLine ?? 1,
57606
+ column: a3.startColumn ?? 1,
57607
+ severity: "error",
57608
+ code: "CL-INTERFACE-KEYWORD-UNSUPPORTED",
57609
+ message: 'The "interface" keyword is not supported by mermaid.js. Use the <<interface>> annotation instead.',
57610
+ hint: 'Auto-fix converts to "class". Then manually add: <<interface>> ClassName after the class definition',
57611
+ length: a3.image?.length ?? 9
57612
+ });
57613
+ }
57614
+ }
57420
57615
  }
57421
57616
  for (const tk of tokList) {
57422
57617
  if (tk.tokenType === InvalidRelArrow) {
@@ -57473,10 +57668,13 @@ function validateClass(text, _options = {}) {
57473
57668
  const has2 = (code, line) => (prev || []).some((e3) => e3.code === code && e3.line === line && e3.severity === "error");
57474
57669
  const lines = src.split(/\r?\n/);
57475
57670
  const classDeclOpen = [];
57671
+ const namespaceDeclOpen = [];
57476
57672
  for (let i3 = 0; i3 < lines.length; i3++) {
57477
57673
  const raw = lines[i3] || "";
57478
57674
  if (/^\s*class\b.*\{\s*$/.test(raw))
57479
57675
  classDeclOpen.push(i3 + 1);
57676
+ if (/^\s*namespace\b.*\{\s*$/.test(raw))
57677
+ namespaceDeclOpen.push(i3 + 1);
57480
57678
  }
57481
57679
  if (classDeclOpen.length > 0) {
57482
57680
  const hasClose = lines.some((l3) => /\}/.test(l3));
@@ -57485,6 +57683,13 @@ function validateClass(text, _options = {}) {
57485
57683
  errors.push({ line: Math.max(1, lines.length), column: 1, severity: "error", code: "CL-BLOCK-MISSING-RBRACE", message: "Missing '}' to close class block.", hint: "Close the block: class Foo { ... }" });
57486
57684
  }
57487
57685
  }
57686
+ if (namespaceDeclOpen.length > 0) {
57687
+ const hasClose = lines.some((l3) => /\}/.test(l3));
57688
+ if (!hasClose && !has2("CL-NAMESPACE-MISSING-RBRACE", Math.max(1, lines.length))) {
57689
+ const last2 = namespaceDeclOpen[namespaceDeclOpen.length - 1];
57690
+ errors.push({ line: Math.max(1, lines.length), column: 1, severity: "error", code: "CL-NAMESPACE-MISSING-RBRACE", message: "Missing '}' to close namespace block.", hint: 'Close the block: namespace "Name" { ... }' });
57691
+ }
57692
+ }
57488
57693
  return errors;
57489
57694
  }
57490
57695
  });
@@ -58139,6 +58344,10 @@ function computeFixes(text, errors, level = "safe") {
58139
58344
  edits.push(replaceRange(text, at(e3), e3.length ?? 2, "-->"));
58140
58345
  continue;
58141
58346
  }
58347
+ if (is("FL-LINK-UNSUPPORTED-MARKER", e3)) {
58348
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, ""));
58349
+ continue;
58350
+ }
58142
58351
  if (is("FL-EDGE-LABEL-QUOTED", e3)) {
58143
58352
  const lineText = lineTextAt(text, e3.line);
58144
58353
  const col = Math.max(0, e3.column - 1);
@@ -58211,6 +58420,29 @@ function computeFixes(text, errors, level = "safe") {
58211
58420
  }
58212
58421
  continue;
58213
58422
  }
58423
+ if (is("CL-NAMESPACE-NAME-QUOTED", e3)) {
58424
+ const lineText = lineTextAt(text, e3.line);
58425
+ const nsIdx = lineText.indexOf("namespace");
58426
+ const startSearch = nsIdx >= 0 ? nsIdx + 9 : 0;
58427
+ const q1 = lineText.indexOf('"', startSearch);
58428
+ if (q1 !== -1) {
58429
+ const q22 = lineText.indexOf('"', q1 + 1);
58430
+ if (q22 > q1) {
58431
+ const namespaceName = lineText.slice(q1 + 1, q22);
58432
+ const validIdentifier = namespaceName.replace(/[^A-Za-z0-9_]/g, "");
58433
+ edits.push(replaceRange(text, { line: e3.line, column: q1 + 1 }, q22 - q1 + 1, validIdentifier));
58434
+ }
58435
+ }
58436
+ continue;
58437
+ }
58438
+ if (is("CL-INTERFACE-KEYWORD-UNSUPPORTED", e3)) {
58439
+ const lineText = lineTextAt(text, e3.line);
58440
+ const ifIdx = lineText.indexOf("interface");
58441
+ if (ifIdx !== -1) {
58442
+ edits.push(replaceRange(text, { line: e3.line, column: ifIdx + 1 }, 9, "class"));
58443
+ }
58444
+ continue;
58445
+ }
58214
58446
  if (is("FL-LABEL-ESCAPED-QUOTE", e3)) {
58215
58447
  const lineText = lineTextAt(text, e3.line);
58216
58448
  const caret0 = Math.max(0, e3.column - 1);
@@ -58358,6 +58590,42 @@ function computeFixes(text, errors, level = "safe") {
58358
58590
  const msg = e3.message || "";
58359
58591
  const lineText = lineTextAt(text, e3.line);
58360
58592
  const caret0 = Math.max(0, e3.column - 1);
58593
+ {
58594
+ const openIdx = lineText.indexOf("([");
58595
+ if (openIdx !== -1) {
58596
+ const badClose = lineText.indexOf("})", openIdx + 2);
58597
+ if (badClose !== -1) {
58598
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58599
+ patchedLines.add(e3.line);
58600
+ continue;
58601
+ }
58602
+ }
58603
+ }
58604
+ {
58605
+ const openIdx = lineText.indexOf("[(");
58606
+ if (openIdx !== -1) {
58607
+ const closePair = lineText.indexOf("))", openIdx + 2);
58608
+ if (closePair !== -1) {
58609
+ edits.push({ start: { line: e3.line, column: closePair + 2 }, end: { line: e3.line, column: closePair + 3 }, newText: "]" });
58610
+ patchedLines.add(e3.line);
58611
+ continue;
58612
+ }
58613
+ }
58614
+ }
58615
+ {
58616
+ const openPair = lineText.indexOf("([");
58617
+ if (openPair !== -1) {
58618
+ const badClose = lineText.indexOf("})", openPair + 2);
58619
+ if (badClose !== -1) {
58620
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58621
+ continue;
58622
+ }
58623
+ }
58624
+ }
58625
+ if (/\(\[/.test(lineText) && lineText.indexOf("})", Math.max(0, caret0 - 1)) !== -1) {
58626
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, "]"));
58627
+ continue;
58628
+ }
58361
58629
  if (msg.includes("opened '('") && msg.includes("closed with ']'")) {
58362
58630
  const openIdx = lineText.lastIndexOf("(", caret0);
58363
58631
  if (openIdx !== -1) {
@@ -58430,7 +58698,36 @@ function computeFixes(text, errors, level = "safe") {
58430
58698
  const caret0 = Math.max(0, e3.column - 1);
58431
58699
  const msg = e3.message || "";
58432
58700
  const bracketMatch = msg.match(/Unclosed '(.+?)'/);
58433
- const expectedOpener = bracketMatch ? bracketMatch[1] : null;
58701
+ const expectedOpener = bracketMatch ? (bracketMatch[1] || "").trim() : null;
58702
+ if (expectedOpener === "((") {
58703
+ if (level === "all") {
58704
+ const openIdx = lineText.lastIndexOf("((", caret0);
58705
+ if (openIdx !== -1) {
58706
+ const contentStart = openIdx + 2;
58707
+ const picks = [];
58708
+ const pushIdx2 = (i3) => {
58709
+ if (i3 >= 0)
58710
+ picks.push(i3);
58711
+ };
58712
+ pushIdx2(lineText.indexOf("-", contentStart));
58713
+ pushIdx2(lineText.indexOf("=", contentStart));
58714
+ pushIdx2(lineText.indexOf(".", contentStart));
58715
+ pushIdx2(lineText.indexOf("|", contentStart));
58716
+ let insertIdx = picks.length ? Math.min(...picks) : lineText.length;
58717
+ const before = lineText.slice(0, openIdx);
58718
+ const m3 = before.match(/([A-Za-z0-9_]+)\s*$/);
58719
+ const inferred = m3 ? m3[1] : "";
58720
+ if (inferred) {
58721
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: insertIdx + 1 }, newText: inferred + "))" });
58722
+ patchedLines.add(e3.line);
58723
+ continue;
58724
+ }
58725
+ patchedLines.add(e3.line);
58726
+ continue;
58727
+ }
58728
+ }
58729
+ continue;
58730
+ }
58434
58731
  const bracketMap = {
58435
58732
  "[": "]",
58436
58733
  "{": "}",
@@ -58516,6 +58813,14 @@ function computeFixes(text, errors, level = "safe") {
58516
58813
  patchedLines.add(e3.line);
58517
58814
  continue;
58518
58815
  }
58816
+ if (innerSeg.includes("(") || innerSeg.includes(")")) {
58817
+ const replaced = innerSeg.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58818
+ if (replaced !== innerSeg) {
58819
+ edits.push({ start: { line: e3.line, column: opened.idx + opened.len + 1 }, end: { line: e3.line, column: closerIdx + 1 }, newText: replaced });
58820
+ patchedLines.add(e3.line);
58821
+ continue;
58822
+ }
58823
+ }
58519
58824
  }
58520
58825
  }
58521
58826
  if (patchedLines.has(e3.line)) {
@@ -58524,9 +58829,35 @@ function computeFixes(text, errors, level = "safe") {
58524
58829
  let closer = "]";
58525
58830
  if (opened)
58526
58831
  closer = opened.close;
58527
- const avail = lineText.slice(caret0);
58528
- const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58529
- edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58832
+ if (closer === "]") {
58833
+ const openIdxSq = lineText.lastIndexOf("[", caret0);
58834
+ if (openIdxSq !== -1) {
58835
+ const picks = [];
58836
+ const pushIdx2 = (i3) => {
58837
+ if (i3 >= 0)
58838
+ picks.push(i3);
58839
+ };
58840
+ pushIdx2(lineText.indexOf("-", openIdxSq + 1));
58841
+ pushIdx2(lineText.indexOf("=", openIdxSq + 1));
58842
+ pushIdx2(lineText.indexOf(".", openIdxSq + 1));
58843
+ pushIdx2(lineText.indexOf("|", openIdxSq + 1));
58844
+ let ins = picks.length ? Math.min(...picks) : lineText.length;
58845
+ let tl = ins - 1;
58846
+ while (tl >= 0 && /\s/.test(lineText[tl]))
58847
+ tl--;
58848
+ const startCol2 = tl + 1 + 1;
58849
+ const endCol2 = ins + 1;
58850
+ edits.push({ start: { line: e3.line, column: startCol2 }, end: { line: e3.line, column: endCol2 }, newText: closer });
58851
+ } else {
58852
+ const avail = lineText.slice(caret0);
58853
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58854
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58855
+ }
58856
+ } else {
58857
+ const avail = lineText.slice(caret0);
58858
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58859
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58860
+ }
58530
58861
  }
58531
58862
  continue;
58532
58863
  }
@@ -58658,9 +58989,11 @@ function computeFixes(text, errors, level = "safe") {
58658
58989
  if (core.length >= 2 && isSlashPair(left, right)) {
58659
58990
  break;
58660
58991
  }
58661
- const newInner = '"' + inner + '"';
58662
- edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: newInner });
58663
- patchedLines.add(e3.line);
58992
+ const replaced = inner.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58993
+ if (replaced !== inner) {
58994
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: replaced });
58995
+ patchedLines.add(e3.line);
58996
+ }
58664
58997
  break;
58665
58998
  }
58666
58999
  searchStart = openIdx + 1;
@@ -58817,14 +59150,33 @@ function computeFixes(text, errors, level = "safe") {
58817
59150
  continue;
58818
59151
  }
58819
59152
  if (is("SE-BOX-EMPTY", e3)) {
58820
- const lines = text.split(/\r?\n/);
58821
- const boxIdx = Math.max(0, e3.line - 1);
58822
- const boxLine = lines[boxIdx] || "";
58823
- const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
58824
- if (labelMatch) {
58825
- const indent = boxLine.match(/^\s*/)?.[0] || "";
58826
- const newLine = `${indent}rect rgb(240, 240, 255)`;
58827
- edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
59153
+ if (level === "all") {
59154
+ const lines = text.split(/\r?\n/);
59155
+ const boxIdx = Math.max(0, e3.line - 1);
59156
+ const boxLine = lines[boxIdx] || "";
59157
+ const openIndent = (boxLine.match(/^(\s*)/)?.[1] || "").length;
59158
+ let endIdx = -1;
59159
+ for (let i3 = boxIdx + 1; i3 < lines.length; i3++) {
59160
+ const raw = lines[i3] || "";
59161
+ const ind = (raw.match(/^(\s*)/)?.[1] || "").length;
59162
+ if (/^\s*end\s*$/.test(raw) && ind <= openIndent) {
59163
+ endIdx = i3;
59164
+ break;
59165
+ }
59166
+ }
59167
+ let hasMsgWithAct = false;
59168
+ if (endIdx !== -1) {
59169
+ const body = lines.slice(boxIdx + 1, endIdx).map((s3) => (s3 || "").trim());
59170
+ hasMsgWithAct = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
59171
+ }
59172
+ if (!hasMsgWithAct) {
59173
+ const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
59174
+ if (labelMatch) {
59175
+ const indent = boxLine.match(/^\s*/)?.[0] || "";
59176
+ const newLine = `${indent}rect rgb(240, 240, 255)`;
59177
+ edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
59178
+ }
59179
+ }
58828
59180
  }
58829
59181
  continue;
58830
59182
  }
@@ -59100,6 +59452,41 @@ ${indent}${tail}` });
59100
59452
  }
59101
59453
  }
59102
59454
  edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
59455
+ `));
59456
+ continue;
59457
+ }
59458
+ if (is("CL-NAMESPACE-MISSING-RBRACE", e3)) {
59459
+ const lines = text.split(/\r?\n/);
59460
+ const curIdx = Math.max(0, e3.line - 1);
59461
+ const openerRe = /^(\s*)namespace\b.*\{\s*$/;
59462
+ let openIdx = -1;
59463
+ let openIndent = "";
59464
+ for (let i3 = curIdx; i3 >= 0; i3--) {
59465
+ const m3 = openerRe.exec(lines[i3] || "");
59466
+ if (m3) {
59467
+ openIdx = i3;
59468
+ openIndent = m3[1] || "";
59469
+ break;
59470
+ }
59471
+ }
59472
+ if (openIdx === -1) {
59473
+ const indent = inferIndentFromLine(lines[curIdx] || "");
59474
+ edits.push(insertAt(text, { line: curIdx + 1, column: 1 }, `${indent}}
59475
+ `));
59476
+ continue;
59477
+ }
59478
+ let insIdx = lines.length;
59479
+ for (let i3 = openIdx + 1; i3 < lines.length; i3++) {
59480
+ const raw = lines[i3] || "";
59481
+ if (raw.trim() === "")
59482
+ continue;
59483
+ const ind = inferIndentFromLine(raw);
59484
+ if (ind.length <= openIndent.length) {
59485
+ insIdx = i3;
59486
+ break;
59487
+ }
59488
+ }
59489
+ edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
59103
59490
  `));
59104
59491
  continue;
59105
59492
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc126",
3
+ "version": "0.6.0-rc127",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -80,7 +80,7 @@
80
80
  "@opentelemetry/sdk-node": "^0.203.0",
81
81
  "@opentelemetry/sdk-trace-base": "^1.30.0",
82
82
  "@opentelemetry/semantic-conventions": "^1.36.0",
83
- "@probelabs/maid": "^0.0.10",
83
+ "@probelabs/maid": "^0.0.13",
84
84
  "ai": "^5.0.0",
85
85
  "axios": "^1.8.3",
86
86
  "fs-extra": "^11.1.1",