Skip to content

Commit 5653a5c

Browse files
bugerclaude
andauthored
feat: add symbols tool — file symbol tree with line numbers (#546)
* feat: add symbols tool — file symbol tree with line numbers Add a new `symbols` command that lists all symbols (functions, structs, classes, constants, enums, traits, impl blocks, type aliases, etc.) in files as a table of contents with line numbers and nesting. Rust implementation uses tree-sitter AST parsing with a new `is_symbol_node()` trait method (broader than `is_acceptable_parent`) and recursive descent for nested symbols (methods inside impl/class). Full pipeline: CLI subcommand → Node.js wrapper → Vercel AI SDK tool → agent registration (schema, system prompt, predefined prompts). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address symbols tool review feedback - Refactor processor.rs extract_all_symbols_from_file to delegate to symbols::extract_symbols, eliminating duplicate AST traversal logic - Fix Vercel tool to return full result array instead of only first element - Add escapeString for file paths in symbols.js matching extract.js pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address Visor review feedback on symbols tool - Extract depth limit to named constant MAX_SYMBOL_DEPTH with docs - Pre-allocate Vec capacity in collect_symbols and format_symbols_text - Simplify Vercel tool return: always result[0] (schema takes single file) - Return consistent JSON for empty results instead of plain string - Improve symbolsSchema description to mention hierarchical nesting - Include stdout preview in JSON parse error messages - Clarify processor.rs legacy wrapper documentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5df01c7 commit 5653a5c

31 files changed

Lines changed: 1360 additions & 148 deletions

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ Direct access to Probe's search, query, and extract tools—without the agent la
204204
- `search` - Semantic code search with Elasticsearch-style queries
205205
- `query` - AST-based structural pattern matching
206206
- `extract` - Extract code blocks by line number or symbol name
207+
- `symbols` - List all symbols in a file (functions, classes, constants) with line numbers
207208

208209
---
209210

@@ -287,6 +288,24 @@ probe extract src/main.rs:10-50
287288
go test | probe extract
288289
```
289290

291+
#### Symbols Command
292+
293+
```bash
294+
probe symbols <FILES> [OPTIONS]
295+
```
296+
297+
**Examples:**
298+
```bash
299+
# List symbols in a file
300+
probe symbols src/main.rs
301+
302+
# JSON output for programmatic use
303+
probe symbols src/main.rs --format json
304+
305+
# Multiple files
306+
probe symbols src/main.rs src/lib.rs
307+
```
308+
290309
#### Query Command (AST Patterns)
291310

292311
```bash
@@ -333,7 +352,7 @@ console.log(agent.getTokenUsage());
333352
**Direct functions:**
334353

335354
```javascript
336-
import { search, extract, query } from '@probelabs/probe';
355+
import { search, extract, query, symbols } from '@probelabs/probe';
337356

338357
// Semantic search
339358
const results = await search({
@@ -348,6 +367,11 @@ const code = await extract({
348367
format: 'markdown'
349368
});
350369

370+
// List symbols in a file
371+
const fileSymbols = await symbols({
372+
files: ['src/auth.ts']
373+
});
374+
351375
// AST pattern query
352376
const matches = await query({
353377
pattern: 'async function $NAME($$$)',
@@ -461,6 +485,7 @@ Full documentation available at [probelabs.com/probe](https://probelabs.com/prob
461485
### Probe CLI
462486
- [Search Command](./docs/probe-cli/search.md) - Elasticsearch-style semantic search
463487
- [Extract Command](./docs/probe-cli/extract.md) - Extract code blocks with full AST context
488+
- [Symbols Command](./docs/probe-cli/symbols.md) - List all symbols in files with line numbers
464489
- [Query Command](./docs/probe-cli/query.md) - AST-based structural pattern matching
465490
- [CLI Reference](./docs/probe-cli/cli-reference.md) - Complete command-line reference
466491

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Pick a path based on what you need to do.
3737
|----------|-------------|
3838
| [Search](./probe-cli/search.md) | Semantic code search and query syntax |
3939
| [Extract](./probe-cli/extract.md) | Block extraction by line, range, symbol, or stdin/diff |
40+
| [Symbols](./probe-cli/symbols.md) | File symbol tree / table of contents with line numbers |
4041
| [Query](./probe-cli/query.md) | AST-grep structural search |
4142
| [CLI Reference](./probe-cli/cli-reference.md) | Command matrix and options |
4243

docs/probe-agent/protocols/acp.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ Initialize the ACP connection.
150150
"tools": [
151151
{ "name": "search", "kind": "search" },
152152
{ "name": "query", "kind": "query" },
153-
{ "name": "extract", "kind": "extract" }
153+
{ "name": "extract", "kind": "extract" },
154+
{ "name": "symbols", "kind": "symbols" }
154155
],
155156
"sessionManagement": true,
156157
"streaming": true,
@@ -458,6 +459,22 @@ Session state changed.
458459
}
459460
```
460461

462+
### symbols
463+
464+
```json
465+
{
466+
"name": "symbols",
467+
"description": "List all symbols in a file with line numbers and nesting",
468+
"kind": "symbols",
469+
"inputSchema": {
470+
"properties": {
471+
"file": { "type": "string", "description": "Path to the file to list symbols from" }
472+
},
473+
"required": ["file"]
474+
}
475+
}
476+
```
477+
461478
### delegate
462479

463480
```json

docs/probe-agent/protocols/mcp-integration.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ The Probe MCP server:
107107
- Implements the Model Context Protocol specification
108108
- Uses stdio for communication with AI editors
109109
- Automatically downloads and manages the Probe binary
110-
- Provides three main tools: search_code, query_code, and extract_code
110+
- Provides tools: search_code, query_code, extract_code, and symbols_code
111111
- Handles tool execution and error reporting
112112

113113
## Available Tools
@@ -216,6 +216,26 @@ Extract code blocks from files based on file paths and optional line numbers.
216216
}
217217
```
218218

219+
### symbols_code
220+
221+
List all symbols (functions, classes, structs, constants, etc.) in a file. Returns a hierarchical tree with line numbers.
222+
223+
#### Parameters
224+
225+
| Parameter | Type | Description | Required |
226+
|-----------|------|-------------|----------|
227+
| `path` | string | Absolute path to the directory | Yes |
228+
| `file` | string | File path to list symbols from | Yes |
229+
230+
#### Example
231+
232+
```json
233+
{
234+
"path": "/path/to/your/project",
235+
"file": "src/main.rs"
236+
}
237+
```
238+
219239
## Integration with AI Assistants
220240

221241
Once configured, you can ask your AI assistant to search your codebase with natural language queries. The AI will translate your request into appropriate Probe commands and display the results.

docs/probe-agent/protocols/mcp-server.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,21 @@ The extract_code tool supports the following parameters:
195195
- `contextLines`: Number of context lines to include (default: 0)
196196
- `format`: Output format (default: "json")
197197

198+
### symbols_code
199+
200+
List all symbols in a file — functions, classes, structs, constants, etc. with line numbers and nesting.
201+
202+
```json
203+
{
204+
"path": "/path/to/your/project",
205+
"file": "src/main.rs"
206+
}
207+
```
208+
209+
The symbols_code tool supports the following parameters:
210+
- `path`: The base directory
211+
- `file`: Path to the file to list symbols from
212+
198213
## Using Probe with AI Assistants
199214

200215
Once configured, you can ask your AI assistant to search your codebase with natural language queries. The AI will translate your request into appropriate Probe commands and display the results.

docs/probe-agent/protocols/mcp.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ When running as an MCP server, Probe exposes these tools:
4747
| `search` | Semantic code search with Elasticsearch syntax |
4848
| `query` | AST-based structural queries |
4949
| `extract` | Extract code blocks from files |
50+
| `symbols` | List all symbols in a file (TOC with line numbers) |
5051
| `listFiles` | List files in directory |
5152
| `searchFiles` | Find files by name pattern |
5253

@@ -105,6 +106,24 @@ When running as an MCP server, Probe exposes these tools:
105106
}
106107
```
107108

109+
**symbols**
110+
```json
111+
{
112+
"name": "symbols",
113+
"description": "List all symbols in a file with line numbers",
114+
"inputSchema": {
115+
"type": "object",
116+
"properties": {
117+
"file": {
118+
"type": "string",
119+
"description": "Path to the file to list symbols from"
120+
}
121+
},
122+
"required": ["file"]
123+
}
124+
}
125+
```
126+
108127
---
109128

110129
## AI Editor Integration

docs/probe-agent/sdk/api-reference.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,22 @@ const code = await extract(
359359

360360
---
361361

362+
### symbols()
363+
364+
List all symbols in a file — functions, classes, structs, constants, etc. with line numbers and nesting.
365+
366+
```javascript
367+
const fileSymbols = await symbols({
368+
files: ['src/auth.ts'],
369+
cwd: './project',
370+
allowTests: false
371+
}): Promise<FileSymbols[]>
372+
```
373+
374+
**Returns** an array of `FileSymbols` objects, each containing a `file` path and `symbols` array with nested `SymbolNode` entries.
375+
376+
---
377+
362378
### grep()
363379

364380
Ripgrep-style search.
@@ -383,13 +399,14 @@ const results = await grep({
383399
```javascript
384400
import { tools } from '@probelabs/probe';
385401

