bluera-knowledge 0.9.32 → 0.9.36

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 (198) 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 +70 -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 +97 -71
  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 +28 -30
  135. package/src/workers/background-worker.test.ts +54 -40
  136. package/src/workers/background-worker.ts +76 -60
  137. package/src/workers/pid-file.test.ts +167 -0
  138. package/src/workers/pid-file.ts +82 -0
  139. package/src/workers/spawn-worker.test.ts +22 -10
  140. package/src/workers/spawn-worker.ts +6 -6
  141. package/tests/analysis/ast-parser.test.ts +3 -3
  142. package/tests/analysis/code-graph.test.ts +5 -5
  143. package/tests/fixtures/code-snippets/api/error-handling.ts +4 -15
  144. package/tests/fixtures/code-snippets/api/rest-controller.ts +3 -9
  145. package/tests/fixtures/code-snippets/auth/jwt-auth.ts +5 -21
  146. package/tests/fixtures/code-snippets/auth/oauth-flow.ts +4 -4
  147. package/tests/fixtures/code-snippets/database/repository-pattern.ts +11 -3
  148. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +2 -2
  149. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +1 -1
  150. package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +2 -2
  151. package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +2 -2
  152. package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +22 -20
  153. package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +13 -10
  154. package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +10 -7
  155. package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +2 -2
  156. package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +1 -1
  157. package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +16 -16
  158. package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +2 -2
  159. package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +3 -3
  160. package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +1 -1
  161. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +2 -2
  162. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +1 -1
  163. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +7 -7
  164. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +3 -3
  165. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +1 -1
  166. package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +6 -6
  167. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +3 -3
  168. package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +1 -1
  169. package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +1 -1
  170. package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +1 -1
  171. package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +2 -2
  172. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +4 -4
  173. package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +1 -1
  174. package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +1 -1
  175. package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +166 -169
  176. package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +8 -8
  177. package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +3 -3
  178. package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +2 -2
  179. package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +2 -2
  180. package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +30 -33
  181. package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +2 -2
  182. package/tests/fixtures/test-server.ts +3 -2
  183. package/tests/helpers/performance-metrics.ts +8 -25
  184. package/tests/helpers/search-relevance.ts +14 -69
  185. package/tests/integration/cli-consistency.test.ts +6 -5
  186. package/tests/integration/python-bridge.test.ts +13 -3
  187. package/tests/mcp/server.test.ts +1 -1
  188. package/tests/services/code-unit.service.test.ts +48 -0
  189. package/tests/services/job.service.test.ts +124 -0
  190. package/tests/services/search.progressive-context.test.ts +2 -2
  191. package/.claude-plugin/plugin.json +0 -13
  192. package/dist/chunk-6PBP5DVD.js.map +0 -1
  193. package/dist/chunk-L2YVNC63.js.map +0 -1
  194. package/dist/chunk-RST4XGRL.js.map +0 -1
  195. package/dist/chunk-WT2DAEO7.js.map +0 -1
  196. package/dist/watch.service-YAIKKDCF.js +0 -7
  197. package/skills/atomic-commits/SKILL.md +0 -77
  198. /package/dist/{watch.service-YAIKKDCF.js.map → watch.service-BJV3TI3F.js.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { parse, type ParserPlugin } from '@babel/parser';
2
- import type { NodePath } from '@babel/traverse';
3
2
  import traverseModule from '@babel/traverse';
4
3
  import * as t from '@babel/types';
4
+ import type { NodePath } from '@babel/traverse';
5
5
 
6
6
  // Handle both ESM and CJS module formats
7
7
  type TraverseFunction = (ast: t.File, visitor: Record<string, unknown>) => void;
@@ -55,7 +55,7 @@ export class ASTParser {
55
55
 
56
56
  const ast = parse(code, {
57
57
  sourceType: 'module',
58
- plugins
58
+ plugins,
59
59
  });
60
60
 
61
61
  const nodes: CodeNode[] = [];
@@ -65,8 +65,9 @@ export class ASTParser {
65
65
  const node = path.node;
66
66
  if (!node.id) return;
67
67
 
68
- const exported = path.parent.type === 'ExportNamedDeclaration' ||
69
- path.parent.type === 'ExportDefaultDeclaration';
68
+ const exported =
69
+ path.parent.type === 'ExportNamedDeclaration' ||
70
+ path.parent.type === 'ExportDefaultDeclaration';
70
71
 
71
72
  nodes.push({
72
73
  type: 'function',
@@ -75,7 +76,7 @@ export class ASTParser {
75
76
  async: node.async,
76
77
  startLine: node.loc?.start.line ?? 0,
77
78
  endLine: node.loc?.end.line ?? 0,
78
- signature: this.extractFunctionSignature(node)
79
+ signature: this.extractFunctionSignature(node),
79
80
  });
80
81
  },
81
82
 
@@ -83,8 +84,9 @@ export class ASTParser {
83
84
  const node = path.node;
84
85
  if (!node.id) return;
85
86
 
86
- const exported = path.parent.type === 'ExportNamedDeclaration' ||
87
- path.parent.type === 'ExportDefaultDeclaration';
87
+ const exported =
88
+ path.parent.type === 'ExportNamedDeclaration' ||
89
+ path.parent.type === 'ExportDefaultDeclaration';
88
90
 
89
91
  const methods: CodeNode['methods'] = [];
90
92
 
@@ -95,7 +97,7 @@ export class ASTParser {
95
97
  async: member.async,
96
98
  signature: this.extractMethodSignature(member),
97
99
  startLine: member.loc?.start.line ?? 0,
98
- endLine: member.loc?.end.line ?? 0
100
+ endLine: member.loc?.end.line ?? 0,
99
101
  });
100
102
  }
101
103
  }
@@ -106,7 +108,7 @@ export class ASTParser {
106
108
  exported,
107
109
  startLine: node.loc?.start.line ?? 0,
108
110
  endLine: node.loc?.end.line ?? 0,
109
- methods
111
+ methods,
110
112
  });
