@probelabs/probe 0.6.0-rc270 → 0.6.0-rc272

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/cjs/index.cjs CHANGED
@@ -13365,22 +13365,16 @@ var init_JsonShapeDeserializer = __esm({
13365
13365
  if (Array.isArray(value) && ns.isListSchema()) {
13366
13366
  const listMember = ns.getValueSchema();
13367
13367
  const out = [];
13368
- const sparse = !!ns.getMergedTraits().sparse;
13369
13368
  for (const item of value) {
13370
- if (sparse || item != null) {
13371
- out.push(this._read(listMember, item));
13372
- }
13369
+ out.push(this._read(listMember, item));
13373
13370
  }
13374
13371
  return out;
13375
13372
  }
13376
13373
  if (ns.isMapSchema()) {
13377
13374
  const mapMember = ns.getValueSchema();
13378
13375
  const out = {};
13379
- const sparse = !!ns.getMergedTraits().sparse;
13380
13376
  for (const [_k, _v] of Object.entries(value)) {
13381
- if (sparse || _v != null) {
13382
- out[_k] = this._read(mapMember, _v);
13383
- }
13377
+ out[_k] = this._read(mapMember, _v);
13384
13378
  }
13385
13379
  return out;
13386
13380
  }
@@ -15029,18 +15023,18 @@ var init_XmlShapeDeserializer = __esm({
15029
15023
  return value;
15030
15024
  }
15031
15025
  if (typeof value === "object") {
15032
- const sparse = !!traits.sparse;
15033
15026
  const flat = !!traits.xmlFlattened;
15034
15027
  if (ns.isListSchema()) {
15035
15028
  const listValue = ns.getValueSchema();
15036
15029
  const buffer2 = [];
15037
15030
  const sourceKey = listValue.getMergedTraits().xmlName ?? "member";
15038
15031
  const source = flat ? value : (value[0] ?? value)[sourceKey];
15032
+ if (source == null) {
15033
+ return buffer2;
15034
+ }
15039
15035
  const sourceArray = Array.isArray(source) ? source : [source];
15040
15036
  for (const v5 of sourceArray) {
15041
- if (v5 != null || sparse) {
15042
- buffer2.push(this.readSchema(listValue, v5));
15043
- }
15037
+ buffer2.push(this.readSchema(listValue, v5));
15044
15038
  }
15045
15039
  return buffer2;
15046
15040
  }
@@ -15059,9 +15053,7 @@ var init_XmlShapeDeserializer = __esm({
15059
15053
  for (const entry of entries) {
15060
15054
  const key = entry[keyProperty];
15061
15055
  const value2 = entry[valueProperty];
15062
- if (value2 != null || sparse) {
15063
- buffer[key] = this.readSchema(memberNs, value2);
15064
- }
15056
+ buffer[key] = this.readSchema(memberNs, value2);
15065
15057
  }
15066
15058
  return buffer;
15067
15059
  }
@@ -19403,7 +19395,7 @@ var require_package2 = __commonJS({
19403
19395
  module2.exports = {
19404
19396
  name: "@aws-sdk/client-bedrock-runtime",
19405
19397
  description: "AWS SDK for JavaScript Bedrock Runtime Client for Node.js, Browser and React Native",
19406
- version: "3.1001.0",
19398
+ version: "3.1002.0",
19407
19399
  scripts: {
19408
19400
  build: "concurrently 'yarn:build:types' 'yarn:build:es' && yarn build:cjs",
19409
19401
  "build:cjs": "node ../../scripts/compilation/inline client-bedrock-runtime",
@@ -19427,21 +19419,21 @@ var require_package2 = __commonJS({
19427
19419
  dependencies: {
19428
19420
  "@aws-crypto/sha256-browser": "5.2.0",
19429
19421
  "@aws-crypto/sha256-js": "5.2.0",
19430
- "@aws-sdk/core": "^3.973.16",
19431
- "@aws-sdk/credential-provider-node": "^3.972.15",
19422
+ "@aws-sdk/core": "^3.973.17",
19423
+ "@aws-sdk/credential-provider-node": "^3.972.16",
19432
19424
  "@aws-sdk/eventstream-handler-node": "^3.972.9",
19433
19425
  "@aws-sdk/middleware-eventstream": "^3.972.6",
19434
19426
  "@aws-sdk/middleware-host-header": "^3.972.6",
19435
19427
  "@aws-sdk/middleware-logger": "^3.972.6",
19436
19428
  "@aws-sdk/middleware-recursion-detection": "^3.972.6",
19437
- "@aws-sdk/middleware-user-agent": "^3.972.16",
19429
+ "@aws-sdk/middleware-user-agent": "^3.972.17",
19438
19430
  "@aws-sdk/middleware-websocket": "^3.972.11",
19439
19431
  "@aws-sdk/region-config-resolver": "^3.972.6",
19440
- "@aws-sdk/token-providers": "3.1001.0",
19432
+ "@aws-sdk/token-providers": "3.1002.0",
19441
19433
  "@aws-sdk/types": "^3.973.4",
19442
19434
  "@aws-sdk/util-endpoints": "^3.996.3",
19443
19435
  "@aws-sdk/util-user-agent-browser": "^3.972.6",
19444
- "@aws-sdk/util-user-agent-node": "^3.973.1",
19436
+ "@aws-sdk/util-user-agent-node": "^3.973.2",
19445
19437
  "@smithy/config-resolver": "^4.4.9",
19446
19438
  "@smithy/core": "^3.23.7",
19447
19439
  "@smithy/eventstream-serde-browser": "^4.2.10",
@@ -20190,7 +20182,7 @@ var init_package = __esm({
20190
20182
  "node_modules/@aws-sdk/nested-clients/package.json"() {
20191
20183
  package_default = {
20192
20184
  name: "@aws-sdk/nested-clients",
20193
- version: "3.996.4",
20185
+ version: "3.996.5",
20194
20186
  description: "Nested clients for AWS SDK packages.",
20195
20187
  main: "./dist-cjs/index.js",
20196
20188
  module: "./dist-es/index.js",
@@ -20219,16 +20211,16 @@ var init_package = __esm({
20219
20211
  dependencies: {
20220
20212
  "@aws-crypto/sha256-browser": "5.2.0",
20221
20213
  "@aws-crypto/sha256-js": "5.2.0",
20222
- "@aws-sdk/core": "^3.973.16",
20214
+ "@aws-sdk/core": "^3.973.17",
20223
20215
  "@aws-sdk/middleware-host-header": "^3.972.6",
20224
20216
  "@aws-sdk/middleware-logger": "^3.972.6",
20225
20217
  "@aws-sdk/middleware-recursion-detection": "^3.972.6",
20226
- "@aws-sdk/middleware-user-agent": "^3.972.16",
20218
+ "@aws-sdk/middleware-user-agent": "^3.972.17",
20227
20219
  "@aws-sdk/region-config-resolver": "^3.972.6",
20228
20220
  "@aws-sdk/types": "^3.973.4",
20229
20221
  "@aws-sdk/util-endpoints": "^3.996.3",
20230
20222
  "@aws-sdk/util-user-agent-browser": "^3.972.6",
20231
- "@aws-sdk/util-user-agent-node": "^3.973.1",
20223
+ "@aws-sdk/util-user-agent-node": "^3.973.2",
20232
20224
  "@smithy/config-resolver": "^4.4.9",
20233
20225
  "@smithy/core": "^3.23.7",
20234
20226
  "@smithy/fetch-http-handler": "^5.3.12",
@@ -110630,6 +110622,17 @@ function parseDelegatedTargets(rawResponse) {
110630
110622
  }
110631
110623
  return normalizeTargets(fallbackTargetsFromText(trimmed));
110632
110624
  }
110625
+ function splitTargetSuffix(target) {
110626
+ const searchStart = target.length > 2 && target[1] === ":" && /[a-zA-Z]/.test(target[0]) ? 2 : 0;
110627
+ const colonIdx = target.indexOf(":", searchStart);
110628
+ const hashIdx = target.indexOf("#");
110629
+ if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
110630
+ return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
110631
+ } else if (hashIdx !== -1) {
110632
+ return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
110633
+ }
110634
+ return { filePart: target, suffix: "" };
110635
+ }
110633
110636
  function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
110634
110637
  return [
110635
110638
  "You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.",
@@ -110644,7 +110647,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
110644
110647
  "",
110645
110648
  "Strategy for complex queries:",
110646
110649
  "1. Analyze the query - identify key concepts, entities, and relationships",
110647
- '2. Run focused searches for each concept (e.g., "error handling" + "authentication" separately)',
110650
+ '2. Run focused searches for each independent concept (e.g., for "how do payments work and how are emails sent", search "payments" and "emails" separately since they are unrelated)',
110648
110651
  "3. Use extract to verify relevance of promising results",
110649
110652
  "4. Combine all relevant targets in your final response",
110650
110653
  "",
@@ -110658,7 +110661,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
110658
110661
  "Deduplicate targets. Do NOT explain or answer - ONLY return the JSON targets."
110659
110662
  ].join("\n");
110660
110663
  }
110661
- var import_ai5, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
110664
+ var import_ai5, import_fs11, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
110662
110665
  var init_vercel = __esm({
110663
110666
  "src/tools/vercel.js"() {
110664
110667
  "use strict";
@@ -110669,6 +110672,7 @@ var init_vercel = __esm({
110669
110672
  init_delegate();
110670
110673
  init_analyzeAll();
110671
110674
  init_common2();
110675
+ import_fs11 = require("fs");
110672
110676
  init_error_types();
110673
110677
  init_hashline();
110674
110678
  CODE_SEARCH_SCHEMA = {
@@ -110794,10 +110798,47 @@ var init_vercel = __esm({
110794
110798
  }
110795
110799
  return fallbackResult;
110796
110800
  }
110801
+ const delegateBase = options.allowedFolders?.[0] || options.cwd || ".";
110797
110802
  const resolutionBase = searchPaths[0] || options.cwd || ".";
110798
- const resolvedTargets = targets.map((target) => resolveTargetPath(target, resolutionBase));
110803
+ const resolvedTargets = targets.map((target) => resolveTargetPath(target, delegateBase));
110804
+ const validatedTargets = [];
110805
+ for (const target of resolvedTargets) {
110806
+ const { filePart, suffix } = splitTargetSuffix(target);
110807
+ if ((0, import_fs11.existsSync)(filePart)) {
110808
+ validatedTargets.push(target);
110809
+ continue;
110810
+ }
110811
+ let fixed = false;
110812
+ const parts = filePart.split("/").filter(Boolean);
110813
+ for (let i5 = 0; i5 < parts.length - 1; i5++) {
110814
+ if (parts[i5] === parts[i5 + 1]) {
110815
+ const candidate = "/" + [...parts.slice(0, i5), ...parts.slice(i5 + 1)].join("/");
110816
+ if ((0, import_fs11.existsSync)(candidate)) {
110817
+ validatedTargets.push(candidate + suffix);
110818
+ if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} \u2192 ${candidate}`);
110819
+ fixed = true;
110820
+ break;
110821
+ }
110822
+ }
110823
+ }
110824
+ if (fixed) continue;
110825
+ for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
110826
+ if (altBase === delegateBase) continue;
110827
+ const altResolved = resolveTargetPath(target, altBase);
110828
+ const { filePart: altFile } = splitTargetSuffix(altResolved);
110829
+ if ((0, import_fs11.existsSync)(altFile)) {
110830
+ validatedTargets.push(altResolved);
110831
+ if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} \u2192 ${altFile}`);
110832
+ fixed = true;
110833
+ break;
110834
+ }
110835
+ }
110836
+ if (fixed) continue;
110837
+ if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
110838
+ validatedTargets.push(target);
110839
+ }
110799
110840
  const extractOptions = {
110800
- files: resolvedTargets,
110841
+ files: validatedTargets,
110801
110842
  cwd: resolutionBase,
110802
110843
  allowTests: allow_tests ?? true
110803
110844
  };
@@ -111350,7 +111391,7 @@ Example: <edit><file_path>${file_path}</file_path><symbol>${allMatches[0].qualif
111350
111391
  Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
111351
111392
  }
111352
111393
  }
111353
- const content = await import_fs11.promises.readFile(resolvedPath2, "utf-8");
111394
+ const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
111354
111395
  const lines = content.split("\n");
111355
111396
  if (position) {
111356
111397
  const refIndent = detectBaseIndent(symbolInfo.code);
@@ -111361,7 +111402,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
111361
111402
  } else {
111362
111403
  lines.splice(symbolInfo.startLine - 1, 0, ...newLines, "");
111363
111404
  }
111364
- await import_fs11.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
111405
+ await import_fs12.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
111365
111406
  if (fileTracker) {
111366
111407
  const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
111367
111408
  if (updated) {
@@ -111379,7 +111420,7 @@ Example: <extract><targets>${file_path}#${symbol15}</targets></extract>`;
111379
111420
  const reindented = reindent(new_string, originalIndent);
111380
111421
  const newLines = reindented.split("\n");
111381
111422
  lines.splice(symbolInfo.startLine - 1, symbolInfo.endLine - symbolInfo.startLine + 1, ...newLines);
111382
- await import_fs11.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
111423
+ await import_fs12.promises.writeFile(resolvedPath2, lines.join("\n"), "utf-8");
111383
111424
  if (fileTracker) {
111384
111425
  const updated = await findSymbol(resolvedPath2, symbol15, cwd || process.cwd());
111385
111426
  if (updated) {
@@ -111434,7 +111475,7 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
111434
111475
  if (position !== void 0 && position !== null && position !== "before" && position !== "after") {
111435
111476
  return 'Error editing file: Invalid position - must be "before" or "after". Use position="before" to insert before the line, or position="after" to insert after it.';
111436
111477
  }
111437
- const content = await import_fs11.promises.readFile(resolvedPath2, "utf-8");
111478
+ const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
111438
111479
  const fileLines = content.split("\n");
111439
111480
  if (startLine > fileLines.length) {
111440
111481
  return `Error editing file: Line ${startLine} is beyond file length (${fileLines.length} lines). Use 'extract' to read the current file content.`;
@@ -111463,20 +111504,20 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
111463
111504
  const newLines = cleaned === "" ? [] : cleaned.split("\n");
111464
111505
  if (position === "after") {
111465
111506
  fileLines.splice(startLine, 0, ...newLines);
111466
- await import_fs11.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111507
+ await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111467
111508
  if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
111468
111509
  const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted after line ${startLine}`;
111469
111510
  return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine, action, modifications);
111470
111511
  } else if (position === "before") {
111471
111512
  fileLines.splice(startLine - 1, 0, ...newLines);
111472
- await import_fs11.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111513
+ await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111473
111514
  if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
111474
111515
  const action = `${newLines.length} line${newLines.length !== 1 ? "s" : ""} inserted before line ${startLine}`;
111475
111516
  return buildLineEditResponse(file_path, startLine, startLine, newLines.length, fileLines, startLine - 1, action, modifications);
111476
111517
  } else {
111477
111518
  const replacedCount = endLine - startLine + 1;
111478
111519
  fileLines.splice(startLine - 1, replacedCount, ...newLines);
111479
- await import_fs11.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111520
+ await import_fs12.promises.writeFile(resolvedPath2, fileLines.join("\n"), "utf-8");
111480
111521
  if (fileTracker) await fileTracker.trackFileAfterWrite(resolvedPath2);
111481
111522
  let action;
111482
111523
  if (newLines.length === 0) {
@@ -111489,14 +111530,14 @@ async function handleLineEdit({ resolvedPath: resolvedPath2, file_path, start_li
111489
111530
  return buildLineEditResponse(file_path, startLine, endLine, newLines.length, fileLines, startLine - 1, action, modifications);
111490
111531
  }
111491
111532
  }
111492
- var import_ai6, import_fs11, import_path16, import_fs12, editTool, createTool, multiEditTool, editSchema, createSchema, multiEditSchema, editDescription, createDescription, multiEditDescription, editToolDefinition, createToolDefinition, multiEditToolDefinition;
111533
+ var import_ai6, import_fs12, import_path16, import_fs13, editTool, createTool, multiEditTool, editSchema, createSchema, multiEditSchema, editDescription, createDescription, multiEditDescription, editToolDefinition, createToolDefinition, multiEditToolDefinition;
111493
111534
  var init_edit = __esm({
111494
111535
  "src/tools/edit.js"() {
111495
111536
  "use strict";
111496
111537
  import_ai6 = require("ai");
111497
- import_fs11 = require("fs");
111498
- import_path16 = require("path");
111499
111538
  import_fs12 = require("fs");
111539
+ import_path16 = require("path");
111540
+ import_fs13 = require("fs");
111500
111541
  init_path_validation();
111501
111542
  init_fuzzyMatch();
111502
111543
  init_symbolEdit();
@@ -111580,7 +111621,7 @@ Parameters:
111580
111621
  const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
111581
111622
  return `Error editing file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
111582
111623
  }
111583
- if (!(0, import_fs12.existsSync)(resolvedPath2)) {
111624
+ if (!(0, import_fs13.existsSync)(resolvedPath2)) {
111584
111625
  return `Error editing file: File not found - ${file_path}. Verify the path is correct and the file exists. Use 'search' to find files by name, or 'create' to make a new file.`;
111585
111626
  }
111586
111627
  if (options.fileTracker && !options.fileTracker.isFileSeen(resolvedPath2)) {
@@ -111610,7 +111651,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
111610
111651
  Example: <extract><targets>${displayPath}</targets></extract>`;
111611
111652
  }
111612
111653
  }
111613
- const content = await import_fs11.promises.readFile(resolvedPath2, "utf-8");
111654
+ const content = await import_fs12.promises.readFile(resolvedPath2, "utf-8");
111614
111655
  let matchTarget = old_string;
111615
111656
  let matchStrategy = "exact";
111616
111657
  if (!content.includes(old_string)) {
@@ -111642,7 +111683,7 @@ Example: <extract><targets>${displayPath}</targets></extract>`;
111642
111683
  if (newContent === content) {
111643
111684
  return `Error editing file: No changes made - the replacement result is identical to the original. Verify that old_string and new_string are actually different. If fuzzy matching was used, the matched text may already equal new_string.`;
111644
111685
  }
111645
- await import_fs11.promises.writeFile(resolvedPath2, newContent, "utf-8");
111686
+ await import_fs12.promises.writeFile(resolvedPath2, newContent, "utf-8");
111646
111687
  if (options.fileTracker) {
111647
111688
  await options.fileTracker.trackFileAfterWrite(resolvedPath2);
111648
111689
  options.fileTracker.recordTextEdit(resolvedPath2);
@@ -111713,13 +111754,13 @@ Important:
111713
111754
  const relativePath = toRelativePath(resolvedPath2, workspaceRoot);
111714
111755
  return `Error creating file: Permission denied - ${relativePath} is outside allowed directories. Use a file path within the project workspace.`;
111715
111756
  }
111716
- if ((0, import_fs12.existsSync)(resolvedPath2) && !overwrite) {
111757
+ if ((0, import_fs13.existsSync)(resolvedPath2) && !overwrite) {
111717
111758
  return `Error creating file: File already exists - ${file_path}. Use overwrite: true to replace it.`;
111718
111759
  }
111719
- const existed = (0, import_fs12.existsSync)(resolvedPath2);
111760
+ const existed = (0, import_fs13.existsSync)(resolvedPath2);
111720
111761
  const dir = (0, import_path16.dirname)(resolvedPath2);
111721
- await import_fs11.promises.mkdir(dir, { recursive: true });
111722
- await import_fs11.promises.writeFile(resolvedPath2, content, "utf-8");
111762
+ await import_fs12.promises.mkdir(dir, { recursive: true });
111763
+ await import_fs12.promises.writeFile(resolvedPath2, content, "utf-8");
111723
111764
  if (options.fileTracker) await options.fileTracker.trackFileAfterWrite(resolvedPath2);
111724
111765
  const action = existed && overwrite ? "overwrote" : "created";
111725
111766
  const bytes = Buffer.byteLength(content, "utf-8");
@@ -112361,10 +112402,10 @@ async function listFilesByLevel(options) {
112361
112402
  maxFiles = 100,
112362
112403
  respectGitignore = true
112363
112404
  } = options;
112364
- if (!import_fs13.default.existsSync(directory)) {
112405
+ if (!import_fs14.default.existsSync(directory)) {
112365
112406
  throw new Error(`Directory does not exist: ${directory}`);
112366
112407
  }
112367
- const gitDirExists = import_fs13.default.existsSync(import_path17.default.join(directory, ".git"));
112408
+ const gitDirExists = import_fs14.default.existsSync(import_path17.default.join(directory, ".git"));
112368
112409
  if (gitDirExists && respectGitignore) {
112369
112410
  try {
112370
112411
  return await listFilesUsingGit(directory, maxFiles);
@@ -112395,7 +112436,7 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
112395
112436
  while (queue.length > 0 && result.length < maxFiles) {
112396
112437
  const { dir, level } = queue.shift();
112397
112438
  try {
112398
- const entries = import_fs13.default.readdirSync(dir, { withFileTypes: true });
112439
+ const entries = import_fs14.default.readdirSync(dir, { withFileTypes: true });
112399
112440
  const files = entries.filter((entry) => {
112400
112441
  const fullPath = import_path17.default.join(dir, entry.name);
112401
112442
  return getEntryTypeSync(entry, fullPath).isFile;
@@ -112426,11 +112467,11 @@ async function listFilesByLevelManually(directory, maxFiles, respectGitignore) {
112426
112467
  }
112427
112468
  function loadGitignorePatterns(directory) {
112428
112469
  const gitignorePath = import_path17.default.join(directory, ".gitignore");
112429
- if (!import_fs13.default.existsSync(gitignorePath)) {
112470
+ if (!import_fs14.default.existsSync(gitignorePath)) {
112430
112471
  return [];
112431
112472
  }
112432
112473
  try {
112433
- const content = import_fs13.default.readFileSync(gitignorePath, "utf8");
112474
+ const content = import_fs14.default.readFileSync(gitignorePath, "utf8");
112434
112475
  return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
112435
112476
  } catch (error2) {
112436
112477
  console.error(`Warning: Could not read .gitignore: ${error2.message}`);
@@ -112448,11 +112489,11 @@ function shouldIgnore(filePath, ignorePatterns) {
112448
112489
  }
112449
112490
  return false;
112450
112491
  }
112451
- var import_fs13, import_path17, import_util12, import_child_process10, execAsync3;
112492
+ var import_fs14, import_path17, import_util12, import_child_process10, execAsync3;
112452
112493
  var init_file_lister = __esm({
112453
112494
  "src/utils/file-lister.js"() {
112454
112495
  "use strict";
112455
- import_fs13 = __toESM(require("fs"), 1);
112496
+ import_fs14 = __toESM(require("fs"), 1);
112456
112497
  import_path17 = __toESM(require("path"), 1);
112457
112498
  import_util12 = require("util");
112458
112499
  import_child_process10 = require("child_process");
@@ -112471,11 +112512,11 @@ function initializeSimpleTelemetryFromOptions(options) {
112471
112512
  });
112472
112513
  return telemetry;
112473
112514
  }
112474
- var import_fs14, import_path18, SimpleTelemetry, SimpleAppTracer;
112515
+ var import_fs15, import_path18, SimpleTelemetry, SimpleAppTracer;
112475
112516
  var init_simpleTelemetry = __esm({
112476
112517
  "src/agent/simpleTelemetry.js"() {
112477
112518
  "use strict";
112478
- import_fs14 = require("fs");
112519
+ import_fs15 = require("fs");
112479
112520
  import_path18 = require("path");
112480
112521
  SimpleTelemetry = class {
112481
112522
  constructor(options = {}) {
@@ -112491,10 +112532,10 @@ var init_simpleTelemetry = __esm({
112491
112532
  initializeFileExporter() {
112492
112533
  try {
112493
112534
  const dir = (0, import_path18.dirname)(this.filePath);
112494
- if (!(0, import_fs14.existsSync)(dir)) {
112495
- (0, import_fs14.mkdirSync)(dir, { recursive: true });
112535
+ if (!(0, import_fs15.existsSync)(dir)) {
112536
+ (0, import_fs15.mkdirSync)(dir, { recursive: true });
112496
112537
  }
112497
- this.stream = (0, import_fs14.createWriteStream)(this.filePath, { flags: "a" });
112538
+ this.stream = (0, import_fs15.createWriteStream)(this.filePath, { flags: "a" });
112498
112539
  this.stream.on("error", (error2) => {
112499
112540
  console.error(`[SimpleTelemetry] Stream error: ${error2.message}`);
112500
112541
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc270",
3
+ "version": "0.6.0-rc272",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -10,6 +10,7 @@ import { extract } from '../extract.js';
10
10
  import { delegate } from '../delegate.js';
11
11
  import { analyzeAll } from './analyzeAll.js';
12
12
  import { searchSchema, querySchema, extractSchema, delegateSchema, analyzeAllSchema, searchDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, parseTargets, parseAndResolvePaths, resolveTargetPath } from './common.js';
13
+ import { existsSync } from 'fs';
13
14
  import { formatErrorForAI } from '../utils/error-types.js';
14
15
  import { annotateOutputWithHashes } from './hashline.js';
15
16
 
@@ -118,6 +119,18 @@ function parseDelegatedTargets(rawResponse) {
118
119
  return normalizeTargets(fallbackTargetsFromText(trimmed));
119
120
  }
120
121
 
122
+ function splitTargetSuffix(target) {
123
+ const searchStart = (target.length > 2 && target[1] === ':' && /[a-zA-Z]/.test(target[0])) ? 2 : 0;
124
+ const colonIdx = target.indexOf(':', searchStart);
125
+ const hashIdx = target.indexOf('#');
126
+ if (colonIdx !== -1 && (hashIdx === -1 || colonIdx < hashIdx)) {
127
+ return { filePart: target.substring(0, colonIdx), suffix: target.substring(colonIdx) };
128
+ } else if (hashIdx !== -1) {
129
+ return { filePart: target.substring(0, hashIdx), suffix: target.substring(hashIdx) };
130
+ }
131
+ return { filePart: target, suffix: '' };
132
+ }
133
+
121
134
  function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, allowTests }) {
122
135
  return [
123
136
  'You are a code-search subagent. Your job is to find ALL relevant code locations for the given query.',
@@ -132,7 +145,7 @@ function buildSearchDelegateTask({ searchQuery, searchPath, exact, language, all
132
145
  '',
133
146
  'Strategy for complex queries:',
134
147
  '1. Analyze the query - identify key concepts, entities, and relationships',
135
- '2. Run focused searches for each concept (e.g., "error handling" + "authentication" separately)',
148
+ '2. Run focused searches for each independent concept (e.g., for "how do payments work and how are emails sent", search "payments" and "emails" separately since they are unrelated)',
136
149
  '3. Use extract to verify relevance of promising results',
137
150
  '4. Combine all relevant targets in your final response',
138
151
  '',
@@ -286,13 +299,61 @@ export const searchTool = (options = {}) => {
286
299
  return fallbackResult;
287
300
  }
288
301
 
289
- // Resolve relative paths against the actual search directory, not the general cwd.
290
- // The delegate returns paths relative to where the search was performed (searchPaths[0]),
291
- // which may differ from options.cwd when the user specifies a path parameter.
302
+ // The delegate runs from workspace root (allowedFolders[0] or cwd), NOT from searchPaths[0].
303
+ // It returns paths relative to that workspace root. Resolve against the same base.
304
+ const delegateBase = options.allowedFolders?.[0] || options.cwd || '.';
292
305
  const resolutionBase = searchPaths[0] || options.cwd || '.';
293
- const resolvedTargets = targets.map(target => resolveTargetPath(target, resolutionBase));
306
+ const resolvedTargets = targets.map(target => resolveTargetPath(target, delegateBase));
307
+
308
+ // Auto-fix: detect and repair invalid paths (doubled segments, AI hallucinations)
309
+ const validatedTargets = [];
310
+ for (const target of resolvedTargets) {
311
+ const { filePart, suffix } = splitTargetSuffix(target);
312
+
313
+ // 1. Path exists as-is
314
+ if (existsSync(filePart)) {
315
+ validatedTargets.push(target);
316
+ continue;
317
+ }
318
+
319
+ // 2. Detect doubled directory segments: /ws/proj/proj/src → /ws/proj/src
320
+ let fixed = false;
321
+ const parts = filePart.split('/').filter(Boolean);
322
+ for (let i = 0; i < parts.length - 1; i++) {
323
+ if (parts[i] === parts[i + 1]) {
324
+ const candidate = '/' + [...parts.slice(0, i), ...parts.slice(i + 1)].join('/');
325
+ if (existsSync(candidate)) {
326
+ validatedTargets.push(candidate + suffix);
327
+ if (debug) console.error(`[search-delegate] Fixed doubled path segment: ${filePart} → ${candidate}`);
328
+ fixed = true;
329
+ break;
330
+ }
331
+ }
332
+ }
333
+ if (fixed) continue;
334
+
335
+ // 3. Try resolving against alternative bases (searchPaths[0], cwd)
336
+ for (const altBase of [resolutionBase, options.cwd].filter(Boolean)) {
337
+ if (altBase === delegateBase) continue;
338
+ const altResolved = resolveTargetPath(target, altBase);
339
+ const { filePart: altFile } = splitTargetSuffix(altResolved);
340
+ if (existsSync(altFile)) {
341
+ validatedTargets.push(altResolved);
342
+ if (debug) console.error(`[search-delegate] Resolved with alt base: ${filePart} → ${altFile}`);
343
+ fixed = true;
344
+ break;
345
+ }
346
+ }
347
+ if (fixed) continue;
348
+
349
+ // 4. Keep target anyway (probe binary will report the error)
350
+ // but log a warning
351
+ if (debug) console.error(`[search-delegate] Warning: target may not exist: ${filePart}`);
352
+ validatedTargets.push(target);
353
+ }
354
+
294
355
  const extractOptions = {
295
- files: resolvedTargets,
356
+ files: validatedTargets,
296
357
  cwd: resolutionBase,
297
358
  allowTests: allow_tests ?? true
298
359
  };