bluera-knowledge 0.9.32 → 0.9.34

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 (196) hide show
  1. package/.claude/hooks/post-edit-check.sh +5 -3
  2. package/.claude/skills/atomic-commits/SKILL.md +3 -1
  3. package/.husky/pre-commit +3 -2
  4. package/.prettierrc +9 -0
  5. package/.versionrc.json +1 -1
  6. package/CHANGELOG.md +33 -0
  7. package/CLAUDE.md +6 -0
  8. package/README.md +25 -13
  9. package/bun.lock +277 -33
  10. package/dist/{chunk-L2YVNC63.js → chunk-6FHWC36B.js} +9 -1
  11. package/dist/chunk-6FHWC36B.js.map +1 -0
  12. package/dist/{chunk-RST4XGRL.js → chunk-DC7CGSGT.js} +288 -241
  13. package/dist/chunk-DC7CGSGT.js.map +1 -0
  14. package/dist/{chunk-6PBP5DVD.js → chunk-WFNPNAAP.js} +3212 -3054
  15. package/dist/chunk-WFNPNAAP.js.map +1 -0
  16. package/dist/{chunk-WT2DAEO7.js → chunk-Z2KKVH45.js} +548 -482
  17. package/dist/chunk-Z2KKVH45.js.map +1 -0
  18. package/dist/index.js +871 -758
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp/server.js +3 -3
  21. package/dist/watch.service-BJV3TI3F.js +7 -0
  22. package/dist/workers/background-worker-cli.js +46 -45
  23. package/dist/workers/background-worker-cli.js.map +1 -1
  24. package/eslint.config.js +43 -1
  25. package/package.json +18 -11
  26. package/plugin.json +8 -0
  27. package/python/requirements.txt +1 -1
  28. package/src/analysis/ast-parser.test.ts +12 -11
  29. package/src/analysis/ast-parser.ts +28 -22
  30. package/src/analysis/code-graph.test.ts +52 -62
  31. package/src/analysis/code-graph.ts +9 -13
  32. package/src/analysis/dependency-usage-analyzer.test.ts +91 -271
  33. package/src/analysis/dependency-usage-analyzer.ts +52 -24
  34. package/src/analysis/go-ast-parser.test.ts +22 -22
  35. package/src/analysis/go-ast-parser.ts +18 -25
  36. package/src/analysis/parser-factory.test.ts +9 -9
  37. package/src/analysis/parser-factory.ts +3 -3
  38. package/src/analysis/python-ast-parser.test.ts +27 -27
  39. package/src/analysis/python-ast-parser.ts +2 -2
  40. package/src/analysis/repo-url-resolver.test.ts +82 -82
  41. package/src/analysis/rust-ast-parser.test.ts +19 -19
  42. package/src/analysis/rust-ast-parser.ts +17 -27
  43. package/src/analysis/tree-sitter-parser.test.ts +3 -3
  44. package/src/analysis/tree-sitter-parser.ts +10 -16
  45. package/src/cli/commands/crawl.test.ts +40 -24
  46. package/src/cli/commands/crawl.ts +186 -166
  47. package/src/cli/commands/index-cmd.test.ts +90 -90
  48. package/src/cli/commands/index-cmd.ts +52 -36
  49. package/src/cli/commands/mcp.test.ts +6 -6
  50. package/src/cli/commands/mcp.ts +2 -2
  51. package/src/cli/commands/plugin-api.test.ts +16 -18
  52. package/src/cli/commands/plugin-api.ts +9 -6
  53. package/src/cli/commands/search.test.ts +16 -7
  54. package/src/cli/commands/search.ts +124 -87
  55. package/src/cli/commands/serve.test.ts +67 -25
  56. package/src/cli/commands/serve.ts +18 -3
  57. package/src/cli/commands/setup.test.ts +176 -101
  58. package/src/cli/commands/setup.ts +140 -117
  59. package/src/cli/commands/store.test.ts +82 -53
  60. package/src/cli/commands/store.ts +56 -37
  61. package/src/cli/program.ts +2 -2
  62. package/src/crawl/article-converter.test.ts +4 -1
  63. package/src/crawl/article-converter.ts +46 -31
  64. package/src/crawl/bridge.test.ts +240 -132
  65. package/src/crawl/bridge.ts +87 -30
  66. package/src/crawl/claude-client.test.ts +124 -56
  67. package/src/crawl/claude-client.ts +7 -15
  68. package/src/crawl/intelligent-crawler.test.ts +65 -22
  69. package/src/crawl/intelligent-crawler.ts +86 -53
  70. package/src/crawl/markdown-utils.ts +1 -4
  71. package/src/db/embeddings.ts +4 -6
  72. package/src/db/lance.test.ts +4 -4
  73. package/src/db/lance.ts +16 -12
  74. package/src/index.ts +26 -17
  75. package/src/logging/index.ts +1 -5
  76. package/src/logging/logger.ts +3 -5
  77. package/src/logging/payload.test.ts +1 -1
  78. package/src/logging/payload.ts +3 -5
  79. package/src/mcp/commands/index.ts +2 -2
  80. package/src/mcp/commands/job.commands.ts +12 -18
  81. package/src/mcp/commands/meta.commands.ts +13 -13
  82. package/src/mcp/commands/registry.ts +5 -8
  83. package/src/mcp/commands/store.commands.ts +19 -19
  84. package/src/mcp/handlers/execute.handler.test.ts +10 -10
  85. package/src/mcp/handlers/execute.handler.ts +4 -5
  86. package/src/mcp/handlers/index.ts +10 -14
  87. package/src/mcp/handlers/job.handler.test.ts +10 -10
  88. package/src/mcp/handlers/job.handler.ts +22 -25
  89. package/src/mcp/handlers/search.handler.test.ts +36 -65
  90. package/src/mcp/handlers/search.handler.ts +135 -104
  91. package/src/mcp/handlers/store.handler.test.ts +41 -52
  92. package/src/mcp/handlers/store.handler.ts +108 -88
  93. package/src/mcp/schemas/index.test.ts +73 -68
  94. package/src/mcp/schemas/index.ts +18 -12
  95. package/src/mcp/server.test.ts +1 -1
  96. package/src/mcp/server.ts +59 -46
  97. package/src/plugin/commands.test.ts +230 -95
  98. package/src/plugin/commands.ts +24 -25
  99. package/src/plugin/dependency-analyzer.test.ts +52 -52
  100. package/src/plugin/dependency-analyzer.ts +85 -22
  101. package/src/plugin/git-clone.test.ts +24 -13
  102. package/src/plugin/git-clone.ts +3 -7
  103. package/src/server/app.test.ts +109 -109
  104. package/src/server/app.ts +32 -23
  105. package/src/server/index.test.ts +64 -66
  106. package/src/services/chunking.service.test.ts +32 -32
  107. package/src/services/chunking.service.ts +16 -9
  108. package/src/services/code-graph.service.test.ts +30 -36
  109. package/src/services/code-graph.service.ts +24 -10
  110. package/src/services/code-unit.service.test.ts +55 -11
  111. package/src/services/code-unit.service.ts +85 -11
  112. package/src/services/config.service.test.ts +37 -18
  113. package/src/services/config.service.ts +30 -7
  114. package/src/services/index.service.test.ts +49 -18
  115. package/src/services/index.service.ts +98 -48
  116. package/src/services/index.ts +6 -9
  117. package/src/services/job.service.test.ts +22 -22
  118. package/src/services/job.service.ts +18 -18
  119. package/src/services/project-root.service.test.ts +1 -3
  120. package/src/services/search.service.test.ts +248 -120
  121. package/src/services/search.service.ts +286 -156
  122. package/src/services/services.test.ts +1 -1
  123. package/src/services/snippet.service.test.ts +14 -6
  124. package/src/services/snippet.service.ts +7 -5
  125. package/src/services/store.service.test.ts +68 -29
  126. package/src/services/store.service.ts +41 -12
  127. package/src/services/watch.service.test.ts +34 -14
  128. package/src/services/watch.service.ts +11 -1
  129. package/src/types/brands.test.ts +3 -1
  130. package/src/types/index.ts +2 -13
  131. package/src/types/search.ts +10 -8
  132. package/src/utils/type-guards.test.ts +20 -15
  133. package/src/utils/type-guards.ts +1 -1
  134. package/src/workers/background-worker-cli.ts +2 -2
  135. package/src/workers/background-worker.test.ts +54 -40
  136. package/src/workers/background-worker.ts +76 -60
  137. package/src/workers/spawn-worker.test.ts +22 -10
  138. package/src/workers/spawn-worker.ts +6 -6
  139. package/tests/analysis/ast-parser.test.ts +3 -3
  140. package/tests/analysis/code-graph.test.ts +5 -5
  141. package/tests/fixtures/code-snippets/api/error-handling.ts +4 -15
  142. package/tests/fixtures/code-snippets/api/rest-controller.ts +3 -9
  143. package/tests/fixtures/code-snippets/auth/jwt-auth.ts +5 -21
  144. package/tests/fixtures/code-snippets/auth/oauth-flow.ts +4 -4
  145. package/tests/fixtures/code-snippets/database/repository-pattern.ts +11 -3
  146. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +2 -2
  147. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +1 -1
  148. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +2 -2
  149. package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +2 -2
  150. package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +22 -20
  151. package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +13 -10
  152. package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +10 -7
  153. package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +2 -2
  154. package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +1 -1
  155. package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +16 -16
  156. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +2 -2
  157. package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +3 -3
  158. package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +1 -1
  159. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +2 -2
  160. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +1 -1
  161. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +7 -7
  162. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +3 -3
  163. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +1 -1
  164. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +6 -6
  165. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +3 -3
  166. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +1 -1
  167. package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +1 -1
  168. package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +1 -1
  169. package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +2 -2
  170. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +4 -4
  171. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +1 -1
  172. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +1 -1
  173. package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +166 -169
  174. package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +8 -8
  175. package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +3 -3
  176. package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +2 -2
  177. package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +2 -2
  178. package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +30 -33
  179. package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +2 -2
  180. package/tests/fixtures/test-server.ts +3 -2
  181. package/tests/helpers/performance-metrics.ts +8 -25
  182. package/tests/helpers/search-relevance.ts +14 -69
  183. package/tests/integration/cli-consistency.test.ts +5 -4
  184. package/tests/integration/python-bridge.test.ts +13 -3
  185. package/tests/mcp/server.test.ts +1 -1
  186. package/tests/services/code-unit.service.test.ts +48 -0
  187. package/tests/services/job.service.test.ts +124 -0
  188. package/tests/services/search.progressive-context.test.ts +2 -2
  189. package/.claude-plugin/plugin.json +0 -13
  190. package/dist/chunk-6PBP5DVD.js.map +0 -1
  191. package/dist/chunk-L2YVNC63.js.map +0 -1
  192. package/dist/chunk-RST4XGRL.js.map +0 -1
  193. package/dist/chunk-WT2DAEO7.js.map +0 -1
  194. package/dist/watch.service-YAIKKDCF.js +0 -7
  195. package/skills/atomic-commits/SKILL.md +0 -77
  196. /package/dist/{watch.service-YAIKKDCF.js.map → watch.service-BJV3TI3F.js.map} +0 -0