386-
const { searchTool, queryTool, extractTool } = tools;
402+
const { searchTool, queryTool, extractTool, symbolsTool } = tools;
387403

388404
// For Vercel AI SDK
389405
const toolSet = {
390406
search: searchTool({ defaultPath: './src' }),
391407
query: queryTool({ defaultPath: './src' }),
392-
extract: extractTool({ defaultPath: './src' })
408+
extract: extractTool({ defaultPath: './src' }),
409+
symbols: symbolsTool({ defaultPath: './src' })
393410
};
394411
```
395412

docs/probe-agent/sdk/tools-reference.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ProbeAgent provides a comprehensive set of tools that the AI can use to interact
88

99
| Category | Tools | Description |
1010
|----------|-------|-------------|
11-
| **Search & Query** | search, query, extract | Find and retrieve code |
11+
| **Search & Query** | search, query, extract, symbols | Find and retrieve code |
1212
| **File Operations** | edit, create, listFiles, searchFiles | Modify and explore files |
1313
| **Execution** | bash | Run shell commands |
1414
| **Analysis** | analyze_all, readMedia | Comprehensive analysis |
@@ -202,6 +202,39 @@ Extract code blocks from files by location or symbol.
202202

203203
---
204204

205+
### symbols
206+
207+
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.
208+
209+
**Parameters:**
210+
211+
| Parameter | Type | Required | Description |
212+
|-----------|------|----------|-------------|
213+
| `file` | string | Yes | Path to the file to list symbols from |
214+
215+
**Example AI Usage:**
216+
```xml
217+
<symbols>
218+
<file>src/auth/login.ts</file>
219+
</symbols>
220+
```
221+
222+
**Response format (JSON):**
223+
```json
224+
{
225+
"file": "src/auth/login.ts",
226+
"symbols": [
227+
{ "name": "loginUser", "kind": "function", "line": 5, "end_line": 25, "signature": "async function loginUser(email: string, password: string)" },
228+
{ "name": "AuthService", "kind": "class", "line": 27, "end_line": 80, "signature": "class AuthService", "children": [
229+
{ "name": "constructor", "kind": "method", "line": 28, "end_line": 35, "signature": "constructor()" },
230+
{ "name": "validate", "kind": "method", "line": 37, "end_line": 50, "signature": "validate(token: string): boolean" }
231+
]}
232+
]
233+
}
234+
```
235+
236+
---
237+
205238
## File Operation Tools
206239

207240
### edit

0 commit comments

Comments
 (0)