@probelabs/probe 0.6.0-rc126 → 0.6.0-rc128
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/README.md +1 -1
- package/build/agent/index.js +409 -22
- package/cjs/agent/ProbeAgent.cjs +519 -195
- package/cjs/index.cjs +519 -195
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -82,7 +82,7 @@ The package installs the actual probe binary, not a JavaScript wrapper, so you g
|
|
|
82
82
|
ProbeAgent provides a high-level AI-powered interface for interacting with your codebase:
|
|
83
83
|
|
|
84
84
|
```javascript
|
|
85
|
-
import { ProbeAgent } from '@
|
|
85
|
+
import { ProbeAgent } from '@probelabs/probe';
|
|
86
86
|
|
|
87
87
|
// Create an AI agent for your project
|
|
88
88
|
const agent = new ProbeAgent({
|
package/build/agent/index.js
CHANGED
|
@@ -28351,7 +28351,6 @@ var init_parser2 = __esm({
|
|
|
28351
28351
|
this.linkStyleStatement = this.RULE("linkStyleStatement", () => {
|
|
28352
28352
|
this.CONSUME(LinkStyleKeyword);
|
|
28353
28353
|
this.SUBRULE(this.linkStyleIndexList);
|
|
28354
|
-
this.OPTION1(() => this.CONSUME1(Newline));
|
|
28355
28354
|
this.SUBRULE(this.linkStylePairs);
|
|
28356
28355
|
this.OPTION2(() => this.CONSUME2(Newline));
|
|
28357
28356
|
});
|
|
@@ -28815,7 +28814,7 @@ var init_semantics = __esm({
|
|
|
28815
28814
|
}
|
|
28816
28815
|
const fnTok = ch.fn?.[0];
|
|
28817
28816
|
if (!fnTok) {
|
|
28818
|
-
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:
|
|
28817
|
+
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()" });
|
|
28819
28818
|
}
|
|
28820
28819
|
const tipTok = ch.tooltip?.[0];
|
|
28821
28820
|
if (tipTok) {
|
|
@@ -28872,7 +28871,7 @@ var init_semantics = __esm({
|
|
|
28872
28871
|
severity: "error",
|
|
28873
28872
|
code: "FL-CLICK-CALL-NAME-MISSING",
|
|
28874
28873
|
message: "'click \u2026 call' requires a function name.",
|
|
28875
|
-
hint:
|
|
28874
|
+
hint: "Example: click A call doThing()"
|
|
28876
28875
|
});
|
|
28877
28876
|
}
|
|
28878
28877
|
return;
|
|
@@ -28953,6 +28952,8 @@ var init_semantics = __esm({
|
|
|
28953
28952
|
const linksHere = Array.isArray(ctx.link) ? ctx.link.length : 0;
|
|
28954
28953
|
if (linksHere > 0)
|
|
28955
28954
|
this.edgeCount += linksHere;
|
|
28955
|
+
if (ctx.link)
|
|
28956
|
+
ctx.link.forEach((ln) => this.visit(ln));
|
|
28956
28957
|
}
|
|
28957
28958
|
// Edge attribute object statements must target a known edge id
|
|
28958
28959
|
// Edge attribute statements are parsed as nodeStatements with a typed attrObject and no links.
|
|
@@ -29012,7 +29013,7 @@ var init_semantics = __esm({
|
|
|
29012
29013
|
severity: "error",
|
|
29013
29014
|
code: "FL-TYPED-SHAPE-UNKNOWN",
|
|
29014
29015
|
message: `Unknown shape '${v}' in '@{ shape: \u2026 }'.`,
|
|
29015
|
-
hint:
|
|
29016
|
+
hint: 'Use one of: rect, rounded, stadium, subroutine, circle, cylinder, diamond, trapezoid, parallelogram, hexagon, "lean-l", "lean-r", icon, image'
|
|
29016
29017
|
});
|
|
29017
29018
|
} else {
|
|
29018
29019
|
const supportedByCli = /* @__PURE__ */ new Set(["rect", "round", "rounded", "diamond", "circle", "cylinder", "stadium", "subroutine", "lean-l", "lean-r"]);
|
|
@@ -29214,8 +29215,8 @@ var init_semantics = __esm({
|
|
|
29214
29215
|
column: t.startColumn ?? 1,
|
|
29215
29216
|
severity: "error",
|
|
29216
29217
|
code: "FL-LABEL-PARENS-UNQUOTED",
|
|
29217
|
-
message: "Parentheses inside an unquoted label are not supported by Mermaid.
|
|
29218
|
-
hint: '
|
|
29218
|
+
message: "Parentheses inside an unquoted label are not supported by Mermaid.",
|
|
29219
|
+
hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and )'
|
|
29219
29220
|
});
|
|
29220
29221
|
}
|
|
29221
29222
|
}
|
|
@@ -29263,6 +29264,29 @@ var init_semantics = __esm({
|
|
|
29263
29264
|
}
|
|
29264
29265
|
}
|
|
29265
29266
|
}
|
|
29267
|
+
// Validate link specifics that Mermaid CLI enforces but our grammar may parse loosely
|
|
29268
|
+
link(ctx) {
|
|
29269
|
+
const inline = ctx.linkTextInline?.[0];
|
|
29270
|
+
if (inline) {
|
|
29271
|
+
const ch = inline.children || {};
|
|
29272
|
+
const parts = [].concat(ch.Identifier || []).concat(ch.Text || []).concat(ch.NumberLiteral || []).concat(ch.Pipe || []);
|
|
29273
|
+
if (parts.length) {
|
|
29274
|
+
const raw = parts.map((t) => String(t.image || "")).join("").trim();
|
|
29275
|
+
if (raw === "x" || raw === "o") {
|
|
29276
|
+
const p = parts[0];
|
|
29277
|
+
this.ctx.errors.push({
|
|
29278
|
+
line: p.startLine ?? 1,
|
|
29279
|
+
column: p.startColumn ?? 1,
|
|
29280
|
+
severity: "error",
|
|
29281
|
+
code: "FL-LINK-UNSUPPORTED-MARKER",
|
|
29282
|
+
message: `Unsupported one-sided link marker '${raw}'. Use symmetric '${raw}--${raw}' or a plain arrow with a label.`,
|
|
29283
|
+
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",
|
|
29284
|
+
length: p.image?.length ?? 1
|
|
29285
|
+
});
|
|
29286
|
+
}
|
|
29287
|
+
}
|
|
29288
|
+
}
|
|
29289
|
+
}
|
|
29266
29290
|
checkBackticksInContent(contentNodes) {
|
|
29267
29291
|
if (!contentNodes)
|
|
29268
29292
|
return;
|
|
@@ -29614,6 +29638,31 @@ function mapFlowchartParserError(err, text) {
|
|
|
29614
29638
|
}
|
|
29615
29639
|
}
|
|
29616
29640
|
}
|
|
29641
|
+
if (isInRule(err, "linkStylePairs") && tokType === "Newline") {
|
|
29642
|
+
const nextLine = Math.min(allLines.length, line + 1);
|
|
29643
|
+
const nxt = allLines[nextLine - 1] || "";
|
|
29644
|
+
const first2 = (nxt.match(/\S/) || { index: 0 }).index || 0;
|
|
29645
|
+
return {
|
|
29646
|
+
line: nextLine,
|
|
29647
|
+
column: Math.max(1, first2 + 1),
|
|
29648
|
+
severity: "error",
|
|
29649
|
+
code: "FL-LINKSTYLE-MULTILINE",
|
|
29650
|
+
message: "'linkStyle' styles must be on the same line as the indices.",
|
|
29651
|
+
hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
|
|
29652
|
+
length: 1
|
|
29653
|
+
};
|
|
29654
|
+
}
|
|
29655
|
+
if ((isInRule(err, "linkStyleIndexList") || isInRule(err, "linkStyleStatement")) && tokType === "Colon") {
|
|
29656
|
+
return {
|
|
29657
|
+
line,
|
|
29658
|
+
column,
|
|
29659
|
+
severity: "error",
|
|
29660
|
+
code: "FL-LINKSTYLE-RANGE-NOT-SUPPORTED",
|
|
29661
|
+
message: "Ranges in 'linkStyle' indices are not supported. Use comma-separated indices.",
|
|
29662
|
+
hint: "Example: linkStyle 0,1 stroke:#f00,stroke-width:2px",
|
|
29663
|
+
length: len
|
|
29664
|
+
};
|
|
29665
|
+
}
|
|
29617
29666
|
if (tokType === "QuotedString") {
|
|
29618
29667
|
const context = err?.context;
|
|
29619
29668
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
@@ -29660,6 +29709,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
29660
29709
|
}
|
|
29661
29710
|
if (isInRule(err, "nodeShape") && err.name === "MismatchedTokenException") {
|
|
29662
29711
|
if (expecting(err, "SquareClose")) {
|
|
29712
|
+
if (tokType === "RoundOpen" || tokType === "RoundClose") {
|
|
29713
|
+
return {
|
|
29714
|
+
line,
|
|
29715
|
+
column,
|
|
29716
|
+
severity: "error",
|
|
29717
|
+
code: "FL-LABEL-PARENS-UNQUOTED",
|
|
29718
|
+
message: "Parentheses inside an unquoted label are not supported by Mermaid.",
|
|
29719
|
+
hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: ( and ).',
|
|
29720
|
+
length: len
|
|
29721
|
+
};
|
|
29722
|
+
}
|
|
29663
29723
|
if (tokType === "QuotedString") {
|
|
29664
29724
|
return {
|
|
29665
29725
|
line,
|
|
@@ -30155,6 +30215,32 @@ ${br.example}`,
|
|
|
30155
30215
|
break;
|
|
30156
30216
|
}
|
|
30157
30217
|
}
|
|
30218
|
+
if (blk.label === "box" && openIdx !== -1) {
|
|
30219
|
+
let endIdx = -1;
|
|
30220
|
+
for (let i = openIdx + 1; i < lines2.length; i++) {
|
|
30221
|
+
const raw = lines2[i] || "";
|
|
30222
|
+
const ind = raw.match(/^(\s*)/)?.[1] || "";
|
|
30223
|
+
if (/^\s*end\s*$/.test(raw) && ind.length <= openIndent.length) {
|
|
30224
|
+
endIdx = i;
|
|
30225
|
+
break;
|
|
30226
|
+
}
|
|
30227
|
+
}
|
|
30228
|
+
if (endIdx !== -1) {
|
|
30229
|
+
const body = lines2.slice(openIdx + 1, endIdx).map((s) => (s || "").trim());
|
|
30230
|
+
const hasMsgWithActivation = body.some((s) => /->/.test(s) && /[+-]/.test(s));
|
|
30231
|
+
if (hasMsgWithActivation) {
|
|
30232
|
+
return {
|
|
30233
|
+
line: openIdx + 1,
|
|
30234
|
+
column: 1,
|
|
30235
|
+
severity: "error",
|
|
30236
|
+
code: "SE-BOX-EMPTY",
|
|
30237
|
+
message: "Box block has no participant/actor declarations. Use 'rect' to group messages visually.",
|
|
30238
|
+
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",
|
|
30239
|
+
length: 3
|
|
30240
|
+
};
|
|
30241
|
+
}
|
|
30242
|
+
}
|
|
30243
|
+
}
|
|
30158
30244
|
let caretLine = line;
|
|
30159
30245
|
if (openIdx !== -1) {
|
|
30160
30246
|
caretLine = lines2.length;
|
|
@@ -31494,7 +31580,7 @@ var init_validate3 = __esm({
|
|
|
31494
31580
|
function tokenize4(text) {
|
|
31495
31581
|
return ClassLexer.tokenize(text);
|
|
31496
31582
|
}
|
|
31497
|
-
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;
|
|
31583
|
+
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;
|
|
31498
31584
|
var init_lexer5 = __esm({
|
|
31499
31585
|
"node_modules/@probelabs/maid/out/diagrams/class/lexer.js"() {
|
|
31500
31586
|
init_api5();
|
|
@@ -31503,7 +31589,10 @@ var init_lexer5 = __esm({
|
|
|
31503
31589
|
ClassDiagramKeyword = createToken({ name: "ClassDiagramKeyword", pattern: /classDiagram/, longer_alt: Identifier3 });
|
|
31504
31590
|
DirectionKw = createToken({ name: "DirectionKw", pattern: /direction/, longer_alt: Identifier3 });
|
|
31505
31591
|
Direction2 = createToken({ name: "Direction", pattern: /LR|RL|TB|BT|TD/, longer_alt: Identifier3 });
|
|
31592
|
+
TitleKw = createToken({ name: "TitleKw", pattern: /title/, longer_alt: Identifier3 });
|
|
31593
|
+
NamespaceKw = createToken({ name: "NamespaceKw", pattern: /namespace/, longer_alt: Identifier3 });
|
|
31506
31594
|
ClassKw = createToken({ name: "ClassKw", pattern: /class/, longer_alt: Identifier3 });
|
|
31595
|
+
InterfaceKw = createToken({ name: "InterfaceKw", pattern: /interface\b/, longer_alt: Identifier3 });
|
|
31507
31596
|
AsKw = createToken({ name: "AsKw", pattern: /as/, longer_alt: Identifier3 });
|
|
31508
31597
|
NoteKw = createToken({ name: "NoteKw", pattern: /note/, longer_alt: Identifier3 });
|
|
31509
31598
|
ForKw = createToken({ name: "ForKw", pattern: /for/, longer_alt: Identifier3 });
|
|
@@ -31546,6 +31635,9 @@ var init_lexer5 = __esm({
|
|
|
31546
31635
|
// Keywords
|
|
31547
31636
|
ClassDiagramKeyword,
|
|
31548
31637
|
DirectionKw,
|
|
31638
|
+
TitleKw,
|
|
31639
|
+
NamespaceKw,
|
|
31640
|
+
InterfaceKw,
|
|
31549
31641
|
ClassKw,
|
|
31550
31642
|
AsKw,
|
|
31551
31643
|
NoteKw,
|
|
@@ -31614,8 +31706,11 @@ var init_parser5 = __esm({
|
|
|
31614
31706
|
});
|
|
31615
31707
|
this.statement = this.RULE("statement", () => {
|
|
31616
31708
|
this.OR([
|
|
31709
|
+
{ ALT: () => this.SUBRULE(this.titleStmt) },
|
|
31617
31710
|
{ ALT: () => this.SUBRULE(this.directionStmt) },
|
|
31711
|
+
{ ALT: () => this.SUBRULE(this.namespaceStmt) },
|
|
31618
31712
|
{ ALT: () => this.SUBRULE(this.classLine) },
|
|
31713
|
+
{ ALT: () => this.SUBRULE(this.interfaceLine) },
|
|
31619
31714
|
{ ALT: () => this.SUBRULE(this.relationStmt) },
|
|
31620
31715
|
{ ALT: () => this.SUBRULE(this.noteStmt) },
|
|
31621
31716
|
{ ALT: () => this.SUBRULE(this.memberAssignStmt) },
|
|
@@ -31627,6 +31722,43 @@ var init_parser5 = __esm({
|
|
|
31627
31722
|
this.CONSUME(Direction2);
|
|
31628
31723
|
this.OPTION(() => this.CONSUME(Newline4));
|
|
31629
31724
|
});
|
|
31725
|
+
this.titleStmt = this.RULE("titleStmt", () => {
|
|
31726
|
+
this.CONSUME(TitleKw);
|
|
31727
|
+
this.OR([
|
|
31728
|
+
{ ALT: () => this.CONSUME(QuotedString4) },
|
|
31729
|
+
{
|
|
31730
|
+
ALT: () => {
|
|
31731
|
+
this.AT_LEAST_ONE(() => {
|
|
31732
|
+
this.OR2([
|
|
31733
|
+
{ ALT: () => this.CONSUME(Identifier3) },
|
|
31734
|
+
{ ALT: () => this.CONSUME(NumberLiteral4) }
|
|
31735
|
+
]);
|
|
31736
|
+
});
|
|
31737
|
+
}
|
|
31738
|
+
}
|
|
31739
|
+
]);
|
|
31740
|
+
this.OPTION(() => this.CONSUME(Newline4));
|
|
31741
|
+
});
|
|
31742
|
+
this.namespaceStmt = this.RULE("namespaceStmt", () => {
|
|
31743
|
+
this.CONSUME(NamespaceKw);
|
|
31744
|
+
this.OR([
|
|
31745
|
+
{ ALT: () => this.CONSUME(QuotedString4) },
|
|
31746
|
+
{ ALT: () => this.CONSUME(Identifier3) }
|
|
31747
|
+
]);
|
|
31748
|
+
this.CONSUME(LCurly);
|
|
31749
|
+
this.MANY(() => {
|
|
31750
|
+
this.OR2([
|
|
31751
|
+
{ ALT: () => this.CONSUME(Newline4) },
|
|
31752
|
+
{ ALT: () => this.SUBRULE(this.classLine) },
|
|
31753
|
+
{ ALT: () => this.SUBRULE(this.interfaceLine) },
|
|
31754
|
+
{ ALT: () => this.SUBRULE(this.relationStmt) },
|
|
31755
|
+
{ ALT: () => this.SUBRULE(this.noteStmt) },
|
|
31756
|
+
{ ALT: () => this.SUBRULE(this.memberAssignStmt) }
|
|
31757
|
+
]);
|
|
31758
|
+
});
|
|
31759
|
+
this.CONSUME(RCurly);
|
|
31760
|
+
this.OPTION(() => this.CONSUME2(Newline4));
|
|
31761
|
+
});
|
|
31630
31762
|
this.classLine = this.RULE("classLine", () => {
|
|
31631
31763
|
this.CONSUME(ClassKw);
|
|
31632
31764
|
this.SUBRULE(this.classRef);
|
|
@@ -31665,6 +31797,44 @@ var init_parser5 = __esm({
|
|
|
31665
31797
|
}
|
|
31666
31798
|
]);
|
|
31667
31799
|
});
|
|
31800
|
+
this.interfaceLine = this.RULE("interfaceLine", () => {
|
|
31801
|
+
this.CONSUME(InterfaceKw);
|
|
31802
|
+
this.SUBRULE(this.classRef);
|
|
31803
|
+
this.OR([
|
|
31804
|
+
{
|
|
31805
|
+
ALT: () => {
|
|
31806
|
+
this.CONSUME(LCurly);
|
|
31807
|
+
this.MANY(() => {
|
|
31808
|
+
this.OR2([
|
|
31809
|
+
{ ALT: () => this.CONSUME3(Newline4) },
|
|
31810
|
+
{ ALT: () => this.SUBRULE(this.memberLineStmt) }
|
|
31811
|
+
]);
|
|
31812
|
+
});
|
|
31813
|
+
this.CONSUME(RCurly);
|
|
31814
|
+
this.OPTION(() => this.CONSUME(Newline4));
|
|
31815
|
+
}
|
|
31816
|
+
},
|
|
31817
|
+
{
|
|
31818
|
+
ALT: () => {
|
|
31819
|
+
this.OPTION1(() => {
|
|
31820
|
+
this.CONSUME(SquareOpen2);
|
|
31821
|
+
this.CONSUME(QuotedString4);
|
|
31822
|
+
this.CONSUME(SquareClose2);
|
|
31823
|
+
});
|
|
31824
|
+
this.OPTION2(() => {
|
|
31825
|
+
this.CONSUME(LTlt);
|
|
31826
|
+
this.CONSUME2(Identifier3);
|
|
31827
|
+
this.CONSUME(GTgt);
|
|
31828
|
+
});
|
|
31829
|
+
this.OPTION3(() => {
|
|
31830
|
+
this.CONSUME(AsKw);
|
|
31831
|
+
this.CONSUME3(Identifier3);
|
|
31832
|
+
});
|
|
31833
|
+
this.OPTION4(() => this.CONSUME2(Newline4));
|
|
31834
|
+
}
|
|
31835
|
+
}
|
|
31836
|
+
]);
|
|
31837
|
+
});
|
|
31668
31838
|
this.memberAssignStmt = this.RULE("memberAssignStmt", () => {
|
|
31669
31839
|
this.SUBRULE(this.classRef);
|
|
31670
31840
|
this.CONSUME(Colon4);
|
|
@@ -31834,6 +32004,31 @@ function validateClass(text, _options = {}) {
|
|
|
31834
32004
|
length: b.image?.length ?? 1
|
|
31835
32005
|
});
|
|
31836
32006
|
}
|
|
32007
|
+
if (a.tokenType === NamespaceKw && b.tokenType === QuotedString4) {
|
|
32008
|
+
errs.push({
|
|
32009
|
+
line: b.startLine ?? 1,
|
|
32010
|
+
column: b.startColumn ?? 1,
|
|
32011
|
+
severity: "error",
|
|
32012
|
+
code: "CL-NAMESPACE-NAME-QUOTED",
|
|
32013
|
+
message: "Quoted namespace names are not supported by mermaid.js. Use an unquoted identifier.",
|
|
32014
|
+
hint: 'Change: namespace "ProbeAgent Core" { ... } \u2192 namespace ProbeAgentCore { ... }',
|
|
32015
|
+
length: b.image?.length ?? 1
|
|
32016
|
+
});
|
|
32017
|
+
}
|
|
32018
|
+
if (a.tokenType === InterfaceKw) {
|
|
32019
|
+
const prevToken = i > 0 ? tokList[i - 1] : null;
|
|
32020
|
+
if (!prevToken || prevToken.tokenType !== LTlt) {
|
|
32021
|
+
errs.push({
|
|
32022
|
+
line: a.startLine ?? 1,
|
|
32023
|
+
column: a.startColumn ?? 1,
|
|
32024
|
+
severity: "error",
|
|
32025
|
+
code: "CL-INTERFACE-KEYWORD-UNSUPPORTED",
|
|
32026
|
+
message: 'The "interface" keyword is not supported by mermaid.js. Use the <<interface>> annotation instead.',
|
|
32027
|
+
hint: 'Auto-fix converts to "class". Then manually add: <<interface>> ClassName after the class definition',
|
|
32028
|
+
length: a.image?.length ?? 9
|
|
32029
|
+
});
|
|
32030
|
+
}
|
|
32031
|
+
}
|
|
31837
32032
|
}
|
|
31838
32033
|
for (const tk of tokList) {
|
|
31839
32034
|
if (tk.tokenType === InvalidRelArrow) {
|
|
@@ -31890,10 +32085,13 @@ function validateClass(text, _options = {}) {
|
|
|
31890
32085
|
const has2 = (code, line) => (prev || []).some((e) => e.code === code && e.line === line && e.severity === "error");
|
|
31891
32086
|
const lines = src.split(/\r?\n/);
|
|
31892
32087
|
const classDeclOpen = [];
|
|
32088
|
+
const namespaceDeclOpen = [];
|
|
31893
32089
|
for (let i = 0; i < lines.length; i++) {
|
|
31894
32090
|
const raw = lines[i] || "";
|
|
31895
32091
|
if (/^\s*class\b.*\{\s*$/.test(raw))
|
|
31896
32092
|
classDeclOpen.push(i + 1);
|
|
32093
|
+
if (/^\s*namespace\b.*\{\s*$/.test(raw))
|
|
32094
|
+
namespaceDeclOpen.push(i + 1);
|
|
31897
32095
|
}
|
|
31898
32096
|
if (classDeclOpen.length > 0) {
|
|
31899
32097
|
const hasClose = lines.some((l) => /\}/.test(l));
|
|
@@ -31902,6 +32100,13 @@ function validateClass(text, _options = {}) {
|
|
|
31902
32100
|
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 { ... }" });
|
|
31903
32101
|
}
|
|
31904
32102
|
}
|
|
32103
|
+
if (namespaceDeclOpen.length > 0) {
|
|
32104
|
+
const hasClose = lines.some((l) => /\}/.test(l));
|
|
32105
|
+
if (!hasClose && !has2("CL-NAMESPACE-MISSING-RBRACE", Math.max(1, lines.length))) {
|
|
32106
|
+
const last2 = namespaceDeclOpen[namespaceDeclOpen.length - 1];
|
|
32107
|
+
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" { ... }' });
|
|
32108
|
+
}
|
|
32109
|
+
}
|
|
31905
32110
|
return errors;
|
|
31906
32111
|
}
|
|
31907
32112
|
});
|
|
@@ -32556,6 +32761,10 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32556
32761
|
edits.push(replaceRange(text, at(e), e.length ?? 2, "-->"));
|
|
32557
32762
|
continue;
|
|
32558
32763
|
}
|
|
32764
|
+
if (is("FL-LINK-UNSUPPORTED-MARKER", e)) {
|
|
32765
|
+
edits.push(replaceRange(text, at(e), e.length ?? 1, ""));
|
|
32766
|
+
continue;
|
|
32767
|
+
}
|
|
32559
32768
|
if (is("FL-EDGE-LABEL-QUOTED", e)) {
|
|
32560
32769
|
const lineText = lineTextAt(text, e.line);
|
|
32561
32770
|
const col = Math.max(0, e.column - 1);
|
|
@@ -32628,6 +32837,29 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32628
32837
|
}
|
|
32629
32838
|
continue;
|
|
32630
32839
|
}
|
|
32840
|
+
if (is("CL-NAMESPACE-NAME-QUOTED", e)) {
|
|
32841
|
+
const lineText = lineTextAt(text, e.line);
|
|
32842
|
+
const nsIdx = lineText.indexOf("namespace");
|
|
32843
|
+
const startSearch = nsIdx >= 0 ? nsIdx + 9 : 0;
|
|
32844
|
+
const q1 = lineText.indexOf('"', startSearch);
|
|
32845
|
+
if (q1 !== -1) {
|
|
32846
|
+
const q2 = lineText.indexOf('"', q1 + 1);
|
|
32847
|
+
if (q2 > q1) {
|
|
32848
|
+
const namespaceName = lineText.slice(q1 + 1, q2);
|
|
32849
|
+
const validIdentifier = namespaceName.replace(/[^A-Za-z0-9_]/g, "");
|
|
32850
|
+
edits.push(replaceRange(text, { line: e.line, column: q1 + 1 }, q2 - q1 + 1, validIdentifier));
|
|
32851
|
+
}
|
|
32852
|
+
}
|
|
32853
|
+
continue;
|
|
32854
|
+
}
|
|
32855
|
+
if (is("CL-INTERFACE-KEYWORD-UNSUPPORTED", e)) {
|
|
32856
|
+
const lineText = lineTextAt(text, e.line);
|
|
32857
|
+
const ifIdx = lineText.indexOf("interface");
|
|
32858
|
+
if (ifIdx !== -1) {
|
|
32859
|
+
edits.push(replaceRange(text, { line: e.line, column: ifIdx + 1 }, 9, "class"));
|
|
32860
|
+
}
|
|
32861
|
+
continue;
|
|
32862
|
+
}
|
|
32631
32863
|
if (is("FL-LABEL-ESCAPED-QUOTE", e)) {
|
|
32632
32864
|
const lineText = lineTextAt(text, e.line);
|
|
32633
32865
|
const caret0 = Math.max(0, e.column - 1);
|
|
@@ -32775,6 +33007,42 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32775
33007
|
const msg = e.message || "";
|
|
32776
33008
|
const lineText = lineTextAt(text, e.line);
|
|
32777
33009
|
const caret0 = Math.max(0, e.column - 1);
|
|
33010
|
+
{
|
|
33011
|
+
const openIdx = lineText.indexOf("([");
|
|
33012
|
+
if (openIdx !== -1) {
|
|
33013
|
+
const badClose = lineText.indexOf("})", openIdx + 2);
|
|
33014
|
+
if (badClose !== -1) {
|
|
33015
|
+
edits.push({ start: { line: e.line, column: badClose + 1 }, end: { line: e.line, column: badClose + 2 }, newText: "]" });
|
|
33016
|
+
patchedLines.add(e.line);
|
|
33017
|
+
continue;
|
|
33018
|
+
}
|
|
33019
|
+
}
|
|
33020
|
+
}
|
|
33021
|
+
{
|
|
33022
|
+
const openIdx = lineText.indexOf("[(");
|
|
33023
|
+
if (openIdx !== -1) {
|
|
33024
|
+
const closePair = lineText.indexOf("))", openIdx + 2);
|
|
33025
|
+
if (closePair !== -1) {
|
|
33026
|
+
edits.push({ start: { line: e.line, column: closePair + 2 }, end: { line: e.line, column: closePair + 3 }, newText: "]" });
|
|
33027
|
+
patchedLines.add(e.line);
|
|
33028
|
+
continue;
|
|
33029
|
+
}
|
|
33030
|
+
}
|
|
33031
|
+
}
|
|
33032
|
+
{
|
|
33033
|
+
const openPair = lineText.indexOf("([");
|
|
33034
|
+
if (openPair !== -1) {
|
|
33035
|
+
const badClose = lineText.indexOf("})", openPair + 2);
|
|
33036
|
+
if (badClose !== -1) {
|
|
33037
|
+
edits.push({ start: { line: e.line, column: badClose + 1 }, end: { line: e.line, column: badClose + 2 }, newText: "]" });
|
|
33038
|
+
continue;
|
|
33039
|
+
}
|
|
33040
|
+
}
|
|
33041
|
+
}
|
|
33042
|
+
if (/\(\[/.test(lineText) && lineText.indexOf("})", Math.max(0, caret0 - 1)) !== -1) {
|
|
33043
|
+
edits.push(replaceRange(text, at(e), e.length ?? 1, "]"));
|
|
33044
|
+
continue;
|
|
33045
|
+
}
|
|
32778
33046
|
if (msg.includes("opened '('") && msg.includes("closed with ']'")) {
|
|
32779
33047
|
const openIdx = lineText.lastIndexOf("(", caret0);
|
|
32780
33048
|
if (openIdx !== -1) {
|
|
@@ -32847,7 +33115,36 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32847
33115
|
const caret0 = Math.max(0, e.column - 1);
|
|
32848
33116
|
const msg = e.message || "";
|
|
32849
33117
|
const bracketMatch = msg.match(/Unclosed '(.+?)'/);
|
|
32850
|
-
const expectedOpener = bracketMatch ? bracketMatch[1] : null;
|
|
33118
|
+
const expectedOpener = bracketMatch ? (bracketMatch[1] || "").trim() : null;
|
|
33119
|
+
if (expectedOpener === "((") {
|
|
33120
|
+
if (level === "all") {
|
|
33121
|
+
const openIdx = lineText.lastIndexOf("((", caret0);
|
|
33122
|
+
if (openIdx !== -1) {
|
|
33123
|
+
const contentStart = openIdx + 2;
|
|
33124
|
+
const picks = [];
|
|
33125
|
+
const pushIdx2 = (i) => {
|
|
33126
|
+
if (i >= 0)
|
|
33127
|
+
picks.push(i);
|
|
33128
|
+
};
|
|
33129
|
+
pushIdx2(lineText.indexOf("-", contentStart));
|
|
33130
|
+
pushIdx2(lineText.indexOf("=", contentStart));
|
|
33131
|
+
pushIdx2(lineText.indexOf(".", contentStart));
|
|
33132
|
+
pushIdx2(lineText.indexOf("|", contentStart));
|
|
33133
|
+
let insertIdx = picks.length ? Math.min(...picks) : lineText.length;
|
|
33134
|
+
const before = lineText.slice(0, openIdx);
|
|
33135
|
+
const m = before.match(/([A-Za-z0-9_]+)\s*$/);
|
|
33136
|
+
const inferred = m ? m[1] : "";
|
|
33137
|
+
if (inferred) {
|
|
33138
|
+
edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: insertIdx + 1 }, newText: inferred + "))" });
|
|
33139
|
+
patchedLines.add(e.line);
|
|
33140
|
+
continue;
|
|
33141
|
+
}
|
|
33142
|
+
patchedLines.add(e.line);
|
|
33143
|
+
continue;
|
|
33144
|
+
}
|
|
33145
|
+
}
|
|
33146
|
+
continue;
|
|
33147
|
+
}
|
|
32851
33148
|
const bracketMap = {
|
|
32852
33149
|
"[": "]",
|
|
32853
33150
|
"{": "}",
|
|
@@ -32933,6 +33230,14 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32933
33230
|
patchedLines.add(e.line);
|
|
32934
33231
|
continue;
|
|
32935
33232
|
}
|
|
33233
|
+
if (innerSeg.includes("(") || innerSeg.includes(")")) {
|
|
33234
|
+
const replaced = innerSeg.replace(/\(/g, "(").replace(/\)/g, ")");
|
|
33235
|
+
if (replaced !== innerSeg) {
|
|
33236
|
+
edits.push({ start: { line: e.line, column: opened.idx + opened.len + 1 }, end: { line: e.line, column: closerIdx + 1 }, newText: replaced });
|
|
33237
|
+
patchedLines.add(e.line);
|
|
33238
|
+
continue;
|
|
33239
|
+
}
|
|
33240
|
+
}
|
|
32936
33241
|
}
|
|
32937
33242
|
}
|
|
32938
33243
|
if (patchedLines.has(e.line)) {
|
|
@@ -32941,9 +33246,35 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
32941
33246
|
let closer = "]";
|
|
32942
33247
|
if (opened)
|
|
32943
33248
|
closer = opened.close;
|
|
32944
|
-
|
|
32945
|
-
|
|
32946
|
-
|
|
33249
|
+
if (closer === "]") {
|
|
33250
|
+
const openIdxSq = lineText.lastIndexOf("[", caret0);
|
|
33251
|
+
if (openIdxSq !== -1) {
|
|
33252
|
+
const picks = [];
|
|
33253
|
+
const pushIdx2 = (i) => {
|
|
33254
|
+
if (i >= 0)
|
|
33255
|
+
picks.push(i);
|
|
33256
|
+
};
|
|
33257
|
+
pushIdx2(lineText.indexOf("-", openIdxSq + 1));
|
|
33258
|
+
pushIdx2(lineText.indexOf("=", openIdxSq + 1));
|
|
33259
|
+
pushIdx2(lineText.indexOf(".", openIdxSq + 1));
|
|
33260
|
+
pushIdx2(lineText.indexOf("|", openIdxSq + 1));
|
|
33261
|
+
let ins = picks.length ? Math.min(...picks) : lineText.length;
|
|
33262
|
+
let tl = ins - 1;
|
|
33263
|
+
while (tl >= 0 && /\s/.test(lineText[tl]))
|
|
33264
|
+
tl--;
|
|
33265
|
+
const startCol2 = tl + 1 + 1;
|
|
33266
|
+
const endCol2 = ins + 1;
|
|
33267
|
+
edits.push({ start: { line: e.line, column: startCol2 }, end: { line: e.line, column: endCol2 }, newText: closer });
|
|
33268
|
+
} else {
|
|
33269
|
+
const avail = lineText.slice(caret0);
|
|
33270
|
+
const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
|
|
33271
|
+
edits.push({ start: { line: e.line, column: caret0 + 1 }, end: { line: e.line, column: caret0 + 1 + replaceLen }, newText: closer });
|
|
33272
|
+
}
|
|
33273
|
+
} else {
|
|
33274
|
+
const avail = lineText.slice(caret0);
|
|
33275
|
+
const replaceLen = Math.min(closer.length, Math.max(1, avail.length));
|
|
33276
|
+
edits.push({ start: { line: e.line, column: caret0 + 1 }, end: { line: e.line, column: caret0 + 1 + replaceLen }, newText: closer });
|
|
33277
|
+
}
|
|
32947
33278
|
}
|
|
32948
33279
|
continue;
|
|
32949
33280
|
}
|
|
@@ -33075,9 +33406,11 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
33075
33406
|
if (core.length >= 2 && isSlashPair(left, right)) {
|
|
33076
33407
|
break;
|
|
33077
33408
|
}
|
|
33078
|
-
const
|
|
33079
|
-
|
|
33080
|
-
|
|
33409
|
+
const replaced = inner.replace(/\(/g, "(").replace(/\)/g, ")");
|
|
33410
|
+
if (replaced !== inner) {
|
|
33411
|
+
edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
|
|
33412
|
+
patchedLines.add(e.line);
|
|
33413
|
+
}
|
|
33081
33414
|
break;
|
|
33082
33415
|
}
|
|
33083
33416
|
searchStart = openIdx + 1;
|
|
@@ -33234,14 +33567,33 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
33234
33567
|
continue;
|
|
33235
33568
|
}
|
|
33236
33569
|
if (is("SE-BOX-EMPTY", e)) {
|
|
33237
|
-
|
|
33238
|
-
|
|
33239
|
-
|
|
33240
|
-
|
|
33241
|
-
|
|
33242
|
-
|
|
33243
|
-
|
|
33244
|
-
|
|
33570
|
+
if (level === "all") {
|
|
33571
|
+
const lines = text.split(/\r?\n/);
|
|
33572
|
+
const boxIdx = Math.max(0, e.line - 1);
|
|
33573
|
+
const boxLine = lines[boxIdx] || "";
|
|
33574
|
+
const openIndent = (boxLine.match(/^(\s*)/)?.[1] || "").length;
|
|
33575
|
+
let endIdx = -1;
|
|
33576
|
+
for (let i = boxIdx + 1; i < lines.length; i++) {
|
|
33577
|
+
const raw = lines[i] || "";
|
|
33578
|
+
const ind = (raw.match(/^(\s*)/)?.[1] || "").length;
|
|
33579
|
+
if (/^\s*end\s*$/.test(raw) && ind <= openIndent) {
|
|
33580
|
+
endIdx = i;
|
|
33581
|
+
break;
|
|
33582
|
+
}
|
|
33583
|
+
}
|
|
33584
|
+
let hasMsgWithAct = false;
|
|
33585
|
+
if (endIdx !== -1) {
|
|
33586
|
+
const body = lines.slice(boxIdx + 1, endIdx).map((s) => (s || "").trim());
|
|
33587
|
+
hasMsgWithAct = body.some((s) => /->/.test(s) && /[+-]/.test(s));
|
|
33588
|
+
}
|
|
33589
|
+
if (!hasMsgWithAct) {
|
|
33590
|
+
const labelMatch = /^\s*box\s+(.+)$/.exec(boxLine);
|
|
33591
|
+
if (labelMatch) {
|
|
33592
|
+
const indent = boxLine.match(/^\s*/)?.[0] || "";
|
|
33593
|
+
const newLine = `${indent}rect rgb(240, 240, 255)`;
|
|
33594
|
+
edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: boxLine.length + 1 }, newText: newLine });
|
|
33595
|
+
}
|
|
33596
|
+
}
|
|
33245
33597
|
}
|
|
33246
33598
|
continue;
|
|
33247
33599
|
}
|
|
@@ -33517,6 +33869,41 @@ ${indent}${tail}` });
|
|
|
33517
33869
|
}
|
|
33518
33870
|
}
|
|
33519
33871
|
edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
|
|
33872
|
+
`));
|
|
33873
|
+
continue;
|
|
33874
|
+
}
|
|
33875
|
+
if (is("CL-NAMESPACE-MISSING-RBRACE", e)) {
|
|
33876
|
+
const lines = text.split(/\r?\n/);
|
|
33877
|
+
const curIdx = Math.max(0, e.line - 1);
|
|
33878
|
+
const openerRe = /^(\s*)namespace\b.*\{\s*$/;
|
|
33879
|
+
let openIdx = -1;
|
|
33880
|
+
let openIndent = "";
|
|
33881
|
+
for (let i = curIdx; i >= 0; i--) {
|
|
33882
|
+
const m = openerRe.exec(lines[i] || "");
|
|
33883
|
+
if (m) {
|
|
33884
|
+
openIdx = i;
|
|
33885
|
+
openIndent = m[1] || "";
|
|
33886
|
+
break;
|
|
33887
|
+
}
|
|
33888
|
+
}
|
|
33889
|
+
if (openIdx === -1) {
|
|
33890
|
+
const indent = inferIndentFromLine(lines[curIdx] || "");
|
|
33891
|
+
edits.push(insertAt(text, { line: curIdx + 1, column: 1 }, `${indent}}
|
|
33892
|
+
`));
|
|
33893
|
+
continue;
|
|
33894
|
+
}
|
|
33895
|
+
let insIdx = lines.length;
|
|
33896
|
+
for (let i = openIdx + 1; i < lines.length; i++) {
|
|
33897
|
+
const raw = lines[i] || "";
|
|
33898
|
+
if (raw.trim() === "")
|
|
33899
|
+
continue;
|
|
33900
|
+
const ind = inferIndentFromLine(raw);
|
|
33901
|
+
if (ind.length <= openIndent.length) {
|
|
33902
|
+
insIdx = i;
|
|
33903
|
+
break;
|
|
33904
|
+
}
|
|
33905
|
+
}
|
|
33906
|
+
edits.push(insertAt(text, { line: insIdx + 1, column: 1 }, `${openIndent}}
|
|
33520
33907
|
`));
|
|
33521
33908
|
continue;
|
|
33522
33909
|
}
|