@@ -1,5 +1,5 @@
1
- import type { PythonBridge, ParsePythonResult } from '../crawl/bridge.js';
2
1
  import type { CodeNode } from './ast-parser.js';
2
+ import type { PythonBridge, ParsePythonResult } from '../crawl/bridge.js';
3
3
 
4
4
  export class PythonASTParser {
5
5
  constructor(private readonly bridge: PythonBridge) {}
@@ -7,7 +7,7 @@ export class PythonASTParser {
7
7
  async parse(code: string, filePath: string): Promise<CodeNode[]> {
8
8
  const result: ParsePythonResult = await this.bridge.parsePython(code, filePath);
9
9
 
10
- return result.nodes.map(node => {
10
+ return result.nodes.map((node) => {
11
11
  const codeNode: CodeNode = {
12
12
  type: node.type,
13
13
  name: node.name,
@@ -21,9 +21,9 @@ describe('RepoUrlResolver', () => {
21
21
  json: async () => ({
22
22
  repository: {
23
23
  type: 'git',
24
- url: 'git+https://github.com/lodash/lodash.git'
25
- }
26
- })
24
+ url: 'git+https://github.com/lodash/lodash.git',
25
+ },
26
+ }),
27
27
  } as Response);
28
28
 
29
29
  const result = await resolver.findRepoUrl('lodash', 'javascript');
@@ -37,8 +37,8 @@ describe('RepoUrlResolver', () => {
37
37
  vi.mocked(fetch).mockResolvedValueOnce({
38
38
  ok: true,
39
39
  json: async () => ({
40
- repository: 'https://github.com/user/repo'
41
- })
40
+ repository: 'https://github.com/user/repo',
41
+ }),
42
42
  } as Response);
43
43
 
44
44
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -50,7 +50,7 @@ describe('RepoUrlResolver', () => {
50
50
  it('handles 404 from npm registry', async () => {
51
51
  vi.mocked(fetch).mockResolvedValueOnce({
52
52
  ok: false,
53
- status: 404
53
+ status: 404,
54
54
  } as Response);
55
55
 
56
56
  const result = await resolver.findRepoUrl('nonexistent', 'javascript');
@@ -73,7 +73,7 @@ describe('RepoUrlResolver', () => {
73
73
  ok: true,
74
74
  json: async () => {
75
75
  throw new Error('Invalid JSON');
76
- }
76
+ },
77
77
  } as Response);
78
78
 
79
79
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -86,8 +86,8 @@ describe('RepoUrlResolver', () => {
86
86
  ok: true,
87
87
  json: async () => ({
88
88
  name: 'package',
89
- version: '1.0.0'
90
- })
89
+ version: '1.0.0',
90
+ }),
91
91
  } as Response);
92
92
 
93
93
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -103,10 +103,10 @@ describe('RepoUrlResolver', () => {
103
103
  json: async () => ({
104
104
  info: {
105
105
  project_urls: {
106
- Source: 'https://github.com/psf/requests'
107
- }
108
- }
109
- })
106
+ Source: 'https://github.com/psf/requests',
107
+ },
108
+ },
109
+ }),
110
110
  } as Response);
111
111
 
112
112
  const result = await resolver.findRepoUrl('requests', 'python');
@@ -123,10 +123,10 @@ describe('RepoUrlResolver', () => {
123
123
  info: {
124
124
  project_urls: {
125
125
  Homepage: 'https://example.com',
126
- Repository: 'https://github.com/user/repo'
127
- }
128
- }
129
- })
126
+ Repository: 'https://github.com/user/repo',
127
+ },
128
+ },
129
+ }),
130
130
  } as Response);
