purecontext-mcp 1.2.0 → 1.5.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/AGENT_INSTRUCTIONS.md +110 -784
- package/AGENT_REFERENCE.md +561 -0
- package/CHANGELOG.md +177 -6
- package/FRAMEWORK-ADAPTERS.md +351 -0
- package/LANGUAGE-SUPPORT.md +144 -0
- package/README.md +92 -12
- package/USER-GUIDE.md +8 -0
- 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 +89 -17
- package/docs/05-cli-reference.md +89 -0
- package/docs/dev/benchmark-findings-eu-za-tebe.md +210 -0
- package/docs/dev/phase-35-coverage-audit.md +469 -0
- package/package.json +4 -1
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
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Framework Adapters
|
|
2
|
+
|
|
3
|
+
A language handler knows what a function or class looks like. A framework adapter knows that `app.get('/users/:id', ...)` is actually a **route**, that a Vue Single File Component is a **component**, and that a Django `models.Model` subclass is a **model** with a table behind it.
|
|
4
|
+
|
|
5
|
+
PureContext ships with adapters for the frameworks most production codebases are written against. They run automatically — drop the index on a NestJS project and `/users` routes show up as first-class symbols you can search for by path, not just by handler-function name.
|
|
6
|
+
|
|
7
|
+
This page is the user-facing tour. For parameter-level details (exact regex patterns, full `frameworkMeta` shapes), see the [reference manual](docs/08-framework-adapters.md).
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## How adapters change what you see
|
|
12
|
+
|
|
13
|
+
Without an adapter, searching for "user routes" in an Express app returns *function names* — `handleGetUser`, `createUserHandler`, `usersRouter` — and you have to read each one to confirm it's actually a route.
|
|
14
|
+
|
|
15
|
+
With the Express adapter active, the same search returns:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
search_symbols(query: "users") →
|
|
19
|
+
|
|
20
|
+
GET /users src/routes/users.ts route
|
|
21
|
+
POST /users src/routes/users.ts route
|
|
22
|
+
GET /users/:id src/routes/users.ts route
|
|
23
|
+
DELETE /users/:id src/routes/users.ts route
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
That's the difference. Adapters extract the *intent* of code (a route, a component, an ORM entity) rather than just its syntactic shape.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Auto-detection
|
|
31
|
+
|
|
32
|
+
Adapters are detected from project config — `package.json`, `composer.json`, `Gemfile`, `pubspec.yaml`, `go.mod`, `Cargo.toml`, `pom.xml`, `build.gradle`. If you have `react` in dependencies, the React adapter runs. If `manage.py` sits at the project root, the Django adapter runs.
|
|
33
|
+
|
|
34
|
+
You don't usually need to configure anything. If you do:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"adapters": "auto" // default
|
|
39
|
+
"adapters": "none" // disable all adapters
|
|
40
|
+
"adapters": ["vue", "nuxt"] // explicit allow-list
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Multiple adapters run side by side. A Vue + Nuxt project activates both. A Nest app that also uses TypeORM gets routes from Nest *and* entities from TypeORM.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## JavaScript and TypeScript
|
|
49
|
+
|
|
50
|
+
### Vue 3
|
|
51
|
+
|
|
52
|
+
Detected by `vue` in `package.json` or any `.vue` file present.
|
|
53
|
+
|
|
54
|
+
Extracts from Single File Components:
|
|
55
|
+
- The component itself (named from `defineComponent` or filename) → `component`
|
|
56
|
+
- Exported `useFoo` functions → `composable`
|
|
57
|
+
|
|
58
|
+
Useful for: jumping to a `<MyButton>` mentioned in a template, or finding every composable that touches the auth store.
|
|
59
|
+
|
|
60
|
+
### Nuxt
|
|
61
|
+
|
|
62
|
+
Detected by `nuxt.config.ts` / `.js` / `.mts` / `.mjs`.
|
|
63
|
+
|
|
64
|
+
Layers Nuxt's conventional routing on top of the Vue adapter:
|
|
65
|
+
- `pages/blog/[slug].vue` → `route /blog/:slug`
|
|
66
|
+
- `server/api/users.get.ts` → `route GET /api/users`
|
|
67
|
+
- `middleware/auth.ts` and `plugins/*` → `middleware`
|
|
68
|
+
- Composables in `composables/` are flagged with `nuxt_auto_import: true`
|
|
69
|
+
|
|
70
|
+
### React
|
|
71
|
+
|
|
72
|
+
Detected by `react` in `package.json`. This adapter doesn't extract new symbols — it *enriches* what the TypeScript handler already found:
|
|
73
|
+
- PascalCase functions that return JSX → `component`
|
|
74
|
+
- `useFoo` functions → `hook`
|
|
75
|
+
|
|
76
|
+
So `MyButton` shows up as a `component` rather than a generic `function`, and `useAuth` shows up as a `hook` rather than a generic `function`.
|
|
77
|
+
|
|
78
|
+
### Next.js
|
|
79
|
+
|
|
80
|
+
Detected by `next.config.*` or `next` in dependencies. Supports both routers:
|
|
81
|
+
|
|
82
|
+
**Pages Router** (`pages/`):
|
|
83
|
+
- `pages/blog/[slug].tsx` → `route /blog/:slug`
|
|
84
|
+
- Detects `getServerSideProps` (SSR) and `getStaticProps` (SSG)
|
|
85
|
+
- API routes from `pages/api/`
|
|
86
|
+
|
|
87
|
+
**App Router** (`app/`):
|
|
88
|
+
- `app/(marketing)/about/page.tsx` → `route /about` (route groups stripped)
|
|
89
|
+
- `'use client'` directive flagged on metadata
|
|
90
|
+
- API routes from `app/**/route.ts` with HTTP method exports
|
|
91
|
+
|
|
92
|
+
**Middleware** (`middleware.ts`) → `middleware` symbol with the matcher config.
|
|
93
|
+
|
|
94
|
+
### Angular
|
|
95
|
+
|
|
96
|
+
Detected by `@angular/core`. Decorated classes become first-class:
|
|
97
|
+
- `@Component` → `component` (with `selector`)
|
|
98
|
+
- `@Injectable` → `class` (service)
|
|
99
|
+
- `@NgModule` → `class` (module)
|
|
100
|
+
- `@Directive` → `component`
|
|
101
|
+
- `@Pipe` → `component` (with the pipe name)
|
|
102
|
+
- `RouterModule.forRoot` / `forChild` configs → `route` symbols
|
|
103
|
+
|
|
104
|
+
### NestJS
|
|
105
|
+
|
|
106
|
+
Detected by `@nestjs/core`. Combines the controller prefix with each method's path:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
@Controller('users')
|
|
110
|
+
class UsersController {
|
|
111
|
+
@Get(':id') findOne() { ... } // → route GET /users/:id
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- `@Injectable` → `class` (with `nestjs_provider: true`)
|
|
116
|
+
- `@Module` → `class` (with `nestjs_module: true`)
|
|
117
|
+
- Guards and `CanActivate` implementations → `middleware`
|
|
118
|
+
|
|
119
|
+
### Express
|
|
120
|
+
|
|
121
|
+
Detected by `express`. Extracts string-literal route registrations:
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
app.get('/path', handler) // → route GET /path
|
|
125
|
+
router.post('/path', handler) // → route POST /path
|
|
126
|
+
app.use('/path', middleware) // → middleware /path
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Dynamic paths built from variables or template literals are skipped — there's no reliable way to recover the runtime value from static analysis.
|
|
130
|
+
|
|
131
|
+
### Fastify
|
|
132
|
+
|
|
133
|
+
Detected by `fastify`. Same pattern as Express: `fastify.get(path, handler)` → `route`.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Python
|
|
138
|
+
|
|
139
|
+
### Django
|
|
140
|
+
|
|
141
|
+
Detected by `manage.py` at the project root, or `django` in requirements.
|
|
142
|
+
|
|
143
|
+
- `models.Model` subclasses → `model` (with field types: `CharField`, `ForeignKey`, etc.)
|
|
144
|
+
- Class-based views (`APIView`, `ViewSet`, etc.) → `view`
|
|
145
|
+
- Function-based views with `@login_required` / `@api_view` → `view`
|
|
146
|
+
- `path(...)` / `re_path(...)` in `urls.py` → `route`
|
|
147
|
+
- `@receiver(post_save)` → `signal`
|
|
148
|
+
|
|
149
|
+
### FastAPI
|
|
150
|
+
|
|
151
|
+
Detected by `fastapi`. Extracts decorated handlers:
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
@app.get('/items/{id}') # → route GET /items/{id}
|
|
155
|
+
@router.post('/items') # → route POST /items
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
FastAPI's `{param}` path syntax is preserved as-is in the route metadata.
|
|
159
|
+
|
|
160
|
+
### Flask
|
|
161
|
+
|
|
162
|
+
Detected by `Flask`. Extracts:
|
|
163
|
+
- `@app.route('/path')` → `route`
|
|
164
|
+
- `@app.get`, `@app.post`, etc. → `route`
|
|
165
|
+
- Blueprint routes (`@bp.route(...)`) → `route`
|
|
166
|
+
- Class-based views inheriting `MethodView` → `view`
|
|
167
|
+
|
|
168
|
+
Flask's `<int:user_id>` path syntax is preserved.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Go
|
|
173
|
+
|
|
174
|
+
### Gin, Echo, Fiber
|
|
175
|
+
|
|
176
|
+
Detected by their respective `go.mod` entries. All three follow the same pattern — `r.GET("/path", handler)` becomes a `route`. Route groups apply their prefix to children.
|
|
177
|
+
|
|
178
|
+
The Fiber adapter handles title-cased methods (`app.Get`, `app.Post`); Gin and Echo use lowercase methods.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## PHP
|
|
183
|
+
|
|
184
|
+
### Laravel
|
|
185
|
+
|
|
186
|
+
Detected by `laravel/framework` in `composer.json`.
|
|
187
|
+
|
|
188
|
+
- `Route::get('/path', ...)` → `route`
|
|
189
|
+
- `Route::resource('users', Controller::class)` → expands into the seven CRUD routes (index/show/create/store/edit/update/destroy)
|
|
190
|
+
- `Route::group(['prefix' => '/api'], ...)` → prefix applied to children
|
|
191
|
+
- `class User extends Model` → `model`
|
|
192
|
+
- Controller public methods → `view` (action)
|
|
193
|
+
- Middleware classes → `middleware`
|
|
194
|
+
|
|
195
|
+
### Symfony
|
|
196
|
+
|
|
197
|
+
Detected by `symfony/framework-bundle`. Supports both routing styles:
|
|
198
|
+
|
|
199
|
+
```php
|
|
200
|
+
#[Route('/path', methods: ['GET'])] // PHP 8 attributes
|
|
201
|
+
@Route('/path') // docblock annotations
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Both produce `route` symbols.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Ruby
|
|
209
|
+
|
|
210
|
+
### Rails
|
|
211
|
+
|
|
212
|
+
Detected by `gem 'rails'` in `Gemfile`.
|
|
213
|
+
|
|
214
|
+
- `ApplicationRecord` subclasses → `model` (with `has_many` associations captured)
|
|
215
|
+
- Controller public methods → `view` (action)
|
|
216
|
+
- `get '/path'`, `resources :users` in `routes.rb` → `route` (resources expand to the seven REST actions)
|
|
217
|
+
|
|
218
|
+
### Sinatra
|
|
219
|
+
|
|
220
|
+
Detected by `gem 'sinatra'` or `require 'sinatra'`. `get '/path' do ... end` → `route`.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Kotlin
|
|
225
|
+
|
|
226
|
+
### Ktor
|
|
227
|
+
|
|
228
|
+
Detected by `io.ktor`. Extracts from the routing DSL:
|
|
229
|
+
|
|
230
|
+
```kotlin
|
|
231
|
+
route("/api") {
|
|
232
|
+
get("/users") { ... } // → route /api/users
|
|
233
|
+
}
|
|
234
|
+
authenticate { ... } // → frameworkMeta.authenticated: true
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Spring (Kotlin)
|
|
238
|
+
|
|
239
|
+
Detected by `org.springframework.boot`. Same extraction as Spring Boot below — adapter handles both Java and Kotlin sources.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Rust
|
|
244
|
+
|
|
245
|
+
### Axum
|
|
246
|
+
|
|
247
|
+
Detected by `axum` in `Cargo.toml`. Extracts router chains:
|
|
248
|
+
|
|
249
|
+
```rust
|
|
250
|
+
.route("/users", get(list_users))
|
|
251
|
+
.route("/users/:id", get(get_user))
|
|
252
|
+
.layer(auth_middleware) // → middleware
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Actix-web
|
|
256
|
+
|
|
257
|
+
Detected by `actix-web`. Extracts attribute macros: `#[get("/path")]` → `route`. `.wrap(...)` calls become `middleware`.
|
|
258
|
+
|
|
259
|
+
### Rocket
|
|
260
|
+
|
|
261
|
+
Detected by `rocket`. Extracts `#[get("/path")]` → `route`. `#[catch(404)]` becomes an error catcher, and `Fairing` implementations become middleware.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Java
|
|
266
|
+
|
|
267
|
+
### Spring Boot
|
|
268
|
+
|
|
269
|
+
Detected by `spring-boot-starter` in build files.
|
|
270
|
+
|
|
271
|
+
- `@GetMapping` / `@PostMapping` (combined with class-level `@RequestMapping` prefix) → `route`
|
|
272
|
+
- `@Service`, `@Component`, `@Repository` → beans with bean metadata
|
|
273
|
+
- `@Bean` factory methods → tracked as bean producers
|
|
274
|
+
- `@Scheduled` methods → scheduled tasks
|
|
275
|
+
|
|
276
|
+
### Micronaut
|
|
277
|
+
|
|
278
|
+
Detected by `io.micronaut`. `@Get("/path")`, `@Post(...)` → `route`. `@Client` interfaces are captured.
|
|
279
|
+
|
|
280
|
+
### Quarkus
|
|
281
|
+
|
|
282
|
+
Detected by `io.quarkus`. JAX-RS `@GET` + `@Path` combinations → `route`. `@ApplicationScoped` → bean.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## ORM adapters
|
|
287
|
+
|
|
288
|
+
ORMs sit slightly off the routing-adapter spine because they don't add routes — they add *entities*, which downstream queries (`find_references`, `get_blast_radius`) treat the same as any other symbol.
|
|
289
|
+
|
|
290
|
+
| Adapter | Detected by | Extracts |
|
|
291
|
+
|---------|-------------|----------|
|
|
292
|
+
| **Hibernate** (Java) | `hibernate-core` / `jakarta.persistence` | `@Entity` classes, table name, columns with types and nullability, `@OneToMany` / `@ManyToOne` relationships, named queries |
|
|
293
|
+
| **SQLAlchemy** (Python) | `sqlalchemy` | `Base` / `DeclarativeBase` subclasses, `__tablename__`, `Column(Type)` fields, `relationship()` associations, `@hybrid_property`. Supports both 1.x and 2.0 (`mapped_column`) styles. |
|
|
294
|
+
| **Django ORM** | `manage.py` | `models.Model` subclasses with field types (`CharField`, `IntegerField`, `ForeignKey`, `ManyToManyField`, etc.) |
|
|
295
|
+
| **Prisma** | `prisma` in `package.json` or `schema.prisma` present | Model definitions and relations from `schema.prisma` |
|
|
296
|
+
| **TypeORM** | `typeorm` in `package.json` | `@Entity` classes and `@Column` / `@Relation` fields |
|
|
297
|
+
|
|
298
|
+
Once entities are first-class symbols, you can ask "what writes to the `users` table?" the same way you'd ask "what calls `validateToken`?".
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
## Mobile
|
|
303
|
+
|
|
304
|
+
### Flutter
|
|
305
|
+
|
|
306
|
+
Detected by `sdk: flutter` in `pubspec.yaml`. Extracts from `.dart` files:
|
|
307
|
+
|
|
308
|
+
- `StatelessWidget` subclasses → `widget`
|
|
309
|
+
- `StatefulWidget` subclasses → `widget` (linked to the State class)
|
|
310
|
+
- `ChangeNotifier` subclasses → `class` with `flutter_notifier: true`
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Disabling an adapter
|
|
315
|
+
|
|
316
|
+
If an adapter is misclassifying things in your project, turn it off:
|
|
317
|
+
|
|
318
|
+
```json
|
|
319
|
+
{
|
|
320
|
+
"adapters": ["vue", "react"] // explicit list — others stay off
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Or to disable framework extraction entirely:
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"adapters": "none"
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
The language handler still runs — you'll still get functions and classes, you just won't get `route` / `component` / `model` annotations on top.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Adding a new adapter
|
|
337
|
+
|
|
338
|
+
Adapters follow the same three-layer rule as language handlers (Core → Handlers → Adapters; never the reverse). To add one:
|
|
339
|
+
|
|
340
|
+
1. Create a file in `src/adapters/`, implementing `FrameworkAdapter`
|
|
341
|
+
2. `detect(projectRoot)` returns true if the framework is present
|
|
342
|
+
3. `extractFrameworkSymbols(tree, source, filePath)` returns the framework-specific symbols
|
|
343
|
+
4. Optionally `enrichMetadata(symbol)` to add `frameworkMeta` to existing symbols
|
|
344
|
+
5. Add tests against fixture projects in `test/adapters/`
|
|
345
|
+
|
|
346
|
+
See `docs/25-architecture-overview.md` for the architecture rules and `src/adapters/vue.ts` for a good reference implementation.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
→ Full parameter-level reference: [docs/08-framework-adapters.md](docs/08-framework-adapters.md)
|
|
351
|
+
→ The language handlers that adapters sit on top of: [LANGUAGE-SUPPORT.md](LANGUAGE-SUPPORT.md)
|