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.
- package/.claude/hooks/post-edit-check.sh +5 -3
- package/.claude/skills/atomic-commits/SKILL.md +3 -1
- package/.husky/pre-commit +3 -2
- package/.prettierrc +9 -0
- package/.versionrc.json +1 -1
- package/CHANGELOG.md +33 -0
- package/CLAUDE.md +6 -0
- package/README.md +25 -13
- package/bun.lock +277 -33
- package/dist/{chunk-L2YVNC63.js → chunk-6FHWC36B.js} +9 -1
- package/dist/chunk-6FHWC36B.js.map +1 -0
- package/dist/{chunk-RST4XGRL.js → chunk-DC7CGSGT.js} +288 -241
- package/dist/chunk-DC7CGSGT.js.map +1 -0
- package/dist/{chunk-6PBP5DVD.js → chunk-WFNPNAAP.js} +3212 -3054
- package/dist/chunk-WFNPNAAP.js.map +1 -0
- package/dist/{chunk-WT2DAEO7.js → chunk-Z2KKVH45.js} +548 -482
- package/dist/chunk-Z2KKVH45.js.map +1 -0
- package/dist/index.js +871 -758
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +3 -3
- package/dist/watch.service-BJV3TI3F.js +7 -0
- package/dist/workers/background-worker-cli.js +46 -45
- package/dist/workers/background-worker-cli.js.map +1 -1
- package/eslint.config.js +43 -1
- package/package.json +18 -11
- package/plugin.json +8 -0
- package/python/requirements.txt +1 -1
- package/src/analysis/ast-parser.test.ts +12 -11
- package/src/analysis/ast-parser.ts +28 -22
- package/src/analysis/code-graph.test.ts +52 -62
- package/src/analysis/code-graph.ts +9 -13
- package/src/analysis/dependency-usage-analyzer.test.ts +91 -271
- package/src/analysis/dependency-usage-analyzer.ts +52 -24
- package/src/analysis/go-ast-parser.test.ts +22 -22
- package/src/analysis/go-ast-parser.ts +18 -25
- package/src/analysis/parser-factory.test.ts +9 -9
- package/src/analysis/parser-factory.ts +3 -3
- package/src/analysis/python-ast-parser.test.ts +27 -27
- package/src/analysis/python-ast-parser.ts +2 -2
- package/src/analysis/repo-url-resolver.test.ts +82 -82
- package/src/analysis/rust-ast-parser.test.ts +19 -19
- package/src/analysis/rust-ast-parser.ts +17 -27
- package/src/analysis/tree-sitter-parser.test.ts +3 -3
- package/src/analysis/tree-sitter-parser.ts +10 -16
- package/src/cli/commands/crawl.test.ts +40 -24
- package/src/cli/commands/crawl.ts +186 -166
- package/src/cli/commands/index-cmd.test.ts +90 -90
- package/src/cli/commands/index-cmd.ts +52 -36
- package/src/cli/commands/mcp.test.ts +6 -6
- package/src/cli/commands/mcp.ts +2 -2
- package/src/cli/commands/plugin-api.test.ts +16 -18
- package/src/cli/commands/plugin-api.ts +9 -6
- package/src/cli/commands/search.test.ts +16 -7
- package/src/cli/commands/search.ts +124 -87
- package/src/cli/commands/serve.test.ts +67 -25
- package/src/cli/commands/serve.ts +18 -3
- package/src/cli/commands/setup.test.ts +176 -101
- package/src/cli/commands/setup.ts +140 -117
- package/src/cli/commands/store.test.ts +82 -53
- package/src/cli/commands/store.ts +56 -37
- package/src/cli/program.ts +2 -2
- package/src/crawl/article-converter.test.ts +4 -1
- package/src/crawl/article-converter.ts +46 -31
- package/src/crawl/bridge.test.ts +240 -132
- package/src/crawl/bridge.ts +87 -30
- package/src/crawl/claude-client.test.ts +124 -56
- package/src/crawl/claude-client.ts +7 -15
- package/src/crawl/intelligent-crawler.test.ts +65 -22
- package/src/crawl/intelligent-crawler.ts +86 -53
- package/src/crawl/markdown-utils.ts +1 -4
- package/src/db/embeddings.ts +4 -6
- package/src/db/lance.test.ts +4 -4
- package/src/db/lance.ts +16 -12
- package/src/index.ts +26 -17
- package/src/logging/index.ts +1 -5
- package/src/logging/logger.ts +3 -5
- package/src/logging/payload.test.ts +1 -1
- package/src/logging/payload.ts +3 -5
- package/src/mcp/commands/index.ts +2 -2
- package/src/mcp/commands/job.commands.ts +12 -18
- package/src/mcp/commands/meta.commands.ts +13 -13
- package/src/mcp/commands/registry.ts +5 -8
- package/src/mcp/commands/store.commands.ts +19 -19
- package/src/mcp/handlers/execute.handler.test.ts +10 -10
- package/src/mcp/handlers/execute.handler.ts +4 -5
- package/src/mcp/handlers/index.ts +10 -14
- package/src/mcp/handlers/job.handler.test.ts +10 -10
- package/src/mcp/handlers/job.handler.ts +22 -25
- package/src/mcp/handlers/search.handler.test.ts +36 -65
- package/src/mcp/handlers/search.handler.ts +135 -104
- package/src/mcp/handlers/store.handler.test.ts +41 -52
- package/src/mcp/handlers/store.handler.ts +108 -88
- package/src/mcp/schemas/index.test.ts +73 -68
- package/src/mcp/schemas/index.ts +18 -12
- package/src/mcp/server.test.ts +1 -1
- package/src/mcp/server.ts +59 -46
- package/src/plugin/commands.test.ts +230 -95
- package/src/plugin/commands.ts +24 -25
- package/src/plugin/dependency-analyzer.test.ts +52 -52
- package/src/plugin/dependency-analyzer.ts +85 -22
- package/src/plugin/git-clone.test.ts +24 -13
- package/src/plugin/git-clone.ts +3 -7
- package/src/server/app.test.ts +109 -109
- package/src/server/app.ts +32 -23
- package/src/server/index.test.ts +64 -66
- package/src/services/chunking.service.test.ts +32 -32
- package/src/services/chunking.service.ts +16 -9
- package/src/services/code-graph.service.test.ts +30 -36
- package/src/services/code-graph.service.ts +24 -10
- package/src/services/code-unit.service.test.ts +55 -11
- package/src/services/code-unit.service.ts +85 -11
- package/src/services/config.service.test.ts +37 -18
- package/src/services/config.service.ts +30 -7
- package/src/services/index.service.test.ts +49 -18
- package/src/services/index.service.ts +98 -48
- package/src/services/index.ts +6 -9
- package/src/services/job.service.test.ts +22 -22
- package/src/services/job.service.ts +18 -18
- package/src/services/project-root.service.test.ts +1 -3
- package/src/services/search.service.test.ts +248 -120
- package/src/services/search.service.ts +286 -156
- package/src/services/services.test.ts +1 -1
- package/src/services/snippet.service.test.ts +14 -6
- package/src/services/snippet.service.ts +7 -5
- package/src/services/store.service.test.ts +68 -29
- package/src/services/store.service.ts +41 -12
- package/src/services/watch.service.test.ts +34 -14
- package/src/services/watch.service.ts +11 -1
- package/src/types/brands.test.ts +3 -1
- package/src/types/index.ts +2 -13
- package/src/types/search.ts +10 -8
- package/src/utils/type-guards.test.ts +20 -15
- package/src/utils/type-guards.ts +1 -1
- package/src/workers/background-worker-cli.ts +2 -2
- package/src/workers/background-worker.test.ts +54 -40
- package/src/workers/background-worker.ts +76 -60
- package/src/workers/spawn-worker.test.ts +22 -10
- package/src/workers/spawn-worker.ts +6 -6
- package/tests/analysis/ast-parser.test.ts +3 -3
- package/tests/analysis/code-graph.test.ts +5 -5
- package/tests/fixtures/code-snippets/api/error-handling.ts +4 -15
- package/tests/fixtures/code-snippets/api/rest-controller.ts +3 -9
- package/tests/fixtures/code-snippets/auth/jwt-auth.ts +5 -21
- package/tests/fixtures/code-snippets/auth/oauth-flow.ts +4 -4
- package/tests/fixtures/code-snippets/database/repository-pattern.ts +11 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +22 -20
- package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +13 -10
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +10 -7
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +16 -16
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +7 -7
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +6 -6
- package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +4 -4
- package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +166 -169
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +8 -8
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +30 -33
- package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +2 -2
- package/tests/fixtures/test-server.ts +3 -2
- package/tests/helpers/performance-metrics.ts +8 -25
- package/tests/helpers/search-relevance.ts +14 -69
- package/tests/integration/cli-consistency.test.ts +5 -4
- package/tests/integration/python-bridge.test.ts +13 -3
- package/tests/mcp/server.test.ts +1 -1
- package/tests/services/code-unit.service.test.ts +48 -0
- package/tests/services/job.service.test.ts +124 -0
- package/tests/services/search.progressive-context.test.ts +2 -2
- package/.claude-plugin/plugin.json +0 -13
- package/dist/chunk-6PBP5DVD.js.map +0 -1
- package/dist/chunk-L2YVNC63.js.map +0 -1
- package/dist/chunk-RST4XGRL.js.map +0 -1
- package/dist/chunk-WT2DAEO7.js.map +0 -1
- package/dist/watch.service-YAIKKDCF.js +0 -7
- package/skills/atomic-commits/SKILL.md +0 -77
- /package/dist/{watch.service-YAIKKDCF.js.map → watch.service-BJV3TI3F.js.map} +0 -0
|
@@ -17,12 +17,12 @@ vi.mock('ora', () => ({
|
|
|
17
17
|
stop: vi.fn(),
|
|
18
18
|
succeed: vi.fn(),
|
|
19
19
|
fail: vi.fn(),
|
|
20
|
-
text: ''
|
|
21
|
-
}))
|
|
20
|
+
text: '',
|
|
21
|
+
})),
|
|
22
22
|
}));
|
|
23
23
|
|
|
24
24
|
vi.mock('../../services/watch.service.js', () => ({
|
|
25
|
-
WatchService: vi.fn()
|
|
25
|
+
WatchService: vi.fn(),
|
|
26
26
|
}));
|
|
27
27
|
|
|
28
28
|
describe('createIndexCommand - Execution Tests', () => {
|
|
@@ -43,22 +43,22 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
43
43
|
getByIdOrName: vi.fn(),
|
|
44
44
|
list: vi.fn(),
|
|
45
45
|
create: vi.fn(),
|
|
46
|
-
delete: vi.fn()
|
|
46
|
+
delete: vi.fn(),
|
|
47
47
|
},
|
|
48
48
|
lance: {
|
|
49
49
|
initialize: vi.fn(),
|
|
50
50
|
search: vi.fn(),
|
|
51
|
-
addDocuments: vi.fn()
|
|
51
|
+
addDocuments: vi.fn(),
|
|
52
52
|
},
|
|
53
53
|
search: {
|
|
54
|
-
search: vi.fn()
|
|
54
|
+
search: vi.fn(),
|
|
55
55
|
},
|
|
56
56
|
index: {
|
|
57
|
-
indexStore: vi.fn()
|
|
57
|
+
indexStore: vi.fn(),
|
|
58
58
|
},
|
|
59
59
|
embeddings: {
|
|
60
|
-
embed: vi.fn()
|
|
61
|
-
}
|
|
60
|
+
embed: vi.fn(),
|
|
61
|
+
},
|
|
62
62
|
} as unknown as ServiceContainer;
|
|
63
63
|
|
|
64
64
|
vi.mocked(createServices).mockResolvedValue(mockServices);
|
|
@@ -74,14 +74,14 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
74
74
|
Object.defineProperty(process.stdout, 'isTTY', {
|
|
75
75
|
value: false,
|
|
76
76
|
writable: true,
|
|
77
|
-
configurable: true
|
|
77
|
+
configurable: true,
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
getOptions = (): GlobalOptions => ({
|
|
81
81
|
config: undefined,
|
|
82
82
|
dataDir: '/tmp/test-data',
|
|
83
83
|
quiet: false,
|
|
84
|
-
format: undefined
|
|
84
|
+
format: undefined,
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
|
|
@@ -97,7 +97,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
97
97
|
type: 'file',
|
|
98
98
|
path: '/test/path',
|
|
99
99
|
createdAt: new Date(),
|
|
100
|
-
updatedAt: new Date()
|
|
100
|
+
updatedAt: new Date(),
|
|
101
101
|
};
|
|
102
102
|
|
|
103
103
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -106,8 +106,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
106
106
|
data: {
|
|
107
107
|
documentsIndexed: 10,
|
|
108
108
|
chunksCreated: 25,
|
|
109
|
-
timeMs: 1500
|
|
110
|
-
}
|
|
109
|
+
timeMs: 1500,
|
|
110
|
+
},
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
const command = createIndexCommand(getOptions);
|
|
@@ -126,7 +126,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
126
126
|
type: 'file',
|
|
127
127
|
path: '/test',
|
|
128
128
|
createdAt: new Date(),
|
|
129
|
-
updatedAt: new Date()
|
|
129
|
+
updatedAt: new Date(),
|
|
130
130
|
};
|
|
131
131
|
|
|
132
132
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -135,8 +135,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
135
135
|
data: {
|
|
136
136
|
documentsIndexed: 5,
|
|
137
137
|
chunksCreated: 12,
|
|
138
|
-
timeMs: 800
|
|
139
|
-
}
|
|
138
|
+
timeMs: 800,
|
|
139
|
+
},
|
|
140
140
|
});
|
|
141
141
|
|
|
142
142
|
const command = createIndexCommand(getOptions);
|
|
@@ -151,7 +151,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
151
151
|
config: undefined,
|
|
152
152
|
dataDir: '/tmp/test-data',
|
|
153
153
|
quiet: false,
|
|
154
|
-
format: 'json'
|
|
154
|
+
format: 'json',
|
|
155
155
|
});
|
|
156
156
|
|
|
157
157
|
const mockStore: Store = {
|
|
@@ -160,7 +160,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
160
160
|
type: 'file',
|
|
161
161
|
path: '/test',
|
|
162
162
|
createdAt: new Date(),
|
|
163
|
-
updatedAt: new Date()
|
|
163
|
+
updatedAt: new Date(),
|
|
164
164
|
};
|
|
165
165
|
|
|
166
166
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -169,17 +169,15 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
169
169
|
data: {
|
|
170
170
|
documentsIndexed: 3,
|
|
171
171
|
chunksCreated: 7,
|
|
172
|
-
timeMs: 500
|
|
173
|
-
}
|
|
172
|
+
timeMs: 500,
|
|
173
|
+
},
|
|
174
174
|
});
|
|
175
175
|
|
|
176
176
|
const command = createIndexCommand(getOptions);
|
|
177
177
|
const action = command._actionHandler;
|
|
178
178
|
await action(['test']);
|
|
179
179
|
|
|
180
|
-
expect(consoleLogSpy).toHaveBeenCalledWith(
|
|
181
|
-
expect.stringContaining('"documentsIndexed": 3')
|
|
182
|
-
);
|
|
180
|
+
expect(consoleLogSpy).toHaveBeenCalledWith(expect.stringContaining('"documentsIndexed": 3'));
|
|
183
181
|
|
|
184
182
|
const jsonOutput = JSON.parse(consoleLogSpy.mock.calls[0]?.[0] as string);
|
|
185
183
|
expect(jsonOutput.documentsIndexed).toBe(3);
|
|
@@ -192,7 +190,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
192
190
|
config: undefined,
|
|
193
191
|
dataDir: '/tmp/test-data',
|
|
194
192
|
quiet: true,
|
|
195
|
-
format: undefined
|
|
193
|
+
format: undefined,
|
|
196
194
|
});
|
|
197
195
|
|
|
198
196
|
const mockStore: Store = {
|
|
@@ -201,7 +199,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
201
199
|
type: 'file',
|
|
202
200
|
path: '/test',
|
|
203
201
|
createdAt: new Date(),
|
|
204
|
-
updatedAt: new Date()
|
|
202
|
+
updatedAt: new Date(),
|
|
205
203
|
};
|
|
206
204
|
|
|
207
205
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -210,8 +208,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
210
208
|
data: {
|
|
211
209
|
documentsIndexed: 1,
|
|
212
210
|
chunksCreated: 2,
|
|
213
|
-
timeMs: 100
|
|
214
|
-
}
|
|
211
|
+
timeMs: 100,
|
|
212
|
+
},
|
|
215
213
|
});
|
|
216
214
|
|
|
217
215
|
const command = createIndexCommand(getOptions);
|
|
@@ -231,7 +229,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
231
229
|
type: 'file',
|
|
232
230
|
path: '/test',
|
|
233
231
|
createdAt: new Date(),
|
|
234
|
-
updatedAt: new Date()
|
|
232
|
+
updatedAt: new Date(),
|
|
235
233
|
};
|
|
236
234
|
|
|
237
235
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -240,8 +238,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
240
238
|
data: {
|
|
241
239
|
documentsIndexed: 1,
|
|
242
240
|
chunksCreated: 2,
|
|
243
|
-
timeMs: 100
|
|
244
|
-
}
|
|
241
|
+
timeMs: 100,
|
|
242
|
+
},
|
|
245
243
|
});
|
|
246
244
|
|
|
247
245
|
const command = createIndexCommand(getOptions);
|
|
@@ -258,7 +256,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
258
256
|
type: 'file',
|
|
259
257
|
path: '/test',
|
|
260
258
|
createdAt: new Date(),
|
|
261
|
-
updatedAt: new Date()
|
|
259
|
+
updatedAt: new Date(),
|
|
262
260
|
};
|
|
263
261
|
|
|
264
262
|
let progressCallback: ((event: IndexEvent) => void) | undefined;
|
|
@@ -272,8 +270,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
272
270
|
data: {
|
|
273
271
|
documentsIndexed: 5,
|
|
274
272
|
chunksCreated: 10,
|
|
275
|
-
timeMs: 1000
|
|
276
|
-
}
|
|
273
|
+
timeMs: 1000,
|
|
274
|
+
},
|
|
277
275
|
};
|
|
278
276
|
});
|
|
279
277
|
|
|
@@ -291,7 +289,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
291
289
|
type: 'repo',
|
|
292
290
|
url: 'https://github.com/test/repo',
|
|
293
291
|
createdAt: new Date(),
|
|
294
|
-
updatedAt: new Date()
|
|
292
|
+
updatedAt: new Date(),
|
|
295
293
|
};
|
|
296
294
|
|
|
297
295
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -300,8 +298,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
300
298
|
data: {
|
|
301
299
|
documentsIndexed: 1,
|
|
302
300
|
chunksCreated: 1,
|
|
303
|
-
timeMs: 100
|
|
304
|
-
}
|
|
301
|
+
timeMs: 100,
|
|
302
|
+
},
|
|
305
303
|
});
|
|
306
304
|
|
|
307
305
|
const command = createIndexCommand(getOptions);
|
|
@@ -315,6 +313,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
315
313
|
|
|
316
314
|
describe('index command - error handling', () => {
|
|
317
315
|
it('exits with code 3 when store not found', async () => {
|
|
316
|
+
const { destroyServices } = await import('../../services/index.js');
|
|
317
|
+
|
|
318
318
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(undefined);
|
|
319
319
|
|
|
320
320
|
const command = createIndexCommand(getOptions);
|
|
@@ -323,22 +323,26 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
323
323
|
|
|
324
324
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Error: Store not found: nonexistent-store');
|
|
325
325
|
expect(processExitSpy).toHaveBeenCalledWith(3);
|
|
326
|
+
// Must call destroyServices before process.exit per CLAUDE.md
|
|
327
|
+
expect(destroyServices).toHaveBeenCalled();
|
|
326
328
|
});
|
|
327
329
|
|
|
328
330
|
it('exits with code 4 when indexing fails', async () => {
|
|
331
|
+
const { destroyServices } = await import('../../services/index.js');
|
|
332
|
+
|
|
329
333
|
const mockStore: Store = {
|
|
330
334
|
id: 'store-123',
|
|
331
335
|
name: 'test',
|
|
332
336
|
type: 'file',
|
|
333
337
|
path: '/test',
|
|
334
338
|
createdAt: new Date(),
|
|
335
|
-
updatedAt: new Date()
|
|
339
|
+
updatedAt: new Date(),
|
|
336
340
|
};
|
|
337
341
|
|
|
338
342
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
339
343
|
vi.mocked(mockServices.index.indexStore).mockResolvedValue({
|
|
340
344
|
success: false,
|
|
341
|
-
error: new Error('Failed to read files')
|
|
345
|
+
error: new Error('Failed to read files'),
|
|
342
346
|
});
|
|
343
347
|
|
|
344
348
|
const command = createIndexCommand(getOptions);
|
|
@@ -347,6 +351,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
347
351
|
|
|
348
352
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Error: Failed to read files');
|
|
349
353
|
expect(processExitSpy).toHaveBeenCalledWith(4);
|
|
354
|
+
// Must call destroyServices before process.exit per CLAUDE.md
|
|
355
|
+
expect(destroyServices).toHaveBeenCalled();
|
|
350
356
|
});
|
|
351
357
|
|
|
352
358
|
it('handles lance initialization errors', async () => {
|
|
@@ -356,7 +362,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
356
362
|
type: 'file',
|
|
357
363
|
path: '/test',
|
|
358
364
|
createdAt: new Date(),
|
|
359
|
-
updatedAt: new Date()
|
|
365
|
+
updatedAt: new Date(),
|
|
360
366
|
};
|
|
361
367
|
|
|
362
368
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -378,21 +384,21 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
378
384
|
type: 'file',
|
|
379
385
|
path: '/test/path',
|
|
380
386
|
createdAt: new Date(),
|
|
381
|
-
updatedAt: new Date()
|
|
387
|
+
updatedAt: new Date(),
|
|
382
388
|
};
|
|
383
389
|
|
|
384
390
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
385
391
|
|
|
386
392
|
const mockWatchService = {
|
|
387
393
|
watch: vi.fn(),
|
|
388
|
-
unwatchAll: vi.fn()
|
|
394
|
+
unwatchAll: vi.fn(),
|
|
389
395
|
};
|
|
390
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
396
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
391
397
|
return mockWatchService as any;
|
|
392
398
|
} as any);
|
|
393
399
|
|
|
394
400
|
const command = createIndexCommand(getOptions);
|
|
395
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
401
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
396
402
|
expect(watchCmd).toBeDefined();
|
|
397
403
|
|
|
398
404
|
const action = watchCmd!._actionHandler;
|
|
@@ -400,11 +406,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
400
406
|
|
|
401
407
|
expect(mockServices.store.getByIdOrName).toHaveBeenCalledWith('test-store');
|
|
402
408
|
expect(WatchService).toHaveBeenCalledWith(mockServices.index, mockServices.lance);
|
|
403
|
-
expect(mockWatchService.watch).toHaveBeenCalledWith(
|
|
404
|
-
mockStore,
|
|
405
|
-
1000,
|
|
406
|
-
expect.any(Function)
|
|
407
|
-
);
|
|
409
|
+
expect(mockWatchService.watch).toHaveBeenCalledWith(mockStore, 1000, expect.any(Function));
|
|
408
410
|
});
|
|
409
411
|
|
|
410
412
|
it('watches a repo store successfully', async () => {
|
|
@@ -416,21 +418,21 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
416
418
|
url: 'https://github.com/test/repo',
|
|
417
419
|
path: '/local/clone/path',
|
|
418
420
|
createdAt: new Date(),
|
|
419
|
-
updatedAt: new Date()
|
|
421
|
+
updatedAt: new Date(),
|
|
420
422
|
};
|
|
421
423
|
|
|
422
424
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
423
425
|
|
|
424
426
|
const mockWatchService = {
|
|
425
427
|
watch: vi.fn(),
|
|
426
|
-
unwatchAll: vi.fn()
|
|
428
|
+
unwatchAll: vi.fn(),
|
|
427
429
|
};
|
|
428
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
430
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
429
431
|
return mockWatchService as any;
|
|
430
432
|
} as any);
|
|
431
433
|
|
|
432
434
|
const command = createIndexCommand(getOptions);
|
|
433
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
435
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
434
436
|
const action = watchCmd!._actionHandler;
|
|
435
437
|
await action(['repo-store']);
|
|
436
438
|
|
|
@@ -445,30 +447,26 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
445
447
|
type: 'file',
|
|
446
448
|
path: '/test',
|
|
447
449
|
createdAt: new Date(),
|
|
448
|
-
updatedAt: new Date()
|
|
450
|
+
updatedAt: new Date(),
|
|
449
451
|
};
|
|
450
452
|
|
|
451
453
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
452
454
|
|
|
453
455
|
const mockWatchService = {
|
|
454
456
|
watch: vi.fn(),
|
|
455
|
-
unwatchAll: vi.fn()
|
|
457
|
+
unwatchAll: vi.fn(),
|
|
456
458
|
};
|
|
457
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
459
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
458
460
|
return mockWatchService as any;
|
|
459
461
|
} as any);
|
|
460
462
|
|
|
461
463
|
const command = createIndexCommand(getOptions);
|
|
462
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
464
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
463
465
|
watchCmd.parseOptions(['--debounce', '2500']);
|
|
464
466
|
const action = watchCmd!._actionHandler;
|
|
465
467
|
await action(['test']);
|
|
466
468
|
|
|
467
|
-
expect(mockWatchService.watch).toHaveBeenCalledWith(
|
|
468
|
-
mockStore,
|
|
469
|
-
2500,
|
|
470
|
-
expect.any(Function)
|
|
471
|
-
);
|
|
469
|
+
expect(mockWatchService.watch).toHaveBeenCalledWith(mockStore, 2500, expect.any(Function));
|
|
472
470
|
});
|
|
473
471
|
|
|
474
472
|
it('outputs watching message in normal mode', async () => {
|
|
@@ -479,21 +477,21 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
479
477
|
type: 'file',
|
|
480
478
|
path: '/test',
|
|
481
479
|
createdAt: new Date(),
|
|
482
|
-
updatedAt: new Date()
|
|
480
|
+
updatedAt: new Date(),
|
|
483
481
|
};
|
|
484
482
|
|
|
485
483
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
486
484
|
|
|
487
485
|
const mockWatchService = {
|
|
488
486
|
watch: vi.fn(),
|
|
489
|
-
unwatchAll: vi.fn()
|
|
487
|
+
unwatchAll: vi.fn(),
|
|
490
488
|
};
|
|
491
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
489
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
492
490
|
return mockWatchService as any;
|
|
493
491
|
} as any);
|
|
494
492
|
|
|
495
493
|
const command = createIndexCommand(getOptions);
|
|
496
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
494
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
497
495
|
const action = watchCmd!._actionHandler;
|
|
498
496
|
await action(['my-store']);
|
|
499
497
|
|
|
@@ -505,7 +503,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
505
503
|
config: undefined,
|
|
506
504
|
dataDir: '/tmp/test-data',
|
|
507
505
|
quiet: true,
|
|
508
|
-
format: undefined
|
|
506
|
+
format: undefined,
|
|
509
507
|
});
|
|
510
508
|
|
|
511
509
|
const { WatchService } = await import('../../services/watch.service.js');
|
|
@@ -515,21 +513,21 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
515
513
|
type: 'file',
|
|
516
514
|
path: '/test',
|
|
517
515
|
createdAt: new Date(),
|
|
518
|
-
updatedAt: new Date()
|
|
516
|
+
updatedAt: new Date(),
|
|
519
517
|
};
|
|
520
518
|
|
|
521
519
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
522
520
|
|
|
523
521
|
const mockWatchService = {
|
|
524
522
|
watch: vi.fn(),
|
|
525
|
-
unwatchAll: vi.fn()
|
|
523
|
+
unwatchAll: vi.fn(),
|
|
526
524
|
};
|
|
527
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
525
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
528
526
|
return mockWatchService as any;
|
|
529
527
|
} as any);
|
|
530
528
|
|
|
531
529
|
const command = createIndexCommand(getOptions);
|
|
532
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
530
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
533
531
|
const action = watchCmd!._actionHandler;
|
|
534
532
|
await action(['test']);
|
|
535
533
|
|
|
@@ -544,7 +542,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
544
542
|
type: 'file',
|
|
545
543
|
path: '/test',
|
|
546
544
|
createdAt: new Date(),
|
|
547
|
-
updatedAt: new Date()
|
|
545
|
+
updatedAt: new Date(),
|
|
548
546
|
};
|
|
549
547
|
|
|
550
548
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -554,14 +552,14 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
554
552
|
watch: vi.fn((store, debounce, callback) => {
|
|
555
553
|
capturedCallback = callback;
|
|
556
554
|
}),
|
|
557
|
-
unwatchAll: vi.fn()
|
|
555
|
+
unwatchAll: vi.fn(),
|
|
558
556
|
};
|
|
559
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
557
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
560
558
|
return mockWatchService as any;
|
|
561
559
|
} as any);
|
|
562
560
|
|
|
563
561
|
const command = createIndexCommand(getOptions);
|
|
564
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
562
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
565
563
|
const action = watchCmd!._actionHandler;
|
|
566
564
|
await action(['test']);
|
|
567
565
|
|
|
@@ -579,28 +577,30 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
579
577
|
type: 'file',
|
|
580
578
|
path: '/test',
|
|
581
579
|
createdAt: new Date(),
|
|
582
|
-
updatedAt: new Date()
|
|
580
|
+
updatedAt: new Date(),
|
|
583
581
|
};
|
|
584
582
|
|
|
585
583
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
586
584
|
|
|
587
585
|
const mockWatchService = {
|
|
588
586
|
watch: vi.fn(),
|
|
589
|
-
unwatchAll: vi.fn()
|
|
587
|
+
unwatchAll: vi.fn(),
|
|
590
588
|
};
|
|
591
|
-
vi.mocked(WatchService).mockImplementation(function(this: any) {
|
|
589
|
+
vi.mocked(WatchService).mockImplementation(function (this: any) {
|
|
592
590
|
return mockWatchService as any;
|
|
593
591
|
} as any);
|
|
594
592
|
|
|
595
593
|
const command = createIndexCommand(getOptions);
|
|
596
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
594
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
597
595
|
const action = watchCmd!._actionHandler;
|
|
598
596
|
await action(['test']);
|
|
599
597
|
|
|
600
598
|
expect(processOnSpy).toHaveBeenCalledWith('SIGINT', expect.any(Function));
|
|
601
599
|
|
|
602
600
|
// Get the SIGINT handler and call it
|
|
603
|
-
const sigintHandler = processOnSpy.mock.calls.find(
|
|
601
|
+
const sigintHandler = processOnSpy.mock.calls.find(
|
|
602
|
+
(call) => call[0] === 'SIGINT'
|
|
603
|
+
)?.[1] as () => void;
|
|
604
604
|
expect(sigintHandler).toBeDefined();
|
|
605
605
|
|
|
606
606
|
// Call the handler
|
|
@@ -616,7 +616,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
616
616
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(undefined);
|
|
617
617
|
|
|
618
618
|
const command = createIndexCommand(getOptions);
|
|
619
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
619
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
620
620
|
const action = watchCmd!._actionHandler;
|
|
621
621
|
await expect(action(['nonexistent'])).rejects.toThrow('process.exit: 3');
|
|
622
622
|
|
|
@@ -631,13 +631,13 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
631
631
|
type: 'web',
|
|
632
632
|
url: 'https://example.com',
|
|
633
633
|
createdAt: new Date(),
|
|
634
|
-
updatedAt: new Date()
|
|
634
|
+
updatedAt: new Date(),
|
|
635
635
|
};
|
|
636
636
|
|
|
637
637
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
638
638
|
|
|
639
639
|
const command = createIndexCommand(getOptions);
|
|
640
|
-
const watchCmd = command.commands.find(c => c.name() === 'watch');
|
|
640
|
+
const watchCmd = command.commands.find((c) => c.name() === 'watch');
|
|
641
641
|
const action = watchCmd!._actionHandler;
|
|
642
642
|
await expect(action(['web-store'])).rejects.toThrow('process.exit: 3');
|
|
643
643
|
|
|
@@ -653,7 +653,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
653
653
|
config: '/custom/config.json',
|
|
654
654
|
dataDir: '/custom/data',
|
|
655
655
|
quiet: false,
|
|
656
|
-
format: undefined
|
|
656
|
+
format: undefined,
|
|
657
657
|
});
|
|
658
658
|
|
|
659
659
|
const mockStore: Store = {
|
|
@@ -662,7 +662,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
662
662
|
type: 'file',
|
|
663
663
|
path: '/test',
|
|
664
664
|
createdAt: new Date(),
|
|
665
|
-
updatedAt: new Date()
|
|
665
|
+
updatedAt: new Date(),
|
|
666
666
|
};
|
|
667
667
|
|
|
668
668
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(mockStore);
|
|
@@ -671,8 +671,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
671
671
|
data: {
|
|
672
672
|
documentsIndexed: 1,
|
|
673
673
|
chunksCreated: 1,
|
|
674
|
-
timeMs: 100
|
|
675
|
-
}
|
|
674
|
+
timeMs: 100,
|
|
675
|
+
},
|
|
676
676
|
});
|
|
677
677
|
|
|
678
678
|
const command = createIndexCommand(getOptions);
|
|
@@ -690,7 +690,7 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
690
690
|
type: 'file',
|
|
691
691
|
path: '/test',
|
|
692
692
|
createdAt: new Date(),
|
|
693
|
-
updatedAt: new Date()
|
|
693
|
+
updatedAt: new Date(),
|
|
694
694
|
};
|
|
695
695
|
|
|
696
696
|
vi.mocked(mockServices.store.getByIdOrName).mockImplementation(async () => {
|
|
@@ -707,8 +707,8 @@ describe('createIndexCommand - Execution Tests', () => {
|
|
|
707
707
|
data: {
|
|
708
708
|
documentsIndexed: 1,
|
|
709
709
|
chunksCreated: 1,
|
|
710
|
-
timeMs: 100
|
|
711
|
-
}
|
|
710
|
+
timeMs: 100,
|
|
711
|
+
},
|
|
712
712
|
};
|
|
713
713
|
});
|
|
714
714
|
|
|
@@ -11,63 +11,79 @@ export function createIndexCommand(getOptions: () => GlobalOptions): Command {
|
|
|
11
11
|
.action(async (storeIdOrName: string, _options: { force?: boolean }) => {
|
|
12
12
|
const globalOpts = getOptions();
|
|
13
13
|
const services = await createServices(globalOpts.config, globalOpts.dataDir);
|
|
14
|
+
let exitCode = 0;
|
|
14
15
|
try {
|
|
15
|
-
|
|
16
|
+
indexLogic: {
|
|
17
|
+
const store = await services.store.getByIdOrName(storeIdOrName);
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
19
|
+
if (store === undefined) {
|
|
20
|
+
console.error(`Error: Store not found: ${storeIdOrName}`);
|
|
21
|
+
exitCode = 3;
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
let spinner: Ora | undefined;
|
|
23
|
+
break indexLogic;
|
|
24
|
+
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
26
|
+
// Use spinner in interactive mode (not quiet, not json output)
|
|
27
|
+
const isInteractive =
|
|
28
|
+
process.stdout.isTTY && globalOpts.quiet !== true && globalOpts.format !== 'json';
|
|
29
|
+
let spinner: Ora | undefined;
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
if (isInteractive) {
|
|
32
|
+
spinner = ora(`Indexing store: ${store.name}`).start();
|
|
33
|
+
} else if (globalOpts.quiet !== true && globalOpts.format !== 'json') {
|
|
34
|
+
console.log(`Indexing store: ${store.name}`);
|
|
35
|
+
}
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
await services.lance.initialize(store.id);
|
|
38
|
+
|
|
39
|
+
const result = await services.index.indexStore(store, (event) => {
|
|
40
|
+
if (event.type === 'progress') {
|
|
41
|
+
if (spinner) {
|
|
42
|
+
spinner.text = `Indexing: ${String(event.current)}/${String(event.total)} files - ${event.message}`;
|
|
43
|
+
}
|
|
38
44
|
}
|
|
39
|
-
}
|
|
40
|
-
});
|
|
45
|
+
});
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
if (result.success) {
|
|
48
|
+
if (globalOpts.format === 'json') {
|
|
49
|
+
console.log(JSON.stringify(result.data, null, 2));
|
|
50
|
+
} else {
|
|
51
|
+
const message = `Indexed ${String(result.data.documentsIndexed)} documents, ${String(result.data.chunksCreated)} chunks in ${String(result.data.timeMs)}ms`;
|
|
52
|
+
if (spinner !== undefined) {
|
|
53
|
+
spinner.succeed(message);
|
|
54
|
+
} else if (globalOpts.quiet !== true) {
|
|
55
|
+
console.log(message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
45
58
|
} else {
|
|
46
|
-
const message = `
|
|
59
|
+
const message = `Error: ${result.error.message}`;
|
|
47
60
|
if (spinner !== undefined) {
|
|
48
|
-
spinner.
|
|
49
|
-
} else
|
|
50
|
-
console.
|
|
61
|
+
spinner.fail(message);
|
|
62
|
+
} else {
|
|
63
|
+
console.error(message);
|
|
51
64
|
}
|
|
65
|
+
exitCode = 4;
|
|
66
|
+
|
|
67
|
+
break indexLogic;
|
|
52
68
|
}
|
|
53
|
-
} else {
|
|
54
|
-
const message = `Error: ${result.error.message}`;
|
|
55
|
-
if (spinner !== undefined) {
|
|
56
|
-
spinner.fail(message);
|
|
57
|
-
} else {
|
|
58
|
-
console.error(message);
|
|
59
|
-
}
|
|
60
|
-
process.exit(4);
|
|
61
69
|
}
|
|
62
70
|
} finally {
|
|
63
71
|
await destroyServices(services);
|
|
64
72
|
}
|
|
73
|
+
|
|
74
|
+
if (exitCode !== 0) {
|
|
75
|
+
process.exit(exitCode);
|
|
76
|
+
}
|
|
65
77
|
});
|
|
66
78
|
|
|
67
79
|
index
|
|
68
80
|
.command('watch <store>')
|
|
69
81
|
.description('Watch store directory; re-index when files change')
|
|
70
|
-
.option(
|
|
82
|
+
.option(
|
|
83
|
+
'--debounce <ms>',
|
|
84
|
+
'Wait N ms after last change before re-indexing (default: 1000)',
|
|
85
|
+
'1000'
|
|
86
|
+
)
|
|
71
87
|
.action(async (storeIdOrName: string, options: { debounce?: string }) => {
|
|
72
88
|
const globalOpts = getOptions();
|
|
73
89
|
const services = await createServices(globalOpts.config, globalOpts.dataDir);
|