131
131
 
132
132
  const result = await resolver.findRepoUrl('package', 'python');
@@ -141,10 +141,10 @@ describe('RepoUrlResolver', () => {
141
141
  info: {
142
142
  project_urls: {
143
143
  Source: 'https://github.com/owner/repo1',
144
- Code: 'https://github.com/owner/repo2'
145
- }
146
- }
147
- })
144
+ Code: 'https://github.com/owner/repo2',
145
+ },
146
+ },
147
+ }),
148
148
  } as Response);
149
149
 
150
150
  const result = await resolver.findRepoUrl('package', 'python');
@@ -158,10 +158,10 @@ describe('RepoUrlResolver', () => {
158
158
  json: async () => ({
159
159
  info: {
160
160
  project_urls: {
161
- Source: 'https://gitlab.com/user/repo'
162
- }
163
- }
164
- })
161
+ Source: 'https://gitlab.com/user/repo',
162
+ },
163
+ },
164
+ }),
165
165
  } as Response);
166
166
 
167
167
  const result = await resolver.findRepoUrl('package', 'python');
@@ -172,7 +172,7 @@ describe('RepoUrlResolver', () => {
172
172
  it('handles 404 from PyPI', async () => {
173
173
  vi.mocked(fetch).mockResolvedValueOnce({
174
174
  ok: false,
175
- status: 404
175
+ status: 404,
176
176
  } as Response);
177
177
 
178
178
  const result = await resolver.findRepoUrl('nonexistent', 'python');
@@ -185,9 +185,9 @@ describe('RepoUrlResolver', () => {
185
185
  ok: true,
186
186
  json: async () => ({
187
187
  info: {
188
- name: 'package'
189
- }
190
- })
188
+ name: 'package',
189
+ },
190
+ }),
191
191
  } as Response);
192
192
 
193
193
  const result = await resolver.findRepoUrl('package', 'python');
@@ -202,9 +202,9 @@ describe('RepoUrlResolver', () => {
202
202
  ok: true,
203
203
  json: async () => ({
204
204
  repository: {
205
- url: 'git+https://github.com/user/repo.git'
206
- }
207
- })
205
+ url: 'git+https://github.com/user/repo.git',
206
+ },
207
+ }),
208
208
  } as Response);
