@probelabs/probe 0.6.0-rc248 → 0.6.0-rc250

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.
@@ -8,6 +8,7 @@
8
8
 
9
9
  import {
10
10
  searchSchema,
11
+ searchAllSchema,
11
12
  querySchema,
12
13
  extractSchema,
13
14
  bashSchema,
@@ -16,6 +17,7 @@ import {
16
17
  // Map of native tool names to their Zod schemas
17
18
  const NATIVE_TOOL_SCHEMAS = {
18
19
  search: searchSchema,
20
+ searchAll: searchAllSchema,
19
21
  query: querySchema,
20
22
  extract: extractSchema,
21
23
  bash: bashSchema,
@@ -23,7 +25,7 @@ const NATIVE_TOOL_SCHEMAS = {
23
25
 
24
26
  // Tools that are inherently async (make network/LLM calls)
25
27
  const ALWAYS_ASYNC = new Set([
26
- 'search', 'query', 'extract', 'listFiles', 'searchFiles', 'bash',
28
+ 'search', 'searchAll', 'query', 'extract', 'listFiles', 'searchFiles', 'bash',
27
29
  'LLM', 'map',
28
30
  ]);
29
31
 
@@ -9905,7 +9905,7 @@ function resolveTargetPath(target, cwd) {
9905
9905
  }
9906
9906
  return filePart + suffix;
9907
9907
  }
9908
- var searchSchema, 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;
9908
+ var 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;
9909
9909
  var init_common = __esm({
9910
9910
  "src/tools/common.js"() {
9911
9911
  "use strict";
@@ -9916,9 +9916,17 @@ var init_common = __esm({
9916
9916
  query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
9917
9917
  path: external_exports.string().optional().default(".").describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
9918
9918
  exact: external_exports.boolean().optional().default(false).describe('Default (false) enables stemming and keyword splitting for exploratory search - "getUserData" matches "get", "user", "data", etc. Set true for precise symbol lookup where "getUserData" matches only "getUserData". Use true when you know the exact symbol name.'),
9919
+ maxTokens: external_exports.number().nullable().optional().describe("Maximum tokens to return. Default is 20000. Set to null for unlimited results."),
9919
9920
  session: external_exports.string().optional().describe("Session ID for result caching and pagination. Pass the session ID from a previous search to get additional results (next page). Results already shown in a session are automatically excluded. Omit for a fresh search."),
9920
9921
  nextPage: external_exports.boolean().optional().default(false).describe("Set to true when requesting the next page of results. Requires passing the same session ID from the previous search output.")
9921
9922
  });
9923
+ searchAllSchema = external_exports.object({
9924
+ query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
9925
+ path: external_exports.string().optional().default(".").describe("Path to search in."),
9926
+ exact: external_exports.boolean().optional().default(false).describe("Use exact matching instead of stemming."),
9927
+ maxTokensPerPage: external_exports.number().optional().default(2e4).describe("Tokens per page when paginating. Default 20000."),
9928
+ maxPages: external_exports.number().optional().default(50).describe("Maximum pages to retrieve. Default 50 (safety limit).")
9929
+ });
9922
9930
  querySchema = external_exports.object({
9923
9931
  pattern: external_exports.string().describe("AST pattern to search for. Use $NAME for variable names, $$$PARAMS for parameter lists, etc."),
9924
9932
  path: external_exports.string().optional().default(".").describe("Path to search in"),
@@ -22110,12 +22118,14 @@ var init_environment = __esm({
22110
22118
  init_common();
22111
22119
  NATIVE_TOOL_SCHEMAS = {
22112
22120
  search: searchSchema,
22121
+ searchAll: searchAllSchema,
22113
22122
  query: querySchema,
22114
22123
  extract: extractSchema,
22115
22124
  bash: bashSchema
22116
22125
  };
22117
22126
  ALWAYS_ASYNC = /* @__PURE__ */ new Set([
22118
22127
  "search",
22128
+ "searchAll",
22119
22129
  "query",
22120
22130
  "extract",
22121
22131
  "listFiles",
@@ -25299,7 +25309,7 @@ var init_esm3 = __esm({
25299
25309
  }
25300
25310
  constructor(src, dest, opts) {
25301
25311
  super(src, dest, opts);
25302
- this.proxyErrors = (er) => dest.emit("error", er);
25312
+ this.proxyErrors = (er) => this.dest.emit("error", er);
25303
25313
  src.on("error", this.proxyErrors);
25304
25314
  }
25305
25315
  };
@@ -26013,6 +26023,8 @@ var init_esm3 = __esm({
26013
26023
  return: stop,
26014
26024
  [Symbol.asyncIterator]() {
26015
26025
  return this;
26026
+ },
26027
+ [Symbol.asyncDispose]: async () => {
26016
26028
  }
26017
26029
  };
26018
26030
  }
@@ -26048,6 +26060,8 @@ var init_esm3 = __esm({
26048
26060
  return: stop,
26049
26061
  [Symbol.iterator]() {
26050
26062
  return this;
26063
+ },
26064
+ [Symbol.dispose]: () => {
26051
26065
  }
26052
26066
  };
26053
26067
  }
@@ -28992,6 +29006,7 @@ function buildToolImplementations(configOptions) {
28992
29006
  if (!searchPaths || searchPaths.length === 0) {
28993
29007
  searchPaths = [cwd || "."];
28994
29008
  }
29009
+ const maxTokens = params.maxTokens !== void 0 ? params.maxTokens : 2e4;
28995
29010
  return await search({
28996
29011
  query: params.query,
28997
29012
  path: searchPaths.join(" "),
@@ -28999,7 +29014,7 @@ function buildToolImplementations(configOptions) {
28999
29014
  allowTests: true,
29000
29015
  exact: params.exact || false,
29001
29016
  json: false,
29002
- maxTokens: 2e4,
29017
+ maxTokens,
29003
29018
  session: sessionId,
29004
29019
  timeout: 60
29005
29020
  });
@@ -29008,6 +29023,56 @@ function buildToolImplementations(configOptions) {
29008
29023
  }
29009
29024
  }
29010
29025
  };
29026
+ tools2.searchAll = {
29027
+ execute: async (params) => {
29028
+ try {
29029
+ let searchPaths;
29030
+ if (params.path) {
29031
+ searchPaths = parseAndResolvePaths(params.path, cwd);
29032
+ }
29033
+ if (!searchPaths || searchPaths.length === 0) {
29034
+ searchPaths = [cwd || "."];
29035
+ }
29036
+ const pathStr = searchPaths.join(" ");
29037
+ const maxTokensPerPage = params.maxTokensPerPage || 2e4;
29038
+ const maxPages = params.maxPages || 50;
29039
+ let allResults = "";
29040
+ let pageCount = 0;
29041
+ while (pageCount < maxPages) {
29042
+ const pageResult = await search({
29043
+ query: params.query,
29044
+ path: pathStr,
29045
+ cwd,
29046
+ allowTests: true,
29047
+ exact: params.exact || false,
29048
+ json: false,
29049
+ maxTokens: maxTokensPerPage,
29050
+ session: sessionId,
29051
+ timeout: 60
29052
+ });
29053
+ pageCount++;
29054
+ if (!pageResult || pageResult.trim().length === 0) {
29055
+ break;
29056
+ }
29057
+ if (pageResult.includes("All results retrieved") || pageResult.includes("No results found") || pageResult.includes("No matching code blocks found")) {
29058
+ if (pageResult.trim().length > 50) {
29059
+ allResults += (allResults ? "\n\n" : "") + pageResult;
29060
+ }
29061
+ break;
29062
+ }
29063
+ allResults += (allResults ? "\n\n" : "") + pageResult;
29064
+ }
29065
+ if (pageCount >= maxPages) {
29066
+ allResults += `
29067
+
29068
+ [Warning: Reached maximum page limit (${maxPages}). Some results may be omitted.]`;
29069
+ }
29070
+ return allResults || "No results found.";
29071
+ } catch (e) {
29072
+ return `SearchAll error: ${e.message}`;
29073
+ }
29074
+ }
29075
+ };
29011
29076
  tools2.query = {
29012
29077
  execute: async (params) => {
29013
29078
  try {
@@ -29192,7 +29257,8 @@ ${lastError}
29192
29257
 
29193
29258
  RULES REMINDER:
29194
29259
  - search(query) is KEYWORD SEARCH \u2014 pass a search query, NOT a filename. Use extract(filepath) to read file contents.
29195
- - search(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
29260
+ - search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
29261
+ - search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
29196
29262
  - Use chunk(stringData) to split a string into an array of chunks.
29197
29263
  - Use map(array, fn) only with arrays. Do NOT pass strings to map().
29198
29264
  - Do NOT use .map(), .forEach(), .filter(), .join() \u2014 use for..of loops instead.
@@ -29493,7 +29559,8 @@ return table;
29493
29559
  ${funcList}
29494
29560
 
29495
29561
  **Return types \u2014 IMPORTANT:**
29496
- - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets). To process parts, use \`chunk()\` to split it.
29562
+ - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets, up to 20K tokens by default). Use \`{maxTokens: null}\` for unlimited.
29563
+ - \`searchAll(query)\` \u2192 **exhaustive keyword search** \u2014 auto-paginates to retrieve ALL matching results. Returns a **string** (all matching code snippets concatenated). Use for bulk analysis.
29497
29564
  - \`query(pattern)\` \u2192 **AST search** \u2014 pass a tree-sitter pattern. Returns a **string** (matching code elements).
29498
29565
  - \`extract(targets)\` \u2192 **read file contents** \u2014 pass a file path like "src/main.js" or "src/main.js:42". Use this to read specific files found by listFiles(). Returns a **string**.
29499
29566
  - \`listFiles(pattern)\` \u2192 **list files** \u2014 pass a glob pattern like "**/*.md". Returns an **array** of file path strings. Use directly with \`for (const f of listFiles("**/*.md"))\`.
@@ -13,10 +13,19 @@ export const searchSchema = z.object({
13
13
  query: z.string().describe('Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation.'),
14
14
  path: z.string().optional().default('.').describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
15
15
  exact: z.boolean().optional().default(false).describe('Default (false) enables stemming and keyword splitting for exploratory search - "getUserData" matches "get", "user", "data", etc. Set true for precise symbol lookup where "getUserData" matches only "getUserData". Use true when you know the exact symbol name.'),
16
+ maxTokens: z.number().nullable().optional().describe('Maximum tokens to return. Default is 20000. Set to null for unlimited results.'),
16
17
  session: z.string().optional().describe('Session ID for result caching and pagination. Pass the session ID from a previous search to get additional results (next page). Results already shown in a session are automatically excluded. Omit for a fresh search.'),
17
18
  nextPage: z.boolean().optional().default(false).describe('Set to true when requesting the next page of results. Requires passing the same session ID from the previous search output.')
18
19
  });
19
20
 
21
+ export const searchAllSchema = z.object({
22
+ query: z.string().describe('Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation.'),
23
+ path: z.string().optional().default('.').describe('Path to search in.'),
24
+ exact: z.boolean().optional().default(false).describe('Use exact matching instead of stemming.'),
25
+ maxTokensPerPage: z.number().optional().default(20000).describe('Tokens per page when paginating. Default 20000.'),
26
+ maxPages: z.number().optional().default(50).describe('Maximum pages to retrieve. Default 50 (safety limit).')
27
+ });
28
+
20
29
  export const querySchema = z.object({
21
30
  pattern: z.string().describe('AST pattern to search for. Use $NAME for variable names, $$$PARAMS for parameter lists, etc.'),
22
31
  path: z.string().optional().default('.').describe('Path to search in'),
@@ -85,6 +85,8 @@ function buildToolImplementations(configOptions) {
85
85
  if (!searchPaths || searchPaths.length === 0) {
86
86
  searchPaths = [cwd || '.'];
87
87
  }
88
+ // Allow maxTokens to be passed through (null = unlimited, undefined = default 20000)
89
+ const maxTokens = params.maxTokens !== undefined ? params.maxTokens : 20000;
88
90
  return await search({
89
91
  query: params.query,
90
92
  path: searchPaths.join(' '),
@@ -92,7 +94,7 @@ function buildToolImplementations(configOptions) {
92
94
  allowTests: true,
93
95
  exact: params.exact || false,
94
96
  json: false,
95
- maxTokens: 20000,
97
+ maxTokens,
96
98
  session: sessionId,
97
99
  timeout: 60,
98
100
  });
@@ -102,6 +104,70 @@ function buildToolImplementations(configOptions) {
102
104
  },
103
105
  };
104
106
 
107
+ // searchAll: auto-paginating search that retrieves ALL results
108
+ // Calls search() repeatedly with same sessionId until no more results
109
+ tools.searchAll = {
110
+ execute: async (params) => {
111
+ try {
112
+ let searchPaths;
113
+ if (params.path) {
114
+ searchPaths = parseAndResolvePaths(params.path, cwd);
115
+ }
116
+ if (!searchPaths || searchPaths.length === 0) {
117
+ searchPaths = [cwd || '.'];
118
+ }
119
+ const pathStr = searchPaths.join(' ');
120
+ const maxTokensPerPage = params.maxTokensPerPage || 20000;
121
+ const maxPages = params.maxPages || 50; // Safety limit
122
+
123
+ let allResults = '';
124
+ let pageCount = 0;
125
+
126
+ while (pageCount < maxPages) {
127
+ const pageResult = await search({
128
+ query: params.query,
129
+ path: pathStr,
130
+ cwd,
131
+ allowTests: true,
132
+ exact: params.exact || false,
133
+ json: false,
134
+ maxTokens: maxTokensPerPage,
135
+ session: sessionId,
136
+ timeout: 60,
137
+ });
138
+
139
+ pageCount++;
140
+
141
+ // Check if we got results
142
+ if (!pageResult || pageResult.trim().length === 0) {
143
+ break;
144
+ }
145
+
146
+ // Check for "All results retrieved" or "No results found" signals
147
+ if (pageResult.includes('All results retrieved') ||
148
+ pageResult.includes('No results found') ||
149
+ pageResult.includes('No matching code blocks found')) {
150
+ // Include this final page if it has content beyond the message
151
+ if (pageResult.trim().length > 50) {
152
+ allResults += (allResults ? '\n\n' : '') + pageResult;
153
+ }
154
+ break;
155
+ }
156
+
157
+ allResults += (allResults ? '\n\n' : '') + pageResult;
158
+ }
159
+
160
+ if (pageCount >= maxPages) {
161
+ allResults += `\n\n[Warning: Reached maximum page limit (${maxPages}). Some results may be omitted.]`;
162
+ }
163
+
164
+ return allResults || 'No results found.';
165
+ } catch (e) {
166
+ return `SearchAll error: ${e.message}`;
167
+ }
168
+ },
169
+ };
170
+
105
171
  tools.query = {
106
172
  execute: async (params) => {
107
173
  try {
@@ -345,7 +411,8 @@ ${lastError}
345
411
 
346
412
  RULES REMINDER:
347
413
  - search(query) is KEYWORD SEARCH — pass a search query, NOT a filename. Use extract(filepath) to read file contents.
348
- - search(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
414
+ - search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
415
+ - search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
349
416
  - Use chunk(stringData) to split a string into an array of chunks.
350
417
  - Use map(array, fn) only with arrays. Do NOT pass strings to map().
351
418
  - Do NOT use .map(), .forEach(), .filter(), .join() — use for..of loops instead.
@@ -684,7 +751,8 @@ return table;
684
751
  ${funcList}
685
752
 
686
753
  **Return types — IMPORTANT:**
687
- - \`search(query)\` → **keyword search** — pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets). To process parts, use \`chunk()\` to split it.
754
+ - \`search(query)\` → **keyword search** — pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets, up to 20K tokens by default). Use \`{maxTokens: null}\` for unlimited.
755
+ - \`searchAll(query)\` → **exhaustive keyword search** — auto-paginates to retrieve ALL matching results. Returns a **string** (all matching code snippets concatenated). Use for bulk analysis.
688
756
  - \`query(pattern)\` → **AST search** — pass a tree-sitter pattern. Returns a **string** (matching code elements).
689
757
  - \`extract(targets)\` → **read file contents** — pass a file path like "src/main.js" or "src/main.js:42". Use this to read specific files found by listFiles(). Returns a **string**.
690
758
  - \`listFiles(pattern)\` → **list files** — pass a glob pattern like "**/*.md". Returns an **array** of file path strings. Use directly with \`for (const f of listFiles("**/*.md"))\`.
@@ -37037,7 +37037,7 @@ function resolveTargetPath(target, cwd) {
37037
37037
  }
37038
37038
  return filePart + suffix;
37039
37039
  }
37040
- var import_path6, searchSchema, 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;
37040
+ 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;
37041
37041
  var init_common2 = __esm({
37042
37042
  "src/tools/common.js"() {
37043
37043
  "use strict";
@@ -37049,9 +37049,17 @@ var init_common2 = __esm({
37049
37049
  query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
37050
37050
  path: external_exports.string().optional().default(".").describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
37051
37051
  exact: external_exports.boolean().optional().default(false).describe('Default (false) enables stemming and keyword splitting for exploratory search - "getUserData" matches "get", "user", "data", etc. Set true for precise symbol lookup where "getUserData" matches only "getUserData". Use true when you know the exact symbol name.'),
37052
+ maxTokens: external_exports.number().nullable().optional().describe("Maximum tokens to return. Default is 20000. Set to null for unlimited results."),
37052
37053
  session: external_exports.string().optional().describe("Session ID for result caching and pagination. Pass the session ID from a previous search to get additional results (next page). Results already shown in a session are automatically excluded. Omit for a fresh search."),
37053
37054
  nextPage: external_exports.boolean().optional().default(false).describe("Set to true when requesting the next page of results. Requires passing the same session ID from the previous search output.")
37054
37055
  });
37056
+ searchAllSchema = external_exports.object({
37057
+ query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
37058
+ path: external_exports.string().optional().default(".").describe("Path to search in."),
37059
+ exact: external_exports.boolean().optional().default(false).describe("Use exact matching instead of stemming."),
37060
+ maxTokensPerPage: external_exports.number().optional().default(2e4).describe("Tokens per page when paginating. Default 20000."),
37061
+ maxPages: external_exports.number().optional().default(50).describe("Maximum pages to retrieve. Default 50 (safety limit).")
37062
+ });
37055
37063
  querySchema = external_exports.object({
37056
37064
  pattern: external_exports.string().describe("AST pattern to search for. Use $NAME for variable names, $$$PARAMS for parameter lists, etc."),
37057
37065
  path: external_exports.string().optional().default(".").describe("Path to search in"),
@@ -49244,12 +49252,14 @@ var init_environment = __esm({
49244
49252
  init_common2();
49245
49253
  NATIVE_TOOL_SCHEMAS = {
49246
49254
  search: searchSchema,
49255
+ searchAll: searchAllSchema,
49247
49256
  query: querySchema,
49248
49257
  extract: extractSchema,
49249
49258
  bash: bashSchema
49250
49259
  };
49251
49260
  ALWAYS_ASYNC = /* @__PURE__ */ new Set([
49252
49261
  "search",
49262
+ "searchAll",
49253
49263
  "query",
49254
49264
  "extract",
49255
49265
  "listFiles",
@@ -52433,7 +52443,7 @@ var init_esm3 = __esm({
52433
52443
  }
52434
52444
  constructor(src, dest, opts) {
52435
52445
  super(src, dest, opts);
52436
- this.proxyErrors = (er) => dest.emit("error", er);
52446
+ this.proxyErrors = (er) => this.dest.emit("error", er);
52437
52447
  src.on("error", this.proxyErrors);
52438
52448
  }
52439
52449
  };
@@ -53147,6 +53157,8 @@ var init_esm3 = __esm({
53147
53157
  return: stop,
53148
53158
  [Symbol.asyncIterator]() {
53149
53159
  return this;
53160
+ },
53161
+ [Symbol.asyncDispose]: async () => {
53150
53162
  }
53151
53163
  };
53152
53164
  }
@@ -53182,6 +53194,8 @@ var init_esm3 = __esm({
53182
53194
  return: stop,
53183
53195
  [Symbol.iterator]() {
53184
53196
  return this;
53197
+ },
53198
+ [Symbol.dispose]: () => {
53185
53199
  }
53186
53200
  };
53187
53201
  }
@@ -56125,6 +56139,7 @@ function buildToolImplementations(configOptions) {
56125
56139
  if (!searchPaths || searchPaths.length === 0) {
56126
56140
  searchPaths = [cwd || "."];
56127
56141
  }
56142
+ const maxTokens = params.maxTokens !== void 0 ? params.maxTokens : 2e4;
56128
56143
  return await search({
56129
56144
  query: params.query,
56130
56145
  path: searchPaths.join(" "),
@@ -56132,7 +56147,7 @@ function buildToolImplementations(configOptions) {
56132
56147
  allowTests: true,
56133
56148
  exact: params.exact || false,
56134
56149
  json: false,
56135
- maxTokens: 2e4,
56150
+ maxTokens,
56136
56151
  session: sessionId,
56137
56152
  timeout: 60
56138
56153
  });
@@ -56141,6 +56156,56 @@ function buildToolImplementations(configOptions) {
56141
56156
  }
56142
56157
  }
56143
56158
  };
56159
+ tools2.searchAll = {
56160
+ execute: async (params) => {
56161
+ try {
56162
+ let searchPaths;
56163
+ if (params.path) {
56164
+ searchPaths = parseAndResolvePaths(params.path, cwd);
56165
+ }
56166
+ if (!searchPaths || searchPaths.length === 0) {
56167
+ searchPaths = [cwd || "."];
56168
+ }
56169
+ const pathStr = searchPaths.join(" ");
56170
+ const maxTokensPerPage = params.maxTokensPerPage || 2e4;
56171
+ const maxPages = params.maxPages || 50;
56172
+ let allResults = "";
56173
+ let pageCount = 0;
56174
+ while (pageCount < maxPages) {
56175
+ const pageResult = await search({
56176
+ query: params.query,
56177
+ path: pathStr,
56178
+ cwd,
56179
+ allowTests: true,
56180
+ exact: params.exact || false,
56181
+ json: false,
56182
+ maxTokens: maxTokensPerPage,
56183
+ session: sessionId,
56184
+ timeout: 60
56185
+ });
56186
+ pageCount++;
56187
+ if (!pageResult || pageResult.trim().length === 0) {
56188
+ break;
56189
+ }
56190
+ if (pageResult.includes("All results retrieved") || pageResult.includes("No results found") || pageResult.includes("No matching code blocks found")) {
56191
+ if (pageResult.trim().length > 50) {
56192
+ allResults += (allResults ? "\n\n" : "") + pageResult;
56193
+ }
56194
+ break;
56195
+ }
56196
+ allResults += (allResults ? "\n\n" : "") + pageResult;
56197
+ }
56198
+ if (pageCount >= maxPages) {
56199
+ allResults += `
56200
+
56201
+ [Warning: Reached maximum page limit (${maxPages}). Some results may be omitted.]`;
56202
+ }
56203
+ return allResults || "No results found.";
56204
+ } catch (e4) {
56205
+ return `SearchAll error: ${e4.message}`;
56206
+ }
56207
+ }
56208
+ };
56144
56209
  tools2.query = {
56145
56210
  execute: async (params) => {
56146
56211
  try {
@@ -56325,7 +56390,8 @@ ${lastError}
56325
56390
 
56326
56391
  RULES REMINDER:
56327
56392
  - search(query) is KEYWORD SEARCH \u2014 pass a search query, NOT a filename. Use extract(filepath) to read file contents.
56328
- - search(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
56393
+ - search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
56394
+ - search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
56329
56395
  - Use chunk(stringData) to split a string into an array of chunks.
56330
56396
  - Use map(array, fn) only with arrays. Do NOT pass strings to map().
56331
56397
  - Do NOT use .map(), .forEach(), .filter(), .join() \u2014 use for..of loops instead.
@@ -56626,7 +56692,8 @@ return table;
56626
56692
  ${funcList}
56627
56693
 
56628
56694
  **Return types \u2014 IMPORTANT:**
56629
- - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets). To process parts, use \`chunk()\` to split it.
56695
+ - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets, up to 20K tokens by default). Use \`{maxTokens: null}\` for unlimited.
56696
+ - \`searchAll(query)\` \u2192 **exhaustive keyword search** \u2014 auto-paginates to retrieve ALL matching results. Returns a **string** (all matching code snippets concatenated). Use for bulk analysis.
56630
56697
  - \`query(pattern)\` \u2192 **AST search** \u2014 pass a tree-sitter pattern. Returns a **string** (matching code elements).
56631
56698
  - \`extract(targets)\` \u2192 **read file contents** \u2014 pass a file path like "src/main.js" or "src/main.js:42". Use this to read specific files found by listFiles(). Returns a **string**.
56632
56699
  - \`listFiles(pattern)\` \u2192 **list files** \u2014 pass a glob pattern like "**/*.md". Returns an **array** of file path strings. Use directly with \`for (const f of listFiles("**/*.md"))\`.
package/cjs/index.cjs CHANGED
@@ -36203,7 +36203,7 @@ function resolveTargetPath(target, cwd) {
36203
36203
  }
36204
36204
  return filePart + suffix;
36205
36205
  }
36206
- var import_path6, searchSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, attemptCompletionSchema, searchToolDefinition, queryToolDefinition, extractToolDefinition, delegateToolDefinition, attemptCompletionToolDefinition, analyzeAllToolDefinition, bashToolDefinition, googleSearchToolDefinition, urlContextToolDefinition, searchDescription, queryDescription, extractDescription, delegateDescription, bashDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS;
36206
+ 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, bashDescription, analyzeAllDescription, DEFAULT_VALID_TOOLS;
36207
36207
  var init_common2 = __esm({
36208
36208
  "src/tools/common.js"() {
36209
36209
  "use strict";
@@ -36215,9 +36215,17 @@ var init_common2 = __esm({
36215
36215
  query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
36216
36216
  path: external_exports.string().optional().default(".").describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
36217
36217
  exact: external_exports.boolean().optional().default(false).describe('Default (false) enables stemming and keyword splitting for exploratory search - "getUserData" matches "get", "user", "data", etc. Set true for precise symbol lookup where "getUserData" matches only "getUserData". Use true when you know the exact symbol name.'),
36218
+ maxTokens: external_exports.number().nullable().optional().describe("Maximum tokens to return. Default is 20000. Set to null for unlimited results."),
36218
36219
  session: external_exports.string().optional().describe("Session ID for result caching and pagination. Pass the session ID from a previous search to get additional results (next page). Results already shown in a session are automatically excluded. Omit for a fresh search."),
36219
36220
  nextPage: external_exports.boolean().optional().default(false).describe("Set to true when requesting the next page of results. Requires passing the same session ID from the previous search output.")
36220
36221
  });
36222
+ searchAllSchema = external_exports.object({
36223
+ query: external_exports.string().describe("Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation."),
36224
+ path: external_exports.string().optional().default(".").describe("Path to search in."),
36225
+ exact: external_exports.boolean().optional().default(false).describe("Use exact matching instead of stemming."),
36226
+ maxTokensPerPage: external_exports.number().optional().default(2e4).describe("Tokens per page when paginating. Default 20000."),
36227
+ maxPages: external_exports.number().optional().default(50).describe("Maximum pages to retrieve. Default 50 (safety limit).")
36228
+ });
36221
36229
  querySchema = external_exports.object({
36222
36230
  pattern: external_exports.string().describe("AST pattern to search for. Use $NAME for variable names, $$$PARAMS for parameter lists, etc."),
36223
36231
  path: external_exports.string().optional().default(".").describe("Path to search in"),
@@ -40456,7 +40464,7 @@ var init_esm3 = __esm({
40456
40464
  }
40457
40465
  constructor(src, dest, opts) {
40458
40466
  super(src, dest, opts);
40459
- this.proxyErrors = (er) => dest.emit("error", er);
40467
+ this.proxyErrors = (er) => this.dest.emit("error", er);
40460
40468
  src.on("error", this.proxyErrors);
40461
40469
  }
40462
40470
  };
@@ -41170,6 +41178,8 @@ var init_esm3 = __esm({
41170
41178
  return: stop,
41171
41179
  [Symbol.asyncIterator]() {
41172
41180
  return this;
41181
+ },
41182
+ [Symbol.asyncDispose]: async () => {
41173
41183
  }
41174
41184
  };
41175
41185
  }
@@ -41205,6 +41215,8 @@ var init_esm3 = __esm({
41205
41215
  return: stop,
41206
41216
  [Symbol.iterator]() {
41207
41217
  return this;
41218
+ },
41219
+ [Symbol.dispose]: () => {
41208
41220
  }
41209
41221
  };
41210
41222
  }
@@ -102069,12 +102081,14 @@ var init_environment = __esm({
102069
102081
  init_common2();
102070
102082
  NATIVE_TOOL_SCHEMAS = {
102071
102083
  search: searchSchema,
102084
+ searchAll: searchAllSchema,
102072
102085
  query: querySchema,
102073
102086
  extract: extractSchema,
102074
102087
  bash: bashSchema
102075
102088
  };
102076
102089
  ALWAYS_ASYNC = /* @__PURE__ */ new Set([
102077
102090
  "search",
102091
+ "searchAll",
102078
102092
  "query",
102079
102093
  "extract",
102080
102094
  "listFiles",
@@ -103898,6 +103912,7 @@ function buildToolImplementations(configOptions) {
103898
103912
  if (!searchPaths || searchPaths.length === 0) {
103899
103913
  searchPaths = [cwd || "."];
103900
103914
  }
103915
+ const maxTokens = params.maxTokens !== void 0 ? params.maxTokens : 2e4;
103901
103916
  return await search({
103902
103917
  query: params.query,
103903
103918
  path: searchPaths.join(" "),
@@ -103905,7 +103920,7 @@ function buildToolImplementations(configOptions) {
103905
103920
  allowTests: true,
103906
103921
  exact: params.exact || false,
103907
103922
  json: false,
103908
- maxTokens: 2e4,
103923
+ maxTokens,
103909
103924
  session: sessionId,
103910
103925
  timeout: 60
103911
103926
  });
@@ -103914,6 +103929,56 @@ function buildToolImplementations(configOptions) {
103914
103929
  }
103915
103930
  }
103916
103931
  };
103932
+ tools2.searchAll = {
103933
+ execute: async (params) => {
103934
+ try {
103935
+ let searchPaths;
103936
+ if (params.path) {
103937
+ searchPaths = parseAndResolvePaths(params.path, cwd);
103938
+ }
103939
+ if (!searchPaths || searchPaths.length === 0) {
103940
+ searchPaths = [cwd || "."];
103941
+ }
103942
+ const pathStr = searchPaths.join(" ");
103943
+ const maxTokensPerPage = params.maxTokensPerPage || 2e4;
103944
+ const maxPages = params.maxPages || 50;
103945
+ let allResults = "";
103946
+ let pageCount = 0;
103947
+ while (pageCount < maxPages) {
103948
+ const pageResult = await search({
103949
+ query: params.query,
103950
+ path: pathStr,
103951
+ cwd,
103952
+ allowTests: true,
103953
+ exact: params.exact || false,
103954
+ json: false,
103955
+ maxTokens: maxTokensPerPage,
103956
+ session: sessionId,
103957
+ timeout: 60
103958
+ });
103959
+ pageCount++;
103960
+ if (!pageResult || pageResult.trim().length === 0) {
103961
+ break;
103962
+ }
103963
+ if (pageResult.includes("All results retrieved") || pageResult.includes("No results found") || pageResult.includes("No matching code blocks found")) {
103964
+ if (pageResult.trim().length > 50) {
103965
+ allResults += (allResults ? "\n\n" : "") + pageResult;
103966
+ }
103967
+ break;
103968
+ }
103969
+ allResults += (allResults ? "\n\n" : "") + pageResult;
103970
+ }
103971
+ if (pageCount >= maxPages) {
103972
+ allResults += `
103973
+
103974
+ [Warning: Reached maximum page limit (${maxPages}). Some results may be omitted.]`;
103975
+ }
103976
+ return allResults || "No results found.";
103977
+ } catch (e4) {
103978
+ return `SearchAll error: ${e4.message}`;
103979
+ }
103980
+ }
103981
+ };
103917
103982
  tools2.query = {
103918
103983
  execute: async (params) => {
103919
103984
  try {
@@ -104098,7 +104163,8 @@ ${lastError}
104098
104163
 
104099
104164
  RULES REMINDER:
104100
104165
  - search(query) is KEYWORD SEARCH \u2014 pass a search query, NOT a filename. Use extract(filepath) to read file contents.
104101
- - search(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
104166
+ - search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
104167
+ - search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
104102
104168
  - Use chunk(stringData) to split a string into an array of chunks.
104103
104169
  - Use map(array, fn) only with arrays. Do NOT pass strings to map().
104104
104170
  - Do NOT use .map(), .forEach(), .filter(), .join() \u2014 use for..of loops instead.
@@ -104399,7 +104465,8 @@ return table;
104399
104465
  ${funcList}
104400
104466
 
104401
104467
  **Return types \u2014 IMPORTANT:**
104402
- - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets). To process parts, use \`chunk()\` to split it.
104468
+ - \`search(query)\` \u2192 **keyword search** \u2014 pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets, up to 20K tokens by default). Use \`{maxTokens: null}\` for unlimited.
104469
+ - \`searchAll(query)\` \u2192 **exhaustive keyword search** \u2014 auto-paginates to retrieve ALL matching results. Returns a **string** (all matching code snippets concatenated). Use for bulk analysis.
104403
104470
  - \`query(pattern)\` \u2192 **AST search** \u2014 pass a tree-sitter pattern. Returns a **string** (matching code elements).
104404
104471
  - \`extract(targets)\` \u2192 **read file contents** \u2014 pass a file path like "src/main.js" or "src/main.js:42". Use this to read specific files found by listFiles(). Returns a **string**.
104405
104472
  - \`listFiles(pattern)\` \u2192 **list files** \u2014 pass a glob pattern like "**/*.md". Returns an **array** of file path strings. Use directly with \`for (const f of listFiles("**/*.md"))\`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@probelabs/probe",
3
- "version": "0.6.0-rc248",
3
+ "version": "0.6.0-rc250",
4
4
  "description": "Node.js wrapper for the probe code search tool",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -8,6 +8,7 @@
8
8
 
9
9
  import {
10
10
  searchSchema,
11
+ searchAllSchema,
11
12
  querySchema,
12
13
  extractSchema,
13
14
  bashSchema,
@@ -16,6 +17,7 @@ import {
16
17
  // Map of native tool names to their Zod schemas
17
18
  const NATIVE_TOOL_SCHEMAS = {
18
19
  search: searchSchema,
20
+ searchAll: searchAllSchema,
19
21
  query: querySchema,
20
22
  extract: extractSchema,
21
23
  bash: bashSchema,
@@ -23,7 +25,7 @@ const NATIVE_TOOL_SCHEMAS = {
23
25
 
24
26
  // Tools that are inherently async (make network/LLM calls)
25
27
  const ALWAYS_ASYNC = new Set([
26
- 'search', 'query', 'extract', 'listFiles', 'searchFiles', 'bash',
28
+ 'search', 'searchAll', 'query', 'extract', 'listFiles', 'searchFiles', 'bash',
27
29
  'LLM', 'map',
28
30
  ]);
29
31
 
@@ -13,10 +13,19 @@ export const searchSchema = z.object({
13
13
  query: z.string().describe('Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation.'),
14
14
  path: z.string().optional().default('.').describe('Path to search in. For dependencies use "go:github.com/owner/repo", "js:package_name", or "rust:cargo_name" etc.'),
15
15
  exact: z.boolean().optional().default(false).describe('Default (false) enables stemming and keyword splitting for exploratory search - "getUserData" matches "get", "user", "data", etc. Set true for precise symbol lookup where "getUserData" matches only "getUserData". Use true when you know the exact symbol name.'),
16
+ maxTokens: z.number().nullable().optional().describe('Maximum tokens to return. Default is 20000. Set to null for unlimited results.'),
16
17
  session: z.string().optional().describe('Session ID for result caching and pagination. Pass the session ID from a previous search to get additional results (next page). Results already shown in a session are automatically excluded. Omit for a fresh search.'),
17
18
  nextPage: z.boolean().optional().default(false).describe('Set to true when requesting the next page of results. Requires passing the same session ID from the previous search output.')
18
19
  });
19
20
 
21
+ export const searchAllSchema = z.object({
22
+ query: z.string().describe('Search query with Elasticsearch syntax. Use quotes for exact matches, AND/OR for boolean logic, - for negation.'),
23
+ path: z.string().optional().default('.').describe('Path to search in.'),
24
+ exact: z.boolean().optional().default(false).describe('Use exact matching instead of stemming.'),
25
+ maxTokensPerPage: z.number().optional().default(20000).describe('Tokens per page when paginating. Default 20000.'),
26
+ maxPages: z.number().optional().default(50).describe('Maximum pages to retrieve. Default 50 (safety limit).')
27
+ });
28
+
20
29
  export const querySchema = z.object({
21
30
  pattern: z.string().describe('AST pattern to search for. Use $NAME for variable names, $$$PARAMS for parameter lists, etc.'),
22
31
  path: z.string().optional().default('.').describe('Path to search in'),
@@ -85,6 +85,8 @@ function buildToolImplementations(configOptions) {
85
85
  if (!searchPaths || searchPaths.length === 0) {
86
86
  searchPaths = [cwd || '.'];
87
87
  }
88
+ // Allow maxTokens to be passed through (null = unlimited, undefined = default 20000)
89
+ const maxTokens = params.maxTokens !== undefined ? params.maxTokens : 20000;
88
90
  return await search({
89
91
  query: params.query,
90
92
  path: searchPaths.join(' '),
@@ -92,7 +94,7 @@ function buildToolImplementations(configOptions) {
92
94
  allowTests: true,
93
95
  exact: params.exact || false,
94
96
  json: false,
95
- maxTokens: 20000,
97
+ maxTokens,
96
98
  session: sessionId,
97
99
  timeout: 60,
98
100
  });
@@ -102,6 +104,70 @@ function buildToolImplementations(configOptions) {
102
104
  },
103
105
  };
104
106
 
107
+ // searchAll: auto-paginating search that retrieves ALL results
108
+ // Calls search() repeatedly with same sessionId until no more results
109
+ tools.searchAll = {
110
+ execute: async (params) => {
111
+ try {
112
+ let searchPaths;
113
+ if (params.path) {
114
+ searchPaths = parseAndResolvePaths(params.path, cwd);
115
+ }
116
+ if (!searchPaths || searchPaths.length === 0) {
117
+ searchPaths = [cwd || '.'];
118
+ }
119
+ const pathStr = searchPaths.join(' ');
120
+ const maxTokensPerPage = params.maxTokensPerPage || 20000;
121
+ const maxPages = params.maxPages || 50; // Safety limit
122
+
123
+ let allResults = '';
124
+ let pageCount = 0;
125
+
126
+ while (pageCount < maxPages) {
127
+ const pageResult = await search({
128
+ query: params.query,
129
+ path: pathStr,
130
+ cwd,
131
+ allowTests: true,
132
+ exact: params.exact || false,
133
+ json: false,
134
+ maxTokens: maxTokensPerPage,
135
+ session: sessionId,
136
+ timeout: 60,
137
+ });
138
+
139
+ pageCount++;
140
+
141
+ // Check if we got results
142
+ if (!pageResult || pageResult.trim().length === 0) {
143
+ break;
144
+ }
145
+
146
+ // Check for "All results retrieved" or "No results found" signals
147
+ if (pageResult.includes('All results retrieved') ||
148
+ pageResult.includes('No results found') ||
149
+ pageResult.includes('No matching code blocks found')) {
150
+ // Include this final page if it has content beyond the message
151
+ if (pageResult.trim().length > 50) {
152
+ allResults += (allResults ? '\n\n' : '') + pageResult;
153
+ }
154
+ break;
155
+ }
156
+
157
+ allResults += (allResults ? '\n\n' : '') + pageResult;
158
+ }
159
+
160
+ if (pageCount >= maxPages) {
161
+ allResults += `\n\n[Warning: Reached maximum page limit (${maxPages}). Some results may be omitted.]`;
162
+ }
163
+
164
+ return allResults || 'No results found.';
165
+ } catch (e) {
166
+ return `SearchAll error: ${e.message}`;
167
+ }
168
+ },
169
+ };
170
+
105
171
  tools.query = {
106
172
  execute: async (params) => {
107
173
  try {
@@ -345,7 +411,8 @@ ${lastError}
345
411
 
346
412
  RULES REMINDER:
347
413
  - search(query) is KEYWORD SEARCH — pass a search query, NOT a filename. Use extract(filepath) to read file contents.
348
- - search(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
414
+ - search() returns up to 20K tokens by default. Use search(query, path, {maxTokens: null}) for unlimited, or searchAll(query) to auto-paginate ALL results.
415
+ - search(), searchAll(), query(), extract(), listFiles(), bash() all return STRINGS, not arrays.
349
416
  - Use chunk(stringData) to split a string into an array of chunks.
350
417
  - Use map(array, fn) only with arrays. Do NOT pass strings to map().
351
418
  - Do NOT use .map(), .forEach(), .filter(), .join() — use for..of loops instead.
@@ -684,7 +751,8 @@ return table;
684
751
  ${funcList}
685
752
 
686
753
  **Return types — IMPORTANT:**
687
- - \`search(query)\` → **keyword search** — pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets). To process parts, use \`chunk()\` to split it.
754
+ - \`search(query)\` → **keyword search** — pass a search query (e.g. "error handling"), NOT a filename. Returns a **string** (matching code snippets, up to 20K tokens by default). Use \`{maxTokens: null}\` for unlimited.
755
+ - \`searchAll(query)\` → **exhaustive keyword search** — auto-paginates to retrieve ALL matching results. Returns a **string** (all matching code snippets concatenated). Use for bulk analysis.
688
756
  - \`query(pattern)\` → **AST search** — pass a tree-sitter pattern. Returns a **string** (matching code elements).
689
757
  - \`extract(targets)\` → **read file contents** — pass a file path like "src/main.js" or "src/main.js:42". Use this to read specific files found by listFiles(). Returns a **string**.
690
758
  - \`listFiles(pattern)\` → **list files** — pass a glob pattern like "**/*.md". Returns an **array** of file path strings. Use directly with \`for (const f of listFiles("**/*.md"))\`.