111
113
  },
112
114
 
@@ -120,9 +122,9 @@ export class ASTParser {
120
122
  name: node.id.name,
121
123
  exported,
122
124
  startLine: node.loc?.start.line ?? 0,
123
- endLine: node.loc?.end.line ?? 0
125
+ endLine: node.loc?.end.line ?? 0,
124
126
  });
125
- }
127
+ },
126
128
  });
127
129
 
128
130
  return nodes;
@@ -136,7 +138,7 @@ export class ASTParser {
136
138
  try {
137
139
  const ast = parse(code, {
138
140
  sourceType: 'module',
139
- plugins: ['typescript', 'jsx']
141
+ plugins: ['typescript', 'jsx'],
140
142
  });
141
143
 
142
144
  const imports: ImportInfo[] = [];
@@ -159,9 +161,9 @@ export class ASTParser {
159
161
  imports.push({
160
162
  source: node.source.value,
161
163
  specifiers,
162
- isType: node.importKind === 'type'
164
+ isType: node.importKind === 'type',
163
165
  });
164
- }
166
+ },
165
167
  });
166
168
 
167
169
  return imports;
@@ -172,19 +174,23 @@ export class ASTParser {
172
174
  }
173
175
 
174
176
  private extractFunctionSignature(node: t.FunctionDeclaration): string {
175
- const params = node.params.map(p => {
176
- if (t.isIdentifier(p)) return p.name;
177
- return 'param';
178
- }).join(', ');
177
+ const params = node.params
178
+ .map((p) => {
179
+ if (t.isIdentifier(p)) return p.name;
180
+ return 'param';
181
+ })
182
+ .join(', ');
179
183
 
180
184
  return `${node.id?.name ?? 'anonymous'}(${params})`;
181
185
  }
182
186
 
