@saluzi/codegraph 0.1.0 → 0.2.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.
Files changed (246) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +885 -0
  3. package/package.json +42 -10
  4. package/scripts/add-lang/bench.sh +60 -0
  5. package/scripts/add-lang/check-grammar.mjs +75 -0
  6. package/scripts/add-lang/dump-ast.mjs +103 -0
  7. package/scripts/add-lang/verify-extraction.mjs +70 -0
  8. package/scripts/agent-eval/ab-adoption.sh +91 -0
  9. package/scripts/agent-eval/ab-hook.sh +86 -0
  10. package/scripts/agent-eval/ab-impl.sh +78 -0
  11. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -0
  12. package/scripts/agent-eval/ab-sufficiency.sh +78 -0
  13. package/scripts/agent-eval/arms-F.sh +21 -0
  14. package/scripts/agent-eval/arms-matrix.sh +37 -0
  15. package/scripts/agent-eval/audit.sh +68 -0
  16. package/scripts/agent-eval/bench-readme.sh +28 -0
  17. package/scripts/agent-eval/bench-why-repo.sh +22 -0
  18. package/scripts/agent-eval/block-read-hook.sh +19 -0
  19. package/scripts/agent-eval/hook-settings.json +15 -0
  20. package/scripts/agent-eval/itrun.sh +120 -0
  21. package/scripts/agent-eval/offload-eval-3arm.sh +72 -0
  22. package/scripts/agent-eval/offload-eval-cost.mjs +133 -0
  23. package/scripts/agent-eval/offload-eval-effort.mjs +108 -0
  24. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -0
  25. package/scripts/agent-eval/offload-eval-frontload.sh +47 -0
  26. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -0
  27. package/scripts/agent-eval/offload-eval-hook.mjs +84 -0
  28. package/scripts/agent-eval/offload-eval-judge.mjs +103 -0
  29. package/scripts/agent-eval/offload-eval-matrix.sh +20 -0
  30. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -0
  31. package/scripts/agent-eval/offload-eval-refs1.sh +50 -0
  32. package/scripts/agent-eval/offload-eval-setup.sh +24 -0
  33. package/scripts/agent-eval/offload-eval-styles.sh +72 -0
  34. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -0
  35. package/scripts/agent-eval/offload-eval.md +76 -0
  36. package/scripts/agent-eval/parse-arms.mjs +116 -0
  37. package/scripts/agent-eval/parse-bench-readme.mjs +84 -0
  38. package/scripts/agent-eval/parse-run.mjs +45 -0
  39. package/scripts/agent-eval/parse-session.mjs +93 -0
  40. package/scripts/agent-eval/probe-context.mjs +21 -0
  41. package/scripts/agent-eval/probe-explore.mjs +40 -0
  42. package/scripts/agent-eval/probe-node.mjs +20 -0
  43. package/scripts/agent-eval/probe-sweep.mjs +119 -0
  44. package/scripts/agent-eval/probe-trace.mjs +20 -0
  45. package/scripts/agent-eval/redirect-read-hook.sh +38 -0
  46. package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
  47. package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
  48. package/scripts/agent-eval/run-agent.sh +34 -0
  49. package/scripts/agent-eval/run-all.sh +75 -0
  50. package/scripts/agent-eval/run-arms.sh +56 -0
  51. package/scripts/agent-eval/seq-matrix.mjs +137 -0
  52. package/scripts/build-bundle.sh +123 -0
  53. package/scripts/extract-release-notes.mjs +130 -0
  54. package/scripts/local-install.sh +41 -0
  55. package/scripts/npm-sdk.js +75 -0
  56. package/scripts/npm-shim.js +275 -0
  57. package/scripts/pack-npm.sh +119 -0
  58. package/scripts/prepare-release.mjs +270 -0
  59. package/dist/bin/codegraph.d.ts +0 -25
  60. package/dist/bin/node-version-check.d.ts +0 -37
  61. package/dist/bin/uninstall.d.ts +0 -14
  62. package/dist/context/formatter.d.ts +0 -33
  63. package/dist/context/formatter.js +0 -244
  64. package/dist/context/index.d.ts +0 -117
  65. package/dist/context/index.js +0 -1050
  66. package/dist/db/index.d.ts +0 -101
  67. package/dist/db/index.js +0 -250
  68. package/dist/db/migrations.d.ts +0 -47
  69. package/dist/db/migrations.js +0 -131
  70. package/dist/db/queries.d.ts +0 -291
  71. package/dist/db/queries.js +0 -1349
  72. package/dist/db/schema.sql +0 -151
  73. package/dist/db/sqlite-adapter.d.ts +0 -49
  74. package/dist/db/sqlite-adapter.js +0 -141
  75. package/dist/directory.d.ts +0 -62
  76. package/dist/directory.js +0 -264
  77. package/dist/errors.d.ts +0 -149
  78. package/dist/errors.js +0 -219
  79. package/dist/extraction/dfm-extractor.d.ts +0 -31
  80. package/dist/extraction/dfm-extractor.js +0 -151
  81. package/dist/extraction/grammars.d.ts +0 -94
  82. package/dist/extraction/grammars.js +0 -357
  83. package/dist/extraction/index.d.ts +0 -148
  84. package/dist/extraction/index.js +0 -1286
  85. package/dist/extraction/languages/c-cpp.d.ts +0 -4
  86. package/dist/extraction/languages/c-cpp.js +0 -126
  87. package/dist/extraction/languages/csharp.d.ts +0 -3
  88. package/dist/extraction/languages/csharp.js +0 -72
  89. package/dist/extraction/languages/dart.d.ts +0 -3
  90. package/dist/extraction/languages/dart.js +0 -192
  91. package/dist/extraction/languages/go.d.ts +0 -3
  92. package/dist/extraction/languages/go.js +0 -58
  93. package/dist/extraction/languages/index.d.ts +0 -10
  94. package/dist/extraction/languages/index.js +0 -49
  95. package/dist/extraction/languages/java.d.ts +0 -3
  96. package/dist/extraction/languages/java.js +0 -64
  97. package/dist/extraction/languages/javascript.d.ts +0 -3
  98. package/dist/extraction/languages/javascript.js +0 -90
  99. package/dist/extraction/languages/kotlin.d.ts +0 -3
  100. package/dist/extraction/languages/kotlin.js +0 -253
  101. package/dist/extraction/languages/lua.d.ts +0 -3
  102. package/dist/extraction/languages/lua.js +0 -150
  103. package/dist/extraction/languages/luau.d.ts +0 -3
  104. package/dist/extraction/languages/luau.js +0 -37
  105. package/dist/extraction/languages/pascal.d.ts +0 -3
  106. package/dist/extraction/languages/pascal.js +0 -66
  107. package/dist/extraction/languages/php.d.ts +0 -3
  108. package/dist/extraction/languages/php.js +0 -107
  109. package/dist/extraction/languages/python.d.ts +0 -3
  110. package/dist/extraction/languages/python.js +0 -56
  111. package/dist/extraction/languages/ruby.d.ts +0 -3
  112. package/dist/extraction/languages/ruby.js +0 -114
  113. package/dist/extraction/languages/rust.d.ts +0 -3
  114. package/dist/extraction/languages/rust.js +0 -109
  115. package/dist/extraction/languages/scala.d.ts +0 -3
  116. package/dist/extraction/languages/scala.js +0 -139
  117. package/dist/extraction/languages/swift.d.ts +0 -3
  118. package/dist/extraction/languages/swift.js +0 -91
  119. package/dist/extraction/languages/typescript.d.ts +0 -3
  120. package/dist/extraction/languages/typescript.js +0 -129
  121. package/dist/extraction/liquid-extractor.d.ts +0 -52
  122. package/dist/extraction/liquid-extractor.js +0 -313
  123. package/dist/extraction/parse-worker.d.ts +0 -8
  124. package/dist/extraction/parse-worker.js +0 -94
  125. package/dist/extraction/svelte-extractor.d.ts +0 -56
  126. package/dist/extraction/svelte-extractor.js +0 -272
  127. package/dist/extraction/tree-sitter-helpers.d.ts +0 -39
  128. package/dist/extraction/tree-sitter-helpers.js +0 -103
  129. package/dist/extraction/tree-sitter-types.d.ts +0 -191
  130. package/dist/extraction/tree-sitter-types.js +0 -10
  131. package/dist/extraction/tree-sitter.d.ts +0 -238
  132. package/dist/extraction/tree-sitter.js +0 -2430
  133. package/dist/extraction/vue-extractor.d.ts +0 -36
  134. package/dist/extraction/vue-extractor.js +0 -163
  135. package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
  136. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  137. package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
  138. package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
  139. package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
  140. package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
  141. package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
  142. package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
  143. package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
  144. package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
  145. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  146. package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
  147. package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
  148. package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
  149. package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
  150. package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  151. package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
  152. package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
  153. package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
  154. package/dist/extraction/wasm-runtime-flags.d.ts +0 -46
  155. package/dist/extraction/wasm-runtime-flags.js +0 -105
  156. package/dist/graph/index.d.ts +0 -8
  157. package/dist/graph/index.js +0 -13
  158. package/dist/graph/queries.d.ts +0 -109
  159. package/dist/graph/queries.js +0 -366
  160. package/dist/graph/traversal.d.ts +0 -137
  161. package/dist/graph/traversal.js +0 -528
  162. package/dist/index.d.ts +0 -509
  163. package/dist/index.js +0 -800
  164. package/dist/installer/claude-md-template.d.ts +0 -19
  165. package/dist/installer/config-writer.d.ts +0 -29
  166. package/dist/installer/index.d.ts +0 -140
  167. package/dist/installer/instructions-template.d.ts +0 -30
  168. package/dist/installer/targets/claude.d.ts +0 -55
  169. package/dist/installer/targets/codex.d.ts +0 -18
  170. package/dist/installer/targets/cursor.d.ts +0 -35
  171. package/dist/installer/targets/hermes.d.ts +0 -18
  172. package/dist/installer/targets/opencode.d.ts +0 -30
  173. package/dist/installer/targets/registry.d.ts +0 -38
  174. package/dist/installer/targets/shared.d.ts +0 -92
  175. package/dist/installer/targets/toml.d.ts +0 -64
  176. package/dist/installer/targets/types.d.ts +0 -122
  177. package/dist/mcp/index.d.ts +0 -98
  178. package/dist/mcp/server-instructions.d.ts +0 -20
  179. package/dist/mcp/tools.d.ts +0 -269
  180. package/dist/mcp/transport.d.ts +0 -117
  181. package/dist/resolution/frameworks/cargo-workspace.d.ts +0 -20
  182. package/dist/resolution/frameworks/cargo-workspace.js +0 -225
  183. package/dist/resolution/frameworks/csharp.d.ts +0 -8
  184. package/dist/resolution/frameworks/csharp.js +0 -213
  185. package/dist/resolution/frameworks/drupal.d.ts +0 -51
  186. package/dist/resolution/frameworks/drupal.js +0 -335
  187. package/dist/resolution/frameworks/express.d.ts +0 -8
  188. package/dist/resolution/frameworks/express.js +0 -225
  189. package/dist/resolution/frameworks/go.d.ts +0 -8
  190. package/dist/resolution/frameworks/go.js +0 -158
  191. package/dist/resolution/frameworks/index.d.ts +0 -52
  192. package/dist/resolution/frameworks/index.js +0 -137
  193. package/dist/resolution/frameworks/java.d.ts +0 -8
  194. package/dist/resolution/frameworks/java.js +0 -177
  195. package/dist/resolution/frameworks/laravel.d.ts +0 -13
  196. package/dist/resolution/frameworks/laravel.js +0 -248
  197. package/dist/resolution/frameworks/nestjs.d.ts +0 -26
  198. package/dist/resolution/frameworks/nestjs.js +0 -374
  199. package/dist/resolution/frameworks/python.d.ts +0 -10
  200. package/dist/resolution/frameworks/python.js +0 -278
  201. package/dist/resolution/frameworks/react.d.ts +0 -8
  202. package/dist/resolution/frameworks/react.js +0 -272
  203. package/dist/resolution/frameworks/ruby.d.ts +0 -8
  204. package/dist/resolution/frameworks/ruby.js +0 -198
  205. package/dist/resolution/frameworks/rust.d.ts +0 -8
  206. package/dist/resolution/frameworks/rust.js +0 -207
  207. package/dist/resolution/frameworks/svelte.d.ts +0 -9
  208. package/dist/resolution/frameworks/svelte.js +0 -249
  209. package/dist/resolution/frameworks/swift.d.ts +0 -10
  210. package/dist/resolution/frameworks/swift.js +0 -376
  211. package/dist/resolution/frameworks/vue.d.ts +0 -9
  212. package/dist/resolution/frameworks/vue.js +0 -306
  213. package/dist/resolution/import-resolver.d.ts +0 -61
  214. package/dist/resolution/import-resolver.js +0 -663
  215. package/dist/resolution/index.d.ts +0 -118
  216. package/dist/resolution/index.js +0 -744
  217. package/dist/resolution/lru-cache.d.ts +0 -24
  218. package/dist/resolution/lru-cache.js +0 -62
  219. package/dist/resolution/name-matcher.d.ts +0 -50
  220. package/dist/resolution/name-matcher.js +0 -384
  221. package/dist/resolution/path-aliases.d.ts +0 -72
  222. package/dist/resolution/path-aliases.js +0 -238
  223. package/dist/resolution/strip-comments.d.ts +0 -40
  224. package/dist/resolution/strip-comments.js +0 -441
  225. package/dist/resolution/types.d.ts +0 -181
  226. package/dist/resolution/types.js +0 -8
  227. package/dist/search/query-parser.d.ts +0 -61
  228. package/dist/search/query-parser.js +0 -177
  229. package/dist/search/query-utils.d.ts +0 -59
  230. package/dist/search/query-utils.js +0 -383
  231. package/dist/sync/git-hooks.d.ts +0 -54
  232. package/dist/sync/git-hooks.js +0 -223
  233. package/dist/sync/index.d.ts +0 -25
  234. package/dist/sync/index.js +0 -28
  235. package/dist/sync/watch-policy.d.ts +0 -51
  236. package/dist/sync/watch-policy.js +0 -124
  237. package/dist/sync/watcher.d.ts +0 -83
  238. package/dist/sync/watcher.js +0 -192
  239. package/dist/types.d.ts +0 -433
  240. package/dist/types.js +0 -75
  241. package/dist/ui/glyphs.d.ts +0 -42
  242. package/dist/ui/shimmer-progress.d.ts +0 -11
  243. package/dist/ui/shimmer-worker.d.ts +0 -2
  244. package/dist/ui/types.d.ts +0 -20
  245. package/dist/utils.d.ts +0 -231
  246. package/dist/utils.js +0 -549
