@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.
@@ -53754,7 +53754,6 @@ var init_parser2 = __esm({
53754
53754
  this.linkStyleStatement = this.RULE("linkStyleStatement", () => {
53755
53755
  this.CONSUME(LinkStyleKeyword);
53756
53756
  this.SUBRULE(this.linkStyleIndexList);
53757
- this.OPTION1(() => this.CONSUME1(Newline));
53758
53757
  this.SUBRULE(this.linkStylePairs);
53759
53758
  this.OPTION2(() => this.CONSUME2(Newline));
53760
53759
  });
@@ -54218,7 +54217,7 @@ var init_semantics = __esm({
54218
54217
  }
54219
54218
  const fnTok = ch.fn?.[0];
54220
54219
  if (!fnTok) {
54221
- 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"' });
54220
+ 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()" });
54222
54221
  }
54223
54222
  const tipTok = ch.tooltip?.[0];
54224
54223
  if (tipTok) {
@@ -54275,7 +54274,7 @@ var init_semantics = __esm({
54275
54274
  severity: "error",
54276
54275
  code: "FL-CLICK-CALL-NAME-MISSING",
54277
54276
  message: "'click \u2026 call' requires a function name.",
54278
- hint: 'Example: click A call doThing() "Tooltip"'
54277
+ hint: "Example: click A call doThing()"
54279
54278
  });
54280
54279
  }
54281
54280
  return;
@@ -54356,6 +54355,8 @@ var init_semantics = __esm({
54356
54355
  const linksHere = Array.isArray(ctx.link) ? ctx.link.length : 0;
54357
54356
  if (linksHere > 0)
54358
54357
  this.edgeCount += linksHere;
54358
+ if (ctx.link)
54359
+ ctx.link.forEach((ln) => this.visit(ln));
54359
54360
  }
54360
54361
  // Edge attribute object statements must target a known edge id
54361
54362
  // Edge attribute statements are parsed as nodeStatements with a typed attrObject and no links.
@@ -54415,7 +54416,7 @@ var init_semantics = __esm({
54415
54416
  severity: "error",
54416
54417
  code: "FL-TYPED-SHAPE-UNKNOWN",
54417
54418
  message: `Unknown shape '${v3}' in '@{ shape: \u2026 }'.`,
54418
- hint: "Use one of: rect, round, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, lean-l, lean-r, icon, image"
54419
+ hint: 'Use one of: rect, rounded, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, "lean-l", "lean-r", icon, image'
54419
54420
  });
54420
54421
  } else {
54421
54422
  const supportedByCli = /* @__PURE__ */ new Set(["rect", "round", "rounded", "diamond", "circle", "cylinder", "stadium", "subroutine", "lean-l", "lean-r"]);
@@ -54617,8 +54618,8 @@ var init_semantics = __esm({
54617
54618
  column: t3.startColumn ?? 1,
54618
54619
  severity: "error",
54619
54620
  code: "FL-LABEL-PARENS-UNQUOTED",
54620
- message: "Parentheses inside an unquoted label are not supported by Mermaid. Wrap the label in quotes.",
54621
- hint: 'Example: A["Calls func(arg)"]'
54621
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
54622
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and )'
54622
54623
  });
54623
54624
  }
54624
54625
  }
@@ -54666,6 +54667,29 @@ var init_semantics = __esm({
54666
54667
  }
54667
54668
  }
54668
54669
  }
54670
+ // Validate link specifics that Mermaid CLI enforces but our grammar may parse loosely
54671
+ link(ctx) {
54672
+ const inline = ctx.linkTextInline?.[0];
54673
+ if (inline) {
54674
+ const ch = inline.children || {};
54675
+ const parts = [].concat(ch.Identifier || []).concat(ch.Text || []).concat(ch.NumberLiteral || []).concat(ch.Pipe || []);
54676
+ if (parts.length) {
54677
+ const raw = parts.map((t3) => String(t3.image || "")).join("").trim();
54678
+ if (raw === "x" || raw === "o") {
54679
+ const p3 = parts[0];
54680
+ this.ctx.errors.push({
54681
+ line: p3.startLine ?? 1,
54682
+ column: p3.startColumn ?? 1,
54683
+ severity: "error",
54684
+ code: "FL-LINK-UNSUPPORTED-MARKER",
54685
+ message: `Unsupported one-sided link marker '${raw}'. Use symmetric '${raw}--${raw}' or a plain arrow with a label.`,
54686
+ 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",
54687
+ length: p3.image?.length ?? 1
54688
+ });
54689
+ }
54690
+ }
54691
+ }
54692
+ }
54669
54693
  checkBackticksInContent(contentNodes) {
54670
54694
  if (!contentNodes)
54671
54695
  return;
@@ -55017,6 +55041,31 @@ function mapFlowchartParserError(err, text) {
55017
55041
  }
55018
55042
  }
