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
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Configuration Management
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Configuration management is the practice of handling system configuration in a systematic, versioned, and automated way. It ensures consistency across environments and enables reproducible deployments.
|
|
6
|
+
|
|
7
|
+
## Core Principles
|
|
8
|
+
|
|
9
|
+
### Infrastructure as Code
|
|
10
|
+
|
|
11
|
+
Configuration should be:
|
|
12
|
+
- Version controlled in Git
|
|
13
|
+
- Reviewed through pull requests
|
|
14
|
+
- Tested before deployment
|
|
15
|
+
- Reproducible across environments
|
|
16
|
+
|
|
17
|
+
### Separation of Concerns
|
|
18
|
+
|
|
19
|
+
Keep configuration separate from code:
|
|
20
|
+
- Environment-specific values in config files
|
|
21
|
+
- Secrets in secure vaults
|
|
22
|
+
- Feature flags in dedicated systems
|
|
23
|
+
|
|
24
|
+
## Configuration Sources
|
|
25
|
+
|
|
26
|
+
### Hierarchy of Configuration
|
|
27
|
+
|
|
28
|
+
Configuration typically follows precedence:
|
|
29
|
+
1. Command-line arguments (highest)
|
|
30
|
+
2. Environment variables
|
|
31
|
+
3. Configuration files
|
|
32
|
+
4. Default values (lowest)
|
|
33
|
+
|
|
34
|
+
### Configuration File Formats
|
|
35
|
+
|
|
36
|
+
Common formats include:
|
|
37
|
+
- **YAML** - Human readable, supports comments
|
|
38
|
+
- **JSON** - Machine readable, widely supported
|
|
39
|
+
- **TOML** - Simple, explicit typing
|
|
40
|
+
- **INI** - Simple key-value pairs
|
|
41
|
+
|
|
42
|
+
## Implementation
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
interface ConfigService {
|
|
46
|
+
get<T>(key: string): T;
|
|
47
|
+
getOrDefault<T>(key: string, defaultValue: T): T;
|
|
48
|
+
has(key: string): boolean;
|
|
49
|
+
reload(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
class ConfigManager implements ConfigService {
|
|
53
|
+
private config: Map<string, unknown>;
|
|
54
|
+
|
|
55
|
+
constructor(sources: ConfigSource[]) {
|
|
56
|
+
// Load and merge from all sources
|
|
57
|
+
// Respect precedence rules
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get<T>(key: string): T {
|
|
61
|
+
// Return typed configuration value
|
|
62
|
+
// Throw if missing
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Best Practices
|
|
68
|
+
|
|
69
|
+
1. **Validate early** - Check configuration at startup
|
|
70
|
+
2. **Document everything** - Keep config schema documented
|
|
71
|
+
3. **Use sensible defaults** - Most users shouldn't need to configure
|
|
72
|
+
4. **Support hot reload** - Allow config changes without restart
|
|
73
|
+
5. **Audit changes** - Track who changed what and when
|
|
74
|
+
|
|
75
|
+
## Common Patterns
|
|
76
|
+
|
|
77
|
+
### Feature Flags
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
if (config.get('features.newDashboard')) {
|
|
81
|
+
renderNewDashboard();
|
|
82
|
+
} else {
|
|
83
|
+
renderLegacyDashboard();
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Environment-Specific Configuration
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
# config.production.yaml
|
|
91
|
+
database:
|
|
92
|
+
host: prod-db.example.com
|
|
93
|
+
poolSize: 100
|
|
94
|
+
|
|
95
|
+
# config.development.yaml
|
|
96
|
+
database:
|
|
97
|
+
host: localhost
|
|
98
|
+
poolSize: 5
|
|
99
|
+
```
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Distributed Systems Architecture
|
|
2
|
+
|
|
3
|
+
## What Are Distributed Systems?
|
|
4
|
+
|
|
5
|
+
A distributed system is a collection of independent computers that appear to users as a single coherent system. These systems enable scalability, fault tolerance, and geographic distribution.
|
|
6
|
+
|
|
7
|
+
## Key Challenges
|
|
8
|
+
|
|
9
|
+
### Network Partitions
|
|
10
|
+
|
|
11
|
+
Networks can fail, causing:
|
|
12
|
+
- Message loss
|
|
13
|
+
- Message delays
|
|
14
|
+
- Split-brain scenarios
|
|
15
|
+
|
|
16
|
+
### Consistency vs Availability
|
|
17
|
+
|
|
18
|
+
The CAP theorem states you can only have two of:
|
|
19
|
+
- **Consistency** - All nodes see same data
|
|
20
|
+
- **Availability** - System responds to requests
|
|
21
|
+
- **Partition tolerance** - System works despite network issues
|
|
22
|
+
|
|
23
|
+
### Clock Synchronization
|
|
24
|
+
|
|
25
|
+
Distributed systems struggle with time:
|
|
26
|
+
- Physical clocks drift
|
|
27
|
+
- Network delays vary
|
|
28
|
+
- Ordering events is challenging
|
|
29
|
+
|
|
30
|
+
## Design Patterns
|
|
31
|
+
|
|
32
|
+
### Service Discovery
|
|
33
|
+
|
|
34
|
+
Services need to find each other:
|
|
35
|
+
- DNS-based discovery
|
|
36
|
+
- Service registries (Consul, etcd)
|
|
37
|
+
- Load balancer integration
|
|
38
|
+
|
|
39
|
+
### Circuit Breakers
|
|
40
|
+
|
|
41
|
+
Prevent cascade failures:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
class CircuitBreaker {
|
|
45
|
+
private failures = 0;
|
|
46
|
+
private state: 'closed' | 'open' | 'half-open' = 'closed';
|
|
47
|
+
|
|
48
|
+
async call<T>(fn: () => Promise<T>): Promise<T> {
|
|
49
|
+
if (this.state === 'open') {
|
|
50
|
+
throw new CircuitOpenError();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const result = await fn();
|
|
55
|
+
this.onSuccess();
|
|
56
|
+
return result;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
this.onFailure();
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Event Sourcing
|
|
66
|
+
|
|
67
|
+
Store state as sequence of events:
|
|
68
|
+
- Complete audit trail
|
|
69
|
+
- Temporal queries
|
|
70
|
+
- Easy replay and debugging
|
|
71
|
+
|
|
72
|
+
## Communication Patterns
|
|
73
|
+
|
|
74
|
+
### Synchronous (Request-Response)
|
|
75
|
+
|
|
76
|
+
- REST APIs
|
|
77
|
+
- gRPC
|
|
78
|
+
- Direct service calls
|
|
79
|
+
|
|
80
|
+
### Asynchronous (Message-Based)
|
|
81
|
+
|
|
82
|
+
- Message queues
|
|
83
|
+
- Event streams
|
|
84
|
+
- Pub/sub systems
|
|
85
|
+
|
|
86
|
+
## Best Practices
|
|
87
|
+
|
|
88
|
+
1. **Design for failure** - Assume components will fail
|
|
89
|
+
2. **Embrace eventual consistency** - Not everything needs strong consistency
|
|
90
|
+
3. **Use idempotent operations** - Safe to retry
|
|
91
|
+
4. **Monitor everything** - Observability is critical
|
|
92
|
+
5. **Test failure modes** - Chaos engineering validates resilience
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Error Handling Patterns
|
|
2
|
+
|
|
3
|
+
## Introduction to Error Handling
|
|
4
|
+
|
|
5
|
+
Error handling is the process of responding to and recovering from error conditions in software. Good error handling improves reliability and user experience.
|
|
6
|
+
|
|
7
|
+
## Error Types
|
|
8
|
+
|
|
9
|
+
### Operational Errors
|
|
10
|
+
|
|
11
|
+
Errors that can occur during normal operation:
|
|
12
|
+
- Network timeouts
|
|
13
|
+
- File not found
|
|
14
|
+
- Invalid user input
|
|
15
|
+
- Database connection failures
|
|
16
|
+
|
|
17
|
+
### Programming Errors
|
|
18
|
+
|
|
19
|
+
Bugs in the code:
|
|
20
|
+
- Null pointer exceptions
|
|
21
|
+
- Type errors
|
|
22
|
+
- Logic errors
|
|
23
|
+
- Array bounds violations
|
|
24
|
+
|
|
25
|
+
## Handling Strategies
|
|
26
|
+
|
|
27
|
+
### Try-Catch Blocks
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
try {
|
|
31
|
+
await riskyOperation();
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error instanceof NetworkError) {
|
|
34
|
+
// Retry logic
|
|
35
|
+
} else if (error instanceof ValidationError) {
|
|
36
|
+
// Return user-friendly message
|
|
37
|
+
} else {
|
|
38
|
+
// Log and re-throw unknown errors
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Result Types
|
|
45
|
+
|
|
46
|
+
Instead of throwing, return success/failure:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
type Result<T, E> =
|
|
50
|
+
| { ok: true; value: T }
|
|
51
|
+
| { ok: false; error: E };
|
|
52
|
+
|
|
53
|
+
function parseConfig(path: string): Result<Config, ConfigError> {
|
|
54
|
+
// Return structured result instead of throwing
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Error Boundaries
|
|
59
|
+
|
|
60
|
+
In UI applications, error boundaries prevent entire app crashes:
|
|
61
|
+
- Catch errors in component trees
|
|
62
|
+
- Display fallback UI
|
|
63
|
+
- Log errors for debugging
|
|
64
|
+
|
|
65
|
+
## Best Practices
|
|
66
|
+
|
|
67
|
+
1. **Be specific** - Catch specific error types, not generic Exception
|
|
68
|
+
2. **Fail fast** - Detect errors early before causing more damage
|
|
69
|
+
3. **Provide context** - Error messages should explain what and why
|
|
70
|
+
4. **Log appropriately** - Stack traces for debugging, summaries for users
|
|
71
|
+
5. **Clean up resources** - Use finally blocks or try-with-resources
|
|
72
|
+
|
|
73
|
+
## Error Handling Anti-Patterns
|
|
74
|
+
|
|
75
|
+
- Swallowing errors silently
|
|
76
|
+
- Catching too broadly
|
|
77
|
+
- Exposing internal details to users
|
|
78
|
+
- Not cleaning up on errors
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Failure Automation
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Failure automation is the practice of automatically detecting, reporting, and responding to system failures without human intervention. This approach is essential for maintaining high availability in modern distributed systems.
|
|
6
|
+
|
|
7
|
+
## Core Concepts
|
|
8
|
+
|
|
9
|
+
### Automated Failure Detection
|
|
10
|
+
|
|
11
|
+
Systems use health checks, heartbeats, and monitoring to detect when components fail. Failure detection must be fast and accurate to minimize downtime.
|
|
12
|
+
|
|
13
|
+
### Automatic Recovery
|
|
14
|
+
|
|
15
|
+
Once a failure is detected, automation can:
|
|
16
|
+
- Restart failed services
|
|
17
|
+
- Failover to backup systems
|
|
18
|
+
- Scale up healthy instances
|
|
19
|
+
- Alert operations teams
|
|
20
|
+
|
|
21
|
+
### Failure Isolation
|
|
22
|
+
|
|
23
|
+
Automated systems can isolate failures to prevent cascading effects. Circuit breakers and bulkheads are common patterns for failure isolation.
|
|
24
|
+
|
|
25
|
+
## Best Practices
|
|
26
|
+
|
|
27
|
+
1. **Test failure scenarios regularly** - Chaos engineering validates that automation works
|
|
28
|
+
2. **Set appropriate timeouts** - Balance between fast detection and false positives
|
|
29
|
+
3. **Log everything** - Automated responses need audit trails
|
|
30
|
+
4. **Graceful degradation** - Systems should partially function during failures
|
|
31
|
+
|
|
32
|
+
## Implementation Example
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
class FailureAutomation {
|
|
36
|
+
detectFailure(component: string): boolean {
|
|
37
|
+
// Check health endpoint
|
|
38
|
+
// Monitor error rates
|
|
39
|
+
// Analyze latency patterns
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
respondToFailure(component: string): void {
|
|
43
|
+
// Trigger automatic recovery
|
|
44
|
+
// Send alerts
|
|
45
|
+
// Update status page
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Related Topics
|
|
51
|
+
|
|
52
|
+
- Error handling and recovery
|
|
53
|
+
- Distributed systems resilience
|
|
54
|
+
- Site reliability engineering
|
|
55
|
+
- Chaos engineering practices
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Job Context
|
|
2
|
+
|
|
3
|
+
## What is Job Context?
|
|
4
|
+
|
|
5
|
+
Job context refers to the environment, state, and metadata associated with a running job or task. Understanding job context is crucial for debugging, monitoring, and managing batch processing systems.
|
|
6
|
+
|
|
7
|
+
## Components of Job Context
|
|
8
|
+
|
|
9
|
+
### Runtime Environment
|
|
10
|
+
|
|
11
|
+
The job context includes:
|
|
12
|
+
- Working directory and file paths
|
|
13
|
+
- Environment variables
|
|
14
|
+
- Process information (PID, memory, CPU)
|
|
15
|
+
- User and permission context
|
|
16
|
+
|
|
17
|
+
### Execution Metadata
|
|
18
|
+
|
|
19
|
+
Each job carries metadata about its execution:
|
|
20
|
+
- Job ID and name
|
|
21
|
+
- Start time and duration
|
|
22
|
+
- Parent job or workflow reference
|
|
23
|
+
- Retry count and history
|
|
24
|
+
|
|
25
|
+
### State Information
|
|
26
|
+
|
|
27
|
+
Job context tracks current state:
|
|
28
|
+
- Input parameters received
|
|
29
|
+
- Progress percentage
|
|
30
|
+
- Intermediate results
|
|
31
|
+
- Checkpoints for recovery
|
|
32
|
+
|
|
33
|
+
## Passing Context Between Jobs
|
|
34
|
+
|
|
35
|
+
In workflow systems, context flows between jobs:
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
interface JobContext {
|
|
39
|
+
jobId: string;
|
|
40
|
+
workflowId: string;
|
|
41
|
+
inputs: Record<string, unknown>;
|
|
42
|
+
outputs: Record<string, unknown>;
|
|
43
|
+
metadata: {
|
|
44
|
+
startedAt: Date;
|
|
45
|
+
parent?: string;
|
|
46
|
+
retryCount: number;
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function executeJob(context: JobContext): Promise<JobContext> {
|
|
51
|
+
// Access context for execution
|
|
52
|
+
// Update outputs and state
|
|
53
|
+
// Return enriched context
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Best Practices
|
|
58
|
+
|
|
59
|
+
1. **Keep context immutable** - Create new context objects rather than mutating
|
|
60
|
+
2. **Serialize context carefully** - Ensure all context can be persisted
|
|
61
|
+
3. **Scope context appropriately** - Don't pass more than needed
|
|
62
|
+
4. **Log context changes** - Track how context evolves
|
|
63
|
+
|
|
64
|
+
## Use Cases
|
|
65
|
+
|
|
66
|
+
- Debugging failed jobs by examining their context
|
|
67
|
+
- Replaying jobs with captured context
|
|
68
|
+
- Monitoring job progress through context updates
|
|
69
|
+
- Implementing job dependencies based on context
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Process Orchestration
|
|
2
|
+
|
|
3
|
+
## Introduction
|
|
4
|
+
|
|
5
|
+
Process orchestration is the automated coordination of multiple tasks, services, or workflows to achieve a business goal. It differs from choreography where services coordinate themselves.
|
|
6
|
+
|
|
7
|
+
## Orchestration vs Choreography
|
|
8
|
+
|
|
9
|
+
### Orchestration (Central Control)
|
|
10
|
+
|
|
11
|
+
A central orchestrator directs the workflow:
|
|
12
|
+
- Single point of control
|
|
13
|
+
- Easy to understand flow
|
|
14
|
+
- Simpler error handling
|
|
15
|
+
- Can become bottleneck
|
|
16
|
+
|
|
17
|
+
### Choreography (Distributed)
|
|
18
|
+
|
|
19
|
+
Services react to events independently:
|
|
20
|
+
- No central point of failure
|
|
21
|
+
- More scalable
|
|
22
|
+
- Harder to track overall flow
|
|
23
|
+
- Complex error handling
|
|
24
|
+
|
|
25
|
+
## Orchestration Patterns
|
|
26
|
+
|
|
27
|
+
### Sequential Execution
|
|
28
|
+
|
|
29
|
+
Tasks run one after another:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
async function processOrder(order: Order): Promise<void> {
|
|
33
|
+
await validateOrder(order);
|
|
34
|
+
await reserveInventory(order.items);
|
|
35
|
+
await processPayment(order.payment);
|
|
36
|
+
await scheduleShipping(order);
|
|
37
|
+
await notifyCustomer(order);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Parallel Execution
|
|
42
|
+
|
|
43
|
+
Independent tasks run concurrently:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
async function enrichOrder(order: Order): Promise<EnrichedOrder> {
|
|
47
|
+
const [customer, inventory, pricing] = await Promise.all([
|
|
48
|
+
fetchCustomerDetails(order.customerId),
|
|
49
|
+
checkInventoryLevels(order.items),
|
|
50
|
+
calculatePricing(order.items),
|
|
51
|
+
]);
|
|
52
|
+
|
|
53
|
+
return { ...order, customer, inventory, pricing };
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Saga Pattern
|
|
58
|
+
|
|
59
|
+
Long-running transactions with compensation:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
class OrderSaga {
|
|
63
|
+
async execute(order: Order): Promise<void> {
|
|
64
|
+
const compensations: (() => Promise<void>)[] = [];
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
await this.reserveInventory(order);
|
|
68
|
+
compensations.push(() => this.releaseInventory(order));
|
|
69
|
+
|
|
70
|
+
await this.chargePayment(order);
|
|
71
|
+
compensations.push(() => this.refundPayment(order));
|
|
72
|
+
|
|
73
|
+
await this.shipOrder(order);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// Run compensations in reverse
|
|
76
|
+
for (const compensate of compensations.reverse()) {
|
|
77
|
+
await compensate();
|
|
78
|
+
}
|
|
79
|
+
throw error;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Workflow Engines
|
|
86
|
+
|
|
87
|
+
Popular orchestration tools:
|
|
88
|
+
- **Temporal** - Durable execution
|
|
89
|
+
- **Apache Airflow** - Data pipelines
|
|
90
|
+
- **Kubernetes Jobs** - Container orchestration
|
|
91
|
+
- **Step Functions** - AWS serverless workflows
|
|
92
|
+
|
|
93
|
+
## Best Practices
|
|
94
|
+
|
|
95
|
+
1. **Idempotent operations** - Safe to retry on failure
|
|
96
|
+
2. **Clear compensation logic** - Know how to rollback
|
|
97
|
+
3. **Visibility and monitoring** - Track workflow state
|
|
98
|
+
4. **Timeout handling** - Don't wait forever
|
|
99
|
+
5. **Version workflows carefully** - Running instances need compatibility
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for argv-preprocessor
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, it } from 'vitest'
|
|
6
|
+
import { preprocessArgvWithValidation } from './argv-preprocessor.js'
|
|
7
|
+
|
|
8
|
+
describe('preprocessArgvWithValidation', () => {
|
|
9
|
+
const node = '/usr/bin/node'
|
|
10
|
+
const script = '/path/to/mdcontext'
|
|
11
|
+
|
|
12
|
+
describe('flag reordering', () => {
|
|
13
|
+
it('reorders flags before positional args', () => {
|
|
14
|
+
const result = preprocessArgvWithValidation([
|
|
15
|
+
node,
|
|
16
|
+
script,
|
|
17
|
+
'search',
|
|
18
|
+
'query',
|
|
19
|
+
'--limit',
|
|
20
|
+
'5',
|
|
21
|
+
'docs/',
|
|
22
|
+
])
|
|
23
|
+
expect(result.argv).toEqual([
|
|
24
|
+
node,
|
|
25
|
+
script,
|
|
26
|
+
'search',
|
|
27
|
+
'--limit',
|
|
28
|
+
'5',
|
|
29
|
+
'query',
|
|
30
|
+
'docs/',
|
|
31
|
+
])
|
|
32
|
+
expect(result.error).toBeUndefined()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('handles --flag=value syntax', () => {
|
|
36
|
+
const result = preprocessArgvWithValidation([
|
|
37
|
+
node,
|
|
38
|
+
script,
|
|
39
|
+
'search',
|
|
40
|
+
'query',
|
|
41
|
+
'--limit=5',
|
|
42
|
+
'docs/',
|
|
43
|
+
])
|
|
44
|
+
expect(result.argv).toEqual([
|
|
45
|
+
node,
|
|
46
|
+
script,
|
|
47
|
+
'search',
|
|
48
|
+
'--limit=5',
|
|
49
|
+
'query',
|
|
50
|
+
'docs/',
|
|
51
|
+
])
|
|
52
|
+
expect(result.error).toBeUndefined()
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it('handles boolean flags', () => {
|
|
56
|
+
const result = preprocessArgvWithValidation([
|
|
57
|
+
node,
|
|
58
|
+
script,
|
|
59
|
+
'context',
|
|
60
|
+
'file.md',
|
|
61
|
+
'--brief',
|
|
62
|
+
])
|
|
63
|
+
expect(result.argv).toEqual([
|
|
64
|
+
node,
|
|
65
|
+
script,
|
|
66
|
+
'context',
|
|
67
|
+
'--brief',
|
|
68
|
+
'file.md',
|
|
69
|
+
])
|
|
70
|
+
expect(result.error).toBeUndefined()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('passes through --help flag', () => {
|
|
74
|
+
const result = preprocessArgvWithValidation([
|
|
75
|
+
node,
|
|
76
|
+
script,
|
|
77
|
+
'context',
|
|
78
|
+
'--help',
|
|
79
|
+
])
|
|
80
|
+
expect(result.argv).toEqual([node, script, 'context', '--help'])
|
|
81
|
+
expect(result.error).toBeUndefined()
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
describe('unknown flag detection', () => {
|
|
86
|
+
it('returns error for unknown flag', () => {
|
|
87
|
+
const result = preprocessArgvWithValidation([
|
|
88
|
+
node,
|
|
89
|
+
script,
|
|
90
|
+
'context',
|
|
91
|
+
'-z',
|
|
92
|
+
'file.md',
|
|
93
|
+
])
|
|
94
|
+
expect(result.error).toContain("Unknown option '-z'")
|
|
95
|
+
expect(result.error).toContain("'context'")
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('returns error for unknown long flag', () => {
|
|
99
|
+
const result = preprocessArgvWithValidation([
|
|
100
|
+
node,
|
|
101
|
+
script,
|
|
102
|
+
'search',
|
|
103
|
+
'--invalid',
|
|
104
|
+
'query',
|
|
105
|
+
])
|
|
106
|
+
expect(result.error).toContain("Unknown option '--invalid'")
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('returns error for unknown flag with value', () => {
|
|
110
|
+
const result = preprocessArgvWithValidation([
|
|
111
|
+
node,
|
|
112
|
+
script,
|
|
113
|
+
'context',
|
|
114
|
+
'--foo=bar',
|
|
115
|
+
'file.md',
|
|
116
|
+
])
|
|
117
|
+
expect(result.error).toContain("Unknown option '--foo'")
|
|
118
|
+
})
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
describe('typo suggestions', () => {
|
|
122
|
+
it('suggests --json for --jsno', () => {
|
|
123
|
+
const result = preprocessArgvWithValidation([
|
|
124
|
+
node,
|
|
125
|
+
script,
|
|
126
|
+
'context',
|
|
127
|
+
'--jsno',
|
|
128
|
+
'file.md',
|
|
129
|
+
])
|
|
130
|
+
expect(result.error).toContain("Did you mean '--json'")
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it('suggests --limit for --limt', () => {
|
|
134
|
+
const result = preprocessArgvWithValidation([
|
|
135
|
+
node,
|
|
136
|
+
script,
|
|
137
|
+
'search',
|
|
138
|
+
'--limt',
|
|
139
|
+
'5',
|
|
140
|
+
'query',
|
|
141
|
+
])
|
|
142
|
+
expect(result.error).toContain("Did you mean '--limit'")
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
it('suggests --tokens for --toekns', () => {
|
|
146
|
+
const result = preprocessArgvWithValidation([
|
|
147
|
+
node,
|
|
148
|
+
script,
|
|
149
|
+
'context',
|
|
150
|
+
'--toekns',
|
|
151
|
+
'100',
|
|
152
|
+
'file.md',
|
|
153
|
+
])
|
|
154
|
+
expect(result.error).toContain("Did you mean '--tokens'")
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
describe('edge cases', () => {
|
|
159
|
+
it('passes through empty args', () => {
|
|
160
|
+
const result = preprocessArgvWithValidation([node, script])
|
|
161
|
+
expect(result.argv).toEqual([node, script])
|
|
162
|
+
expect(result.error).toBeUndefined()
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('passes through unknown subcommand', () => {
|
|
166
|
+
const result = preprocessArgvWithValidation([
|
|
167
|
+
node,
|
|
168
|
+
script,
|
|
169
|
+
'unknown',
|
|
170
|
+
'--flag',
|
|
171
|
+
])
|
|
172
|
+
// Unknown subcommand should pass through (no schema)
|
|
173
|
+
expect(result.argv).toEqual([node, script, 'unknown', '--flag'])
|
|
174
|
+
expect(result.error).toBeUndefined()
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
it('handles -- end of flags marker', () => {
|
|
178
|
+
const result = preprocessArgvWithValidation([
|
|
179
|
+
node,
|
|
180
|
+
script,
|
|
181
|
+
'context',
|
|
182
|
+
'--',
|
|
183
|
+
'--not-a-flag',
|
|
184
|
+
'file.md',
|
|
185
|
+
])
|
|
186
|
+
// After --, everything is positional
|
|
187
|
+
expect(result.argv).toEqual([
|
|
188
|
+
node,
|
|
189
|
+
script,
|
|
190
|
+
'context',
|
|
191
|
+
'--not-a-flag',
|
|
192
|
+
'file.md',
|
|
193
|
+
])
|
|
194
|
+
expect(result.error).toBeUndefined()
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('validates alias flags', () => {
|
|
198
|
+
const result = preprocessArgvWithValidation([
|
|
199
|
+
node,
|
|
200
|
+
script,
|
|
201
|
+
'context',
|
|
202
|
+
'-t',
|
|
203
|
+
'100',
|
|
204
|
+
'file.md',
|
|
205
|
+
])
|
|
206
|
+
expect(result.error).toBeUndefined()
|
|
207
|
+
expect(result.argv).toContain('-t')
|
|
208
|
+
})
|
|
209
|
+
})
|
|
210
|
+
})
|