183
187
  private extractMethodSignature(node: t.ClassMethod): string {
184
- const params = node.params.map(p => {
185
- if (t.isIdentifier(p)) return p.name;
186
- return 'param';
187
- }).join(', ');
188
+ const params = node.params
189
+ .map((p) => {
190
+ if (t.isIdentifier(p)) return p.name;
191
+ return 'param';
192
+ })
193
+ .join(', ');
188
194
 
189
195
  const name = t.isIdentifier(node.key) ? node.key.name : 'method';
190
196
  return `${name}(${params})`;
@@ -13,8 +13,8 @@ describe('CodeGraph', () => {
13
13
  exported: true,
14
14
  startLine: 1,
15
15
  endLine: 5,
16
- signature: 'testFn()'
17
- }
16
+ signature: 'testFn()',
17
+ },
18
18
  ];
19
19
 
20
20
  graph.addNodes(nodes, '/src/test.ts');
@@ -33,8 +33,8 @@ describe('CodeGraph', () => {
33
33
  name: 'shared',
34
34
  exported: false,
35
35
  startLine: 1,
36
- endLine: 3
37
- }
36
+ endLine: 3,
37
+ },
38
38
  ];
39
39
 
40
40
  graph.addNodes(nodes, '/src/file1.ts');
@@ -57,8 +57,8 @@ describe('CodeGraph', () => {
57
57
  exported: true,
58
58
  startLine: 1,
59
59
  endLine: 3,
60
- signature: 'add(a, b)'
61
- }
60
+ signature: 'add(a, b)',
61
+ },
62
62
  ];
63
63
 
64
64
  graph.addNodes(nodes, '/src/math.ts');
@@ -75,8 +75,8 @@ describe('CodeGraph', () => {
75
75
  name: 'User',
76
76
  exported: true,
77
77
  startLine: 1,
78
- endLine: 3
79
- }
78
+ endLine: 3,
79
+ },
80
80
  ];
81
81
 
82
82
  graph.addNodes(nodes, '/src/types.ts');
@@ -93,22 +93,22 @@ describe('CodeGraph', () => {
93
93
  name: 'fn1',
94
94
  exported: false,
95
95
  startLine: 1,
96
- endLine: 2
96
+ endLine: 2,
97
97
  },
98
98
  {
99
99
  type: 'function',
100
100
  name: 'fn2',
101
101
  exported: false,
102
102
  startLine: 3,
103
- endLine: 4
104
- }
103
+ endLine: 4,
104
+ },
105
105
  ];
106
106
 
107
107
  graph.addNodes(nodes, '/src/test.ts');
108
108
  const allNodes = graph.getAllNodes();
109
109
 
110
110
  expect(allNodes).toHaveLength(2);
111
- expect(allNodes.map(n => n.name)).toEqual(['fn1', 'fn2']);
111
+ expect(allNodes.map((n) => n.name)).toEqual(['fn1', 'fn2']);
112
112
  });
113
113
 
114
114
  it('returns undefined for non-existent node', () => {
@@ -195,15 +195,15 @@ describe('CodeGraph', () => {
195
195
  name: 'caller',
196
196
  exported: false,
197
197
  startLine: 1,
198
- endLine: 3
198
+ endLine: 3,
199
199
  },
200
200
  {
201
201
  type: 'function',
202
202
  name: 'helper',
203
203
  exported: false,
204
204
  startLine: 5,
205
- endLine: 7
206
- }
205
+ endLine: 7,
206
+ },
207
207
  ];
208
208
 
209
209
  graph.addNodes(nodes, '/src/test.ts');
@@ -216,7 +216,7 @@ describe('CodeGraph', () => {
216
216
  graph.analyzeCallRelationships(code, '/src/test.ts', 'caller');
217
217
  const edges = graph.getEdges('/src/test.ts:caller');
218
218
 
219
- const helperCall = edges.find(e => e.to === '/src/test.ts:helper');
219
+ const helperCall = edges.find((e) => e.to === '/src/test.ts:helper');
220
220
  expect(helperCall).toBeDefined();
221
221
  expect(helperCall?.type).toBe('calls');
222
222
  });
@@ -229,8 +229,8 @@ describe('CodeGraph', () => {
229
229
  name: 'test',
230
230
  exported: false,
231
231
  startLine: 1,
232
- endLine: 3
233
- }
232
+ endLine: 3,
233
+ },
234
234
  ];
