@probelabs/probe 0.6.0-rc264 → 0.6.0-rc265

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.
@@ -2771,6 +2771,7 @@ Follow these instructions carefully:
2771
2771
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
2772
2772
  * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ''}
2773
2773
  * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? ' and hashes' : ''}, then use start_line/end_line to surgically edit specific lines within it.
2774
+ * IMPORTANT: Keep old_string as small as possible — include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
2774
2775
  - Use 'create' for new files or complete file rewrites.
2775
2776
  - If an edit fails, read the error message — it tells you exactly how to fix the call and retry.
2776
2777
  - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ''}
@@ -9553,6 +9553,11 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
9553
9553
  if (!replace_all && occurrences > 1) {
9554
9554
  return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
9555
9555
  }
9556
+ const oldLines = matchTarget.split("\n").length;
9557
+ const newLines = new_string.split("\n").length;
9558
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
9559
+ return `Error editing file: Edit scope too large \u2014 replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
9560
+ }
9556
9561
  let newContent;
9557
9562
  if (replace_all) {
9558
9563
  newContent = content.replaceAll(matchTarget, new_string);
@@ -47588,7 +47593,7 @@ function validateFlowchart(text, options = {}) {
47588
47593
  const byLine = /* @__PURE__ */ new Map();
47589
47594
  const collect = (arr) => {
47590
47595
  for (const e of arr || []) {
47591
- if (e && (e.code === "FL-LABEL-PARENS-UNQUOTED" || e.code === "FL-LABEL-AT-IN-UNQUOTED" || e.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
47596
+ 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")) {
47592
47597
  const ln = e.line ?? 0;
47593
47598
  const col = e.column ?? 1;
47594
47599
  const list = byLine.get(ln) || [];
@@ -47671,6 +47676,7 @@ function validateFlowchart(text, options = {}) {
47671
47676
  const hasAt = seg.includes("@");
47672
47677
  const hasQuote = seg.includes('"');
47673
47678
  const isSingleQuoted = /^'[^]*'$/.test(trimmed);
47679
+ const hasLeadingSlash = lsp === "/" || lsp === "\\";
47674
47680
  if (!covered && !isQuoted && !isParenWrapped && hasParens) {
47675
47681
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: &#40; and &#41;.' });
47676
47682
  existing.push({ start: startCol, end: endCol });
@@ -47681,6 +47687,11 @@ function validateFlowchart(text, options = {}) {
47681
47687
  existing.push({ start: startCol, end: endCol });
47682
47688
  byLine.set(ln, existing);
47683
47689
  }
47690
+ if (!covered && !isQuoted && !isSlashPair && hasLeadingSlash) {
47691
+ errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-SLASH-UNQUOTED", message: "Leading / or \\ inside an unquoted label is treated as a shape marker by Mermaid.", hint: 'Wrap the label in quotes, e.g., F["/dev/tty unavailable"], or use &#47; / &#92; for literal slashes.' });
47692
+ existing.push({ start: startCol, end: endCol });
47693
+ byLine.set(ln, existing);
47694
+ }
47684
47695
  if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
47685
47696
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use &quot; for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility=&quot;true&quot;"]' });
47686
47697
  existing.push({ start: startCol, end: endCol });
@@ -50689,7 +50700,7 @@ function computeFixes(text, errors, level = "safe") {
50689
50700
  }
50690
50701
  continue;
50691
50702
  }
50692
- if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e)) {
50703
+ if (is("FL-LABEL-PARENS-UNQUOTED", e) || is("FL-LABEL-AT-IN-UNQUOTED", e) || is("FL-LABEL-SLASH-UNQUOTED", e)) {
50693
50704
  if (level === "safe" || level === "all") {
50694
50705
  if (patchedLines.has(e.line))
50695
50706
  continue;
@@ -71984,6 +71995,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
71984
71995
  - Avoid implementing special cases when a general approach works
71985
71996
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
71986
71997
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
71998
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) \u2014 it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
71987
71999
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
71988
72000
 
71989
72001
  # After Implementation
@@ -71994,11 +72006,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
71994
72006
 
71995
72007
  # GitHub Integration
71996
72008
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
71997
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
71998
72009
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
71999
72010
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
72000
72011
  - Always return the pull request URL to the user after creating one.
72001
- - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
72012
+ - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
72013
+
72014
+ # Pull Request Creation
72015
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
72016
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
72017
+ - **PR body**: MUST follow this structure:
72018
+
72019
+ \`\`\`
72020
+ ## Problem / Task
72021
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
72022
+
72023
+ ## Changes
72024
+ <Concise list of what was actually changed. Describe each meaningful change \u2014 files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
72025
+
72026
+ ## Testing
72027
+ <What tests were added, modified, or run. Include:
72028
+ - New test names and what they verify
72029
+ - Whether existing tests still pass
72030
+ - Manual verification steps if applicable
72031
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
72032
+ \`\`\`
72033
+
72034
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
72035
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
72002
72036
  "support": `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
