lsp-intelligence 0.2.1 → 0.3.2
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/.claude-plugin/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +11 -0
- package/CLAUDE.md +75 -0
- package/README.md +15 -38
- package/dist/adapters/express/index.d.ts +9 -0
- package/dist/adapters/express/index.js +46 -0
- package/dist/adapters/express/index.js.map +1 -0
- package/dist/adapters/next/index.d.ts +10 -0
- package/dist/adapters/next/index.js +67 -0
- package/dist/adapters/next/index.js.map +1 -0
- package/dist/adapters/react/index.d.ts +11 -0
- package/dist/adapters/react/index.js +133 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/registry.d.ts +22 -0
- package/dist/adapters/registry.js +101 -0
- package/dist/adapters/registry.js.map +1 -0
- package/dist/adapters/types.d.ts +97 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/analysis/ts/applyVirtualEdit.d.ts +27 -0
- package/dist/analysis/ts/applyVirtualEdit.js +235 -0
- package/dist/analysis/ts/applyVirtualEdit.js.map +1 -0
- package/dist/analysis/ts/changeRecipes.d.ts +52 -0
- package/dist/analysis/ts/changeRecipes.js +14 -0
- package/dist/analysis/ts/changeRecipes.js.map +1 -0
- package/dist/analysis/ts/compatibility.d.ts +54 -0
- package/dist/analysis/ts/compatibility.js +113 -0
- package/dist/analysis/ts/compatibility.js.map +1 -0
- package/dist/analysis/ts/diffDeclarationShape.d.ts +26 -0
- package/dist/analysis/ts/diffDeclarationShape.js +114 -0
- package/dist/analysis/ts/diffDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/exhaustiveness.d.ts +49 -0
- package/dist/analysis/ts/exhaustiveness.js +158 -0
- package/dist/analysis/ts/exhaustiveness.js.map +1 -0
- package/dist/analysis/ts/extractDeclarationShape.d.ts +30 -0
- package/dist/analysis/ts/extractDeclarationShape.js +127 -0
- package/dist/analysis/ts/extractDeclarationShape.js.map +1 -0
- package/dist/analysis/ts/extractExports.d.ts +19 -0
- package/dist/analysis/ts/extractExports.js +178 -0
- package/dist/analysis/ts/extractExports.js.map +1 -0
- package/dist/analysis/ts/extractRoutes.d.ts +12 -0
- package/dist/analysis/ts/extractRoutes.js +165 -0
- package/dist/analysis/ts/extractRoutes.js.map +1 -0
- package/dist/analysis/ts/parseSourceFile.d.ts +5 -1
- package/dist/analysis/ts/parseSourceFile.js +6 -2
- package/dist/analysis/ts/parseSourceFile.js.map +1 -1
- package/dist/analysis/ts/program/CheckerQueries.d.ts +56 -0
- package/dist/analysis/ts/program/CheckerQueries.js +187 -0
- package/dist/analysis/ts/program/CheckerQueries.js.map +1 -0
- package/dist/analysis/ts/program/ProgramManager.d.ts +27 -0
- package/dist/analysis/ts/program/ProgramManager.js +147 -0
- package/dist/analysis/ts/program/ProgramManager.js.map +1 -0
- package/dist/analysis/ts/program/TypeFacts.d.ts +58 -0
- package/dist/analysis/ts/program/TypeFacts.js +68 -0
- package/dist/analysis/ts/program/TypeFacts.js.map +1 -0
- package/dist/analysis/ts/typeState.d.ts +46 -0
- package/dist/analysis/ts/typeState.js +108 -0
- package/dist/analysis/ts/typeState.js.map +1 -0
- package/dist/ast/diffDeclarationShapes.js +25 -11
- package/dist/ast/diffDeclarationShapes.js.map +1 -1
- package/dist/ast/extractExportDeclarations.js +8 -3
- package/dist/ast/extractExportDeclarations.js.map +1 -1
- package/dist/cache/CacheSchema.d.ts +30 -0
- package/dist/cache/CacheSchema.js +9 -0
- package/dist/cache/CacheSchema.js.map +1 -0
- package/dist/cache/CacheStore.d.ts +22 -0
- package/dist/cache/CacheStore.js +111 -0
- package/dist/cache/CacheStore.js.map +1 -0
- package/dist/cache/SemanticCache.d.ts +38 -0
- package/dist/cache/SemanticCache.js +87 -0
- package/dist/cache/SemanticCache.js.map +1 -0
- package/dist/cache/SnapshotFingerprint.d.ts +17 -0
- package/dist/cache/SnapshotFingerprint.js +14 -0
- package/dist/cache/SnapshotFingerprint.js.map +1 -0
- package/dist/engine/DocumentManager.d.ts +16 -0
- package/dist/engine/DocumentManager.js +32 -0
- package/dist/engine/DocumentManager.js.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/search/adapters/http.d.ts +9 -3
- package/dist/search/adapters/http.js +7 -52
- package/dist/search/adapters/http.js.map +1 -1
- package/dist/search/adapters/react.d.ts +8 -8
- package/dist/search/adapters/react.js +3 -88
- package/dist/search/adapters/react.js.map +1 -1
- package/dist/search/adapters/registry.d.ts +7 -4
- package/dist/search/adapters/registry.js +7 -17
- package/dist/search/adapters/registry.js.map +1 -1
- package/dist/search/expand/graphExpansion.js +47 -14
- package/dist/search/expand/graphExpansion.js.map +1 -1
- package/dist/search/index/declarationIndex.d.ts +3 -1
- package/dist/search/index/declarationIndex.js +4 -2
- package/dist/search/index/declarationIndex.js.map +1 -1
- package/dist/search/index/routeIndex.d.ts +6 -0
- package/dist/search/index/routeIndex.js +19 -0
- package/dist/search/index/routeIndex.js.map +1 -0
- package/dist/search/index/usageIndex.d.ts +3 -1
- package/dist/search/index/usageIndex.js +4 -2
- package/dist/search/index/usageIndex.js.map +1 -1
- package/dist/search/index/workspaceIndex.d.ts +7 -1
- package/dist/search/index/workspaceIndex.js +54 -14
- package/dist/search/index/workspaceIndex.js.map +1 -1
- package/dist/search/query/compileEffectiveSearchSpec.js +9 -0
- package/dist/search/query/compileEffectiveSearchSpec.js.map +1 -1
- package/dist/search/query/parseQuery.js +5 -1
- package/dist/search/query/parseQuery.js.map +1 -1
- package/dist/search/query/planQuery.js +14 -4
- package/dist/search/query/planQuery.js.map +1 -1
- package/dist/search/ranking/mergeCandidates.d.ts +1 -0
- package/dist/search/ranking/mergeCandidates.js +16 -0
- package/dist/search/ranking/mergeCandidates.js.map +1 -1
- package/dist/search/retrievers/routeRetriever.d.ts +7 -0
- package/dist/search/retrievers/routeRetriever.js +64 -0
- package/dist/search/retrievers/routeRetriever.js.map +1 -0
- package/dist/search/types.d.ts +16 -4
- package/dist/session/OverlayStore.d.ts +15 -0
- package/dist/session/OverlayStore.js +46 -0
- package/dist/session/OverlayStore.js.map +1 -0
- package/dist/session/SnapshotResolver.d.ts +31 -0
- package/dist/session/SnapshotResolver.js +50 -0
- package/dist/session/SnapshotResolver.js.map +1 -0
- package/dist/session/WorkspaceSnapshot.d.ts +21 -0
- package/dist/session/WorkspaceSnapshot.js +2 -0
- package/dist/session/WorkspaceSnapshot.js.map +1 -0
- package/dist/tools/composites/apiGuard.d.ts +4 -0
- package/dist/tools/composites/apiGuard.js +158 -24
- package/dist/tools/composites/apiGuard.js.map +1 -1
- package/dist/tools/composites/findCode.js +12 -2
- package/dist/tools/composites/findCode.js.map +1 -1
- package/dist/tools/composites/rootCauseTrace.js +89 -13
- package/dist/tools/composites/rootCauseTrace.js.map +1 -1
- package/dist/workflows/simulateChange.d.ts +44 -0
- package/dist/workflows/simulateChange.js +194 -0
- package/dist/workflows/simulateChange.js.map +1 -0
- package/dist/workflows/verifyChangeSet.d.ts +58 -0
- package/dist/workflows/verifyChangeSet.js +300 -0
- package/dist/workflows/verifyChangeSet.js.map +1 -0
- package/hooks/hooks.json +25 -0
- package/hooks/post-edit-check.sh +23 -0
- package/package.json +20 -4
- package/scripts/launch.mjs +29 -0
- package/skills/api-check/SKILL.md +34 -0
- package/skills/check/SKILL.md +25 -0
- package/skills/context/SKILL.md +24 -0
- package/skills/diff/SKILL.md +27 -0
- package/skills/find/SKILL.md +63 -0
- package/skills/impact/SKILL.md +21 -0
- package/skills/verify/SKILL.md +54 -0
- package/skills/why/SKILL.md +31 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lsp-intelligence-marketplace",
|
|
3
|
+
"description": "Official marketplace for the lsp-intelligence Claude Code plugin",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "Peri Levy"
|
|
6
|
+
},
|
|
7
|
+
"plugins": [
|
|
8
|
+
{
|
|
9
|
+
"name": "lsp-intelligence",
|
|
10
|
+
"description": "Local code intelligence for TypeScript/JavaScript — Find code, explain failures, guard API contracts, simulate changes.",
|
|
11
|
+
"source": {
|
|
12
|
+
"source": "npm",
|
|
13
|
+
"package": "lsp-intelligence",
|
|
14
|
+
"version": "0.3.2"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lsp-intelligence",
|
|
3
|
+
"description": "Local code intelligence for TypeScript/JavaScript — Find code, explain failures, guard API contracts, simulate changes.",
|
|
4
|
+
"version": "0.3.2",
|
|
5
|
+
"mcpServers": {
|
|
6
|
+
"lsp-intelligence": {
|
|
7
|
+
"command": "node",
|
|
8
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/launch.mjs"]
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# LSP Intelligence — Agent Instructions
|
|
2
|
+
|
|
3
|
+
Local code intelligence for real engineering workflows. **Find** code, **explain** failures, **guard** API contracts.
|
|
4
|
+
|
|
5
|
+
> **Note:** The first query in a new session may take a few seconds while the TypeScript engine warms up. The workspace index is persisted and loads instantly on repeat sessions. Subsequent queries are 100-300ms.
|
|
6
|
+
|
|
7
|
+
## Primary tools
|
|
8
|
+
|
|
9
|
+
| Workflow | Tool | Skill |
|
|
10
|
+
|----------|------|-------|
|
|
11
|
+
| Find code by intent | `find_code` | `/find` |
|
|
12
|
+
| Find structural patterns | `find_pattern` | — |
|
|
13
|
+
| Trace root cause of an error | `root_cause_trace` | `/why` |
|
|
14
|
+
| Check API contract changes | `api_guard` | `/api-check` |
|
|
15
|
+
| Full pre-merge verification | `verify_changes` | `/verify` |
|
|
16
|
+
|
|
17
|
+
## When to use LSP tools
|
|
18
|
+
|
|
19
|
+
| You want to... | Instead of... | Use |
|
|
20
|
+
|----------------|---------------|-----|
|
|
21
|
+
| Find where an API is used | `grep "symbolName"` | `find_code` or `find_references` |
|
|
22
|
+
| Find implementations by concept | Multiple greps | `find_code` (auto-routes to behavior search) |
|
|
23
|
+
| Find structural patterns | Manual code reading | `find_code` or `find_pattern` |
|
|
24
|
+
| Find config/route/flag definitions | Grepping JSON/YAML | `find_code` with config focus |
|
|
25
|
+
| Jump to a definition | Reading imports | `goto_definition` |
|
|
26
|
+
| Understand a type signature | Reading the source file | `hover` |
|
|
27
|
+
| See what a file contains | `read` on the whole file | `outline` |
|
|
28
|
+
| Know what breaks if you change something | Manual tracing | `impact_trace` |
|
|
29
|
+
| Prepare context for a coding task | Reading 5-10 files | `gather_context` |
|
|
30
|
+
| Check for type errors after editing | Running `tsc` | `live_diagnostics` |
|
|
31
|
+
| Understand a TypeScript error | Reading error + source | `explain_error` / `/why` |
|
|
32
|
+
| Review what you changed semantically | `git diff` | `semantic_diff` |
|
|
33
|
+
|
|
34
|
+
## When to still use grep
|
|
35
|
+
|
|
36
|
+
- Searching for string literals in comments or logs
|
|
37
|
+
- Searching non-code files where LSP has no coverage
|
|
38
|
+
- Simple text matching where code-aware ranking isn't needed
|
|
39
|
+
|
|
40
|
+
## Workflow patterns
|
|
41
|
+
|
|
42
|
+
### Before modifying code
|
|
43
|
+
1. `outline` — understand structure without reading everything
|
|
44
|
+
2. `impact_trace` — know the blast radius
|
|
45
|
+
3. `gather_context` — get only relevant code, token-budgeted
|
|
46
|
+
4. `find_test_files` — know which tests to update
|
|
47
|
+
|
|
48
|
+
### While implementing
|
|
49
|
+
- `hover` to check types before writing
|
|
50
|
+
- `auto_import` to get import paths right
|
|
51
|
+
- `goto_definition` to navigate to source
|
|
52
|
+
- `find_references` to verify you're not missing usages
|
|
53
|
+
|
|
54
|
+
### After editing
|
|
55
|
+
- `live_diagnostics` on every file you changed
|
|
56
|
+
- If errors: `explain_error` or `/why` for root cause
|
|
57
|
+
- `semantic_diff` before committing
|
|
58
|
+
- `api_guard` or `/api-check` if exports changed
|
|
59
|
+
|
|
60
|
+
## Symbol-name input
|
|
61
|
+
|
|
62
|
+
All tools accept symbol names directly: `{ "symbol": "UserService" }`. You don't need file paths and line numbers. Only fall back to position-based input when the symbol name is ambiguous across packages.
|
|
63
|
+
|
|
64
|
+
## Skills
|
|
65
|
+
|
|
66
|
+
| Skill | Purpose |
|
|
67
|
+
|-------|---------|
|
|
68
|
+
| `/find <query>` | Guided code search with follow-up actions |
|
|
69
|
+
| `/why <file:line>` | Root cause trace with evidence chain |
|
|
70
|
+
| `/api-check` | API contract guard with semver verdict |
|
|
71
|
+
| `/verify` | Full pre-merge: types + API + test coverage |
|
|
72
|
+
| `/check <files>` | Type check with error explanations |
|
|
73
|
+
| `/impact <symbol>` | Transitive usage trace |
|
|
74
|
+
| `/context <symbols>` | Token-budgeted context extraction |
|
|
75
|
+
| `/diff` | Semantic diff with blast radius |
|
package/README.md
CHANGED
|
@@ -36,52 +36,35 @@ Or get a file overview without reading it:
|
|
|
36
36
|
|
|
37
37
|
## Installation
|
|
38
38
|
|
|
39
|
-
Requires **Node.js 20+**.
|
|
40
|
-
|
|
41
|
-
### Option 1: CLI (recommended)
|
|
39
|
+
Requires **Node.js 20+**.
|
|
42
40
|
|
|
43
|
-
|
|
41
|
+
### Plugin install (recommended)
|
|
44
42
|
|
|
45
|
-
```
|
|
43
|
+
```
|
|
46
44
|
/plugin marketplace add perilevy/lsp-intelligence
|
|
47
|
-
/plugin install lsp-intelligence
|
|
45
|
+
/plugin install lsp-intelligence
|
|
48
46
|
/reload-plugins
|
|
49
47
|
```
|
|
50
48
|
|
|
51
|
-
|
|
49
|
+
That's it. The plugin installs the MCP server, skills, hooks, and agent context in one step. No separate runtime install, no manual `.mcp.json` edits.
|
|
50
|
+
|
|
51
|
+
### MCP server only (advanced)
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
For non-Claude Code agents or manual MCP configuration:
|
|
54
54
|
|
|
55
55
|
```json
|
|
56
56
|
{
|
|
57
|
-
"
|
|
57
|
+
"mcpServers": {
|
|
58
58
|
"lsp-intelligence": {
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": ["-y", "lsp-intelligence"],
|
|
61
|
+
"env": { "LSP_WORKSPACE_ROOT": "${workspaceFolder}" }
|
|
63
62
|
}
|
|
64
|
-
},
|
|
65
|
-
"enabledPlugins": {
|
|
66
|
-
"lsp-intelligence@lsp-intelligence": true
|
|
67
63
|
}
|
|
68
64
|
}
|
|
69
65
|
```
|
|
70
66
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Use npm source in `marketplace.json` for version pinning and built-in dependency resolution:
|
|
74
|
-
|
|
75
|
-
```json
|
|
76
|
-
{
|
|
77
|
-
"name": "lsp-intelligence",
|
|
78
|
-
"source": {
|
|
79
|
-
"source": "npm",
|
|
80
|
-
"package": "lsp-intelligence",
|
|
81
|
-
"version": "0.2.0"
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
```
|
|
67
|
+
This gives you the raw MCP tools only — no skills or hooks.
|
|
85
68
|
|
|
86
69
|
## Capabilities
|
|
87
70
|
|
|
@@ -260,10 +243,7 @@ Add to your `.mcp.json`:
|
|
|
260
243
|
"mcpServers": {
|
|
261
244
|
"lsp": {
|
|
262
245
|
"command": "npx",
|
|
263
|
-
"args": ["-y", "lsp-intelligence"]
|
|
264
|
-
"env": {
|
|
265
|
-
"LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
|
|
266
|
-
}
|
|
246
|
+
"args": ["-y", "lsp-intelligence"]
|
|
267
247
|
}
|
|
268
248
|
}
|
|
269
249
|
}
|
|
@@ -286,10 +266,7 @@ Then in `.mcp.json`:
|
|
|
286
266
|
"mcpServers": {
|
|
287
267
|
"lsp": {
|
|
288
268
|
"command": "node",
|
|
289
|
-
"args": ["/absolute/path/to/lsp-intelligence/dist/index.js"]
|
|
290
|
-
"env": {
|
|
291
|
-
"LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
|
|
292
|
-
}
|
|
269
|
+
"args": ["/absolute/path/to/lsp-intelligence/dist/index.js"]
|
|
293
270
|
}
|
|
294
271
|
}
|
|
295
272
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IntelligenceAdapter } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Express/Fastify IntelligenceAdapter v2.
|
|
4
|
+
*
|
|
5
|
+
* Capabilities:
|
|
6
|
+
* - detect: route definition queries
|
|
7
|
+
* - graph.denylist: Express framework functions not useful as implementation roots
|
|
8
|
+
*/
|
|
9
|
+
export declare const expressAdapter: IntelligenceAdapter;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Express/Fastify IntelligenceAdapter v2.
|
|
3
|
+
*
|
|
4
|
+
* Capabilities:
|
|
5
|
+
* - detect: route definition queries
|
|
6
|
+
* - graph.denylist: Express framework functions not useful as implementation roots
|
|
7
|
+
*/
|
|
8
|
+
export const expressAdapter = {
|
|
9
|
+
id: 'express',
|
|
10
|
+
detect(ir) {
|
|
11
|
+
if (!ir.traits.routeLike)
|
|
12
|
+
return [];
|
|
13
|
+
const nlTokens = ir.nlTokens;
|
|
14
|
+
const recipes = [];
|
|
15
|
+
const isRouteDef = nlTokens.some(t => ['route', 'endpoint', 'handler', 'defined', 'registered', 'handled'].includes(t)) || ir.phrases.some(p => p.includes('is handled') || p.includes('is defined'));
|
|
16
|
+
if (isRouteDef) {
|
|
17
|
+
recipes.push({
|
|
18
|
+
id: 'express.route-definition',
|
|
19
|
+
adapter: 'express',
|
|
20
|
+
retrievers: ['route', 'behavior', 'regex'],
|
|
21
|
+
exactIdentifiers: [],
|
|
22
|
+
regexes: [
|
|
23
|
+
{ id: 'express-route', pattern: '(?:app|router)\\.(?:get|post|put|delete|patch|all|use)\\s*\\(', flags: 'gi' },
|
|
24
|
+
{ id: 'fastify-route', pattern: 'fastify\\.(?:get|post|put|delete|patch)\\s*\\(', flags: 'g' },
|
|
25
|
+
{ id: 'route-config', pattern: '(?:routes|endpoints)\\s*[:=]\\s*[\\[{]', flags: 'gi' },
|
|
26
|
+
],
|
|
27
|
+
scoreBoost: 3,
|
|
28
|
+
reasons: ['Express adapter: route definition pattern'],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return recipes;
|
|
32
|
+
},
|
|
33
|
+
graph: {
|
|
34
|
+
denylist: [
|
|
35
|
+
// Express framework — not real implementation roots
|
|
36
|
+
'Router', 'express', 'use', 'listen', 'set',
|
|
37
|
+
'json', 'urlencoded', 'static', 'raw', 'text',
|
|
38
|
+
'next', // Express next() middleware callback
|
|
39
|
+
// Common Express middleware names
|
|
40
|
+
'cors', 'helmet', 'morgan', 'compression',
|
|
41
|
+
// Fastify framework
|
|
42
|
+
'fastify', 'register', 'addHook', 'addPlugin',
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/express/index.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAwB;IACjD,EAAE,EAAE,SAAS;IAEb,MAAM,CAAC,EAAW;QAChB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAEpC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;QAC7B,MAAM,OAAO,GAAmB,EAAE,CAAC;QAEnC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CACnC,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CACjF,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QAEhF,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,0BAA0B;gBAC9B,OAAO,EAAE,SAAS;gBAClB,UAAU,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC;gBAC1C,gBAAgB,EAAE,EAAE;gBACpB,OAAO,EAAE;oBACP,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,+DAA+D,EAAE,KAAK,EAAE,IAAI,EAAE;oBAC9G,EAAE,EAAE,EAAE,eAAe,EAAE,OAAO,EAAE,gDAAgD,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC9F,EAAE,EAAE,EAAE,cAAc,EAAE,OAAO,EAAE,wCAAwC,EAAE,KAAK,EAAE,IAAI,EAAE;iBACvF;gBACD,UAAU,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC,2CAA2C,CAAC;aACvD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,EAAE;QACL,QAAQ,EAAE;YACR,oDAAoD;YACpD,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK;YAC3C,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM;YAC7C,MAAM,EAAK,qCAAqC;YAChD,kCAAkC;YAClC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa;YACzC,oBAAoB;YACpB,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW;SAC9C;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IntelligenceAdapter } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Next.js IntelligenceAdapter v2.
|
|
4
|
+
*
|
|
5
|
+
* Capabilities:
|
|
6
|
+
* - detect: route/page/API queries routed to Next.js patterns
|
|
7
|
+
* - graph.denylist: Next.js framework functions not useful as impl roots
|
|
8
|
+
* - graph.rootHints: page/route handler patterns that ARE real roots
|
|
9
|
+
*/
|
|
10
|
+
export declare const nextAdapter: IntelligenceAdapter;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js IntelligenceAdapter v2.
|
|
3
|
+
*
|
|
4
|
+
* Capabilities:
|
|
5
|
+
* - detect: route/page/API queries routed to Next.js patterns
|
|
6
|
+
* - graph.denylist: Next.js framework functions not useful as impl roots
|
|
7
|
+
* - graph.rootHints: page/route handler patterns that ARE real roots
|
|
8
|
+
*/
|
|
9
|
+
export const nextAdapter = {
|
|
10
|
+
id: 'next',
|
|
11
|
+
detect(ir) {
|
|
12
|
+
if (!ir.traits.routeLike && !ir.traits.reactLike)
|
|
13
|
+
return [];
|
|
14
|
+
const recipes = [];
|
|
15
|
+
const nlTokens = ir.nlTokens;
|
|
16
|
+
const isApiRoute = nlTokens.some(t => ['api', 'endpoint', 'handler'].includes(t)) ||
|
|
17
|
+
ir.phrases.some(p => p.includes('api route') || p.includes('api handler'));
|
|
18
|
+
const isPageRoute = nlTokens.some(t => ['page', 'route', 'layout'].includes(t)) ||
|
|
19
|
+
ir.phrases.some(p => p.includes('page component') || p.includes('app router'));
|
|
20
|
+
if (isApiRoute) {
|
|
21
|
+
recipes.push({
|
|
22
|
+
id: 'next.api-route',
|
|
23
|
+
adapter: 'next',
|
|
24
|
+
retrievers: ['route', 'identifier'],
|
|
25
|
+
exactIdentifiers: [],
|
|
26
|
+
regexes: [
|
|
27
|
+
{ id: 'next-api-handler', pattern: 'export\\s+(?:default\\s+)?(?:async\\s+)?function\\s+handler', flags: 'g' },
|
|
28
|
+
{ id: 'next-route-handler', pattern: 'export\\s+(?:async\\s+)?function\\s+(?:GET|POST|PUT|DELETE|PATCH)', flags: 'g' },
|
|
29
|
+
],
|
|
30
|
+
scoreBoost: 3,
|
|
31
|
+
reasons: ['Next adapter: API route handler pattern'],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (isPageRoute) {
|
|
35
|
+
recipes.push({
|
|
36
|
+
id: 'next.page-component',
|
|
37
|
+
adapter: 'next',
|
|
38
|
+
retrievers: ['identifier', 'route'],
|
|
39
|
+
exactIdentifiers: [],
|
|
40
|
+
regexes: [
|
|
41
|
+
{ id: 'next-page-export', pattern: 'export\\s+default\\s+(?:function|const|class)', flags: 'g' },
|
|
42
|
+
{ id: 'next-get-static', pattern: 'getStaticProps|getServerSideProps|generateStaticParams', flags: 'g' },
|
|
43
|
+
],
|
|
44
|
+
scoreBoost: 2,
|
|
45
|
+
reasons: ['Next adapter: page component pattern'],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return recipes;
|
|
49
|
+
},
|
|
50
|
+
graph: {
|
|
51
|
+
denylist: [
|
|
52
|
+
// Next.js data fetching helpers — not implementation roots
|
|
53
|
+
'getStaticProps', 'getServerSideProps', 'getStaticPaths', 'generateStaticParams',
|
|
54
|
+
'generateMetadata', 'revalidate',
|
|
55
|
+
// Next.js router
|
|
56
|
+
'useRouter', 'usePathname', 'useSearchParams', 'useParams',
|
|
57
|
+
'redirect', 'notFound', 'permanentRedirect',
|
|
58
|
+
// Next.js image/link
|
|
59
|
+
'Image', 'Link', 'Script', 'Head',
|
|
60
|
+
],
|
|
61
|
+
rootHints: [
|
|
62
|
+
// Functions that ARE real implementation roots in Next.js
|
|
63
|
+
// (future: boost these during graph expansion)
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/next/index.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAwB;IAC9C,EAAE,EAAE,MAAM;IAEV,MAAM,CAAC,EAAW;QAChB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS;YAAE,OAAO,EAAE,CAAC;QAE5D,MAAM,OAAO,GAAmB,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC;QAE7B,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC/E,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;QAE7E,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC7E,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;QAEjF,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,gBAAgB;gBACpB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;gBACnC,gBAAgB,EAAE,EAAE;gBACpB,OAAO,EAAE;oBACP,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,6DAA6D,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC9G,EAAE,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE,mEAAmE,EAAE,KAAK,EAAE,GAAG,EAAE;iBACvH;gBACD,UAAU,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC,yCAAyC,CAAC;aACrD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC;gBACX,EAAE,EAAE,qBAAqB;gBACzB,OAAO,EAAE,MAAM;gBACf,UAAU,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC;gBACnC,gBAAgB,EAAE,EAAE;gBACpB,OAAO,EAAE;oBACP,EAAE,EAAE,EAAE,kBAAkB,EAAE,OAAO,EAAE,+CAA+C,EAAE,KAAK,EAAE,GAAG,EAAE;oBAChG,EAAE,EAAE,EAAE,iBAAiB,EAAE,OAAO,EAAE,wDAAwD,EAAE,KAAK,EAAE,GAAG,EAAE;iBACzG;gBACD,UAAU,EAAE,CAAC;gBACb,OAAO,EAAE,CAAC,sCAAsC,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,EAAE;QACL,QAAQ,EAAE;YACR,2DAA2D;YAC3D,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,sBAAsB;YAChF,kBAAkB,EAAE,YAAY;YAChC,iBAAiB;YACjB,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,WAAW;YAC1D,UAAU,EAAE,UAAU,EAAE,mBAAmB;YAC3C,qBAAqB;YACrB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;SAClC;QAED,SAAS,EAAE;QACT,0DAA0D;QAC1D,+CAA+C;SAChD;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IntelligenceAdapter } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* React IntelligenceAdapter v2.
|
|
4
|
+
*
|
|
5
|
+
* Capabilities beyond the old SearchAdapter:
|
|
6
|
+
* - graph.denylist: React built-ins and HOC wrappers that should never be
|
|
7
|
+
* promoted as implementation roots during graph expansion
|
|
8
|
+
* - graph.rootHints: patterns indicating actual component implementations
|
|
9
|
+
* - explain.causeHints: React-specific root cause patterns
|
|
10
|
+
*/
|
|
11
|
+
export declare const reactAdapter: IntelligenceAdapter;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
const HOOK_PATTERN = /^use[A-Z]/;
|
|
2
|
+
/**
|
|
3
|
+
* React IntelligenceAdapter v2.
|
|
4
|
+
*
|
|
5
|
+
* Capabilities beyond the old SearchAdapter:
|
|
6
|
+
* - graph.denylist: React built-ins and HOC wrappers that should never be
|
|
7
|
+
* promoted as implementation roots during graph expansion
|
|
8
|
+
* - graph.rootHints: patterns indicating actual component implementations
|
|
9
|
+
* - explain.causeHints: React-specific root cause patterns
|
|
10
|
+
*/
|
|
11
|
+
export const reactAdapter = {
|
|
12
|
+
id: 'react',
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Search recipes (migrated from src/search/adapters/react.ts)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
detect(ir) {
|
|
17
|
+
if (!ir.traits.reactLike)
|
|
18
|
+
return [];
|
|
19
|
+
const recipes = [];
|
|
20
|
+
const hookIds = ir.exactIdentifiers.filter((id) => HOOK_PATTERN.test(id));
|
|
21
|
+
const hasUseEffect = hookIds.includes('useEffect');
|
|
22
|
+
const hasUseMemo = hookIds.includes('useMemo');
|
|
23
|
+
const hasUseCallback = hookIds.includes('useCallback');
|
|
24
|
+
if (hasUseEffect && (ir.structuralPredicates.includes('conditional') ||
|
|
25
|
+
ir.structuralPredicates.includes('returns-cleanup') ||
|
|
26
|
+
ir.codeTokens.includes('cleanup'))) {
|
|
27
|
+
recipes.push({
|
|
28
|
+
id: 'react.useeffect.conditional-cleanup',
|
|
29
|
+
adapter: 'react',
|
|
30
|
+
retrievers: ['identifier', 'structural', 'regex'],
|
|
31
|
+
exactIdentifiers: ['useEffect'],
|
|
32
|
+
structuralPredicates: ['returns-cleanup', 'conditional'],
|
|
33
|
+
regexes: [
|
|
34
|
+
{ id: 'conditional-return', pattern: 'if\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s*\\(\\)', flags: 'g' },
|
|
35
|
+
{ id: 'useeffect-cleanup', pattern: 'useEffect\\s*\\(\\s*\\(\\)\\s*=>\\s*\\{[\\s\\S]*?return\\s', flags: 'g' },
|
|
36
|
+
],
|
|
37
|
+
scoreBoost: 3,
|
|
38
|
+
reasons: ['React adapter: useEffect + conditional cleanup pattern'],
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
if (hasUseEffect && ir.traits.previousStateLike) {
|
|
42
|
+
recipes.push({
|
|
43
|
+
id: 'react.useeffect.functional-state-updater',
|
|
44
|
+
adapter: 'react',
|
|
45
|
+
retrievers: ['identifier', 'structural', 'regex'],
|
|
46
|
+
exactIdentifiers: ['useEffect'],
|
|
47
|
+
structuralPredicates: ['functional-state-updater'],
|
|
48
|
+
regexes: [
|
|
49
|
+
{ id: 'functional-updater', pattern: 'set\\w+\\s*\\(\\s*(?:prev|current|existing|old)\\w*\\s*=>', flags: 'g' },
|
|
50
|
+
{ id: 'updater-arrow', pattern: 'set\\w+\\s*\\(\\s*\\w+\\s*=>\\s*\\w+', flags: 'g' },
|
|
51
|
+
],
|
|
52
|
+
scoreBoost: 4,
|
|
53
|
+
reasons: ['React adapter: useEffect + functional state updater'],
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (hasUseMemo) {
|
|
57
|
+
recipes.push({
|
|
58
|
+
id: 'react.usememo.computation',
|
|
59
|
+
adapter: 'react',
|
|
60
|
+
retrievers: ['identifier'],
|
|
61
|
+
exactIdentifiers: ['useMemo'],
|
|
62
|
+
scoreBoost: 1,
|
|
63
|
+
reasons: ['React adapter: useMemo computation'],
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
if (hasUseCallback) {
|
|
67
|
+
recipes.push({
|
|
68
|
+
id: 'react.usecallback.memoized-handler',
|
|
69
|
+
adapter: 'react',
|
|
70
|
+
retrievers: ['identifier'],
|
|
71
|
+
exactIdentifiers: ['useCallback'],
|
|
72
|
+
scoreBoost: 1,
|
|
73
|
+
reasons: ['React adapter: useCallback memoized handler'],
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (hookIds.length > 0 && recipes.length === 0) {
|
|
77
|
+
recipes.push({
|
|
78
|
+
id: 'react.hook.general',
|
|
79
|
+
adapter: 'react',
|
|
80
|
+
retrievers: ['identifier'],
|
|
81
|
+
exactIdentifiers: hookIds,
|
|
82
|
+
scoreBoost: 0,
|
|
83
|
+
reasons: [`React adapter: general hook query for ${hookIds.join(', ')}`],
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return recipes;
|
|
87
|
+
},
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// Phase 2E: Graph intelligence — prevents React built-ins from appearing
|
|
90
|
+
// as implementation roots when users ask "what is the real implementation?"
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
graph: {
|
|
93
|
+
denylist: [
|
|
94
|
+
// React core hooks
|
|
95
|
+
'useState', 'useEffect', 'useMemo', 'useCallback', 'useRef', 'useContext',
|
|
96
|
+
'useReducer', 'useLayoutEffect', 'useImperativeHandle', 'useDebugValue',
|
|
97
|
+
'useTransition', 'useDeferredValue', 'useId', 'useSyncExternalStore',
|
|
98
|
+
// React component wrappers — not "real" implementations
|
|
99
|
+
'memo', 'forwardRef', 'lazy', 'Suspense',
|
|
100
|
+
// React factory functions
|
|
101
|
+
'createElement', 'createContext', 'createRef', 'createPortal',
|
|
102
|
+
'cloneElement', 'isValidElement', 'Children',
|
|
103
|
+
// React Router / Next.js HOCs
|
|
104
|
+
'withRouter', 'connect', 'inject',
|
|
105
|
+
],
|
|
106
|
+
rootHints: [
|
|
107
|
+
// Functions named after common React patterns are often real implementations
|
|
108
|
+
// (used to boost these during graph expansion)
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Phase 2E: Explain hints — React-specific root cause patterns
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
explain: {
|
|
115
|
+
causeHints: [
|
|
116
|
+
{
|
|
117
|
+
matchCode: '2345',
|
|
118
|
+
matchMessage: /props/i,
|
|
119
|
+
causeCategory: 'react-prop-type-mismatch',
|
|
120
|
+
hint: 'Check that the component\'s prop type interface matches what is being passed',
|
|
121
|
+
scoreBoost: 2,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
matchCode: '2339',
|
|
125
|
+
matchMessage: /useEffect|useState|useMemo/i,
|
|
126
|
+
causeCategory: 'react-hook-return',
|
|
127
|
+
hint: 'The hook may not return what you expect — check the hook\'s return type definition',
|
|
128
|
+
scoreBoost: 2,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/react/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { QueryIR, SearchRecipe } from '../search/types.js';
|
|
2
|
+
import type { IntelligenceAdapter, AdapterCauseHint } from './types.js';
|
|
3
|
+
/** Run all adapter detect() methods and return merged search recipes. */
|
|
4
|
+
export declare function runAdapters(ir: QueryIR): SearchRecipe[];
|
|
5
|
+
/** Get the merged denylist from all adapters. */
|
|
6
|
+
export declare function getAdapterGraphDenylist(): Set<string>;
|
|
7
|
+
/** Get all root hints from all adapters. */
|
|
8
|
+
export declare function getAdapterRootHints(): string[];
|
|
9
|
+
/** Get all cause hints from all adapters. */
|
|
10
|
+
export declare function getAdapterCauseHints(): AdapterCauseHint[];
|
|
11
|
+
/**
|
|
12
|
+
* Find the best cause hint for a given diagnostic code + message.
|
|
13
|
+
* Returns the highest-scoring matching hint, or null if none match.
|
|
14
|
+
*/
|
|
15
|
+
export declare function matchCauseHint(code: string | undefined, message: string): AdapterCauseHint | null;
|
|
16
|
+
/** Run all adapter verify checks on the given files. */
|
|
17
|
+
export declare function runAdapterVerifyChecks(filePaths: string[]): Array<{
|
|
18
|
+
adapterId: string;
|
|
19
|
+
issues: ReturnType<NonNullable<NonNullable<IntelligenceAdapter['verify']>['checks']>[number]['run']>;
|
|
20
|
+
}>;
|
|
21
|
+
export declare function getAdapter(id: string): IntelligenceAdapter | undefined;
|
|
22
|
+
export declare function getAllAdapters(): readonly IntelligenceAdapter[];
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { reactAdapter } from './react/index.js';
|
|
2
|
+
import { nextAdapter } from './next/index.js';
|
|
3
|
+
import { expressAdapter } from './express/index.js';
|
|
4
|
+
// Config adapter remains in search/adapters until Phase 4 — wrapped here for compatibility
|
|
5
|
+
import { configAdapter as legacyConfigAdapter } from '../search/adapters/config.js';
|
|
6
|
+
/**
|
|
7
|
+
* Phase 2E — Central IntelligenceAdapter registry.
|
|
8
|
+
*
|
|
9
|
+
* This is the single source of truth for all adapter capabilities.
|
|
10
|
+
* The old src/search/adapters/registry.ts delegates here for backward compatibility.
|
|
11
|
+
*/
|
|
12
|
+
// Wrap the legacy configAdapter as an IntelligenceAdapter for inclusion
|
|
13
|
+
const configAdapterCompat = {
|
|
14
|
+
id: 'config',
|
|
15
|
+
detect: (ir) => legacyConfigAdapter.detect(ir),
|
|
16
|
+
};
|
|
17
|
+
const ADAPTERS = [
|
|
18
|
+
reactAdapter,
|
|
19
|
+
nextAdapter,
|
|
20
|
+
expressAdapter,
|
|
21
|
+
configAdapterCompat,
|
|
22
|
+
];
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Search recipes (backward-compatible with old SearchAdapter.detect())
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Run all adapter detect() methods and return merged search recipes. */
|
|
27
|
+
export function runAdapters(ir) {
|
|
28
|
+
const recipes = [];
|
|
29
|
+
for (const adapter of ADAPTERS) {
|
|
30
|
+
if (adapter.detect) {
|
|
31
|
+
recipes.push(...adapter.detect(ir));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return recipes;
|
|
35
|
+
}
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Graph intelligence
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
/** Get the merged denylist from all adapters. */
|
|
40
|
+
export function getAdapterGraphDenylist() {
|
|
41
|
+
const merged = new Set();
|
|
42
|
+
for (const adapter of ADAPTERS) {
|
|
43
|
+
for (const symbol of adapter.graph?.denylist ?? []) {
|
|
44
|
+
merged.add(symbol);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return merged;
|
|
48
|
+
}
|
|
49
|
+
/** Get all root hints from all adapters. */
|
|
50
|
+
export function getAdapterRootHints() {
|
|
51
|
+
return ADAPTERS.flatMap((a) => a.graph?.rootHints ?? []);
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Explain intelligence
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/** Get all cause hints from all adapters. */
|
|
57
|
+
export function getAdapterCauseHints() {
|
|
58
|
+
return ADAPTERS.flatMap((a) => a.explain?.causeHints ?? []);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find the best cause hint for a given diagnostic code + message.
|
|
62
|
+
* Returns the highest-scoring matching hint, or null if none match.
|
|
63
|
+
*/
|
|
64
|
+
export function matchCauseHint(code, message) {
|
|
65
|
+
const candidates = getAdapterCauseHints().filter((h) => {
|
|
66
|
+
if (h.matchCode && code !== h.matchCode)
|
|
67
|
+
return false;
|
|
68
|
+
if (h.matchMessage && !h.matchMessage.test(message))
|
|
69
|
+
return false;
|
|
70
|
+
return true;
|
|
71
|
+
});
|
|
72
|
+
if (candidates.length === 0)
|
|
73
|
+
return null;
|
|
74
|
+
return candidates.reduce((best, c) => c.scoreBoost > best.scoreBoost ? c : best);
|
|
75
|
+
}
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Verify checks
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
/** Run all adapter verify checks on the given files. */
|
|
80
|
+
export function runAdapterVerifyChecks(filePaths) {
|
|
81
|
+
const results = [];
|
|
82
|
+
for (const adapter of ADAPTERS) {
|
|
83
|
+
for (const check of adapter.verify?.checks ?? []) {
|
|
84
|
+
const issues = check.run(filePaths);
|
|
85
|
+
if (issues.length > 0) {
|
|
86
|
+
results.push({ adapterId: adapter.id, issues });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Adapter access
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
export function getAdapter(id) {
|
|
96
|
+
return ADAPTERS.find((a) => a.id === id);
|
|
97
|
+
}
|
|
98
|
+
export function getAllAdapters() {
|
|
99
|
+
return ADAPTERS;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"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"}
|