235
235
 
236
236
  graph.addNodes(nodes, '/src/test.ts');
@@ -247,7 +247,7 @@ describe('CodeGraph', () => {
247
247
  graph.analyzeCallRelationships('unknownFunction();', '/src/test.ts', 'caller');
248
248
  const edges = graph.getEdges('/src/test.ts:caller');
249
249
 
250
- const unknownCall = edges.find(e => e.to === 'unknown:unknownFunction');
250
+ const unknownCall = edges.find((e) => e.to === 'unknown:unknownFunction');
251
251
  expect(unknownCall).toBeDefined();
252
252
  expect(unknownCall?.confidence).toBe(0.5);
253
253
  });
@@ -290,8 +290,8 @@ describe('CodeGraph', () => {
290
290
  name: 'test',
291
291
  exported: true,
292
292
  startLine: 1,
293
- endLine: 3
294
- }
293
+ endLine: 3,
294
+ },
295
295
  ];
296
296
 
297
297
  graph.addNodes(nodes, '/src/test.ts');
@@ -313,8 +313,8 @@ describe('CodeGraph', () => {
313
313
  name: 'fn',
314
314
  exported: false,
315
315
  startLine: 1,
316
- endLine: 2
317
- }
316
+ endLine: 2,
317
+ },
318
318
  ];
319
319
 
320
320
  graph.addNodes(nodes, '/src/test.ts');
@@ -323,7 +323,7 @@ describe('CodeGraph', () => {
323
323
 
324
324
  const json = graph.toJSON();
325
325
 
326
- const edgeTypes = json.edges.map(e => e.type);
326
+ const edgeTypes = json.edges.map((e) => e.type);
327
327
  expect(edgeTypes).toContain('imports');
328
328
  expect(edgeTypes).toContain('calls');
329
329
  });