72003
72037
 
72004
72038
  When troubleshooting:
@@ -85264,6 +85298,7 @@ Follow these instructions carefully:
85264
85298
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
85265
85299
  * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ""}
85266
85300
  * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? " and hashes" : ""}, then use start_line/end_line to surgically edit specific lines within it.
85301
+ * IMPORTANT: Keep old_string as small as possible \u2014 include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
85267
85302
  - Use 'create' for new files or complete file rewrites.
85268
85303
  - If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
85269
85304
  - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ""}
@@ -87,6 +87,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
87
87
  - Avoid implementing special cases when a general approach works
88
88
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
89
89
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
90
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) — it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
90
91
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
91
92
 
92
93
  # After Implementation
@@ -97,11 +98,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
97
98
 
98
99
  # GitHub Integration
99
100
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
100
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
101
101
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
102
102
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
103
103
  - Always return the pull request URL to the user after creating one.
104
- - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
104
+ - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
105
+
106
+ # Pull Request Creation
107
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
108
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
109
+ - **PR body**: MUST follow this structure:
110
+
111
+ \`\`\`
112
+ ## Problem / Task
113
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
114
+
115
+ ## Changes
116
+ <Concise list of what was actually changed. Describe each meaningful change — files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
117
+
118
+ ## Testing
119
+ <What tests were added, modified, or run. Include:
120
+ - New test names and what they verify
121
+ - Whether existing tests still pass
122
+ - Manual verification steps if applicable
123
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
124
+ \`\`\`
125
+
126
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
127
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
105
128
 
106
129
  'support': `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
107
130
 
@@ -448,6 +448,13 @@ Parameters:
448
448
  return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
449
449
  }
450
450
 
451
+ // Guard against over-scoped text edits (replacing large blocks with tiny replacements)
452
+ const oldLines = matchTarget.split('\n').length;
453
+ const newLines = new_string.split('\n').length;
454
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
455
+ return `Error editing file: Edit scope too large — replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
456
+ }
457
+
451
458
  // Perform the replacement
452
459
  let newContent;
453
460
  if (replace_all) {
@@ -37025,6 +37025,11 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
37025
37025
  if (!replace_all && occurrences > 1) {
37026
37026
  return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
37027
37027
  }
37028
+ const oldLines = matchTarget.split("\n").length;
37029
+ const newLines = new_string.split("\n").length;
37030
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
37031
+ return `Error editing file: Edit scope too large \u2014 replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
37032
+ }
37028
37033
  let newContent;
