indexter 0.1.2__tar.gz

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.
Files changed (37) hide show
  1. indexter-0.1.2/PKG-INFO +609 -0
  2. indexter-0.1.2/README.md +562 -0
  3. indexter-0.1.2/pyproject.toml +120 -0
  4. indexter-0.1.2/src/indexter/__init__.py +9 -0
  5. indexter-0.1.2/src/indexter/cli/__init__.py +5 -0
  6. indexter-0.1.2/src/indexter/cli/cli.py +450 -0
  7. indexter-0.1.2/src/indexter/cli/config.py +77 -0
  8. indexter-0.1.2/src/indexter/cli/store.py +419 -0
  9. indexter-0.1.2/src/indexter/config.py +860 -0
  10. indexter-0.1.2/src/indexter/exceptions.py +10 -0
  11. indexter-0.1.2/src/indexter/mcp/__init__.py +0 -0
  12. indexter-0.1.2/src/indexter/mcp/prompts.py +62 -0
  13. indexter-0.1.2/src/indexter/mcp/server.py +220 -0
  14. indexter-0.1.2/src/indexter/mcp/tools.py +146 -0
  15. indexter-0.1.2/src/indexter/models.py +610 -0
  16. indexter-0.1.2/src/indexter/parser/__init__.py +3 -0
  17. indexter-0.1.2/src/indexter/parser/models.py +76 -0
  18. indexter-0.1.2/src/indexter/parser/parser.py +196 -0
  19. indexter-0.1.2/src/indexter/parser/parsers/__init__.py +0 -0
  20. indexter-0.1.2/src/indexter/parser/parsers/base.py +154 -0
  21. indexter-0.1.2/src/indexter/parser/parsers/chunk.py +59 -0
  22. indexter-0.1.2/src/indexter/parser/parsers/css.py +170 -0
  23. indexter-0.1.2/src/indexter/parser/parsers/html.py +344 -0
  24. indexter-0.1.2/src/indexter/parser/parsers/javascript.py +301 -0
  25. indexter-0.1.2/src/indexter/parser/parsers/json.py +154 -0
  26. indexter-0.1.2/src/indexter/parser/parsers/markdown.py +133 -0
  27. indexter-0.1.2/src/indexter/parser/parsers/python.py +220 -0
  28. indexter-0.1.2/src/indexter/parser/parsers/rust.py +332 -0
  29. indexter-0.1.2/src/indexter/parser/parsers/toml.py +173 -0
  30. indexter-0.1.2/src/indexter/parser/parsers/typescript.py +388 -0
  31. indexter-0.1.2/src/indexter/parser/parsers/yaml.py +186 -0
  32. indexter-0.1.2/src/indexter/store/__init__.py +3 -0
  33. indexter-0.1.2/src/indexter/store/models.py +74 -0
  34. indexter-0.1.2/src/indexter/store/store.py +626 -0
  35. indexter-0.1.2/src/indexter/walker/__init__.py +3 -0
  36. indexter-0.1.2/src/indexter/walker/models.py +32 -0
  37. indexter-0.1.2/src/indexter/walker/walker.py +396 -0
