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
@@ -4,7 +4,7 @@ import {
4
4
  handleGetStoreInfo,
5
5
  handleCreateStore,
6
6
  handleIndexStore,
7
- handleDeleteStore
7
+ handleDeleteStore,
8
8
  } from './store.handler.js';
9
9
  import type { HandlerContext } from '../types.js';
10
10
  import type {
@@ -12,7 +12,7 @@ import type {
12
12
  GetStoreInfoArgs,
13
13
  CreateStoreArgs,
14
14
  IndexStoreArgs,
15
- DeleteStoreArgs
15
+ DeleteStoreArgs,
16
16
  } from '../schemas/index.js';
17
17
  import { StoreService } from '../../services/store.service.js';
18
18
  import { mkdtempSync, rmSync, writeFileSync } from 'fs';
@@ -21,7 +21,7 @@ import { tmpdir } from 'os';
21
21
 
22
22
  // Mock the worker spawn function
23
23
  vi.mock('../../workers/spawn-worker.js', () => ({
24
- spawnBackgroundWorker: vi.fn()
24
+ spawnBackgroundWorker: vi.fn(),
25
25
  }));
26
26
 
27
27
  import { spawnBackgroundWorker } from '../../workers/spawn-worker.js';
@@ -40,10 +40,10 @@ describe('store.handler', () => {
40
40
  services: {
41
41
  store: storeService,
42
42
  lance: {
43
- deleteStore: vi.fn().mockResolvedValue(undefined)
44
- }
43
+ deleteStore: vi.fn().mockResolvedValue(undefined),
44
+ },
45
45
  } as any,
46
- options: { dataDir: tempDir }
46
+ options: { dataDir: tempDir },
47
47
  };
48
48
 
49
49
  mockSpawnBackgroundWorker.mockClear();
@@ -63,13 +63,13 @@ describe('store.handler', () => {
63
63
  name: 'store1',
64
64
  type: 'file',
65
65
  path: path1,
66
- description: 'Test store 1'
66
+ description: 'Test store 1',
67
67
  });
68
68
  await storeService.create({
69
69
  name: 'store2',
70
70
  type: 'file',
71
71
  path: path2,
72
- description: 'Test store 2'
72
+ description: 'Test store 2',
73
73
  });
74
74
 
75
75
  const args: ListStoresArgs = {};
@@ -88,13 +88,13 @@ describe('store.handler', () => {
88
88
  name: 'file-store',
89
89
  type: 'file',
90
90
  path: tempDir,
91
- description: 'File store'
91
+ description: 'File store',
92
92
  });
93
93
  await storeService.create({
94
94
  name: 'repo-store',
95
95
  type: 'repo',
96
96
  url: 'https://github.com/test/repo',
97
- description: 'Repo store'
97
+ description: 'Repo store',
98
98
  });
99
99
 
100
100
  const args: ListStoresArgs = { type: 'file' };
@@ -110,7 +110,7 @@ describe('store.handler', () => {
110
110
  name: 'test-store',
111
111
  type: 'file',
112
112
  path: tempDir,
113
- description: 'Test description'
113
+ description: 'Test description',
114
114
  });
115
115
 
116
116
  const args: ListStoresArgs = {};
@@ -132,7 +132,7 @@ describe('store.handler', () => {
132
132
  name: 'test-store',
133
133
  type: 'file',
134
134
  path: tempDir,
135
- description: 'Test store'
135
+ description: 'Test store',
136
136
  });
137
137
 
138
138
  const args: GetStoreInfoArgs = { store: createResult.data.id };
@@ -148,7 +148,7 @@ describe('store.handler', () => {
148
148
  name: 'test-store',
149
149
  type: 'file',
150
150
  path: tempDir,
151
- description: 'Test store'
151
+ description: 'Test store',
152
152
  });
153
153
 
154
154
  const args: GetStoreInfoArgs = { store: 'test-store' };
@@ -163,7 +163,7 @@ describe('store.handler', () => {
163
163
  name: 'file-store',
164
164
  type: 'file',
165
165
  path: tempDir,
166
- description: 'Test description'
166
+ description: 'Test description',
167
167
  });
168
168
 
169
169
  const args: GetStoreInfoArgs = { store: 'file-store' };
@@ -183,9 +183,9 @@ describe('store.handler', () => {
183
183
  it('should throw if store not found', async () => {
184
184
  const args: GetStoreInfoArgs = { store: 'nonexistent' };
185
185
 
186
- await expect(
187
- handleGetStoreInfo(args, mockContext)
188
- ).rejects.toThrow('Store not found: nonexistent');
186
+ await expect(handleGetStoreInfo(args, mockContext)).rejects.toThrow(
187
+ 'Store not found: nonexistent'
188
+ );
189
189
  });
190
190
  });
191
191
 
@@ -198,7 +198,7 @@ describe('store.handler', () => {
198
198
  name: 'new-store',
199
199
  type: 'file',
200
200
  source: sourcePath,
201
- description: 'New test store'
201
+ description: 'New test store',
202
202
  };
203
203
 
204
204
  const result = await handleCreateStore(args, mockContext);
@@ -219,16 +219,13 @@ describe('store.handler', () => {
219
219
  const args: CreateStoreArgs = {
220
220
  name: 'worker-test',
221
221
  type: 'file',
222
- source: sourcePath
222
+ source: sourcePath,
223
223
  };
224
224
 
225
225
  const result = await handleCreateStore(args, mockContext);
226
226
  const data = JSON.parse(result.content[0].text);
227
227
 
228
- expect(mockSpawnBackgroundWorker).toHaveBeenCalledWith(
229
- data.job.id,
230
- tempDir
231
- );
228
+ expect(mockSpawnBackgroundWorker).toHaveBeenCalledWith(data.job.id, tempDir);
232
229
 
233
230
  rmSync(sourcePath, { recursive: true, force: true });
234
231
  });
@@ -239,17 +236,15 @@ describe('store.handler', () => {
239
236
  type: 'repo',
240
237
  source: 'https://github.com/test/repo.git',
241
238
  branch: 'main',
242
- description: 'Git repo store'
239
+ description: 'Git repo store',
243
240
  };
244
241
 
245
242
  // This will fail to clone, but should still create the store record
246
- await expect(
247
- handleCreateStore(args, mockContext)
248
- ).rejects.toThrow(/Git clone failed/);
243
+ await expect(handleCreateStore(args, mockContext)).rejects.toThrow(/Git clone failed/);
249
244
 
250
245
  // Verify store was NOT created since clone failed
251
246
  const stores = await storeService.list();
252
- const found = stores.find(s => s.name === 'repo-store');
247
+ const found = stores.find((s) => s.name === 'repo-store');
253
248
  expect(found).toBeUndefined();
254
249
  });
255
250
 
@@ -257,13 +252,11 @@ describe('store.handler', () => {
257
252
  const httpArgs: CreateStoreArgs = {
258
253
  name: 'http-store',
259
254
  type: 'repo',
260
- source: 'http://github.com/test/repo'
255
+ source: 'http://github.com/test/repo',
261
256
  };
262
257
 
263
258
  // Will fail to clone, which is expected
264
- await expect(
265
- handleCreateStore(httpArgs, mockContext)
266
- ).rejects.toThrow(/Git clone failed/);
259
+ await expect(handleCreateStore(httpArgs, mockContext)).rejects.toThrow(/Git clone failed/);
267
260
  });
268
261
 
269
262
  it('should reject store with nonexistent path', async () => {
@@ -271,7 +264,7 @@ describe('store.handler', () => {
271
264
  const args: CreateStoreArgs = {
272
265
  name: 'bad-store',
273
266
  type: 'file',
274
- source: '/nonexistent/path/that/does/not/exist'
267
+ source: '/nonexistent/path/that/does/not/exist',
275
268
  };
276
269
 
277
270
  await expect(handleCreateStore(args, mockContext)).rejects.toThrow(
@@ -286,7 +279,7 @@ describe('store.handler', () => {
286
279
  name: 'index-test',
287
280
  type: 'file',
288
281
  path: tempDir,
289
- description: 'Test indexing'
282
+ description: 'Test indexing',
290
283
  });
291
284
 
292
285
  const args: IndexStoreArgs = { store: createResult.data.id };
@@ -304,17 +297,14 @@ describe('store.handler', () => {
304
297
  const createResult = await storeService.create({
305
298
  name: 'index-worker-test',
306
299
  type: 'file',
307
- path: tempDir
300
+ path: tempDir,
308
301
  });
309
302
 
310
303
  const args: IndexStoreArgs = { store: createResult.data.id };
311
304
  const result = await handleIndexStore(args, mockContext);
312
305
  const data = JSON.parse(result.content[0].text);
313
306
 
314
- expect(mockSpawnBackgroundWorker).toHaveBeenCalledWith(
315
- data.job.id,
316
- tempDir
317
- );
307
+ expect(mockSpawnBackgroundWorker).toHaveBeenCalledWith(data.job.id, tempDir);
318
308
  });
319
309
 
320
310
  it('should work with store name', async () => {
@@ -322,7 +312,7 @@ describe('store.handler', () => {
322
312
  name: 'named-store',
323
313
  type: 'file',
324
314
  path: tempDir,
325
- description: 'Test'
315
+ description: 'Test',
326
316
  });
327
317
 
328
318
  const args: IndexStoreArgs = { store: 'named-store' };
@@ -335,9 +325,9 @@ describe('store.handler', () => {
335
325
  it('should throw if store not found', async () => {
336
326
  const args: IndexStoreArgs = { store: 'nonexistent' };
337
327
 
338
- await expect(
339
- handleIndexStore(args, mockContext)
340
- ).rejects.toThrow('Store not found: nonexistent');
328
+ await expect(handleIndexStore(args, mockContext)).rejects.toThrow(
329
+ 'Store not found: nonexistent'
330
+ );
341
331
  });
342
332
  });
343
333
 
@@ -346,7 +336,7 @@ describe('store.handler', () => {
346
336
  await storeService.create({
347
337
  name: 'delete-test',
348
338
  type: 'file',
349
- path: tempDir
339
+ path: tempDir,
350
340
  });
351
341
 
352
342
  const args: DeleteStoreArgs = { store: 'delete-test' };
@@ -359,14 +349,14 @@ describe('store.handler', () => {
359
349
 
360
350
  // Verify store is actually deleted
361
351
  const stores = await storeService.list();
362
- expect(stores.find(s => s.name === 'delete-test')).toBeUndefined();
352
+ expect(stores.find((s) => s.name === 'delete-test')).toBeUndefined();
363
353
  });
364
354
 
365
355
  it('should delete store by ID', async () => {
366
356
  const createResult = await storeService.create({
367
357
  name: 'delete-by-id',
368
358
  type: 'file',
369
- path: tempDir
359
+ path: tempDir,
370
360
  });
371
361
 
372
362
  const args: DeleteStoreArgs = { store: createResult.data.id };
@@ -381,7 +371,7 @@ describe('store.handler', () => {
381
371
  const createResult = await storeService.create({
382
372
  name: 'lance-delete-test',
383
373
  type: 'file',
384
- path: tempDir
374
+ path: tempDir,
385
375
  });
386
376
 
387
377
  const args: DeleteStoreArgs = { store: 'lance-delete-test' };
@@ -393,16 +383,16 @@ describe('store.handler', () => {
393
383
  it('should throw if store not found', async () => {
394
384
  const args: DeleteStoreArgs = { store: 'nonexistent' };
395
385
 
396
- await expect(
397
- handleDeleteStore(args, mockContext)
398
- ).rejects.toThrow('Store not found: nonexistent');
386
+ await expect(handleDeleteStore(args, mockContext)).rejects.toThrow(
387
+ 'Store not found: nonexistent'
388
+ );
399
389
  });
400
390
 
401
391
  it('should include store type in response', async () => {
402
392
  await storeService.create({
403
393
  name: 'type-test',
404
394
  type: 'file',
405
- path: tempDir
395
+ path: tempDir,
406
396
  });
407
397
 
408
398
  const args: DeleteStoreArgs = { store: 'type-test' };
@@ -411,6 +401,5 @@ describe('store.handler', () => {
411
401
  const data = JSON.parse(result.content[0].text);
412
402
  expect(data.store.type).toBe('file');
413
403
  });
414
-
415
404
  });
416
405
  });
@@ -1,23 +1,23 @@
1
1
  import { rm } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
- import type { ToolHandler, ToolResponse } from '../types.js';
4
- import type {
5
- ListStoresArgs,
6
- GetStoreInfoArgs,
7
- CreateStoreArgs,
8
- IndexStoreArgs,
9
- DeleteStoreArgs
10
- } from '../schemas/index.js';
3
+ import { JobService } from '../../services/job.service.js';
4
+ import { createStoreId } from '../../types/brands.js';
5
+ import { spawnBackgroundWorker } from '../../workers/spawn-worker.js';
11
6
  import {
12
7
  ListStoresArgsSchema,
13
8
  GetStoreInfoArgsSchema,
14
9
  CreateStoreArgsSchema,
15
10
  IndexStoreArgsSchema,
16
- DeleteStoreArgsSchema
11
+ DeleteStoreArgsSchema,
17
12
  } from '../schemas/index.js';
18
- import { JobService } from '../../services/job.service.js';
19
- import { spawnBackgroundWorker } from '../../workers/spawn-worker.js';
20
- import { createStoreId } from '../../types/brands.js';
13
+ import type {
14
+ ListStoresArgs,
15
+ GetStoreInfoArgs,
16
+ CreateStoreArgs,
17
+ IndexStoreArgs,
18
+ DeleteStoreArgs,
19
+ } from '../schemas/index.js';
20
+ import type { ToolHandler, ToolResponse } from '../types.js';
21
21
 
22
22
  /**
23
23
  * Handle list_stores requests
@@ -34,27 +34,30 @@ export const handleListStores: ToolHandler<ListStoresArgs> = async (
34
34
  const { services } = context;
35
35
 
36
36
  const stores = await services.store.list();
37
- const filtered = validated.type !== undefined
38
- ? stores.filter(s => s.type === validated.type)
39
- : stores;
37
+ const filtered =
38
+ validated.type !== undefined ? stores.filter((s) => s.type === validated.type) : stores;
40
39
 
41
40
  return {
42
41
  content: [
43
42
  {
44
43
  type: 'text',
45
- text: JSON.stringify({
46
- stores: filtered.map(s => ({
47
- id: s.id,
48
- name: s.name,
49
- type: s.type,
50
- path: 'path' in s ? s.path : undefined,
51
- url: 'url' in s && s.url !== undefined ? s.url : undefined,
52
- description: s.description,
53
- createdAt: s.createdAt.toISOString()
54
- }))
55
- }, null, 2)
56
- }
57
- ]
44
+ text: JSON.stringify(
45
+ {
46
+ stores: filtered.map((s) => ({
47
+ id: s.id,
48
+ name: s.name,
49
+ type: s.type,
50
+ path: 'path' in s ? s.path : undefined,
51
+ url: 'url' in s && s.url !== undefined ? s.url : undefined,
52
+ description: s.description,
53
+ createdAt: s.createdAt.toISOString(),
54
+ })),
55
+ },
56
+ null,
57
+ 2
58
+ ),
59
+ },
60
+ ],
58
61
  };
59
62
  };
60
63
 
@@ -82,20 +85,24 @@ export const handleGetStoreInfo: ToolHandler<GetStoreInfoArgs> = async (
82
85
  content: [
83
86
  {
84
87
  type: 'text',
85
- text: JSON.stringify({
86
- id: store.id,
87
- name: store.name,
88
- type: store.type,
89
- path: 'path' in store ? store.path : undefined,
90
- url: 'url' in store && store.url !== undefined ? store.url : undefined,
91
- branch: 'branch' in store ? store.branch : undefined,
92
- description: store.description,
93
- status: store.status,
94
- createdAt: store.createdAt.toISOString(),
95
- updatedAt: store.updatedAt.toISOString()
96
- }, null, 2)
97
- }
98
- ]
88
+ text: JSON.stringify(
89
+ {
90
+ id: store.id,
91
+ name: store.name,
92
+ type: store.type,
93
+ path: 'path' in store ? store.path : undefined,
94
+ url: 'url' in store && store.url !== undefined ? store.url : undefined,
95
+ branch: 'branch' in store ? store.branch : undefined,
96
+ description: store.description,
97
+ status: store.status,
98
+ createdAt: store.createdAt.toISOString(),
99
+ updatedAt: store.updatedAt.toISOString(),
100
+ },
101
+ null,
102
+ 2
103
+ ),
104
+ },
105
+ ],
99
106
  };
100
107
  };
101
108
 
@@ -115,16 +122,17 @@ export const handleCreateStore: ToolHandler<CreateStoreArgs> = async (
115
122
  const { services, options } = context;
116
123
 
117
124
  // Determine if source is a URL or path
118
- const isUrl = validated.source.startsWith('http://') ||
119
- validated.source.startsWith('https://') ||
120
- validated.source.startsWith('git@');
125
+ const isUrl =
126
+ validated.source.startsWith('http://') ||
127
+ validated.source.startsWith('https://') ||
128
+ validated.source.startsWith('git@');
121
129
 
122
130
  const result = await services.store.create({
123
131
  name: validated.name,
124
132
  type: validated.type,
125
133
  ...(isUrl ? { url: validated.source } : { path: validated.source }),
126
134
  ...(validated.branch !== undefined ? { branch: validated.branch } : {}),
127
- ...(validated.description !== undefined ? { description: validated.description } : {})
135
+ ...(validated.description !== undefined ? { description: validated.description } : {}),
128
136
  });
129
137
 
130
138
  if (!result.success) {
@@ -135,7 +143,7 @@ export const handleCreateStore: ToolHandler<CreateStoreArgs> = async (
135
143
  const jobService = new JobService(options.dataDir);
136
144
  const jobDetails: Record<string, unknown> = {
137
145
  storeName: result.data.name,
138
- storeId: result.data.id
146
+ storeId: result.data.id,
139
147
  };
140
148
  if (isUrl) {
141
149
  jobDetails['url'] = validated.source;
@@ -146,7 +154,7 @@ export const handleCreateStore: ToolHandler<CreateStoreArgs> = async (
146
154
  const job = jobService.createJob({
147
155
  type: validated.type === 'repo' && isUrl ? 'clone' : 'index',
148
156
  details: jobDetails,
149
- message: `Indexing ${result.data.name}...`
157
+ message: `Indexing ${result.data.name}...`,
150
158
  });
151
159
 
152
160
  // Spawn background worker (dataDir defaults to project-local .bluera if undefined)
@@ -156,22 +164,26 @@ export const handleCreateStore: ToolHandler<CreateStoreArgs> = async (
156
164
  content: [
157
165
  {
158
166
  type: 'text',
159
- text: JSON.stringify({
160
- store: {
161
- id: result.data.id,
162
- name: result.data.name,
163
- type: result.data.type,
164
- path: 'path' in result.data ? result.data.path : undefined
167
+ text: JSON.stringify(
168
+ {
169
+ store: {
170
+ id: result.data.id,
171
+ name: result.data.name,
172
+ type: result.data.type,
173
+ path: 'path' in result.data ? result.data.path : undefined,
174
+ },
175
+ job: {
176
+ id: job.id,
177
+ status: job.status,
178
+ message: job.message,
179
+ },
180
+ message: `Store created. Indexing started in background (Job ID: ${job.id})`,
165
181
  },
166
- job: {
167
- id: job.id,
168
- status: job.status,
169
- message: job.message
170
- },
171
- message: `Store created. Indexing started in background (Job ID: ${job.id})`
172
- }, null, 2)
173
- }
174
- ]
182
+ null,
183
+ 2
184
+ ),
185
+ },
186
+ ],
175
187
  };
176
188
  };
177
189
 
@@ -200,7 +212,7 @@ export const handleIndexStore: ToolHandler<IndexStoreArgs> = async (
200
212
  const jobService = new JobService(options.dataDir);
201
213
  const jobDetails: Record<string, unknown> = {
202
214
  storeName: store.name,
203
- storeId: store.id
215
+ storeId: store.id,
204
216
  };
205
217
  if ('path' in store && store.path) {
206
218
  jobDetails['path'] = store.path;
@@ -208,7 +220,7 @@ export const handleIndexStore: ToolHandler<IndexStoreArgs> = async (
208
220
  const job = jobService.createJob({
209
221
  type: 'index',
210
222
  details: jobDetails,
211
- message: `Re-indexing ${store.name}...`
223
+ message: `Re-indexing ${store.name}...`,
212
224
  });
213
225
 
214
226
  // Spawn background worker (dataDir defaults to project-local .bluera if undefined)
@@ -218,20 +230,24 @@ export const handleIndexStore: ToolHandler<IndexStoreArgs> = async (
218
230
  content: [
219
231
  {
220
232
  type: 'text',
221
- text: JSON.stringify({
222
- store: {
223
- id: store.id,
224
- name: store.name
233
+ text: JSON.stringify(
234
+ {
235
+ store: {
236
+ id: store.id,
237
+ name: store.name,
238
+ },
239
+ job: {
240
+ id: job.id,
241
+ status: job.status,
242
+ message: job.message,
243
+ },
244
+ message: `Indexing started in background (Job ID: ${job.id})`,
225
245
  },
226
- job: {
227
- id: job.id,
228
- status: job.status,
229
- message: job.message
230
- },
231
- message: `Indexing started in background (Job ID: ${job.id})`
232
- }, null, 2)
233
- }
234
- ]
246
+ null,
247
+ 2
248
+ ),
249
+ },
250
+ ],
235
251
  };
236
252
  };
237
253
 
@@ -280,16 +296,20 @@ export const handleDeleteStore: ToolHandler<DeleteStoreArgs> = async (
280
296
  content: [
281
297
  {
282
298
  type: 'text',
283
- text: JSON.stringify({
284
- deleted: true,
285
- store: {
286
- id: store.id,
287
- name: store.name,
288
- type: store.type
299
+ text: JSON.stringify(
300
+ {
301
+ deleted: true,
302
+ store: {
303
+ id: store.id,
304
+ name: store.name,
305
+ type: store.type,
306
+ },
307
+ message: `Successfully deleted store: ${store.name}`,
289
308
  },
290
- message: `Successfully deleted store: ${store.name}`
291
- }, null, 2)
292
- }
293
- ]
309
+ null,
310
+ 2
311
+ ),
312
+ },
313
+ ],
294
314
  };
295
315
  };