@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/src/agent/probeTool.js
CHANGED
|
@@ -265,6 +265,15 @@ export function createWrappedTools(baseTools) {
|
|
|
265
265
|
);
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
// Wrap symbols tool
|
|
269
|
+
if (baseTools.symbolsTool) {
|
|
270
|
+
wrappedTools.symbolsToolInstance = wrapToolWithEmitter(
|
|
271
|
+
baseTools.symbolsTool,
|
|
272
|
+
'symbols',
|
|
273
|
+
baseTools.symbolsTool.execute
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
268
277
|
return wrappedTools;
|
|
269
278
|
}
|
|
270
279
|
|
|
@@ -12,6 +12,7 @@ CRITICAL - ALWAYS search before answering:
|
|
|
12
12
|
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.
|
|
13
13
|
|
|
14
14
|
When exploring code:
|
|
15
|
+
- Use the symbols tool to get a quick overview of a file's structure (functions, classes, constants) before diving into details with extract
|
|
15
16
|
- Provide clear, concise explanations based on user request
|
|
16
17
|
- Find and highlight the most relevant code snippets, if required
|
|
17
18
|
- Trace function calls and data flow through the system — follow the FULL call chain, not just the entry point
|
|
@@ -43,6 +44,7 @@ You think like a code explorer — you understand that codebases have layers:
|
|
|
43
44
|
|
|
44
45
|
When searching:
|
|
45
46
|
- Search for the MAIN concept first, then think: "what RELATED subsystems would a real codebase have?"
|
|
47
|
+
- Use symbols to get a file's table of contents (functions, classes, constants with line numbers) before extracting — it helps you pick the right symbols to extract
|
|
46
48
|
- Use extract to READ the code you find — look for function calls, type references, and imports that point to OTHER relevant code
|
|
47
49
|
- If you find middleware, check: are there org-level or tenant-level variants?
|
|
48
50
|
- If you find algorithms, check: are there different storage backends?
|
|
@@ -90,6 +92,7 @@ If the solution is clear, you can jump to implementation right away. If not, ask
|
|
|
90
92
|
- Do not add code comments unless the logic is genuinely complex and non-obvious.
|
|
91
93
|
|
|
92
94
|
# Before Implementation
|
|
95
|
+
- Use symbols to get a quick overview of file structure (functions, classes, constants with line numbers) before reading or editing files.
|
|
93
96
|
- Read tests first — find existing test files for the module you're changing. They reveal expected behavior, edge cases, and the project's testing patterns.
|
|
94
97
|
- Read neighboring files — understand naming conventions, error handling patterns, import style, and existing utilities before creating new ones.
|
|
95
98
|
- Trace the call chain — follow how the code you're changing is called and what depends on it. Check interfaces, types, and consumers.
|
|
@@ -126,7 +129,7 @@ Use the right tool:
|
|
|
126
129
|
1. To MODIFY existing code → \`edit\` tool (old_string → new_string, or start_line/end_line)
|
|
127
130
|
2. To CREATE a new file → \`create\` tool
|
|
128
131
|
3. To CHANGE multiple files at once → \`multi_edit\` tool
|
|
129
|
-
4. To READ code → \`extract\` or \`search\` tools
|
|
132
|
+
4. To READ code → \`extract\` or \`search\` tools. Use \`symbols\` to get a file's table of contents (functions, classes, constants with line numbers) before extracting.
|
|
130
133
|
5. If \`edit\` fails with "file has not been read yet" → 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.
|
|
131
134
|
|
|
132
135
|
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.
|
package/src/agent/tools.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
extractTool,
|
|
6
6
|
delegateTool,
|
|
7
7
|
analyzeAllTool,
|
|
8
|
+
symbolsTool,
|
|
8
9
|
createExecutePlanTool,
|
|
9
10
|
createCleanupExecutePlanTool,
|
|
10
11
|
bashTool,
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
searchFilesSchema,
|
|
28
29
|
readImageSchema,
|
|
29
30
|
readMediaSchema,
|
|
31
|
+
symbolsSchema,
|
|
30
32
|
listSkillsSchema,
|
|
31
33
|
useSkillSchema
|
|
32
34
|
} from '../index.js';
|
|
@@ -52,6 +54,9 @@ export function createTools(configOptions) {
|
|
|
52
54
|
if (isToolAllowed('extract')) {
|
|
53
55
|
tools.extractTool = extractTool(configOptions);
|
|
54
56
|
}
|
|
57
|
+
if (isToolAllowed('symbols')) {
|
|
58
|
+
tools.symbolsTool = symbolsTool(configOptions);
|
|
59
|
+
}
|
|
55
60
|
if (configOptions.enableDelegate && isToolAllowed('delegate')) {
|
|
56
61
|
tools.delegateTool = delegateTool(configOptions);
|
|
57
62
|
}
|
|
@@ -111,6 +116,7 @@ export {
|
|
|
111
116
|
searchFilesSchema,
|
|
112
117
|
readImageSchema,
|
|
113
118
|
readMediaSchema,
|
|
119
|
+
symbolsSchema,
|
|
114
120
|
listSkillsSchema,
|
|
115
121
|
useSkillSchema
|
|
116
122
|
};
|
package/src/index.js
CHANGED
|
@@ -14,6 +14,7 @@ dotenv.config();
|
|
|
14
14
|
import { search } from './search.js';
|
|
15
15
|
import { query } from './query.js';
|
|
16
16
|
import { extract } from './extract.js';
|
|
17
|
+
import { symbols } from './symbols.js';
|
|
17
18
|
import { grep } from './grep.js';
|
|
18
19
|
import { delegate } from './delegate.js';
|
|
19
20
|
import { getBinaryPath, setBinaryPath } from './utils.js';
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
searchFilesSchema,
|
|
34
35
|
readImageSchema,
|
|
35
36
|
readMediaSchema,
|
|
37
|
+
symbolsSchema,
|
|
36
38
|
listSkillsSchema,
|
|
37
39
|
useSkillSchema
|
|
38
40
|
} from './tools/common.js';
|
|
@@ -41,7 +43,7 @@ import {
|
|
|
41
43
|
createSchema,
|
|
42
44
|
multiEditSchema
|
|
43
45
|
} from './tools/edit.js';
|
|
44
|
-
import { searchTool, queryTool, extractTool, delegateTool, analyzeAllTool } from './tools/vercel.js';
|
|
46
|
+
import { searchTool, queryTool, extractTool, delegateTool, analyzeAllTool, symbolsTool } from './tools/vercel.js';
|
|
45
47
|
import { createExecutePlanTool, createCleanupExecutePlanTool } from './tools/executePlan.js';
|
|
46
48
|
import { bashTool } from './tools/bash.js';
|
|
47
49
|
import { editTool, createTool, multiEditTool } from './tools/edit.js';
|
|
@@ -62,6 +64,7 @@ export {
|
|
|
62
64
|
search,
|
|
63
65
|
query,
|
|
64
66
|
extract,
|
|
67
|
+
symbols,
|
|
65
68
|
grep,
|
|
66
69
|
delegate,
|
|
67
70
|
getBinaryPath,
|
|
@@ -91,6 +94,7 @@ export {
|
|
|
91
94
|
extractTool,
|
|
92
95
|
delegateTool,
|
|
93
96
|
analyzeAllTool,
|
|
97
|
+
symbolsTool,
|
|
94
98
|
createExecutePlanTool,
|
|
95
99
|
createCleanupExecutePlanTool,
|
|
96
100
|
bashTool,
|
|
@@ -117,6 +121,7 @@ export {
|
|
|
117
121
|
searchFilesSchema,
|
|
118
122
|
readImageSchema,
|
|
119
123
|
readMediaSchema,
|
|
124
|
+
symbolsSchema,
|
|
120
125
|
listSkillsSchema,
|
|
121
126
|
useSkillSchema,
|
|
122
127
|
// Export task management
|
package/src/symbols.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Symbols functionality for the probe package
|
|
3
|
+
* @module symbols
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
import { getBinaryPath, escapeString } from './utils.js';
|
|
8
|
+
import { validateCwdPath } from './utils/path-validation.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* List symbols (functions, structs, classes, constants, etc.) in files
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} options - Symbols options
|
|
14
|
+
* @param {string[]} options.files - Files to list symbols from
|
|
15
|
+
* @param {string} [options.cwd] - Working directory for resolving relative file paths
|
|
16
|
+
* @param {boolean} [options.allowTests] - Include test functions/methods
|
|
17
|
+
* @param {Object} [options.binaryOptions] - Options for getting the binary
|
|
18
|
+
* @returns {Promise<Object[]>} - Array of FileSymbols objects (parsed JSON)
|
|
19
|
+
* @throws {Error} If the command fails
|
|
20
|
+
*/
|
|
21
|
+
export async function symbols(options) {
|
|
22
|
+
if (!options) {
|
|
23
|
+
throw new Error('Options object is required');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!options.files || !Array.isArray(options.files) || options.files.length === 0) {
|
|
27
|
+
throw new Error('At least one file path is required');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const binaryPath = await getBinaryPath(options.binaryOptions || {});
|
|
31
|
+
const cwd = await validateCwdPath(options.cwd);
|
|
32
|
+
|
|
33
|
+
const args = ['symbols', '--format', 'json'];
|
|
34
|
+
|
|
35
|
+
if (options.allowTests) {
|
|
36
|
+
args.push('--allow-tests');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
for (const file of options.files) {
|
|
40
|
+
args.push(escapeString(file));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (process.env.DEBUG === '1') {
|
|
44
|
+
console.error(`\nSymbols: files="${options.files.join(', ')}" cwd="${cwd}"`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const childProcess = spawn(binaryPath, args, {
|
|
49
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
50
|
+
cwd
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
let stdout = '';
|
|
54
|
+
let stderr = '';
|
|
55
|
+
|
|
56
|
+
childProcess.stdout.on('data', (data) => {
|
|
57
|
+
stdout += data.toString();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
childProcess.stderr.on('data', (data) => {
|
|
61
|
+
stderr += data.toString();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
childProcess.on('close', (code) => {
|
|
65
|
+
if (stderr && process.env.DEBUG === '1') {
|
|
66
|
+
console.error(`stderr: ${stderr}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (code !== 0) {
|
|
70
|
+
reject(new Error(`Symbols command failed with exit code ${code}: ${stderr}`));
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try {
|
|
75
|
+
const result = JSON.parse(stdout);
|
|
76
|
+
resolve(result);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
reject(new Error(`Failed to parse symbols output: ${error.message}. Output: ${stdout.substring(0, 200)}`));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
childProcess.on('error', (error) => {
|
|
83
|
+
reject(new Error(`Failed to spawn symbols process: ${error.message}`));
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
package/src/tools/common.js
CHANGED
|
@@ -72,6 +72,10 @@ export const readMediaSchema = z.object({
|
|
|
72
72
|
path: z.string().describe('Path to the media file to read. Supports images (png, jpg, jpeg, webp, bmp, svg) and documents (pdf).')
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
export const symbolsSchema = z.object({
|
|
76
|
+
file: z.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).')
|
|
77
|
+
});
|
|
78
|
+
|
|
75
79
|
export const bashSchema = z.object({
|
|
76
80
|
command: z.string().describe('The bash command to execute'),
|
|
77
81
|
workingDirectory: z.string().optional().describe('Directory to execute the command in (optional)'),
|
package/src/tools/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
// Export Vercel AI SDK tool generators
|
|
7
|
-
export { searchTool, queryTool, extractTool, delegateTool } from './vercel.js';
|
|
7
|
+
export { searchTool, queryTool, extractTool, delegateTool, symbolsTool } from './vercel.js';
|
|
8
8
|
export { bashTool } from './bash.js';
|
|
9
9
|
export { editTool, createTool, multiEditTool } from './edit.js';
|
|
10
10
|
|
|
@@ -31,6 +31,7 @@ export {
|
|
|
31
31
|
searchFilesSchema,
|
|
32
32
|
readImageSchema,
|
|
33
33
|
readMediaSchema,
|
|
34
|
+
symbolsSchema,
|
|
34
35
|
listSkillsSchema,
|
|
35
36
|
useSkillSchema
|
|
36
37
|
} from './common.js';
|
|
@@ -33,6 +33,10 @@ You are Probe, a specialized code intelligence assistant. Your objective is to a
|
|
|
33
33
|
* **Purpose:** Retrieve specific code blocks or entire files *after* \`search\` or \`query\` identifies the target.
|
|
34
34
|
* **Syntax:** Optional \`#symbol\` (e.g., \`#MyClass\`), \`#Lstart-Lend\` (e.g., \`#L50-L75\`).
|
|
35
35
|
* **Mandatory Argument:** \`path\` (specific file path, e.g., \`"src/utils/helpers.go"\`, or dependency file like \`"go:github.com/gin-gonic/gin/context.go"\`).
|
|
36
|
+
* \`symbols\`
|
|
37
|
+
* **Purpose:** List all symbols (functions, classes, structs, constants, etc.) in a file — a table of contents with line numbers and nesting.
|
|
38
|
+
* **Syntax:** \`file\` (path to the file to list symbols from).
|
|
39
|
+
* **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\`.
|
|
36
40
|
|
|
37
41
|
[Examples]
|
|
38
42
|
|
package/src/tools/vercel.js
CHANGED
|
@@ -7,9 +7,10 @@ import { tool, generateText } from 'ai';
|
|
|
7
7
|
import { search } from '../search.js';
|
|
8
8
|
import { query } from '../query.js';
|
|
9
9
|
import { extract } from '../extract.js';
|
|
10
|
+
import { symbols } from '../symbols.js';
|
|
10
11
|
import { delegate } from '../delegate.js';
|
|
11
12
|
import { analyzeAll } from './analyzeAll.js';
|
|
12
|
-
import { searchSchema, searchDelegateSchema, querySchema, extractSchema, delegateSchema, analyzeAllSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, parseTargets, parseAndResolvePaths, resolveTargetPath } from './common.js';
|
|
13
|
+
import { searchSchema, searchDelegateSchema, querySchema, extractSchema, symbolsSchema, delegateSchema, analyzeAllSchema, searchDescription, searchDelegateDescription, queryDescription, extractDescription, delegateDescription, analyzeAllDescription, parseTargets, parseAndResolvePaths, resolveTargetPath } from './common.js';
|
|
13
14
|
import { existsSync } from 'fs';
|
|
14
15
|
import { formatErrorForAI } from '../utils/error-types.js';
|
|
15
16
|
import { annotateOutputWithHashes } from './hashline.js';
|
|
@@ -1344,3 +1345,37 @@ export const analyzeAllTool = (options = {}) => {
|
|
|
1344
1345
|
}
|
|
1345
1346
|
});
|
|
1346
1347
|
};
|
|
1348
|
+
|
|
1349
|
+
export const symbolsTool = (options = {}) => {
|
|
1350
|
+
return tool({
|
|
1351
|
+
name: 'symbols',
|
|
1352
|
+
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 files.',
|
|
1353
|
+
inputSchema: symbolsSchema,
|
|
1354
|
+
execute: async ({ file }) => {
|
|
1355
|
+
try {
|
|
1356
|
+
let filePath = file;
|
|
1357
|
+
if (options.cwd) {
|
|
1358
|
+
const resolvedPaths = parseAndResolvePaths(file, options.cwd);
|
|
1359
|
+
if (resolvedPaths.length > 0) {
|
|
1360
|
+
filePath = resolvedPaths[0];
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
const result = await symbols({
|
|
1365
|
+
files: [filePath],
|
|
1366
|
+
cwd: options.cwd,
|
|
1367
|
+
binaryOptions: options.binaryOptions
|
|
1368
|
+
});
|
|
1369
|
+
|
|
1370
|
+
// Schema accepts single file, so return first result directly
|
|
1371
|
+
if (result && result.length > 0) {
|
|
1372
|
+
return JSON.stringify(result[0], null, 2);
|
|
1373
|
+
}
|
|
1374
|
+
return JSON.stringify({ file, symbols: [] }, null, 2);
|
|
1375
|
+
} catch (error) {
|
|
1376
|
+
console.error('Error executing symbols:', error);
|
|
1377
|
+
return formatErrorForAI(error);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
1381
|
+
};
|