@@ -1,278 +0,0 @@
1
- "use strict";
2
- /**
3
- * Python Framework Resolver
4
- *
5
- * Handles Django, Flask, and FastAPI patterns.
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.fastapiResolver = exports.flaskResolver = exports.djangoResolver = void 0;
9
- const strip_comments_1 = require("../strip-comments");
10
- exports.djangoResolver = {
11
- name: 'django',
12
- languages: ['python'],
13
- detect(context) {
14
- const requirements = context.readFile('requirements.txt');
15
- if (requirements && requirements.toLowerCase().includes('django'))
16
- return true;
17
- const setup = context.readFile('setup.py');
18
- if (setup && setup.toLowerCase().includes('django'))
19
- return true;
20
- const pyproject = context.readFile('pyproject.toml');
21
- if (pyproject && pyproject.toLowerCase().includes('django'))
22
- return true;
23
- return context.fileExists('manage.py');
24
- },
25
- resolve(ref, context) {
26
- if (ref.referenceName.endsWith('Model') || /^[A-Z][a-z]+$/.test(ref.referenceName)) {
27
- const result = resolveByNameAndKind(ref.referenceName, CLASS_KINDS, MODEL_DIRS, context);
28
- if (result)
29
- return { original: ref, targetNodeId: result, confidence: 0.8, resolvedBy: 'framework' };
30
- }
31
- if (ref.referenceName.endsWith('View') || ref.referenceName.endsWith('ViewSet')) {
32
- const result = resolveByNameAndKind(ref.referenceName, VIEW_KINDS, VIEW_DIRS, context);
33
- if (result)
34
- return { original: ref, targetNodeId: result, confidence: 0.8, resolvedBy: 'framework' };
35
- }
36
- if (ref.referenceName.endsWith('Form')) {
37
- const result = resolveByNameAndKind(ref.referenceName, CLASS_KINDS, FORM_DIRS, context);
38
- if (result)
39
- return { original: ref, targetNodeId: result, confidence: 0.8, resolvedBy: 'framework' };
40
- }
41
- return null;
42
- },
43
- extract(filePath, content) {
44
- if (!filePath.endsWith('.py'))
45
- return { nodes: [], references: [] };
46
- const nodes = [];
47
- const references = [];
48
- const now = Date.now();
49
- const safe = (0, strip_comments_1.stripCommentsForRegex)(content, 'python');
50
- // path('url', handler, name=...) / re_path(r'...', handler) / url(r'...', handler)
51
- // Capture groups: 1=function name, 2=url string, 3=handler expr
52
- // Handler expr may contain one balanced () pair (e.g. View.as_view(), include('x.y'))
53
- const routeRegex = /\b(path|re_path|url)\s*\(\s*r?['"]([^'"]+)['"]\s*,\s*([\w.]+(?:\s*\([^)]*\))?)/g;
54
- let match;
55
- while ((match = routeRegex.exec(safe)) !== null) {
56
- const [, _fn, urlPath, handlerExpr] = match;
57
- const line = safe.slice(0, match.index).split('\n').length;
58
- const routeNode = {
59
- id: `route:${filePath}:${line}:${urlPath}`,
60
- kind: 'route',
61
- name: urlPath,
62
- qualifiedName: `${filePath}::route:${urlPath}`,
63
- filePath,
64
- startLine: line,
65
- endLine: line,
66
- startColumn: 0,
67
- endColumn: match[0].length,
68
- language: 'python',
69
- updatedAt: now,
70
- };
71
- nodes.push(routeNode);
72
- const handler = handlerExpr.trim();
73
- const target = resolveHandlerName(handler);
74
- if (target) {
75
- references.push({
76
- fromNodeId: routeNode.id,
77
- referenceName: target.name,
78
- referenceKind: target.kind,
79
- line,
80
- column: 0,
81
- filePath,
82
- language: 'python',
83
- });
84
- }
85
- }
86
- return { nodes, references };
87
- },
88
- };
89
- /**
90
- * Parse a Django URL handler expression and return the symbol/module to link.
91
- * Returns null for shapes we can't confidently link (e.g. lambdas).
92
- */
93
- function resolveHandlerName(expr) {
94
- // include('module.path')
95
- const includeMatch = expr.match(/^include\s*\(\s*['"]([^'"]+)['"]/);
96
- if (includeMatch)
97
- return { name: includeMatch[1], kind: 'imports' };
98
- // Strip trailing .as_view(...) or .as_view()
99
- let head = expr.replace(/\.as_view\s*\([^)]*\)\s*$/, '');
100
- // Drop any other trailing method call
101
- head = head.replace(/\.\w+\s*\([^)]*\)\s*$/, '');
102
- const dotted = head.split('.').filter(Boolean);
103
- if (dotted.length === 0)
104
- return null;
105
- const last = dotted[dotted.length - 1];
106
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(last))
107
- return null;
108
- return { name: last, kind: 'references' };
109
- }
110
- exports.flaskResolver = {
111
- name: 'flask',
112
- languages: ['python'],
113
- detect(context) {
114
- const requirements = context.readFile('requirements.txt');
115
- if (requirements && /\bflask\b/i.test(requirements))
116
- return true;
117
- const pyproject = context.readFile('pyproject.toml');
118
- if (pyproject && /\bflask\b/i.test(pyproject))
119
- return true;
120
- for (const file of ['app.py', 'application.py', 'main.py', '__init__.py']) {
121
- const content = context.readFile(file);
122
- if (content && content.includes('Flask(__name__)'))
123
- return true;
124
- }
125
- return false;
126
- },
127
- resolve(ref, context) {
128
- if (ref.referenceName.endsWith('_bp') || ref.referenceName.endsWith('_blueprint')) {
129
- const result = resolveByNameAndKind(ref.referenceName, VARIABLE_KINDS, [], context);
130
- if (result)
131
- return { original: ref, targetNodeId: result, confidence: 0.8, resolvedBy: 'framework' };
132
- }
133
- return null;
134
- },
135
- extract(filePath, content) {
136
- if (!filePath.endsWith('.py'))
137
- return { nodes: [], references: [] };
138
- return extractDecoratorRoutes(filePath, (0, strip_comments_1.stripCommentsForRegex)(content, 'python'), {
139
- // Flask: @x.route('/path', methods=[...])
140
- decoratorRegex: /@(\w+)\.route\s*\(\s*['"]([^'"]+)['"](?:\s*,\s*methods\s*=\s*\[([^\]]+)\])?\s*\)\s*\n\s*(?:async\s+)?def\s+(\w+)/g,
141
- defaultMethod: 'GET',
142
- methodFromGroup: 3,
143
- pathGroup: 2,
144
- handlerGroup: 4,
145
- language: 'python',
146
- });
147
- },
148
- };
149
- exports.fastapiResolver = {
150
- name: 'fastapi',
151
- languages: ['python'],
152
- detect(context) {
153
- const requirements = context.readFile('requirements.txt');
154
- if (requirements && /\bfastapi\b/i.test(requirements))
155
- return true;
156
- const pyproject = context.readFile('pyproject.toml');
157
- if (pyproject && /\bfastapi\b/i.test(pyproject))
158
- return true;
159
- for (const file of ['app.py', 'main.py', 'api.py']) {
160
- const content = context.readFile(file);
161
- if (content && content.includes('FastAPI('))
162
- return true;
163
- }
164
- return false;
165
- },
166
- resolve(ref, context) {
167
- if (ref.referenceName.endsWith('_router') || ref.referenceName === 'router') {
168
- const result = resolveByNameAndKind(ref.referenceName, VARIABLE_KINDS, ROUTER_DIRS, context);
169
- if (result)
170
- return { original: ref, targetNodeId: result, confidence: 0.8, resolvedBy: 'framework' };
171
- }
172
- if (ref.referenceName.startsWith('get_') || ref.referenceName.startsWith('Depends')) {
173
- const result = resolveByNameAndKind(ref.referenceName, FUNCTION_KINDS, DEP_DIRS, context);
174
- if (result)
175
- return { original: ref, targetNodeId: result, confidence: 0.75, resolvedBy: 'framework' };
176
- }
177
- return null;
178
- },
179
- extract(filePath, content) {
180
- if (!filePath.endsWith('.py'))
181
- return { nodes: [], references: [] };
182
- return extractDecoratorRoutes(filePath, (0, strip_comments_1.stripCommentsForRegex)(content, 'python'), {
183
- // FastAPI: @x.METHOD('/path') -> handler on the next def line
184
- decoratorRegex: /@(\w+)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"]([^'"]+)['"]/g,
185
- defaultMethod: '',
186
- methodGroup: 2,
187
- pathGroup: 3,
188
- findHandler: true,
189
- language: 'python',
190
- });
191
- },
192
- };
193
- function extractDecoratorRoutes(filePath, content, opts) {
194
- const nodes = [];
195
- const references = [];
196
- const now = Date.now();
197
- let match;
198
- while ((match = opts.decoratorRegex.exec(content)) !== null) {
199
- const routePath = match[opts.pathGroup];
200
- let method = opts.defaultMethod;
201
- if (opts.methodGroup && match[opts.methodGroup]) {
202
- method = match[opts.methodGroup].toUpperCase();
203
- }
204
- else if (opts.methodFromGroup && match[opts.methodFromGroup]) {
205
- const m = match[opts.methodFromGroup].match(/['"]([A-Z]+)['"]/i);
206
- if (m)
207
- method = m[1].toUpperCase();
208
- }
209
- const line = content.slice(0, match.index).split('\n').length;
210
- const name = method ? `${method} ${routePath}` : routePath;
211
- const routeNode = {
212
- id: `route:${filePath}:${line}:${method}:${routePath}`,
213
- kind: 'route',
214
- name,
215
- qualifiedName: `${filePath}::${method}:${routePath}`,
216
- filePath,
217
- startLine: line,
218
- endLine: line,
219
- startColumn: 0,
220
- endColumn: match[0].length,
221
- language: opts.language,
222
- updatedAt: now,
223
- };
224
- nodes.push(routeNode);
225
- let handlerName;
226
- if (opts.handlerGroup && match[opts.handlerGroup]) {
227
- handlerName = match[opts.handlerGroup];
228
- }
229
- else if (opts.findHandler) {
230
- const tail = content.slice(match.index + match[0].length);
231
- const defMatch = tail.match(/\n\s*(?:async\s+)?def\s+(\w+)/);
232
- if (defMatch)
233
- handlerName = defMatch[1];
234
- }
235
- if (handlerName) {
236
- references.push({
237
- fromNodeId: routeNode.id,
238
- referenceName: handlerName,
239
- referenceKind: 'references',
240
- line,
241
- column: 0,
242
- filePath,
243
- language: 'python',
244
- });
245
- }
246
- }
247
- return { nodes, references };
248
- }
249
- // Directory patterns
250
- const MODEL_DIRS = ['models', 'app/models', 'src/models'];
251
- const VIEW_DIRS = ['views', 'app/views', 'src/views', 'api/views'];
252
- const FORM_DIRS = ['forms', 'app/forms', 'src/forms'];
253
- const ROUTER_DIRS = ['/routers/', '/api/', '/routes/', '/endpoints/'];
254
- const DEP_DIRS = ['/dependencies/', '/deps/', '/core/'];
255
- const CLASS_KINDS = new Set(['class']);
256
- const VIEW_KINDS = new Set(['class', 'function']);
257
- const VARIABLE_KINDS = new Set(['variable']);
258
- const FUNCTION_KINDS = new Set(['function']);
259
- /**
260
- * Resolve a symbol by name using indexed queries instead of scanning all files.
261
- */
262
- function resolveByNameAndKind(name, kinds, preferredDirPatterns, context) {
263
- const candidates = context.getNodesByName(name);
264
- if (candidates.length === 0)
265
- return null;
266
- const kindFiltered = candidates.filter((n) => kinds.has(n.kind));
267
- if (kindFiltered.length === 0)
268
- return null;
269
- // Prefer candidates in framework-conventional directories
270
- if (preferredDirPatterns.length > 0) {
271
- const preferred = kindFiltered.filter((n) => preferredDirPatterns.some((d) => n.filePath.includes(d)));
272
- if (preferred.length > 0)
273
- return preferred[0].id;
274
- }
275
- // Fall back to any match
276
- return kindFiltered[0].id;
277
- }
278
- //# sourceMappingURL=python.js.map
@@ -1,8 +0,0 @@
1
- /**
2
- * React Framework Resolver
3
- *
4
- * Handles React and Next.js patterns.
5
- */
6
- import { FrameworkResolver } from '../types'
7
- export declare const reactResolver: FrameworkResolver
8
- //# sourceMappingURL=react.d.ts.map
@@ -1,272 +0,0 @@
1
- "use strict";
2
- /**
3
- * React Framework Resolver
4
- *
5
- * Handles React and Next.js patterns.
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.reactResolver = void 0;
9
- exports.reactResolver = {
10
- name: 'react',
11
- languages: ['javascript', 'typescript'],
12
- detect(context) {
13
- // Check for React in package.json
14
- const packageJson = context.readFile('package.json');
15
- if (packageJson) {
16
- try {
17
- const pkg = JSON.parse(packageJson);
18
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
19
- if (deps.react || deps.next || deps['react-native']) {
20
- return true;
21
- }
22
- }
23
- catch {
24
- // Invalid JSON
25
- }
26
- }
27
- // Check for .jsx/.tsx files
28
- const allFiles = context.getAllFiles();
29
- return allFiles.some((f) => f.endsWith('.jsx') || f.endsWith('.tsx'));
30
- },
31
- resolve(ref, context) {
32
- // Pattern 1: Component references (PascalCase)
33
- if (isPascalCase(ref.referenceName) && !isBuiltInType(ref.referenceName)) {
34
- const result = resolveComponent(ref.referenceName, ref.filePath, context);
35
- if (result) {
36
- return {
37
- original: ref,
38
- targetNodeId: result,
39
- confidence: 0.8,
40
- resolvedBy: 'framework',
41
- };
42
- }
43
- }
44
- // Pattern 2: Hook references (use*)
45
- if (ref.referenceName.startsWith('use') && ref.referenceName.length > 3) {
46
- const result = resolveHook(ref.referenceName, context);
47
- if (result) {
48
- return {
49
- original: ref,
50
- targetNodeId: result,
51
- confidence: 0.85,
52
- resolvedBy: 'framework',
53
- };
54
- }
55
- }
56
- // Pattern 3: Context references
57
- if (ref.referenceName.endsWith('Context') || ref.referenceName.endsWith('Provider')) {
58
- const result = resolveContext(ref.referenceName, context);
59
- if (result) {
60
- return {
61
- original: ref,
62
- targetNodeId: result,
63
- confidence: 0.8,
64
- resolvedBy: 'framework',
65
- };
66
- }
67
- }
68
- return null;
69
- },
70
- extract(filePath, content) {
71
- const nodes = [];
72
- const now = Date.now();
73
- // Extract component definitions
74
- // function Component() or const Component = () =>
75
- const componentPatterns = [
76
- // Function components
77
- /(?:export\s+)?function\s+([A-Z][a-zA-Z0-9]*)\s*\(/g,
78
- // Arrow function components
79
- /(?:export\s+)?(?:const|let)\s+([A-Z][a-zA-Z0-9]*)\s*=\s*(?:\([^)]*\)|[a-zA-Z_][a-zA-Z0-9_]*)\s*=>/g,
80
- // forwardRef components
81
- /(?:export\s+)?(?:const|let)\s+([A-Z][a-zA-Z0-9]*)\s*=\s*(?:React\.)?forwardRef/g,
82
- // memo components
83
- /(?:export\s+)?(?:const|let)\s+([A-Z][a-zA-Z0-9]*)\s*=\s*(?:React\.)?memo/g,
84
- ];
85
- for (const pattern of componentPatterns) {
86
- let match;
87
- while ((match = pattern.exec(content)) !== null) {
88
- const [fullMatch, name] = match;
89
- const line = content.slice(0, match.index).split('\n').length;
90
- // Check if it returns JSX (rough heuristic)
91
- const afterMatch = content.slice(match.index + fullMatch.length, match.index + fullMatch.length + 500);
92
- const hasJSX = afterMatch.includes('<') && (afterMatch.includes('/>') || afterMatch.includes('</'));
93
- if (hasJSX) {
94
- nodes.push({
95
- id: `component:${filePath}:${name}:${line}`,
96
- kind: 'component',
97
- name: name,
98
- qualifiedName: `${filePath}::${name}`,
99
- filePath,
100
- startLine: line,
101
- endLine: line,
102
- startColumn: 0,
103
- endColumn: fullMatch.length,
104
- language: filePath.endsWith('.tsx') ? 'tsx' : 'jsx',
105
- isExported: fullMatch.includes('export'),
106
- updatedAt: now,
107
- });
108
- }
109
- }
110
- }
111
- // Extract custom hooks
112
- const hookPattern = /(?:export\s+)?(?:function|const|let)\s+(use[A-Z][a-zA-Z0-9]*)\s*[=(]/g;
113
- let hookMatch;
114
- while ((hookMatch = hookPattern.exec(content)) !== null) {
115
- const [fullMatch, name] = hookMatch;
116
- const line = content.slice(0, hookMatch.index).split('\n').length;
117
- nodes.push({
118
- id: `hook:${filePath}:${name}:${line}`,
119
- kind: 'function',
120
- name: name,
121
- qualifiedName: `${filePath}::${name}`,
122
- filePath,
123
- startLine: line,
124
- endLine: line,
125
- startColumn: 0,
126
- endColumn: fullMatch.length,
127
- language: filePath.endsWith('.ts') || filePath.endsWith('.tsx') ? 'typescript' : 'javascript',
128
- isExported: fullMatch.includes('export'),
129
- updatedAt: now,
130
- });
131
- }
132
- // Extract Next.js pages/routes (pages directory convention)
133
- if (filePath.includes('pages/') || filePath.includes('app/')) {
134
- // Default export in pages becomes a route
135
- if (content.includes('export default')) {
136
- const routePath = filePathToRoute(filePath);
137
- if (routePath) {
138
- const line = content.indexOf('export default');
139
- const lineNum = content.slice(0, line).split('\n').length;
140
- nodes.push({
141
- id: `route:${filePath}:${routePath}:${lineNum}`,
142
- kind: 'route',
143
- name: routePath,
144
- qualifiedName: `${filePath}::route:${routePath}`,
145
- filePath,
146
- startLine: lineNum,
147
- endLine: lineNum,
148
- startColumn: 0,
149
- endColumn: 0,
150
- language: filePath.endsWith('.tsx') ? 'tsx' : filePath.endsWith('.ts') ? 'typescript' : 'javascript',
151
- updatedAt: now,
152
- });
153
- }
154
- }
155
- }
156
- return { nodes, references: [] };
157
- },
158
- };
159
- /**
160
- * Check if string is PascalCase
161
- */
162
- function isPascalCase(str) {
163
- return /^[A-Z][a-zA-Z0-9]*$/.test(str);
164
- }
165
- /**
166
- * Check if name is a built-in type
167
- */
168
- function isBuiltInType(name) {
169
- return BUILT_IN_TYPES.has(name);
170
- }
171
- const BUILT_IN_TYPES = new Set([
172
- 'Array', 'Boolean', 'Date', 'Error', 'Function', 'JSON', 'Math', 'Number',
173
- 'Object', 'Promise', 'RegExp', 'String', 'Symbol', 'Map', 'Set', 'WeakMap', 'WeakSet',
174
- 'React', 'Component', 'Fragment', 'Suspense', 'StrictMode',
175
- ]);
176
- const COMPONENT_KINDS = new Set(['component', 'function', 'class']);
177
- /**
178
- * Resolve a component reference using name-based lookup
179
- */
180
- function resolveComponent(name, fromFile, context) {
181
- const candidates = context.getNodesByName(name);
182
- if (candidates.length === 0)
183
- return null;
184
- const components = candidates.filter((n) => COMPONENT_KINDS.has(n.kind));
185
- if (components.length === 0)
186
- return null;
187
- // Prefer same directory
188
- const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));
189
- const sameDir = components.filter((n) => n.filePath.startsWith(fromDir));
190
- if (sameDir.length > 0)
191
- return sameDir[0].id;
192
- // Prefer component directories
193
- const COMPONENT_DIRS = ['/components/', '/src/components/', '/app/components/', '/pages/', '/src/pages/', '/views/', '/src/views/'];
194
- const preferred = components.filter((n) => COMPONENT_DIRS.some((d) => n.filePath.includes(d)));
195
- if (preferred.length > 0)
196
- return preferred[0].id;
197
- return components[0].id;
198
- }
199
- /**
200
- * Resolve a custom hook reference using name-based lookup
201
- */
202
- function resolveHook(name, context) {
203
- const candidates = context.getNodesByName(name);
204
- if (candidates.length === 0)
205
- return null;
206
- const hooks = candidates.filter((n) => n.kind === 'function' && n.name.startsWith('use'));
207
- if (hooks.length === 0)
208
- return null;
209
- // Prefer hooks directories
210
- const HOOK_DIRS = ['/hooks/', '/src/hooks/', '/lib/hooks/', '/utils/hooks/'];
211
- const preferred = hooks.filter((n) => HOOK_DIRS.some((d) => n.filePath.includes(d)));
212
- if (preferred.length > 0)
213
- return preferred[0].id;
214
- return hooks[0].id;
215
- }
216
- /**
217
- * Resolve a context reference using name-based lookup
218
- */
219
- function resolveContext(name, context) {
220
- const candidates = context.getNodesByName(name);
221
- if (candidates.length === 0) {
222
- // Try without Context/Provider suffix
223
- const baseName = name.replace(/Context$|Provider$/, '');
224
- if (baseName !== name) {
225
- const baseCandidates = context.getNodesByName(baseName);
226
- if (baseCandidates.length > 0)
227
- return baseCandidates[0].id;
228
- }
229
- return null;
230
- }
231
- // Prefer context directories
232
- const CONTEXT_DIRS = ['/context/', '/contexts/', '/src/context/', '/src/contexts/', '/providers/', '/src/providers/'];
233
- const preferred = candidates.filter((n) => CONTEXT_DIRS.some((d) => n.filePath.includes(d)));
234
- if (preferred.length > 0)
235
- return preferred[0].id;
236
- return candidates[0].id;
237
- }
238
- /**
239
- * Convert file path to Next.js route
240
- */
241
- function filePathToRoute(filePath) {
242
- // pages/index.tsx -> /
243
- // pages/about.tsx -> /about
244
- // pages/blog/[slug].tsx -> /blog/:slug
245
- // app/page.tsx -> /
246
- // app/about/page.tsx -> /about
247
- if (filePath.includes('pages/')) {
248
- let route = filePath
249
- .replace(/^.*pages\//, '/')
250
- .replace(/\/index\.(tsx?|jsx?)$/, '')
251
- .replace(/\.(tsx?|jsx?)$/, '')
252
- .replace(/\[([^\]]+)\]/g, ':$1');
253
- if (route === '')
254
- route = '/';
255
- return route;
256
- }
257
- if (filePath.includes('app/')) {
258
- // App router - only page.tsx files are routes
259
- if (!filePath.includes('page.')) {
260
- return null;
261
- }
262
- let route = filePath
263
- .replace(/^.*app\//, '/')
264
- .replace(/\/page\.(tsx?|jsx?)$/, '')
265
- .replace(/\[([^\]]+)\]/g, ':$1');
266
- if (route === '')
267
- route = '/';
268
- return route;
269
- }
270
- return null;
271
- }
272
- //# sourceMappingURL=react.js.map
@@ -1,8 +0,0 @@
1
- /**
2
- * Ruby Framework Resolver
3
- *
4
- * Handles Ruby on Rails patterns.
5
- */
6
- import { FrameworkResolver } from '../types'
7
- export declare const railsResolver: FrameworkResolver
8
- //# sourceMappingURL=ruby.d.ts.map