37029
37034
  if (replace_all) {
37030
37035
  newContent = content.replaceAll(matchTarget, new_string);
@@ -74627,7 +74632,7 @@ function validateFlowchart(text, options = {}) {
74627
74632
  const byLine = /* @__PURE__ */ new Map();
74628
74633
  const collect = (arr) => {
74629
74634
  for (const e5 of arr || []) {
74630
- if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
74635
+ if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e5.code === "FL-LABEL-SLASH-UNQUOTED")) {
74631
74636
  const ln = e5.line ?? 0;
74632
74637
  const col = e5.column ?? 1;
74633
74638
  const list2 = byLine.get(ln) || [];
@@ -74710,6 +74715,7 @@ function validateFlowchart(text, options = {}) {
74710
74715
  const hasAt = seg.includes("@");
74711
74716
  const hasQuote = seg.includes('"');
74712
74717
  const isSingleQuoted = /^'[^]*'$/.test(trimmed);
74718
+ const hasLeadingSlash = lsp === "/" || lsp === "\\";
74713
74719
  if (!covered && !isQuoted && !isParenWrapped && hasParens) {
74714
74720
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: &#40; and &#41;.' });
74715
74721
  existing.push({ start: startCol, end: endCol });
@@ -74720,6 +74726,11 @@ function validateFlowchart(text, options = {}) {
74720
74726
  existing.push({ start: startCol, end: endCol });
74721
74727
  byLine.set(ln, existing);
74722
74728
  }
74729
+ if (!covered && !isQuoted && !isSlashPair && hasLeadingSlash) {
74730
+ errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-SLASH-UNQUOTED", message: "Leading / or \\ inside an unquoted label is treated as a shape marker by Mermaid.", hint: 'Wrap the label in quotes, e.g., F["/dev/tty unavailable"], or use &#47; / &#92; for literal slashes.' });
74731
+ existing.push({ start: startCol, end: endCol });
74732
+ byLine.set(ln, existing);
74733
+ }
74723
74734
  if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
74724
74735
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use &quot; for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility=&quot;true&quot;"]' });
74725
74736
  existing.push({ start: startCol, end: endCol });
@@ -77728,7 +77739,7 @@ function computeFixes(text, errors, level = "safe") {
77728
77739
  }
77729
77740
  continue;
77730
77741
  }
77731
- if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5)) {
77742
+ if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5) || is("FL-LABEL-SLASH-UNQUOTED", e5)) {
77732
77743
  if (level === "safe" || level === "all") {
77733
77744
  if (patchedLines.has(e5.line))
77734
77745
  continue;
@@ -99023,6 +99034,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
99023
99034
  - Avoid implementing special cases when a general approach works
99024
99035
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
99025
99036
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
99037
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) \u2014 it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
99026
99038
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
99027
99039
 
99028
99040
  # After Implementation
@@ -99033,11 +99045,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
99033
99045
 
99034
99046
  # GitHub Integration
99035
99047
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
99036
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
99037
99048
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
99038
99049
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
99039
99050
  - Always return the pull request URL to the user after creating one.
99040
- - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
99051
+ - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
99052
+
99053
+ # Pull Request Creation
99054
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
99055
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
99056
+ - **PR body**: MUST follow this structure:
99057
+
99058
+ \`\`\`
99059
+ ## Problem / Task
99060
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
99061
+
99062
+ ## Changes
99063
+ <Concise list of what was actually changed. Describe each meaningful change \u2014 files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
99064
+
99065
+ ## Testing
99066
+ <What tests were added, modified, or run. Include:
99067
+ - New test names and what they verify
99068
+ - Whether existing tests still pass
99069
+ - Manual verification steps if applicable
99070
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
99071
+ \`\`\`
99072
+
99073
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
99074
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
99041
99075
  "support": `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
99042
99076
 
99043
99077
  When troubleshooting:
@@ -112302,6 +112336,7 @@ Follow these instructions carefully:
112302
112336
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
112303
112337
  * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ""}
112304
112338
  * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? " and hashes" : ""}, then use start_line/end_line to surgically edit specific lines within it.
112339
+ * IMPORTANT: Keep old_string as small as possible \u2014 include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
112305
112340
  - Use 'create' for new files or complete file rewrites.
112306
112341
  - If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
112307
112342
  - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ""}
package/cjs/index.cjs CHANGED
@@ -36188,6 +36188,11 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
36188
36188
  if (!replace_all && occurrences > 1) {
36189
36189
  return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
36190
36190
  }