209
209
 
210
210
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -217,9 +217,9 @@ describe('RepoUrlResolver', () => {
217
217
  ok: true,
218
218
  json: async () => ({
219
219
  repository: {
220
- url: 'https://github.com/user/repo.git'
221
- }
222
- })
220
+ url: 'https://github.com/user/repo.git',
221
+ },
222
+ }),
223
223
  } as Response);
224
224
 
225
225
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -232,9 +232,9 @@ describe('RepoUrlResolver', () => {
232
232
  ok: true,
233
233
  json: async () => ({
234
234
  repository: {
235
- url: 'git://github.com/user/repo.git'
236
- }
237
- })
235
+ url: 'git://github.com/user/repo.git',
236
+ },
237
+ }),
238
238
  } as Response);
239
239
 
240
240
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -247,9 +247,9 @@ describe('RepoUrlResolver', () => {
247
247
  ok: true,
248
248
  json: async () => ({
249
249
  repository: {
250
- url: 'ssh://git@github.com/user/repo.git'
251
- }
252
- })
250
+ url: 'ssh://git@github.com/user/repo.git',
251
+ },
252
+ }),
253
253
  } as Response);
254
254
 
255
255
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -262,9 +262,9 @@ describe('RepoUrlResolver', () => {
262
262
  ok: true,
263
263
  json: async () => ({
264
264
  repository: {
265
- url: 'git@github.com:user/repo.git'
266
- }
267
- })
265
+ url: 'git@github.com:user/repo.git',
266
+ },
267
+ }),
268
268
  } as Response);
