@probelabs/probe 0.6.0-rc258 → 0.6.0-rc259

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.
@@ -363,7 +363,7 @@ Parameters:
363
363
  required: ['file_path', 'new_string']
364
364
  },
365
365
 
366
- execute: async ({ file_path, old_string, new_string, replace_all = false, symbol, position, start_line, end_line }) => {
366
+ execute: async ({ file_path, old_string, new_string, replace_all = false, symbol, position, start_line, end_line, workingDirectory }) => {
367
367
  try {
368
368
  // Validate input parameters
369
369
  if (!file_path || typeof file_path !== 'string' || file_path.trim() === '') {
@@ -373,8 +373,9 @@ Parameters:
373
373
  return `Error editing file: Invalid new_string - must be a string. Provide the replacement content as a string value (empty string "" is valid for deletions).`;
374
374
  }
375
375
 
376
- // Resolve the file path
377
- const resolvedPath = isAbsolute(file_path) ? file_path : resolve(cwd || process.cwd(), file_path);
376
+ // Resolve the file path (workingDirectory from runtime takes priority over cwd from tool creation)
377
+ const effectiveCwd = workingDirectory || cwd || process.cwd();
378
+ const resolvedPath = isAbsolute(file_path) ? file_path : resolve(effectiveCwd, file_path);
378
379
 
379
380
  if (debug) {
380
381
  console.error(`[Edit] Attempting to edit file: ${resolvedPath}`);
@@ -530,7 +531,7 @@ Important:
530
531
  required: ['file_path', 'content']
531
532
  },
532
533
 
533
- execute: async ({ file_path, content, overwrite = false }) => {
534
+ execute: async ({ file_path, content, overwrite = false, workingDirectory }) => {
534
535
  try {
535
536
  // Validate input parameters
536
537
  if (!file_path || typeof file_path !== 'string' || file_path.trim() === '') {
@@ -540,8 +541,9 @@ Important:
540
541
  return `Error creating file: Invalid content - must be a string. Provide the file content as a string value (empty string "" is valid for an empty file).`;
541
542
  }
542
543
 
543
- // Resolve the file path
544
- const resolvedPath = isAbsolute(file_path) ? file_path : resolve(cwd || process.cwd(), file_path);
544
+ // Resolve the file path (workingDirectory from runtime takes priority over cwd from tool creation)
545
+ const effectiveCwd = workingDirectory || cwd || process.cwd();
546
+ const resolvedPath = isAbsolute(file_path) ? file_path : resolve(effectiveCwd, file_path);
545
547
 
546
548
  if (debug) {
547
549
  console.error(`[Create] Attempting to create file: ${resolvedPath}`);
@@ -587,6 +589,86 @@ Important:
587
589
  });
588
590
  };
589
591
 
592
+ /**
593
+ * Multi-edit tool — apply multiple edit operations in a single call.
594
+ * Reuses the edit tool internally; edits are applied sequentially.
595
+ *
596
+ * @param {Object} [options] - Same configuration as editTool
597
+ * @returns {Object} Configured multi_edit tool
598
+ */
599
+ export const multiEditTool = (options = {}) => {
600
+ const editInstance = editTool(options);
601
+
602
+ return tool({
603
+ name: 'multi_edit',
604
+ description: 'Apply multiple file edits in a single tool call. Accepts a JSON array of edit operations.',
605
+
606
+ inputSchema: {
607
+ type: 'object',
608
+ properties: {
609
+ edits: {
610
+ type: 'string',
611
+ description: 'JSON array of edit operations. Each object supports: file_path, old_string, new_string, replace_all, symbol, position, start_line, end_line.'
612
+ }
613
+ },
614
+ required: ['edits']
615
+ },
616
+
617
+ execute: async ({ edits: rawEdits }) => {
618
+ let edits;
619
+ if (typeof rawEdits === 'string') {
620
+ try {
621
+ edits = JSON.parse(rawEdits);
622
+ } catch (e) {
623
+ return `Error: Invalid JSON in edits parameter - ${e.message}. Provide a raw JSON array between <edits> tags.`;
624
+ }
625
+ } else if (Array.isArray(rawEdits)) {
626
+ edits = rawEdits;
627
+ } else {
628
+ return 'Error: edits must be a JSON array of edit operations.';
629
+ }
630
+
631
+ if (!Array.isArray(edits) || edits.length === 0) {
632
+ return 'Error: edits must be a non-empty JSON array.';
633
+ }
634
+ if (edits.length > 50) {
635
+ return `Error: Too many edits (${edits.length}). Maximum 50 per batch.`;
636
+ }
637
+
638
+ const results = [];
639
+ let successCount = 0;
640
+ let failCount = 0;
641
+
642
+ for (let i = 0; i < edits.length; i++) {
643
+ const editOp = edits[i];
644
+ if (!editOp || typeof editOp !== 'object' || Array.isArray(editOp)) {
645
+ results.push(`[${i + 1}] FAIL: Invalid edit operation - must be an object`);
646
+ failCount++;
647
+ continue;
648
+ }
649
+ try {
650
+ const result = await editInstance.execute(editOp);
651
+ const isError = typeof result === 'string' && result.startsWith('Error');
652
+ if (isError) {
653
+ results.push(`[${i + 1}] FAIL: ${result}`);
654
+ failCount++;
655
+ } else {
656
+ results.push(`[${i + 1}] OK: ${result}`);
657
+ successCount++;
658
+ }
659
+ } catch (error) {
660
+ results.push(`[${i + 1}] FAIL: ${error.message}`);
661
+ failCount++;
662
+ }
663
+ }
664
+
665
+ const summary = `Multi-edit: ${successCount}/${edits.length} succeeded` +
666
+ (failCount > 0 ? `, ${failCount} failed` : '');
667
+ return summary + '\n\n' + results.join('\n');
668
+ }
669
+ });
670
+ };
671
+
590
672
  // Export schemas for tool definitions
591
673
  export const editSchema = {
592
674
  type: 'object',
@@ -647,9 +729,21 @@ export const createSchema = {
647
729
  required: ['file_path', 'content']
648
730
  };
649
731
 
732
+ export const multiEditSchema = {
733
+ type: 'object',
734
+ properties: {
735
+ edits: {
736
+ type: 'string',
737
+ description: 'JSON array of edit operations'
738
+ }
739
+ },
740
+ required: ['edits']
741
+ };
742
+
650
743
  // Tool descriptions for XML definitions
651
744
  export const editDescription = 'Edit files using text replacement, AST-aware symbol operations, or line-targeted editing. Supports fuzzy matching for text edits and optional hash-based integrity verification for line edits.';
652
745
  export const createDescription = 'Create new files with specified content. Will create parent directories if needed.';
746
+ export const multiEditDescription = 'Apply multiple file edits in a single tool call. Accepts a JSON array of edit operations, each supporting the same modes as the edit tool.';
653
747
 
654
748
  // XML tool definitions
655
749
  export const editToolDefinition = `
@@ -808,3 +902,42 @@ Examples:
808
902
  This is a new project.</content>
809
903
  <overwrite>true</overwrite>
810
904
  </create>`;
905
+
906
+ export const multiEditToolDefinition = `
907
+ ## multi_edit
908
+ Description: ${multiEditDescription}
909
+
910
+ Apply multiple edits in one call. Each operation in the array uses the same parameters as the edit tool:
911
+ - file_path, old_string, new_string (text mode)
912
+ - file_path, symbol, new_string (symbol replace)
913
+ - file_path, symbol, new_string, position (symbol insert)
914
+ - file_path, start_line, new_string (line-targeted)
915
+
916
+ Edits are applied sequentially. Failures do not stop remaining edits. Maximum 50 edits per call.
917
+
918
+ Parameters:
919
+ - edits: (required) JSON array of edit objects. Place raw JSON between tags.
920
+
921
+ When to use multi_edit vs edit:
922
+ - Use edit for a single change to one file
923
+ - Use multi_edit when making 2+ related changes across files (e.g., rename a function and update all call sites)
924
+ - Use multi_edit for coordinated multi-file refactoring where order matters
925
+
926
+ Examples:
927
+
928
+ Multiple text replacements across files:
929
+ <multi_edit>
930
+ <edits>[
931
+ {"file_path": "src/main.js", "old_string": "return false;", "new_string": "return true;"},
932
+ {"file_path": "src/config.js", "old_string": "debug: false", "new_string": "debug: true"}
933
+ ]</edits>
934
+ </multi_edit>
935
+
936
+ Mixed edit modes in one batch:
937
+ <multi_edit>
938
+ <edits>[
939
+ {"file_path": "src/utils.js", "symbol": "oldHelper", "new_string": "function newHelper() { return 42; }"},
940
+ {"file_path": "src/main.js", "old_string": "oldHelper()", "new_string": "newHelper()", "replace_all": true},
941
+ {"file_path": "src/index.js", "start_line": "10", "end_line": "12", "new_string": "export { newHelper };"}
942
+ ]</edits>
943
+ </multi_edit>`;
@@ -6,7 +6,7 @@
6
6
  // Export Vercel AI SDK tool generators
7
7
  export { searchTool, queryTool, extractTool, delegateTool } from './vercel.js';
8
8
  export { bashTool } from './bash.js';
9
- export { editTool, createTool } from './edit.js';
9
+ export { editTool, createTool, multiEditTool } from './edit.js';
10
10
 
11
11
  // Export LangChain tools
12
12
  export { createSearchTool, createQueryTool, createExtractTool } from './langchain.js';
@@ -39,10 +39,13 @@ export {
39
39
  export {
40
40
  editSchema,
41
41
  createSchema,
42
+ multiEditSchema,
42
43
  editDescription,
43
44
  createDescription,
45
+ multiEditDescription,
44
46
  editToolDefinition,
45
- createToolDefinition
47
+ createToolDefinition,
48
+ multiEditToolDefinition
46
49
  } from './edit.js';
47
50
 
48
51
  // Export system message
@@ -36704,7 +36704,7 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
36704
36704
  return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
36705
36705
  }
36706
36706
  }
36707
- var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, editSchema, createSchema, editDescription, createDescription, editToolDefinition, createToolDefinition;
36707
+ var import_ai, import_fs4, import_path5, import_fs5, editTool, createTool, multiEditTool, editSchema, createSchema, multiEditSchema, editDescription, createDescription, multiEditDescription, editToolDefinition, createToolDefinition, multiEditToolDefinition;
36708
36708
  var init_edit = __esm({
36709
36709
  "src/tools/edit.js"() {
36710
36710
  "use strict";
@@ -36778,7 +36778,7 @@ Parameters:
36778
36778
  },
36779
36779
  required: ["file_path", "new_string"]
36780
36780
  },
36781
- execute: async ({ file_path, old_string, new_string, replace_all = false, symbol: symbol15, position, start_line, end_line }) => {
36781
+ execute: async ({ file_path, old_string, new_string, replace_all = false, symbol: symbol15, position, start_line, end_line, workingDirectory }) => {
36782
36782
  try {
36783
36783
  if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
36784
36784
  return `Error editing file: Invalid file_path - must be a non-empty string. Provide an absolute path or a path relative to the working directory (e.g. "src/main.js").`;
@@ -36786,7 +36786,8 @@ Parameters:
36786
36786
  if (new_string === void 0 || new_string === null || typeof new_string !== "string") {
36787
36787
  return `Error editing file: Invalid new_string - must be a string. Provide the replacement content as a string value (empty string "" is valid for deletions).`;
36788
36788
  }
36789
- const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
36789
+ const effectiveCwd = workingDirectory || cwd || process.cwd();
36790
+ const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(effectiveCwd, file_path);
36790
36791
  if (debug) {
36791
36792
  console.error(`[Edit] Attempting to edit file: ${resolvedPath2}`);
36792
36793
  }
@@ -36893,7 +36894,7 @@ Important:
36893
36894
  },
36894
36895
  required: ["file_path", "content"]
36895
36896
  },
36896
- execute: async ({ file_path, content, overwrite = false }) => {
36897
+ execute: async ({ file_path, content, overwrite = false, workingDirectory }) => {
36897
36898
  try {
36898
36899
  if (!file_path || typeof file_path !== "string" || file_path.trim() === "") {
36899
36900
  return `Error creating file: Invalid file_path - must be a non-empty string. Provide an absolute path or a path relative to the working directory (e.g. "src/newFile.js").`;
@@ -36901,7 +36902,8 @@ Important:
36901
36902
  if (content === void 0 || content === null || typeof content !== "string") {
36902
36903
  return `Error creating file: Invalid content - must be a string. Provide the file content as a string value (empty string "" is valid for an empty file).`;
36903
36904
  }
36904
- const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(cwd || process.cwd(), file_path);
36905
+ const effectiveCwd = workingDirectory || cwd || process.cwd();
36906
+ const resolvedPath2 = (0, import_path5.isAbsolute)(file_path) ? file_path : (0, import_path5.resolve)(effectiveCwd, file_path);
36905
36907
  if (debug) {
36906
36908
  console.error(`[Create] Attempting to create file: ${resolvedPath2}`);
36907
36909
  }
@@ -36930,6 +36932,70 @@ Important:
36930
36932
  }
36931
36933
  });
36932
36934
  };
36935
+ multiEditTool = (options = {}) => {
36936
+ const editInstance = editTool(options);
36937
+ return (0, import_ai.tool)({
36938
+ name: "multi_edit",
36939
+ description: "Apply multiple file edits in a single tool call. Accepts a JSON array of edit operations.",
36940
+ inputSchema: {
36941
+ type: "object",
36942
+ properties: {
36943
+ edits: {
36944
+ type: "string",
36945
+ description: "JSON array of edit operations. Each object supports: file_path, old_string, new_string, replace_all, symbol, position, start_line, end_line."
36946
+ }
36947
+ },
36948
+ required: ["edits"]
36949
+ },
36950
+ execute: async ({ edits: rawEdits }) => {
36951
+ let edits;
36952
+ if (typeof rawEdits === "string") {
36953
+ try {
36954
+ edits = JSON.parse(rawEdits);
36955
+ } catch (e5) {
36956
+ return `Error: Invalid JSON in edits parameter - ${e5.message}. Provide a raw JSON array between <edits> tags.`;
36957
+ }
36958
+ } else if (Array.isArray(rawEdits)) {
36959
+ edits = rawEdits;
36960
+ } else {
36961
+ return "Error: edits must be a JSON array of edit operations.";
36962
+ }
36963
+ if (!Array.isArray(edits) || edits.length === 0) {
36964
+ return "Error: edits must be a non-empty JSON array.";
36965
+ }
36966
+ if (edits.length > 50) {
36967
+ return `Error: Too many edits (${edits.length}). Maximum 50 per batch.`;
36968
+ }
36969
+ const results = [];
36970
+ let successCount = 0;
36971
+ let failCount = 0;
36972
+ for (let i5 = 0; i5 < edits.length; i5++) {
36973
+ const editOp = edits[i5];
36974
+ if (!editOp || typeof editOp !== "object" || Array.isArray(editOp)) {
36975
+ results.push(`[${i5 + 1}] FAIL: Invalid edit operation - must be an object`);
36976
+ failCount++;
36977
+ continue;
36978
+ }
36979
+ try {
36980
+ const result = await editInstance.execute(editOp);
36981
+ const isError = typeof result === "string" && result.startsWith("Error");
36982
+ if (isError) {
36983
+ results.push(`[${i5 + 1}] FAIL: ${result}`);
36984
+ failCount++;
36985
+ } else {
36986
+ results.push(`[${i5 + 1}] OK: ${result}`);
36987
+ successCount++;
36988
+ }
36989
+ } catch (error2) {
36990
+ results.push(`[${i5 + 1}] FAIL: ${error2.message}`);
36991
+ failCount++;
36992
+ }
36993
+ }
36994
+ const summary = `Multi-edit: ${successCount}/${edits.length} succeeded` + (failCount > 0 ? `, ${failCount} failed` : "");
36995
+ return summary + "\n\n" + results.join("\n");
36996
+ }
36997
+ });
36998
+ };
36933
36999
  editSchema = {
36934
37000
  type: "object",
36935
37001
  properties: {
@@ -36987,8 +37053,19 @@ Important:
36987
37053
  },
36988
37054
  required: ["file_path", "content"]
36989
37055
  };
37056
+ multiEditSchema = {
37057
+ type: "object",
37058
+ properties: {
37059
+ edits: {
37060
+ type: "string",
37061
+ description: "JSON array of edit operations"
37062
+ }
37063
+ },
37064
+ required: ["edits"]
37065
+ };
36990
37066
  editDescription = "Edit files using text replacement, AST-aware symbol operations, or line-targeted editing. Supports fuzzy matching for text edits and optional hash-based integrity verification for line edits.";
36991
37067
  createDescription = "Create new files with specified content. Will create parent directories if needed.";
37068
+ multiEditDescription = "Apply multiple file edits in a single tool call. Accepts a JSON array of edit operations, each supporting the same modes as the edit tool.";
36992
37069
  editToolDefinition = `
36993
37070
  ## edit
36994
37071
  Description: ${editDescription}
@@ -37144,6 +37221,44 @@ Examples:
37144
37221
  This is a new project.</content>
37145
37222
  <overwrite>true</overwrite>
37146
37223
  </create>`;
37224
+ multiEditToolDefinition = `
37225
+ ## multi_edit
37226
+ Description: ${multiEditDescription}
37227
+
37228
+ Apply multiple edits in one call. Each operation in the array uses the same parameters as the edit tool:
37229
+ - file_path, old_string, new_string (text mode)
37230
+ - file_path, symbol, new_string (symbol replace)
37231
+ - file_path, symbol, new_string, position (symbol insert)
37232
+ - file_path, start_line, new_string (line-targeted)
37233
+
37234
+ Edits are applied sequentially. Failures do not stop remaining edits. Maximum 50 edits per call.
37235
+
37236
+ Parameters:
37237
+ - edits: (required) JSON array of edit objects. Place raw JSON between tags.
37238
+
37239
+ When to use multi_edit vs edit:
37240
+ - Use edit for a single change to one file
37241
+ - Use multi_edit when making 2+ related changes across files (e.g., rename a function and update all call sites)
37242
+ - Use multi_edit for coordinated multi-file refactoring where order matters
37243
+
37244
+ Examples:
37245
+
37246
+ Multiple text replacements across files:
37247
+ <multi_edit>
37248
+ <edits>[
37249
+ {"file_path": "src/main.js", "old_string": "return false;", "new_string": "return true;"},
37250
+ {"file_path": "src/config.js", "old_string": "debug: false", "new_string": "debug: true"}
37251
+ ]</edits>
37252
+ </multi_edit>
37253
+
37254
+ Mixed edit modes in one batch:
37255
+ <multi_edit>
37256
+ <edits>[
37257
+ {"file_path": "src/utils.js", "symbol": "oldHelper", "new_string": "function newHelper() { return 42; }"},
37258
+ {"file_path": "src/main.js", "old_string": "oldHelper()", "new_string": "newHelper()", "replace_all": true},
37259
+ {"file_path": "src/index.js", "start_line": "10", "end_line": "12", "new_string": "export { newHelper };"}
37260
+ ]</edits>
37261
+ </multi_edit>`;
37147
37262
  }
37148
37263
  });
37149
37264
 
@@ -37636,7 +37751,8 @@ function getValidParamsForTool(toolName) {
37636
37751
  task: taskSchema,
37637
37752
  attempt_completion: attemptCompletionSchema,
37638
37753
  edit: editSchema,
37639
- create: createSchema
37754
+ create: createSchema,
37755
+ multi_edit: multiEditSchema
37640
37756
  };
37641
37757
  const schema = schemaMap[toolName];
37642
37758
  if (!schema) {
@@ -37676,7 +37792,7 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
37676
37792
  const closeTag = `</${toolName}>`;
37677
37793
  const openIndex = earliestOpenIndex;
37678
37794
  let closeIndex;
37679
- if (toolName === "attempt_completion") {
37795
+ if (LAST_INDEX_TOOLS.has(toolName)) {
37680
37796
  closeIndex = xmlString.lastIndexOf(closeTag);
37681
37797
  if (closeIndex !== -1 && closeIndex <= openIndex + openTag.length) {
37682
37798
  closeIndex = -1;
@@ -37701,7 +37817,15 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
37701
37817
  if (paramOpenIndex === -1) {
37702
37818
  continue;
37703
37819
  }
37704
- let paramCloseIndex = innerContent.indexOf(paramCloseTag, paramOpenIndex + paramOpenTag.length);
37820
+ let paramCloseIndex;
37821
+ if (RAW_CONTENT_PARAMS.has(paramName)) {
37822
+ paramCloseIndex = innerContent.lastIndexOf(paramCloseTag);
37823
+ if (paramCloseIndex !== -1 && paramCloseIndex <= paramOpenIndex + paramOpenTag.length) {
37824
+ paramCloseIndex = -1;
37825
+ }
37826
+ } else {
37827
+ paramCloseIndex = innerContent.indexOf(paramCloseTag, paramOpenIndex + paramOpenTag.length);
37828
+ }
37705
37829
  if (paramCloseIndex === -1) {
37706
37830
  let nextTagIndex = innerContent.length;
37707
37831
  for (const nextParam of validParams) {
@@ -37713,18 +37837,26 @@ function parseXmlToolCall(xmlString, validTools = DEFAULT_VALID_TOOLS) {
37713
37837
  }
37714
37838
  paramCloseIndex = nextTagIndex;
37715
37839
  }
37716
- let paramValue = unescapeXmlEntities(innerContent.substring(
37840
+ const rawValue = innerContent.substring(
37717
37841
  paramOpenIndex + paramOpenTag.length,
37718
37842
  paramCloseIndex
37719
- ).trim());
37720
- if (paramValue.toLowerCase() === "true") {
37721
- paramValue = true;
37722
- } else if (paramValue.toLowerCase() === "false") {
37723
- paramValue = false;
37724
- } else if (!isNaN(paramValue) && paramValue.trim() !== "") {
37725
- const num = Number(paramValue);
37726
- if (Number.isFinite(num)) {
37727
- paramValue = num;
37843
+ );
37844
+ let paramValue;
37845
+ if (RAW_CONTENT_PARAMS.has(paramName)) {
37846
+ paramValue = unescapeXmlEntities(rawValue.replace(/^\n/, "").replace(/\n$/, ""));
37847
+ } else {
37848
+ paramValue = unescapeXmlEntities(rawValue.trim());
37849
+ }
37850
+ if (!RAW_CONTENT_PARAMS.has(paramName)) {
37851
+ if (paramValue.toLowerCase() === "true") {
37852
+ paramValue = true;
37853
+ } else if (paramValue.toLowerCase() === "false") {
37854
+ paramValue = false;
37855
+ } else if (!isNaN(paramValue) && paramValue.trim() !== "") {
37856
+ const num = Number(paramValue);
37857
+ if (Number.isFinite(num)) {
37858
+ paramValue = num;
37859
+ }
37728
37860
  }
37729
37861
  }
37730
37862
  params[paramName] = paramValue;
@@ -37767,6 +37899,7 @@ function detectUnrecognizedToolCall(xmlString, validTools) {
37767
37899
  "readImage",
37768
37900
  "edit",
37769
37901
  "create",
37902
+ "multi_edit",
37770
37903
  "delegate",
37771
37904
  "bash",
37772
37905
  "task",
@@ -37896,7 +38029,7 @@ function resolveTargetPath(target, cwd) {
37896
38029
  }
37897
38030
  return filePart + suffix;
37898
38031
  }
37899
- var import_path6, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, analyzeAllToolDefinition, bashToolDefinition, googleSearchToolDefinition, urlContextToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS;
38032
+ var import_path6, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, analyzeAllToolDefinition, bashToolDefinition, googleSearchToolDefinition, urlContextToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS, RAW_CONTENT_PARAMS, LAST_INDEX_TOOLS;
37900
38033
  var init_common2 = __esm({
37901
38034
  "src/tools/common.js"() {
37902
38035
  "use strict";
@@ -38315,6 +38448,8 @@ Capabilities:
38315
38448
  "task",
38316
38449
  "attempt_completion"
38317
38450
  ];
38451
+ RAW_CONTENT_PARAMS = /* @__PURE__ */ new Set(["content", "new_string", "old_string"]);
38452
+ LAST_INDEX_TOOLS = /* @__PURE__ */ new Set(["attempt_completion", "create", "edit"]);
38318
38453
  }
38319
38454
  });
38320
38455
 
@@ -58876,6 +59011,13 @@ function createWrappedTools(baseTools) {
58876
59011
  baseTools.createTool.execute
58877
59012
  );
58878
59013
  }
59014
+ if (baseTools.multiEditTool) {
59015
+ wrappedTools.multiEditToolInstance = wrapToolWithEmitter(
59016
+ baseTools.multiEditTool,
59017
+ "multi_edit",
59018
+ baseTools.multiEditTool.execute
59019
+ );
59020
+ }
58879
59021
  return wrappedTools;
58880
59022
  }
58881
59023
  var import_child_process8, import_util12, import_crypto4, import_events, import_fs10, import_fs11, import_path12, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
@@ -59801,6 +59943,9 @@ function createTools(configOptions) {
59801
59943
  if (configOptions.allowEdit && isToolAllowed("create")) {
59802
59944
  tools2.createTool = createTool(configOptions);
59803
59945
  }
59946
+ if (configOptions.allowEdit && isToolAllowed("multi_edit")) {
59947
+ tools2.multiEditTool = multiEditTool(configOptions);
59948
+ }
59804
59949
  return tools2;
59805
59950
  }
59806
59951
  function parseXmlToolCallWithThinking(xmlString, validTools) {
@@ -110299,6 +110444,9 @@ var init_ProbeAgent = __esm({
110299
110444
  if (wrappedTools.createToolInstance && isToolAllowed("create")) {
110300
110445
  this.toolImplementations.create = wrappedTools.createToolInstance;
110301
110446
  }
110447
+ if (wrappedTools.multiEditToolInstance && isToolAllowed("multi_edit")) {
110448
+ this.toolImplementations.multi_edit = wrappedTools.multiEditToolInstance;
110449
+ }
110302
110450
  }
110303
110451
  this.wrappedTools = wrappedTools;
110304
110452
  if (this.debug) {
@@ -111588,6 +111736,10 @@ Workspace: ${this.allowedFolders.join(", ")}`;
111588
111736
  }
111589
111737
  if (this.allowEdit && isToolAllowed("create")) {
111590
111738
  toolDefinitions += `${createToolDefinition}
111739
+ `;
111740
+ }
111741
+ if (this.allowEdit && isToolAllowed("multi_edit")) {
111742
+ toolDefinitions += `${multiEditToolDefinition}
111591
111743
  `;
111592
111744
  }
111593
111745
  if (this.enableBash && isToolAllowed("bash")) {
@@ -111684,6 +111836,9 @@ The configuration is loaded from src/config.js lines 15-25 which contains the da
111684
111836
  if (this.allowEdit && isToolAllowed("create")) {
111685
111837
  availableToolsList += "- create: Create new files with specified content.\n";
111686
111838
  }
111839
+ if (this.allowEdit && isToolAllowed("multi_edit")) {
111840
+ availableToolsList += "- multi_edit: Apply multiple file edits in one call using a JSON array of operations.\n";
111841
+ }
111687
111842
  if (this.enableDelegate && isToolAllowed("delegate")) {
111688
111843
  availableToolsList += "- delegate: Delegate big distinct tasks to specialized probe subagents.\n";
111689
111844
  }
@@ -112278,6 +112433,9 @@ You are working with a workspace. Available paths: ${workspaceDesc}
112278
112433
  if (this.allowEdit && this.allowedTools.isEnabled("create")) {
112279
112434
  validTools.push("create");
112280
112435
  }
112436
+ if (this.allowEdit && this.allowedTools.isEnabled("multi_edit")) {
112437
+ validTools.push("multi_edit");
112438
+ }
112281
112439
  if (this.enableBash && this.allowedTools.isEnabled("bash")) {
112282
112440
  validTools.push("bash");
112283
112441
  }