@@ -0,0 +1,609 @@
1
+ Metadata-Version: 2.4
2
+ Name: indexter
3
+ Version: 0.1.2
4
+ Summary: CLI tool and MCP server for enhanced codebase context via RAG
5
+ Keywords: cli,mcp,rag,vector-search,tree-sitter,code-indexing,ai-agents
6
+ Author: Joe Badger
7
+ License-Expression: MIT
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
+ Classifier: Typing :: Typed
19
+ Requires-Dist: anyio>=4.0.0
20
+ Requires-Dist: pathspec>=0.12.1
21
+ Requires-Dist: qdrant-client[fastembed]>=1.12.0
22
+ Requires-Dist: pydantic>=2.10.0
23
+ Requires-Dist: pydantic-settings>=2.6.0
24
+ Requires-Dist: tomli>=2.0.0
25
+ Requires-Dist: tomlkit>=0.13.0
26
+ Requires-Dist: tree-sitter>=0.25.2
27
+ Requires-Dist: tree-sitter-language-pack>=0.13.0
28
+ Requires-Dist: docker>=7.0.0 ; extra == 'cli'
29
+ Requires-Dist: rich>=13.9.0 ; extra == 'cli'
30
+ Requires-Dist: typer>=0.12.0 ; extra == 'cli'
31
+ Requires-Dist: docker>=7.0.0 ; extra == 'full'
32
+ Requires-Dist: fastmcp>=0.4.1 ; extra == 'full'
33
+ Requires-Dist: rich>=13.9.0 ; extra == 'full'
34
+ Requires-Dist: typer>=0.12.0 ; extra == 'full'
35
+ Requires-Dist: fastmcp>=0.4.1 ; extra == 'mcp'
36
+ Requires-Python: >=3.11, <3.14
37
+ Project-URL: Homepage, https://github.com/jdbadger/indexter
38
+ Project-URL: Repository, https://github.com/jdbadger/indexter
39
+ Project-URL: Documentation, https://github.com/jdbadger/indexter#readme
40
+ Project-URL: Bug Tracker, https://github.com/jdbadger/indexter/issues
41
+ Project-URL: Changelog, https://github.com/jdbadger/indexter/blob/main/CHANGELOG.md
42
+ Provides-Extra: cli
43
+ Provides-Extra: core
44
+ Provides-Extra: full
45
+ Provides-Extra: mcp
46
+ Description-Content-Type: text/markdown
47
+
48
+ <div align="center">
49
+ <picture>
50
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jdbadger/indexter/main/indexter-light.svg">
51
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/jdbadger/indexter/main/indexter-dark.svg">
52
+ <img src="https://raw.githubusercontent.com/jdbadger/indexter/main/indexter.png" alt="Indexter Logo">
53
+ </picture>
54
+ </div>
55
+
56
+ <p align="center">
57
+ <strong>Semantic Code Context For Your LLM</strong>
58
+ </p>
59
+
60
+ Indexter indexes your local git repositories, parses them semantically using tree-sitter, and provides a hybrid search interface for AI agents via the Model Context Protocol (MCP).
61
+
62
+ ## Table of Contents
63
+
64
+ - [Features](#features)
65
+ - [Supported Languages](#supported-languages)
66
+ - [Prerequisites](#prerequisites)
67
+ - [Installation](#installation)
68
+ - [Using uv](#using-uv)
69
+ - [Modular Installation](#modular-installation)
70
+ - [Using pipx](#using-pipx)
71
+ - [From source](#from-source)
72
+ - [Quickstart](#quickstart)
73
+ - [Configuration](#configuration)
74
+ - [Global Configuration](#global-configuration)
75
+ - [Per-Repository Configuration](#per-repository-configuration)
76
+ - [CLI Usage](#cli-usage)
77
+ - [Examples](#examples)
78
+ - [MCP Usage](#mcp-usage)
79
+ - [Claude Desktop](#claude-desktop)
80
+ - [VS Code](#vs-code)
81
+ - [Cursor](#cursor)
82
+ - [Programmatic Usage](#programmatic-usage)
83
+ - [Contributing](#contributing)
84
+
85
+ ## Features
86
+
87
+ - 🌳 **Semantic parsing** using tree-sitter for:
88
+ - Python, JavaScript, TypeScript (including JSX/TSX), Rust
89
+ - HTML, CSS, JSON, YAML, TOML, Markdown
90
+ - Generic chunking fallback for other file types
91
+ - 📁 **Respects .gitignore** and configurable ignore patterns
92
+ - 🔄 **Incremental updates** sync changed files via content hash comparison
93
+ - 🔍 **Hybrid search** combining dense semantic vectors and sparse keyword vectors with reciprocal rank fusion (RRF)
94
+ - ⚡ **Powered by Qdrant** vector database with automatic embedding generation via FastEmbed
95
+ - ⌨️ **CLI** for indexing repositories, searching code and inspecting configuration from your terminal
96
+ - 🤖 **MCP server** for seamless AI agent integration via FastMCP
97
+ - 📦 **Multi-repo support** with separate collections per repository
98
+ - ⚙️ **XDG-compliant** configuration and data storage
99
+
100
+ ## Hybrid Search
101
+
102
+ Indexter uses **hybrid search** to combine the strengths of both semantic and keyword-based retrieval:
103
+
104
+ - **Dense Vectors**: Semantic embeddings (default: `sentence-transformers/all-MiniLM-L6-v2`) capture the meaning and context of code, enabling natural language queries like "authentication handler" to find relevant code even without exact keyword matches.
105
+
106
+ - **Sparse Vectors**: BM25 keyword embeddings (default: `Qdrant/bm25`) provide traditional keyword-based search, ensuring exact matches for function names, variable names, and technical terms.
107
+
108
+ - **Reciprocal Rank Fusion (RRF)**: Results from both dense and sparse searches are combined and re-ranked using RRF, which:
109
+ - Merges rankings from multiple retrieval methods
110
+ - Reduces the impact of outliers from any single method
111
+ - Provides more robust and relevant results than either approach alone
112
+
113
+ This hybrid approach ensures you get the best of both worlds: semantic understanding for conceptual queries and precision matching for specific identifiers.
114
+
115
+ ## Supported Languages
116
+
117
+ Indexter uses tree-sitter for semantic parsing. Each parser extracts meaningful code units **along with their documentation** (docstrings, JSDoc, TSDoc, Rust doc comments, etc.):
118
+
119
+ | Language | Extensions | Semantic Units Extracted |
120
+ |----------|------------|-------------------------|
121
+ | Python | `.py` | Functions (sync/async), classes, decorated definitions, module-level constants + docstrings |
122
+ | JavaScript | `.js`, `.jsx` | Function declarations, generators, arrow functions, classes, methods + JSDoc comments |
123
+ | TypeScript | `.ts`, `.tsx` | Functions, generators, arrow functions, classes, interfaces, type aliases + TSDoc comments |
124
+ | Rust | `.rs` | Functions (sync/async/unsafe), structs, enums, traits, impl blocks + doc comments (`///`, `//!`) |
125
+ | HTML | `.html` | Semantic elements: tables, lists, headers (`<h1>`–`<h6>`) |
126
+ | CSS | `.css` | Rule sets, media queries, keyframes, imports, at-rules |
127
+ | JSON | `.json` | Objects, arrays |
128
+ | YAML | `.yaml`, `.yml` | Block mappings, block sequences |
129
+ | TOML | `.toml` | Tables, array tables, top-level pairs |
130
+ | Markdown | `.md`, `.mkd`, `.markdown` | ATX headings with section content |
131
+ | *Fallback* | `*` | Fixed-size overlapping chunks (for unsupported file types) |
132
+
133
+ ## Prerequisites
134
+
135
+ - Python 3.11, 3.12, or 3.13
136
+ - [uv](https://docs.astral.sh/uv/) or [pipx](https://pipx.pypa.io/)
137
+ - [Docker](https://docs.docker.com/get-docker/) (for Qdrant vector database)
138
+
139
+ ## Installation
140
+
141
+ ### Using uv
142
+
143
+ To install the full application (CLI + MCP server):
144
+
145
+ ```bash
146
+ uv tool install "indexter[full]"
147
+ ```
148
+
149
+ ### Modular Installation
150
+
151
+ Indexter is modular. You can install only the components you need:
152
+
153
+ - **Full Application** (CLI + MCP): `uv tool install "indexter[full]"`
154
+ - **CLI Only**: `uv tool install indexter[cli]`
155
+ - **MCP Server Only**: `uv tool install indexter[mcp]`
156
+ - **Core Library Only**: `uv add indexter[core]` (preferred: explicit > implicit) or `uv add indexter` - Useful for programmatic usage or building custom integrations.
157
+
158
+ ### Using pipx
159
+
160
+ ```bash
161
+ pipx install "indexter[full]"
162
+ ```
163
+
164
+ ### From source
165
+
166
+ ```bash
167
+ git clone https://github.com/jdbadger/indexter.git
168
+ cd indexter
169
+ uv sync --all-extras
170
+ ```
171
+
172
+ ## Quickstart
173
+
174
+ ```bash
175
+ # Initialize the Qdrant vector store (pulls Docker image and starts container)
176
+ indexter store init
177
+
178
+ # Initialize and index a repository (indexes automatically by default)
179
+ indexter init --path /path/to/your/repo/root
180
+
181
+ # Or initialize current directory
182
+ indexter init
183
+
184
+ # Search the indexed code
185
+ indexter search "function that handles authentication" your-repo-name
186
+
187
+ # Check status of all indexed repositories
188
+ indexter status
189
+ ```
190
+
191
+ ## Configuration
192
+
193
+ ### Global Configuration
194
+
195
+ Indexter uses XDG-compliant paths for configuration and data storage:
196
+
197
+ | Type | Path |
198
+ |------|------|
199
+ | Config | `~/.config/indexter/indexter.toml` |
200
+ | Data | `~/.local/share/indexter/` |
201
+
202
+ The global config controls embedding model, file processing settings, vector store, and MCP server:
203
+
204
+ ```bash
205
+ # Show current configuration
206
+ indexter config show
207
+
208
+ # Get config file path
209
+ indexter config path
210
+
211
+ # Edit config manually
212
+ $EDITOR $(indexter config path)
213
+ ```
214
+
215
+ ```toml
216
+ # ~/.config/indexter/indexter.toml
217
+
218
+ # Dense embedding model for semantic search (default: 384-dim sentence-transformers model)
219
+ embedding_model = "sentence-transformers/all-MiniLM-L6-v2"
220
+
221
+ # Sparse embedding model for keyword-based search (BM25 algorithm)
222
+ sparse_embedding_model = "Qdrant/bm25"
223
+
224
+ # File patterns to exclude from indexing (gitignore-style syntax)
225
+ # These are in addition to patterns from .gitignore files
226
+ ignore_patterns = [
227
+ ".git/",
228
+ "__pycache__/",
229
+ "*.pyc",
230
+ ".DS_Store",
231
+ "node_modules/",
232
+ ".venv/",
233
+ "*.lock",
234
+ # etc...
235
+ ]
236
+
237
+ # Maximum file size (in bytes) to process
238
+ max_file_size = 1048576 # 1 MB
239
+
240
+ # Maximum number of files to process in a repository
241
+ max_files = 1000
242
+
243
+ # Number of top similar documents to retrieve for queries
244
+ top_k = 10
245
+
246
+ # Number of documents to upsert in a single batch operation
247
+ upsert_batch_size = 100
248
+
249
+ [store]
250
+ # Vector Store connection mode: 'server' or 'memory'
251
+ mode = "server"
252
+
253
+ # Docker image for the Qdrant container (used by 'indexter store init')
254
+ image = "qdrant/qdrant:latest"
255
+
256
+ # Timeout in seconds for API operations (increase if experiencing timeouts)
257
+ timeout = 120
258
+
259
+ # Server mode settings (used when mode = "server"):
260
+ # host = "localhost" # Hostname of the Qdrant server
261
+ # port = 6333 # HTTP API port
262
+ # grpc_port = 6334 # gRPC port
263
+ # prefer_grpc = false # Whether to prefer gRPC over HTTP
264
+ # api_key = "" # API key for authentication
265
+
266
+ [mcp]
267
+ # MCP transport mode: 'stdio' or 'http'
268
+ transport = "stdio"
269
+
270
+ # HTTP mode settings (only used when transport = "http"):
271
+ # host = "localhost" # Hostname for the MCP HTTP server
272
+ # port = 8765 # Port for the MCP HTTP server
273
+ ```
274
+
275
+ **Store Modes:**
276
+ - `server`: Docker-managed Qdrant container (default, managed via `indexter store` commands)
277
+ - `memory`: In-RAM, ephemeral — useful for testing
278
+
279
+ **MCP Transports:**
280
+ - `stdio`: Standard input/output streams (default for MCP server integrations)
281
+ - `http`: HTTP server mode — configure `host` and `port`
282
+
283
+ Settings can also be overridden via environment variables:
284
+
285
+ | Variable | Default | Description |
286
+ |----------|---------|-------------|
287
+ | `INDEXTER_EMBEDDING_MODEL` | `sentence-transformers/all-MiniLM-L6-v2` | Dense embedding model for semantic search |
288
+ | `INDEXTER_SPARSE_EMBEDDING_MODEL` | `Qdrant/bm25` | Sparse embedding model for keyword search |
289
+ | `INDEXTER_MAX_FILE_SIZE` | `1048576` | Maximum file size in bytes |
290
+ | `INDEXTER_MAX_FILES` | `1000` | Maximum files per repository |
291
+ | `INDEXTER_TOP_K` | `10` | Number of search results |
292
+ | `INDEXTER_UPSERT_BATCH_SIZE` | `100` | Batch size for vector operations |
293
+ | `INDEXTER_STORE_MODE` | `server` | Storage mode: `server` or `memory` |
294
+ | `INDEXTER_STORE_IMAGE` | `qdrant/qdrant:latest` | Docker image for Qdrant container |
295
+ | `INDEXTER_STORE_HOST` | `localhost` | Qdrant server host |
296
+ | `INDEXTER_STORE_PORT` | `6333` | Qdrant HTTP API port |
297
+ | `INDEXTER_STORE_GRPC_PORT` | `6334` | Qdrant gRPC port |
298
+ | `INDEXTER_STORE_PREFER_GRPC` | `false` | Prefer gRPC over HTTP |
299
+ | `INDEXTER_STORE_API_KEY` | `None` | Qdrant API key |
300
+ | `INDEXTER_STORE_TIMEOUT` | `120` | API operation timeout (seconds) |
301
+ | `INDEXTER_MCP_TRANSPORT` | `stdio` | MCP transport: `stdio` or `http` |
302
+ | `INDEXTER_MCP_HOST` | `localhost` | MCP HTTP server host |
303
+ | `INDEXTER_MCP_PORT` | `8765` | MCP HTTP server port |
304
+
305
+ ### Per-Repository Configuration
306
+
307
+ Create an `indexter.toml` in your repository root, or add a `[tool.indexter]` section to `pyproject.toml`:
308
+
309
+ ```toml
310
+ # indexter.toml (or [tool.indexter] in pyproject.toml)
311
+
312
+ # Dense embedding model for semantic search
313
+ # embedding_model = "sentence-transformers/all-MiniLM-L6-v2"
314
+
315
+ # Sparse embedding model for keyword-based search
316
+ # sparse_embedding_model = "Qdrant/bm25"
317
+
318
+ # Additional patterns to ignore (combined with .gitignore and global patterns)
319
+ ignore_patterns = [
320
+ "*.generated.*",
321
+ "vendor/",
322
+ ]
323
+
324
+ # Maximum file size (in bytes) to process. Default: 1048576 (1 MB)
325
+ # max_file_size = 1048576
326
+
327
+ # Maximum number of files to process in this repository. Default: 1000
328
+ # max_files = 1000
329
+
330
+ # Number of top similar documents to retrieve for queries. Default: 10
331
+ # top_k = 10
332
+
333
+ # Number of documents to batch when upserting to vector store. Default: 50
334
+ # upsert_batch_size = 100
335
+ ```
336
+
337
+ ## CLI Usage
338
+
339
+ ```
340
+ indexter - Enhanced codebase context for AI agents via RAG.
341
+
342
+ Commands:
343
+ init Initialize a git repository for indexing
344
+ --path, -p Path to the git repository (defaults to current directory)
345
+ --no-index, -n Skip indexing after initialization
346
+ index <name> Sync a repository to the vector store
347
+ search <query> <name> Search indexed nodes in a repository
348
+ status Show status of indexed repositories
349
+ forget <name> Remove a repository from indexter
350
+ config View Indexter global settings
351
+ show Show global settings with syntax highlighting
352
+ path Print path to the settings config file
353
+ store Manage the Qdrant vector store container
354
+ init Initialize the store (pull image and start container)
355
+ start Start the store container
356
+ status Show store container status
357
+ stop Stop the store container
358
+ remove Remove the store container
359
+ --volumes, -v Also remove data volumes
360
+
361
+ Options:
362
+ --verbose, -v Enable verbose output
363
+ --version Show version
364
+ --help Show help
365
+ ```
366
+
367
+ ### Store Management
368
+
369
+ Indexter uses Qdrant as its vector database, running in a Docker container. The `indexter store` commands manage this container lifecycle:
370
+
371
+ ```bash
372
+ # Initialize the store (pulls image, creates and starts container)
373
+ indexter store init
374
+
375
+ # Check container status
376
+ indexter store status
377
+
378
+ # Stop the container (data is preserved)
379
+ indexter store stop
380
+
381
+ # Start a stopped container
382
+ indexter store start
383
+
384
+ # Remove the container (data is preserved in ~/.local/share/indexter/qdrant)
385
+ indexter store remove
386
+
387
+ # Remove the container and all stored data
388
+ indexter store remove --volumes
389
+ ```
390
+
391
+ The store data is persisted in `~/.local/share/indexter/qdrant` via a bind mount, so your indexed data survives container restarts and removals (unless `--volumes` is used).
392
+
393
+ ### Examples
394
+
395
+ ```bash
396
+ # Initialize and index a repository
397
+ indexter init --path ~/projects/my-repo
398
+
399
+ # Initialize without indexing (index later)
400
+ indexter init --path ~/projects/my-repo --no-index
401
+ indexter index my-repo
402
+
403
+ # Initialize current directory
404
+ indexter init
405
+
406
+ # Force full re-index (ignores incremental sync)
407
+ indexter index my-repo --full
408
+
409
+ # Search with result limit
410
+ indexter search "error handling" my-repo --limit 5
411
+
412
+ # Forget a repository (removes from indexter and deletes indexed data)
413
+ indexter forget my-repo
414
+ ```
415
+
416
+ ## MCP Usage
417
+
418
+ Indexter provides an MCP server for AI agent integration. The server exposes:
419
+
420
+ | Type | Name | Description |
421
+ |------|------|-------------|
422
+ | Tool | `list_repositories` | List all configured repositories with their indexing status |
423
+ | Tool | `get_repository` | Get metadata for a specific repository |
424
+ | Tool | `search_repository` | Semantic search across indexed code with filtering options |
425
+ | Prompt | `search_workflow` | Guide for effectively searching code repositories |
426
+
427
+ ### Claude Desktop & Claude Code
428
+
429
+ Add to your `claude_desktop_config.json` (located at `~/Library/Application Support/Claude/` on macOS or `%APPDATA%\Claude\` on Windows):
430
+
431
+ ```json
432
+ {
433
+ "mcpServers": {
434
+ "indexter": {
435
+ "command": "indexter-mcp"
436
+ }
437
+ }
438
+ }
439
+ ```
440
+
441
+ If installed with uv:
442
+
443
+ ```json
444
+ {
445
+ "mcpServers": {
446
+ "indexter": {
447
+ "command": "uv",
448
+ "args": ["tool", "run", "indexter-mcp"]
449
+ }
450
+ }
451
+ }
452
+ ```
453
+
454
+ ### VS Code
455
+
456
+ Add to your VS Code settings (`.vscode/settings.json` in your workspace or user settings):
457
+
458
+ ```json
459
+ {
460
+ "github.copilot.chat.mcp.servers": {
461
+ "indexter": {
462
+ "command": "indexter-mcp"
463
+ }
464
+ }
465
+ }
466
+ ```
467
+
468
+ If installed with uv:
469
+
470
+ ```json
471
+ {
472
+ "github.copilot.chat.mcp.servers": {
473
+ "indexter": {
474
+ "command": "uv",
475
+ "args": ["tool", "run", "indexter-mcp"]
476
+ }
477
+ }
478
+ }
479
+ ```
480
+
481
+ ### Cursor
482
+
483
+ Add to your Cursor MCP settings:
484
+
485
+ ```json
486
+ {
487
+ "mcpServers": {
488
+ "indexter": {
489
+ "command": "indexter-mcp"
490
+ }
491
+ }
492
+ }
493
+ ```
494
+
495
+ If installed with uv:
496
+
497
+ ```json
498
+ {
499
+ "mcpServers": {
500
+ "indexter": {
501
+ "command": "uv",
502
+ "args": ["tool", "run", "indexter-mcp"]
503
+ }
504
+ }
505
+ }
506
+ ```
507
+
508
+ ## Programmatic Usage
509
+
510
+ For custom integrations, use the `Repo` class with a `VectorStore` context manager:
511
+
512
+ ```python
513
+ import asyncio
514
+ from pathlib import Path
515
+ from indexter import Repo
516
+ from indexter.store import VectorStore
517
+
518
+ async def main():
519
+ async with VectorStore() as store:
520
+ # Initialize a new repository (name derived from directory)
521
+ repo = await Repo.init(Path("/path/to/your/repo"), store)
522
+
523
+ # Index the repository
524
+ result = await repo.index(store)
525
+ print(f"Indexed {result.nodes_added} nodes")
526
+
527
+ # Search indexed code
528
+ results = await repo.search("authentication handler", store, limit=5)
529
+ for r in results.results:
530
+ print(f"{r.score:.3f}: {r.metadata['node_name']}")
531
+
532
+ # Retrieve an existing repository with status metadata
533
+ repo = await Repo.get_one("my-repo", store, with_metadata=True)
534
+ print(f"Stale: {repo.metadata.is_stale}")
535
+
536
+ # List all configured repositories
537
+ all_repos = await Repo.get_all(store)
538
+
539
+ # Remove a repository and its indexed data
540
+ await Repo.remove_one("my-repo", store)
541
+
542
+ asyncio.run(main())
543
+ ```
544
+
545
+ Key properties: `repo.name`, `repo.path`, `repo.collection_name`, `repo.settings`.
546
+
547
+ ## Contributing
548
+
549
+ Contributions are welcome! Please fork the repository, create a feature branch, and submit a pull request.
550
+
551
+ ```bash
552
+ # Clone your fork
553
+ git clone https://github.com/YOUR_USERNAME/indexter.git
554
+ cd indexter
555
+
556
+ # Install dependencies with all extras and test dependencies
557
+ uv sync --all-extras --group test
558
+
559
+ # Run tests
560
+ uv run --group test pytest
561
+
562
+ # Run tests against all supported python versions
563
+ uv run just test
564
+ ```
565
+
566
+ ### Pre-commit Hooks
567
+
568
+ This repository uses [pre-commit](https://pre-commit.com/) to automatically run code quality checks before commits. The following hooks are configured:
569
+
570
+ - **File validation**: Check JSON, TOML, and YAML syntax, prevent large files
571
+ - **Dependency locking**: Keep `uv.lock` synchronized with `pyproject.toml`
572
+ - **Code formatting**: Format code with [Ruff](https://docs.astral.sh/ruff/)
573
+ - **Linting**: Lint and auto-fix issues with Ruff
574
+ - **Testing**: Run tests with [pytest](https://pytest.org/) and [testmon](https://testmon.org/) for fast incremental testing
575
+ - **Type checking**: Verify type hints with [ty](https://docs.astral.sh/ty/)
576
+
577
+ #### Setup
578
+
579
+ First, install pre-commit if you haven't already:
580
+
581
+ ```bash
582
+ uv tool install pre-commit
583
+ ```
584
+
585
+ Then initialize pre-commit for your clone:
586
+
587
+ ```bash
588
+ pre-commit install
589
+ pre-commit install-hooks
590
+ ```
591
+
592
+ #### Usage
593
+
594
+ Pre-commit hooks will now run automatically on `git commit`. To run all hooks manually:
595
+
596
+ ```bash
597
+ # Run all hooks on all files
598
+ pre-commit run --all-files
599
+
600
+ # Run all hooks on staged files only
601
+ pre-commit run
602
+
603
+ # Run a specific hook
604
+ pre-commit run ruff-format --all-files
605
+ ```
606
+
607
+ ## License
608
+
609
+ MIT License - See [LICENSE](LICENSE) for details.