@probelabs/probe 0.6.0-rc307 → 0.6.0-rc309
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/README.md +25 -0
- package/bin/binaries/{probe-v0.6.0-rc307-aarch64-apple-darwin.tar.gz → probe-v0.6.0-rc309-aarch64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc307-aarch64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc309-aarch64-unknown-linux-musl.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc307-x86_64-apple-darwin.tar.gz → probe-v0.6.0-rc309-x86_64-apple-darwin.tar.gz} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc307-x86_64-pc-windows-msvc.zip → probe-v0.6.0-rc309-x86_64-pc-windows-msvc.zip} +0 -0
- package/bin/binaries/{probe-v0.6.0-rc307-x86_64-unknown-linux-musl.tar.gz → probe-v0.6.0-rc309-x86_64-unknown-linux-musl.tar.gz} +0 -0
- package/build/agent/ProbeAgent.js +17 -4
- package/build/agent/probeTool.js +9 -0
- package/build/agent/shared/prompts.js +4 -1
- package/build/agent/tools.js +6 -0
- package/build/index.js +6 -1
- package/build/symbols.js +86 -0
- package/build/tools/common.js +4 -0
- package/build/tools/index.js +2 -1
- package/build/tools/system-message.js +4 -0
- package/build/tools/vercel.js +36 -1
- package/cjs/agent/ProbeAgent.cjs +180 -40
- package/cjs/index.cjs +188 -40
- package/index.d.ts +63 -0
- package/package.json +1 -1
- package/src/agent/ProbeAgent.js +17 -4
- package/src/agent/probeTool.js +9 -0
- package/src/agent/shared/prompts.js +4 -1
- package/src/agent/tools.js +6 -0
- package/src/index.js +6 -1
- package/src/symbols.js +86 -0
- package/src/tools/common.js +4 -0
- package/src/tools/index.js +2 -1
- package/src/tools/system-message.js +4 -0
- package/src/tools/vercel.js +36 -1
package/cjs/index.cjs
CHANGED
|
@@ -2187,6 +2187,70 @@ var init_extract = __esm({
|
|
|
2187
2187
|
}
|
|
2188
2188
|
});
|
|
2189
2189
|
|
|
2190
|
+
// src/symbols.js
|
|
2191
|
+
async function symbols(options) {
|
|
2192
|
+
if (!options) {
|
|
2193
|
+
throw new Error("Options object is required");
|
|
2194
|
+
}
|
|
2195
|
+
if (!options.files || !Array.isArray(options.files) || options.files.length === 0) {
|
|
2196
|
+
throw new Error("At least one file path is required");
|
|
2197
|
+
}
|
|
2198
|
+
const binaryPath = await getBinaryPath(options.binaryOptions || {});
|
|
2199
|
+
const cwd = await validateCwdPath(options.cwd);
|
|
2200
|
+
const args = ["symbols", "--format", "json"];
|
|
2201
|
+
if (options.allowTests) {
|
|
2202
|
+
args.push("--allow-tests");
|
|
2203
|
+
}
|
|
2204
|
+
for (const file2 of options.files) {
|
|
2205
|
+
args.push(escapeString(file2));
|
|
2206
|
+
}
|
|
2207
|
+
if (process.env.DEBUG === "1") {
|
|
2208
|
+
console.error(`
|
|
2209
|
+
Symbols: files="${options.files.join(", ")}" cwd="${cwd}"`);
|
|
2210
|
+
}
|
|
2211
|
+
return new Promise((resolve9, reject2) => {
|
|
2212
|
+
const childProcess = (0, import_child_process5.spawn)(binaryPath, args, {
|
|
2213
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
2214
|
+
cwd
|
|
2215
|
+
});
|
|
2216
|
+
let stdout = "";
|
|
2217
|
+
let stderr = "";
|
|
2218
|
+
childProcess.stdout.on("data", (data2) => {
|
|
2219
|
+
stdout += data2.toString();
|
|
2220
|
+
});
|
|
2221
|
+
childProcess.stderr.on("data", (data2) => {
|
|
2222
|
+
stderr += data2.toString();
|
|
2223
|
+
});
|
|
2224
|
+
childProcess.on("close", (code) => {
|
|
2225
|
+
if (stderr && process.env.DEBUG === "1") {
|
|
2226
|
+
console.error(`stderr: ${stderr}`);
|
|
2227
|
+
}
|
|
2228
|
+
if (code !== 0) {
|
|
2229
|
+
reject2(new Error(`Symbols command failed with exit code ${code}: ${stderr}`));
|
|
2230
|
+
return;
|
|
2231
|
+
}
|
|
2232
|
+
try {
|
|
2233
|
+
const result = JSON.parse(stdout);
|
|
2234
|
+
resolve9(result);
|
|
2235
|
+
} catch (error40) {
|
|
2236
|
+
reject2(new Error(`Failed to parse symbols output: ${error40.message}. Output: ${stdout.substring(0, 200)}`));
|
|
2237
|
+
}
|
|
2238
|
+
});
|
|
2239
|
+
childProcess.on("error", (error40) => {
|
|
2240
|
+
reject2(new Error(`Failed to spawn symbols process: ${error40.message}`));
|
|
2241
|
+
});
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
var import_child_process5;
|
|
2245
|
+
var init_symbols = __esm({
|
|
2246
|
+
"src/symbols.js"() {
|
|
2247
|
+
"use strict";
|
|
2248
|
+
import_child_process5 = require("child_process");
|
|
2249
|
+
init_utils();
|
|
2250
|
+
init_path_validation();
|
|
2251
|
+
}
|
|
2252
|
+
});
|
|
2253
|
+
|
|
2190
2254
|
// src/grep.js
|
|
2191
2255
|
async function grep(options) {
|
|
2192
2256
|
if (!options || !options.pattern) {
|
|
@@ -2230,14 +2294,14 @@ async function grep(options) {
|
|
|
2230
2294
|
throw new Error(`Grep failed: ${errorMessage}`);
|
|
2231
2295
|
}
|
|
2232
2296
|
}
|
|
2233
|
-
var
|
|
2297
|
+
var import_child_process6, import_util5, execFileAsync2, GREP_FLAG_MAP;
|
|
2234
2298
|
var init_grep = __esm({
|
|
2235
2299
|
"src/grep.js"() {
|
|
2236
2300
|
"use strict";
|
|
2237
|
-
|
|
2301
|
+
import_child_process6 = require("child_process");
|
|
2238
2302
|
import_util5 = require("util");
|
|
2239
2303
|
init_utils();
|
|
2240
|
-
execFileAsync2 = (0, import_util5.promisify)(
|
|
2304
|
+
execFileAsync2 = (0, import_util5.promisify)(import_child_process6.execFile);
|
|
2241
2305
|
GREP_FLAG_MAP = {
|
|
2242
2306
|
ignoreCase: "-i",
|
|
2243
2307
|
lineNumbers: "-n",
|
|
@@ -27645,6 +27709,9 @@ function createTools(configOptions) {
|
|
|
27645
27709
|
if (isToolAllowed("extract")) {
|
|
27646
27710
|
tools2.extractTool = extractTool(configOptions);
|
|
27647
27711
|
}
|
|
27712
|
+
if (isToolAllowed("symbols")) {
|
|
27713
|
+
tools2.symbolsTool = symbolsTool(configOptions);
|
|
27714
|
+
}
|
|
27648
27715
|
if (configOptions.enableDelegate && isToolAllowed("delegate")) {
|
|
27649
27716
|
tools2.delegateTool = delegateTool(configOptions);
|
|
27650
27717
|
}
|
|
@@ -27813,7 +27880,7 @@ function resolveTargetPath(target, cwd) {
|
|
|
27813
27880
|
}
|
|
27814
27881
|
return filePart + suffix;
|
|
27815
27882
|
}
|
|
27816
|
-
var import_path6, searchDelegateSchema, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, readMediaSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, bashDescription, analyzeAllDescription;
|
|
27883
|
+
var import_path6, searchDelegateSchema, searchSchema, searchAllSchema, querySchema, extractSchema, delegateSchema, listSkillsSchema, useSkillSchema, listFilesSchema, searchFilesSchema, readImageSchema, readMediaSchema, symbolsSchema, bashSchema, analyzeAllSchema, executePlanSchema, cleanupExecutePlanSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, bashDescription, analyzeAllDescription;
|
|
27817
27884
|
var init_common = __esm({
|
|
27818
27885
|
"src/tools/common.js"() {
|
|
27819
27886
|
"use strict";
|
|
@@ -27872,6 +27939,9 @@ var init_common = __esm({
|
|
|
27872
27939
|
readMediaSchema = external_exports2.object({
|
|
27873
27940
|
path: external_exports2.string().describe("Path to the media file to read. Supports images (png, jpg, jpeg, webp, bmp, svg) and documents (pdf).")
|
|
27874
27941
|
});
|
|
27942
|
+
symbolsSchema = external_exports2.object({
|
|
27943
|
+
file: external_exports2.string().describe("Path to the file to list symbols from. Returns a hierarchical tree of functions, classes, structs, constants, etc. with line numbers and nesting (e.g., methods inside classes/impl blocks).")
|
|
27944
|
+
});
|
|
27875
27945
|
bashSchema = external_exports2.object({
|
|
27876
27946
|
command: external_exports2.string().describe("The bash command to execute"),
|
|
27877
27947
|
workingDirectory: external_exports2.string().optional().describe("Directory to execute the command in (optional)"),
|
|
@@ -35281,14 +35351,21 @@ function createWrappedTools(baseTools) {
|
|
|
35281
35351
|
baseTools.multiEditTool.execute
|
|
35282
35352
|
);
|
|
35283
35353
|
}
|
|
35354
|
+
if (baseTools.symbolsTool) {
|
|
35355
|
+
wrappedTools.symbolsToolInstance = wrapToolWithEmitter(
|
|
35356
|
+
baseTools.symbolsTool,
|
|
35357
|
+
"symbols",
|
|
35358
|
+
baseTools.symbolsTool.execute
|
|
35359
|
+
);
|
|
35360
|
+
}
|
|
35284
35361
|
return wrappedTools;
|
|
35285
35362
|
}
|
|
35286
|
-
var
|
|
35363
|
+
var import_child_process7, import_util13, import_crypto3, import_events, import_fs6, import_fs7, import_path8, toolCallEmitter, activeToolExecutions, wrapToolWithEmitter, listFilesTool, searchFilesTool, listFilesToolInstance, searchFilesToolInstance;
|
|
35287
35364
|
var init_probeTool = __esm({
|
|
35288
35365
|
"src/agent/probeTool.js"() {
|
|
35289
35366
|
"use strict";
|
|
35290
35367
|
init_index();
|
|
35291
|
-
|
|
35368
|
+
import_child_process7 = require("child_process");
|
|
35292
35369
|
import_util13 = require("util");
|
|
35293
35370
|
import_crypto3 = require("crypto");
|
|
35294
35371
|
import_events = require("events");
|
|
@@ -73938,6 +74015,7 @@ CRITICAL - ALWAYS search before answering:
|
|
|
73938
74015
|
You must NEVER answer questions about the codebase from memory or general knowledge. ALWAYS use the search and extract tools first to find the actual code, then base your answer ONLY on what you found. Even if you think you know the answer, you MUST verify it against the actual code. Your answers must be grounded in code evidence, not assumptions.
|
|
73939
74016
|
|
|
73940
74017
|
When exploring code:
|
|
74018
|
+
- Use the symbols tool to get a quick overview of a file's structure (functions, classes, constants) before diving into details with extract
|
|
73941
74019
|
- Provide clear, concise explanations based on user request
|
|
73942
74020
|
- Find and highlight the most relevant code snippets, if required
|
|
73943
74021
|
- Trace function calls and data flow through the system \u2014 follow the FULL call chain, not just the entry point
|
|
@@ -73968,6 +74046,7 @@ You think like a code explorer \u2014 you understand that codebases have layers:
|
|
|
73968
74046
|
|
|
73969
74047
|
When searching:
|
|
73970
74048
|
- Search for the MAIN concept first, then think: "what RELATED subsystems would a real codebase have?"
|
|
74049
|
+
- Use symbols to get a file's table of contents (functions, classes, constants with line numbers) before extracting \u2014 it helps you pick the right symbols to extract
|
|
73971
74050
|
- Use extract to READ the code you find \u2014 look for function calls, type references, and imports that point to OTHER relevant code
|
|
73972
74051
|
- If you find middleware, check: are there org-level or tenant-level variants?
|
|
73973
74052
|
- If you find algorithms, check: are there different storage backends?
|
|
@@ -74011,6 +74090,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
74011
74090
|
- Do not add code comments unless the logic is genuinely complex and non-obvious.
|
|
74012
74091
|
|
|
74013
74092
|
# Before Implementation
|
|
74093
|
+
- Use symbols to get a quick overview of file structure (functions, classes, constants with line numbers) before reading or editing files.
|
|
74014
74094
|
- Read tests first \u2014 find existing test files for the module you're changing. They reveal expected behavior, edge cases, and the project's testing patterns.
|
|
74015
74095
|
- Read neighboring files \u2014 understand naming conventions, error handling patterns, import style, and existing utilities before creating new ones.
|
|
74016
74096
|
- Trace the call chain \u2014 follow how the code you're changing is called and what depends on it. Check interfaces, types, and consumers.
|
|
@@ -74047,7 +74127,7 @@ Use the right tool:
|
|
|
74047
74127
|
1. To MODIFY existing code \u2192 \`edit\` tool (old_string \u2192 new_string, or start_line/end_line)
|
|
74048
74128
|
2. To CREATE a new file \u2192 \`create\` tool
|
|
74049
74129
|
3. To CHANGE multiple files at once \u2192 \`multi_edit\` tool
|
|
74050
|
-
4. To READ code \u2192 \`extract\` or \`search\` tools
|
|
74130
|
+
4. To READ code \u2192 \`extract\` or \`search\` tools. Use \`symbols\` to get a file's table of contents (functions, classes, constants with line numbers) before extracting.
|
|
74051
74131
|
5. If \`edit\` fails with "file has not been read yet" \u2192 use \`extract\` with the EXACT same file path you will pass to \`edit\`. Relative vs absolute path mismatch causes this error. Use the same path format consistently. If it still fails, use bash \`cat\` to read the file, then use \`create\` to write the entire modified file. Do NOT fall back to sed.
|
|
74052
74132
|
|
|
74053
74133
|
Bash is fine for: formatters (gofmt, prettier, black), build/test/lint commands, git operations, and read-only file inspection (cat, head, tail). sed/awk should ONLY be used for trivial non-code tasks (e.g., config file tweaks) where the replacement is a simple literal string swap.
|
|
@@ -76501,6 +76581,7 @@ var require_stringify = __commonJS({
|
|
|
76501
76581
|
nullStr: "null",
|
|
76502
76582
|
simpleKeys: false,
|
|
76503
76583
|
singleQuote: null,
|
|
76584
|
+
trailingComma: false,
|
|
76504
76585
|
trueStr: "true",
|
|
76505
76586
|
verifyAliasOrder: true
|
|
76506
76587
|
}, doc.schema.toStringOptions, options);
|
|
@@ -77018,12 +77099,19 @@ ${indent}${line}` : "\n";
|
|
|
77018
77099
|
if (comment)
|
|
77019
77100
|
reqNewline = true;
|
|
77020
77101
|
let str = stringify.stringify(item, itemCtx, () => comment = null);
|
|
77021
|
-
|
|
77102
|
+
reqNewline || (reqNewline = lines.length > linesAtValue || str.includes("\n"));
|
|
77103
|
+
if (i < items.length - 1) {
|
|
77022
77104
|
str += ",";
|
|
77105
|
+
} else if (ctx.options.trailingComma) {
|
|
77106
|
+
if (ctx.options.lineWidth > 0) {
|
|
77107
|
+
reqNewline || (reqNewline = lines.reduce((sum, line) => sum + line.length + 2, 2) + (str.length + 2) > ctx.options.lineWidth);
|
|
77108
|
+
}
|
|
77109
|
+
if (reqNewline) {
|
|
77110
|
+
str += ",";
|
|
77111
|
+
}
|
|
77112
|
+
}
|
|
77023
77113
|
if (comment)
|
|
77024
77114
|
str += stringifyComment.lineComment(str, itemIndent, commentString(comment));
|
|
77025
|
-
if (!reqNewline && (lines.length > linesAtValue || str.includes("\n")))
|
|
77026
|
-
reqNewline = true;
|
|
77027
77115
|
lines.push(str);
|
|
77028
77116
|
linesAtValue = lines.length;
|
|
77029
77117
|
}
|
|
@@ -80037,17 +80125,22 @@ var require_compose_node = __commonJS({
|
|
|
80037
80125
|
case "block-map":
|
|
80038
80126
|
case "block-seq":
|
|
80039
80127
|
case "flow-collection":
|
|
80040
|
-
|
|
80041
|
-
|
|
80042
|
-
|
|
80128
|
+
try {
|
|
80129
|
+
node = composeCollection.composeCollection(CN, ctx, token, props, onError);
|
|
80130
|
+
if (anchor)
|
|
80131
|
+
node.anchor = anchor.source.substring(1);
|
|
80132
|
+
} catch (error40) {
|
|
80133
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
80134
|
+
onError(token, "RESOURCE_EXHAUSTION", message);
|
|
80135
|
+
}
|
|
80043
80136
|
break;
|
|
80044
80137
|
default: {
|
|
80045
80138
|
const message = token.type === "error" ? token.message : `Unsupported token (type: ${token.type})`;
|
|
80046
80139
|
onError(token, "UNEXPECTED_TOKEN", message);
|
|
80047
|
-
node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError);
|
|
80048
80140
|
isSrcToken = false;
|
|
80049
80141
|
}
|
|
80050
80142
|
}
|
|
80143
|
+
node ?? (node = composeEmptyNode(ctx, token.offset, void 0, null, props, onError));
|
|
80051
80144
|
if (anchor && node.anchor === "")
|
|
80052
80145
|
onError(anchor, "BAD_ALIAS", "Anchor cannot be an empty string");
|
|
80053
80146
|
if (atKey && ctx.options.stringKeys && (!identity2.isScalar(node) || typeof node.value !== "string" || node.tag && node.tag !== "tag:yaml.org,2002:str")) {
|
|
@@ -95036,7 +95129,7 @@ async function executeBashCommand(command, options = {}) {
|
|
|
95036
95129
|
[cmd, ...cmdArgs] = args;
|
|
95037
95130
|
useShell = false;
|
|
95038
95131
|
}
|
|
95039
|
-
const child = (0,
|
|
95132
|
+
const child = (0, import_child_process8.spawn)(cmd, cmdArgs, {
|
|
95040
95133
|
cwd,
|
|
95041
95134
|
env: processEnv,
|
|
95042
95135
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -95232,11 +95325,11 @@ function validateExecutionOptions(options = {}) {
|
|
|
95232
95325
|
warnings
|
|
95233
95326
|
};
|
|
95234
95327
|
}
|
|
95235
|
-
var
|
|
95328
|
+
var import_child_process8, import_path13, import_fs10;
|
|
95236
95329
|
var init_bashExecutor = __esm({
|
|
95237
95330
|
"src/agent/bashExecutor.js"() {
|
|
95238
95331
|
"use strict";
|
|
95239
|
-
|
|
95332
|
+
import_child_process8 = require("child_process");
|
|
95240
95333
|
import_path13 = require("path");
|
|
95241
95334
|
import_fs10 = require("fs");
|
|
95242
95335
|
init_bashCommandUtils();
|
|
@@ -96762,7 +96855,7 @@ ${opts.schema}`;
|
|
|
96762
96855
|
}
|
|
96763
96856
|
}
|
|
96764
96857
|
const toolCollector = [];
|
|
96765
|
-
const proc2 = (0,
|
|
96858
|
+
const proc2 = (0, import_child_process9.spawn)("sh", ["-c", shellCmd], {
|
|
96766
96859
|
env: { ...process.env, FORCE_COLOR: "0" },
|
|
96767
96860
|
stdio: ["ignore", "pipe", "pipe"]
|
|
96768
96861
|
// Ignore stdin since echo handles it
|
|
@@ -97117,11 +97210,11 @@ function combinePrompts(systemPrompt, customPrompt, agent) {
|
|
|
97117
97210
|
}
|
|
97118
97211
|
return systemPrompt || "";
|
|
97119
97212
|
}
|
|
97120
|
-
var
|
|
97213
|
+
var import_child_process9, import_crypto6, import_promises5, import_path15, import_os5, import_events3;
|
|
97121
97214
|
var init_enhanced_claude_code = __esm({
|
|
97122
97215
|
"src/agent/engines/enhanced-claude-code.js"() {
|
|
97123
97216
|
"use strict";
|
|
97124
|
-
|
|
97217
|
+
import_child_process9 = require("child_process");
|
|
97125
97218
|
import_crypto6 = require("crypto");
|
|
97126
97219
|
import_promises5 = __toESM(require("fs/promises"), 1);
|
|
97127
97220
|
import_path15 = __toESM(require("path"), 1);
|
|
@@ -97163,7 +97256,7 @@ async function createCodexEngine(options = {}) {
|
|
|
97163
97256
|
if (debug) {
|
|
97164
97257
|
console.log("[DEBUG] Starting Codex MCP server...");
|
|
97165
97258
|
}
|
|
97166
|
-
const codexProcess = (0,
|
|
97259
|
+
const codexProcess = (0, import_child_process10.spawn)("codex", ["mcp-server"], {
|
|
97167
97260
|
stdio: ["pipe", "pipe", "pipe"]
|
|
97168
97261
|
});
|
|
97169
97262
|
let requestId = 0;
|
|
@@ -97395,11 +97488,11 @@ function combinePrompts2(systemPrompt, customPrompt, agent) {
|
|
|
97395
97488
|
}
|
|
97396
97489
|
return systemPrompt || "";
|
|
97397
97490
|
}
|
|
97398
|
-
var
|
|
97491
|
+
var import_child_process10, import_crypto7, import_readline;
|
|
97399
97492
|
var init_codex = __esm({
|
|
97400
97493
|
"src/agent/engines/codex.js"() {
|
|
97401
97494
|
"use strict";
|
|
97402
|
-
|
|
97495
|
+
import_child_process10 = require("child_process");
|
|
97403
97496
|
import_crypto7 = require("crypto");
|
|
97404
97497
|
import_readline = require("readline");
|
|
97405
97498
|
init_built_in_server();
|
|
@@ -98165,6 +98258,9 @@ var init_ProbeAgent = __esm({
|
|
|
98165
98258
|
if (isToolAllowed("searchFiles")) {
|
|
98166
98259
|
this.toolImplementations.searchFiles = searchFilesToolInstance;
|
|
98167
98260
|
}
|
|
98261
|
+
if (wrappedTools.symbolsToolInstance && isToolAllowed("symbols")) {
|
|
98262
|
+
this.toolImplementations.symbols = wrappedTools.symbolsToolInstance;
|
|
98263
|
+
}
|
|
98168
98264
|
if (this.enableSkills) {
|
|
98169
98265
|
const registry2 = this._getSkillsRegistry();
|
|
98170
98266
|
const { listSkillsToolInstance, useSkillToolInstance } = createSkillToolInstances({
|
|
@@ -99196,6 +99292,10 @@ var init_ProbeAgent = __esm({
|
|
|
99196
99292
|
schema: searchFilesSchema,
|
|
99197
99293
|
description: "Find files matching a glob pattern with recursive search capability."
|
|
99198
99294
|
},
|
|
99295
|
+
symbols: {
|
|
99296
|
+
schema: symbolsSchema,
|
|
99297
|
+
description: "List all symbols (functions, classes, structs, constants, etc.) in a file. Returns a hierarchical tree with line numbers \u2014 like a table of contents for code."
|
|
99298
|
+
},
|
|
99199
99299
|
readMedia: {
|
|
99200
99300
|
schema: readMediaSchema,
|
|
99201
99301
|
description: "Read and load a media file (image or PDF document) for AI analysis. Supports: png, jpg, jpeg, webp, bmp, svg, pdf."
|
|
@@ -99851,7 +99951,8 @@ ${this.architectureContext.content}
|
|
|
99851
99951
|
${searchToolDesc1}
|
|
99852
99952
|
- extract: Extract specific code sections with context
|
|
99853
99953
|
- listFiles: Browse directory contents
|
|
99854
|
-
- searchFiles: Find files by name patterns
|
|
99954
|
+
- searchFiles: Find files by name patterns
|
|
99955
|
+
- symbols: List all symbols in a file (functions, classes, constants, etc.) with line numbers`;
|
|
99855
99956
|
if (this.enableBash) {
|
|
99856
99957
|
systemPrompt += `
|
|
99857
99958
|
- bash: Execute bash commands for system operations (building, running tests, git, etc.). NEVER use bash for code exploration (no grep, cat, find, head, tail) \u2014 always use search and extract tools instead, they are faster and more accurate.`;
|
|
@@ -99906,7 +100007,8 @@ Workspace: ${this.allowedFolders.join(", ")}`;
|
|
|
99906
100007
|
${searchToolDesc2}
|
|
99907
100008
|
- extract: Extract specific code sections with context
|
|
99908
100009
|
- listFiles: Browse directory contents
|
|
99909
|
-
- searchFiles: Find files by name patterns
|
|
100010
|
+
- searchFiles: Find files by name patterns
|
|
100011
|
+
- symbols: List all symbols in a file (functions, classes, constants, etc.) with line numbers`;
|
|
99910
100012
|
if (this.enableBash) {
|
|
99911
100013
|
systemPrompt += `
|
|
99912
100014
|
- bash: Execute bash commands for system operations (building, running tests, git, etc.). NEVER use bash for code exploration (no grep, cat, find, head, tail) \u2014 always use search and extract tools instead, they are faster and more accurate.`;
|
|
@@ -100485,40 +100587,42 @@ or
|
|
|
100485
100587
|
}
|
|
100486
100588
|
const jsonStr = responseText.replace(/^```(?:json)?\s*/, "").replace(/\s*```$/, "");
|
|
100487
100589
|
const decision = JSON.parse(jsonStr);
|
|
100590
|
+
let grantedMs = 0;
|
|
100591
|
+
let grantedMin = 0;
|
|
100488
100592
|
if (decision.extend && decision.minutes > 0) {
|
|
100489
100593
|
const requestedMs = Math.min(decision.minutes, maxPerReqMin) * 6e4;
|
|
100490
|
-
|
|
100491
|
-
|
|
100594
|
+
grantedMs = Math.min(requestedMs, remainingBudgetMs, negotiatedTimeoutState.maxPerRequestMs);
|
|
100595
|
+
grantedMin = Math.round(grantedMs / 6e4 * 10) / 10;
|
|
100492
100596
|
negotiatedTimeoutState.extensionsUsed++;
|
|
100493
|
-
negotiatedTimeoutState.totalExtraTimeMs +=
|
|
100494
|
-
negotiatedTimeoutState.extensionMessage = `\u23F0 Time limit was reached. The timeout observer granted ${
|
|
100597
|
+
negotiatedTimeoutState.totalExtraTimeMs += grantedMs;
|
|
100598
|
+
negotiatedTimeoutState.extensionMessage = `\u23F0 Time limit was reached. The timeout observer granted ${grantedMin} more minute(s) (reason: ${decision.reason || "work in progress"}). Extensions remaining: ${negotiatedTimeoutState.maxRequests - negotiatedTimeoutState.extensionsUsed}. Continue your work efficiently.`;
|
|
100495
100599
|
negotiatedTimeoutState.softTimeoutId = setTimeout(() => {
|
|
100496
100600
|
runTimeoutObserver();
|
|
100497
|
-
},
|
|
100601
|
+
}, grantedMs);
|
|
100498
100602
|
if (this.debug) {
|
|
100499
|
-
console.log(`[DEBUG] Timeout observer: granted ${
|
|
100603
|
+
console.log(`[DEBUG] Timeout observer: granted ${grantedMin} min (reason: ${decision.reason}). Extensions: ${negotiatedTimeoutState.extensionsUsed}/${negotiatedTimeoutState.maxRequests}`);
|
|
100500
100604
|
}
|
|
100501
100605
|
if (this.tracer) {
|
|
100502
100606
|
this.tracer.addEvent("negotiated_timeout.observer_extended", {
|
|
100503
100607
|
decision_reason: decision.reason,
|
|
100504
100608
|
requested_minutes: decision.minutes,
|
|
100505
|
-
granted_ms:
|
|
100506
|
-
granted_min:
|
|
100609
|
+
granted_ms: grantedMs,
|
|
100610
|
+
granted_min: grantedMin,
|
|
100507
100611
|
extensions_used: negotiatedTimeoutState.extensionsUsed,
|
|
100508
100612
|
max_requests: negotiatedTimeoutState.maxRequests,
|
|
100509
100613
|
total_extra_time_ms: negotiatedTimeoutState.totalExtraTimeMs,
|
|
100510
|
-
budget_remaining_ms: remainingBudgetMs -
|
|
100614
|
+
budget_remaining_ms: remainingBudgetMs - grantedMs,
|
|
100511
100615
|
active_tools: activeToolsList.map((t) => t.name),
|
|
100512
100616
|
active_tools_count: activeToolsList.length
|
|
100513
100617
|
});
|
|
100514
100618
|
}
|
|
100515
100619
|
this.events.emit("timeout.extended", {
|
|
100516
|
-
grantedMs
|
|
100620
|
+
grantedMs,
|
|
100517
100621
|
reason: decision.reason || "work in progress",
|
|
100518
100622
|
extensionsUsed: negotiatedTimeoutState.extensionsUsed,
|
|
100519
100623
|
extensionsRemaining: negotiatedTimeoutState.maxRequests - negotiatedTimeoutState.extensionsUsed,
|
|
100520
100624
|
totalExtraTimeMs: negotiatedTimeoutState.totalExtraTimeMs,
|
|
100521
|
-
budgetRemainingMs: remainingBudgetMs -
|
|
100625
|
+
budgetRemainingMs: remainingBudgetMs - grantedMs
|
|
100522
100626
|
});
|
|
100523
100627
|
} else {
|
|
100524
100628
|
if (this.debug) {
|
|
@@ -103349,7 +103453,7 @@ The "searches" field helps the caller understand what was attempted.
|
|
|
103349
103453
|
- Deduplicate files across groups.
|
|
103350
103454
|
</output-rules>`;
|
|
103351
103455
|
}
|
|
103352
|
-
var import_ai5, import_fs12, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool;
|
|
103456
|
+
var import_ai5, import_fs12, CODE_SEARCH_SCHEMA, searchTool, queryTool, extractTool, delegateTool, analyzeAllTool, symbolsTool;
|
|
103353
103457
|
var init_vercel = __esm({
|
|
103354
103458
|
"src/tools/vercel.js"() {
|
|
103355
103459
|
"use strict";
|
|
@@ -103357,6 +103461,7 @@ var init_vercel = __esm({
|
|
|
103357
103461
|
init_search();
|
|
103358
103462
|
init_query();
|
|
103359
103463
|
init_extract();
|
|
103464
|
+
init_symbols();
|
|
103360
103465
|
init_delegate();
|
|
103361
103466
|
init_analyzeAll();
|
|
103362
103467
|
init_common();
|
|
@@ -104079,6 +104184,36 @@ Do NOT search for analogies or loosely related concepts. If the feature does not
|
|
|
104079
104184
|
}
|
|
104080
104185
|
});
|
|
104081
104186
|
};
|
|
104187
|
+
symbolsTool = (options = {}) => {
|
|
104188
|
+
return (0, import_ai5.tool)({
|
|
104189
|
+
name: "symbols",
|
|
104190
|
+
description: "List all symbols (functions, classes, structs, constants, etc.) in a file. Returns a hierarchical tree with line numbers \u2014 like a table of contents for code files.",
|
|
104191
|
+
inputSchema: symbolsSchema,
|
|
104192
|
+
execute: async ({ file: file2 }) => {
|
|
104193
|
+
try {
|
|
104194
|
+
let filePath = file2;
|
|
104195
|
+
if (options.cwd) {
|
|
104196
|
+
const resolvedPaths = parseAndResolvePaths(file2, options.cwd);
|
|
104197
|
+
if (resolvedPaths.length > 0) {
|
|
104198
|
+
filePath = resolvedPaths[0];
|
|
104199
|
+
}
|
|
104200
|
+
}
|
|
104201
|
+
const result = await symbols({
|
|
104202
|
+
files: [filePath],
|
|
104203
|
+
cwd: options.cwd,
|
|
104204
|
+
binaryOptions: options.binaryOptions
|
|
104205
|
+
});
|
|
104206
|
+
if (result && result.length > 0) {
|
|
104207
|
+
return JSON.stringify(result[0], null, 2);
|
|
104208
|
+
}
|
|
104209
|
+
return JSON.stringify({ file: file2, symbols: [] }, null, 2);
|
|
104210
|
+
} catch (error40) {
|
|
104211
|
+
console.error("Error executing symbols:", error40);
|
|
104212
|
+
return formatErrorForAI(error40);
|
|
104213
|
+
}
|
|
104214
|
+
}
|
|
104215
|
+
});
|
|
104216
|
+
};
|
|
104082
104217
|
}
|
|
104083
104218
|
});
|
|
104084
104219
|
|
|
@@ -105239,6 +105374,10 @@ You are Probe, a specialized code intelligence assistant. Your objective is to a
|
|
|
105239
105374
|
* **Purpose:** Retrieve specific code blocks or entire files *after* \`search\` or \`query\` identifies the target.
|
|
105240
105375
|
* **Syntax:** Optional \`#symbol\` (e.g., \`#MyClass\`), \`#Lstart-Lend\` (e.g., \`#L50-L75\`).
|
|
105241
105376
|
* **Mandatory Argument:** \`path\` (specific file path, e.g., \`"src/utils/helpers.go"\`, or dependency file like \`"go:github.com/gin-gonic/gin/context.go"\`).
|
|
105377
|
+
* \`symbols\`
|
|
105378
|
+
* **Purpose:** List all symbols (functions, classes, structs, constants, etc.) in a file \u2014 a table of contents with line numbers and nesting.
|
|
105379
|
+
* **Syntax:** \`file\` (path to the file to list symbols from).
|
|
105380
|
+
* **Use When:** You need to understand a file's structure before extracting specific parts, or to find the right symbol name/line number for \`extract\`.
|
|
105242
105381
|
|
|
105243
105382
|
[Examples]
|
|
105244
105383
|
|
|
@@ -105373,6 +105512,8 @@ __export(tools_exports, {
|
|
|
105373
105512
|
searchFilesSchema: () => searchFilesSchema,
|
|
105374
105513
|
searchSchema: () => searchSchema,
|
|
105375
105514
|
searchTool: () => searchTool,
|
|
105515
|
+
symbolsSchema: () => symbolsSchema,
|
|
105516
|
+
symbolsTool: () => symbolsTool,
|
|
105376
105517
|
tools: () => tools,
|
|
105377
105518
|
useSkillSchema: () => useSkillSchema
|
|
105378
105519
|
});
|
|
@@ -105496,16 +105637,16 @@ function shouldIgnore(filePath, ignorePatterns) {
|
|
|
105496
105637
|
}
|
|
105497
105638
|
return false;
|
|
105498
105639
|
}
|
|
105499
|
-
var import_fs15, import_path18, import_util14,
|
|
105640
|
+
var import_fs15, import_path18, import_util14, import_child_process11, execAsync3;
|
|
105500
105641
|
var init_file_lister = __esm({
|
|
105501
105642
|
"src/utils/file-lister.js"() {
|
|
105502
105643
|
"use strict";
|
|
105503
105644
|
import_fs15 = __toESM(require("fs"), 1);
|
|
105504
105645
|
import_path18 = __toESM(require("path"), 1);
|
|
105505
105646
|
import_util14 = require("util");
|
|
105506
|
-
|
|
105647
|
+
import_child_process11 = require("child_process");
|
|
105507
105648
|
init_symlink_utils();
|
|
105508
|
-
execAsync3 = (0, import_util14.promisify)(
|
|
105649
|
+
execAsync3 = (0, import_util14.promisify)(import_child_process11.exec);
|
|
105509
105650
|
}
|
|
105510
105651
|
});
|
|
105511
105652
|
|
|
@@ -105581,6 +105722,9 @@ __export(index_exports, {
|
|
|
105581
105722
|
searchSchema: () => searchSchema,
|
|
105582
105723
|
searchTool: () => searchTool,
|
|
105583
105724
|
setBinaryPath: () => setBinaryPath,
|
|
105725
|
+
symbols: () => symbols,
|
|
105726
|
+
symbolsSchema: () => symbolsSchema,
|
|
105727
|
+
symbolsTool: () => symbolsTool,
|
|
105584
105728
|
taskSchema: () => taskSchema,
|
|
105585
105729
|
taskSystemPrompt: () => taskSystemPrompt,
|
|
105586
105730
|
tools: () => tools_exports,
|
|
@@ -105594,6 +105738,7 @@ var init_index = __esm({
|
|
|
105594
105738
|
init_search();
|
|
105595
105739
|
init_query();
|
|
105596
105740
|
init_extract();
|
|
105741
|
+
init_symbols();
|
|
105597
105742
|
init_grep();
|
|
105598
105743
|
init_delegate();
|
|
105599
105744
|
init_utils();
|
|
@@ -105671,6 +105816,9 @@ init_index();
|
|
|
105671
105816
|
searchSchema,
|
|
105672
105817
|
searchTool,
|
|
105673
105818
|
setBinaryPath,
|
|
105819
|
+
symbols,
|
|
105820
|
+
symbolsSchema,
|
|
105821
|
+
symbolsTool,
|
|
105674
105822
|
taskSchema,
|
|
105675
105823
|
taskSystemPrompt,
|
|
105676
105824
|
tools,
|
package/index.d.ts
CHANGED
|
@@ -408,6 +408,58 @@ export interface QueryParams {
|
|
|
408
408
|
sessionId?: string;
|
|
409
409
|
}
|
|
410
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Symbols tool parameters
|
|
413
|
+
*/
|
|
414
|
+
export interface SymbolsParams {
|
|
415
|
+
/** Files to list symbols from */
|
|
416
|
+
files: string[];
|
|
417
|
+
/** Working directory for resolving relative paths */
|
|
418
|
+
cwd?: string;
|
|
419
|
+
/** Include test functions/methods */
|
|
420
|
+
allowTests?: boolean;
|
|
421
|
+
/** Binary options */
|
|
422
|
+
binaryOptions?: {
|
|
423
|
+
forceDownload?: boolean;
|
|
424
|
+
version?: string;
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* A node in the symbol tree
|
|
430
|
+
*/
|
|
431
|
+
export interface SymbolNode {
|
|
432
|
+
/** Symbol name */
|
|
433
|
+
name: string;
|
|
434
|
+
/** Symbol kind (function, struct, class, const, etc.) */
|
|
435
|
+
kind: string;
|
|
436
|
+
/** Clean signature without body */
|
|
437
|
+
signature: string;
|
|
438
|
+
/** Start line (1-indexed) */
|
|
439
|
+
line: number;
|
|
440
|
+
/** End line (1-indexed) */
|
|
441
|
+
end_line: number;
|
|
442
|
+
/** Nested symbols (methods inside classes/impl blocks, etc.) */
|
|
443
|
+
children?: SymbolNode[];
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Symbols extracted from a single file
|
|
448
|
+
*/
|
|
449
|
+
export interface FileSymbols {
|
|
450
|
+
/** File path */
|
|
451
|
+
file: string;
|
|
452
|
+
/** Top-level symbols with optional nesting */
|
|
453
|
+
symbols: SymbolNode[];
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Symbols tool function type
|
|
458
|
+
*/
|
|
459
|
+
export type SymbolsTool = (options?: SearchOptions) => {
|
|
460
|
+
execute(params: { file: string }): Promise<string>;
|
|
461
|
+
};
|
|
462
|
+
|
|
411
463
|
/**
|
|
412
464
|
* Extract tool parameters
|
|
413
465
|
*/
|
|
@@ -537,6 +589,11 @@ export declare function grep(options: {
|
|
|
537
589
|
};
|
|
538
590
|
}): Promise<string>;
|
|
539
591
|
|
|
592
|
+
/**
|
|
593
|
+
* List symbols (functions, structs, classes, constants, etc.) in files
|
|
594
|
+
*/
|
|
595
|
+
export declare function symbols(options: SymbolsParams): Promise<FileSymbols[]>;
|
|
596
|
+
|
|
540
597
|
/**
|
|
541
598
|
* Extract code blocks from files
|
|
542
599
|
*/
|
|
@@ -564,6 +621,11 @@ export declare function queryTool(options?: SearchOptions): ReturnType<QueryTool
|
|
|
564
621
|
*/
|
|
565
622
|
export declare function extractTool(options?: SearchOptions): ReturnType<ExtractTool>;
|
|
566
623
|
|
|
624
|
+
/**
|
|
625
|
+
* Create symbols tool instance
|
|
626
|
+
*/
|
|
627
|
+
export declare function symbolsTool(options?: SearchOptions): ReturnType<SymbolsTool>;
|
|
628
|
+
|
|
567
629
|
/**
|
|
568
630
|
* Get the path to the probe binary
|
|
569
631
|
*/
|
|
@@ -778,6 +840,7 @@ export declare function createTool(options?: EditToolOptions): {
|
|
|
778
840
|
export declare const searchSchema: any;
|
|
779
841
|
export declare const querySchema: any;
|
|
780
842
|
export declare const extractSchema: any;
|
|
843
|
+
export declare const symbolsSchema: any;
|
|
781
844
|
export declare const editSchema: any;
|
|
782
845
|
export declare const createSchema: any;
|
|
783
846
|
export declare const attemptCompletionSchema: any;
|
package/package.json
CHANGED
package/src/agent/ProbeAgent.js
CHANGED
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
searchFilesSchema,
|
|
57
57
|
readImageSchema,
|
|
58
58
|
readMediaSchema,
|
|
59
|
+
symbolsSchema,
|
|
59
60
|
listSkillsSchema,
|
|
60
61
|
useSkillSchema
|
|
61
62
|
} from './tools.js';
|
|
@@ -945,6 +946,9 @@ export class ProbeAgent {
|
|
|
945
946
|
if (isToolAllowed('searchFiles')) {
|
|
946
947
|
this.toolImplementations.searchFiles = searchFilesToolInstance;
|
|
947
948
|
}
|
|
949
|
+
if (wrappedTools.symbolsToolInstance && isToolAllowed('symbols')) {
|
|
950
|
+
this.toolImplementations.symbols = wrappedTools.symbolsToolInstance;
|
|
951
|
+
}
|
|
948
952
|
|
|
949
953
|
if (this.enableSkills) {
|
|
950
954
|
const registry = this._getSkillsRegistry();
|
|
@@ -2225,6 +2229,10 @@ export class ProbeAgent {
|
|
|
2225
2229
|
schema: searchFilesSchema,
|
|
2226
2230
|
description: 'Find files matching a glob pattern with recursive search capability.'
|
|
2227
2231
|
},
|
|
2232
|
+
symbols: {
|
|
2233
|
+
schema: symbolsSchema,
|
|
2234
|
+
description: 'List all symbols (functions, classes, structs, constants, etc.) in a file. Returns a hierarchical tree with line numbers — like a table of contents for code.'
|
|
2235
|
+
},
|
|
2228
2236
|
readMedia: {
|
|
2229
2237
|
schema: readMediaSchema,
|
|
2230
2238
|
description: 'Read and load a media file (image or PDF document) for AI analysis. Supports: png, jpg, jpeg, webp, bmp, svg, pdf.'
|
|
@@ -3019,7 +3027,8 @@ export class ProbeAgent {
|
|
|
3019
3027
|
${searchToolDesc1}
|
|
3020
3028
|
- extract: Extract specific code sections with context
|
|
3021
3029
|
- listFiles: Browse directory contents
|
|
3022
|
-
- searchFiles: Find files by name patterns
|
|
3030
|
+
- searchFiles: Find files by name patterns
|
|
3031
|
+
- symbols: List all symbols in a file (functions, classes, constants, etc.) with line numbers`;
|
|
3023
3032
|
|
|
3024
3033
|
if (this.enableBash) {
|
|
3025
3034
|
systemPrompt += `\n- bash: Execute bash commands for system operations (building, running tests, git, etc.). NEVER use bash for code exploration (no grep, cat, find, head, tail) — always use search and extract tools instead, they are faster and more accurate.`;
|
|
@@ -3085,7 +3094,8 @@ ${extractGuidance1}
|
|
|
3085
3094
|
${searchToolDesc2}
|
|
3086
3095
|
- extract: Extract specific code sections with context
|
|
3087
3096
|
- listFiles: Browse directory contents
|
|
3088
|
-
- searchFiles: Find files by name patterns
|
|
3097
|
+
- searchFiles: Find files by name patterns
|
|
3098
|
+
- symbols: List all symbols in a file (functions, classes, constants, etc.) with line numbers`;
|
|
3089
3099
|
|
|
3090
3100
|
if (this.enableBash) {
|
|
3091
3101
|
systemPrompt += `\n- bash: Execute bash commands for system operations (building, running tests, git, etc.). NEVER use bash for code exploration (no grep, cat, find, head, tail) — always use search and extract tools instead, they are faster and more accurate.`;
|
|
@@ -3814,10 +3824,13 @@ or
|
|
|
3814
3824
|
const jsonStr = responseText.replace(/^```(?:json)?\s*/, '').replace(/\s*```$/, '');
|
|
3815
3825
|
const decision = JSON.parse(jsonStr);
|
|
3816
3826
|
|
|
3827
|
+
let grantedMs = 0;
|
|
3828
|
+
let grantedMin = 0;
|
|
3829
|
+
|
|
3817
3830
|
if (decision.extend && decision.minutes > 0) {
|
|
3818
3831
|
const requestedMs = Math.min(decision.minutes, maxPerReqMin) * 60000;
|
|
3819
|
-
|
|
3820
|
-
|
|
3832
|
+
grantedMs = Math.min(requestedMs, remainingBudgetMs, negotiatedTimeoutState.maxPerRequestMs);
|
|
3833
|
+
grantedMin = Math.round(grantedMs / 60000 * 10) / 10;
|
|
3821
3834
|
|
|
3822
3835
|
// Update state
|
|
3823
3836
|
negotiatedTimeoutState.extensionsUsed++;
|