purecontext-mcp 1.2.0 → 1.5.1
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/AGENT_INSTRUCTIONS.md +110 -784
- package/AGENT_REFERENCE.md +561 -0
- package/BENCHMARKS.md +153 -0
- package/CHANGELOG.md +177 -6
- package/FRAMEWORK-ADAPTERS.md +351 -0
- package/FULL-INSTALLATION-GUIDE.md +341 -0
- package/LANGUAGE-SUPPORT.md +144 -0
- package/README.md +154 -16
- package/USER-GUIDE.md +29 -21
- package/dist/cli/hooks.d.ts +28 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +570 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/install-detect.d.ts +16 -0
- package/dist/cli/install-detect.d.ts.map +1 -0
- package/dist/cli/install-detect.js +70 -0
- package/dist/cli/install-detect.js.map +1 -0
- package/dist/cli/install-writers.d.ts +59 -0
- package/dist/cli/install-writers.d.ts.map +1 -0
- package/dist/cli/install-writers.js +292 -0
- package/dist/cli/install-writers.js.map +1 -0
- package/dist/cli/install.d.ts +14 -0
- package/dist/cli/install.d.ts.map +1 -0
- package/dist/cli/install.js +150 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/config/config-loader.js +3 -0
- package/dist/config/config-loader.js.map +1 -1
- package/dist/config/config-schema.d.ts +11 -0
- package/dist/config/config-schema.d.ts.map +1 -1
- package/dist/config/config-schema.js +15 -0
- package/dist/config/config-schema.js.map +1 -1
- package/dist/core/db/symbol-store.d.ts +1 -0
- package/dist/core/db/symbol-store.d.ts.map +1 -1
- package/dist/core/db/symbol-store.js +120 -6
- package/dist/core/db/symbol-store.js.map +1 -1
- package/dist/core/file-discovery.d.ts +6 -0
- package/dist/core/file-discovery.d.ts.map +1 -1
- package/dist/core/file-discovery.js +20 -13
- package/dist/core/file-discovery.js.map +1 -1
- package/dist/core/file-processor.d.ts.map +1 -1
- package/dist/core/file-processor.js +26 -1
- package/dist/core/file-processor.js.map +1 -1
- package/dist/core/git-log-reader.d.ts.map +1 -1
- package/dist/core/git-log-reader.js +21 -0
- package/dist/core/git-log-reader.js.map +1 -1
- package/dist/core/index-manager.d.ts.map +1 -1
- package/dist/core/index-manager.js +21 -7
- package/dist/core/index-manager.js.map +1 -1
- package/dist/core/indexing-worker.d.ts.map +1 -1
- package/dist/core/indexing-worker.js +14 -0
- package/dist/core/indexing-worker.js.map +1 -1
- package/dist/core/parse-dispatcher.d.ts.map +1 -1
- package/dist/core/parse-dispatcher.js +20 -5
- package/dist/core/parse-dispatcher.js.map +1 -1
- package/dist/core/search/query-preprocessor.d.ts +69 -3
- package/dist/core/search/query-preprocessor.d.ts.map +1 -1
- package/dist/core/search/query-preprocessor.js +450 -17
- package/dist/core/search/query-preprocessor.js.map +1 -1
- package/dist/core/search/relevance-ranker.d.ts +60 -5
- package/dist/core/search/relevance-ranker.d.ts.map +1 -1
- package/dist/core/search/relevance-ranker.js +931 -33
- package/dist/core/search/relevance-ranker.js.map +1 -1
- package/dist/core/test-mapper.d.ts.map +1 -1
- package/dist/core/test-mapper.js +7 -1
- package/dist/core/test-mapper.js.map +1 -1
- package/dist/core/types.d.ts +28 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/handlers/angular-html.d.ts +3 -0
- package/dist/handlers/angular-html.d.ts.map +1 -0
- package/dist/handlers/angular-html.js +215 -0
- package/dist/handlers/angular-html.js.map +1 -0
- package/dist/handlers/c.d.ts.map +1 -1
- package/dist/handlers/c.js +19 -0
- package/dist/handlers/c.js.map +1 -1
- package/dist/handlers/cpp-macro-registry.d.ts +21 -0
- package/dist/handlers/cpp-macro-registry.d.ts.map +1 -0
- package/dist/handlers/cpp-macro-registry.js +44 -0
- package/dist/handlers/cpp-macro-registry.js.map +1 -0
- package/dist/handlers/cpp.d.ts.map +1 -1
- package/dist/handlers/cpp.js +579 -10
- package/dist/handlers/cpp.js.map +1 -1
- package/dist/handlers/csharp.d.ts.map +1 -1
- package/dist/handlers/csharp.js +39 -2
- package/dist/handlers/csharp.js.map +1 -1
- package/dist/handlers/css.d.ts +3 -0
- package/dist/handlers/css.d.ts.map +1 -0
- package/dist/handlers/css.js +154 -0
- package/dist/handlers/css.js.map +1 -0
- package/dist/handlers/erlang.d.ts.map +1 -1
- package/dist/handlers/erlang.js +8 -1
- package/dist/handlers/erlang.js.map +1 -1
- package/dist/handlers/fortran.js +1 -1
- package/dist/handlers/fortran.js.map +1 -1
- package/dist/handlers/go.d.ts.map +1 -1
- package/dist/handlers/go.js +87 -2
- package/dist/handlers/go.js.map +1 -1
- package/dist/handlers/handler-registry.d.ts.map +1 -1
- package/dist/handlers/handler-registry.js +4 -0
- package/dist/handlers/handler-registry.js.map +1 -1
- package/dist/handlers/hcl.d.ts +3 -0
- package/dist/handlers/hcl.d.ts.map +1 -0
- package/dist/handlers/hcl.js +193 -0
- package/dist/handlers/hcl.js.map +1 -0
- package/dist/handlers/java.d.ts.map +1 -1
- package/dist/handlers/java.js +33 -16
- package/dist/handlers/java.js.map +1 -1
- package/dist/handlers/kotlin.d.ts.map +1 -1
- package/dist/handlers/kotlin.js +48 -3
- package/dist/handlers/kotlin.js.map +1 -1
- package/dist/handlers/less.d.ts +3 -0
- package/dist/handlers/less.d.ts.map +1 -0
- package/dist/handlers/less.js +255 -0
- package/dist/handlers/less.js.map +1 -0
- package/dist/handlers/objective-c.d.ts.map +1 -1
- package/dist/handlers/objective-c.js +122 -64
- package/dist/handlers/objective-c.js.map +1 -1
- package/dist/handlers/openapi.d.ts.map +1 -1
- package/dist/handlers/openapi.js +30 -5
- package/dist/handlers/openapi.js.map +1 -1
- package/dist/handlers/php.d.ts.map +1 -1
- package/dist/handlers/php.js +287 -41
- package/dist/handlers/php.js.map +1 -1
- package/dist/handlers/protobuf.d.ts.map +1 -1
- package/dist/handlers/protobuf.js +1 -0
- package/dist/handlers/protobuf.js.map +1 -1
- package/dist/handlers/python.d.ts.map +1 -1
- package/dist/handlers/python.js +1 -3
- package/dist/handlers/python.js.map +1 -1
- package/dist/handlers/ruby-dsl.d.ts +23 -0
- package/dist/handlers/ruby-dsl.d.ts.map +1 -0
- package/dist/handlers/ruby-dsl.js +251 -0
- package/dist/handlers/ruby-dsl.js.map +1 -0
- package/dist/handlers/ruby.d.ts.map +1 -1
- package/dist/handlers/ruby.js +29 -4
- package/dist/handlers/ruby.js.map +1 -1
- package/dist/handlers/rust.d.ts.map +1 -1
- package/dist/handlers/rust.js +98 -2
- package/dist/handlers/rust.js.map +1 -1
- package/dist/handlers/scss.d.ts +3 -0
- package/dist/handlers/scss.d.ts.map +1 -0
- package/dist/handlers/scss.js +290 -0
- package/dist/handlers/scss.js.map +1 -0
- package/dist/handlers/sql.d.ts.map +1 -1
- package/dist/handlers/sql.js +37 -18
- package/dist/handlers/sql.js.map +1 -1
- package/dist/handlers/typescript.d.ts.map +1 -1
- package/dist/handlers/typescript.js +65 -17
- package/dist/handlers/typescript.js.map +1 -1
- package/dist/handlers/xml.d.ts.map +1 -1
- package/dist/handlers/xml.js +35 -2
- package/dist/handlers/xml.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -0
- package/dist/index.js.map +1 -1
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +10 -0
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/tools/detect-antipatterns.d.ts +1 -1
- package/dist/server/tools/get-architecture-snapshot.d.ts +1 -1
- package/dist/server/tools/get-entry-points.d.ts +1 -1
- package/dist/server/tools/get-lexical-scope-matches.d.ts +54 -0
- package/dist/server/tools/get-lexical-scope-matches.d.ts.map +1 -0
- package/dist/server/tools/get-lexical-scope-matches.js +470 -0
- package/dist/server/tools/get-lexical-scope-matches.js.map +1 -0
- package/dist/server/tools/search-symbols.d.ts +10 -0
- package/dist/server/tools/search-symbols.d.ts.map +1 -1
- package/dist/server/tools/search-symbols.js +353 -8
- package/dist/server/tools/search-symbols.js.map +1 -1
- package/dist/server/tools/trace-invocation-chain.d.ts +53 -0
- package/dist/server/tools/trace-invocation-chain.d.ts.map +1 -0
- package/dist/server/tools/trace-invocation-chain.js +280 -0
- package/dist/server/tools/trace-invocation-chain.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/02-installation.md +43 -245
- package/docs/05-cli-reference.md +89 -0
- package/docs/07-language-support.md +73 -50
- package/docs/08-framework-adapters.md +7 -2
- package/docs/15-team-setup.md +70 -200
- package/docs/17-web-ui.md +73 -93
- package/docs/README.md +60 -39
- package/docs/dev/benchmark-findings-eu-za-tebe.md +210 -0
- package/docs/dev/phase-35-coverage-audit.md +469 -0
- package/package.json +6 -3
- package/user-manual.md +0 -2466
package/BENCHMARKS.md
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
PureContext is benchmarked on **87 real-world open-source projects** spanning 29 language groups. This page reports measured search precision so you can decide whether PureContext fits your stack before installing.
|
|
4
|
+
|
|
5
|
+
The benchmarks are reproducible — every project, query set, and result file lives in the `benchmarks/` directory of the source repository.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Methodology
|
|
10
|
+
|
|
11
|
+
For each project:
|
|
12
|
+
|
|
13
|
+
1. **Index it** with PureContext.
|
|
14
|
+
2. **Run 25 ground-truth queries** drawn from real symbol names and natural-language descriptions of what each symbol does. Ground-truth answers are the curated "correct" symbols a developer would expect.
|
|
15
|
+
3. **Score three metrics:**
|
|
16
|
+
- **P@1** (Precision at rank 1): the correct symbol is the top result.
|
|
17
|
+
- **P@3** (Precision at rank 3): the correct symbol is in the top 3.
|
|
18
|
+
- **R@5** (Recall at top 5): the correct symbol appears anywhere in the top 5.
|
|
19
|
+
|
|
20
|
+
P@1 is the most demanding metric — it measures how often the *first* answer is the right one without the agent having to scroll through alternatives. P@3 and R@5 reflect what an agent actually consumes in a real session.
|
|
21
|
+
|
|
22
|
+
Ground-truth query sets are intentionally curated by hand (`benchmarks/<project>/queries.json`), not auto-generated, and can be inspected or extended.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Per-language averages
|
|
27
|
+
|
|
28
|
+
Group averages over all benchmarked projects in each language.
|
|
29
|
+
|
|
30
|
+
| Language group | Projects | P@1 | P@3 | R@5 |
|
|
31
|
+
|----------------|---------:|----:|----:|----:|
|
|
32
|
+
| GraphQL | 3 | **65%** | 81% | 87% |
|
|
33
|
+
| Nix | 2 | **60%** | 74% | 76% |
|
|
34
|
+
| GDScript | 2 | **58%** | 78% | 88% |
|
|
35
|
+
| Terraform / HCL | 2 | **53%** | 64% | 67% |
|
|
36
|
+
| Protobuf | 3 | **51%** | 51% | 60% |
|
|
37
|
+
| TypeScript / JavaScript | 4 | **44%** | 57% | 61% |
|
|
38
|
+
| Lua | 2 | **36%** | 56% | 64% |
|
|
39
|
+
| PHP | 2 | **36%** | 54% | 58% |
|
|
40
|
+
| Python | 2 | **34%** | 46% | 56% |
|
|
41
|
+
| Rust | 2 | **34%** | 50% | 60% |
|
|
42
|
+
| OpenAPI / YAML | 3 | **31%** | 32% | 36% |
|
|
43
|
+
| Kotlin | 2 | **30%** | 36% | 40% |
|
|
44
|
+
| Go | 1 | **28%** | 56% | 76% |
|
|
45
|
+
| Java | 1 | **24%** | 32% | 44% |
|
|
46
|
+
| SQL | 3 | **23%** | 44% | 52% |
|
|
47
|
+
| C / C++ | 6 | **13%** | 22% | 30% |
|
|
48
|
+
| Scala | 2 | 12% | 20% | 32% |
|
|
49
|
+
| Swift | 3 | 11% | 19% | 23% |
|
|
50
|
+
| Ruby | 4 | 10% | 16% | 20% |
|
|
51
|
+
| C# / .NET | 2 | 10% | 16% | 18% |
|
|
52
|
+
| Dart / Flutter | 2 | 8% | 14% | 18% |
|
|
53
|
+
| Objective-C | 3 | 5% | 11% | 16% |
|
|
54
|
+
| Haskell | 2 | 0% | 16% | 22% |
|
|
55
|
+
|
|
56
|
+
Numbers are averages across the projects in each row. Bold P@1 values mark groups where PureContext consistently produces the right answer at rank 1 on a non-trivial fraction of queries.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Per-project highlights
|
|
61
|
+
|
|
62
|
+
Selected projects from the full set of 87 — full results in `benchmarks/<project>/results/purecontext.json`.
|
|
63
|
+
|
|
64
|
+
| Project | Language / framework | P@1 | P@3 | R@5 | Symbols indexed |
|
|
65
|
+
|---------|----------------------|----:|----:|----:|----------------:|
|
|
66
|
+
| nestjs-ecommerce-api | TypeScript / NestJS | 84% | 100% | 100% | 3,314 |
|
|
67
|
+
| terraform-aws-eks | Terraform / HCL | 84% | 92% | 96% | 1,589 |
|
|
68
|
+
| dialogic | GDScript | 84% | 100% | 100% | 3,025 |
|
|
69
|
+
| grpc-proto | Protobuf | 72% | 80% | 92% | 260 |
|
|
70
|
+
| saleor | GraphQL / Python | 72% | 88% | 96% | 27,719 |
|
|
71
|
+
| graphql-code-generator | TypeScript / GraphQL | 72% | 84% | 84% | 3,602 |
|
|
72
|
+
| terraform-aws-components | Terraform / HCL | 68% | 80% | 84% | 14,914 |
|
|
73
|
+
| kubernetes-openapi | OpenAPI / YAML | 64% | 68% | 80% | 4,739 |
|
|
74
|
+
| eu-za-tebe | PHP / CodeIgniter | 60% | 72% | 72% | 5,575 |
|
|
75
|
+
| envoy | Protobuf / C++ | 60% | 60% | 68% | 44,739 |
|
|
76
|
+
| home-manager | Nix | 60% | 72% | 76% | 9,023 |
|
|
77
|
+
| flake-utils | Nix | 60% | 76% | 76% | 50 |
|
|
78
|
+
| kurirfe | JavaScript / Nuxt | 56% | 60% | 64% | 382 |
|
|
79
|
+
| love | C++ / Lua | 52% | 80% | 88% | 26,165 |
|
|
80
|
+
| graphql-engine | GraphQL / Rust / Haskell | 52% | 72% | 80% | 40,417 |
|
|
81
|
+
| maven | XML / Java | 48% | 52% | 56% | 15,284 |
|
|
82
|
+
| jaffle-shop | SQL / dbt | 44% | 80% | 84% | 54 |
|
|
83
|
+
| ecrad | Fortran | 44% | 60% | 64% | 684 |
|
|
84
|
+
| ktor | Kotlin | 44% | 48% | 52% | 11,974 |
|
|
85
|
+
| tokio | Rust | 40% | 60% | 72% | 2,799 |
|
|
86
|
+
| phoenix | Elixir / Phoenix | 36% | 64% | 76% | 1,317 |
|
|
87
|
+
| neovim | Lua / C | 36% | 68% | 80% | 9,514 |
|
|
88
|
+
| kong | Lua / Kong | 36% | 52% | 56% | 4,210 |
|
|
89
|
+
| sqitch | Perl | 36% | 60% | 72% | 1,143 |
|
|
90
|
+
| rabbitmq-server | Erlang | 36% | 48% | 52% | 32,585 |
|
|
91
|
+
| angular-realworld | Angular / TypeScript | 36% | 68% | 72% | 127 |
|
|
92
|
+
| jhipster-sample-app | Angular / TypeScript | 32% | 36% | 48% | 1,302 |
|
|
93
|
+
| godot-demo-projects | GDScript | 32% | 56% | 76% | 3,274 |
|
|
94
|
+
| stripe-openapi | OpenAPI / YAML | 28% | 28% | 28% | 43,078 |
|
|
95
|
+
| listmonk | Go | 28% | 56% | 76% | 966 |
|
|
96
|
+
| serde | Rust | 28% | 40% | 48% | 293 |
|
|
97
|
+
| emqx | Erlang | 28% | 32% | 36% | 43,147 |
|
|
98
|
+
| infisical | React / TypeScript | 8% | 28% | 36% | 27,295 |
|
|
99
|
+
|
|
100
|
+
The TypeScript/NestJS result (84% P@1, 100% P@3) is the strongest single-project number — NestJS routes and providers map cleanly to the decorator-based extraction in PureContext's framework adapter.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Where PureContext wins clearly
|
|
105
|
+
|
|
106
|
+
**Framework-aware extraction.** Adapters for NestJS, Terraform, Protobuf, GraphQL, and dbt-style SQL pull domain symbols (routes, resources, services, schemas, models) out as first-class entries rather than relying on generic function/class extraction. This is where the highest P@1 numbers come from.
|
|
107
|
+
|
|
108
|
+
**Cross-language identifier aliases.** Neovim's C API (`nvim_open_win`) is called from Lua as `vim.api.nvim_open_win`. PureContext stores the Lua alias as an FTS token so semantic queries find the C implementation (36% P@1 on neovim).
|
|
109
|
+
|
|
110
|
+
**Handler depth where it matters.** Ruby DSL macros (`has_many`, `belongs_to`, `before_action`), Rust impl methods stored as bare names with identity-exact ranking, Erlang functions stored without arity suffix, and ObjC selectors built as `setObject:forKey:` — each lift dynamic-language search precision substantially.
|
|
111
|
+
|
|
112
|
+
**IaC and schema languages.** Terraform/HCL extraction (resources, modules, variables, outputs) and OpenAPI handler with hyphen-aware regex give PureContext competitive numbers on infrastructure repos that traditional code-search tools miss.
|
|
113
|
+
|
|
114
|
+
## Where PureContext currently scores low
|
|
115
|
+
|
|
116
|
+
These are honest gaps, tracked as P1 work:
|
|
117
|
+
|
|
118
|
+
- **Swift (11% P@1).** Generic type parameters are stripped and protocol types lack semantic summaries. Concept-based queries like *"protocol that describes how application state evolves"* fail to match `Reducer<State, Action>`.
|
|
119
|
+
- **Scala (12% P@1).** Heavily generic types (`ZIO[R, E, A]`, `ZLayer[RIn, E, ROut]`) have no FTS overlap with their semantic descriptions; `given`/`using` instances are not extracted.
|
|
120
|
+
- **Haskell (0% P@1, 16% P@3).** Record types and functions have no docstrings by default; FTS content is name-tokens only. Symbols enter the top-5 (R@5 = 22%) but never rank first.
|
|
121
|
+
- **Objective-C (5% P@1).** The handler was strengthened in 1.5.0 (full `@interface`/`@protocol` extraction and selector building) — numbers will rise on the next benchmark cycle.
|
|
122
|
+
- **Large monorepos with abstract type queries (flutter SDK, novu).** Queries like *"abstract widget that owns mutable state"* don't tokenize against `StatefulWidget` without semantic embeddings on top. Improving this requires summary enrichment, not ranker tweaks.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Token efficiency
|
|
127
|
+
|
|
128
|
+
PureContext achieves near-100% token reduction versus the naive "read every source file" baseline on every benchmarked project. Token savings are not the main differentiator — what matters is **whether the returned symbols are correct**, which is what the P@1 / P@3 / R@5 numbers above measure.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Reproducing the benchmark
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
git clone https://github.com/goranocokoljic/pure-context
|
|
136
|
+
cd pure-context
|
|
137
|
+
npm install
|
|
138
|
+
npm run build
|
|
139
|
+
npm run benchmark -- --project nestjs-ecommerce-api
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Results are written to `benchmarks/<project>/results/purecontext.json`. Ground-truth query sets live in `benchmarks/<project>/queries.json` and can be inspected, extended, or replaced.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Limitations of these numbers
|
|
147
|
+
|
|
148
|
+
- **25 queries per project is a small sample.** Group averages over multiple projects are more reliable than any single project's score.
|
|
149
|
+
- **Ground-truth queries are biased toward what humans ask AI agents** — symbol lookups by name and short natural-language descriptions. They do not measure agent-driven graph traversal (`get_blast_radius`, `get_call_hierarchy`, etc.), which is where most of the real value in an MCP server shows up in production agent loops.
|
|
150
|
+
- **Numbers reflect PureContext 1.5.0 (May 2026).** Each release shifts results — re-run the benchmark before making decisions on stale data.
|
|
151
|
+
- **Project mix is convenience-sampled.** Projects were selected to cover language and framework breadth, not weighted by GitHub popularity or download counts. Some categories (Web/TypeScript, IaC) are deliberately over-represented; mobile and embedded categories are under-represented.
|
|
152
|
+
|
|
153
|
+
The full per-project breakdown including symbol counts, indexing speeds, and language-group narratives is generated from the same benchmark runs and lives in the `dev-docs/benchmarks/` directory of the source repository (gitignored from npm releases).
|
package/CHANGELOG.md
CHANGED
|
@@ -7,18 +7,189 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
**Claude Code hook system overhaul**
|
|
15
|
+
|
|
16
|
+
Hooks now use CLI-style commands (`npx purecontext-mcp hook-*`) registered directly in `~/.claude/settings.json`. No scripts are copied to `~/.claude/hooks/` — the commands invoke the installed package directly, so hook logic updates automatically when the package updates.
|
|
17
|
+
|
|
18
|
+
Seven hook events are now supported (up from three):
|
|
19
|
+
|
|
20
|
+
| Hook event | Command | What it does |
|
|
21
|
+
|------------|---------|--------------|
|
|
22
|
+
| `PostToolUse` | `hook-posttooluse` | Re-indexes modified files after Edit/Write/MultiEdit |
|
|
23
|
+
| `PreCompact` | `hook-precompact` | Injects indexed repo list into context before compaction |
|
|
24
|
+
| `PreToolUse` | `hook-pretooluse` | Soft edit guard — suggests read tools before editing |
|
|
25
|
+
| `WorktreeCreate` | `hook-worktree-create` | Auto-indexes a newly created agent worktree |
|
|
26
|
+
| `WorktreeRemove` | `hook-worktree-remove` | Fires when an agent worktree is removed |
|
|
27
|
+
| `TaskCompleted` | `hook-taskcompleted` | Post-task diagnostics: complexity stats, TODO count, tool suggestions |
|
|
28
|
+
| `SubagentStart` | `hook-subagentstart` | Injects condensed repo orientation for newly spawned subagents |
|
|
29
|
+
|
|
30
|
+
*TaskCompleted* — after the agent finishes a task, queries each indexed repo for high-complexity symbols (cyclomatic complexity > 5) and TODO/FIXME annotations, then injects a diagnostic summary plus a reminder of relevant tools: `find_dead_code`, `find_untested_symbols`, `get_todos`, `get_complexity_hotspots`, `health_radar`.
|
|
31
|
+
|
|
32
|
+
*SubagentStart* — when a subagent spawns it has no session context. This hook injects the indexed repo list (repoId, path, file and symbol counts, last-indexed timestamp) plus the mandatory workflow table so the subagent is oriented without needing an extra tool call.
|
|
33
|
+
|
|
34
|
+
*WorktreeCreate* — Claude Code's Agent tool can create isolated git worktrees for sub-tasks. This hook calls `index-folder` on the new worktree automatically so PureContext tools work immediately inside it.
|
|
35
|
+
|
|
36
|
+
Re-running `npx purecontext-mcp hooks --install` upgrades existing installations: old `node ~/.claude/hooks/purecontext-*.mjs` entries are replaced with the new CLI form, and the four new hook events are added.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## [1.5.0] - 2026-05-22
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
**New language handlers**
|
|
45
|
+
|
|
46
|
+
- **HCL / Terraform** (`.tf`, `.tfvars`, `.hcl`) — extracts `variable`, `output`, `resource`, `data`, `module`, `provider`, and `locals` blocks; names follow Terraform reference syntax (`var.name`, `module.name`, `local.name`, `output.name`) so queries match the way you write them in code
|
|
47
|
+
- **Angular HTML templates** (`.html`) — extracts component selectors, structural directives (`*ngIf`, `*ngFor`, `@if`, `@for`), event bindings (`(click)="handler"`), template references (`#userInput`), and `routerLink` directives; auto-detected via a sibling `.component.ts` file or Angular marker patterns
|
|
48
|
+
- **Extensionless scripts** — extensionless files (e.g. `plugins/*/functions` in Bash-heavy projects) are now discovered and indexed automatically; shebang detection routes each file to the correct handler
|
|
49
|
+
|
|
50
|
+
**Objective-C handler overhaul**
|
|
51
|
+
|
|
52
|
+
- `@interface`, `@protocol`, and `@implementation` declarations now fully extracted from both `.m` and `.h` files
|
|
53
|
+
- Named categories stored as `ClassName+CategoryName`; anonymous categories flagged with `classExtension: true`
|
|
54
|
+
- Full Objective-C selector building (`setObject:forKey:`) instead of plain method names
|
|
55
|
+
- Properties extracted with `property` kind (was `const`)
|
|
56
|
+
- `.h` files guarded by an ObjC detection pass — C headers that happen to use `.h` are not misidentified
|
|
57
|
+
|
|
58
|
+
**XML symbol disambiguation**
|
|
59
|
+
|
|
60
|
+
- Root-element symbols in multi-module XML repositories (e.g. `pom.xml` across 30+ Maven modules) are now stored as `tag@module` names, eliminating collisions where every module shared the same top-level element name
|
|
61
|
+
- Bare tag name retained as an FTS token so single-word queries still find the right file
|
|
62
|
+
|
|
63
|
+
**Search relevance improvements**
|
|
64
|
+
|
|
65
|
+
- *Monorepo path heuristics* — frontend app directories (`apps/dashboard/`, `apps/web/`) get a score boost when the query contains hook or component vocabulary; avoids backend symbols drowning React/Angular results in mixed monorepos
|
|
66
|
+
- *Java/Groovy core-path boost* — symbols in `/core/src/main/java/` paths boosted; symbols in plugin directories penalised; reduces noise from plugin implementations when querying for core API methods
|
|
67
|
+
- *Library path penalties* extended to cover `engine/`, `erts/`, and `contrib/` directory segments (common in projects that embed a runtime)
|
|
68
|
+
- *Compound underscore boost* — fires when all underscore-separated parts of a symbol name are present in the query, without requiring an exact full-name match
|
|
69
|
+
- *Single-token exact match boost* — single-word queries reliably surface the best exact match at rank 1
|
|
70
|
+
- *Cross-language FTS aliases* — Neovim `nvim_*` C functions get a `vim.api.nvim_*` alias so Lua-style queries (`vim.api.nvim_open_win`) find the C implementation; Proto RPC method symbols include their service name as an FTS token
|
|
71
|
+
- *Erlang bare function names* — Erlang symbols stored without arity suffix (`start_link` instead of `start_link/3`); arity preserved in `frameworkMeta`; module name injected as an FTS token so `module:function` queries work
|
|
72
|
+
- *TypeScript HOC detection* — `export const X = React.memo(() => ...)`, `forwardRef(...)`, and similar HOC-wrapped arrow functions emitted as `kind=function` instead of `kind=const`, ensuring rendering-domain boosts fire correctly
|
|
73
|
+
|
|
74
|
+
### Fixed
|
|
75
|
+
|
|
76
|
+
- Case-insensitive file extension matching in file discovery (`.F90` Fortran files were silently skipped)
|
|
77
|
+
- Directory trailing-slash handling in `ignore` negation patterns — fixes traversal of directories with explicit `!negation` rules
|
|
78
|
+
- Index workers were missing registrations for the Fortran, SCSS, LESS, CSS, and Objective-C handlers; files with those extensions were silently dropped before parsing
|
|
79
|
+
- C++ qualified name FTS — bare local name (`Future`) now stored as a separate FTS token alongside the fully-qualified name (`folly::Future`), improving single-word C++ queries
|
|
80
|
+
- Rust synonym scoping — `future→poll`, `spawn→tokio/task`, and serde-specific synonyms now fire only in Rust repositories, preventing them from polluting C++ search results
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## [1.4.0] - 2026-05-20
|
|
85
|
+
|
|
86
|
+
### Added
|
|
87
|
+
|
|
88
|
+
**New MCP tools**
|
|
89
|
+
|
|
90
|
+
- `get_lexical_scope_matches` — returns all symbols accessible from a given file and line (local scope, module imports, and exported API), letting agents reason about what identifiers are in scope without reading whole files
|
|
91
|
+
- `trace_invocation_chain` — follows call edges from a symbol N hops deep and returns the linearised invocation path; useful for tracing a request from an entry point through to storage
|
|
92
|
+
|
|
93
|
+
**Language handler depth**
|
|
94
|
+
|
|
95
|
+
- *Ruby* — DSL macro extraction: `has_many`, `belongs_to`, `has_one`, `has_and_belongs_to_many`, `before_action`, `after_action`, `validates`, and `scope` class macros extracted as `property` symbols; metaprogramming patterns (`define_method`, `method_missing`) flagged in `frameworkMeta`
|
|
96
|
+
- *Rust* — `#[cfg(...)]` attributes now captured in `frameworkMeta.cfgAttributes`; new `cfgFilter` parameter on `search_symbols` restricts results to symbols matching a specific cfg condition (e.g. `target_os = "linux"`)
|
|
97
|
+
- *C++* — export-macro class extraction: `class MY_EXPORT ClassName` and similar patterns now correctly identified as class declarations rather than function definitions
|
|
98
|
+
- *TypeScript* — `export const X = forwardRef(...)` / `React.memo(...)` and similar HOC patterns emitted as `kind=function`; decorator extraction inside `export_statement` wrapper fixed (was silently dropping `@Injectable` and similar decorators on exported classes)
|
|
99
|
+
- *C#* — interface member extraction fixed (interface members are implicitly public; visibility guard removed); method name extraction uses `findLast` before `parameter_list` to avoid returning the return type; event field declarations (`event_field_declaration`) extracted as `property` kind
|
|
100
|
+
- *Kotlin* — extension function extraction; primary constructor property parameters extracted as `property` symbols
|
|
101
|
+
- *PHP* — PHP 8 `#[Attribute]` syntax parsed correctly; Symfony route and controller patterns added to quality-gate trigger; property declarations, `define()` constants, closures, abstract methods, enum cases, and interface constants all extracted
|
|
102
|
+
|
|
103
|
+
**Search quality**
|
|
104
|
+
|
|
105
|
+
- FTS BM25 raw rank exposed to the relevance ranker — high keyword-match scores contribute a 0–50 point bonus on top of structural scoring; prevents purely-structural boosts from overriding strong keyword matches
|
|
106
|
+
- Docstring extraction extended — Python and C++ full-paragraph docstrings (not just the first line) fed to the FTS index; improves matches for queries that use documentation vocabulary rather than identifier names
|
|
107
|
+
- Nuxt/Vue-specific vocabulary synonyms added (`composable`, `setup`, `defineComponent`, `useNuxt`, etc.)
|
|
108
|
+
- `search_symbols` returns `verdict: "no_match"` with `negative_evidence` details when all retrieval strategies are exhausted, allowing agents to stop retrying instead of looping through variant queries
|
|
109
|
+
|
|
110
|
+
**Multi-IDE installer**
|
|
111
|
+
|
|
112
|
+
`npx purecontext-mcp install <tool|all>` now supports:
|
|
113
|
+
|
|
114
|
+
| IDE / Tool | Config location |
|
|
115
|
+
|------------|----------------|
|
|
116
|
+
| Cursor | `.cursor/rules/purecontext.mdc` |
|
|
117
|
+
| Windsurf | `.windsurfrules` |
|
|
118
|
+
| Continue | `.continue/config.json` system message |
|
|
119
|
+
| Cline | `.clinerules` |
|
|
120
|
+
| Roo Code | `.roo/rules-code.md` |
|
|
121
|
+
| VS Code Copilot | `.github/copilot-instructions.md` |
|
|
122
|
+
| Claude Desktop | Platform config (`claude_desktop_config.json`) |
|
|
123
|
+
|
|
124
|
+
All writers are idempotent — running `install` a second time updates the existing block rather than appending a duplicate.
|
|
125
|
+
|
|
126
|
+
**Claude Code hooks**
|
|
127
|
+
|
|
128
|
+
- *PostToolUse index hook* — re-indexes modified files automatically after any Edit/Write tool call, keeping the symbol index in sync with in-session edits
|
|
129
|
+
- *PreCompact snapshot hook* — captures an architecture snapshot before context is compacted
|
|
130
|
+
- *Edit guard hook* (soft) — warns when an edit target has dependents with high blast radius; never blocks
|
|
131
|
+
|
|
132
|
+
Install via `npx purecontext-mcp hooks --install`.
|
|
133
|
+
|
|
134
|
+
### Fixed
|
|
135
|
+
|
|
136
|
+
- `expandVerbSynonyms`: prototype-chain collision on the `constructor` key — calling `expandVerbSynonyms("constructor")` previously returned the built-in `Function.prototype.constructor`; fixed by using `Object.create(null)` for the synonym map
|
|
137
|
+
- Test-mapper transaction: FK constraint errors no longer propagate and block FTS index population
|
|
138
|
+
- Windows path-case mismatch: repo ID computation now uses the canonical absolute path from the indexer output rather than recomputing from a potentially different-cased input string
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## [1.3.0] - 2026-05-16
|
|
143
|
+
|
|
144
|
+
### Added
|
|
145
|
+
|
|
146
|
+
**Search quality**
|
|
147
|
+
|
|
148
|
+
- *OR-fallback retrieval* — when the FTS5 AND query returns too few results, the engine automatically retries with an OR query and re-ranks the combined pool; improves recall for longer, natural-language queries
|
|
149
|
+
- *Abbreviation expansion* — common abbreviations in queries expanded before FTS: `db→database`, `auth→authentication`, `cfg→configuration`, `mgr→manager`, `ctrl→controller`, and 40+ more; C/C++ abbreviations included
|
|
150
|
+
- *camelCase boundary tokenisation* — FTS5 index now correctly splits `getUserById` into `get`, `user`, `by`, `id` at index time, not just at query time; improves recall when query uses word-boundary terms that appear inside camelCase identifiers
|
|
151
|
+
- *Verb synonym expansion* — common verb synonyms expanded at query time: `fetch↔get↔retrieve`, `create↔insert↔add`, `delete↔remove↔drop`, `update↔modify↔edit`, `authenticate→login`, `list↔find`, and more
|
|
152
|
+
- *Stop-word expansion* — 30 additional stop words filtered from multi-word queries: `with`, `without`, `using`, `via`, `existing`, `before`, `after`, `during`, and others
|
|
153
|
+
- *Service/repository kind boost* — `*Service` method symbols +30, `*Repository`/`*Manager`/`*Store` method symbols +15; surfaces application-layer API methods before utility helpers with similar names
|
|
154
|
+
- *Method verb bonus* — fires when the first camelCase part of a method name (the action verb) matches a query word, differentiating `ProductsService.create` from `buildProductListCacheKey`
|
|
155
|
+
- *Quality-gate OR-fallback* — if the AND pool contains no `*Service`/`*Repository` methods even after the first OR-fallback, a second OR pass retrieves the broader candidate pool
|
|
156
|
+
- *Stem matching* — pluralised name parts (`products→product`) now match singular query words
|
|
157
|
+
- *Library path penalty* — symbols from `vendor/`, `node_modules/`, `bower_components/`, `third_party/`, and similar paths penalised to prevent dependency code from ranking above project code
|
|
158
|
+
|
|
159
|
+
**New stylesheet handlers**
|
|
160
|
+
|
|
161
|
+
- *SCSS / SASS* (`.scss`, `.sass`) — `@mixin` → function, `@function` → function, top-level `$variable` → const, `%placeholder` → class, `@keyframes` → type
|
|
162
|
+
- *LESS* (`.less`) — `.mixin(@params){}` → function, top-level `@variable` → const, `@keyframes` → type
|
|
163
|
+
- *CSS* (`.css`) — CSS custom properties (`--token-name`) indexed as const (opt-in via `indexing.cssVariables: true` in config)
|
|
164
|
+
|
|
165
|
+
**Handler depth improvements**
|
|
166
|
+
|
|
167
|
+
- *Go* — interface `method_spec` extraction; top-level `var` declarations; `*Handler`/`*DB`/`*Client` receiver types added to kind-boost patterns
|
|
168
|
+
- *Java* — inner-class extraction no longer gated on `isStatic`; package-private methods included; Android `Activity`/`Fragment`/`ViewModel` pattern boosts
|
|
169
|
+
- *Rust* — `impl` methods filtered to `pub` visibility by default; `trait` implementations boosted; Rust-specific synonyms scoped to Rust repos only
|
|
170
|
+
- *PHP* — UTF-8 multibyte character offset bug fixed (was producing broken symbol names for methods after accented characters in source); property declarations, closures, `define()` global constants, abstract methods, PHP 8.1 enum cases, and interface constants all extracted
|
|
171
|
+
- *TypeScript* — decorator extraction inside `export_statement` wrapper fixed
|
|
172
|
+
|
|
173
|
+
### Fixed
|
|
174
|
+
|
|
175
|
+
- FTS5 syntax error in synonym OR-groups: tokens joined as `(a OR b)` were concatenated without an explicit `AND` connector when followed by another group, producing invalid FTS5 queries; fixed by inserting explicit ` AND ` between groups and checking for top-level OR context before switching to OR-fallback mode
|
|
176
|
+
- `namePrefix` word-boundary guard: stem matching no longer fires when a name only contains the query word as an interior substring (e.g. query `user` no longer matches `superuser` via stem)
|
|
177
|
+
- Short-token filter in multi-word query branch: tokens shorter than 2 characters no longer enter the AND query, preventing FTS5 from returning zero results on trivially-true constraints
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
10
181
|
## [1.2.0] - 2026-05-13
|
|
11
182
|
|
|
12
183
|
### Added
|
|
13
184
|
|
|
14
|
-
**Advanced relationship analysis
|
|
185
|
+
**Advanced relationship analysis**
|
|
15
186
|
- `find_implementations` — find all concrete implementations of a TypeScript interface or abstract class; returns implementing classes with `implementedMethods` and `missingMethods` arrays compared against the interface contract
|
|
16
187
|
- `get_call_hierarchy` — callers and callees of a function N levels deep as a hierarchical tree; supports `callers`, `callees`, and `both` directions; recursive calls marked `cyclic: true`
|
|
17
188
|
- `get_class_hierarchy` — full inheritance tree rooted at a class, showing both ancestors and descendants; use before refactoring a base class to understand the full polymorphism surface
|
|
18
189
|
- `find_cycles` — detect circular import dependencies across the repo or a subtree; returns strongly-connected components with severity rating
|
|
19
190
|
- `get_coupling_map` — afferent/efferent coupling metrics and instability scores (`I = efferent / (afferent + efferent)`) for every file; highlights highest-risk refactoring candidates
|
|
20
191
|
|
|
21
|
-
**Architectural visualization
|
|
192
|
+
**Architectural visualization**
|
|
22
193
|
- `render_diagram` — general-purpose Mermaid or DOT dependency diagram (module, call graph, class hierarchy); output renders natively in GitHub, VS Code, and Claude
|
|
23
194
|
- `render_call_graph` — specialized call graph diagram rooted at a symbol with call-graph-specific layout options
|
|
24
195
|
- `render_import_graph` — file-level import graph for a directory or whole repo; nodes clustered by directory
|
|
@@ -26,24 +197,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
26
197
|
- `render_dep_matrix` — dependency matrix diagram showing coupling between modules as a grid; surfaces structural hotspots at a glance
|
|
27
198
|
- `get_architecture_snapshot` — captures architectural state (file count, symbol count, module breakdown, coupling summary, health scores); take two snapshots to prove structural improvement objectively
|
|
28
199
|
|
|
29
|
-
**Refactoring safety checks
|
|
200
|
+
**Refactoring safety checks**
|
|
30
201
|
- `check_rename_safe` — pre-flight check before renaming a symbol; returns `safe` verdict and all `affectedSites` (call, import, type-reference, string-literal, comment) with file, line, column, and context snippet
|
|
31
202
|
- `check_delete_safe` — pre-flight check before deleting a symbol; returns `safe: false` if anything in the repo still imports or references the symbol
|
|
32
203
|
- `check_move_safe` — pre-flight check before moving a symbol to a different file; validates no import conflicts and lists all import statements that need updating
|
|
33
204
|
- `plan_refactoring` — generate a sequenced, dependency-ordered plan for a structural change from a natural-language description; steps ordered so lower-risk changes happen first
|
|
34
205
|
|
|
35
|
-
**Health dashboards & debt reporting
|
|
206
|
+
**Health dashboards & debt reporting**
|
|
36
207
|
- `health_radar` — five-axis health score (complexity, coupling, maintainability, documentation, stability), each 0–100; returns `overallHealth` score and letter grade (A–F); designed for CI health gates
|
|
37
208
|
- `diff_health_radar` — compare two health radar snapshots (before/after a refactoring) with axis-by-axis deltas and regression/improvement verdicts
|
|
38
209
|
- `get_debt_report` — detailed technical debt report with per-file rankings, priority tiers, worst files by each metric, specific symbols to address, and estimated effort indicators
|
|
39
210
|
|
|
40
|
-
**AST-level search
|
|
211
|
+
**AST-level search**
|
|
41
212
|
- `search_ast` — find every occurrence of a specific tree-sitter node type across all indexed files (e.g. `try_statement`, `arrow_function`, `await_expression`); returns file, line, column, and snippet
|
|
42
213
|
- `search_by_signature` — search symbols by type signature pattern (regex or substring); find all functions returning `Promise<void>` or methods accepting a `Request` parameter
|
|
43
214
|
- `search_by_decorator` — find all symbols annotated with a specific decorator; works for TypeScript (`@Injectable`, `@Controller`) and Python (`@app.route`, `@property`) decorators
|
|
44
215
|
- `search_by_complexity` — find symbols above or below a complexity threshold; returns symbols ranked by complexity score; use before refactoring sprints or to enforce complexity budgets
|
|
45
216
|
|
|
46
|
-
**Code intelligence helpers
|
|
217
|
+
**Code intelligence helpers**
|
|
47
218
|
- `get_entry_points` — identify all runnable entry points: main functions, CLI handlers, HTTP server startups, Lambda handlers, test suites, and scripts; each result includes `kind`, `confidence`, and reason
|
|
48
219
|
- `get_public_api` — all exported symbols grouped by file; use to document a library, audit what is exposed, or check for accidental exports
|
|
49
220
|
- `get_todos` — find all TODO, FIXME, HACK, NOTE, and XXX comments across the repo with file, line, tag type, and comment text
|