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.
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ code-symbol-index = code_symbol_index:main
@@ -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