36191
+ const oldLines = matchTarget.split("\n").length;
36192
+ const newLines = new_string.split("\n").length;
36193
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
36194
+ return `Error editing file: Edit scope too large \u2014 replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
36195
+ }
36191
36196
  let newContent;
36192
36197
  if (replace_all) {
36193
36198
  newContent = content.replaceAll(matchTarget, new_string);
@@ -60262,7 +60267,7 @@ function validateFlowchart(text, options = {}) {
60262
60267
  const byLine = /* @__PURE__ */ new Map();
60263
60268
  const collect = (arr) => {
60264
60269
  for (const e5 of arr || []) {
60265
- if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED")) {
60270
+ if (e5 && (e5.code === "FL-LABEL-PARENS-UNQUOTED" || e5.code === "FL-LABEL-AT-IN-UNQUOTED" || e5.code === "FL-LABEL-QUOTE-IN-UNQUOTED" || e5.code === "FL-LABEL-SLASH-UNQUOTED")) {
60266
60271
  const ln = e5.line ?? 0;
60267
60272
  const col = e5.column ?? 1;
60268
60273
  const list2 = byLine.get(ln) || [];
@@ -60345,6 +60350,7 @@ function validateFlowchart(text, options = {}) {
60345
60350
  const hasAt = seg.includes("@");
60346
60351
  const hasQuote = seg.includes('"');
60347
60352
  const isSingleQuoted = /^'[^]*'$/.test(trimmed);
60353
+ const hasLeadingSlash = lsp === "/" || lsp === "\\";
60348
60354
  if (!covered && !isQuoted && !isParenWrapped && hasParens) {
60349
60355
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-PARENS-UNQUOTED", message: "Parentheses inside an unquoted label are not supported by Mermaid.", hint: 'Wrap the label in quotes, e.g., A["Mark (X)"] \u2014 or replace ( and ) with HTML entities: &#40; and &#41;.' });
60350
60356
  existing.push({ start: startCol, end: endCol });
@@ -60355,6 +60361,11 @@ function validateFlowchart(text, options = {}) {
60355
60361
  existing.push({ start: startCol, end: endCol });
60356
60362
  byLine.set(ln, existing);
60357
60363
  }
60364
+ if (!covered && !isQuoted && !isSlashPair && hasLeadingSlash) {
60365
+ errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-SLASH-UNQUOTED", message: "Leading / or \\ inside an unquoted label is treated as a shape marker by Mermaid.", hint: 'Wrap the label in quotes, e.g., F["/dev/tty unavailable"], or use &#47; / &#92; for literal slashes.' });
60366
+ existing.push({ start: startCol, end: endCol });
60367
+ byLine.set(ln, existing);
60368
+ }
60358
60369
  if (!covered && !isQuoted && !isSlashPair && hasQuote && !isSingleQuoted) {
60359
60370
  errs.push({ line: ln, column: startCol, severity: "error", code: "FL-LABEL-QUOTE-IN-UNQUOTED", message: "Quotes are not allowed inside unquoted node labels. Use &quot; for quotes or wrap the entire label in quotes.", hint: 'Example: C["HTML Output: data-trigger-visibility=&quot;true&quot;"]' });
60360
60371
  existing.push({ start: startCol, end: endCol });
@@ -63363,7 +63374,7 @@ function computeFixes(text, errors, level = "safe") {
63363
63374
  }
63364
63375
  continue;
63365
63376
  }
63366
- if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5)) {
63377
+ if (is("FL-LABEL-PARENS-UNQUOTED", e5) || is("FL-LABEL-AT-IN-UNQUOTED", e5) || is("FL-LABEL-SLASH-UNQUOTED", e5)) {
63367
63378
  if (level === "safe" || level === "all") {
63368
63379
  if (patchedLines.has(e5.line))
63369
63380
  continue;
@@ -84658,6 +84669,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
84658
84669
  - Avoid implementing special cases when a general approach works
84659
84670
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
84660
84671
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
84672
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) \u2014 it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
84661
84673
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
84662
84674
 
84663
84675
  # After Implementation
@@ -84668,11 +84680,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
84668
84680
 
84669
84681
  # GitHub Integration
84670
84682
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
84671
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
84672
84683
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
84673
84684
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
84674
84685
  - Always return the pull request URL to the user after creating one.
84675
- - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
84686
+ - When checking GitHub Actions, only read logs of failed jobs \u2014 do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
84687
+
84688
+ # Pull Request Creation
84689
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
84690
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
84691
+ - **PR body**: MUST follow this structure:
84692
+
84693
+ \`\`\`
84694
+ ## Problem / Task
84695
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
84696
+
84697
+ ## Changes
84698
+ <Concise list of what was actually changed. Describe each meaningful change \u2014 files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
84699
+
84700
+ ## Testing
84701
+ <What tests were added, modified, or run. Include:
84702
+ - New test names and what they verify
84703
+ - Whether existing tests still pass
84704
+ - Manual verification steps if applicable
84705
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
84706
+ \`\`\`
84707
+
84708
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
84709
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
84676
84710
  "support": `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
