code-symbol-index 0.1.3__py3-none-any.whl
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.
- code_symbol_index-0.1.3.dist-info/METADATA +349 -0
- code_symbol_index-0.1.3.dist-info/RECORD +7 -0
- code_symbol_index-0.1.3.dist-info/WHEEL +5 -0
- code_symbol_index-0.1.3.dist-info/entry_points.txt +2 -0
- code_symbol_index-0.1.3.dist-info/licenses/LICENSE +21 -0
- code_symbol_index-0.1.3.dist-info/top_level.txt +1 -0
- code_symbol_index.py +3329 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: code-symbol-index
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: Tree-sitter backed symbol search and inspection for codebases.
|
|
5
|
+
Author-email: hit9 <hit9@icloud.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: pathspec
|
|
11
|
+
Requires-Dist: tree-sitter
|
|
12
|
+
Requires-Dist: tree-sitter-language-pack
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest; extra == "dev"
|
|
15
|
+
Dynamic: license-file
|
|
16
|
+
|
|
17
|
+
# code-symbol-index
|
|
18
|
+
|
|
19
|
+
Tree-sitter backed symbol index and code navigation for tools that need fast,
|
|
20
|
+
bounded, LLM-friendly answers over a local codebase.
|
|
21
|
+
|
|
22
|
+
It provides a small Python API and a single CLI command:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
code-symbol-index
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The default CLI output is readable text. Add `--json` on query commands when a
|
|
29
|
+
machine-readable response is better.
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- Disk-backed SQLite index at `.code-symbol-index/index.sqlite`
|
|
34
|
+
- Incremental indexing by `mtime_ns + size`
|
|
35
|
+
- `.gitignore` aware file discovery
|
|
36
|
+
- UTF-8 text file filtering
|
|
37
|
+
- Mainstream language parsing through `tree-sitter-language-pack`
|
|
38
|
+
- Symbol search, inspect, references, implementors, file outline, and index status
|
|
39
|
+
- Bounded outputs designed for coding LLM context windows
|
|
40
|
+
|
|
41
|
+
This is syntactic code navigation, not a language server. It does not provide
|
|
42
|
+
type-aware rename safety or full semantic call graph accuracy.
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
Install the CLI as a uv tool:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
uv tool install code-symbol-index
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or install from a local checkout:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv tool install .
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
For local development with editable imports and tests:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv venv .venv
|
|
62
|
+
uv pip install --python .venv/bin/python -e '.[dev]'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
code-symbol-index --version
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
Build or refresh the index:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
code-symbol-index index --root /path/to/repo
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Check whether indexed tools are available:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
code-symbol-index status --root /path/to/repo
|
|
83
|
+
code-symbol-index status --root /path/to/repo --check
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Search symbols:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
code-symbol-index search Tool --root /path/to/repo --limit 20
|
|
90
|
+
code-symbol-index search Tool Agent Runner --root /path/to/repo
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Inspect one symbol:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
code-symbol-index inspect Tool --root /path/to/repo
|
|
97
|
+
code-symbol-index inspect Tool.method_name --root /path/to/repo
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Outline a file:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
code-symbol-index outline src/app.py --root /path/to/repo
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## CLI
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
code-symbol-index languages
|
|
110
|
+
code-symbol-index --version
|
|
111
|
+
code-symbol-index version
|
|
112
|
+
code-symbol-index index --root /path/to/repo
|
|
113
|
+
code-symbol-index status --root /path/to/repo
|
|
114
|
+
code-symbol-index status --root /path/to/repo --check
|
|
115
|
+
code-symbol-index search Tool --root /path/to/repo
|
|
116
|
+
code-symbol-index search Tool Agent Runner --root /path/to/repo
|
|
117
|
+
code-symbol-index inspect Tool --root /path/to/repo
|
|
118
|
+
code-symbol-index outline src/app.py --root /path/to/repo
|
|
119
|
+
code-symbol-index refs Tool --root /path/to/repo --limit 20 --offset 0
|
|
120
|
+
code-symbol-index impls Greeter --root /path/to/repo --kind trait --limit 20 --offset 0
|
|
121
|
+
code-symbol-index clean --root /path/to/repo
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
JSON is available for structured consumers:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
code-symbol-index search Tool --root /path/to/repo --json
|
|
128
|
+
code-symbol-index inspect Tool --root /path/to/repo --json
|
|
129
|
+
code-symbol-index outline src/app.py --root /path/to/repo --json
|
|
130
|
+
code-symbol-index refs Tool --root /path/to/repo --json
|
|
131
|
+
code-symbol-index impls Tool --root /path/to/repo --json
|
|
132
|
+
code-symbol-index status --root /path/to/repo --json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Output Formats
|
|
136
|
+
|
|
137
|
+
Search returns candidates only, never source:
|
|
138
|
+
|
|
139
|
+
```text
|
|
140
|
+
query: Tool
|
|
141
|
+
count: 2
|
|
142
|
+
limit: 20
|
|
143
|
+
has_more: false
|
|
144
|
+
|
|
145
|
+
symbols:
|
|
146
|
+
- id: python:class:Tool:nanocode.py:1284:1330
|
|
147
|
+
name: Tool
|
|
148
|
+
kind: class
|
|
149
|
+
file: nanocode.py
|
|
150
|
+
range: 1284:1330
|
|
151
|
+
signature: class Tool:
|
|
152
|
+
score: exact
|
|
153
|
+
language: python
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
For multiple search queries:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
queries:
|
|
160
|
+
- Tool
|
|
161
|
+
- Agent
|
|
162
|
+
count: 2
|
|
163
|
+
limit: 20
|
|
164
|
+
has_more: false
|
|
165
|
+
|
|
166
|
+
symbols:
|
|
167
|
+
- id: python:class:Tool:nanocode.py:1284:1330
|
|
168
|
+
name: Tool
|
|
169
|
+
kind: class
|
|
170
|
+
file: nanocode.py
|
|
171
|
+
range: 1284:1330
|
|
172
|
+
signature: class Tool:
|
|
173
|
+
score: exact
|
|
174
|
+
matched_query: Tool
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Inspect returns bounded source with stable 0-based line ranges:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
symbol:
|
|
181
|
+
id: python:function:foo:src/app.py:120:123
|
|
182
|
+
name: foo
|
|
183
|
+
kind: function
|
|
184
|
+
file: src/app.py
|
|
185
|
+
range: 120:123
|
|
186
|
+
signature: def foo():
|
|
187
|
+
source:
|
|
188
|
+
status: full
|
|
189
|
+
range: 120:123
|
|
190
|
+
shown_range: 120:123
|
|
191
|
+
total_lines: 3
|
|
192
|
+
|
|
193
|
+
120 |def foo():
|
|
194
|
+
121 | if ok:
|
|
195
|
+
122 | return 1
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Outline returns file structure without source or ids:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
file: nanocode.py
|
|
202
|
+
range: 0:9060
|
|
203
|
+
count: 142
|
|
204
|
+
|
|
205
|
+
outline:
|
|
206
|
+
1284:1330 | class Tool:
|
|
207
|
+
1289:1292 | def cli_args(cls, args):
|
|
208
|
+
1312:1325 | def tool_schema(cls):
|
|
209
|
+
9023:9060 | def main(argv=None):
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Status is fast by default and does not scan the directory:
|
|
213
|
+
|
|
214
|
+
```text
|
|
215
|
+
index:
|
|
216
|
+
status: ready
|
|
217
|
+
root: /path/to/repo
|
|
218
|
+
files: 128
|
|
219
|
+
symbols: 4820
|
|
220
|
+
languages: python, typescript
|
|
221
|
+
language_breakdown:
|
|
222
|
+
- python: 80 files (62.5%)
|
|
223
|
+
- typescript: 48 files (37.5%)
|
|
224
|
+
pending_changes: unknown
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Use `--check` to scan the directory and compute staleness:
|
|
228
|
+
|
|
229
|
+
```text
|
|
230
|
+
index:
|
|
231
|
+
status: stale
|
|
232
|
+
root: /path/to/repo
|
|
233
|
+
files: 128
|
|
234
|
+
symbols: 4820
|
|
235
|
+
pending_changes: 3
|
|
236
|
+
reason: files changed after last index update
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Query Rules
|
|
240
|
+
|
|
241
|
+
`inspect` accepts only symbol-like input:
|
|
242
|
+
|
|
243
|
+
- `ClassName`
|
|
244
|
+
- `function_name`
|
|
245
|
+
- `ClassName.method_name`
|
|
246
|
+
- `symbol_prefix`
|
|
247
|
+
|
|
248
|
+
It rejects natural language, file paths, and directory paths. Use `outline` for
|
|
249
|
+
file paths.
|
|
250
|
+
|
|
251
|
+
All line ranges are `start:end`, 0-based, with `end` exclusive.
|
|
252
|
+
|
|
253
|
+
## Python API
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
import code_symbol_index as csi
|
|
257
|
+
|
|
258
|
+
csi.index("/path/to/repo")
|
|
259
|
+
csi.update(["src/app.py", "src/lib.py"], root="/path/to/repo")
|
|
260
|
+
|
|
261
|
+
print(csi.status_text("/path/to/repo"))
|
|
262
|
+
print(csi.search_text("Tool", root="/path/to/repo"))
|
|
263
|
+
print(csi.inspect_text("Tool", root="/path/to/repo"))
|
|
264
|
+
print(csi.outline_text("src/app.py", root="/path/to/repo"))
|
|
265
|
+
|
|
266
|
+
symbols = csi.search("Tool", root="/path/to/repo", format="object")
|
|
267
|
+
symbols = csi.search(["Tool", "Agent", "Runner"], root="/path/to/repo")
|
|
268
|
+
search_payload = csi.search("Tool", root="/path/to/repo", format="json")
|
|
269
|
+
search_text = csi.search("Tool", root="/path/to/repo", format="text")
|
|
270
|
+
inspection = csi.inspect("Tool", root="/path/to/repo")
|
|
271
|
+
references = csi.refs("Tool", root="/path/to/repo", limit=20, offset=0)
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
For repeated queries, reuse a repository handle:
|
|
275
|
+
|
|
276
|
+
```python
|
|
277
|
+
repo = csi.Repository("/path/to/repo")
|
|
278
|
+
repo.update(["src/app.py"])
|
|
279
|
+
print(repo.search_text("Tool"))
|
|
280
|
+
print(repo.inspect_text("Tool"))
|
|
281
|
+
print(repo.outline_text("src/app.py"))
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Queries require an existing index. Run `code-symbol-index index` or
|
|
285
|
+
`code_symbol_index.index()` first. Queries do not sync automatically unless
|
|
286
|
+
called with `--sync` or `sync=True`. After external file edits, call
|
|
287
|
+
`code_symbol_index.update(paths, root=...)` or `Repository.update(paths)` to
|
|
288
|
+
refresh only those files; deleted or newly ignored paths are removed from the
|
|
289
|
+
index.
|
|
290
|
+
|
|
291
|
+
Top-level query APIs accept `format="object" | "text" | "json"`:
|
|
292
|
+
|
|
293
|
+
- `object` returns Python dataclasses/lists and is the default.
|
|
294
|
+
- `text` returns the same readable format as the `*_text` helpers.
|
|
295
|
+
- `json` returns JSON-safe Python dict/list data.
|
|
296
|
+
|
|
297
|
+
`search` accepts one query or a list of symbol names/prefixes. Multiple queries
|
|
298
|
+
are OR-ed, are not regexes, and share one total `limit`. Search text and JSON
|
|
299
|
+
formats include `has_more` when more matches exist beyond `limit`.
|
|
300
|
+
|
|
301
|
+
## Development
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
make install
|
|
305
|
+
make check
|
|
306
|
+
make smoke
|
|
307
|
+
make clean
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Python API List
|
|
311
|
+
|
|
312
|
+
Index lifecycle:
|
|
313
|
+
|
|
314
|
+
- `index(root=".", *, language=None) -> Repository`
|
|
315
|
+
- `update(paths, *, root=".", language=None) -> Repository`
|
|
316
|
+
- `clean(root=".") -> None`
|
|
317
|
+
- `status(root=".", *, language=None, db_path=None, check=False, format="object") -> IndexStatus | str | dict`
|
|
318
|
+
- `status_text(root=".", *, language=None, db_path=None, check=False) -> str`
|
|
319
|
+
|
|
320
|
+
Queries:
|
|
321
|
+
|
|
322
|
+
- `search(query: str | list[str], *, root=".", kind=None, language=None, limit=20, sync=False, format="object") -> list[Symbol] | str | dict`
|
|
323
|
+
- `search_text(query: str | list[str], *, root=".", kind=None, language=None, limit=20, sync=False) -> str`
|
|
324
|
+
- `inspect(query, *, root=".", kind=None, language=None, limit=20, sync=False, format="object", ...) -> Inspection | str | dict`
|
|
325
|
+
- `inspect_text(query, *, root=".", kind=None, language=None, sync=False, ...) -> str`
|
|
326
|
+
- `refs(query, *, root=".", kind=None, language=None, limit=20, offset=0, sync=False, format="object") -> Page | str | dict`
|
|
327
|
+
- `impls(query, *, root=".", kind=None, language=None, limit=20, offset=0, sync=False, format="object") -> Page | str | dict`
|
|
328
|
+
- `outline(path, *, root=".", max_symbols=200, sync=False, format="object") -> Page | str | dict`
|
|
329
|
+
- `outline_text(path, *, root=".", max_symbols=200, sync=False) -> str`
|
|
330
|
+
|
|
331
|
+
Repository handle:
|
|
332
|
+
|
|
333
|
+
- `Repository(root=".", *, languages=None, include=None, exclude=None, db_path=None)`
|
|
334
|
+
- `Repository.refresh() -> Repository`
|
|
335
|
+
- `Repository.update(paths=None) -> Repository`
|
|
336
|
+
- `Repository.search(...)`, `search_text(...)`
|
|
337
|
+
- `Repository.inspect(...)`, `inspect_text(...)`
|
|
338
|
+
- `Repository.refs(...)`, `impls(...)`
|
|
339
|
+
- `Repository.outline(...)`, `outline_text(...)`
|
|
340
|
+
- `Repository.clean() -> None`
|
|
341
|
+
|
|
342
|
+
Data classes:
|
|
343
|
+
|
|
344
|
+
- `Symbol`
|
|
345
|
+
- `Reference`
|
|
346
|
+
- `Page`
|
|
347
|
+
- `Inspection`
|
|
348
|
+
- `InspectOptions`
|
|
349
|
+
- `IndexStatus`
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
code_symbol_index.py,sha256=FSydWQZJg3AbqtL-XZbRZBWFz67Cl8ZYI6JR84RYR7k,113882
|
|
2
|
+
code_symbol_index-0.1.3.dist-info/licenses/LICENSE,sha256=mp888oHgZoyIwgDvOI2rznGFfXbIk4rwf3mylkcEOhQ,1061
|
|
3
|
+
code_symbol_index-0.1.3.dist-info/METADATA,sha256=T3NpkjJzc2aKHgi72p1CQJ3foblrsJcOpmoKpG0FCf0,9171
|
|
4
|
+
code_symbol_index-0.1.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
5
|
+
code_symbol_index-0.1.3.dist-info/entry_points.txt,sha256=B4yZgK0HJQH4fzeGk26FUhznWGIf71zCkgnP3KBertw,61
|
|
6
|
+
code_symbol_index-0.1.3.dist-info/top_level.txt,sha256=OcNMQntgaQfMin4ZW1FObhv-Xg204_M8uJeMZZ6W4oA,18
|
|
7
|
+
code_symbol_index-0.1.3.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 hit9
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
code_symbol_index
|