@probelabs/probe 0.6.0-rc286 → 0.6.0-rc287
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/bin/binaries/probe-v0.6.0-rc287-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc287-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc287-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc287-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc287-x86_64-unknown-linux-musl.tar.gz +0 -0
- package/build/agent/index.js +127 -15
- package/build/tools/common.js +11 -1
- package/build/tools/vercel.js +31 -2
- package/cjs/agent/ProbeAgent.cjs +127 -15
- package/cjs/index.cjs +127 -15
- package/package.json +3 -3
- package/src/tools/common.js +11 -1
- package/src/tools/vercel.js +31 -2
- package/bin/binaries/probe-v0.6.0-rc286-aarch64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-aarch64-unknown-linux-musl.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-apple-darwin.tar.gz +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-pc-windows-msvc.zip +0 -0
- package/bin/binaries/probe-v0.6.0-rc286-x86_64-unknown-linux-musl.tar.gz +0 -0
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/build/agent/index.js
CHANGED
|
@@ -8933,7 +8933,14 @@ function parseTargets(targets) {
|
|
|
8933
8933
|
}
|
|
8934
8934
|
function parseAndResolvePaths(pathStr, cwd) {
|
|
8935
8935
|
if (!pathStr) return [];
|
|
8936
|
-
|
|
8936
|
+
let paths = pathStr.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
8937
|
+
paths = paths.flatMap((p) => {
|
|
8938
|
+
if (!/\s/.test(p)) return [p];
|
|
8939
|
+
const parts = p.split(/\s+/).filter(Boolean);
|
|
8940
|
+
if (parts.length <= 1) return [p];
|
|
8941
|
+
const allLookLikePaths = parts.every((part) => /[/\\]/.test(part) || /\.\w+/.test(part));
|
|
8942
|
+
return allLookLikePaths ? parts : [p];
|
|
8943
|
+
});
|
|
8937
8944
|
return paths.map((p) => {
|
|
8938
8945
|
if (isAbsolute(p)) {
|
|
8939
8946
|
return p;
|
|
@@ -9167,11 +9174,24 @@ function normalizeTargets(targets) {
|
|
|
9167
9174
|
if (typeof target !== "string") continue;
|
|
9168
9175
|
const trimmed = target.trim();
|
|
9169
9176
|
if (!trimmed || seen.has(trimmed)) continue;
|
|
9170
|
-
|
|
9171
|
-
|
|
9177
|
+
const subTargets = splitSpaceSeparatedPaths(trimmed);
|
|
9178
|
+
for (const sub of subTargets) {
|
|
9179
|
+
if (!seen.has(sub)) {
|
|
9180
|
+
seen.add(sub);
|
|
9181
|
+
normalized.push(sub);
|
|
9182
|
+
}
|
|
9183
|
+
}
|
|
9172
9184
|
}
|
|
9173
9185
|
return normalized;
|
|
9174
9186
|
}
|
|
9187
|
+
function splitSpaceSeparatedPaths(target) {
|
|
9188
|
+
if (!/\s/.test(target)) return [target];
|
|
9189
|
+
const parts = target.split(/\s+/).filter(Boolean);
|
|
9190
|
+
if (parts.length <= 1) return [target];
|
|
9191
|
+
const allLookLikePaths = parts.every((p) => /[/\\]/.test(p) || /\.\w+/.test(p));
|
|
9192
|
+
if (allLookLikePaths) return parts;
|
|
9193
|
+
return [target];
|
|
9194
|
+
}
|
|
9175
9195
|
function extractJsonSnippet(text) {
|
|
9176
9196
|
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
|
|
9177
9197
|
if (jsonBlockMatch) {
|
|
@@ -44307,6 +44327,7 @@ var init_parser2 = __esm({
|
|
|
44307
44327
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
44308
44328
|
{ ALT: () => this.CONSUME(Text) },
|
|
44309
44329
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
44330
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
44310
44331
|
// Note: RoundOpen and RoundClose (parentheses) are NOT allowed in unquoted labels
|
|
44311
44332
|
// to match Mermaid's behavior - use quoted labels like ["text (with parens)"] instead
|
|
44312
44333
|
// Allow HTML-like tags (e.g., <br/>) inside labels
|
|
@@ -44398,6 +44419,7 @@ var init_parser2 = __esm({
|
|
|
44398
44419
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
44399
44420
|
{ ALT: () => this.CONSUME(Text) },
|
|
44400
44421
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
44422
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
44401
44423
|
// Allow HTML-like angle brackets and slashes for <br/>, <i>, etc.
|
|
44402
44424
|
{ ALT: () => this.CONSUME(AngleLess) },
|
|
44403
44425
|
{ ALT: () => this.CONSUME(AngleOpen) },
|
|
@@ -45573,13 +45595,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
45573
45595
|
length: len
|
|
45574
45596
|
};
|
|
45575
45597
|
}
|
|
45576
|
-
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
45598
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose" || tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
45577
45599
|
const context = err?.context;
|
|
45578
45600
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
45579
45601
|
const lineContent = allLines[Math.max(0, line - 1)] || "";
|
|
45580
45602
|
const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
|
|
45581
45603
|
const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
|
|
45582
45604
|
if (inLinkRule || hasLinkBefore) {
|
|
45605
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
45606
|
+
return {
|
|
45607
|
+
line,
|
|
45608
|
+
column,
|
|
45609
|
+
severity: "error",
|
|
45610
|
+
code: "FL-EDGE-LABEL-CURLY-IN-PIPES",
|
|
45611
|
+
message: "Curly braces { } are not supported inside pipe-delimited edge labels.",
|
|
45612
|
+
hint: "Use HTML entities { and } inside |...|, e.g., --|Resolve ${VAR}|-->",
|
|
45613
|
+
length: len
|
|
45614
|
+
};
|
|
45615
|
+
}
|
|
45583
45616
|
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
45584
45617
|
return {
|
|
45585
45618
|
line,
|
|
@@ -45641,6 +45674,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
45641
45674
|
length: len
|
|
45642
45675
|
};
|
|
45643
45676
|
}
|
|
45677
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
45678
|
+
return {
|
|
45679
|
+
line,
|
|
45680
|
+
column,
|
|
45681
|
+
severity: "error",
|
|
45682
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
45683
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
45684
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
45685
|
+
length: len
|
|
45686
|
+
};
|
|
45687
|
+
}
|
|
45644
45688
|
{
|
|
45645
45689
|
const caret0 = Math.max(0, column - 1);
|
|
45646
45690
|
const openIdx = lineStr.lastIndexOf("[", caret0);
|
|
@@ -45682,9 +45726,20 @@ function mapFlowchartParserError(err, text) {
|
|
|
45682
45726
|
length: len
|
|
45683
45727
|
};
|
|
45684
45728
|
}
|
|
45729
|
+
if (seg.includes("{") || seg.includes("}")) {
|
|
45730
|
+
return {
|
|
45731
|
+
line,
|
|
45732
|
+
column,
|
|
45733
|
+
severity: "error",
|
|
45734
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
45735
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
45736
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
45737
|
+
length: len
|
|
45738
|
+
};
|
|
45739
|
+
}
|
|
45685
45740
|
}
|
|
45686
45741
|
}
|
|
45687
|
-
if (tokType === "QuotedString"
|
|
45742
|
+
if (tokType === "QuotedString") {
|
|
45688
45743
|
return {
|
|
45689
45744
|
line,
|
|
45690
45745
|
column,
|
|
@@ -45695,6 +45750,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
45695
45750
|
length: len
|
|
45696
45751
|
};
|
|
45697
45752
|
}
|
|
45753
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
45754
|
+
return {
|
|
45755
|
+
line,
|
|
45756
|
+
column,
|
|
45757
|
+
severity: "error",
|
|
45758
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
45759
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
45760
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
45761
|
+
length: len
|
|
45762
|
+
};
|
|
45763
|
+
}
|
|
45698
45764
|
const q = findInnerQuoteIssue("[");
|
|
45699
45765
|
if (q?.kind === "escaped") {
|
|
45700
45766
|
return { line, column: q.column, severity: "error", code: "FL-LABEL-ESCAPED-QUOTE", message: 'Escaped quotes (\\") in node labels are not supported by Mermaid. Use " instead.', hint: 'Prefer "He said "Hi"".', length: 2 };
|
|
@@ -45705,7 +45771,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
45705
45771
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '['. Add a matching ']' before the arrow or newline.", hint: "Example: A[Label] --> B", length: 1 };
|
|
45706
45772
|
}
|
|
45707
45773
|
if (expecting(err, "RoundClose")) {
|
|
45708
|
-
if (tokType === "QuotedString"
|
|
45774
|
+
if (tokType === "QuotedString") {
|
|
45709
45775
|
return {
|
|
45710
45776
|
line,
|
|
45711
45777
|
column,
|
|
@@ -45716,6 +45782,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
45716
45782
|
length: len
|
|
45717
45783
|
};
|
|
45718
45784
|
}
|
|
45785
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
45786
|
+
return {
|
|
45787
|
+
line,
|
|
45788
|
+
column,
|
|
45789
|
+
severity: "error",
|
|
45790
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
45791
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
45792
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
45793
|
+
length: len
|
|
45794
|
+
};
|
|
45795
|
+
}
|
|
45719
45796
|
{
|
|
45720
45797
|
const caret0 = Math.max(0, column - 1);
|
|
45721
45798
|
const openIdx = lineStr.lastIndexOf("(", caret0);
|
|
@@ -45744,7 +45821,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
45744
45821
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
|
|
45745
45822
|
}
|
|
45746
45823
|
if (expecting(err, "DiamondClose")) {
|
|
45747
|
-
if (tokType === "QuotedString"
|
|
45824
|
+
if (tokType === "QuotedString") {
|
|
45748
45825
|
return {
|
|
45749
45826
|
line,
|
|
45750
45827
|
column,
|
|
@@ -45755,6 +45832,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
45755
45832
|
length: len
|
|
45756
45833
|
};
|
|
45757
45834
|
}
|
|
45835
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
45836
|
+
return {
|
|
45837
|
+
line,
|
|
45838
|
+
column,
|
|
45839
|
+
severity: "error",
|
|
45840
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
45841
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
45842
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
45843
|
+
length: len
|
|
45844
|
+
};
|
|
45845
|
+
}
|
|
45758
45846
|
{
|
|
45759
45847
|
const caret0 = Math.max(0, column - 1);
|
|
45760
45848
|
const openIdx = lineStr.lastIndexOf("{", caret0);
|
|
@@ -46597,7 +46685,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
46597
46685
|
const byLine = /* @__PURE__ */ new Map();
|
|
46598
46686
|
const collect = (arr) => {
|
|
46599
46687
|
for (const e of arr || []) {
|
|
46600
|
-
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED")) {
|
|
46688
|
+
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED" || e.code === "FL-LABEL-CURLY-IN-UNQUOTED" || e.code === "FL-LABEL-BRACKET-IN-UNQUOTED")) {
|
|
46601
46689
|
const ln = e.line ?? 0;
|
|
46602
46690
|
const col = e.column ?? 1;
|
|
46603
46691
|
const list = byLine.get(ln) || [];
|
|
@@ -46679,6 +46767,9 @@ function validateFlowchart(text, options = {}) {
|
|
|
46679
46767
|
const hasParens = seg.includes("(") || seg.includes(")");
|
|
46680
46768
|
const hasAt = seg.includes("@");
|
|
46681
46769
|
const hasQuote = seg.includes('"');
|
|
46770
|
+
const hasCurly = seg.includes("{") || seg.includes("}");
|
|
46771
|
+
const hasBracket = seg.includes("[") || seg.includes("]");
|
|
46772
|
+
const isDoubleSquare = raw.slice(i, i + 2) === "[[" && raw.slice(j - 2, j) === "]]";
|
|
46682
46773
|
const isSingleQuoted = /^'[^]*'$/.test(trimmed);
|
|
46683
46774
|
const hasLeadingSlash = lsp === "/" || lsp === "\\";
|
|
46684
46775
|
if (!covered && !isQuoted && !isParenWrapped && hasParens) {
|
|
@@ -46696,6 +46787,16 @@ function validateFlowchart(text, options = {}) {
|
|
|
46696
46787
|
existing.push({ start: startCol, end: endCol });
|
|
46697
46788
|
byLine.set(ln, existing);
|
|
46698
46789
|
}
|
|
46790
|
+
if (!covered && !isQuoted && !isSlashPair && hasCurly) {
|
|
46791
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-CURLY-IN-UNQUOTED", message: "Curly braces are not supported inside unquoted node labels.", hint: "Use { and } for literal braces, e.g., C[Substitute {params}]." });
|
|
46792
|
+
existing.push({ start: startCol, end: endCol });
|
|
46793
|
+
byLine.set(ln, existing);
|
|
46794
|
+
}
|
|
46795
|
+
if (!covered && !isQuoted && !isSlashPair && !isDoubleSquare && hasBracket) {
|
|
46796
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-BRACKET-IN-UNQUOTED", message: "Square brackets are not supported inside unquoted node labels.", hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]' });
|
|
46797
|
+
existing.push({ start: startCol, end: endCol });
|
|
46798
|
+
byLine.set(ln, existing);
|
|
46799
|
+
}
|
|
46699
46800
|
if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
|
|
46700
46801
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility="true""]' });
|
|
46701
46802
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -49056,7 +49157,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
49056
49157
|
}
|
|
49057
49158
|
continue;
|
|
49058
49159
|
}
|
|
49059
|
-
if (is("FL-EDGE-LABEL-BRACKET", e)) {
|
|
49160
|
+
if (is("FL-EDGE-LABEL-BRACKET", e) || is("FL-EDGE-LABEL-CURLY-IN-PIPES", e)) {
|
|
49060
49161
|
const lineText = lineTextAt(text, e.line);
|
|
49061
49162
|
const firstBar = lineText.indexOf("|");
|
|
49062
49163
|
const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
|
|
@@ -49064,7 +49165,8 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
49064
49165
|
const before = lineText.slice(0, firstBar + 1);
|
|
49065
49166
|
const label = lineText.slice(firstBar + 1, secondBar);
|
|
49066
49167
|
const after = lineText.slice(secondBar);
|
|
49067
|
-
|
|
49168
|
+
let fixedLabel = label.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
49169
|
+
fixedLabel = fixedLabel.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
49068
49170
|
const fixedLine = before + fixedLabel + after;
|
|
49069
49171
|
const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m, seg) => "[" + String(seg).replace(/`/g, "") + "]");
|
|
49070
49172
|
edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: lineText.length + 1 }, newText: finalLine });
|
|
@@ -49704,7 +49806,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
49704
49806
|
}
|
|
49705
49807
|
continue;
|
|
49706
49808
|
}
|
|
49707
|
-
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
|
|
49809
|
+
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e) || is("FL-LABEL-CURLY-IN-UNQUOTED", e) || is("FL-LABEL-BRACKET-IN-UNQUOTED", e)) {
|
|
49708
49810
|
if (level === "safe" || level === "all") {
|
|
49709
49811
|
if (patchedLines.has(e.line))
|
|
49710
49812
|
continue;
|
|
@@ -49745,7 +49847,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
49745
49847
|
if (openIdx === -1)
|
|
49746
49848
|
break;
|
|
49747
49849
|
const contentStart = openIdx + shape.open.length;
|
|
49748
|
-
const closeIdx = shape.open === "(" && shape.close === ")" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
49850
|
+
const closeIdx = shape.open === "(" && shape.close === ")" || shape.open === "[" && shape.close === "]" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
49749
49851
|
if (closeIdx === -1)
|
|
49750
49852
|
break;
|
|
49751
49853
|
if (openIdx <= caret0 && caret0 < closeIdx) {
|
|
@@ -49765,11 +49867,21 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
49765
49867
|
const isSlashPair = (l, r) => l === "/" && r === "/" || l === "\\" && r === "\\" || l === "/" && r === "\\" || l === "\\" && r === "/";
|
|
49766
49868
|
const isParallelogramShape = core.length >= 2 && isSlashPair(left, right);
|
|
49767
49869
|
let replaced;
|
|
49768
|
-
if (!isParallelogramShape) {
|
|
49769
|
-
const
|
|
49870
|
+
if (is("FL-LABEL-BRACKET-IN-UNQUOTED", e) && !isParallelogramShape) {
|
|
49871
|
+
const hasOtherHazards = /[(){}@]/.test(inner) || inner.includes('"') || inner.includes('\\"');
|
|
49872
|
+
if (hasOtherHazards) {
|
|
49873
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
49874
|
+
replaced = '"' + escaped + '"';
|
|
49875
|
+
} else {
|
|
49876
|
+
replaced = inner.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
49877
|
+
}
|
|
49878
|
+
} else if (is("FL-LABEL-CURLY-IN-UNQUOTED", e)) {
|
|
49879
|
+
replaced = inner.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
49880
|
+
} else if (!isParallelogramShape) {
|
|
49881
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
49770
49882
|
replaced = '"' + escaped + '"';
|
|
49771
49883
|
} else {
|
|
49772
|
-
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\"/g, """).replace(/"/g, """);
|
|
49884
|
+
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\[/g, "[").replace(/\]/g, "]").replace(/\\"/g, """).replace(/"/g, """);
|
|
49773
49885
|
}
|
|
49774
49886
|
if (replaced !== inner) {
|
|
49775
49887
|
edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
|
package/build/tools/common.js
CHANGED
|
@@ -228,7 +228,17 @@ export function parseAndResolvePaths(pathStr, cwd) {
|
|
|
228
228
|
if (!pathStr) return [];
|
|
229
229
|
|
|
230
230
|
// Split on comma and trim whitespace
|
|
231
|
-
|
|
231
|
+
let paths = pathStr.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
232
|
+
|
|
233
|
+
// Auto-fix: model sometimes passes space-separated file paths as one string
|
|
234
|
+
// e.g. "src/ranking.rs src/simd_ranking.rs" — split if each part looks like a path
|
|
235
|
+
paths = paths.flatMap(p => {
|
|
236
|
+
if (!/\s/.test(p)) return [p];
|
|
237
|
+
const parts = p.split(/\s+/).filter(Boolean);
|
|
238
|
+
if (parts.length <= 1) return [p];
|
|
239
|
+
const allLookLikePaths = parts.every(part => /[/\\]/.test(part) || /\.\w+/.test(part));
|
|
240
|
+
return allLookLikePaths ? parts : [p];
|
|
241
|
+
});
|
|
232
242
|
|
|
233
243
|
// Resolve relative paths against cwd
|
|
234
244
|
return paths.map(p => {
|
package/build/tools/vercel.js
CHANGED
|
@@ -105,13 +105,42 @@ function normalizeTargets(targets) {
|
|
|
105
105
|
if (typeof target !== 'string') continue;
|
|
106
106
|
const trimmed = target.trim();
|
|
107
107
|
if (!trimmed || seen.has(trimmed)) continue;
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
|
|
109
|
+
// Auto-fix: model sometimes puts multiple space-separated file paths in one string
|
|
110
|
+
// e.g. "src/ranking.rs src/simd_ranking.rs" — split them apart
|
|
111
|
+
const subTargets = splitSpaceSeparatedPaths(trimmed);
|
|
112
|
+
for (const sub of subTargets) {
|
|
113
|
+
if (!seen.has(sub)) {
|
|
114
|
+
seen.add(sub);
|
|
115
|
+
normalized.push(sub);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
return normalized;
|
|
113
121
|
}
|
|
114
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Split a string that may contain multiple space-separated file paths.
|
|
125
|
+
* Detects patterns like "path/file.ext path2/file2.ext" and splits them.
|
|
126
|
+
* Preserves single paths and paths with suffixes like ":10-20" or "#Symbol".
|
|
127
|
+
*/
|
|
128
|
+
function splitSpaceSeparatedPaths(target) {
|
|
129
|
+
// If no spaces, it's a single target
|
|
130
|
+
if (!/\s/.test(target)) return [target];
|
|
131
|
+
|
|
132
|
+
// Split on whitespace and check if parts look like file paths
|
|
133
|
+
const parts = target.split(/\s+/).filter(Boolean);
|
|
134
|
+
if (parts.length <= 1) return [target];
|
|
135
|
+
|
|
136
|
+
// Check if each part looks like a file path (has a dot extension or path separator)
|
|
137
|
+
const allLookLikePaths = parts.every(p => /[/\\]/.test(p) || /\.\w+/.test(p));
|
|
138
|
+
if (allLookLikePaths) return parts;
|
|
139
|
+
|
|
140
|
+
// Not confident these are separate paths — return as-is
|
|
141
|
+
return [target];
|
|
142
|
+
}
|
|
143
|
+
|
|
115
144
|
function extractJsonSnippet(text) {
|
|
116
145
|
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
|
|
117
146
|
if (jsonBlockMatch) {
|
package/cjs/agent/ProbeAgent.cjs
CHANGED
|
@@ -27070,7 +27070,14 @@ function parseTargets(targets) {
|
|
|
27070
27070
|
}
|
|
27071
27071
|
function parseAndResolvePaths(pathStr, cwd) {
|
|
27072
27072
|
if (!pathStr) return [];
|
|
27073
|
-
|
|
27073
|
+
let paths = pathStr.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
27074
|
+
paths = paths.flatMap((p) => {
|
|
27075
|
+
if (!/\s/.test(p)) return [p];
|
|
27076
|
+
const parts = p.split(/\s+/).filter(Boolean);
|
|
27077
|
+
if (parts.length <= 1) return [p];
|
|
27078
|
+
const allLookLikePaths = parts.every((part) => /[/\\]/.test(part) || /\.\w+/.test(part));
|
|
27079
|
+
return allLookLikePaths ? parts : [p];
|
|
27080
|
+
});
|
|
27074
27081
|
return paths.map((p) => {
|
|
27075
27082
|
if ((0, import_path5.isAbsolute)(p)) {
|
|
27076
27083
|
return p;
|
|
@@ -27303,11 +27310,24 @@ function normalizeTargets(targets) {
|
|
|
27303
27310
|
if (typeof target !== "string") continue;
|
|
27304
27311
|
const trimmed = target.trim();
|
|
27305
27312
|
if (!trimmed || seen.has(trimmed)) continue;
|
|
27306
|
-
|
|
27307
|
-
|
|
27313
|
+
const subTargets = splitSpaceSeparatedPaths(trimmed);
|
|
27314
|
+
for (const sub of subTargets) {
|
|
27315
|
+
if (!seen.has(sub)) {
|
|
27316
|
+
seen.add(sub);
|
|
27317
|
+
normalized.push(sub);
|
|
27318
|
+
}
|
|
27319
|
+
}
|
|
27308
27320
|
}
|
|
27309
27321
|
return normalized;
|
|
27310
27322
|
}
|
|
27323
|
+
function splitSpaceSeparatedPaths(target) {
|
|
27324
|
+
if (!/\s/.test(target)) return [target];
|
|
27325
|
+
const parts = target.split(/\s+/).filter(Boolean);
|
|
27326
|
+
if (parts.length <= 1) return [target];
|
|
27327
|
+
const allLookLikePaths = parts.every((p) => /[/\\]/.test(p) || /\.\w+/.test(p));
|
|
27328
|
+
if (allLookLikePaths) return parts;
|
|
27329
|
+
return [target];
|
|
27330
|
+
}
|
|
27311
27331
|
function extractJsonSnippet(text) {
|
|
27312
27332
|
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
|
|
27313
27333
|
if (jsonBlockMatch) {
|
|
@@ -62012,6 +62032,7 @@ var init_parser2 = __esm({
|
|
|
62012
62032
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
62013
62033
|
{ ALT: () => this.CONSUME(Text) },
|
|
62014
62034
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
62035
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
62015
62036
|
// Note: RoundOpen and RoundClose (parentheses) are NOT allowed in unquoted labels
|
|
62016
62037
|
// to match Mermaid's behavior - use quoted labels like ["text (with parens)"] instead
|
|
62017
62038
|
// Allow HTML-like tags (e.g., <br/>) inside labels
|
|
@@ -62103,6 +62124,7 @@ var init_parser2 = __esm({
|
|
|
62103
62124
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
62104
62125
|
{ ALT: () => this.CONSUME(Text) },
|
|
62105
62126
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
62127
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
62106
62128
|
// Allow HTML-like angle brackets and slashes for <br/>, <i>, etc.
|
|
62107
62129
|
{ ALT: () => this.CONSUME(AngleLess) },
|
|
62108
62130
|
{ ALT: () => this.CONSUME(AngleOpen) },
|
|
@@ -63278,13 +63300,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
63278
63300
|
length: len
|
|
63279
63301
|
};
|
|
63280
63302
|
}
|
|
63281
|
-
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
63303
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose" || tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
63282
63304
|
const context = err?.context;
|
|
63283
63305
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
63284
63306
|
const lineContent = allLines[Math.max(0, line - 1)] || "";
|
|
63285
63307
|
const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
|
|
63286
63308
|
const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
|
|
63287
63309
|
if (inLinkRule || hasLinkBefore) {
|
|
63310
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
63311
|
+
return {
|
|
63312
|
+
line,
|
|
63313
|
+
column,
|
|
63314
|
+
severity: "error",
|
|
63315
|
+
code: "FL-EDGE-LABEL-CURLY-IN-PIPES",
|
|
63316
|
+
message: "Curly braces { } are not supported inside pipe-delimited edge labels.",
|
|
63317
|
+
hint: "Use HTML entities { and } inside |...|, e.g., --|Resolve ${VAR}|-->",
|
|
63318
|
+
length: len
|
|
63319
|
+
};
|
|
63320
|
+
}
|
|
63288
63321
|
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
63289
63322
|
return {
|
|
63290
63323
|
line,
|
|
@@ -63346,6 +63379,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
63346
63379
|
length: len
|
|
63347
63380
|
};
|
|
63348
63381
|
}
|
|
63382
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
63383
|
+
return {
|
|
63384
|
+
line,
|
|
63385
|
+
column,
|
|
63386
|
+
severity: "error",
|
|
63387
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
63388
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
63389
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
63390
|
+
length: len
|
|
63391
|
+
};
|
|
63392
|
+
}
|
|
63349
63393
|
{
|
|
63350
63394
|
const caret0 = Math.max(0, column - 1);
|
|
63351
63395
|
const openIdx = lineStr.lastIndexOf("[", caret0);
|
|
@@ -63387,9 +63431,20 @@ function mapFlowchartParserError(err, text) {
|
|
|
63387
63431
|
length: len
|
|
63388
63432
|
};
|
|
63389
63433
|
}
|
|
63434
|
+
if (seg.includes("{") || seg.includes("}")) {
|
|
63435
|
+
return {
|
|
63436
|
+
line,
|
|
63437
|
+
column,
|
|
63438
|
+
severity: "error",
|
|
63439
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
63440
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
63441
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
63442
|
+
length: len
|
|
63443
|
+
};
|
|
63444
|
+
}
|
|
63390
63445
|
}
|
|
63391
63446
|
}
|
|
63392
|
-
if (tokType === "QuotedString"
|
|
63447
|
+
if (tokType === "QuotedString") {
|
|
63393
63448
|
return {
|
|
63394
63449
|
line,
|
|
63395
63450
|
column,
|
|
@@ -63400,6 +63455,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
63400
63455
|
length: len
|
|
63401
63456
|
};
|
|
63402
63457
|
}
|
|
63458
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
63459
|
+
return {
|
|
63460
|
+
line,
|
|
63461
|
+
column,
|
|
63462
|
+
severity: "error",
|
|
63463
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
63464
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
63465
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
63466
|
+
length: len
|
|
63467
|
+
};
|
|
63468
|
+
}
|
|
63403
63469
|
const q = findInnerQuoteIssue("[");
|
|
63404
63470
|
if (q?.kind === "escaped") {
|
|
63405
63471
|
return { line, column: q.column, severity: "error", code: "FL-LABEL-ESCAPED-QUOTE", message: 'Escaped quotes (\\") in node labels are not supported by Mermaid. Use " instead.', hint: 'Prefer "He said "Hi"".', length: 2 };
|
|
@@ -63410,7 +63476,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
63410
63476
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '['. Add a matching ']' before the arrow or newline.", hint: "Example: A[Label] --> B", length: 1 };
|
|
63411
63477
|
}
|
|
63412
63478
|
if (expecting(err, "RoundClose")) {
|
|
63413
|
-
if (tokType === "QuotedString"
|
|
63479
|
+
if (tokType === "QuotedString") {
|
|
63414
63480
|
return {
|
|
63415
63481
|
line,
|
|
63416
63482
|
column,
|
|
@@ -63421,6 +63487,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
63421
63487
|
length: len
|
|
63422
63488
|
};
|
|
63423
63489
|
}
|
|
63490
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
63491
|
+
return {
|
|
63492
|
+
line,
|
|
63493
|
+
column,
|
|
63494
|
+
severity: "error",
|
|
63495
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
63496
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
63497
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
63498
|
+
length: len
|
|
63499
|
+
};
|
|
63500
|
+
}
|
|
63424
63501
|
{
|
|
63425
63502
|
const caret0 = Math.max(0, column - 1);
|
|
63426
63503
|
const openIdx = lineStr.lastIndexOf("(", caret0);
|
|
@@ -63449,7 +63526,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
63449
63526
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
|
|
63450
63527
|
}
|
|
63451
63528
|
if (expecting(err, "DiamondClose")) {
|
|
63452
|
-
if (tokType === "QuotedString"
|
|
63529
|
+
if (tokType === "QuotedString") {
|
|
63453
63530
|
return {
|
|
63454
63531
|
line,
|
|
63455
63532
|
column,
|
|
@@ -63460,6 +63537,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
63460
63537
|
length: len
|
|
63461
63538
|
};
|
|
63462
63539
|
}
|
|
63540
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
63541
|
+
return {
|
|
63542
|
+
line,
|
|
63543
|
+
column,
|
|
63544
|
+
severity: "error",
|
|
63545
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
63546
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
63547
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
63548
|
+
length: len
|
|
63549
|
+
};
|
|
63550
|
+
}
|
|
63463
63551
|
{
|
|
63464
63552
|
const caret0 = Math.max(0, column - 1);
|
|
63465
63553
|
const openIdx = lineStr.lastIndexOf("{", caret0);
|
|
@@ -64302,7 +64390,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
64302
64390
|
const byLine = /* @__PURE__ */ new Map();
|
|
64303
64391
|
const collect = (arr) => {
|
|
64304
64392
|
for (const e of arr || []) {
|
|
64305
|
-
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED")) {
|
|
64393
|
+
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED" || e.code === "FL-LABEL-CURLY-IN-UNQUOTED" || e.code === "FL-LABEL-BRACKET-IN-UNQUOTED")) {
|
|
64306
64394
|
const ln = e.line ?? 0;
|
|
64307
64395
|
const col = e.column ?? 1;
|
|
64308
64396
|
const list = byLine.get(ln) || [];
|
|
@@ -64384,6 +64472,9 @@ function validateFlowchart(text, options = {}) {
|
|
|
64384
64472
|
const hasParens = seg.includes("(") || seg.includes(")");
|
|
64385
64473
|
const hasAt = seg.includes("@");
|
|
64386
64474
|
const hasQuote = seg.includes('"');
|
|
64475
|
+
const hasCurly = seg.includes("{") || seg.includes("}");
|
|
64476
|
+
const hasBracket = seg.includes("[") || seg.includes("]");
|
|
64477
|
+
const isDoubleSquare = raw.slice(i, i + 2) === "[[" && raw.slice(j - 2, j) === "]]";
|
|
64387
64478
|
const isSingleQuoted = /^'[^]*'$/.test(trimmed);
|
|
64388
64479
|
const hasLeadingSlash = lsp === "/" || lsp === "\\";
|
|
64389
64480
|
if (!covered && !isQuoted && !isParenWrapped && hasParens) {
|
|
@@ -64401,6 +64492,16 @@ function validateFlowchart(text, options = {}) {
|
|
|
64401
64492
|
existing.push({ start: startCol, end: endCol });
|
|
64402
64493
|
byLine.set(ln, existing);
|
|
64403
64494
|
}
|
|
64495
|
+
if (!covered && !isQuoted && !isSlashPair && hasCurly) {
|
|
64496
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-CURLY-IN-UNQUOTED", message: "Curly braces are not supported inside unquoted node labels.", hint: "Use { and } for literal braces, e.g., C[Substitute {params}]." });
|
|
64497
|
+
existing.push({ start: startCol, end: endCol });
|
|
64498
|
+
byLine.set(ln, existing);
|
|
64499
|
+
}
|
|
64500
|
+
if (!covered && !isQuoted && !isSlashPair && !isDoubleSquare && hasBracket) {
|
|
64501
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-BRACKET-IN-UNQUOTED", message: "Square brackets are not supported inside unquoted node labels.", hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]' });
|
|
64502
|
+
existing.push({ start: startCol, end: endCol });
|
|
64503
|
+
byLine.set(ln, existing);
|
|
64504
|
+
}
|
|
64404
64505
|
if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
|
|
64405
64506
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility="true""]' });
|
|
64406
64507
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -66761,7 +66862,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
66761
66862
|
}
|
|
66762
66863
|
continue;
|
|
66763
66864
|
}
|
|
66764
|
-
if (is("FL-EDGE-LABEL-BRACKET", e)) {
|
|
66865
|
+
if (is("FL-EDGE-LABEL-BRACKET", e) || is("FL-EDGE-LABEL-CURLY-IN-PIPES", e)) {
|
|
66765
66866
|
const lineText = lineTextAt(text, e.line);
|
|
66766
66867
|
const firstBar = lineText.indexOf("|");
|
|
66767
66868
|
const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
|
|
@@ -66769,7 +66870,8 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
66769
66870
|
const before = lineText.slice(0, firstBar + 1);
|
|
66770
66871
|
const label = lineText.slice(firstBar + 1, secondBar);
|
|
66771
66872
|
const after = lineText.slice(secondBar);
|
|
66772
|
-
|
|
66873
|
+
let fixedLabel = label.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
66874
|
+
fixedLabel = fixedLabel.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
66773
66875
|
const fixedLine = before + fixedLabel + after;
|
|
66774
66876
|
const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m, seg) => "[" + String(seg).replace(/`/g, "") + "]");
|
|
66775
66877
|
edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: lineText.length + 1 }, newText: finalLine });
|
|
@@ -67409,7 +67511,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
67409
67511
|
}
|
|
67410
67512
|
continue;
|
|
67411
67513
|
}
|
|
67412
|
-
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
|
|
67514
|
+
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e) || is("FL-LABEL-CURLY-IN-UNQUOTED", e) || is("FL-LABEL-BRACKET-IN-UNQUOTED", e)) {
|
|
67413
67515
|
if (level === "safe" || level === "all") {
|
|
67414
67516
|
if (patchedLines.has(e.line))
|
|
67415
67517
|
continue;
|
|
@@ -67450,7 +67552,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
67450
67552
|
if (openIdx === -1)
|
|
67451
67553
|
break;
|
|
67452
67554
|
const contentStart = openIdx + shape.open.length;
|
|
67453
|
-
const closeIdx = shape.open === "(" && shape.close === ")" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
67555
|
+
const closeIdx = shape.open === "(" && shape.close === ")" || shape.open === "[" && shape.close === "]" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
67454
67556
|
if (closeIdx === -1)
|
|
67455
67557
|
break;
|
|
67456
67558
|
if (openIdx <= caret0 && caret0 < closeIdx) {
|
|
@@ -67470,11 +67572,21 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
67470
67572
|
const isSlashPair = (l, r) => l === "/" && r === "/" || l === "\\" && r === "\\" || l === "/" && r === "\\" || l === "\\" && r === "/";
|
|
67471
67573
|
const isParallelogramShape = core.length >= 2 && isSlashPair(left, right);
|
|
67472
67574
|
let replaced;
|
|
67473
|
-
if (!isParallelogramShape) {
|
|
67474
|
-
const
|
|
67575
|
+
if (is("FL-LABEL-BRACKET-IN-UNQUOTED", e) && !isParallelogramShape) {
|
|
67576
|
+
const hasOtherHazards = /[(){}@]/.test(inner) || inner.includes('"') || inner.includes('\\"');
|
|
67577
|
+
if (hasOtherHazards) {
|
|
67578
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
67579
|
+
replaced = '"' + escaped + '"';
|
|
67580
|
+
} else {
|
|
67581
|
+
replaced = inner.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
67582
|
+
}
|
|
67583
|
+
} else if (is("FL-LABEL-CURLY-IN-UNQUOTED", e)) {
|
|
67584
|
+
replaced = inner.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
67585
|
+
} else if (!isParallelogramShape) {
|
|
67586
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
67475
67587
|
replaced = '"' + escaped + '"';
|
|
67476
67588
|
} else {
|
|
67477
|
-
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\"/g, """).replace(/"/g, """);
|
|
67589
|
+
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\[/g, "[").replace(/\]/g, "]").replace(/\\"/g, """).replace(/"/g, """);
|
|
67478
67590
|
}
|
|
67479
67591
|
if (replaced !== inner) {
|
|
67480
67592
|
edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
|
package/cjs/index.cjs
CHANGED
|
@@ -27057,7 +27057,14 @@ function parseTargets(targets) {
|
|
|
27057
27057
|
}
|
|
27058
27058
|
function parseAndResolvePaths(pathStr, cwd) {
|
|
27059
27059
|
if (!pathStr) return [];
|
|
27060
|
-
|
|
27060
|
+
let paths = pathStr.split(",").map((p) => p.trim()).filter((p) => p.length > 0);
|
|
27061
|
+
paths = paths.flatMap((p) => {
|
|
27062
|
+
if (!/\s/.test(p)) return [p];
|
|
27063
|
+
const parts = p.split(/\s+/).filter(Boolean);
|
|
27064
|
+
if (parts.length <= 1) return [p];
|
|
27065
|
+
const allLookLikePaths = parts.every((part) => /[/\\]/.test(part) || /\.\w+/.test(part));
|
|
27066
|
+
return allLookLikePaths ? parts : [p];
|
|
27067
|
+
});
|
|
27061
27068
|
return paths.map((p) => {
|
|
27062
27069
|
if ((0, import_path5.isAbsolute)(p)) {
|
|
27063
27070
|
return p;
|
|
@@ -46720,6 +46727,7 @@ var init_parser2 = __esm({
|
|
|
46720
46727
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
46721
46728
|
{ ALT: () => this.CONSUME(Text) },
|
|
46722
46729
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
46730
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
46723
46731
|
// Note: RoundOpen and RoundClose (parentheses) are NOT allowed in unquoted labels
|
|
46724
46732
|
// to match Mermaid's behavior - use quoted labels like ["text (with parens)"] instead
|
|
46725
46733
|
// Allow HTML-like tags (e.g., <br/>) inside labels
|
|
@@ -46811,6 +46819,7 @@ var init_parser2 = __esm({
|
|
|
46811
46819
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
46812
46820
|
{ ALT: () => this.CONSUME(Text) },
|
|
46813
46821
|
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
46822
|
+
{ ALT: () => this.CONSUME(ColorValue) },
|
|
46814
46823
|
// Allow HTML-like angle brackets and slashes for <br/>, <i>, etc.
|
|
46815
46824
|
{ ALT: () => this.CONSUME(AngleLess) },
|
|
46816
46825
|
{ ALT: () => this.CONSUME(AngleOpen) },
|
|
@@ -47986,13 +47995,24 @@ function mapFlowchartParserError(err, text) {
|
|
|
47986
47995
|
length: len
|
|
47987
47996
|
};
|
|
47988
47997
|
}
|
|
47989
|
-
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
47998
|
+
if (tokType === "QuotedString" || tokType === "SquareOpen" || tokType === "SquareClose" || tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
47990
47999
|
const context = err?.context;
|
|
47991
48000
|
const inLinkRule = context?.ruleStack?.includes("linkTextInline") || context?.ruleStack?.includes("link") || false;
|
|
47992
48001
|
const lineContent = allLines[Math.max(0, line - 1)] || "";
|
|
47993
48002
|
const beforeQuote = lineContent.slice(0, Math.max(0, column - 1));
|
|
47994
48003
|
const hasLinkBefore = beforeQuote.match(/--\s*$|==\s*$|-\.\s*$|-\.-\s*$|\[\s*$/);
|
|
47995
48004
|
if (inLinkRule || hasLinkBefore) {
|
|
48005
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
48006
|
+
return {
|
|
48007
|
+
line,
|
|
48008
|
+
column,
|
|
48009
|
+
severity: "error",
|
|
48010
|
+
code: "FL-EDGE-LABEL-CURLY-IN-PIPES",
|
|
48011
|
+
message: "Curly braces { } are not supported inside pipe-delimited edge labels.",
|
|
48012
|
+
hint: "Use HTML entities { and } inside |...|, e.g., --|Resolve ${VAR}|-->",
|
|
48013
|
+
length: len
|
|
48014
|
+
};
|
|
48015
|
+
}
|
|
47996
48016
|
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
47997
48017
|
return {
|
|
47998
48018
|
line,
|
|
@@ -48054,6 +48074,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
48054
48074
|
length: len
|
|
48055
48075
|
};
|
|
48056
48076
|
}
|
|
48077
|
+
if (tokType === "DiamondOpen" || tokType === "DiamondClose") {
|
|
48078
|
+
return {
|
|
48079
|
+
line,
|
|
48080
|
+
column,
|
|
48081
|
+
severity: "error",
|
|
48082
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
48083
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
48084
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
48085
|
+
length: len
|
|
48086
|
+
};
|
|
48087
|
+
}
|
|
48057
48088
|
{
|
|
48058
48089
|
const caret0 = Math.max(0, column - 1);
|
|
48059
48090
|
const openIdx = lineStr.lastIndexOf("[", caret0);
|
|
@@ -48095,9 +48126,20 @@ function mapFlowchartParserError(err, text) {
|
|
|
48095
48126
|
length: len
|
|
48096
48127
|
};
|
|
48097
48128
|
}
|
|
48129
|
+
if (seg.includes("{") || seg.includes("}")) {
|
|
48130
|
+
return {
|
|
48131
|
+
line,
|
|
48132
|
+
column,
|
|
48133
|
+
severity: "error",
|
|
48134
|
+
code: "FL-LABEL-CURLY-IN-UNQUOTED",
|
|
48135
|
+
message: "Curly braces are not supported inside unquoted node labels.",
|
|
48136
|
+
hint: "Use { and } for literal braces, e.g., C[Substitute {params}].",
|
|
48137
|
+
length: len
|
|
48138
|
+
};
|
|
48139
|
+
}
|
|
48098
48140
|
}
|
|
48099
48141
|
}
|
|
48100
|
-
if (tokType === "QuotedString"
|
|
48142
|
+
if (tokType === "QuotedString") {
|
|
48101
48143
|
return {
|
|
48102
48144
|
line,
|
|
48103
48145
|
column,
|
|
@@ -48108,6 +48150,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
48108
48150
|
length: len
|
|
48109
48151
|
};
|
|
48110
48152
|
}
|
|
48153
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
48154
|
+
return {
|
|
48155
|
+
line,
|
|
48156
|
+
column,
|
|
48157
|
+
severity: "error",
|
|
48158
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
48159
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
48160
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
48161
|
+
length: len
|
|
48162
|
+
};
|
|
48163
|
+
}
|
|
48111
48164
|
const q = findInnerQuoteIssue("[");
|
|
48112
48165
|
if (q?.kind === "escaped") {
|
|
48113
48166
|
return { line, column: q.column, severity: "error", code: "FL-LABEL-ESCAPED-QUOTE", message: 'Escaped quotes (\\") in node labels are not supported by Mermaid. Use " instead.', hint: 'Prefer "He said "Hi"".', length: 2 };
|
|
@@ -48118,7 +48171,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
48118
48171
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '['. Add a matching ']' before the arrow or newline.", hint: "Example: A[Label] --> B", length: 1 };
|
|
48119
48172
|
}
|
|
48120
48173
|
if (expecting(err, "RoundClose")) {
|
|
48121
|
-
if (tokType === "QuotedString"
|
|
48174
|
+
if (tokType === "QuotedString") {
|
|
48122
48175
|
return {
|
|
48123
48176
|
line,
|
|
48124
48177
|
column,
|
|
@@ -48129,6 +48182,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
48129
48182
|
length: len
|
|
48130
48183
|
};
|
|
48131
48184
|
}
|
|
48185
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
48186
|
+
return {
|
|
48187
|
+
line,
|
|
48188
|
+
column,
|
|
48189
|
+
severity: "error",
|
|
48190
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
48191
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
48192
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
48193
|
+
length: len
|
|
48194
|
+
};
|
|
48195
|
+
}
|
|
48132
48196
|
{
|
|
48133
48197
|
const caret0 = Math.max(0, column - 1);
|
|
48134
48198
|
const openIdx = lineStr.lastIndexOf("(", caret0);
|
|
@@ -48157,7 +48221,7 @@ function mapFlowchartParserError(err, text) {
|
|
|
48157
48221
|
return { line, column, severity: "error", code: "FL-NODE-UNCLOSED-BRACKET", message: "Unclosed '('. Add a matching ')'.", hint: "Example: B(Label)", length: 1 };
|
|
48158
48222
|
}
|
|
48159
48223
|
if (expecting(err, "DiamondClose")) {
|
|
48160
|
-
if (tokType === "QuotedString"
|
|
48224
|
+
if (tokType === "QuotedString") {
|
|
48161
48225
|
return {
|
|
48162
48226
|
line,
|
|
48163
48227
|
column,
|
|
@@ -48168,6 +48232,17 @@ function mapFlowchartParserError(err, text) {
|
|
|
48168
48232
|
length: len
|
|
48169
48233
|
};
|
|
48170
48234
|
}
|
|
48235
|
+
if (tokType === "SquareOpen" || tokType === "SquareClose") {
|
|
48236
|
+
return {
|
|
48237
|
+
line,
|
|
48238
|
+
column,
|
|
48239
|
+
severity: "error",
|
|
48240
|
+
code: "FL-LABEL-BRACKET-IN-UNQUOTED",
|
|
48241
|
+
message: "Square brackets are not supported inside unquoted node labels.",
|
|
48242
|
+
hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]',
|
|
48243
|
+
length: len
|
|
48244
|
+
};
|
|
48245
|
+
}
|
|
48171
48246
|
{
|
|
48172
48247
|
const caret0 = Math.max(0, column - 1);
|
|
48173
48248
|
const openIdx = lineStr.lastIndexOf("{", caret0);
|
|
@@ -49010,7 +49085,7 @@ function validateFlowchart(text, options = {}) {
|
|
|
49010
49085
|
const byLine = /* @__PURE__ */ new Map();
|
|
49011
49086
|
const collect = (arr) => {
|
|
49012
49087
|
for (const e of arr || []) {
|
|
49013
|
-
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED")) {
|
|
49088
|
+
if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e.code === "FL-LABEL-SLASH-UNQUOTED" || e.code === "FL-LABEL-CURLY-IN-UNQUOTED" || e.code === "FL-LABEL-BRACKET-IN-UNQUOTED")) {
|
|
49014
49089
|
const ln = e.line ?? 0;
|
|
49015
49090
|
const col = e.column ?? 1;
|
|
49016
49091
|
const list = byLine.get(ln) || [];
|
|
@@ -49092,6 +49167,9 @@ function validateFlowchart(text, options = {}) {
|
|
|
49092
49167
|
const hasParens = seg.includes("(") || seg.includes(")");
|
|
49093
49168
|
const hasAt = seg.includes("@");
|
|
49094
49169
|
const hasQuote = seg.includes('"');
|
|
49170
|
+
const hasCurly = seg.includes("{") || seg.includes("}");
|
|
49171
|
+
const hasBracket = seg.includes("[") || seg.includes("]");
|
|
49172
|
+
const isDoubleSquare = raw.slice(i, i + 2) === "[[" && raw.slice(j - 2, j) === "]]";
|
|
49095
49173
|
const isSingleQuoted = /^'[^]*'$/.test(trimmed);
|
|
49096
49174
|
const hasLeadingSlash = lsp === "/" || lsp === "\\";
|
|
49097
49175
|
if (!covered && !isQuoted && !isParenWrapped && hasParens) {
|
|
@@ -49109,6 +49187,16 @@ function validateFlowchart(text, options = {}) {
|
|
|
49109
49187
|
existing.push({ start: startCol, end: endCol });
|
|
49110
49188
|
byLine.set(ln, existing);
|
|
49111
49189
|
}
|
|
49190
|
+
if (!covered && !isQuoted && !isSlashPair && hasCurly) {
|
|
49191
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-CURLY-IN-UNQUOTED", message: "Curly braces are not supported inside unquoted node labels.", hint: "Use { and } for literal braces, e.g., C[Substitute {params}]." });
|
|
49192
|
+
existing.push({ start: startCol, end: endCol });
|
|
49193
|
+
byLine.set(ln, existing);
|
|
49194
|
+
}
|
|
49195
|
+
if (!covered && !isQuoted && !isSlashPair && !isDoubleSquare && hasBracket) {
|
|
49196
|
+
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-BRACKET-IN-UNQUOTED", message: "Square brackets are not supported inside unquoted node labels.", hint: 'Use [ and ] for literal brackets or wrap the label in quotes, e.g., C["bind_paths[]"]' });
|
|
49197
|
+
existing.push({ start: startCol, end: endCol });
|
|
49198
|
+
byLine.set(ln, existing);
|
|
49199
|
+
}
|
|
49112
49200
|
if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
|
|
49113
49201
|
errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use " for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility="true""]' });
|
|
49114
49202
|
existing.push({ start: startCol, end: endCol });
|
|
@@ -51469,7 +51557,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
51469
51557
|
}
|
|
51470
51558
|
continue;
|
|
51471
51559
|
}
|
|
51472
|
-
if (is("FL-EDGE-LABEL-BRACKET", e)) {
|
|
51560
|
+
if (is("FL-EDGE-LABEL-BRACKET", e) || is("FL-EDGE-LABEL-CURLY-IN-PIPES", e)) {
|
|
51473
51561
|
const lineText = lineTextAt(text, e.line);
|
|
51474
51562
|
const firstBar = lineText.indexOf("|");
|
|
51475
51563
|
const secondBar = firstBar >= 0 ? lineText.indexOf("|", firstBar + 1) : -1;
|
|
@@ -51477,7 +51565,8 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
51477
51565
|
const before = lineText.slice(0, firstBar + 1);
|
|
51478
51566
|
const label = lineText.slice(firstBar + 1, secondBar);
|
|
51479
51567
|
const after = lineText.slice(secondBar);
|
|
51480
|
-
|
|
51568
|
+
let fixedLabel = label.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
51569
|
+
fixedLabel = fixedLabel.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
51481
51570
|
const fixedLine = before + fixedLabel + after;
|
|
51482
51571
|
const finalLine = fixedLine.replace(/\[([^\]]*)\]/g, (m, seg) => "[" + String(seg).replace(/`/g, "") + "]");
|
|
51483
51572
|
edits.push({ start: { line: e.line, column: 1 }, end: { line: e.line, column: lineText.length + 1 }, newText: finalLine });
|
|
@@ -52117,7 +52206,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
52117
52206
|
}
|
|
52118
52207
|
continue;
|
|
52119
52208
|
}
|
|
52120
|
-
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
|
|
52209
|
+
if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e) || is("FL-LABEL-CURLY-IN-UNQUOTED", e) || is("FL-LABEL-BRACKET-IN-UNQUOTED", e)) {
|
|
52121
52210
|
if (level === "safe" || level === "all") {
|
|
52122
52211
|
if (patchedLines.has(e.line))
|
|
52123
52212
|
continue;
|
|
@@ -52158,7 +52247,7 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
52158
52247
|
if (openIdx === -1)
|
|
52159
52248
|
break;
|
|
52160
52249
|
const contentStart = openIdx + shape.open.length;
|
|
52161
|
-
const closeIdx = shape.open === "(" && shape.close === ")" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
52250
|
+
const closeIdx = shape.open === "(" && shape.close === ")" || shape.open === "[" && shape.close === "]" ? findMatchingCloser(lineText, openIdx, shape.open, shape.close) : lineText.indexOf(shape.close, contentStart);
|
|
52162
52251
|
if (closeIdx === -1)
|
|
52163
52252
|
break;
|
|
52164
52253
|
if (openIdx <= caret0 && caret0 < closeIdx) {
|
|
@@ -52178,11 +52267,21 @@ function computeFixes(text, errors, level = "safe") {
|
|
|
52178
52267
|
const isSlashPair = (l, r) => l === "/" && r === "/" || l === "\\" && r === "\\" || l === "/" && r === "\\" || l === "\\" && r === "/";
|
|
52179
52268
|
const isParallelogramShape = core.length >= 2 && isSlashPair(left, right);
|
|
52180
52269
|
let replaced;
|
|
52181
|
-
if (!isParallelogramShape) {
|
|
52182
|
-
const
|
|
52270
|
+
if (is("FL-LABEL-BRACKET-IN-UNQUOTED", e) && !isParallelogramShape) {
|
|
52271
|
+
const hasOtherHazards = /[(){}@]/.test(inner) || inner.includes('"') || inner.includes('\\"');
|
|
52272
|
+
if (hasOtherHazards) {
|
|
52273
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
52274
|
+
replaced = '"' + escaped + '"';
|
|
52275
|
+
} else {
|
|
52276
|
+
replaced = inner.replace(/\[/g, "[").replace(/\]/g, "]");
|
|
52277
|
+
}
|
|
52278
|
+
} else if (is("FL-LABEL-CURLY-IN-UNQUOTED", e)) {
|
|
52279
|
+
replaced = inner.replace(/\{/g, "{").replace(/\}/g, "}");
|
|
52280
|
+
} else if (!isParallelogramShape) {
|
|
52281
|
+
const escaped = inner.replace(/`/g, "").replace(/\\"/g, """).replace(/"/g, """);
|
|
52183
52282
|
replaced = '"' + escaped + '"';
|
|
52184
52283
|
} else {
|
|
52185
|
-
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\"/g, """).replace(/"/g, """);
|
|
52284
|
+
replaced = inner.replace(/`/g, "").replace(/\(/g, "(").replace(/\)/g, ")").replace(/\[/g, "[").replace(/\]/g, "]").replace(/\\"/g, """).replace(/"/g, """);
|
|
52186
52285
|
}
|
|
52187
52286
|
if (replaced !== inner) {
|
|
52188
52287
|
edits.push({ start: { line: e.line, column: contentStart + 1 }, end: { line: e.line, column: closeIdx + 1 }, newText: replaced });
|
|
@@ -100920,11 +101019,24 @@ function normalizeTargets(targets) {
|
|
|
100920
101019
|
if (typeof target !== "string") continue;
|
|
100921
101020
|
const trimmed = target.trim();
|
|
100922
101021
|
if (!trimmed || seen.has(trimmed)) continue;
|
|
100923
|
-
|
|
100924
|
-
|
|
101022
|
+
const subTargets = splitSpaceSeparatedPaths(trimmed);
|
|
101023
|
+
for (const sub of subTargets) {
|
|
101024
|
+
if (!seen.has(sub)) {
|
|
101025
|
+
seen.add(sub);
|
|
101026
|
+
normalized.push(sub);
|
|
101027
|
+
}
|
|
101028
|
+
}
|
|
100925
101029
|
}
|
|
100926
101030
|
return normalized;
|
|
100927
101031
|
}
|
|
101032
|
+
function splitSpaceSeparatedPaths(target) {
|
|
101033
|
+
if (!/\s/.test(target)) return [target];
|
|
101034
|
+
const parts = target.split(/\s+/).filter(Boolean);
|
|
101035
|
+
if (parts.length <= 1) return [target];
|
|
101036
|
+
const allLookLikePaths = parts.every((p) => /[/\\]/.test(p) || /\.\w+/.test(p));
|
|
101037
|
+
if (allLookLikePaths) return parts;
|
|
101038
|
+
return [target];
|
|
101039
|
+
}
|
|
100928
101040
|
function extractJsonSnippet(text) {
|
|
100929
101041
|
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
|
|
100930
101042
|
if (jsonBlockMatch) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@probelabs/probe",
|
|
3
|
-
"version": "0.6.0-
|
|
3
|
+
"version": "0.6.0-rc287",
|
|
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,11 +80,11 @@
|
|
|
80
80
|
"@anthropic-ai/claude-agent-sdk": "^0.1.46",
|
|
81
81
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
82
82
|
"@nyariv/sandboxjs": "github:probelabs/SandboxJS",
|
|
83
|
-
"@probelabs/maid": "^0.0.
|
|
83
|
+
"@probelabs/maid": "^0.0.27",
|
|
84
84
|
"acorn": "^8.15.0",
|
|
85
85
|
"acorn-walk": "^8.3.4",
|
|
86
86
|
"adm-zip": "^0.5.16",
|
|
87
|
-
"ai": "^6.0.
|
|
87
|
+
"ai": "^6.0.0",
|
|
88
88
|
"ajv": "^8.17.1",
|
|
89
89
|
"astring": "^1.9.0",
|
|
90
90
|
"axios": "^1.8.3",
|
package/src/tools/common.js
CHANGED
|
@@ -228,7 +228,17 @@ export function parseAndResolvePaths(pathStr, cwd) {
|
|
|
228
228
|
if (!pathStr) return [];
|
|
229
229
|
|
|
230
230
|
// Split on comma and trim whitespace
|
|
231
|
-
|
|
231
|
+
let paths = pathStr.split(',').map(p => p.trim()).filter(p => p.length > 0);
|
|
232
|
+
|
|
233
|
+
// Auto-fix: model sometimes passes space-separated file paths as one string
|
|
234
|
+
// e.g. "src/ranking.rs src/simd_ranking.rs" — split if each part looks like a path
|
|
235
|
+
paths = paths.flatMap(p => {
|
|
236
|
+
if (!/\s/.test(p)) return [p];
|
|
237
|
+
const parts = p.split(/\s+/).filter(Boolean);
|
|
238
|
+
if (parts.length <= 1) return [p];
|
|
239
|
+
const allLookLikePaths = parts.every(part => /[/\\]/.test(part) || /\.\w+/.test(part));
|
|
240
|
+
return allLookLikePaths ? parts : [p];
|
|
241
|
+
});
|
|
232
242
|
|
|
233
243
|
// Resolve relative paths against cwd
|
|
234
244
|
return paths.map(p => {
|
package/src/tools/vercel.js
CHANGED
|
@@ -105,13 +105,42 @@ function normalizeTargets(targets) {
|
|
|
105
105
|
if (typeof target !== 'string') continue;
|
|
106
106
|
const trimmed = target.trim();
|
|
107
107
|
if (!trimmed || seen.has(trimmed)) continue;
|
|
108
|
-
|
|
109
|
-
|
|
108
|
+
|
|
109
|
+
// Auto-fix: model sometimes puts multiple space-separated file paths in one string
|
|
110
|
+
// e.g. "src/ranking.rs src/simd_ranking.rs" — split them apart
|
|
111
|
+
const subTargets = splitSpaceSeparatedPaths(trimmed);
|
|
112
|
+
for (const sub of subTargets) {
|
|
113
|
+
if (!seen.has(sub)) {
|
|
114
|
+
seen.add(sub);
|
|
115
|
+
normalized.push(sub);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
return normalized;
|
|
113
121
|
}
|
|
114
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Split a string that may contain multiple space-separated file paths.
|
|
125
|
+
* Detects patterns like "path/file.ext path2/file2.ext" and splits them.
|
|
126
|
+
* Preserves single paths and paths with suffixes like ":10-20" or "#Symbol".
|
|
127
|
+
*/
|
|
128
|
+
function splitSpaceSeparatedPaths(target) {
|
|
129
|
+
// If no spaces, it's a single target
|
|
130
|
+
if (!/\s/.test(target)) return [target];
|
|
131
|
+
|
|
132
|
+
// Split on whitespace and check if parts look like file paths
|
|
133
|
+
const parts = target.split(/\s+/).filter(Boolean);
|
|
134
|
+
if (parts.length <= 1) return [target];
|
|
135
|
+
|
|
136
|
+
// Check if each part looks like a file path (has a dot extension or path separator)
|
|
137
|
+
const allLookLikePaths = parts.every(p => /[/\\]/.test(p) || /\.\w+/.test(p));
|
|
138
|
+
if (allLookLikePaths) return parts;
|
|
139
|
+
|
|
140
|
+
// Not confident these are separate paths — return as-is
|
|
141
|
+
return [target];
|
|
142
|
+
}
|
|
143
|
+
|
|
115
144
|
function extractJsonSnippet(text) {
|
|
116
145
|
const jsonBlockMatch = text.match(/```json\s*([\s\S]*?)```/i);
|
|
117
146
|
if (jsonBlockMatch) {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|