55019
55043
  }
55044
+ if (isInRule(err, "linkStylePairs") && tokType === "Newline") {
55045
+ const nextLine = Math.min(allLines.length, line + 1);
55046
+ const nxt = allLines[nextLine - 1] || "";
55047
+ const first2 = (nxt.match(/\S/) || { index: 0 }).index || 0;
55048
+ return {
55049
+ line: nextLine,
55050
+ column: Math.max(1, first2 + 1),
55051
+ severity: "error",
55052
+ code: "FL-LINKSTYLE-MULTILINE",
55053
+ message: "'linkStyle' styles must be on the same line as the indices.",
55054
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55055
+ length: 1
55056
+ };
55057
+ }
55058
+ if ((isInRule(err, "linkStyleIndexList") || isInRule(err, "linkStyleStatement")) && tokType === "Colon") {
55059
+ return {
55060
+ line,
55061
+ column,
55062
+ severity: "error",
55063
+ code: "FL-LINKSTYLE-RANGE-NOT-SUPPORTED",
55064
+ message: "Ranges in 'linkStyle' indices are not supported. Use comma-separated indices.",
55065
+ hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
55066
+ length: len
55067
+ };
55068
+ }
55020
55069
  if (tokType === "QuotedString") {
55021
55070
  const context = err?.context;
55022
55071
  const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
@@ -55063,6 +55112,17 @@ function mapFlowchartParserError(err, text) {
55063
55112
  }
55064
55113
  if (isInRule(err, "nodeShape") && err.name === "MismatchedTokenException") {
55065
55114
  if (expecting(err, "SquareClose")) {
55115
+ if (tokType === "RoundOpen" || tokType === "RoundClose") {
55116
+ return {
55117
+ line,
55118
+ column,
55119
+ severity: "error",
55120
+ code: "FL-LABEL-PARENS-UNQUOTED",
55121
+ message: "Parentheses inside an unquoted label are not supported by Mermaid.",
55122
+ hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
55123
+ length: len
55124
+ };
55125
+ }
55066
55126
  if (tokType === "QuotedString") {
55067
55127
  return {
55068
55128
  line,
@@ -55558,6 +55618,32 @@ ${br.example}`,
55558
55618
  break;
55559
55619
  }
55560
55620
  }
55621
+ if (blk.label === "box" && openIdx !== -1) {
55622
+ let endIdx = -1;
55623
+ for (let i3 = openIdx + 1; i3 < lines2.length; i3++) {
55624
+ const raw = lines2[i3] || "";
55625
+ const ind = raw.match(/^(\s*)/)?.[1] || "";
55626
+ if (/^\s*end\s*$/.test(raw) && ind.length <= openIndent.length) {
55627
+ endIdx = i3;
55628
+ break;
55629
+ }
55630
+ }
55631
+ if (endIdx !== -1) {
55632
+ const body = lines2.slice(openIdx + 1, endIdx).map((s3) => (s3 || "").trim());
55633
+ const hasMsgWithActivation = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
55634
+ if (hasMsgWithActivation) {
55635
+ return {
55636
+ line: openIdx + 1,
55637
+ column: 1,
55638
+ severity: "error",
55639
+ code: "SE-BOX-EMPTY",
55640
+ message: "Box block has no participant/actor declarations. Use 'rect' to group messages visually.",
55641
+ 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",
55642
+ length: 3
55643
+ };
55644
+ }
55645
+ }
55646
+ }
55561
55647
  let caretLine = line;
55562
55648
  if (openIdx !== -1) {
55563
55649
  caretLine = lines2.length;
@@ -56897,7 +56983,7 @@ var init_validate3 = __esm({
56897
56983
  function tokenize4(text) {
56898
56984
  return ClassLexer.tokenize(text);
56899
56985
  }
56900
- 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;
56986
+ 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;
56901
56987
  var init_lexer5 = __esm({
56902
56988
  "node_modules/@probelabs/maid/out/diagrams/class/lexer.js"() {
56903
56989
  init_api5();
@@ -56906,7 +56992,10 @@ var init_lexer5 = __esm({
56906
56992
  ClassDiagramKeyword = createToken({ name: "ClassDiagramKeyword", pattern: /classDiagram/, longer_alt: Identifier3 });
56907
56993
  DirectionKw = createToken({ name: "DirectionKw", pattern: /direction/, longer_alt: Identifier3 });
56908
56994
  Direction2 = createToken({ name: "Direction", pattern: /LR|RL|TB|BT|TD/, longer_alt: Identifier3 });
56995
+ TitleKw = createToken({ name: "TitleKw", pattern: /title/, longer_alt: Identifier3 });
56996
+ NamespaceKw = createToken({ name: "NamespaceKw", pattern: /namespace/, longer_alt: Identifier3 });
56909
56997
  ClassKw = createToken({ name: "ClassKw", pattern: /class/, longer_alt: Identifier3 });
56998
+ InterfaceKw = createToken({ name: "InterfaceKw", pattern: /interface\b/, longer_alt: Identifier3 });
56910
56999
  AsKw = createToken({ name: "AsKw", pattern: /as/, longer_alt: Identifier3 });
56911
57000
  NoteKw = createToken({ name: "NoteKw", pattern: /note/, longer_alt: Identifier3 });
56912
57001
  ForKw = createToken({ name: "ForKw", pattern: /for/, longer_alt: Identifier3 });
@@ -56949,6 +57038,9 @@ var init_lexer5 = __esm({
56949
57038
  // Keywords
56950
57039
  ClassDiagramKeyword,
56951
57040
  DirectionKw,
57041
+ TitleKw,
57042
+ NamespaceKw,
57043
+ InterfaceKw,
56952
57044
  ClassKw,
56953
57045
  AsKw,
56954
57046
  NoteKw,
@@ -57017,8 +57109,11 @@ var init_parser5 = __esm({
57017
57109
  });
57018
57110
  this.statement = this.RULE("statement", () => {
57019
57111
  this.OR([
57112
+ { ALT: () => this.SUBRULE(this.titleStmt) },
57020
57113
  { ALT: () => this.SUBRULE(this.directionStmt) },
57114
+ { ALT: () => this.SUBRULE(this.namespaceStmt) },
57021
57115
  { ALT: () => this.SUBRULE(this.classLine) },
57116
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
57022
57117
  { ALT: () => this.SUBRULE(this.relationStmt) },
57023
57118
  { ALT: () => this.SUBRULE(this.noteStmt) },
57024
57119
  { ALT: () => this.SUBRULE(this.memberAssignStmt) },
@@ -57030,6 +57125,43 @@ var init_parser5 = __esm({
57030
57125
  this.CONSUME(Direction2);
57031
57126
  this.OPTION(() => this.CONSUME(Newline4));
57032
57127
  });
57128
+ this.titleStmt = this.RULE("titleStmt", () => {
57129
+ this.CONSUME(TitleKw);
57130
+ this.OR([
57131
+ { ALT: () => this.CONSUME(QuotedString4) },
57132
+ {
57133
+ ALT: () => {
57134
+ this.AT_LEAST_ONE(() => {
57135
+ this.OR2([
57136
+ { ALT: () => this.CONSUME(Identifier3) },
57137
+ { ALT: () => this.CONSUME(NumberLiteral4) }
57138
+ ]);
57139
+ });
57140
+ }
57141
+ }
57142
+ ]);
57143
+ this.OPTION(() => this.CONSUME(Newline4));
57144
+ });
57145
+ this.namespaceStmt = this.RULE("namespaceStmt", () => {
57146
+ this.CONSUME(NamespaceKw);
57147
+ this.OR([
57148
+ { ALT: () => this.CONSUME(QuotedString4) },
57149
+ { ALT: () => this.CONSUME(Identifier3) }
57150
+ ]);
57151
+ this.CONSUME(LCurly);
57152
+ this.MANY(() => {
57153
+ this.OR2([
57154
+ { ALT: () => this.CONSUME(Newline4) },
57155
+ { ALT: () => this.SUBRULE(this.classLine) },
57156
+ { ALT: () => this.SUBRULE(this.interfaceLine) },
57157
+ { ALT: () => this.SUBRULE(this.relationStmt) },
57158
+ { ALT: () => this.SUBRULE(this.noteStmt) },
57159
+ { ALT: () => this.SUBRULE(this.memberAssignStmt) }
57160
+ ]);
57161
+ });
57162
+ this.CONSUME(RCurly);
57163
+ this.OPTION(() => this.CONSUME2(Newline4));
57164
+ });
57033
57165
  this.classLine = this.RULE("classLine", () => {
57034
57166
  this.CONSUME(ClassKw);
57035
57167
  this.SUBRULE(this.classRef);
@@ -57068,6 +57200,44 @@ var init_parser5 = __esm({
57068
57200
  }
57069
57201
  ]);
57070
57202
  });
57203
+ this.interfaceLine = this.RULE("interfaceLine", () => {
57204
+ this.CONSUME(InterfaceKw);
57205
+ this.SUBRULE(this.classRef);
57206
+ this.OR([
57207
+ {
57208
+ ALT: () => {
57209
+ this.CONSUME(LCurly);
57210
+ this.MANY(() => {
57211
+ this.OR2([
57212
+ { ALT: () => this.CONSUME3(Newline4) },
57213
+ { ALT: () => this.SUBRULE(this.memberLineStmt) }
57214
+ ]);
57215
+ });
57216
+ this.CONSUME(RCurly);
57217
+ this.OPTION(() => this.CONSUME(Newline4));
57218
+ }
57219
+ },
57220
+ {
57221
+ ALT: () => {
57222
+ this.OPTION1(() => {
57223
+ this.CONSUME(SquareOpen2);
57224
+ this.CONSUME(QuotedString4);
57225
+ this.CONSUME(SquareClose2);
57226
+ });
57227
+ this.OPTION2(() => {
57228
+ this.CONSUME(LTlt);
57229
+ this.CONSUME2(Identifier3);
57230
+ this.CONSUME(GTgt);
57231
+ });
57232
+ this.OPTION3(() => {
57233
+ this.CONSUME(AsKw);
57234
+ this.CONSUME3(Identifier3);
57235
+ });
57236
+ this.OPTION4(() => this.CONSUME2(Newline4));
57237
+ }
57238
+ }
57239
+ ]);
57240
+ });
57071
57241
  this.memberAssignStmt = this.RULE("memberAssignStmt", () => {
57072
57242
  this.SUBRULE(this.classRef);
57073
57243
  this.CONSUME(Colon4);
@@ -57237,6 +57407,31 @@ function validateClass(text, _options = {}) {
57237
57407
  length: b3.image?.length ?? 1
57238
57408
  });
57239
57409
  }
57410
+ if (a3.tokenType === NamespaceKw && b3.tokenType === QuotedString4) {
57411
+ errs.push({
57412
+ line: b3.startLine ?? 1,
57413
+ column: b3.startColumn ?? 1,
57414
+ severity: "error",
57415
+ code: "CL-NAMESPACE-NAME-QUOTED",
57416
+ message: "Quoted namespace names are not supported by mermaid.js. Use an unquoted identifier.",
57417
+ hint: 'Change: namespace "ProbeAgent Core" { ... } \u2192 namespace ProbeAgentCore { ... }',
57418
+ length: b3.image?.length ?? 1
57419
+ });
57420
+ }
57421
+ if (a3.tokenType === InterfaceKw) {
57422
+ const prevToken = i3 > 0 ? tokList[i3 - 1] : null;
57423
+ if (!prevToken || prevToken.tokenType !== LTlt) {
57424
+ errs.push({
57425
+ line: a3.startLine ?? 1,
57426
+ column: a3.startColumn ?? 1,
57427
+ severity: "error",
57428
+ code: "CL-INTERFACE-KEYWORD-UNSUPPORTED",
57429
+ message: 'The "interface" keyword is not supported by mermaid.js. Use the <<interface>> annotation instead.',
57430
+ hint: 'Auto-fix converts to "class". Then manually add: <<interface>> ClassName after the class definition',
57431
+ length: a3.image?.length ?? 9
57432
+ });
57433
+ }
57434
+ }
57240
57435
  }
57241
57436
  for (const tk of tokList) {
57242
57437
  if (tk.tokenType === InvalidRelArrow) {
@@ -57293,10 +57488,13 @@ function validateClass(text, _options = {}) {
57293
57488
  const has2 = (code, line) => (prev || []).some((e3) => e3.code === code && e3.line === line && e3.severity === "error");
57294
57489
  const lines = src.split(/\r?\n/);
57295
57490
  const classDeclOpen = [];
57491
+ const namespaceDeclOpen = [];
57296
57492
  for (let i3 = 0; i3 < lines.length; i3++) {
57297
57493
  const raw = lines[i3] || "";
57298
57494
  if (/^\s*class\b.*\{\s*$/.test(raw))
57299
57495
  classDeclOpen.push(i3 + 1);
57496
+ if (/^\s*namespace\b.*\{\s*$/.test(raw))
57497
+ namespaceDeclOpen.push(i3 + 1);
57300
57498
  }
57301
57499
  if (classDeclOpen.length > 0) {
57302
57500
  const hasClose = lines.some((l3) => /\}/.test(l3));
@@ -57305,6 +57503,13 @@ function validateClass(text, _options = {}) {
57305
57503
  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 { ... }" });
57306
57504
  }
57307
57505
  }
57506
+ if (namespaceDeclOpen.length > 0) {
57507
+ const hasClose = lines.some((l3) => /\}/.test(l3));
57508
+ if (!hasClose && !has2("CL-NAMESPACE-MISSING-RBRACE", Math.max(1, lines.length))) {
57509
+ const last2 = namespaceDeclOpen[namespaceDeclOpen.length - 1];
57510
+ 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" { ... }' });
57511
+ }
57512
+ }
57308
57513
  return errors;
57309
57514
  }
57310
57515
  });
@@ -57959,6 +58164,10 @@ function computeFixes(text, errors, level = "safe") {
57959
58164
  edits.push(replaceRange(text, at(e3), e3.length ?? 2, "-->"));
57960
58165
  continue;
57961
58166
  }
58167
+ if (is("FL-LINK-UNSUPPORTED-MARKER", e3)) {
58168
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, ""));
58169
+ continue;
58170
+ }
57962
58171
  if (is("FL-EDGE-LABEL-QUOTED", e3)) {
57963
58172
  const lineText = lineTextAt(text, e3.line);
57964
58173
  const col = Math.max(0, e3.column - 1);
@@ -58031,6 +58240,29 @@ function computeFixes(text, errors, level = "safe") {
58031
58240
  }
58032
58241
  continue;
58033
58242
  }
58243
+ if (is("CL-NAMESPACE-NAME-QUOTED", e3)) {
58244
+ const lineText = lineTextAt(text, e3.line);
58245
+ const nsIdx = lineText.indexOf("namespace");
58246
+ const startSearch = nsIdx >= 0 ? nsIdx + 9 : 0;
58247
+ const q1 = lineText.indexOf('"', startSearch);
58248
+ if (q1 !== -1) {
58249
+ const q22 = lineText.indexOf('"', q1 + 1);
58250
+ if (q22 > q1) {
58251
+ const namespaceName = lineText.slice(q1 + 1, q22);
58252
+ const validIdentifier = namespaceName.replace(/[^A-Za-z0-9_]/g, "");
58253
+ edits.push(replaceRange(text, { line: e3.line, column: q1 + 1 }, q22 - q1 + 1, validIdentifier));
58254
+ }
58255
+ }
58256
+ continue;
58257
+ }
58258
+ if (is("CL-INTERFACE-KEYWORD-UNSUPPORTED", e3)) {
58259
+ const lineText = lineTextAt(text, e3.line);
58260
+ const ifIdx = lineText.indexOf("interface");
58261
+ if (ifIdx !== -1) {
58262
+ edits.push(replaceRange(text, { line: e3.line, column: ifIdx + 1 }, 9, "class"));
58263
+ }
58264
+ continue;
58265
+ }
58034
58266
  if (is("FL-LABEL-ESCAPED-QUOTE", e3)) {
58035
58267
  const lineText = lineTextAt(text, e3.line);
58036
58268
  const caret0 = Math.max(0, e3.column - 1);
@@ -58178,6 +58410,42 @@ function computeFixes(text, errors, level = "safe") {
58178
58410
  const msg = e3.message || "";
58179
58411
  const lineText = lineTextAt(text, e3.line);
58180
58412
  const caret0 = Math.max(0, e3.column - 1);
58413
+ {
58414
+ const openIdx = lineText.indexOf("([");
58415
+ if (openIdx !== -1) {
58416
+ const badClose = lineText.indexOf("})", openIdx + 2);
58417
+ if (badClose !== -1) {
58418
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58419
+ patchedLines.add(e3.line);
58420
+ continue;
58421
+ }
58422
+ }
58423
+ }
58424
+ {
58425
+ const openIdx = lineText.indexOf("[(");
58426
+ if (openIdx !== -1) {
58427
+ const closePair = lineText.indexOf("))", openIdx + 2);
58428
+ if (closePair !== -1) {
58429
+ edits.push({ start: { line: e3.line, column: closePair + 2 }, end: { line: e3.line, column: closePair + 3 }, newText: "]" });
58430
+ patchedLines.add(e3.line);
58431
+ continue;
58432
+ }
58433
+ }
58434
+ }
58435
+ {
58436
+ const openPair = lineText.indexOf("([");
58437
+ if (openPair !== -1) {
58438
+ const badClose = lineText.indexOf("})", openPair + 2);
58439
+ if (badClose !== -1) {
58440
+ edits.push({ start: { line: e3.line, column: badClose + 1 }, end: { line: e3.line, column: badClose + 2 }, newText: "]" });
58441
+ continue;
58442
+ }
58443
+ }
58444
+ }
58445
+ if (/\(\[/.test(lineText) && lineText.indexOf("})", Math.max(0, caret0 - 1)) !== -1) {
58446
+ edits.push(replaceRange(text, at(e3), e3.length ?? 1, "]"));
58447
+ continue;
58448
+ }
58181
58449
  if (msg.includes("opened '('") && msg.includes("closed with ']'")) {
58182
58450
  const openIdx = lineText.lastIndexOf("(", caret0);
58183
58451
  if (openIdx !== -1) {
@@ -58250,7 +58518,36 @@ function computeFixes(text, errors, level = "safe") {
58250
58518
  const caret0 = Math.max(0, e3.column - 1);
58251
58519
  const msg = e3.message || "";
58252
58520
  const bracketMatch = msg.match(/Unclosed '(.+?)'/);
58253
- const expectedOpener = bracketMatch ? bracketMatch[1] : null;
58521
+ const expectedOpener = bracketMatch ? (bracketMatch[1] || "").trim() : null;
58522
+ if (expectedOpener === "((") {
58523
+ if (level === "all") {
58524
+ const openIdx = lineText.lastIndexOf("((", caret0);
58525
+ if (openIdx !== -1) {
58526
+ const contentStart = openIdx + 2;
58527
+ const picks = [];
58528
+ const pushIdx2 = (i3) => {
58529
+ if (i3 >= 0)
58530
+ picks.push(i3);
58531
+ };
58532
+ pushIdx2(lineText.indexOf("-", contentStart));
58533
+ pushIdx2(lineText.indexOf("=", contentStart));
58534
+ pushIdx2(lineText.indexOf(".", contentStart));
58535
+ pushIdx2(lineText.indexOf("|", contentStart));
58536
+ let insertIdx = picks.length ? Math.min(...picks) : lineText.length;
58537
+ const before = lineText.slice(0, openIdx);
58538
+ const m3 = before.match(/([A-Za-z0-9_]+)\s*$/);
58539
+ const inferred = m3 ? m3[1] : "";
58540
+ if (inferred) {
58541
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: insertIdx + 1 }, newText: inferred + "))" });
58542
+ patchedLines.add(e3.line);
58543
+ continue;
58544
+ }
58545
+ patchedLines.add(e3.line);
58546
+ continue;
58547
+ }
58548
+ }
58549
+ continue;
58550
+ }
58254
58551
  const bracketMap = {
58255
58552
  "[": "]",
58256
58553
  "{": "}",
@@ -58336,6 +58633,14 @@ function computeFixes(text, errors, level = "safe") {
58336
58633
  patchedLines.add(e3.line);
58337
58634
  continue;
58338
58635
  }
58636
+ if (innerSeg.includes("(") || innerSeg.includes(")")) {
58637
+ const replaced = innerSeg.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58638
+ if (replaced !== innerSeg) {
58639
+ edits.push({ start: { line: e3.line, column: opened.idx + opened.len + 1 }, end: { line: e3.line, column: closerIdx + 1 }, newText: replaced });
58640
+ patchedLines.add(e3.line);
58641
+ continue;
58642
+ }
58643
+ }
58339
58644
  }
58340
58645
  }
58341
58646
  if (patchedLines.has(e3.line)) {
@@ -58344,9 +58649,35 @@ function computeFixes(text, errors, level = "safe") {
58344
58649
  let closer = "]";
58345
58650
  if (opened)
58346
58651
  closer = opened.close;
58347
- const avail = lineText.slice(caret0);
58348
- const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58349
- edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58652
+ if (closer === "]") {
58653
+ const openIdxSq = lineText.lastIndexOf("[", caret0);
58654
+ if (openIdxSq !== -1) {
58655
+ const picks = [];
58656
+ const pushIdx2 = (i3) => {
58657
+ if (i3 >= 0)
58658
+ picks.push(i3);
58659
+ };
58660
+ pushIdx2(lineText.indexOf("-", openIdxSq + 1));
58661
+ pushIdx2(lineText.indexOf("=", openIdxSq + 1));
58662
+ pushIdx2(lineText.indexOf(".", openIdxSq + 1));
58663
+ pushIdx2(lineText.indexOf("|", openIdxSq + 1));
58664
+ let ins = picks.length ? Math.min(...picks) : lineText.length;
58665
+ let tl = ins - 1;
58666
+ while (tl >= 0 && /\s/.test(lineText[tl]))
58667
+ tl--;
58668
+ const startCol2 = tl + 1 + 1;
58669
+ const endCol2 = ins + 1;
58670
+ edits.push({ start: { line: e3.line, column: startCol2 }, end: { line: e3.line, column: endCol2 }, newText: closer });
58671
+ } else {
58672
+ const avail = lineText.slice(caret0);
58673
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58674
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58675
+ }
58676
+ } else {
58677
+ const avail = lineText.slice(caret0);
58678
+ const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
58679
+ edits.push({ start: { line: e3.line, column: caret0 + 1 }, end: { line: e3.line, column: caret0 + 1 + replaceLen }, newText: closer });
58680
+ }
58350
58681
  }
58351
58682
  continue;
58352
58683
  }
@@ -58478,9 +58809,11 @@ function computeFixes(text, errors, level = "safe") {
58478
58809
  if (core.length >= 2 && isSlashPair(left, right)) {
58479
58810
  break;
58480
58811
  }
58481
- const newInner = '"' + inner + '"';
58482
- edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: newInner });
58483
- patchedLines.add(e3.line);
58812
+ const replaced = inner.replace(/\(/g, "&#40;").replace(/\)/g, "&#41;");
58813
+ if (replaced !== inner) {
58814
+ edits.push({ start: { line: e3.line, column: contentStart + 1 }, end: { line: e3.line, column: closeIdx + 1 }, newText: replaced });
58815
+ patchedLines.add(e3.line);
58816
+ }
58484
58817
  break;
58485
58818
  }
58486
58819
  searchStart = openIdx + 1;
@@ -58637,14 +58970,33 @@ function computeFixes(text, errors, level = "safe") {
58637
58970
  continue;
58638
58971
  }
58639
58972
  if (is("SE-BOX-EMPTY", e3)) {
58640
- const lines = text.split(/\r?\n/);
58641
- const boxIdx = Math.max(0, e3.line - 1);
58642
- const boxLine = lines[boxIdx] || "";
58643
- const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
58644
- if (labelMatch) {
58645
- const indent = boxLine.match(/^\s*/)?.[0] || "";
58646
- const newLine = `${indent}rect rgb(240, 240, 255)`;
58647
- edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
58973
+ if (level === "all") {
58974
+ const lines = text.split(/\r?\n/);
58975
+ const boxIdx = Math.max(0, e3.line - 1);
58976
+ const boxLine = lines[boxIdx] || "";
58977
+ const openIndent = (boxLine.match(/^(\s*)/)?.[1] || "").length;
58978
+ let endIdx = -1;
58979
+ for (let i3 = boxIdx + 1; i3 < lines.length; i3++) {
58980
+ const raw = lines[i3] || "";
58981
+ const ind = (raw.match(/^(\s*)/)?.[1] || "").length;
58982
+ if (/^\s*end\s*$/.test(raw) && ind <= openIndent) {
58983
+ endIdx = i3;
58984
+ break;
58985
+ }
58986
+ }
58987
+ let hasMsgWithAct = false;
58988
+ if (endIdx !== -1) {
58989
+ const body = lines.slice(boxIdx + 1, endIdx).map((s3) => (s3 || "").trim());
58990
+ hasMsgWithAct = body.some((s3) => /->/.test(s3) && /[+-]/.test(s3));
58991
+ }
58992
+ if (!hasMsgWithAct) {
58993
+ const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
58994
+ if (labelMatch) {
58995
+ const indent = boxLine.match(/^\s*/)?.[0] || "";
58996
+ const newLine = `${indent}rect rgb(240, 240, 255)`;
58997
+ edits.push({ start: { line: e3.line, column: 1 }, end: { line: e3.line, column: boxLine.length + 1 }, newText: newLine });
58998
+ }
58999
+ }
58648
59000
  }
58649
59001
  continue;
58650
59002
  }
@@ -58920,6 +59272,41 @@ ${indent}${tail}` });
58920
59272
  }
58921
59273
  }
58922
59274
  edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
59275
+ `));
59276
+ continue;
59277
+ }
59278
+ if (is("CL-NAMESPACE-MISSING-RBRACE", e3)) {
59279
+ const lines = text.split(/\r?\n/);
59280
+ const curIdx = Math.max(0, e3.line - 1);
59281
+ const openerRe = /^(\s*)namespace\b.*\{\s*$/;
59282
+ let openIdx = -1;
59283
+ let openIndent = "";
59284
+ for (let i3 = curIdx; i3 >= 0; i3--) {
59285
+ const m3 = openerRe.exec(lines[i3] || "");
59286
+ if (m3) {
59287
+ openIdx = i3;
59288
+ openIndent = m3[1] || "";
59289
+ break;
59290
+ }
59291
+ }
59292
+ if (openIdx === -1) {
59293
+ const indent = inferIndentFromLine(lines[curIdx] || "");
59294
+ edits.push(insertAt(text, { line: curIdx + 1, column: 1 }, `${indent}}
59295
+ `));
59296
+ continue;
59297
+ }
59298
+ let insIdx = lines.length;
59299
+ for (let i3 = openIdx + 1; i3 < lines.length; i3++) {
59300
+ const raw = lines[i3] || "";
59301
+ if (raw.trim() === "")
59302
+ continue;
59303
+ const ind = inferIndentFromLine(raw);
59304
+ if (ind.length <= openIndent.length) {
59305
+ insIdx = i3;
59306
+ break;
59307
+ }
59308
+ }
59309
+ edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
58923
59310
  `));
58924
59311
  continue;
58925
59312
  }