84677
84711
 
84678
84712
  When troubleshooting:
@@ -110620,6 +110654,7 @@ Follow these instructions carefully:
110620
110654
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
110621
110655
  * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ""}
110622
110656
  * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? " and hashes" : ""}, then use start_line/end_line to surgically edit specific lines within it.
110657
+ * IMPORTANT: Keep old_string as small as possible \u2014 include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
110623
110658
  - Use 'create' for new files or complete file rewrites.
110624
110659
  - If an edit fails, read the error message \u2014 it tells you exactly how to fix the call and retry.
110625
110660
  - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc264",
3
+ "version": "0.6.0-rc265",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -80,7 +80,7 @@
80
80
  "@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.25",
83
+ "@probelabs/maid": "^0.0.26",
84
84
  "acorn": "^8.15.0",
85
85
  "acorn-walk": "^8.3.4",
86
86
  "adm-zip": "^0.5.16",
@@ -2771,6 +2771,7 @@ Follow these instructions carefully:
2771
2771
  * For rewriting entire functions/classes/methods, use the symbol parameter instead (no exact text matching needed).
2772
2772
  * For editing specific lines from search/extract output, use start_line (and optionally end_line) with the line numbers shown in the output.${this.hashLines ? ' Line references include content hashes (e.g. "42:ab") for integrity verification.' : ''}
2773
2773
  * For editing inside large functions: first use extract with the symbol target (e.g. "file.js#myFunction") to see the function with line numbers${this.hashLines ? ' and hashes' : ''}, then use start_line/end_line to surgically edit specific lines within it.
2774
+ * IMPORTANT: Keep old_string as small as possible — include only the lines you need to change plus minimal context for uniqueness. For replacing large blocks (10+ lines), prefer line-targeted editing with start_line/end_line to constrain scope.
2774
2775
  - Use 'create' for new files or complete file rewrites.
2775
2776
  - If an edit fails, read the error message — it tells you exactly how to fix the call and retry.
