pindex 1.0.0
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/LICENSE +21 -0
- package/README.md +767 -0
- package/dist/cli/daemon.d.ts +13 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +70 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +212 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +44 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +301 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/project-detector.d.ts +44 -0
- package/dist/cli/project-detector.d.ts.map +1 -0
- package/dist/cli/project-detector.js +144 -0
- package/dist/cli/project-detector.js.map +1 -0
- package/dist/cli/setup.d.ts +9 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +110 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/db/database.d.ts +5 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +19 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/migrations.d.ts +6 -0
- package/dist/db/migrations.d.ts.map +1 -0
- package/dist/db/migrations.js +32 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/queries.d.ts +132 -0
- package/dist/db/queries.d.ts.map +1 -0
- package/dist/db/queries.js +222 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +5 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +179 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/gui/index.d.ts +3 -0
- package/dist/gui/index.d.ts.map +1 -0
- package/dist/gui/index.js +56 -0
- package/dist/gui/index.js.map +1 -0
- package/dist/gui/server.d.ts +31 -0
- package/dist/gui/server.d.ts.map +1 -0
- package/dist/gui/server.js +729 -0
- package/dist/gui/server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer/index.d.ts +38 -0
- package/dist/indexer/index.d.ts.map +1 -0
- package/dist/indexer/index.js +283 -0
- package/dist/indexer/index.js.map +1 -0
- package/dist/indexer/parser.d.ts +20 -0
- package/dist/indexer/parser.d.ts.map +1 -0
- package/dist/indexer/parser.js +431 -0
- package/dist/indexer/parser.js.map +1 -0
- package/dist/indexer/summarizer.d.ts +15 -0
- package/dist/indexer/summarizer.d.ts.map +1 -0
- package/dist/indexer/summarizer.js +24 -0
- package/dist/indexer/summarizer.js.map +1 -0
- package/dist/indexer/watcher.d.ts +25 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +54 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/monitoring/estimator.d.ts +20 -0
- package/dist/monitoring/estimator.d.ts.map +1 -0
- package/dist/monitoring/estimator.js +94 -0
- package/dist/monitoring/estimator.js.map +1 -0
- package/dist/monitoring/server.d.ts +20 -0
- package/dist/monitoring/server.d.ts.map +1 -0
- package/dist/monitoring/server.js +86 -0
- package/dist/monitoring/server.js.map +1 -0
- package/dist/monitoring/token-logger.d.ts +26 -0
- package/dist/monitoring/token-logger.d.ts.map +1 -0
- package/dist/monitoring/token-logger.js +47 -0
- package/dist/monitoring/token-logger.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +310 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/find_usages.d.ts +4 -0
- package/dist/tools/find_usages.d.ts.map +1 -0
- package/dist/tools/find_usages.js +13 -0
- package/dist/tools/find_usages.js.map +1 -0
- package/dist/tools/get_context.d.ts +6 -0
- package/dist/tools/get_context.d.ts.map +1 -0
- package/dist/tools/get_context.js +36 -0
- package/dist/tools/get_context.js.map +1 -0
- package/dist/tools/get_dependencies.d.ts +4 -0
- package/dist/tools/get_dependencies.d.ts.map +1 -0
- package/dist/tools/get_dependencies.js +16 -0
- package/dist/tools/get_dependencies.js.map +1 -0
- package/dist/tools/get_doc_chunk.d.ts +4 -0
- package/dist/tools/get_doc_chunk.d.ts.map +1 -0
- package/dist/tools/get_doc_chunk.js +32 -0
- package/dist/tools/get_doc_chunk.js.map +1 -0
- package/dist/tools/get_file_summary.d.ts +4 -0
- package/dist/tools/get_file_summary.d.ts.map +1 -0
- package/dist/tools/get_file_summary.js +23 -0
- package/dist/tools/get_file_summary.js.map +1 -0
- package/dist/tools/get_project_overview.d.ts +5 -0
- package/dist/tools/get_project_overview.d.ts.map +1 -0
- package/dist/tools/get_project_overview.js +60 -0
- package/dist/tools/get_project_overview.js.map +1 -0
- package/dist/tools/get_symbol.d.ts +4 -0
- package/dist/tools/get_symbol.d.ts.map +1 -0
- package/dist/tools/get_symbol.js +21 -0
- package/dist/tools/get_symbol.js.map +1 -0
- package/dist/tools/get_token_stats.d.ts +4 -0
- package/dist/tools/get_token_stats.d.ts.map +1 -0
- package/dist/tools/get_token_stats.js +6 -0
- package/dist/tools/get_token_stats.js.map +1 -0
- package/dist/tools/reindex.d.ts +5 -0
- package/dist/tools/reindex.d.ts.map +1 -0
- package/dist/tools/reindex.js +21 -0
- package/dist/tools/reindex.js.map +1 -0
- package/dist/tools/save_context.d.ts +4 -0
- package/dist/tools/save_context.d.ts.map +1 -0
- package/dist/tools/save_context.js +17 -0
- package/dist/tools/save_context.js.map +1 -0
- package/dist/tools/search_docs.d.ts +4 -0
- package/dist/tools/search_docs.d.ts.map +1 -0
- package/dist/tools/search_docs.js +42 -0
- package/dist/tools/search_docs.js.map +1 -0
- package/dist/tools/search_symbols.d.ts +5 -0
- package/dist/tools/search_symbols.d.ts.map +1 -0
- package/dist/tools/search_symbols.js +36 -0
- package/dist/tools/search_symbols.js.map +1 -0
- package/dist/tools/start_comparison.d.ts +4 -0
- package/dist/tools/start_comparison.d.ts.map +1 -0
- package/dist/tools/start_comparison.js +15 -0
- package/dist/tools/start_comparison.js.map +1 -0
- package/dist/types.d.ts +318 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,767 @@
|
|
|
1
|
+
# PindeX – MCP Codebase Indexer
|
|
2
|
+
|
|
3
|
+
**Structural codebase indexing for AI coding assistants — 80–90% fewer tokens per session.**
|
|
4
|
+
|
|
5
|
+
PindeX is an [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that parses your TypeScript/JavaScript project with `tree-sitter`, stores symbols, imports, and dependency graphs in a local SQLite database, and exposes 13 targeted tools so AI assistants can answer questions about your code — and your documentation — without reading entire files.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [How It Works](#how-it-works)
|
|
12
|
+
- [Requirements](#requirements)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Quick Start](#quick-start)
|
|
15
|
+
- [Multi-Project & Federation](#multi-project--federation)
|
|
16
|
+
- [MCP Tools](#mcp-tools)
|
|
17
|
+
- [Code tools](#code-tools)
|
|
18
|
+
- [Document & context tools](#document--context-tools)
|
|
19
|
+
- [Environment Variables](#environment-variables)
|
|
20
|
+
- [Integrations](#integrations)
|
|
21
|
+
- [Claude Code](#claude-code)
|
|
22
|
+
- [Goose](#goose)
|
|
23
|
+
- [CLI Reference](#cli-reference)
|
|
24
|
+
- [Monitoring Dashboard](#monitoring-dashboard)
|
|
25
|
+
- [Development](#development)
|
|
26
|
+
- [Project Structure](#project-structure)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## How It Works
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
Your project files
|
|
34
|
+
│
|
|
35
|
+
├── .ts/.js ──► tree-sitter AST ──► symbols, imports, dependencies
|
|
36
|
+
│ │
|
|
37
|
+
└── .md/.yaml/.txt ──► chunker ──────────► documents (heading/line chunks)
|
|
38
|
+
│
|
|
39
|
+
Claude calls save_context(…) ──────────────────► context_entries
|
|
40
|
+
│
|
|
41
|
+
▼
|
|
42
|
+
SQLite (FTS5) ← stored in ~/.pindex/projects/{hash}/index.db
|
|
43
|
+
├── files (path, hash, language, token estimate)
|
|
44
|
+
├── symbols (name, kind, signature, lines) ─► search_symbols
|
|
45
|
+
├── dependencies (import graph) ─► get_dependencies
|
|
46
|
+
├── usages (symbol → call sites) ─► find_usages
|
|
47
|
+
├── documents (text chunks from .md/.yaml/.txt) ─► search_docs
|
|
48
|
+
├── context_entries (notes saved by Claude mid-session) ─► search_docs
|
|
49
|
+
└── token_log (per-session metrics)
|
|
50
|
+
│
|
|
51
|
+
▼
|
|
52
|
+
13 MCP tools ──── stdio ────► Claude Code / Goose / any MCP client
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Instead of sending full file contents to the AI, PindeX lets it call `search_symbols`, `search_docs`, `get_context`, or `get_file_summary` — returning only what it actually needs.
|
|
56
|
+
Claude can also persist important facts across sessions with `save_context`, then retrieve them later with `search_docs` instead of re-reading large files.
|
|
57
|
+
Token savings are tracked per session and visible in a live web dashboard.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Requirements
|
|
62
|
+
|
|
63
|
+
| Dependency | Version |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Node.js | ≥ 18.0.0 |
|
|
66
|
+
| npm | ≥ 8 |
|
|
67
|
+
| Operating System | macOS, Linux, Windows (WSL recommended) |
|
|
68
|
+
|
|
69
|
+
> **Note:** `better-sqlite3` ships prebuilt binaries for most platforms. If your environment is unusual, `npm install` will compile from source — you'll need `python3` and a C++ compiler (`build-essential` / Xcode CLT).
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Installation
|
|
74
|
+
|
|
75
|
+
### Install globally from source
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
git clone https://github.com/phash/PindeX.git
|
|
79
|
+
cd PindeX
|
|
80
|
+
npm install
|
|
81
|
+
npm run build
|
|
82
|
+
npm install -g .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This makes three commands available globally:
|
|
86
|
+
|
|
87
|
+
| Command | Purpose |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `pindex` | CLI — init, federation, status |
|
|
90
|
+
| `pindex-server` | MCP stdio server (Claude Code spawns this automatically) |
|
|
91
|
+
| `pindex-gui` | Aggregated dashboard for all projects |
|
|
92
|
+
|
|
93
|
+
> **Note:** PindeX is not yet published on npm. Use `npm install -g .` from the cloned repo to install globally.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
### 1. Set up a project
|
|
100
|
+
|
|
101
|
+
Run `pindex` (with no arguments) in any project directory:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd /my/project
|
|
105
|
+
pindex
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
PindeX will:
|
|
109
|
+
1. Walk upward from your current directory to find the project root (`package.json`, `.git`, etc.)
|
|
110
|
+
2. Assign a dedicated monitoring port for this project
|
|
111
|
+
3. Write `.mcp.json` into the project root with absolute paths
|
|
112
|
+
4. Register the project in `~/.pindex/registry.json`
|
|
113
|
+
|
|
114
|
+
Output:
|
|
115
|
+
```
|
|
116
|
+
╔══════════════════════════════════════════╗
|
|
117
|
+
║ PindeX – Ready ║
|
|
118
|
+
╚══════════════════════════════════════════╝
|
|
119
|
+
|
|
120
|
+
Project : /my/project
|
|
121
|
+
Index : ~/.pindex/projects/a3f8b2c1/index.db
|
|
122
|
+
Port : 7856
|
|
123
|
+
Config : .mcp.json (written)
|
|
124
|
+
|
|
125
|
+
── Next steps ─────────────────────────────
|
|
126
|
+
1. Restart Claude Code in this directory
|
|
127
|
+
2. Open the dashboard: pindex-gui
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 2. Restart Claude Code
|
|
131
|
+
|
|
132
|
+
Claude Code auto-discovers `.mcp.json`. On the next startup it will spawn `pindex-server` with the correct `PROJECT_ROOT` — the index is built automatically in the background.
|
|
133
|
+
|
|
134
|
+
### 3. Use the tools
|
|
135
|
+
|
|
136
|
+
Once connected, your AI assistant can call tools like:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
search_symbols("AuthService")
|
|
140
|
+
get_file_summary("src/auth/service.ts")
|
|
141
|
+
get_context("src/auth/service.ts", 42, 20)
|
|
142
|
+
find_usages("validateToken")
|
|
143
|
+
get_dependencies("src/api/routes.ts", "both")
|
|
144
|
+
|
|
145
|
+
# Documentation and context memory:
|
|
146
|
+
search_docs("authentication JWT") # search CLAUDE.md, README.md, …
|
|
147
|
+
get_doc_chunk("CLAUDE.md", 2) # read one section only
|
|
148
|
+
save_context("Decision: use JWT …", "auth") # store for future sessions
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 4. Open the dashboard
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
pindex-gui
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Opens `http://localhost:7842` — an aggregated dashboard showing token savings, symbol counts, and session stats for **all** registered projects.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Multi-Project & Federation
|
|
162
|
+
|
|
163
|
+
### Multiple independent projects
|
|
164
|
+
|
|
165
|
+
Each project gets its own `.mcp.json` (pointing to its own `PROJECT_ROOT`) and its own SQLite database at `~/.pindex/projects/{hash}/index.db`. When Claude Code opens Project A, it spawns `pindex-server` with `PROJECT_ROOT=/path/to/project-a` — it never touches Project B's index.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
cd /project-a && pindex # registers project-a
|
|
169
|
+
cd /project-b && pindex # registers project-b, different port + different DB
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Linking repos (federation)
|
|
173
|
+
|
|
174
|
+
If you work on a monorepo split into separate repositories, or if one project imports types from another, you can link them:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cd /project-a
|
|
178
|
+
pindex add /project-b
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
This updates `/project-a/.mcp.json` with `FEDERATION_REPOS=/project-b`. After restarting Claude Code in Project A, the MCP tools search **both** codebases:
|
|
182
|
+
|
|
183
|
+
- `search_symbols` returns results from both projects (federated results include a `project` field)
|
|
184
|
+
- `get_project_overview` shows stats for all linked projects
|
|
185
|
+
|
|
186
|
+
Add more repos at any time:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
pindex add /project-c # links a third repo
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Remove a link:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
pindex remove /project-b
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### View all projects
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
pindex status
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
3 registered project(s):
|
|
206
|
+
|
|
207
|
+
[idle] project-a + 1 federated repo
|
|
208
|
+
/home/user/project-a
|
|
209
|
+
port: 7856 index: ~/.pindex/projects/a3f8b2c1/
|
|
210
|
+
|
|
211
|
+
[idle] project-b
|
|
212
|
+
/home/user/project-b
|
|
213
|
+
port: 7901 index: ~/.pindex/projects/f1e2d3c4/
|
|
214
|
+
...
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## MCP Tools
|
|
220
|
+
|
|
221
|
+
All 13 tools are available over stdio transport.
|
|
222
|
+
|
|
223
|
+
### Code tools
|
|
224
|
+
|
|
225
|
+
### `search_symbols`
|
|
226
|
+
|
|
227
|
+
Full-text search across all indexed symbols (names, signatures, summaries) using SQLite FTS5.
|
|
228
|
+
When federation is active, results from linked repos include a `project` field.
|
|
229
|
+
|
|
230
|
+
| Parameter | Type | Required | Description |
|
|
231
|
+
|---|---|---|---|
|
|
232
|
+
| `query` | string | ✓ | Search term (supports FTS5 syntax) |
|
|
233
|
+
| `limit` | number | | Max results per project (default: 20) |
|
|
234
|
+
|
|
235
|
+
**Returns:** List of matching symbols with name, kind, signature, file path, and line number.
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
### `get_symbol`
|
|
240
|
+
|
|
241
|
+
Detailed information about a specific symbol including its signature, location, and the files it depends on.
|
|
242
|
+
|
|
243
|
+
| Parameter | Type | Required | Description |
|
|
244
|
+
|---|---|---|---|
|
|
245
|
+
| `name` | string | ✓ | Symbol name |
|
|
246
|
+
| `file` | string | | Narrow results to a specific file path |
|
|
247
|
+
|
|
248
|
+
**Returns:** Symbol record + file-level dependency list.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### `get_context`
|
|
253
|
+
|
|
254
|
+
Read a slice of a source file centred around a given line. Files are read from disk at call time — only metadata lives in the DB.
|
|
255
|
+
|
|
256
|
+
| Parameter | Type | Required | Description |
|
|
257
|
+
|---|---|---|---|
|
|
258
|
+
| `file` | string | ✓ | File path (relative to `PROJECT_ROOT`) |
|
|
259
|
+
| `line` | number | ✓ | Centre line |
|
|
260
|
+
| `range` | number | | Lines above and below (default: 30) |
|
|
261
|
+
|
|
262
|
+
**Returns:** Code snippet with detected language and line numbers.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
### `get_file_summary`
|
|
267
|
+
|
|
268
|
+
High-level overview of a file without loading its full content.
|
|
269
|
+
|
|
270
|
+
| Parameter | Type | Required | Description |
|
|
271
|
+
|---|---|---|---|
|
|
272
|
+
| `file` | string | ✓ | File path |
|
|
273
|
+
|
|
274
|
+
**Returns:** Language, summary text, all symbols (with kind + signature), imports, and exports.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### `find_usages`
|
|
279
|
+
|
|
280
|
+
All locations in the codebase where a symbol is referenced.
|
|
281
|
+
|
|
282
|
+
| Parameter | Type | Required | Description |
|
|
283
|
+
|---|---|---|---|
|
|
284
|
+
| `symbol` | string | ✓ | Symbol name to look up |
|
|
285
|
+
|
|
286
|
+
**Returns:** List of `{ file, line, context }` entries.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
### `get_dependencies`
|
|
291
|
+
|
|
292
|
+
Import graph for a file — what it imports, what imports it, or both.
|
|
293
|
+
|
|
294
|
+
| Parameter | Type | Required | Description |
|
|
295
|
+
|---|---|---|---|
|
|
296
|
+
| `target` | string | ✓ | File path |
|
|
297
|
+
| `direction` | `"imports"` \| `"imported_by"` \| `"both"` | | Default: `"both"` |
|
|
298
|
+
|
|
299
|
+
**Returns:** Dependency list with resolved file paths and imported symbol names.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
### `get_project_overview`
|
|
304
|
+
|
|
305
|
+
Project-wide statistics — no parameters required.
|
|
306
|
+
When federation is active, also includes stats for each linked repository.
|
|
307
|
+
|
|
308
|
+
**Returns:** Total file count, dominant language, entry points (`index`, `main`, `app` files), module list with symbol counts, and (if federated) per-repo breakdowns.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### `reindex`
|
|
313
|
+
|
|
314
|
+
Rebuild the index for a single file or the entire project.
|
|
315
|
+
|
|
316
|
+
| Parameter | Type | Required | Description |
|
|
317
|
+
|---|---|---|---|
|
|
318
|
+
| `target` | string | | File path or omit for full project reindex |
|
|
319
|
+
|
|
320
|
+
**Returns:** Count of indexed / updated / error files.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### `get_token_stats`
|
|
325
|
+
|
|
326
|
+
Token usage and savings statistics for a session.
|
|
327
|
+
|
|
328
|
+
| Parameter | Type | Required | Description |
|
|
329
|
+
|---|---|---|---|
|
|
330
|
+
| `session_id` | string | | Defaults to `"default"` |
|
|
331
|
+
|
|
332
|
+
**Returns:** Total tokens used, estimated tokens without the index, net savings, and savings percentage.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### `start_comparison`
|
|
337
|
+
|
|
338
|
+
Create a labelled A/B testing session to compare indexed vs. baseline token usage.
|
|
339
|
+
|
|
340
|
+
| Parameter | Type | Required | Description |
|
|
341
|
+
|---|---|---|---|
|
|
342
|
+
| `label` | string | ✓ | Human-readable session name |
|
|
343
|
+
| `mode` | `"indexed"` \| `"baseline"` | ✓ | Tracking mode |
|
|
344
|
+
|
|
345
|
+
**Returns:** `session_id` and the monitoring dashboard URL.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
### Document & context tools
|
|
350
|
+
|
|
351
|
+
These three tools extend PindeX beyond code: documentation files are indexed automatically alongside source files, and Claude can persist notes to a persistent knowledge store.
|
|
352
|
+
|
|
353
|
+
**What gets indexed as documents:**
|
|
354
|
+
|
|
355
|
+
| File type | Chunking strategy |
|
|
356
|
+
|---|---|
|
|
357
|
+
| `.md` / `.markdown` | Split at `#` / `##` / `###` heading boundaries — each section is one chunk |
|
|
358
|
+
| `.yaml` / `.yml` | Fixed 50-line chunks |
|
|
359
|
+
| `.txt` | Fixed 50-line chunks |
|
|
360
|
+
|
|
361
|
+
Documents are discovered by `indexAll()` and kept in sync by the same MD5-hash incremental indexer used for code files.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### `search_docs`
|
|
366
|
+
|
|
367
|
+
Full-text search (FTS5) across indexed document chunks **and** saved context entries.
|
|
368
|
+
Use this instead of loading entire documentation files.
|
|
369
|
+
|
|
370
|
+
| Parameter | Type | Required | Description |
|
|
371
|
+
|---|---|---|---|
|
|
372
|
+
| `query` | string | ✓ | Search term |
|
|
373
|
+
| `limit` | number | | Max results (default: 20) |
|
|
374
|
+
| `type` | `"docs"` \| `"context"` \| `"all"` | | Filter by source (default: `"all"`) |
|
|
375
|
+
|
|
376
|
+
**Returns:** List of matches, each with:
|
|
377
|
+
- `type` — `"doc"` (from a file) or `"context"` (saved by Claude)
|
|
378
|
+
- `content_preview` — first 200 characters of the chunk
|
|
379
|
+
- `file`, `heading`, `start_line` — for `"doc"` results, enables precise navigation
|
|
380
|
+
- `tags`, `session_id`, `created_at` — for `"context"` results
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
### `get_doc_chunk`
|
|
385
|
+
|
|
386
|
+
Retrieve the full content of one or all chunks of an indexed document.
|
|
387
|
+
More token-efficient than `get_context` for large documentation files because it returns pre-segmented sections.
|
|
388
|
+
|
|
389
|
+
| Parameter | Type | Required | Description |
|
|
390
|
+
|---|---|---|---|
|
|
391
|
+
| `file` | string | ✓ | File path (project-relative) |
|
|
392
|
+
| `chunk_index` | number | | Specific chunk to retrieve — omit for all chunks |
|
|
393
|
+
|
|
394
|
+
**Returns:** `{ file, total_chunks, chunks: [{ index, heading, start_line, end_line, content }] }`
|
|
395
|
+
|
|
396
|
+
**Typical workflow:**
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
search_docs("authentication JWT")
|
|
400
|
+
→ { file: "CLAUDE.md", heading: "Authentication", start_line: 12, chunk_index: 2 }
|
|
401
|
+
|
|
402
|
+
get_doc_chunk("CLAUDE.md", 2)
|
|
403
|
+
→ full text of the Authentication section only
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
### `save_context`
|
|
409
|
+
|
|
410
|
+
Persist an important fact, decision, or snippet to the context store.
|
|
411
|
+
Entries are searchable across all future sessions via `search_docs`.
|
|
412
|
+
|
|
413
|
+
Use this to offload information from the context window — instead of keeping a long summary in the prompt, write it once and retrieve it on demand.
|
|
414
|
+
|
|
415
|
+
| Parameter | Type | Required | Description |
|
|
416
|
+
|---|---|---|---|
|
|
417
|
+
| `content` | string | ✓ | The text to store |
|
|
418
|
+
| `tags` | string | | Comma-separated keywords for better retrieval (e.g. `"auth,jwt,security"`) |
|
|
419
|
+
|
|
420
|
+
**Returns:** `{ id, session_id, created_at }`
|
|
421
|
+
|
|
422
|
+
**Example — saving a decision:**
|
|
423
|
+
|
|
424
|
+
```
|
|
425
|
+
save_context(
|
|
426
|
+
"JWT expiry: access=1h, refresh=7d. Refresh stored in Redis. See src/auth/tokens.ts.",
|
|
427
|
+
"auth,jwt,redis"
|
|
428
|
+
)
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Example — retrieving it in a later session:**
|
|
432
|
+
|
|
433
|
+
```
|
|
434
|
+
search_docs("JWT expiry", type: "context")
|
|
435
|
+
→ { content_preview: "JWT expiry: access=1h, refresh=7d …", tags: "auth,jwt,redis" }
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
## Environment Variables
|
|
441
|
+
|
|
442
|
+
These are set automatically in the generated `.mcp.json` — you rarely need to change them by hand.
|
|
443
|
+
|
|
444
|
+
| Variable | Default | Description |
|
|
445
|
+
|---|---|---|
|
|
446
|
+
| `PROJECT_ROOT` | `.` | Root directory of the project to index |
|
|
447
|
+
| `INDEX_PATH` | `~/.pindex/projects/{hash}/index.db` | Path to the SQLite database |
|
|
448
|
+
| `LANGUAGES` | `typescript,javascript` | Comma-separated list of languages to index |
|
|
449
|
+
| `AUTO_REINDEX` | `true` | Watch for file changes and reindex automatically |
|
|
450
|
+
| `MONITORING_PORT` | assigned per-project | Port for the live dashboard + WebSocket |
|
|
451
|
+
| `MONITORING_AUTO_OPEN` | `false` | Open the dashboard in the browser on startup |
|
|
452
|
+
| `BASELINE_MODE` | `false` | Disable the index entirely (for A/B baseline sessions) |
|
|
453
|
+
| `GENERATE_SUMMARIES` | `false` | Generate LLM summaries per symbol (stub — not yet wired) |
|
|
454
|
+
| `TOKEN_PRICE_PER_MILLION` | `3.00` | USD price per million tokens — used for cost estimates |
|
|
455
|
+
| `FEDERATION_REPOS` | _(empty)_ | Colon-separated absolute paths to linked repositories |
|
|
456
|
+
| `DOCUMENT_PATTERNS` | `**/*.md,**/*.markdown,**/*.yaml,**/*.yml,**/*.txt` | Glob patterns for document files to index alongside code |
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Integrations
|
|
461
|
+
|
|
462
|
+
### Claude Code
|
|
463
|
+
|
|
464
|
+
Run `pindex` in each project you want to index. The command writes `.mcp.json` automatically:
|
|
465
|
+
|
|
466
|
+
```bash
|
|
467
|
+
cd /my/project
|
|
468
|
+
pindex
|
|
469
|
+
# → .mcp.json written
|
|
470
|
+
# restart Claude Code → pindex-server starts automatically
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
The `.mcp.json` format (auto-generated, do not edit by hand):
|
|
474
|
+
|
|
475
|
+
```json
|
|
476
|
+
{
|
|
477
|
+
"mcpServers": {
|
|
478
|
+
"pindex": {
|
|
479
|
+
"command": "pindex-server",
|
|
480
|
+
"args": [],
|
|
481
|
+
"env": {
|
|
482
|
+
"PROJECT_ROOT": "/absolute/path/to/project",
|
|
483
|
+
"INDEX_PATH": "/home/user/.pindex/projects/a3f8b2c1/index.db",
|
|
484
|
+
"MONITORING_PORT": "7856",
|
|
485
|
+
"AUTO_REINDEX": "true",
|
|
486
|
+
"GENERATE_SUMMARIES": "false",
|
|
487
|
+
"MONITORING_AUTO_OPEN": "false",
|
|
488
|
+
"BASELINE_MODE": "false",
|
|
489
|
+
"TOKEN_PRICE_PER_MILLION": "3.00"
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
With federation (`pindex add /other/project`):
|
|
497
|
+
|
|
498
|
+
```json
|
|
499
|
+
{
|
|
500
|
+
"mcpServers": {
|
|
501
|
+
"pindex": {
|
|
502
|
+
"command": "pindex-server",
|
|
503
|
+
"args": [],
|
|
504
|
+
"env": {
|
|
505
|
+
"PROJECT_ROOT": "/absolute/path/to/project",
|
|
506
|
+
"FEDERATION_REPOS": "/absolute/path/to/other/project",
|
|
507
|
+
"..."
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
---
|
|
515
|
+
|
|
516
|
+
### Goose
|
|
517
|
+
|
|
518
|
+
[Goose](https://block.github.io/goose/) reads extensions from `~/.config/goose/config.yaml`.
|
|
519
|
+
|
|
520
|
+
**Step 1 — Install PindeX:**
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
git clone https://github.com/phash/PindeX.git
|
|
524
|
+
cd PindeX && npm install && npm run build && npm install -g .
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Step 2 — Run `pindex` in your project** to get the assigned hash and port:
|
|
528
|
+
|
|
529
|
+
```bash
|
|
530
|
+
cd /my/project && pindex
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
**Step 3 — Edit `~/.config/goose/config.yaml`:**
|
|
534
|
+
|
|
535
|
+
```yaml
|
|
536
|
+
extensions:
|
|
537
|
+
pindex:
|
|
538
|
+
name: PindeX
|
|
539
|
+
type: stdio
|
|
540
|
+
cmd: pindex-server
|
|
541
|
+
args: []
|
|
542
|
+
envs:
|
|
543
|
+
PROJECT_ROOT: /absolute/path/to/project
|
|
544
|
+
INDEX_PATH: /home/user/.pindex/projects/{hash}/index.db
|
|
545
|
+
LANGUAGES: typescript,javascript
|
|
546
|
+
AUTO_REINDEX: "true"
|
|
547
|
+
GENERATE_SUMMARIES: "false"
|
|
548
|
+
MONITORING_PORT: "{port}"
|
|
549
|
+
MONITORING_AUTO_OPEN: "false"
|
|
550
|
+
BASELINE_MODE: "false"
|
|
551
|
+
TOKEN_PRICE_PER_MILLION: "3.00"
|
|
552
|
+
enabled: true
|
|
553
|
+
timeout: 300
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
Replace `{hash}` and `{port}` with the values shown by `pindex`. A ready-to-copy template is available in [`goose-extension.yaml`](./goose-extension.yaml).
|
|
557
|
+
|
|
558
|
+
**Step 4 — Restart Goose:**
|
|
559
|
+
|
|
560
|
+
```bash
|
|
561
|
+
goose session start
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
566
|
+
## CLI Reference
|
|
567
|
+
|
|
568
|
+
```
|
|
569
|
+
pindex [command] [options]
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
| Command | Description |
|
|
573
|
+
|---|---|
|
|
574
|
+
| _(no args)_ / `init` | Set up this project: write `.mcp.json`, register globally |
|
|
575
|
+
| `add <path>` | Link another repo for cross-repo search (federation) |
|
|
576
|
+
| `remove [path]` | Remove a federated repo link, or deregister the current project |
|
|
577
|
+
| `setup` | One-time global setup (autostart config) |
|
|
578
|
+
| `status` | Show all registered projects and their status |
|
|
579
|
+
| `list` | List all registered projects (compact) |
|
|
580
|
+
| `index [path]` | Manually index a directory (default: current directory) |
|
|
581
|
+
| `index --force` | Force full reindex, bypassing MD5 hash checks |
|
|
582
|
+
| `gui` | Open the aggregated monitoring dashboard in the browser |
|
|
583
|
+
| `stats` | Print a short stats summary |
|
|
584
|
+
| `uninstall` | Stop all daemons (data stays in `~/.pindex`) |
|
|
585
|
+
|
|
586
|
+
**Examples:**
|
|
587
|
+
|
|
588
|
+
```bash
|
|
589
|
+
# Set up a new project
|
|
590
|
+
cd /my/project && pindex
|
|
591
|
+
|
|
592
|
+
# Link project-b for cross-repo search
|
|
593
|
+
pindex add /my/project-b
|
|
594
|
+
|
|
595
|
+
# Check all registered projects
|
|
596
|
+
pindex status
|
|
597
|
+
|
|
598
|
+
# Manually force a full reindex
|
|
599
|
+
pindex index --force
|
|
600
|
+
|
|
601
|
+
# Open the dashboard
|
|
602
|
+
pindex-gui
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## Monitoring Dashboard
|
|
608
|
+
|
|
609
|
+
### Per-project dashboard
|
|
610
|
+
|
|
611
|
+
Each `pindex-server` instance starts a monitoring server on its assigned port. Open it at:
|
|
612
|
+
|
|
613
|
+
```
|
|
614
|
+
http://localhost:{MONITORING_PORT}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Or let it open automatically on startup:
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
MONITORING_AUTO_OPEN=true node dist/index.js
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### Aggregated dashboard (all projects)
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
pindex-gui
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Opens `http://localhost:7842` — reads **all** registered project databases directly and shows:
|
|
630
|
+
|
|
631
|
+
- Token savings per project (bar chart)
|
|
632
|
+
- Indexed file and symbol counts
|
|
633
|
+
- Session history
|
|
634
|
+
- Average savings % across all projects
|
|
635
|
+
|
|
636
|
+
The GUI refreshes automatically every 15 seconds and works even when no `pindex-server` is running.
|
|
637
|
+
|
|
638
|
+
**Dashboard features (both dashboards):**
|
|
639
|
+
- Real-time chart (Chart.js) of tokens used vs. estimated cost without index
|
|
640
|
+
- Per-tool breakdown: which tools are used most and how much they save
|
|
641
|
+
- Session comparison: side-by-side indexed vs. baseline A/B data
|
|
642
|
+
- REST API at `/api/sessions` and `/api/sessions/:id` for programmatic access
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## Development
|
|
647
|
+
|
|
648
|
+
### Setup
|
|
649
|
+
|
|
650
|
+
```bash
|
|
651
|
+
git clone https://github.com/phash/PindeX.git
|
|
652
|
+
cd PindeX
|
|
653
|
+
npm install
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### Build
|
|
657
|
+
|
|
658
|
+
```bash
|
|
659
|
+
npm run build # compile src/ → dist/
|
|
660
|
+
npm run build:watch # watch mode
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
### Tests
|
|
664
|
+
|
|
665
|
+
```bash
|
|
666
|
+
npm test # run full test suite (vitest, pool: forks)
|
|
667
|
+
npm run test:watch # watch mode
|
|
668
|
+
npm run test:coverage # coverage report — threshold: 80%
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
> Tests use `pool: 'forks'` — required because `better-sqlite3` uses native bindings that cannot share a process with the vitest worker pool.
|
|
672
|
+
|
|
673
|
+
### Lint / Type-check
|
|
674
|
+
|
|
675
|
+
```bash
|
|
676
|
+
npm run lint # tsc --noEmit (type errors only, no output files)
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Test structure
|
|
680
|
+
|
|
681
|
+
```
|
|
682
|
+
tests/
|
|
683
|
+
├── setup.ts # global mocks (tree-sitter, chokidar, open)
|
|
684
|
+
├── helpers/ # createTestDb(), fixtures, test server
|
|
685
|
+
├── db/ # schema, migrations, queries
|
|
686
|
+
├── indexer/ # parser, indexer, watcher
|
|
687
|
+
├── tools/ # one file per MCP tool (13 total)
|
|
688
|
+
├── monitoring/ # estimator, token-logger, Express server
|
|
689
|
+
├── cli/ # project-detector, setup, daemon
|
|
690
|
+
└── integration/
|
|
691
|
+
├── mcp-server.test.ts # MCP server wiring smoke tests
|
|
692
|
+
└── doc-indexing.test.ts # full document + context memory workflow
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
---
|
|
696
|
+
|
|
697
|
+
## Project Structure
|
|
698
|
+
|
|
699
|
+
```
|
|
700
|
+
src/
|
|
701
|
+
├── index.ts # Entry point — MCP stdio server + FEDERATION_REPOS
|
|
702
|
+
├── server.ts # Tool registration (13 tools, FederatedDb interface)
|
|
703
|
+
├── types.ts # Shared TypeScript interfaces
|
|
704
|
+
│
|
|
705
|
+
├── db/
|
|
706
|
+
│ ├── schema.ts # SQLite schema + FTS5 tables + triggers (v2)
|
|
707
|
+
│ ├── queries.ts # Typed query helpers
|
|
708
|
+
│ ├── database.ts # Connection management
|
|
709
|
+
│ └── migrations.ts # Schema versioning (PRAGMA user_version)
|
|
710
|
+
│
|
|
711
|
+
├── indexer/
|
|
712
|
+
│ ├── index.ts # Orchestrator — code + document file discovery
|
|
713
|
+
│ ├── parser.ts # tree-sitter AST → symbols; text → doc chunks
|
|
714
|
+
│ ├── summarizer.ts # LLM summary stub (not yet active)
|
|
715
|
+
│ └── watcher.ts # chokidar file watcher → auto-reindex
|
|
716
|
+
│
|
|
717
|
+
├── tools/ # One file per MCP tool
|
|
718
|
+
│ ├── search_symbols.ts # FTS5 symbol search — supports federated DBs
|
|
719
|
+
│ ├── get_symbol.ts
|
|
720
|
+
│ ├── get_context.ts
|
|
721
|
+
│ ├── get_file_summary.ts
|
|
722
|
+
│ ├── find_usages.ts
|
|
723
|
+
│ ├── get_dependencies.ts
|
|
724
|
+
│ ├── get_project_overview.ts # federation-aware stats
|
|
725
|
+
│ ├── reindex.ts
|
|
726
|
+
│ ├── get_token_stats.ts
|
|
727
|
+
│ ├── start_comparison.ts
|
|
728
|
+
│ ├── search_docs.ts # FTS5 across documents + context entries
|
|
729
|
+
│ ├── get_doc_chunk.ts # retrieve specific document section(s)
|
|
730
|
+
│ └── save_context.ts # persist a fact/decision to context store
|
|
731
|
+
│
|
|
732
|
+
├── monitoring/
|
|
733
|
+
│ ├── server.ts # Express + WebSocket (per-project instance)
|
|
734
|
+
│ ├── token-logger.ts # Per-call token logging
|
|
735
|
+
│ ├── estimator.ts # "without index" heuristic
|
|
736
|
+
│ └── ui/ # Dashboard HTML / CSS / Chart.js
|
|
737
|
+
│
|
|
738
|
+
├── gui/
|
|
739
|
+
│ ├── index.ts # pindex-gui entry point
|
|
740
|
+
│ └── server.ts # Aggregated Express app (reads all project DBs)
|
|
741
|
+
│
|
|
742
|
+
└── cli/
|
|
743
|
+
├── index.ts # CLI router
|
|
744
|
+
├── init.ts # initProject(), writeMcpJson(), addFederatedRepo()
|
|
745
|
+
├── setup.ts # One-time setup (pindex setup)
|
|
746
|
+
├── daemon.ts # Per-project PID-file daemon management
|
|
747
|
+
└── project-detector.ts # getPindexHome(), findProjectRoot(), GlobalRegistry
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Key implementation notes
|
|
751
|
+
|
|
752
|
+
- **ES Modules** — all relative imports use `.js` extensions (TypeScript ESM / NodeNext resolution).
|
|
753
|
+
- **FTS5 sync** — `symbols`, `documents`, and `context_entries` are all kept in sync by SQLite `AFTER INSERT/UPDATE/DELETE` triggers; no application-level bookkeeping needed.
|
|
754
|
+
- **Incremental reindexing** — MD5 hash per file; unchanged files are skipped for both code and document indexing.
|
|
755
|
+
- **Document chunking** — markdown splits at `#`/`##`/`###` heading boundaries; all other text files use fixed 50-line windows. Empty chunks are filtered out before storage.
|
|
756
|
+
- **Context memory** — `save_context` writes to `context_entries` keyed by `session_id`. Entries are never scoped to a single session — `search_docs` always searches the full history, enabling cross-session knowledge retrieval.
|
|
757
|
+
- **Live context** — `get_context` reads from disk at call time so it always returns the current file state, not a stale cache.
|
|
758
|
+
- **Testability** — `createMonitoringApp()` (returns the Express `app`) and `startMonitoringServer()` (binds the HTTP/WebSocket server) are separate functions so tests can mount the app without binding a port.
|
|
759
|
+
- **Per-project ports** — assigned deterministically as `7842 + (parseInt(hash.slice(0,4), 16) % 2000)` and stored in `registry.json` so they never change.
|
|
760
|
+
- **`pindex-gui` reads DBs directly** — no running server required; works as a standalone dashboard even when Claude Code is not open.
|
|
761
|
+
- **Migration** — `getPindexHome()` automatically renames `~/.mcp-indexer` → `~/.pindex` on first call if the old directory exists.
|
|
762
|
+
|
|
763
|
+
---
|
|
764
|
+
|
|
765
|
+
## License
|
|
766
|
+
|
|
767
|
+
MIT
|