mdcontext 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/config.json +9 -9
- package/.claude/settings.local.json +25 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +85 -0
- package/CONTRIBUTING.md +186 -0
- package/NOTES/NOTES +44 -0
- package/README.md +206 -3
- package/biome.json +1 -1
- package/dist/chunk-23UPXDNL.js +3044 -0
- package/dist/chunk-2W7MO2DL.js +1366 -0
- package/dist/chunk-3NUAZGMA.js +1689 -0
- package/dist/chunk-7TOWB2XB.js +366 -0
- package/dist/chunk-7XOTOADQ.js +3065 -0
- package/dist/chunk-AH2PDM2K.js +3042 -0
- package/dist/chunk-BNXWSZ63.js +3742 -0
- package/dist/chunk-BTL5DJVU.js +3222 -0
- package/dist/chunk-HDHYG7E4.js +104 -0
- package/dist/chunk-HLR4KZBP.js +3234 -0
- package/dist/chunk-IP3FRFEB.js +1045 -0
- package/dist/chunk-KHU56VDO.js +3042 -0
- package/dist/chunk-KRYIFLQR.js +85 -89
- package/dist/chunk-LBSDNLEM.js +287 -0
- package/dist/chunk-MNTQ7HCP.js +2643 -0
- package/dist/chunk-MUJELQQ6.js +1387 -0
- package/dist/chunk-MXJGMSLV.js +2199 -0
- package/dist/chunk-N6QJGC3Z.js +2636 -0
- package/dist/chunk-OBELGBPM.js +1713 -0
- package/dist/chunk-OT7R5XTA.js +3192 -0
- package/dist/chunk-P7X4RA2T.js +106 -0
- package/dist/chunk-PIDUQNC2.js +3185 -0
- package/dist/chunk-POGCDIH4.js +3187 -0
- package/dist/chunk-PSIEOQGZ.js +3043 -0
- package/dist/chunk-PVRT3IHA.js +3238 -0
- package/dist/chunk-QNN4TT23.js +1430 -0
- package/dist/chunk-RE3R45RJ.js +3042 -0
- package/dist/chunk-S7E6TFX6.js +718 -657
- package/dist/chunk-SG6GLU4U.js +1378 -0
- package/dist/chunk-SJCDV2ST.js +274 -0
- package/dist/chunk-SYE5XLF3.js +104 -0
- package/dist/chunk-T5VLYBZD.js +103 -0
- package/dist/chunk-TOQB7VWU.js +3238 -0
- package/dist/chunk-VFNMZ4ZQ.js +3228 -0
- package/dist/chunk-VVTGZNBT.js +1533 -1423
- package/dist/chunk-W7Q4RFEV.js +104 -0
- package/dist/chunk-XTYYVRLO.js +3190 -0
- package/dist/chunk-Y6MDYVJD.js +3063 -0
- package/dist/cli/main.js +4072 -629
- package/dist/index.d.ts +420 -33
- package/dist/index.js +8 -15
- package/dist/mcp/server.js +103 -7
- package/dist/schema-BAWSG7KY.js +22 -0
- package/dist/schema-E3QUPL26.js +20 -0
- package/dist/schema-EHL7WUT6.js +20 -0
- package/docs/019-USAGE.md +44 -5
- package/docs/020-current-implementation.md +8 -8
- package/docs/021-DOGFOODING-FINDINGS.md +1 -1
- package/docs/CONFIG.md +1123 -0
- package/docs/ERRORS.md +383 -0
- package/docs/summarization.md +320 -0
- package/justfile +40 -0
- package/package.json +39 -33
- package/research/INDEX.md +315 -0
- package/research/code-review/README.md +90 -0
- package/research/code-review/cli-error-handling-review.md +979 -0
- package/research/code-review/code-review-validation-report.md +464 -0
- package/research/code-review/main-ts-review.md +1128 -0
- package/research/config-docs/SUMMARY.md +357 -0
- package/research/config-docs/TEST-RESULTS.md +776 -0
- package/research/config-docs/TODO.md +542 -0
- package/research/config-docs/analysis.md +744 -0
- package/research/config-docs/fix-validation.md +502 -0
- package/research/config-docs/help-audit.md +264 -0
- package/research/config-docs/help-system-analysis.md +890 -0
- package/research/frontmatter/COMMENTS-ARE-SKIPPED.md +149 -0
- package/research/frontmatter/LLM-CODE-NAVIGATION.md +276 -0
- package/research/issue-review.md +603 -0
- package/research/llm-summarization/agent-cli-tools-2026.md +1082 -0
- package/research/llm-summarization/alternative-providers-2026.md +1428 -0
- package/research/llm-summarization/anthropic-2026.md +367 -0
- package/research/llm-summarization/claude-cli-integration.md +1706 -0
- package/research/llm-summarization/cli-integration-patterns.md +3155 -0
- package/research/llm-summarization/openai-2026.md +473 -0
- package/research/llm-summarization/openai-compatible-providers-2026.md +1022 -0
- package/research/llm-summarization/opencode-cli-integration.md +1552 -0
- package/research/llm-summarization/prompt-engineering-2026.md +1426 -0
- package/research/llm-summarization/prototype-results.md +56 -0
- package/research/llm-summarization/provider-switching-patterns-2026.md +2153 -0
- package/research/llm-summarization/typescript-llm-libraries-2026.md +2436 -0
- package/research/mdcontext-pudding/00-EXECUTIVE-SUMMARY.md +282 -0
- package/research/mdcontext-pudding/01-index-embed.md +956 -0
- package/research/mdcontext-pudding/02-search-COMMANDS.md +142 -0
- package/research/mdcontext-pudding/02-search-SUMMARY.md +146 -0
- package/research/mdcontext-pudding/02-search.md +970 -0
- package/research/mdcontext-pudding/03-context.md +779 -0
- package/research/mdcontext-pudding/04-navigation-and-analytics.md +803 -0
- package/research/mdcontext-pudding/04-tree.md +704 -0
- package/research/mdcontext-pudding/05-config.md +1038 -0
- package/research/mdcontext-pudding/06-links-summary.txt +87 -0
- package/research/mdcontext-pudding/06-links.md +679 -0
- package/research/mdcontext-pudding/07-stats.md +693 -0
- package/research/mdcontext-pudding/BUG-FIX-PLAN.md +388 -0
- package/research/mdcontext-pudding/P0-BUG-VALIDATION.md +167 -0
- package/research/mdcontext-pudding/README.md +168 -0
- package/research/mdcontext-pudding/TESTING-SUMMARY.md +128 -0
- package/research/research-quality-review.md +834 -0
- package/research/semantic-search/embedding-text-analysis.md +156 -0
- package/research/semantic-search/multi-word-failure-reproduction.md +171 -0
- package/research/semantic-search/query-processing-analysis.md +207 -0
- package/research/semantic-search/root-cause-and-solution.md +114 -0
- package/research/semantic-search/threshold-validation-report.md +69 -0
- package/research/semantic-search/vector-search-analysis.md +63 -0
- package/research/test-path-issues.md +276 -0
- package/review/ALP-76/1-error-type-design.md +962 -0
- package/review/ALP-76/2-error-handling-patterns.md +906 -0
- package/review/ALP-76/3-error-presentation.md +624 -0
- package/review/ALP-76/4-test-coverage.md +625 -0
- package/review/ALP-76/5-migration-completeness.md +440 -0
- package/review/ALP-76/6-effect-best-practices.md +755 -0
- package/scripts/apply-branch-protection.sh +47 -0
- package/scripts/branch-protection-templates.json +79 -0
- package/scripts/prototype-summarization.ts +346 -0
- package/scripts/rebuild-hnswlib.js +32 -37
- package/scripts/setup-branch-protection.sh +64 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/active-provider.json +7 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.json +541 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.meta.json +5 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/config.json +8 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/documents.json +60 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/links.json +13 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/sections.json +1197 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/configuration-management.md +99 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/distributed-systems.md +92 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/error-handling.md +78 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/failure-automation.md +55 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/job-context.md +69 -0
- package/src/__tests__/fixtures/semantic-search/multi-word-corpus/process-orchestration.md +99 -0
- package/src/cli/argv-preprocessor.test.ts +2 -2
- package/src/cli/cli.test.ts +230 -33
- package/src/cli/commands/config-cmd.ts +642 -0
- package/src/cli/commands/context.ts +97 -9
- package/src/cli/commands/duplicates.ts +122 -0
- package/src/cli/commands/embeddings.ts +529 -0
- package/src/cli/commands/index-cmd.ts +210 -30
- package/src/cli/commands/index.ts +3 -0
- package/src/cli/commands/search.ts +894 -64
- package/src/cli/commands/stats.ts +3 -0
- package/src/cli/commands/tree.ts +26 -5
- package/src/cli/config-layer.ts +176 -0
- package/src/cli/error-handler.test.ts +235 -0
- package/src/cli/error-handler.ts +655 -0
- package/src/cli/flag-schemas.ts +66 -0
- package/src/cli/help.ts +209 -7
- package/src/cli/main.ts +348 -58
- package/src/cli/options.ts +10 -0
- package/src/cli/shared-error-handling.ts +199 -0
- package/src/cli/utils.ts +150 -17
- package/src/config/file-provider.test.ts +320 -0
- package/src/config/file-provider.ts +273 -0
- package/src/config/index.ts +72 -0
- package/src/config/integration.test.ts +667 -0
- package/src/config/precedence.test.ts +277 -0
- package/src/config/precedence.ts +451 -0
- package/src/config/schema.test.ts +414 -0
- package/src/config/schema.ts +603 -0
- package/src/config/service.test.ts +320 -0
- package/src/config/service.ts +243 -0
- package/src/config/testing.test.ts +264 -0
- package/src/config/testing.ts +110 -0
- package/src/core/types.ts +6 -33
- package/src/duplicates/detector.test.ts +183 -0
- package/src/duplicates/detector.ts +414 -0
- package/src/duplicates/index.ts +18 -0
- package/src/embeddings/embedding-namespace.test.ts +300 -0
- package/src/embeddings/embedding-namespace.ts +947 -0
- package/src/embeddings/heading-boost.test.ts +222 -0
- package/src/embeddings/hnsw-build-options.test.ts +198 -0
- package/src/embeddings/hyde.test.ts +272 -0
- package/src/embeddings/hyde.ts +264 -0
- package/src/embeddings/index.ts +2 -0
- package/src/embeddings/openai-provider.ts +332 -83
- package/src/embeddings/pricing.json +22 -0
- package/src/embeddings/provider-constants.ts +204 -0
- package/src/embeddings/provider-errors.test.ts +967 -0
- package/src/embeddings/provider-errors.ts +565 -0
- package/src/embeddings/provider-factory.test.ts +240 -0
- package/src/embeddings/provider-factory.ts +225 -0
- package/src/embeddings/provider-integration.test.ts +788 -0
- package/src/embeddings/query-preprocessing.test.ts +187 -0
- package/src/embeddings/semantic-search-threshold.test.ts +508 -0
- package/src/embeddings/semantic-search.ts +780 -93
- package/src/embeddings/types.ts +293 -16
- package/src/embeddings/vector-store.ts +486 -77
- package/src/embeddings/voyage-provider.ts +313 -0
- package/src/errors/errors.test.ts +845 -0
- package/src/errors/index.ts +533 -0
- package/src/index/ignore-patterns.test.ts +354 -0
- package/src/index/ignore-patterns.ts +305 -0
- package/src/index/indexer.ts +286 -48
- package/src/index/storage.ts +94 -30
- package/src/index/types.ts +40 -2
- package/src/index/watcher.ts +67 -9
- package/src/index.ts +22 -0
- package/src/integration/search-keyword.test.ts +678 -0
- package/src/mcp/server.ts +135 -6
- package/src/parser/parser.ts +18 -19
- package/src/parser/section-filter.test.ts +277 -0
- package/src/parser/section-filter.ts +125 -3
- package/src/search/__tests__/hybrid-search.test.ts +650 -0
- package/src/search/bm25-store.ts +366 -0
- package/src/search/cross-encoder.test.ts +253 -0
- package/src/search/cross-encoder.ts +406 -0
- package/src/search/fuzzy-search.test.ts +419 -0
- package/src/search/fuzzy-search.ts +273 -0
- package/src/search/hybrid-search.ts +448 -0
- package/src/search/path-matcher.test.ts +276 -0
- package/src/search/path-matcher.ts +33 -0
- package/src/search/searcher.test.ts +99 -1
- package/src/search/searcher.ts +189 -67
- package/src/search/wink-bm25.d.ts +30 -0
- package/src/summarization/cli-providers/claude.ts +202 -0
- package/src/summarization/cli-providers/detection.test.ts +273 -0
- package/src/summarization/cli-providers/detection.ts +118 -0
- package/src/summarization/cli-providers/index.ts +8 -0
- package/src/summarization/cost.test.ts +139 -0
- package/src/summarization/cost.ts +102 -0
- package/src/summarization/error-handler.test.ts +127 -0
- package/src/summarization/error-handler.ts +111 -0
- package/src/summarization/index.ts +102 -0
- package/src/summarization/pipeline.test.ts +498 -0
- package/src/summarization/pipeline.ts +231 -0
- package/src/summarization/prompts.test.ts +269 -0
- package/src/summarization/prompts.ts +133 -0
- package/src/summarization/provider-factory.test.ts +396 -0
- package/src/summarization/provider-factory.ts +178 -0
- package/src/summarization/types.ts +184 -0
- package/src/summarize/summarizer.ts +104 -35
- package/src/types/huggingface-transformers.d.ts +66 -0
- package/tests/fixtures/cli/.mdcontext/active-provider.json +7 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/indexes/documents.json +4 -4
- package/tests/fixtures/cli/.mdcontext/indexes/sections.json +14 -0
- package/tests/integration/embed-index.test.ts +712 -0
- package/tests/integration/search-context.test.ts +469 -0
- package/tests/integration/search-semantic.test.ts +522 -0
- package/vitest.config.ts +1 -6
- package/AGENTS.md +0 -46
- package/tests/fixtures/cli/.mdcontext/vectors.bin +0 -0
- package/tests/fixtures/cli/.mdcontext/vectors.meta.json +0 -1264
package/src/cli/cli.test.ts
CHANGED
|
@@ -177,48 +177,66 @@ describe.concurrent('mdcontext CLI e2e', () => {
|
|
|
177
177
|
expect(output).toContain('Results:')
|
|
178
178
|
})
|
|
179
179
|
|
|
180
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
181
|
+
'handles no results gracefully',
|
|
182
|
+
async () => {
|
|
183
|
+
const output = await run('search "xyznonexistent123"')
|
|
184
|
+
expect(output).toContain('Results: 0')
|
|
185
|
+
},
|
|
186
|
+
)
|
|
184
187
|
|
|
185
188
|
it('supports -k flag for explicit keyword search', async () => {
|
|
186
189
|
const output = await run('search -k "API Reference"')
|
|
187
190
|
expect(output).toContain('Content search')
|
|
188
191
|
})
|
|
189
192
|
|
|
190
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
194
|
+
'supports -n flag to limit results',
|
|
195
|
+
async () => {
|
|
196
|
+
const output = await run('search -n 2 "the"')
|
|
197
|
+
const lines = output
|
|
198
|
+
.split('\n')
|
|
199
|
+
.filter((l) => l.trim().match(/^\w+.*\.md/))
|
|
200
|
+
expect(lines.length).toBeLessThanOrEqual(2)
|
|
201
|
+
},
|
|
202
|
+
)
|
|
197
203
|
|
|
198
204
|
it('shows mode indicator in output', async () => {
|
|
199
205
|
const output = await run('search -k "getting started"')
|
|
200
206
|
expect(output).toContain('[keyword]')
|
|
201
207
|
})
|
|
202
208
|
|
|
203
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
210
|
+
'supports boolean AND operator',
|
|
211
|
+
async () => {
|
|
212
|
+
const output = await run('search "test AND fixture"')
|
|
213
|
+
expect(output).toContain('Results:')
|
|
214
|
+
},
|
|
215
|
+
)
|
|
207
216
|
|
|
208
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
217
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
218
|
+
'supports boolean OR operator',
|
|
219
|
+
async () => {
|
|
220
|
+
const output = await run('search "installation OR endpoints"')
|
|
221
|
+
expect(output).toContain('Results:')
|
|
222
|
+
},
|
|
223
|
+
)
|
|
212
224
|
|
|
213
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
226
|
+
'supports boolean NOT operator',
|
|
227
|
+
async () => {
|
|
228
|
+
const output = await run('search "test NOT endpoints"')
|
|
229
|
+
expect(output).toContain('Results:')
|
|
230
|
+
},
|
|
231
|
+
)
|
|
217
232
|
|
|
218
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
233
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
234
|
+
'supports quoted phrase search',
|
|
235
|
+
async () => {
|
|
236
|
+
const output = await run('search \'"Getting Started"\' .')
|
|
237
|
+
expect(output).toContain('Results:')
|
|
238
|
+
},
|
|
239
|
+
)
|
|
222
240
|
|
|
223
241
|
it('supports --mode flag', async () => {
|
|
224
242
|
const output = await run('search --mode keyword "getting started"')
|
|
@@ -292,10 +310,13 @@ describe.concurrent('mdcontext CLI e2e', () => {
|
|
|
292
310
|
expect(output).toContain('[keyword]')
|
|
293
311
|
})
|
|
294
312
|
|
|
295
|
-
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
313
|
+
it.skipIf(!INCLUDE_EMBED_TESTS)(
|
|
314
|
+
'supports -B and -A flags for asymmetric context',
|
|
315
|
+
async () => {
|
|
316
|
+
const output = await run('search "test" . -B 1 -A 3')
|
|
317
|
+
expect(output).toContain('[semantic]')
|
|
318
|
+
},
|
|
319
|
+
)
|
|
299
320
|
|
|
300
321
|
it('includes contextLines in JSON output', async () => {
|
|
301
322
|
const output = await run('search -k "test" . -C 2 --json -n 1')
|
|
@@ -349,8 +370,8 @@ describe.concurrent('mdcontext CLI e2e', () => {
|
|
|
349
370
|
|
|
350
371
|
describe('unknown flag handling', () => {
|
|
351
372
|
it('shows clear error for unknown flag', async () => {
|
|
352
|
-
const output = await run('context -
|
|
353
|
-
expect(output).toContain("Unknown option '-
|
|
373
|
+
const output = await run('context -z README.md', { expectError: true })
|
|
374
|
+
expect(output).toContain("Unknown option '-z' for 'context'")
|
|
354
375
|
expect(output).toContain('Valid options for')
|
|
355
376
|
})
|
|
356
377
|
|
|
@@ -427,4 +448,180 @@ describe.concurrent('mdcontext CLI e2e', () => {
|
|
|
427
448
|
expect(output).toContain('Content search')
|
|
428
449
|
})
|
|
429
450
|
})
|
|
451
|
+
|
|
452
|
+
describe('config loading error handling', () => {
|
|
453
|
+
it('shows error for non-existent config file', async () => {
|
|
454
|
+
const output = await run('--config /nonexistent/path.json --help', {
|
|
455
|
+
expectError: true,
|
|
456
|
+
})
|
|
457
|
+
expect(output).toContain('Error: Config file not found')
|
|
458
|
+
expect(output).toContain('path.json')
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
it('shows error for invalid JSON config file', async () => {
|
|
462
|
+
// Create a temp file with invalid JSON
|
|
463
|
+
const fs = await import('node:fs')
|
|
464
|
+
const os = await import('node:os')
|
|
465
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
466
|
+
const invalidConfigPath = path.join(tempDir, 'invalid.json')
|
|
467
|
+
fs.writeFileSync(invalidConfigPath, 'not valid json { broken')
|
|
468
|
+
|
|
469
|
+
try {
|
|
470
|
+
const output = await run(`--config ${invalidConfigPath} --help`, {
|
|
471
|
+
expectError: true,
|
|
472
|
+
})
|
|
473
|
+
expect(output).toContain('Error: Invalid JSON in config file')
|
|
474
|
+
expect(output).toContain(invalidConfigPath)
|
|
475
|
+
} finally {
|
|
476
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
477
|
+
}
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
it('shows error for JS config that exports non-object', async () => {
|
|
481
|
+
const fs = await import('node:fs')
|
|
482
|
+
const os = await import('node:os')
|
|
483
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
484
|
+
const badConfigPath = path.join(tempDir, 'bad.config.mjs')
|
|
485
|
+
fs.writeFileSync(badConfigPath, 'export default "not an object"')
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
const output = await run(`--config ${badConfigPath} --help`, {
|
|
489
|
+
expectError: true,
|
|
490
|
+
})
|
|
491
|
+
expect(output).toContain(
|
|
492
|
+
'Error: Config file must export a default object',
|
|
493
|
+
)
|
|
494
|
+
expect(output).toContain(badConfigPath)
|
|
495
|
+
} finally {
|
|
496
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
497
|
+
}
|
|
498
|
+
})
|
|
499
|
+
|
|
500
|
+
it('shows error for JS config that exports null', async () => {
|
|
501
|
+
const fs = await import('node:fs')
|
|
502
|
+
const os = await import('node:os')
|
|
503
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
504
|
+
const nullConfigPath = path.join(tempDir, 'null.config.mjs')
|
|
505
|
+
fs.writeFileSync(nullConfigPath, 'export default null')
|
|
506
|
+
|
|
507
|
+
try {
|
|
508
|
+
const output = await run(`--config ${nullConfigPath} --help`, {
|
|
509
|
+
expectError: true,
|
|
510
|
+
})
|
|
511
|
+
expect(output).toContain(
|
|
512
|
+
'Error: Config file must export a default object',
|
|
513
|
+
)
|
|
514
|
+
expect(output).toContain(nullConfigPath)
|
|
515
|
+
} finally {
|
|
516
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
517
|
+
}
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
it('shows error for JS config that exports array', async () => {
|
|
521
|
+
const fs = await import('node:fs')
|
|
522
|
+
const os = await import('node:os')
|
|
523
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
524
|
+
const arrayConfigPath = path.join(tempDir, 'array.config.mjs')
|
|
525
|
+
fs.writeFileSync(
|
|
526
|
+
arrayConfigPath,
|
|
527
|
+
'export default [{ index: { maxDepth: 5 } }]',
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
try {
|
|
531
|
+
const output = await run(`--config ${arrayConfigPath} --help`, {
|
|
532
|
+
expectError: true,
|
|
533
|
+
})
|
|
534
|
+
expect(output).toContain(
|
|
535
|
+
'Error: Config file must export a default object',
|
|
536
|
+
)
|
|
537
|
+
expect(output).toContain(arrayConfigPath)
|
|
538
|
+
} finally {
|
|
539
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
540
|
+
}
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
it('shows error for JS config with syntax error', async () => {
|
|
544
|
+
const fs = await import('node:fs')
|
|
545
|
+
const os = await import('node:os')
|
|
546
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
547
|
+
const syntaxErrorPath = path.join(tempDir, 'syntax-error.config.mjs')
|
|
548
|
+
fs.writeFileSync(
|
|
549
|
+
syntaxErrorPath,
|
|
550
|
+
'export default { invalid syntax here >>>',
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
try {
|
|
554
|
+
const output = await run(`--config ${syntaxErrorPath} --help`, {
|
|
555
|
+
expectError: true,
|
|
556
|
+
})
|
|
557
|
+
expect(output).toContain('Error')
|
|
558
|
+
} finally {
|
|
559
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
560
|
+
}
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
it('shows error for JS config with no exports', async () => {
|
|
564
|
+
const fs = await import('node:fs')
|
|
565
|
+
const os = await import('node:os')
|
|
566
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
567
|
+
const noExportPath = path.join(tempDir, 'no-export.config.mjs')
|
|
568
|
+
fs.writeFileSync(
|
|
569
|
+
noExportPath,
|
|
570
|
+
'const config = { index: { maxDepth: 5 } }; // no export',
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
try {
|
|
574
|
+
const output = await run(`--config ${noExportPath} --help`, {
|
|
575
|
+
expectError: true,
|
|
576
|
+
})
|
|
577
|
+
expect(output).toContain(
|
|
578
|
+
'Error: Config file must export a default object',
|
|
579
|
+
)
|
|
580
|
+
} finally {
|
|
581
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
582
|
+
}
|
|
583
|
+
})
|
|
584
|
+
|
|
585
|
+
it('loads valid JSON config file successfully', async () => {
|
|
586
|
+
const fs = await import('node:fs')
|
|
587
|
+
const os = await import('node:os')
|
|
588
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
589
|
+
const validConfigPath = path.join(tempDir, 'valid.json')
|
|
590
|
+
fs.writeFileSync(
|
|
591
|
+
validConfigPath,
|
|
592
|
+
JSON.stringify({ index: { maxDepth: 5 } }),
|
|
593
|
+
)
|
|
594
|
+
|
|
595
|
+
try {
|
|
596
|
+
const output = await run(`--config ${validConfigPath} --help`)
|
|
597
|
+
// Should show help without errors
|
|
598
|
+
expect(output).toContain('index')
|
|
599
|
+
expect(output).toContain('search')
|
|
600
|
+
expect(output).not.toContain('Error')
|
|
601
|
+
} finally {
|
|
602
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
603
|
+
}
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
it('loads valid MJS config file successfully', async () => {
|
|
607
|
+
const fs = await import('node:fs')
|
|
608
|
+
const os = await import('node:os')
|
|
609
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mdcontext-test-'))
|
|
610
|
+
const validConfigPath = path.join(tempDir, 'valid.config.mjs')
|
|
611
|
+
fs.writeFileSync(
|
|
612
|
+
validConfigPath,
|
|
613
|
+
'export default { index: { maxDepth: 5 } }',
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
try {
|
|
617
|
+
const output = await run(`--config ${validConfigPath} --help`)
|
|
618
|
+
// Should show help without errors
|
|
619
|
+
expect(output).toContain('index')
|
|
620
|
+
expect(output).toContain('search')
|
|
621
|
+
expect(output).not.toContain('Error')
|
|
622
|
+
} finally {
|
|
623
|
+
fs.rmSync(tempDir, { recursive: true, force: true })
|
|
624
|
+
}
|
|
625
|
+
})
|
|
626
|
+
})
|
|
430
627
|
})
|