269
269
 
270
270
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -277,9 +277,9 @@ describe('RepoUrlResolver', () => {
277
277
  ok: true,
278
278
  json: async () => ({
279
279
  repository: {
280
- url: 'https://bitbucket.org/user/repo'
281
- }
282
- })
280
+ url: 'https://bitbucket.org/user/repo',
281
+ },
282
+ }),
283
283
  } as Response);
284
284
 
285
285
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -292,9 +292,9 @@ describe('RepoUrlResolver', () => {
292
292
  ok: true,
293
293
  json: async () => ({
294
294
  repository: {
295
- url: 'https://github.com/user/repo'
296
- }
297
- })
295
+ url: 'https://github.com/user/repo',
296
+ },
297
+ }),
298
298
  } as Response);
299
299
 
300
300
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -309,9 +309,9 @@ describe('RepoUrlResolver', () => {
309
309
  ok: true,
310
310
  json: async () => ({
311
311
  crate: {
312
- repository: 'https://github.com/serde-rs/serde'
313
- }
314
- })
312
+ repository: 'https://github.com/serde-rs/serde',
313
+ },
314
+ }),
315
315
  } as Response);
316
316
 
317
317
  const result = await resolver.findRepoUrl('serde', 'rust');
@@ -326,9 +326,9 @@ describe('RepoUrlResolver', () => {
326
326
  ok: true,
327
327
  json: async () => ({
328
328
  crate: {
329
- repository: 'https://github.com/user/repo'
330
- }
331
- })
329
+ repository: 'https://github.com/user/repo',
330
+ },
331
+ }),
332
332
  } as Response);
333
333
 
334
334
  await resolver.findRepoUrl('tokio', 'rust');
@@ -337,8 +337,8 @@ describe('RepoUrlResolver', () => {
337
337
  'https://crates.io/api/v1/crates/tokio',
338
338
  expect.objectContaining({
339
339
  headers: expect.objectContaining({
340
- 'User-Agent': expect.stringContaining('bluera-knowledge')
341
- })
340
+ 'User-Agent': expect.stringContaining('bluera-knowledge'),
341
+ }),
342
342
  })
343
343
  );
344
344
  });
@@ -346,7 +346,7 @@ describe('RepoUrlResolver', () => {
346
346
  it('handles 404 from crates.io', async () => {
347
347
  vi.mocked(fetch).mockResolvedValueOnce({
348
348
  ok: false,
349
- status: 404
349
+ status: 404,
350
350
  } as Response);
351
351
 
352
352
  const result = await resolver.findRepoUrl('nonexistent-crate', 'rust');
@@ -361,9 +361,9 @@ describe('RepoUrlResolver', () => {
361
361
  json: async () => ({
362
362
  crate: {
363
363
  name: 'some-crate',
364
- version: '1.0.0'
365
- }
366
- })
364
+ version: '1.0.0',
365
+ },
366
+ }),
367
367
  } as Response);
368
368
 
369
369
  const result = await resolver.findRepoUrl('some-crate', 'rust');
@@ -376,9 +376,9 @@ describe('RepoUrlResolver', () => {
376
376
  ok: true,
377
377
  json: async () => ({
378
378
  crate: {
379
- repository: 'git+https://github.com/user/repo.git'
380
- }
381
- })
379
+ repository: 'git+https://github.com/user/repo.git',
380
+ },
381
+ }),
382
382
  } as Response);
383
383
 
384
384
  const result = await resolver.findRepoUrl('crate', 'rust');
@@ -415,7 +415,7 @@ describe('RepoUrlResolver', () => {
415
415
  it('returns null for non-github modules when proxy fails', async () => {
416
416
  vi.mocked(fetch).mockResolvedValueOnce({
417
417
  ok: false,
418
- status: 404
418
+ status: 404,
419
419
  } as Response);
420
420
 
421
421
  const result = await resolver.findRepoUrl('golang.org/x/net', 'go');
@@ -438,9 +438,9 @@ describe('RepoUrlResolver', () => {
438
438
  ok: true,
439
439
  json: async () => ({
440
440
  repository: {
441
- url: 'https://github.com/org/package'
442
- }
443
- })
441
+ url: 'https://github.com/org/package',
442
+ },
443
+ }),
444
444
  } as Response);
445
445
 
446
446
  const result = await resolver.findRepoUrl('@org/package', 'javascript');
@@ -454,9 +454,9 @@ describe('RepoUrlResolver', () => {
454
454
  ok: true,
455
455
  json: async () => ({
456
456
  repository: {
457
- url: 'https://github.com/user/my-package'
458
- }
459
- })
457
+ url: 'https://github.com/user/my-package',
458
+ },
459
+ }),
460
460
  } as Response);