2776
2777
  - The system tracks which files you've seen via search/extract. If you try to edit a file you haven't read, or one that changed since you last read it, the edit will fail with instructions to re-read first. Always use extract before editing to ensure you have current file content.` : ''}
@@ -87,6 +87,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
87
87
  - Avoid implementing special cases when a general approach works
88
88
  - Never expose secrets, API keys, or credentials in generated code. Never log sensitive information.
89
89
  - Do not surprise the user with unrequested changes. Do what was asked, including reasonable follow-up actions, but do not refactor surrounding code or add features that were not requested.
90
+ - When editing files, keep edits focused and minimal. For changes spanning more than a few lines, prefer line-targeted editing (start_line/end_line) over text replacement (old_string) — it constrains scope and prevents accidental removal of adjacent content. Never include unrelated sections in an edit operation.
90
91
  - After every significant change, verify the project still builds and passes linting. Do not wait until the end to discover breakage.
91
92
 
92
93
  # After Implementation
@@ -97,11 +98,33 @@ If the solution is clear, you can jump to implementation right away. If not, ask
97
98
 
98
99
  # GitHub Integration
99
100
  - Use the \`gh\` CLI for all GitHub operations: issues, pull requests, checks, releases.
100
- - To create a pull request: commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
101
101
  - To view issues or PRs: \`gh issue view <number>\`, \`gh pr view <number>\`.
102
102
  - If given a GitHub URL, use \`gh\` to fetch the relevant information rather than guessing.
103
103
  - Always return the pull request URL to the user after creating one.
104
- - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.`,
104
+ - When checking GitHub Actions, only read logs of failed jobs — do not waste time on successful ones. Use \`gh run view <run-id> --log-failed\` to fetch only the relevant output.
105
+
106
+ # Pull Request Creation
107
+ - Commit your changes, push the branch, then use \`gh pr create --title "..." --body "..."\`.
108
+ - **PR title**: Keep it short (under 72 characters). Use imperative mood describing the change (e.g. "Add retry logic for API calls", "Fix race condition in cache invalidation"). Prefix with the type of change when useful: \`fix:\`, \`feat:\`, \`refactor:\`, \`docs:\`, \`test:\`, \`chore:\`.
109
+ - **PR body**: MUST follow this structure:
110
+
111
+ \`\`\`
112
+ ## Problem / Task
113
+ <What problem is being solved or what task was requested. If there is a linked issue, reference it with #number. Be specific about the root cause or motivation.>
114
+
115
+ ## Changes
116
+ <Concise list of what was actually changed. Describe each meaningful change — files modified, logic added/removed, and why. Do NOT just list filenames; explain what each change does.>
117
+
118
+ ## Testing
119
+ <What tests were added, modified, or run. Include:
120
+ - New test names and what they verify
121
+ - Whether existing tests still pass
122
+ - Manual verification steps if applicable
123
+ - Commands used to validate (e.g. \`make test\`, \`npm test\`)>
124
+ \`\`\`
125
+
126
+ - If the task originated from a GitHub issue, always reference it in the PR body (e.g. "Fixes #123" or "Closes #123") so the issue is automatically closed on merge. If it originated from an external ticket system (Jira, Linear, etc.), include the ticket ID and link in the Problem / Task section (e.g. "Resolves PROJ-456").
127
+ - Do not leave the PR body empty or vague. Every PR must clearly communicate what was done and why so reviewers can understand the change without reading every line of diff.`,
105
128
 
106
129
  'support': `You are ProbeChat Support, a specialized AI assistant focused on helping developers troubleshoot issues and solve problems. Your primary function is to help users diagnose errors, understand unexpected behaviors, and find solutions using the provided code analysis tools.
107
130
 
package/src/tools/edit.js CHANGED
@@ -448,6 +448,13 @@ Parameters:
448
448
  return `Error editing file: Multiple occurrences found - the old_string appears ${occurrences} times in ${file_path}. To fix: (1) Set replace_all=true to replace all occurrences, or (2) Include more surrounding lines in old_string to make the match unique (add the full line or adjacent lines for context).`;
449
449
  }
450
450
 
451
+ // Guard against over-scoped text edits (replacing large blocks with tiny replacements)
452
+ const oldLines = matchTarget.split('\n').length;
453
+ const newLines = new_string.split('\n').length;
454
+ if (oldLines >= 20 && newLines < oldLines * 0.5) {
455
+ return `Error editing file: Edit scope too large — replacing ${oldLines} lines with ${newLines} lines risks accidental content deletion. To fix: (1) Use line-targeted editing (start_line/end_line) instead to constrain scope, or (2) Split into smaller, focused edits that each target only the lines you intend to change.`;
456
+ }
457
+
451
458
  // Perform the replacement
452
459
  let newContent;
453
460
  if (replace_all) {