mdcontext 0.0.1 → 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/README.md +28 -0
- package/.changeset/config.json +11 -0
- package/.claude/settings.local.json +25 -0
- package/.github/workflows/ci.yml +83 -0
- package/.github/workflows/claude-code-review.yml +44 -0
- package/.github/workflows/claude.yml +85 -0
- package/.github/workflows/release.yml +113 -0
- package/.tldrignore +112 -0
- package/BACKLOG.md +338 -0
- package/CONTRIBUTING.md +186 -0
- package/NOTES/NOTES +44 -0
- package/README.md +434 -11
- package/biome.json +36 -0
- package/cspell.config.yaml +14 -0
- 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 +88 -0
- 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 +803 -0
- 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 +1629 -0
- 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.d.ts +1 -0
- package/dist/cli/main.js +5458 -0
- package/dist/index.d.ts +653 -0
- package/dist/index.js +79 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +472 -0
- 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 +625 -0
- package/docs/020-current-implementation.md +364 -0
- package/docs/021-DOGFOODING-FINDINGS.md +175 -0
- package/docs/BACKLOG.md +80 -0
- package/docs/CONFIG.md +1123 -0
- package/docs/DESIGN.md +439 -0
- package/docs/ERRORS.md +383 -0
- package/docs/PROJECT.md +88 -0
- package/docs/ROADMAP.md +407 -0
- package/docs/summarization.md +320 -0
- package/docs/test-links.md +9 -0
- package/justfile +40 -0
- package/package.json +74 -9
- package/pnpm-workspace.yaml +5 -0
- 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-analysis/01-current-implementation.md +470 -0
- package/research/config-analysis/02-strategy-recommendation.md +428 -0
- package/research/config-analysis/03-task-candidates.md +715 -0
- package/research/config-analysis/033-research-configuration-management.md +828 -0
- package/research/config-analysis/034-research-effect-cli-config.md +1504 -0
- package/research/config-analysis/04-consolidated-task-candidates.md +277 -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/dogfood/consolidated-tool-evaluation.md +373 -0
- package/research/dogfood/strategy-a/a-synthesis.md +184 -0
- package/research/dogfood/strategy-a/a1-docs.md +226 -0
- package/research/dogfood/strategy-a/a2-amorphic.md +156 -0
- package/research/dogfood/strategy-a/a3-llm.md +164 -0
- package/research/dogfood/strategy-b/b-synthesis.md +228 -0
- package/research/dogfood/strategy-b/b1-architecture.md +207 -0
- package/research/dogfood/strategy-b/b2-gaps.md +258 -0
- package/research/dogfood/strategy-b/b3-workflows.md +250 -0
- package/research/dogfood/strategy-c/c-synthesis.md +451 -0
- package/research/dogfood/strategy-c/c1-explorer.md +192 -0
- package/research/dogfood/strategy-c/c2-diver-memory.md +145 -0
- package/research/dogfood/strategy-c/c3-diver-control.md +148 -0
- package/research/dogfood/strategy-c/c4-diver-failure.md +151 -0
- package/research/dogfood/strategy-c/c5-diver-execution.md +221 -0
- package/research/dogfood/strategy-c/c6-diver-org.md +221 -0
- package/research/effect-cli-error-handling.md +845 -0
- package/research/effect-errors-as-values.md +943 -0
- package/research/errors-task-analysis/00-consolidated-tasks.md +207 -0
- package/research/errors-task-analysis/cli-commands-analysis.md +909 -0
- package/research/errors-task-analysis/embeddings-analysis.md +709 -0
- package/research/errors-task-analysis/index-search-analysis.md +812 -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-error-analysis.md +521 -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/npm_publish/011-npm-workflow-research-agent2.md +792 -0
- package/research/npm_publish/012-npm-workflow-research-agent1.md +530 -0
- package/research/npm_publish/013-npm-workflow-research-agent3.md +722 -0
- package/research/npm_publish/014-npm-workflow-synthesis.md +556 -0
- package/research/npm_publish/031-npm-workflow-task-analysis.md +134 -0
- package/research/research-quality-review.md +834 -0
- package/research/semantic-search/002-research-embedding-models.md +490 -0
- package/research/semantic-search/003-research-rag-alternatives.md +523 -0
- package/research/semantic-search/004-research-vector-search.md +841 -0
- package/research/semantic-search/032-research-semantic-search.md +427 -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/task-management-2026/00-synthesis-recommendations.md +295 -0
- package/research/task-management-2026/01-ai-workflow-tools.md +416 -0
- package/research/task-management-2026/02-agent-framework-patterns.md +476 -0
- package/research/task-management-2026/03-lightweight-file-based.md +567 -0
- package/research/task-management-2026/04-established-tools-ai-features.md +541 -0
- package/research/task-management-2026/linear/01-core-features-workflow.md +771 -0
- package/research/task-management-2026/linear/02-api-integrations.md +930 -0
- package/research/task-management-2026/linear/03-ai-features.md +368 -0
- package/research/task-management-2026/linear/04-pricing-setup.md +205 -0
- package/research/task-management-2026/linear/05-usage-patterns-best-practices.md +605 -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 +58 -0
- 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 +210 -0
- package/src/cli/argv-preprocessor.ts +202 -0
- package/src/cli/cli.test.ts +627 -0
- package/src/cli/commands/backlinks.ts +54 -0
- package/src/cli/commands/config-cmd.ts +642 -0
- package/src/cli/commands/context.ts +285 -0
- package/src/cli/commands/duplicates.ts +122 -0
- package/src/cli/commands/embeddings.ts +529 -0
- package/src/cli/commands/index-cmd.ts +480 -0
- package/src/cli/commands/index.ts +16 -0
- package/src/cli/commands/links.ts +52 -0
- package/src/cli/commands/search.ts +1281 -0
- package/src/cli/commands/stats.ts +149 -0
- package/src/cli/commands/tree.ts +128 -0
- 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 +341 -0
- package/src/cli/help.ts +588 -0
- package/src/cli/index.ts +9 -0
- package/src/cli/main.ts +435 -0
- package/src/cli/options.ts +41 -0
- package/src/cli/shared-error-handling.ts +199 -0
- package/src/cli/typo-suggester.test.ts +105 -0
- package/src/cli/typo-suggester.ts +130 -0
- package/src/cli/utils.ts +259 -0
- 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/index.ts +1 -0
- package/src/core/types.ts +113 -0
- 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 +10 -0
- package/src/embeddings/openai-provider.ts +414 -0
- 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 +1270 -0
- package/src/embeddings/types.ts +359 -0
- package/src/embeddings/vector-store.ts +708 -0
- 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/index.ts +4 -0
- package/src/index/indexer.ts +684 -0
- package/src/index/storage.ts +260 -0
- package/src/index/types.ts +147 -0
- package/src/index/watcher.ts +189 -0
- package/src/index.ts +30 -0
- package/src/integration/search-keyword.test.ts +678 -0
- package/src/mcp/server.ts +612 -0
- package/src/parser/index.ts +1 -0
- package/src/parser/parser.test.ts +291 -0
- package/src/parser/parser.ts +394 -0
- package/src/parser/section-filter.test.ts +277 -0
- package/src/parser/section-filter.ts +392 -0
- 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/query-parser.test.ts +260 -0
- package/src/search/query-parser.ts +319 -0
- package/src/search/searcher.test.ts +280 -0
- package/src/search/searcher.ts +724 -0
- 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/budget-bugs.test.ts +620 -0
- package/src/summarize/formatters.ts +419 -0
- package/src/summarize/index.ts +20 -0
- package/src/summarize/summarizer.test.ts +275 -0
- package/src/summarize/summarizer.ts +597 -0
- package/src/summarize/verify-bugs.test.ts +238 -0
- package/src/types/huggingface-transformers.d.ts +66 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/tokens.test.ts +142 -0
- package/src/utils/tokens.ts +186 -0
- package/tests/fixtures/cli/.mdcontext/active-provider.json +7 -0
- package/tests/fixtures/cli/.mdcontext/config.json +8 -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 +33 -0
- package/tests/fixtures/cli/.mdcontext/indexes/links.json +12 -0
- package/tests/fixtures/cli/.mdcontext/indexes/sections.json +247 -0
- package/tests/fixtures/cli/README.md +9 -0
- package/tests/fixtures/cli/api-reference.md +11 -0
- package/tests/fixtures/cli/getting-started.md +11 -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/tsconfig.json +26 -0
- package/vitest.config.ts +16 -0
- package/vitest.setup.ts +12 -0
package/docs/ERRORS.md
ADDED
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
# Error Handling Patterns
|
|
2
|
+
|
|
3
|
+
This document describes the error handling conventions used in mdcontext, following Effect's "errors as values" philosophy.
|
|
4
|
+
|
|
5
|
+
## Error Type Taxonomy
|
|
6
|
+
|
|
7
|
+
All domain errors are defined in `src/errors/index.ts` using Effect's `Data.TaggedError`:
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export class FileReadError extends Data.TaggedError('FileReadError')<{
|
|
11
|
+
readonly path: string
|
|
12
|
+
readonly message: string
|
|
13
|
+
readonly cause?: unknown
|
|
14
|
+
}> {
|
|
15
|
+
get code() { return ErrorCode.FILE_READ }
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Error Categories
|
|
20
|
+
|
|
21
|
+
- **File System**: `FileReadError`, `FileWriteError`, `DirectoryCreateError`, `DirectoryWalkError`
|
|
22
|
+
- **Parsing**: `ParseError` (for markdown parsing failures)
|
|
23
|
+
- **API**: `ApiKeyMissingError`, `ApiKeyInvalidError`
|
|
24
|
+
- **Embeddings**: `EmbeddingError` (rate limits, quota, network failures)
|
|
25
|
+
- **Index**: `IndexNotFoundError`, `IndexCorruptedError`, `IndexBuildError`
|
|
26
|
+
- **Search**: `DocumentNotFoundError`, `EmbeddingsNotFoundError`
|
|
27
|
+
- **Config**: `ConfigError`
|
|
28
|
+
- **Vector Store**: `VectorStoreError`
|
|
29
|
+
- **Watch**: `WatchError`
|
|
30
|
+
- **CLI**: `CliValidationError`
|
|
31
|
+
|
|
32
|
+
## Error Codes
|
|
33
|
+
|
|
34
|
+
Each error type has a unique error code for programmatic handling. Error codes are stable identifiers that don't change when messages are updated.
|
|
35
|
+
|
|
36
|
+
### Code Format
|
|
37
|
+
|
|
38
|
+
Codes follow the pattern `E{category}{number}`:
|
|
39
|
+
|
|
40
|
+
| Category | Code Range | Description |
|
|
41
|
+
|----------|------------|-------------|
|
|
42
|
+
| File System | E1xx | File and directory operations |
|
|
43
|
+
| Parse | E2xx | Markdown parsing errors |
|
|
44
|
+
| API | E3xx | API authentication and embedding errors |
|
|
45
|
+
| Index | E4xx | Index operations |
|
|
46
|
+
| Search | E5xx | Search operations |
|
|
47
|
+
| Vector Store | E6xx | Vector store operations |
|
|
48
|
+
| Config | E7xx | Configuration errors |
|
|
49
|
+
| Watch | E8xx | File watcher errors |
|
|
50
|
+
| CLI | E9xx | CLI validation errors |
|
|
51
|
+
|
|
52
|
+
### Error Code Reference
|
|
53
|
+
|
|
54
|
+
| Code | Error Type | Description |
|
|
55
|
+
|------|------------|-------------|
|
|
56
|
+
| E100 | FileReadError | Cannot read file |
|
|
57
|
+
| E101 | FileWriteError | Cannot write file |
|
|
58
|
+
| E102 | DirectoryCreateError | Cannot create directory |
|
|
59
|
+
| E103 | DirectoryWalkError | Cannot traverse directory |
|
|
60
|
+
| E200 | ParseError | Markdown parsing failed |
|
|
61
|
+
| E300 | ApiKeyMissingError | API key not set in environment |
|
|
62
|
+
| E301 | ApiKeyInvalidError | API key rejected by provider |
|
|
63
|
+
| E310 | EmbeddingError (RateLimit) | Rate limit exceeded |
|
|
64
|
+
| E311 | EmbeddingError (QuotaExceeded) | API quota exceeded |
|
|
65
|
+
| E312 | EmbeddingError (Network) | Network error during embedding |
|
|
66
|
+
| E313 | EmbeddingError (ModelError) | Model error |
|
|
67
|
+
| E319 | EmbeddingError (Unknown) | Unknown embedding error |
|
|
68
|
+
| E400 | IndexNotFoundError | Index does not exist |
|
|
69
|
+
| E401 | IndexCorruptedError | Index is corrupted |
|
|
70
|
+
| E402 | IndexBuildError | Failed to build index |
|
|
71
|
+
| E500 | DocumentNotFoundError | Document not in index |
|
|
72
|
+
| E501 | EmbeddingsNotFoundError | Embeddings not found |
|
|
73
|
+
| E600 | VectorStoreError | Vector store operation failed |
|
|
74
|
+
| E700 | ConfigError | Configuration error |
|
|
75
|
+
| E800 | WatchError | File watcher error |
|
|
76
|
+
| E900 | CliValidationError | Invalid CLI arguments |
|
|
77
|
+
|
|
78
|
+
### Exit Codes
|
|
79
|
+
|
|
80
|
+
CLI exit codes map to error categories:
|
|
81
|
+
|
|
82
|
+
| Exit Code | Category | Description |
|
|
83
|
+
|-----------|----------|-------------|
|
|
84
|
+
| 0 | Success | Operation completed successfully |
|
|
85
|
+
| 1 | User Error | Invalid arguments, missing config, etc. |
|
|
86
|
+
| 2 | System Error | File system, network, etc. |
|
|
87
|
+
| 3 | API Error | Authentication, rate limits, etc. |
|
|
88
|
+
|
|
89
|
+
### Usage in Scripts
|
|
90
|
+
|
|
91
|
+
Error codes enable reliable scripting and CI/CD integration:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Check for specific error codes in output
|
|
95
|
+
mdcontext search "query" 2>&1 | grep -q "\[E400\]" && echo "Index not found"
|
|
96
|
+
|
|
97
|
+
# Use exit codes for control flow
|
|
98
|
+
mdcontext index || {
|
|
99
|
+
case $? in
|
|
100
|
+
1) echo "User error - check arguments" ;;
|
|
101
|
+
2) echo "System error - check permissions" ;;
|
|
102
|
+
3) echo "API error - check credentials" ;;
|
|
103
|
+
esac
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Programmatic Access
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { FileReadError, ErrorCode } from './errors/index.js'
|
|
111
|
+
|
|
112
|
+
const error = new FileReadError({ path: '/file.md', message: 'ENOENT' })
|
|
113
|
+
console.log(error.code) // 'E100'
|
|
114
|
+
console.log(error._tag) // 'FileReadError'
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Transformation Patterns
|
|
118
|
+
|
|
119
|
+
### 1. `mapError` - Transform Error Types
|
|
120
|
+
|
|
121
|
+
Use `mapError` to convert low-level errors to domain errors. This preserves error specificity while adapting the error type.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
// GOOD - Maps to domain error with context
|
|
125
|
+
parse(content, options).pipe(
|
|
126
|
+
Effect.mapError((e) =>
|
|
127
|
+
new ParseError({
|
|
128
|
+
message: e.message,
|
|
129
|
+
path: filePath,
|
|
130
|
+
cause: e,
|
|
131
|
+
})
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
// BAD - Loses type information
|
|
136
|
+
Effect.mapError((e) => new Error(`${e._tag}: ${e.message}`))
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**When to use:**
|
|
140
|
+
- Converting library errors to domain errors
|
|
141
|
+
- Adding context (path, operation) to errors
|
|
142
|
+
- Translating between error domains
|
|
143
|
+
|
|
144
|
+
### 2. `catchTag` / `catchTags` - Handle Specific Errors
|
|
145
|
+
|
|
146
|
+
Use `catchTag` when you need to handle a specific known error type. This enables exhaustive error handling and type-safe recovery.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// Handle specific error with recovery
|
|
150
|
+
estimateEmbeddingCost(dir).pipe(
|
|
151
|
+
Effect.catchTag('IndexNotFoundError', () =>
|
|
152
|
+
Effect.succeed(null) // Index doesn't exist, return null estimate
|
|
153
|
+
)
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
// Handle multiple specific errors
|
|
157
|
+
buildEmbeddings(dir).pipe(
|
|
158
|
+
Effect.catchTags({
|
|
159
|
+
ApiKeyMissingError: (e) => {
|
|
160
|
+
console.error(e.message)
|
|
161
|
+
return Effect.succeed(null)
|
|
162
|
+
},
|
|
163
|
+
ApiKeyInvalidError: (e) => {
|
|
164
|
+
console.error(e.message)
|
|
165
|
+
return Effect.succeed(null)
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**When to use:**
|
|
172
|
+
- Recovering from expected error conditions
|
|
173
|
+
- Providing fallback values for specific failures
|
|
174
|
+
- Implementing retry logic for transient errors
|
|
175
|
+
- Filtering/handling known error types mid-pipeline
|
|
176
|
+
|
|
177
|
+
### 3. `catchAll` - Boundary Error Handling
|
|
178
|
+
|
|
179
|
+
Use `catchAll` **only at system boundaries** where all errors must be converted to a final format (user message, JSON response, etc.).
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
// GOOD - At CLI boundary (main.ts)
|
|
183
|
+
program.pipe(
|
|
184
|
+
Effect.catchAll((error) => {
|
|
185
|
+
console.error(formatError(error))
|
|
186
|
+
return Effect.succeed(ExitCode.failure)
|
|
187
|
+
})
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
// GOOD - At MCP boundary (server.ts)
|
|
191
|
+
// MCP protocol requires JSON responses for all operations
|
|
192
|
+
handler.pipe(
|
|
193
|
+
Effect.catchAll((e) =>
|
|
194
|
+
Effect.succeed({
|
|
195
|
+
isError: true,
|
|
196
|
+
content: [{ type: 'text', text: `Error: ${e.message}` }]
|
|
197
|
+
})
|
|
198
|
+
)
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
// BAD - In middle of pipeline (loses type information)
|
|
202
|
+
readFile(path).pipe(
|
|
203
|
+
Effect.catchAll(() => Effect.succeed(null)) // Silent failure!
|
|
204
|
+
)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**When to use:**
|
|
208
|
+
- CLI entry points (converting to exit codes)
|
|
209
|
+
- MCP/API handlers (converting to protocol responses)
|
|
210
|
+
- Top-level program error handling
|
|
211
|
+
|
|
212
|
+
**When NOT to use:**
|
|
213
|
+
- Middle of pipelines (use `catchTag` instead)
|
|
214
|
+
- When error type information is needed downstream
|
|
215
|
+
- For silent failures without logging
|
|
216
|
+
|
|
217
|
+
### 4. `Effect.tryPromise` / `Effect.try` - Lift External Operations
|
|
218
|
+
|
|
219
|
+
Use these to wrap promise-based or synchronous operations, converting thrown errors to Effect failures.
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
// For promises
|
|
223
|
+
Effect.tryPromise({
|
|
224
|
+
try: () => fs.readFile(path, 'utf-8'),
|
|
225
|
+
catch: (e) => new FileReadError({
|
|
226
|
+
path,
|
|
227
|
+
message: e instanceof Error ? e.message : String(e),
|
|
228
|
+
cause: e,
|
|
229
|
+
})
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// For synchronous code that may throw
|
|
233
|
+
Effect.try({
|
|
234
|
+
try: () => JSON.parse(content),
|
|
235
|
+
catch: (e) => new IndexCorruptedError({
|
|
236
|
+
path,
|
|
237
|
+
reason: 'InvalidJson',
|
|
238
|
+
details: e instanceof Error ? e.message : undefined,
|
|
239
|
+
})
|
|
240
|
+
})
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Best Practices
|
|
244
|
+
|
|
245
|
+
### Do's
|
|
246
|
+
|
|
247
|
+
- **Always use domain errors** - Never map to generic `Error`
|
|
248
|
+
- **Preserve cause chains** - Include `cause` field for debugging
|
|
249
|
+
- **Add context** - Include path, operation, and relevant metadata
|
|
250
|
+
- **Document error types** - Use JSDoc to specify thrown errors
|
|
251
|
+
- **Log at boundaries** - When swallowing errors, log for debugging
|
|
252
|
+
|
|
253
|
+
### Don'ts
|
|
254
|
+
|
|
255
|
+
- **Don't swallow errors silently** - Always log or handle explicitly
|
|
256
|
+
- **Don't use `catchAll` mid-pipeline** - Use `catchTag` instead
|
|
257
|
+
- **Don't mix paradigms** - Avoid try/catch inside Effect.gen
|
|
258
|
+
- **Don't map to generic Error** - Always use typed domain errors
|
|
259
|
+
|
|
260
|
+
### Batch Processing Pattern
|
|
261
|
+
|
|
262
|
+
When processing multiple items where individual failures shouldn't stop the batch:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
const processFile = Effect.gen(function* () {
|
|
266
|
+
// ... processing logic
|
|
267
|
+
}).pipe(
|
|
268
|
+
// Note: catchAll intentional for batch processing
|
|
269
|
+
// Individual file failures collected in errors array
|
|
270
|
+
// rather than stopping the entire operation
|
|
271
|
+
Effect.catchAll((error) => {
|
|
272
|
+
errors.push({ path, message: error.message })
|
|
273
|
+
return Effect.void
|
|
274
|
+
})
|
|
275
|
+
)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Always add a comment explaining why `catchAll` is appropriate.
|
|
279
|
+
|
|
280
|
+
### Graceful Degradation Pattern
|
|
281
|
+
|
|
282
|
+
When a feature is optional and failure shouldn't block the main operation:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
// Optional embedding cost estimate for user prompt
|
|
286
|
+
const estimate = yield* estimateEmbeddingCost(dir).pipe(
|
|
287
|
+
Effect.catchTag('IndexNotFoundError', () => Effect.succeed(null)),
|
|
288
|
+
// Note: catchAll for graceful degradation
|
|
289
|
+
// This is optional information - failure shouldn't block indexing
|
|
290
|
+
Effect.catchAll((e) => {
|
|
291
|
+
Effect.runSync(Effect.logWarning(`Could not estimate: ${e.message}`))
|
|
292
|
+
return Effect.succeed(null)
|
|
293
|
+
})
|
|
294
|
+
)
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Summarization Error Handling
|
|
298
|
+
|
|
299
|
+
AI summarization uses a separate error system with graceful degradation - errors never prevent search results from being displayed.
|
|
300
|
+
|
|
301
|
+
### Summarization Error Codes
|
|
302
|
+
|
|
303
|
+
| Code | Error Type | Description |
|
|
304
|
+
|------|------------|-------------|
|
|
305
|
+
| PROVIDER_NOT_FOUND | Provider name unknown | Check provider spelling |
|
|
306
|
+
| PROVIDER_NOT_AVAILABLE | CLI tool not installed | Install the CLI tool |
|
|
307
|
+
| CLI_EXECUTION_FAILED | CLI process error | Check CLI authentication |
|
|
308
|
+
| API_REQUEST_FAILED | API call failed | Check API key and network |
|
|
309
|
+
| RATE_LIMITED | Too many requests | Wait and retry |
|
|
310
|
+
| INVALID_RESPONSE | Bad provider response | Report as bug |
|
|
311
|
+
| TIMEOUT | Request timed out | Reduce result set |
|
|
312
|
+
| NO_API_KEY | Missing API key | Set environment variable |
|
|
313
|
+
|
|
314
|
+
### Troubleshooting Summarization
|
|
315
|
+
|
|
316
|
+
**"CLI tool 'claude' not found"**
|
|
317
|
+
```bash
|
|
318
|
+
# Install Claude Code
|
|
319
|
+
# Visit: https://claude.ai/download
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**"CLI tool 'opencode' not found"**
|
|
323
|
+
```bash
|
|
324
|
+
# Install OpenCode
|
|
325
|
+
npm install -g @opencode/cli
|
|
326
|
+
# Or: https://github.com/opencode-ai/opencode
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**"Authentication failed for anthropic"**
|
|
330
|
+
```bash
|
|
331
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**"Rate limit exceeded"**
|
|
335
|
+
- Wait 60 seconds and retry
|
|
336
|
+
- Consider switching to CLI provider (free with subscription)
|
|
337
|
+
|
|
338
|
+
**"Summarization failed: timeout"**
|
|
339
|
+
- Reduce results: `mdcontext search "query" --limit 5 --summarize`
|
|
340
|
+
- The default timeout is 60 seconds
|
|
341
|
+
|
|
342
|
+
**"No summarization providers available"**
|
|
343
|
+
Either:
|
|
344
|
+
1. Install a CLI tool: `claude`, `opencode`, or `gh copilot`
|
|
345
|
+
2. Configure an API provider with a valid API key
|
|
346
|
+
|
|
347
|
+
### Graceful Degradation
|
|
348
|
+
|
|
349
|
+
Summarization errors never crash the CLI. When summarization fails:
|
|
350
|
+
|
|
351
|
+
1. Error message is displayed
|
|
352
|
+
2. Search results are shown normally
|
|
353
|
+
3. Exit code remains 0 (success)
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
// Implementation pattern in search.ts
|
|
357
|
+
const runSummarization = (options: SummarizationOptions): Effect.Effect<void, never> =>
|
|
358
|
+
runSummarizationUnsafe(options).pipe(
|
|
359
|
+
Effect.catchAll((error) =>
|
|
360
|
+
Effect.sync(() => {
|
|
361
|
+
displaySummarizationError(error)
|
|
362
|
+
// Search results still displayed
|
|
363
|
+
}),
|
|
364
|
+
),
|
|
365
|
+
)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Error Formatting
|
|
369
|
+
|
|
370
|
+
Error formatting (user-friendly messages) should only happen at the CLI boundary in `src/cli/error-handler.ts`. Internal errors carry structured data; presentation is separate from logic.
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
// src/cli/error-handler.ts
|
|
374
|
+
const formatError = (error: MdContextError): string => {
|
|
375
|
+
switch (error._tag) {
|
|
376
|
+
case 'FileReadError':
|
|
377
|
+
return `Cannot read file: ${error.path}\n${error.message}`
|
|
378
|
+
case 'ApiKeyMissingError':
|
|
379
|
+
return `API key not configured.\n\nSet ${error.envVar} environment variable.`
|
|
380
|
+
// ... other error types
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
```
|
package/docs/PROJECT.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @hw/mdcontext
|
|
2
|
+
|
|
3
|
+
## What This Is
|
|
4
|
+
|
|
5
|
+
Token-efficient markdown analysis for LLMs. The "TLDR for code" approach applied to markdown documents — extract structure, build relationships, enable semantic search, optimize for LLM consumption.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
1. **HumanWork needs it** — Session logs, summaries, task specs are all markdown. PM turns need efficient access to Worker output.
|
|
10
|
+
2. **LLMs waste tokens on markdown** — Raw markdown dumps are inefficient. Structure matters.
|
|
11
|
+
3. **Nothing exists** — Parsers exist, embeddings exist, but no unified tool for LLM-optimized markdown retrieval.
|
|
12
|
+
4. **Training data** — Same indexes serve runtime retrieval AND training data preparation.
|
|
13
|
+
|
|
14
|
+
## Core Capabilities
|
|
15
|
+
|
|
16
|
+
| Capability | Description |
|
|
17
|
+
| ------------- | ------------------------------------------------------------------------------- |
|
|
18
|
+
| **Parse** | Extract AST: headings, sections, lists, code blocks, links, tables, frontmatter |
|
|
19
|
+
| **Graph** | Build relationships: doc→doc links, section hierarchy, backlinks |
|
|
20
|
+
| **Embed** | Semantic vectors for sections/documents |
|
|
21
|
+
| **Summarize** | Hierarchical compression: doc → section → key points |
|
|
22
|
+
| **Search** | Structural (find H2s) + semantic (find content about X) |
|
|
23
|
+
| **Optimize** | Token-efficient output, context window assembly |
|
|
24
|
+
| **Measure** | Analytics on queries, latency, token usage |
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
┌─────────────────────────────────────┐
|
|
30
|
+
│ mdcontext daemon │
|
|
31
|
+
│ ┌─────────┐ ┌─────────────────┐ │
|
|
32
|
+
Markdown ────────▶│ │ Parser │──│ Structure Index │ │
|
|
33
|
+
Files │ └─────────┘ └─────────────────┘ │
|
|
34
|
+
│ ┌─────────┐ ┌─────────────────┐ │
|
|
35
|
+
│ │Embedder │──│ Vector Index │ │
|
|
36
|
+
│ └─────────┘ └─────────────────┘ │
|
|
37
|
+
│ ┌─────────┐ ┌─────────────────┐ │
|
|
38
|
+
│ │Analytics│──│ Metrics Store │ │
|
|
39
|
+
│ └─────────┘ └─────────────────┘ │
|
|
40
|
+
└─────────────────────────────────────┘
|
|
41
|
+
│ │
|
|
42
|
+
┌─────────┴───┐ ┌───┴─────────┐
|
|
43
|
+
│ CLI API │ │ MCP Server │
|
|
44
|
+
└─────────────┘ └─────────────┘
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Components
|
|
48
|
+
|
|
49
|
+
1. **Parser** — Markdown → AST → Structured sections
|
|
50
|
+
2. **Structure Index** — Fast lookup by path, heading, section
|
|
51
|
+
3. **Embedder** — Sections → Vectors (pluggable: local or API)
|
|
52
|
+
4. **Vector Index** — FAISS or similar for semantic search
|
|
53
|
+
5. **Summarizer** — Hierarchical compression engine
|
|
54
|
+
6. **Analytics** — Metrics collection, latency tracking
|
|
55
|
+
7. **Daemon** — In-memory indexes, file watching, fast queries
|
|
56
|
+
8. **CLI** — Command-line interface
|
|
57
|
+
9. **MCP Server** — Claude integration
|
|
58
|
+
|
|
59
|
+
## Tech Stack
|
|
60
|
+
|
|
61
|
+
| Component | Choice | Rationale |
|
|
62
|
+
| ------------- | -------------------------------------------- | ----------------------------------- |
|
|
63
|
+
| Language | TypeScript | Matches HumanWork, Effect ecosystem |
|
|
64
|
+
| Parser | remark/unified | Battle-tested, plugin ecosystem |
|
|
65
|
+
| Embeddings | sentence-transformers (Python) or OpenAI API | Start with API, add local later |
|
|
66
|
+
| Vector Store | FAISS or hnswlib | Proven, fast |
|
|
67
|
+
| Metrics | Effect Metrics | Native to our stack |
|
|
68
|
+
| File Watching | chokidar | Standard, reliable |
|
|
69
|
+
|
|
70
|
+
## Non-Goals (v1)
|
|
71
|
+
|
|
72
|
+
- Multi-language support (English only initially)
|
|
73
|
+
- Real-time collaboration
|
|
74
|
+
- Web UI (CLI + MCP first)
|
|
75
|
+
- Custom embedding models
|
|
76
|
+
|
|
77
|
+
## Success Metrics
|
|
78
|
+
|
|
79
|
+
| Metric | Target |
|
|
80
|
+
| ------------------------ | ---------------------- |
|
|
81
|
+
| Token reduction | 80%+ vs raw markdown |
|
|
82
|
+
| Query latency (cached) | <100ms |
|
|
83
|
+
| Index build time | <10s for 1000 docs |
|
|
84
|
+
| Semantic search accuracy | Relevant in top-3 90%+ |
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
_Created: 2025-01-18_
|