461
461
 
462
462
  const result = await resolver.findRepoUrl('my-package', 'javascript');
@@ -467,7 +467,7 @@ describe('RepoUrlResolver', () => {
467
467
  it('handles empty response body', async () => {
468
468
  vi.mocked(fetch).mockResolvedValueOnce({
469
469
  ok: true,
470
- json: async () => null
470
+ json: async () => null,
471
471
  } as Response);
472
472
 
473
473
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -479,8 +479,8 @@ describe('RepoUrlResolver', () => {
479
479
  vi.mocked(fetch).mockResolvedValueOnce({
480
480
  ok: true,
481
481
  json: async () => ({
482
- repository: []
483
- })
482
+ repository: [],
483
+ }),
484
484
  } as Response);
485
485
 
486
486
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -493,9 +493,9 @@ describe('RepoUrlResolver', () => {
493
493
  ok: true,
494
494
  json: async () => ({
495
495
  repository: {
496
- url: null
497
- }
498
- })
496
+ url: null,
497
+ },
498
+ }),
499
499
  } as Response);
500
500
 
501
501
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -508,9 +508,9 @@ describe('RepoUrlResolver', () => {
508
508
  ok: true,
509
509
  json: async () => ({
510
510
  repository: {
511
- url: undefined
512
- }
513
- })
511
+ url: undefined,
512
+ },
513
+ }),
514
514
  } as Response);
515
515
 
516
516
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -521,7 +521,7 @@ describe('RepoUrlResolver', () => {
521
521
  it('uses fallback when all strategies fail', async () => {
522
522
  vi.mocked(fetch).mockResolvedValueOnce({
523
523
  ok: false,
524
- status: 500
524
+ status: 500,
525
525
  } as Response);
526
526
 
527
527
  const result = await resolver.findRepoUrl('package', 'javascript');
@@ -14,7 +14,7 @@ describe('RustASTParser', () => {
14
14
  type: 'function',
15
15
  name: 'hello',
16
16
  exported: false,
17
- async: false
17
+ async: false,
18
18
  });
19
19
  expect(nodes[0]?.signature).toContain('hello');
20
20
  });
@@ -81,9 +81,9 @@ pub fn third() -> i32 { 3 }
81
81
  `.trim();
82
82
  const nodes = parser.parse(code, 'test.rs');
83
83
 
84
- const functions = nodes.filter(n => n.type === 'function');
84
+ const functions = nodes.filter((n) => n.type === 'function');
85
85
  expect(functions).toHaveLength(3);
86
- expect(functions.map(f => f.name)).toEqual(['first', 'second', 'third']);
86
+ expect(functions.map((f) => f.name)).toEqual(['first', 'second', 'third']);
87
87
  expect(functions[2]?.exported).toBe(true);
88
88
  });
89
89
  });
@@ -97,7 +97,7 @@ pub fn third() -> i32 { 3 }
97
97
  expect(nodes[0]).toMatchObject({
98
98
  type: 'class',
99
99
  name: 'User',
100
- exported: false
100
+ exported: false,
101
101
  });
102
102
  });
103
103
 
@@ -157,7 +157,7 @@ struct Data {
157
157
  expect(nodes[0]).toMatchObject({
158
158
  type: 'interface',
159
159
  name: 'Drawable',
160
- exported: false
160
+ exported: false,
161
161
  });
162
162
  expect(nodes[0]?.methods).toBeDefined();
163
163
  });
@@ -210,7 +210,7 @@ trait Animal {
210
210
  expect(nodes[0]).toMatchObject({
211
211
  type: 'type',
212
212
  name: 'Result',
213
- exported: false
213
+ exported: false,
214
214
  });
215
215
  expect(nodes[0]?.signature).toContain('Result');
216
216
  });
@@ -240,7 +240,7 @@ trait Animal {
240
240
  expect(nodes[0]).toMatchObject({
241
241
  type: 'const',
242
242
  name: 'MAX_SIZE',
243
- exported: false
243
+ exported: false,
244
244
  });
245
245
  expect(nodes[0]?.signature).toContain('usize');
246
246
  });
@@ -259,7 +259,7 @@ trait Animal {
259
259
 
260
260
  expect(nodes[0]).toMatchObject({
261
261
  type: 'const',
262
- name: 'COUNTER'
262
+ name: 'COUNTER',
263
263
  });
264
264
  });
265
265
 
@@ -289,7 +289,7 @@ impl User {
289
289
  `.trim();
290
290
  const nodes = parser.parse(code, 'test.rs');
291
291
 
292
- const userStruct = nodes.find(n => n.name === 'User');
292
+ const userStruct = nodes.find((n) => n.name === 'User');
293
293
  expect(userStruct).toBeDefined();
294
294
  expect(userStruct?.methods).toHaveLength(2);
295
295
  expect(userStruct?.methods?.[0]?.name).toBe('new');
@@ -308,7 +308,7 @@ impl Service {
308
308
  `.trim();
309
309
  const nodes = parser.parse(code, 'test.rs');
310
310
 
311
- const service = nodes.find(n => n.name === 'Service');
311
+ const service = nodes.find((n) => n.name === 'Service');
312
312
  expect(service?.methods?.[0]?.async).toBe(true);
313
313
  });
314
314
 
@@ -326,7 +326,7 @@ impl Drawable for Circle {
326
326
  const nodes = parser.parse(code, 'test.rs');
327
327
 
328
328
  // Trait impl methods shouldn't attach to struct
329
- const circle = nodes.find(n => n.name === 'Circle');
329
+ const circle = nodes.find((n) => n.name === 'Circle');
330
330
  expect(circle).toBeDefined();
331
331
  });
332
332
 
@@ -344,7 +344,7 @@ impl Data {
344
344
  `.trim();
345
345
  const nodes = parser.parse(code, 'test.rs');
346
346
 
347
- const data = nodes.find(n => n.name === 'Data');
347
+ const data = nodes.find((n) => n.name === 'Data');
348
348
  expect(data?.methods).toHaveLength(2);
349
349
  });
350
350
  });