@@ -341,11 +341,7 @@ describe('CodeGraph', () => {
341
341
  it('handles deeply nested relative imports', () => {
342
342
  const graph = new CodeGraph();
343
343
 
344
- graph.addImport(
345
- '/src/very/deep/nested/component.ts',
346
- '../../../root',
347
- ['config']
348
- );
344
+ graph.addImport('/src/very/deep/nested/component.ts', '../../../root', ['config']);
349
345
  const edges = graph.getEdges('/src/very/deep/nested/component.ts');
350
346
 
351
347
  expect(edges[0]?.to).toBe('/src/root:config');
@@ -386,7 +382,7 @@ describe('CodeGraph', () => {
386
382
  const nodes: CodeNode[] = [
387
383
  { type: 'function', name: 'caller1', exported: false, startLine: 1, endLine: 2 },
388
384
  { type: 'function', name: 'caller2', exported: false, startLine: 3, endLine: 4 },
389
- { type: 'function', name: 'target', exported: false, startLine: 5, endLine: 6 }
385
+ { type: 'function', name: 'target', exported: false, startLine: 5, endLine: 6 },
390
386
  ];
391
387
 
392
388
  graph.addNodes(nodes, '/src/test.ts');
@@ -398,14 +394,14 @@ describe('CodeGraph', () => {
398
394
  const incoming = graph.getIncomingEdges('/src/test.ts:target');
399
395
 
400
396
  expect(incoming).toHaveLength(2);
401
- expect(incoming.every(e => e.to === '/src/test.ts:target')).toBe(true);
402
- expect(incoming.every(e => e.type === 'calls')).toBe(true);
397
+ expect(incoming.every((e) => e.to === '/src/test.ts:target')).toBe(true);
398
+ expect(incoming.every((e) => e.type === 'calls')).toBe(true);
403
399
  });
404
400
 
405
401
  it('returns empty array for node with no incoming edges', () => {
406
402
  const graph = new CodeGraph();
407
403
  const nodes: CodeNode[] = [
408
- { type: 'function', name: 'isolated', exported: false, startLine: 1, endLine: 2 }
404
+ { type: 'function', name: 'isolated', exported: false, startLine: 1, endLine: 2 },
409
405
  ];
410
406
 
411
407
  graph.addNodes(nodes, '/src/test.ts');
@@ -420,7 +416,7 @@ describe('CodeGraph', () => {
420
416
  { type: 'function', name: 'fn1', exported: false, startLine: 1, endLine: 2 },
421
417
  { type: 'function', name: 'fn2', exported: false, startLine: 3, endLine: 4 },
422
418
  { type: 'function', name: 'fn3', exported: false, startLine: 5, endLine: 6 },
423
- { type: 'function', name: 'utility', exported: false, startLine: 7, endLine: 8 }
419
+ { type: 'function', name: 'utility', exported: false, startLine: 7, endLine: 8 },
424
420
  ];
425
421
 
426
422
  graph.addNodes(nodes, '/src/test.ts');
@@ -445,7 +441,7 @@ describe('CodeGraph', () => {
445
441
  const nodes: CodeNode[] = [
446
442
  { type: 'function', name: 'main', exported: false, startLine: 1, endLine: 10 },
447
443
  { type: 'function', name: 'helper1', exported: false, startLine: 11, endLine: 15 },
448
- { type: 'function', name: 'helper2', exported: false, startLine: 16, endLine: 20 }
444
+ { type: 'function', name: 'helper2', exported: false, startLine: 16, endLine: 20 },
449
445
  ];
450
446
 
451
447
  graph.addNodes(nodes, '/src/test.ts');
@@ -461,7 +457,7 @@ describe('CodeGraph', () => {
461
457
  it('returns 0 for calls when function makes no calls', () => {
462
458
  const graph = new CodeGraph();
463
459
  const nodes: CodeNode[] = [
464
- { type: 'function', name: 'leaf', exported: false, startLine: 1, endLine: 2 }
460
+ { type: 'function', name: 'leaf', exported: false, startLine: 1, endLine: 2 },
465
461
  ];
466
462
 
467
463
  graph.addNodes(nodes, '/src/test.ts');
@@ -474,7 +470,7 @@ describe('CodeGraph', () => {
474
470
  it('distinguishes between call edges and import edges in calledBy count', () => {
475
471
  const graph = new CodeGraph();
476
472
  const nodes: CodeNode[] = [
477
- { type: 'function', name: 'target', exported: true, startLine: 1, endLine: 2 }
473
+ { type: 'function', name: 'target', exported: true, startLine: 1, endLine: 2 },
478
474
  ];
479
475
 
480
476
  graph.addNodes(nodes, '/src/test.ts');
@@ -502,9 +498,9 @@ describe('CodeGraph', () => {
502
498
  endLine: 20,
503
499
  methods: [
504
500
  { name: 'search', async: true, signature: 'search(query: string): Promise<Result>' },
505
- { name: 'update', async: false, signature: 'update(id: string): void' }
506
- ]
507
- }
501
+ { name: 'update', async: false, signature: 'update(id: string): void' },
502
+ ],
503
+ },
508
504
  ];
509
505
 
510
506
  graph.addNodes(nodes, '/src/service.ts');
@@ -538,17 +534,15 @@ describe('CodeGraph', () => {
538
534
  exported: true,
539
535
  startLine: 1,
540
536
  endLine: 10,
541
- methods: [
542
- { name: 'search', async: true, signature: 'search(): Promise<void>' }
543
- ]
537
+ methods: [{ name: 'search', async: true, signature: 'search(): Promise<void>' }],
544
538
  },
545
539
  {
546
540
  type: 'function',
547
541
  name: 'handleSearch',
548
542
  exported: false,
549
543
  startLine: 12,
550
- endLine: 15
551
- }
544
+ endLine: 15,
545
+ },
552
546
  ];
553
547
 
554
548
  graph.addNodes(nodes, '/src/test.ts');
@@ -571,24 +565,22 @@ describe('CodeGraph', () => {
571
565
  exported: true,
572
566
  startLine: 1,
573
567
  endLine: 20,
574
- methods: [
575
- { name: 'main', async: true, signature: 'main(): Promise<void>' }
576
- ]
568
+ methods: [{ name: 'main', async: true, signature: 'main(): Promise<void>' }],
577
569
  },
578
570
  {
579
571
  type: 'function',
580
572
  name: 'helper1',
581
573
  exported: false,
582
574
  startLine: 22,
583
- endLine: 24
575
+ endLine: 24,
584
576
  },
585
577
  {
586
578
  type: 'function',
587
579
  name: 'helper2',
588
580
  exported: false,
589
581
  startLine: 26,
590
- endLine: 28
591
- }
582
+ endLine: 28,
583
+ },
592
584
  ];
593
585
 
594
586
  graph.addNodes(nodes, '/src/test.ts');
@@ -610,8 +602,8 @@ describe('CodeGraph', () => {
610
602
  exported: false,
611
603
  startLine: 1,
612
604
  endLine: 2,
613
- methods: []
614
- }
605
+ methods: [],
606
+ },
615
607
  ];
616
608
 
617
609
  graph.addNodes(nodes, '/src/test.ts');
@@ -630,10 +622,8 @@ describe('CodeGraph', () => {
630
622
  exported: true,
631
623
  startLine: 1,
632
624
  endLine: 10,
633
- methods: [
634
- { name: 'method1', async: true, signature: 'method1(): Promise<void>' }
635
- ]
636
- }
625
+ methods: [{ name: 'method1', async: true, signature: 'method1(): Promise<void>' }],
626
+ },
637
627
  ];
638
628
 
639
629
  graph.addNodes(nodes, '/src/test.ts');
@@ -644,7 +634,7 @@ describe('CodeGraph', () => {
644
634
 
645
635
  // Deserialize would happen in CodeGraphService.loadGraph
646
636
  // Just verify the JSON structure is correct
647
- const methodNode = json.nodes.find(n => n.id.includes('method1'));
637
+ const methodNode = json.nodes.find((n) => n.id.includes('method1'));
648
638
  expect(methodNode).toBeDefined();
649
639
  expect(methodNode?.type).toBe('method');
650
640
  });
@@ -655,10 +645,10 @@ describe('CodeGraph', () => {
655
645
  const graph = new CodeGraph();
656
646
 
657
647
  const file1Nodes: CodeNode[] = [
658
- { type: 'function', name: 'fn1', exported: true, startLine: 1, endLine: 2 }
648
+ { type: 'function', name: 'fn1', exported: true, startLine: 1, endLine: 2 },
659
649
  ];
660
650
  const file2Nodes: CodeNode[] = [
661
- { type: 'function', name: 'fn2', exported: true, startLine: 1, endLine: 2 }
651
+ { type: 'function', name: 'fn2', exported: true, startLine: 1, endLine: 2 },
662
652
  ];
663
653
 
664
654
  graph.addNodes(file1Nodes, '/src/file1.ts');
@@ -669,7 +659,7 @@ describe('CodeGraph', () => {
669
659
  const file2Edges = graph.getEdges('/src/file2.ts');
670
660
 
671
661
  expect(allNodes).toHaveLength(2);
672
- expect(file2Edges.some(e => e.to.includes('fn1'))).toBe(true);
662
+ expect(file2Edges.some((e) => e.to.includes('fn1'))).toBe(true);
673
663
  });
674
664
 
675
665
  it('handles circular import detection', () => {
@@ -692,7 +682,7 @@ describe('CodeGraph', () => {
692
682
  const edges = graph.getEdges('/src/app.ts');
693
683
 
694
684
  expect(edges).toHaveLength(3);
695
- expect(edges.every(e => e.from === '/src/app.ts')).toBe(true);
685
+ expect(edges.every((e) => e.from === '/src/app.ts')).toBe(true);
696
686
  });
697
687
  });
698
688
  });
@@ -33,7 +33,7 @@ export class CodeGraph {
33
33
  name: node.name,
34
34
  exported: node.exported,
35
35
  startLine: node.startLine,
36
- endLine: node.endLine
36
+ endLine: node.endLine,
37
37
  };
38
38
 
39
39
  if (node.signature !== undefined) {
@@ -60,7 +60,7 @@ export class CodeGraph {
60
60
  exported: node.exported, // Methods inherit export status from class
61
61
  startLine: method.startLine,
62
62
  endLine: method.endLine,
63
- signature: method.signature
63
+ signature: method.signature,
64
64
  };
65
65
 
66
66
  this.nodes.set(methodId, methodNode);
@@ -83,7 +83,7 @@ export class CodeGraph {
83
83
  from: fromFile,
84
84
  to: `${resolvedTo}:${spec}`,
85
85
  type: 'imports',
86
- confidence: 1.0
86
+ confidence: 1.0,
87
87
  };
88
88
 
89
89
  const edges = this.edges.get(fromFile) ?? [];
@@ -117,7 +117,7 @@ export class CodeGraph {
117
117
  from: nodeId,
118
118
  to: targetNode.id,
119
119
  type: 'calls',
120
- confidence: 0.8 // Lower confidence for regex-based detection
120
+ confidence: 0.8, // Lower confidence for regex-based detection
121
121
  });
122
122
  } else {
123
123
  // Unknown function, possibly from import
@@ -125,7 +125,7 @@ export class CodeGraph {
125
125
  from: nodeId,
126
126
  to: `unknown:${calledFunction}`,
127
127
  type: 'calls',
128
- confidence: 0.5
128
+ confidence: 0.5,
129
129
  });
130
130
  }
131
131
  }
@@ -181,18 +181,14 @@ export class CodeGraph {
181
181
  * Count how many nodes call this node
182
182
  */
183
183
  getCalledByCount(nodeId: string): number {
184
- return this.getIncomingEdges(nodeId)
185
- .filter(e => e.type === 'calls')
186
- .length;
184
+ return this.getIncomingEdges(nodeId).filter((e) => e.type === 'calls').length;
187
185
  }
188
186
 
189
187
  /**
190
188
  * Count how many nodes this node calls
191
189
  */
192
190
  getCallsCount(nodeId: string): number {
193
- return this.getEdges(nodeId)
194
- .filter(e => e.type === 'calls')
195
- .length;
191
+ return this.getEdges(nodeId).filter((e) => e.type === 'calls').length;
196
192
  }
197
193
 
198
194
  getAllNodes(): GraphNode[] {
@@ -220,7 +216,7 @@ export class CodeGraph {
220
216
  if (part === '..') {
221
217
  resolved = resolved.split('/').slice(0, -1).join('/');
222
218
  } else if (part !== '.') {
223
- resolved += '/' + part;
219
+ resolved += `/${part}`;
224
220
  }
225
221
  }
226
222
 
@@ -239,7 +235,7 @@ export class CodeGraph {
239
235
 
240
236
  return {
241
237
  nodes: Array.from(this.nodes.values()),
242
- edges: allEdges.map(e => ({ from: e.from, to: e.to, type: e.type }))
238
+ edges: allEdges.map((e) => ({ from: e.from, to: e.to, type: e.type })),
243
239
  };
244
240
  }
245
241
  }