@@ -358,7 +358,7 @@ impl Data {
358
358
  expect(imports[0]).toMatchObject({
359
359
  source: 'std::collections',
360
360
  specifiers: ['HashMap'],
361
- isType: false
361
+ isType: false,
362
362
  });
363
363
  });
364
364
 
@@ -490,10 +490,10 @@ trait Handler {
490
490
 
491
491
  expect(nodes.length).toBeGreaterThan(0);
492
492
 
493
- const structs = nodes.filter(n => n.type === 'class');
494
- const functions = nodes.filter(n => n.type === 'function');
495
- const traits = nodes.filter(n => n.type === 'interface');
496
- const constants = nodes.filter(n => n.type === 'const');
493
+ const structs = nodes.filter((n) => n.type === 'class');
494
+ const functions = nodes.filter((n) => n.type === 'function');
495
+ const traits = nodes.filter((n) => n.type === 'interface');
496
+ const constants = nodes.filter((n) => n.type === 'const');
497
497
 
498
498
  expect(structs).toHaveLength(1);
499
499
  expect(functions).toHaveLength(1);
@@ -539,7 +539,7 @@ impl Test {
539
539
  `.trim();
540
540
  const nodes = parser.parse(code, 'test.rs');
541
541
 
542
- const test = nodes.find(n => n.name === 'Test');
542
+ const test = nodes.find((n) => n.name === 'Test');
543
543
  const method = test?.methods?.[0];
544
544
 
545
545
  expect(method?.startLine).toBe(4);
@@ -558,7 +558,7 @@ impl Service {
558
558
  `.trim();
559
559
  const nodes = parser.parse(code, 'test.rs');
560
560
 
561
- const service = nodes.find(n => n.name === 'Service');
561
+ const service = nodes.find((n) => n.name === 'Service');
562
562
  const method = service?.methods?.[0];
563
563
 
564
564
  expect(method?.signature).toContain('process');
@@ -1,4 +1,3 @@
1
- import type { CodeNode, ImportInfo } from './ast-parser.js';
2
1
  import {
3
2
  parseRustCode,
4
3
  queryNodesByType,
@@ -9,8 +8,9 @@ import {
9
8
  getFunctionSignature,
10
9
  extractImportPath,
11
10
  type TreeSitterNode,
12
- type TreeSitterTree
11
+ type TreeSitterTree,
13
12
  } from './tree-sitter-parser.js';
13
+ import type { CodeNode, ImportInfo } from './ast-parser.js';
14
14
 
15
15
  /**
16
16
  * Parser for Rust code using tree-sitter
@@ -90,7 +90,7 @@ export class RustASTParser {
90
90
  imports.push({
91
91
  source,
92
92
  specifiers,
93
- isType: false // Rust doesn't distinguish type-only imports at syntax level
93
+ isType: false, // Rust doesn't distinguish type-only imports at syntax level
94
94
  });
95
95
  }
96
96
 
@@ -132,7 +132,7 @@ export class RustASTParser {
132
132
  async,
133
133
  startLine,
134
134
  endLine,
135
- signature
135
+ signature,
136
136
  });
137
137
  }
138
138
 
@@ -173,9 +173,7 @@ export class RustASTParser {
173
173
 
174
174
  // Get type parameters (generics) if present
175
175
  const typeParamsNode = getChildByFieldName(structNode, 'type_parameters');
176
- const signature = typeParamsNode !== null
177
- ? `${name}${typeParamsNode.text}`
178
- : name;
176
+ const signature = typeParamsNode !== null ? `${name}${typeParamsNode.text}` : name;
179
177
 
180
178
  nodes.push({
181
179
  type: 'class',
@@ -184,7 +182,7 @@ export class RustASTParser {
184
182
  startLine,
185
183
  endLine,
186
184
  signature,
187
- methods: [] // Will be populated by parseImplBlocks
185
+ methods: [], // Will be populated by parseImplBlocks
188
186
  });
189
187
  }
190
188
 
@@ -211,9 +209,7 @@ export class RustASTParser {
211
209
 
212
210
  // Get type parameters (generics) if present
213
211
  const typeParamsNode = getChildByFieldName(traitNode, 'type_parameters');
214
- const signature = typeParamsNode !== null
215
- ? `${name}${typeParamsNode.text}`
216
- : name;
212
+ const signature = typeParamsNode !== null ? `${name}${typeParamsNode.text}` : name;
217
213
 
218
214
  // Extract trait methods
219
215
  const methods = this.extractTraitMethods(traitNode);
@@ -225,7 +221,7 @@ export class RustASTParser {
225
221
  startLine,
226
222
  endLine,
227
223
  signature,
228
- methods
224
+ methods,
229
225
  });
230
226
  }
231
227
 
@@ -252,9 +248,7 @@ export class RustASTParser {
252
248
 
253
249
  // Get the full type alias definition
254
250
  const valueNode = getChildByFieldName(typeNode, 'type');
255
- const signature = valueNode !== null
256
- ? `${name} = ${valueNode.text}`
257
- : name;
251
+ const signature = valueNode !== null ? `${name} = ${valueNode.text}` : name;
258
252
 
259
253
  nodes.push({
260
254
  type: 'type',
@@ -262,7 +256,7 @@ export class RustASTParser {
262
256
  exported,
263
257
  startLine,
264
258
  endLine,
265
- signature
259
+ signature,
266
260
  });
267
261
  }
268
262
 
@@ -289,9 +283,7 @@ export class RustASTParser {
289
283
 
290
284
  // Get type annotation
291
285
  const typeNode = getChildByFieldName(constNode, 'type');
292
- const signature = typeNode !== null
293
- ? `${name}: ${typeNode.text}`
294
- : name;
286
+ const signature = typeNode !== null ? `${name}: ${typeNode.text}` : name;
295
287
 
296
288
  nodes.push({
297
289
  type: 'const',
@@ -299,7 +291,7 @@ export class RustASTParser {
299
291
  exported,
300
292
  startLine,
301
293
  endLine,
302
- signature
294
+ signature,
303
295
  });
304
296
  }
305
297
 
@@ -325,11 +317,9 @@ export class RustASTParser {
325
317
  const methods = this.extractImplMethods(implNode);
326
318
 
327
319
  // Find the corresponding struct and attach methods
328
- const structNode = nodes.find(
329
- node => node.type === 'class' && node.name === typeName
330
- );
320
+ const structNode = nodes.find((node) => node.type === 'class' && node.name === typeName);
331
321
 
332
- if (structNode !== undefined && structNode.methods !== undefined) {
322
+ if (structNode?.methods !== undefined) {
333
323
  structNode.methods.push(...methods);
334
324
  }
335
325
  }
@@ -379,7 +369,7 @@ export class RustASTParser {
379
369
  async,
380
370
  signature,
381
371
  startLine,
382
- endLine
372
+ endLine,
383
373
  });
384
374
  }
385
375
 
@@ -430,7 +420,7 @@ export class RustASTParser {
430
420
  async,
431
421
  signature,
432
422
  startLine,
433
- endLine
423
+ endLine,
434
424
  });
435
425
  }
436
426
 
@@ -459,7 +449,7 @@ export class RustASTParser {
459
449
  if (scopedMatch !== null) {
460
450
  const source = scopedMatch[1] ?? '';
461
451
  const specifiersStr = scopedMatch[2] ?? '';
462
- const specifiers = specifiersStr.split(',').map(s => s.trim());
452
+ const specifiers = specifiersStr.split(',').map((s) => s.trim());
463
453
  return { source, specifiers };
464
454
  }
465
455