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
|
@@ -0,0 +1,890 @@
|
|
|
1
|
+
# Help System Architecture Analysis
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
**RESEARCH METADATA**
|
|
5
|
+
|
|
6
|
+
- Analysis Date: 2026-01-24
|
|
7
|
+
- Git Commit: 07c9e72ba01cda840046b96a1be4743a85e3d4c5
|
|
8
|
+
- Status: Valid
|
|
9
|
+
- Last Validated: 2026-01-24
|
|
10
|
+
- Worktree: nancy-ALP-139
|
|
11
|
+
- Related: [help-audit.md](help-audit.md)
|
|
12
|
+
- Index: [/research/INDEX.md](../INDEX.md)
|
|
13
|
+
|
|
14
|
+
**ACCURACY NOTE**
|
|
15
|
+
|
|
16
|
+
This analysis documents the help system architecture as implemented in the codebase.
|
|
17
|
+
It is code-dependent and validated against the current implementation.
|
|
18
|
+
See help-audit.md for UX evaluation of the help output quality.
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
The mdcontext CLI uses a hybrid help system that combines:
|
|
24
|
+
1. **Custom help implementation** (help.ts) - For beautiful, branded help output
|
|
25
|
+
2. **Effect CLI's built-in help** - For automatic command structure and parsing
|
|
26
|
+
|
|
27
|
+
This document explains how the two systems work together, which commands use which approach, and the pattern matching logic that determines what help gets shown.
|
|
28
|
+
|
|
29
|
+
## Architecture Components
|
|
30
|
+
|
|
31
|
+
### 1. Custom Help System (src/cli/help.ts)
|
|
32
|
+
|
|
33
|
+
The custom help system provides world-class, beautifully formatted help that matches the quality of professional tools like git and gh.
|
|
34
|
+
|
|
35
|
+
**Key Features:**
|
|
36
|
+
- Color-coded section headers (yellow for USAGE, EXAMPLES, OPTIONS, NOTES)
|
|
37
|
+
- Cyan highlighting for commands and values
|
|
38
|
+
- Progressive examples (simple to complex)
|
|
39
|
+
- Real-world workflow examples
|
|
40
|
+
- Helpful notes about prerequisites and behavior
|
|
41
|
+
|
|
42
|
+
**File Structure:**
|
|
43
|
+
```typescript
|
|
44
|
+
// help.ts exports:
|
|
45
|
+
export const helpContent: Record<string, CommandHelp>
|
|
46
|
+
export const showMainHelp = (): void
|
|
47
|
+
export const showSubcommandHelp = (command: string): void
|
|
48
|
+
export const checkSubcommandHelp = (): boolean
|
|
49
|
+
export const checkBareSubcommandHelp = (): boolean
|
|
50
|
+
export const shouldShowMainHelp = (): boolean
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Help Content Structure:**
|
|
54
|
+
```typescript
|
|
55
|
+
interface CommandHelp {
|
|
56
|
+
description: string
|
|
57
|
+
usage: string
|
|
58
|
+
examples: string[]
|
|
59
|
+
options: { name: string; description: string }[]
|
|
60
|
+
notes?: string[]
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Commands with Custom Help:**
|
|
65
|
+
- `mdcontext --help` (main help)
|
|
66
|
+
- `mdcontext index --help`
|
|
67
|
+
- `mdcontext search --help`
|
|
68
|
+
- `mdcontext context --help`
|
|
69
|
+
- `mdcontext tree --help`
|
|
70
|
+
- `mdcontext links --help`
|
|
71
|
+
- `mdcontext backlinks --help`
|
|
72
|
+
- `mdcontext stats --help`
|
|
73
|
+
- `mdcontext config --help`
|
|
74
|
+
|
|
75
|
+
### 2. Effect CLI Help System
|
|
76
|
+
|
|
77
|
+
Effect CLI provides automatic help generation based on command definitions, but it:
|
|
78
|
+
- Has different formatting (white headers instead of yellow)
|
|
79
|
+
- Uses dashes before command names in listings
|
|
80
|
+
- Lacks examples and notes sections
|
|
81
|
+
- Doesn't match the mdcontext brand/style
|
|
82
|
+
|
|
83
|
+
**When Effect CLI Help Appears:**
|
|
84
|
+
Effect's help is only shown when the custom help system doesn't intercept the request.
|
|
85
|
+
|
|
86
|
+
### 3. Help Request Flow
|
|
87
|
+
|
|
88
|
+
The help system uses a waterfall pattern to determine what help to show:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
main.ts (lines 89-99):
|
|
92
|
+
┌─────────────────────────────────────┐
|
|
93
|
+
│ 1. checkSubcommandHelp() │ → Intercepts "mdcontext <cmd> --help"
|
|
94
|
+
│ - Checks for: cmd + (--help|-h) │
|
|
95
|
+
│ - Shows custom help via │
|
|
96
|
+
│ showSubcommandHelp(command) │
|
|
97
|
+
│ - Exits with process.exit(0) │
|
|
98
|
+
└─────────────────────────────────────┘
|
|
99
|
+
│ (if no match)
|
|
100
|
+
▼
|
|
101
|
+
┌─────────────────────────────────────┐
|
|
102
|
+
│ 2. checkBareSubcommandHelp() │ → Intercepts "mdcontext config"
|
|
103
|
+
│ - Checks for: bare "config" │
|
|
104
|
+
│ - Shows custom config help │
|
|
105
|
+
│ - Prevents ugly Effect default │
|
|
106
|
+
│ - Exits with process.exit(0) │
|
|
107
|
+
└─────────────────────────────────────┘
|
|
108
|
+
│ (if no match)
|
|
109
|
+
▼
|
|
110
|
+
┌─────────────────────────────────────┐
|
|
111
|
+
│ 3. shouldShowMainHelp() │ → Intercepts main help requests
|
|
112
|
+
│ - Checks for: no args, --help, │
|
|
113
|
+
│ -h, or "help" command │
|
|
114
|
+
│ - Shows custom main help │
|
|
115
|
+
│ - Exits with process.exit(0) │
|
|
116
|
+
└─────────────────────────────────────┘
|
|
117
|
+
│ (if no match)
|
|
118
|
+
▼
|
|
119
|
+
┌─────────────────────────────────────┐
|
|
120
|
+
│ 4. Effect CLI Processing │ → Default Effect CLI handling
|
|
121
|
+
│ - Runs the CLI command │
|
|
122
|
+
│ - Uses Effect's built-in help │
|
|
123
|
+
│ if --help flag is present │
|
|
124
|
+
└─────────────────────────────────────┘
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Pattern Matching Logic
|
|
128
|
+
|
|
129
|
+
### Pattern 1: Subcommand Help (`checkSubcommandHelp`)
|
|
130
|
+
|
|
131
|
+
**Location:** help.ts lines 395-408
|
|
132
|
+
|
|
133
|
+
**Matches:**
|
|
134
|
+
- `mdcontext index --help`
|
|
135
|
+
- `mdcontext search -h`
|
|
136
|
+
- `mdcontext config --help`
|
|
137
|
+
|
|
138
|
+
**Logic:**
|
|
139
|
+
```typescript
|
|
140
|
+
const args = process.argv.slice(2)
|
|
141
|
+
if (args.length < 2) return false
|
|
142
|
+
|
|
143
|
+
const command = args[0]
|
|
144
|
+
const hasHelpFlag = args.includes('--help') || args.includes('-h')
|
|
145
|
+
|
|
146
|
+
if (hasHelpFlag && command && helpContent[command]) {
|
|
147
|
+
showSubcommandHelp(command)
|
|
148
|
+
process.exit(0)
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
**Behavior:**
|
|
153
|
+
- Requires at least 2 arguments (command + flag)
|
|
154
|
+
- Command must exist in helpContent
|
|
155
|
+
- Shows custom help and exits
|
|
156
|
+
|
|
157
|
+
### Pattern 2: Bare Subcommand Help (`checkBareSubcommandHelp`)
|
|
158
|
+
|
|
159
|
+
**Location:** help.ts lines 415-431
|
|
160
|
+
|
|
161
|
+
**Matches:**
|
|
162
|
+
- `mdcontext config` (no args, no flags)
|
|
163
|
+
|
|
164
|
+
**Purpose:** Prevents ugly Effect CLI default output for commands with subcommands
|
|
165
|
+
|
|
166
|
+
**Logic:**
|
|
167
|
+
```typescript
|
|
168
|
+
const args = process.argv.slice(2)
|
|
169
|
+
|
|
170
|
+
// Look for: exactly one arg that is a command with subcommands in helpContent
|
|
171
|
+
if (args.length !== 1) return false
|
|
172
|
+
|
|
173
|
+
const command = args[0]
|
|
174
|
+
|
|
175
|
+
// Only handle commands that have subcommands and custom help
|
|
176
|
+
// Currently only "config" has subcommands
|
|
177
|
+
if (command === 'config' && helpContent[command]) {
|
|
178
|
+
showSubcommandHelp(command)
|
|
179
|
+
process.exit(0)
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Behavior:**
|
|
184
|
+
- Only triggers for exactly 1 argument
|
|
185
|
+
- Currently hard-coded to only handle "config"
|
|
186
|
+
- Shows the parent command's custom help
|
|
187
|
+
- Prevents Effect's raw default listing
|
|
188
|
+
|
|
189
|
+
**Why This Exists:**
|
|
190
|
+
Running `mdcontext config` without the fix would show Effect's default output:
|
|
191
|
+
```
|
|
192
|
+
mdcontext
|
|
193
|
+
|
|
194
|
+
mdcontext 0.1.0
|
|
195
|
+
|
|
196
|
+
USAGE
|
|
197
|
+
|
|
198
|
+
$ config
|
|
199
|
+
|
|
200
|
+
DESCRIPTION
|
|
201
|
+
|
|
202
|
+
Configuration management
|
|
203
|
+
|
|
204
|
+
COMMANDS
|
|
205
|
+
|
|
206
|
+
- init [(-f, --format js | json)] [--force] [--json] [--pretty] Create a starter config file
|
|
207
|
+
- show [--json] [--pretty] Show config file location
|
|
208
|
+
- check [--json] [--pretty] Validate and display configuration
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
With the fix, it shows the beautiful custom help instead.
|
|
212
|
+
|
|
213
|
+
### Pattern 3: Main Help (`shouldShowMainHelp`)
|
|
214
|
+
|
|
215
|
+
**Location:** help.ts lines 436-445
|
|
216
|
+
|
|
217
|
+
**Matches:**
|
|
218
|
+
- `mdcontext` (no args)
|
|
219
|
+
- `mdcontext --help`
|
|
220
|
+
- `mdcontext -h`
|
|
221
|
+
- `mdcontext help`
|
|
222
|
+
|
|
223
|
+
**Logic:**
|
|
224
|
+
```typescript
|
|
225
|
+
const args = process.argv.slice(2)
|
|
226
|
+
const showHelp =
|
|
227
|
+
args.length === 0 ||
|
|
228
|
+
args.includes('--help') ||
|
|
229
|
+
args.includes('-h') ||
|
|
230
|
+
(args.length === 1 && args[0] === 'help')
|
|
231
|
+
|
|
232
|
+
return showHelp && !args.some((a) => !a.startsWith('-') && a !== 'help')
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Behavior:**
|
|
236
|
+
- Shows main help for various patterns
|
|
237
|
+
- Second condition prevents showing main help if a subcommand is present
|
|
238
|
+
|
|
239
|
+
### Pattern 4: Effect CLI Default
|
|
240
|
+
|
|
241
|
+
**When it activates:**
|
|
242
|
+
When none of the above patterns match and Effect CLI takes over.
|
|
243
|
+
|
|
244
|
+
**Example:** Config subcommands
|
|
245
|
+
- `mdcontext config init --help`
|
|
246
|
+
- `mdcontext config show --help`
|
|
247
|
+
- `mdcontext config check --help`
|
|
248
|
+
|
|
249
|
+
**Current Behavior:**
|
|
250
|
+
These show the **parent config help**, not subcommand-specific help.
|
|
251
|
+
|
|
252
|
+
**Why:**
|
|
253
|
+
The custom help interceptor in `checkSubcommandHelp` looks for:
|
|
254
|
+
```typescript
|
|
255
|
+
const command = args[0] // This would be "config"
|
|
256
|
+
const hasHelpFlag = args.includes('--help')
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
When you run `mdcontext config init --help`, args[0] is "config", so it shows the config help.
|
|
260
|
+
|
|
261
|
+
**Is this intentional?**
|
|
262
|
+
Looking at the config command implementation (config-cmd.ts lines 635-638):
|
|
263
|
+
```typescript
|
|
264
|
+
export const configCommand = Command.make('config').pipe(
|
|
265
|
+
Command.withDescription('Configuration management'),
|
|
266
|
+
Command.withSubcommands([initCommand, showCommand, checkCommand]),
|
|
267
|
+
)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
The subcommands (init, show, check) are simple enough that centralizing all help in the parent command is reasonable. The parent help already documents all subcommands comprehensively.
|
|
271
|
+
|
|
272
|
+
## Command-by-Command Help Routing
|
|
273
|
+
|
|
274
|
+
| Command Pattern | Which System | Notes |
|
|
275
|
+
|-----------------|--------------|-------|
|
|
276
|
+
| `mdcontext` | Custom | shouldShowMainHelp |
|
|
277
|
+
| `mdcontext --help` | Custom | shouldShowMainHelp |
|
|
278
|
+
| `mdcontext help` | Custom | shouldShowMainHelp |
|
|
279
|
+
| `mdcontext index --help` | Custom | checkSubcommandHelp |
|
|
280
|
+
| `mdcontext search --help` | Custom | checkSubcommandHelp |
|
|
281
|
+
| `mdcontext context --help` | Custom | checkSubcommandHelp |
|
|
282
|
+
| `mdcontext tree --help` | Custom | checkSubcommandHelp |
|
|
283
|
+
| `mdcontext links --help` | Custom | checkSubcommandHelp |
|
|
284
|
+
| `mdcontext backlinks --help` | Custom | checkSubcommandHelp |
|
|
285
|
+
| `mdcontext stats --help` | Custom | checkSubcommandHelp |
|
|
286
|
+
| `mdcontext config` | Custom | checkBareSubcommandHelp |
|
|
287
|
+
| `mdcontext config --help` | Custom | checkSubcommandHelp |
|
|
288
|
+
| `mdcontext config init --help` | Custom (parent) | checkSubcommandHelp shows config help |
|
|
289
|
+
| `mdcontext config show --help` | Custom (parent) | checkSubcommandHelp shows config help |
|
|
290
|
+
| `mdcontext config check --help` | Custom (parent) | checkSubcommandHelp shows config help |
|
|
291
|
+
|
|
292
|
+
## Implementation Details
|
|
293
|
+
|
|
294
|
+
### Custom Help Rendering
|
|
295
|
+
|
|
296
|
+
**Main Help (showMainHelp):**
|
|
297
|
+
Location: help.ts lines 329-385
|
|
298
|
+
|
|
299
|
+
Features:
|
|
300
|
+
- Hardcoded template string with ANSI color codes
|
|
301
|
+
- Sections: COMMANDS, EXAMPLES, WORKFLOWS, GLOBAL OPTIONS
|
|
302
|
+
- Yellow headers (\x1b[33m)
|
|
303
|
+
- Cyan highlights (\x1b[36m)
|
|
304
|
+
- Dim text for comments (\x1b[2m)
|
|
305
|
+
|
|
306
|
+
**Subcommand Help (showSubcommandHelp):**
|
|
307
|
+
Location: help.ts lines 286-324
|
|
308
|
+
|
|
309
|
+
Process:
|
|
310
|
+
1. Look up command in helpContent map
|
|
311
|
+
2. Exit with error if not found
|
|
312
|
+
3. Format sections dynamically:
|
|
313
|
+
- Header with command name and description
|
|
314
|
+
- USAGE section (single line)
|
|
315
|
+
- EXAMPLES section (array of examples)
|
|
316
|
+
- OPTIONS section (aligned at 24 chars)
|
|
317
|
+
- NOTES section (if present)
|
|
318
|
+
|
|
319
|
+
**Color Scheme:**
|
|
320
|
+
```typescript
|
|
321
|
+
\x1b[1m - Bold (command names)
|
|
322
|
+
\x1b[33m - Yellow (section headers)
|
|
323
|
+
\x1b[36m - Cyan (values/highlights)
|
|
324
|
+
\x1b[2m - Dim (comments)
|
|
325
|
+
\x1b[0m - Reset
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
### Effect CLI Integration
|
|
329
|
+
|
|
330
|
+
**Main Command Definition:**
|
|
331
|
+
Location: main.ts lines 55-67
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
const mainCommand = Command.make('mdcontext').pipe(
|
|
335
|
+
Command.withDescription('Token-efficient markdown analysis for LLMs'),
|
|
336
|
+
Command.withSubcommands([
|
|
337
|
+
indexCommand,
|
|
338
|
+
searchCommand,
|
|
339
|
+
contextCommand,
|
|
340
|
+
treeCommand,
|
|
341
|
+
linksCommand,
|
|
342
|
+
backlinksCommand,
|
|
343
|
+
statsCommand,
|
|
344
|
+
configCommand,
|
|
345
|
+
]),
|
|
346
|
+
)
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**CLI Configuration:**
|
|
350
|
+
Location: main.ts lines 69-77
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
const cli = Command.run(mainCommand, {
|
|
354
|
+
name: 'mdcontext',
|
|
355
|
+
version: '0.1.0',
|
|
356
|
+
})
|
|
357
|
+
|
|
358
|
+
const cliConfigLayer = CliConfig.layer({
|
|
359
|
+
showBuiltIns: false, // Hides built-in options from Effect help
|
|
360
|
+
})
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
**Why showBuiltIns: false:**
|
|
364
|
+
This prevents Effect CLI from showing its automatic --help and --version options in help output, since we handle those ourselves with custom formatting.
|
|
365
|
+
|
|
366
|
+
## Where Each Command Gets Its Help
|
|
367
|
+
|
|
368
|
+
### Commands Using Custom Help Exclusively
|
|
369
|
+
|
|
370
|
+
All primary commands use custom help from help.ts:
|
|
371
|
+
|
|
372
|
+
1. **index** - helpContent.index (lines 24-58)
|
|
373
|
+
2. **search** - helpContent.search (lines 59-124)
|
|
374
|
+
3. **context** - helpContent.context (lines 125-178)
|
|
375
|
+
4. **tree** - helpContent.tree (lines 179-196)
|
|
376
|
+
5. **links** - helpContent.links (lines 197-213)
|
|
377
|
+
6. **backlinks** - helpContent.backlinks (lines 214-231)
|
|
378
|
+
7. **stats** - helpContent.stats (lines 232-245)
|
|
379
|
+
8. **config** - helpContent.config (lines 246-277)
|
|
380
|
+
|
|
381
|
+
### Effect CLI Default Commands
|
|
382
|
+
|
|
383
|
+
None currently. The custom help system intercepts all help requests.
|
|
384
|
+
|
|
385
|
+
**Historical Issue:**
|
|
386
|
+
Before the `checkBareSubcommandHelp` fix, running `mdcontext config` (no args) would show Effect's default output. This is now fixed.
|
|
387
|
+
|
|
388
|
+
## How to Fix Commands Using Effect Defaults
|
|
389
|
+
|
|
390
|
+
If you encounter a command showing ugly Effect CLI help, follow this pattern:
|
|
391
|
+
|
|
392
|
+
### Step 1: Add to helpContent
|
|
393
|
+
|
|
394
|
+
In help.ts, add your command to the helpContent object:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
export const helpContent: Record<string, CommandHelp> = {
|
|
398
|
+
// ... existing commands
|
|
399
|
+
|
|
400
|
+
yourCommand: {
|
|
401
|
+
description: 'Brief description of what it does',
|
|
402
|
+
usage: 'mdcontext yourCommand [options]',
|
|
403
|
+
examples: [
|
|
404
|
+
'mdcontext yourCommand # Basic usage',
|
|
405
|
+
'mdcontext yourCommand --flag # With option',
|
|
406
|
+
],
|
|
407
|
+
options: [
|
|
408
|
+
{ name: '--flag', description: 'What the flag does' },
|
|
409
|
+
],
|
|
410
|
+
notes: [
|
|
411
|
+
'Any important notes about prerequisites or behavior',
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Step 2: Ensure checkSubcommandHelp Covers It
|
|
418
|
+
|
|
419
|
+
The existing checkSubcommandHelp should automatically handle it:
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
if (hasHelpFlag && command && helpContent[command]) {
|
|
423
|
+
showSubcommandHelp(command)
|
|
424
|
+
process.exit(0)
|
|
425
|
+
}
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
As long as your command is in helpContent, `mdcontext yourCommand --help` will work.
|
|
429
|
+
|
|
430
|
+
### Step 3: Handle Bare Command (if has subcommands)
|
|
431
|
+
|
|
432
|
+
If your command has subcommands and you want `mdcontext yourCommand` (no args) to show help instead of Effect's listing, add it to checkBareSubcommandHelp:
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
export const checkBareSubcommandHelp = (): boolean => {
|
|
436
|
+
const args = process.argv.slice(2)
|
|
437
|
+
if (args.length !== 1) return false
|
|
438
|
+
|
|
439
|
+
const command = args[0]
|
|
440
|
+
|
|
441
|
+
// Add your command here
|
|
442
|
+
if ((command === 'config' || command === 'yourCommand') && helpContent[command]) {
|
|
443
|
+
showSubcommandHelp(command)
|
|
444
|
+
process.exit(0)
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return false
|
|
448
|
+
}
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## Config Command Case Study
|
|
452
|
+
|
|
453
|
+
The config command demonstrates the complete help system architecture:
|
|
454
|
+
|
|
455
|
+
### Variants and Their Help
|
|
456
|
+
|
|
457
|
+
1. **`mdcontext config`** (no args)
|
|
458
|
+
- **Interceptor:** checkBareSubcommandHelp (help.ts line 425-427)
|
|
459
|
+
- **Help shown:** Custom config help (helpContent.config)
|
|
460
|
+
- **Why:** Prevents ugly Effect listing of subcommands
|
|
461
|
+
|
|
462
|
+
2. **`mdcontext config --help`**
|
|
463
|
+
- **Interceptor:** checkSubcommandHelp (help.ts line 402-404)
|
|
464
|
+
- **Help shown:** Custom config help (helpContent.config)
|
|
465
|
+
- **Why:** Standard help request
|
|
466
|
+
|
|
467
|
+
3. **`mdcontext config init --help`**
|
|
468
|
+
- **Interceptor:** checkSubcommandHelp (help.ts line 402-404)
|
|
469
|
+
- **Help shown:** Custom config help (helpContent.config) - PARENT help
|
|
470
|
+
- **Why:** args[0] is "config", so parent help is shown
|
|
471
|
+
- **Intentional:** Config subcommands are simple, centralized help is fine
|
|
472
|
+
|
|
473
|
+
4. **`mdcontext config show --help`**
|
|
474
|
+
- Same as init - shows parent config help
|
|
475
|
+
|
|
476
|
+
5. **`mdcontext config check --help`**
|
|
477
|
+
- Same as init - shows parent config help
|
|
478
|
+
|
|
479
|
+
### Config Command Implementation
|
|
480
|
+
|
|
481
|
+
**File:** src/cli/commands/config-cmd.ts
|
|
482
|
+
|
|
483
|
+
**Structure:**
|
|
484
|
+
```typescript
|
|
485
|
+
// Three subcommands
|
|
486
|
+
const initCommand = Command.make('init', {...})
|
|
487
|
+
const showCommand = Command.make('show', {...})
|
|
488
|
+
const checkCommand = Command.make('check', {...})
|
|
489
|
+
|
|
490
|
+
// Parent command with subcommands
|
|
491
|
+
export const configCommand = Command.make('config').pipe(
|
|
492
|
+
Command.withDescription('Configuration management'),
|
|
493
|
+
Command.withSubcommands([initCommand, showCommand, checkCommand]),
|
|
494
|
+
)
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Each Subcommand:**
|
|
498
|
+
- Has its own options defined via Effect CLI's Options API
|
|
499
|
+
- Implements its own Effect generator function for execution
|
|
500
|
+
- Has its own Effect CLI description via withDescription()
|
|
501
|
+
|
|
502
|
+
**But:**
|
|
503
|
+
- All share the same custom help from helpContent.config
|
|
504
|
+
- This is intentional - the parent help documents all subcommands clearly
|
|
505
|
+
- Keeps help centralized and consistent
|
|
506
|
+
|
|
507
|
+
## Effect CLI Options vs Custom Help
|
|
508
|
+
|
|
509
|
+
### Effect CLI Options (Used in Implementation)
|
|
510
|
+
|
|
511
|
+
Example from config init (config-cmd.ts lines 194-210):
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
const initCommand = Command.make(
|
|
515
|
+
'init',
|
|
516
|
+
{
|
|
517
|
+
format: Options.choice('format', ['js', 'json']).pipe(
|
|
518
|
+
Options.withAlias('f'),
|
|
519
|
+
Options.withDescription('Config file format (js recommended for type safety)'),
|
|
520
|
+
Options.withDefault('js' as const),
|
|
521
|
+
),
|
|
522
|
+
force: Options.boolean('force').pipe(
|
|
523
|
+
Options.withDescription('Overwrite existing config file'),
|
|
524
|
+
Options.withDefault(false),
|
|
525
|
+
),
|
|
526
|
+
json: jsonOption,
|
|
527
|
+
pretty: prettyOption,
|
|
528
|
+
},
|
|
529
|
+
({ format, force, json, pretty }) => Effect.gen(function* () {
|
|
530
|
+
// Implementation
|
|
531
|
+
}),
|
|
532
|
+
).pipe(Command.withDescription('Create a starter config file'))
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
**These Effect options:**
|
|
536
|
+
- Define the command's actual behavior
|
|
537
|
+
- Control parsing and validation
|
|
538
|
+
- Are NOT used for help display (custom help is shown instead)
|
|
539
|
+
|
|
540
|
+
### Custom Help Content (Used for Display)
|
|
541
|
+
|
|
542
|
+
From helpContent.config (help.ts lines 246-277):
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
config: {
|
|
546
|
+
description: 'Configuration management',
|
|
547
|
+
usage: 'mdcontext config <command> [options]',
|
|
548
|
+
examples: [
|
|
549
|
+
'mdcontext config init # Create a starter config file',
|
|
550
|
+
'mdcontext config init --format json # Create JSON config instead of JS',
|
|
551
|
+
'mdcontext config show # Show config file location',
|
|
552
|
+
'mdcontext config check # Validate and show effective config',
|
|
553
|
+
'mdcontext config check --json # Output config as JSON',
|
|
554
|
+
],
|
|
555
|
+
options: [
|
|
556
|
+
{ name: 'init', description: 'Create a starter config file' },
|
|
557
|
+
{ name: 'show', description: 'Display config file location' },
|
|
558
|
+
{ name: 'check', description: 'Validate and show effective configuration' },
|
|
559
|
+
{ name: '-f, --format <format>', description: 'Config format: js or json (init only)' },
|
|
560
|
+
{ name: '--force', description: 'Overwrite existing config (init only)' },
|
|
561
|
+
{ name: '--json', description: 'Output as JSON' },
|
|
562
|
+
{ name: '--pretty', description: 'Pretty-print JSON output' },
|
|
563
|
+
],
|
|
564
|
+
notes: [
|
|
565
|
+
'Config files set persistent defaults for all commands.',
|
|
566
|
+
'Precedence: CLI flags > environment > config file > defaults.',
|
|
567
|
+
'See docs/CONFIG.md for full configuration reference.',
|
|
568
|
+
],
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**This custom content:**
|
|
573
|
+
- Is displayed when --help is requested
|
|
574
|
+
- Must be manually kept in sync with actual options
|
|
575
|
+
- Provides better formatting, examples, and notes than Effect can generate
|
|
576
|
+
|
|
577
|
+
### The Sync Challenge
|
|
578
|
+
|
|
579
|
+
There are TWO sources of truth:
|
|
580
|
+
1. **Effect CLI options** - What the command actually accepts
|
|
581
|
+
2. **Custom help content** - What we tell users it accepts
|
|
582
|
+
|
|
583
|
+
**Risk:** These can get out of sync if you:
|
|
584
|
+
- Add a new option to Effect options but forget to update helpContent
|
|
585
|
+
- Change an option name/description in one place but not the other
|
|
586
|
+
- Add a new subcommand but don't update the help examples
|
|
587
|
+
|
|
588
|
+
**Mitigation:**
|
|
589
|
+
- Keep help.ts and command implementation files close together
|
|
590
|
+
- Review both when making changes
|
|
591
|
+
- Consider automated tests that compare option definitions
|
|
592
|
+
|
|
593
|
+
## Design Decisions
|
|
594
|
+
|
|
595
|
+
### Why Not Use Effect CLI Help Exclusively?
|
|
596
|
+
|
|
597
|
+
Effect CLI can auto-generate help from command definitions, but:
|
|
598
|
+
|
|
599
|
+
1. **Formatting Quality:** Effect's default is functional but not beautiful
|
|
600
|
+
- Different color scheme (white vs yellow headers)
|
|
601
|
+
- Different structure (dashes before commands)
|
|
602
|
+
- Less polished overall feel
|
|
603
|
+
|
|
604
|
+
2. **Brand Consistency:** mdcontext has high standards for CLI UX
|
|
605
|
+
- Help should match the quality of git, gh, npm
|
|
606
|
+
- Consistent color scheme across all output
|
|
607
|
+
- Professional polish reflects well on the tool
|
|
608
|
+
|
|
609
|
+
3. **Examples and Notes:** Auto-generated help can't include:
|
|
610
|
+
- Progressive example sequences (basic → advanced)
|
|
611
|
+
- Real-world workflow examples
|
|
612
|
+
- Context about prerequisites
|
|
613
|
+
- Tips and best practices
|
|
614
|
+
|
|
615
|
+
4. **Control:** Custom help gives complete control over:
|
|
616
|
+
- What information is shown and in what order
|
|
617
|
+
- How examples are formatted and grouped
|
|
618
|
+
- What notes and context are provided
|
|
619
|
+
|
|
620
|
+
### Why Keep Effect CLI at All?
|
|
621
|
+
|
|
622
|
+
If we're overriding all help with custom implementations, why use Effect CLI?
|
|
623
|
+
|
|
624
|
+
**Benefits of Effect CLI:**
|
|
625
|
+
1. **Command Structure:** Defines the command hierarchy
|
|
626
|
+
2. **Option Parsing:** Handles flag parsing, validation, defaults
|
|
627
|
+
3. **Type Safety:** Options are fully typed in TypeScript
|
|
628
|
+
4. **Error Handling:** Built-in validation error messages
|
|
629
|
+
5. **Subcommand Routing:** Automatically routes to the right subcommand
|
|
630
|
+
6. **Future Flexibility:** Easy to add new commands with proper structure
|
|
631
|
+
|
|
632
|
+
**What We Override:**
|
|
633
|
+
- Only the help display
|
|
634
|
+
- Keep all the parsing and validation logic
|
|
635
|
+
|
|
636
|
+
**Hybrid Approach:**
|
|
637
|
+
- Use Effect for structure, parsing, and execution
|
|
638
|
+
- Use custom help for display and user experience
|
|
639
|
+
|
|
640
|
+
### Why checkBareSubcommandHelp Only Handles "config"?
|
|
641
|
+
|
|
642
|
+
The function could be generalized to handle any command with subcommands:
|
|
643
|
+
|
|
644
|
+
```typescript
|
|
645
|
+
// Current approach (hard-coded):
|
|
646
|
+
if (command === 'config' && helpContent[command]) {
|
|
647
|
+
showSubcommandHelp(command)
|
|
648
|
+
process.exit(0)
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Could be generalized to:
|
|
652
|
+
const commandsWithSubcommands = ['config', 'future-command']
|
|
653
|
+
if (commandsWithSubcommands.includes(command) && helpContent[command]) {
|
|
654
|
+
showSubcommandHelp(command)
|
|
655
|
+
process.exit(0)
|
|
656
|
+
}
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
**Why it's not generalized:**
|
|
660
|
+
1. **YAGNI (You Ain't Gonna Need It):** Only config has this issue currently
|
|
661
|
+
2. **Explicit is Better:** Hard-coding makes the behavior clear
|
|
662
|
+
3. **Easy to Extend:** When a second command needs it, then generalize
|
|
663
|
+
|
|
664
|
+
## Testing the Help System
|
|
665
|
+
|
|
666
|
+
### Manual Testing Commands
|
|
667
|
+
|
|
668
|
+
Test all help variants to ensure custom help is shown:
|
|
669
|
+
|
|
670
|
+
```bash
|
|
671
|
+
# Main help
|
|
672
|
+
mdcontext
|
|
673
|
+
mdcontext --help
|
|
674
|
+
mdcontext -h
|
|
675
|
+
mdcontext help
|
|
676
|
+
|
|
677
|
+
# Subcommand help
|
|
678
|
+
mdcontext index --help
|
|
679
|
+
mdcontext search --help
|
|
680
|
+
mdcontext context --help
|
|
681
|
+
mdcontext tree --help
|
|
682
|
+
mdcontext links --help
|
|
683
|
+
mdcontext backlinks --help
|
|
684
|
+
mdcontext stats --help
|
|
685
|
+
mdcontext config --help
|
|
686
|
+
|
|
687
|
+
# Config variants (critical tests)
|
|
688
|
+
mdcontext config # Should show custom help (not ugly Effect default)
|
|
689
|
+
mdcontext config init --help # Should show config help (parent)
|
|
690
|
+
mdcontext config show --help # Should show config help (parent)
|
|
691
|
+
mdcontext config check --help # Should show config help (parent)
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### What to Check
|
|
695
|
+
|
|
696
|
+
For each command, verify:
|
|
697
|
+
|
|
698
|
+
1. **Color scheme:**
|
|
699
|
+
- Yellow section headers (USAGE, EXAMPLES, OPTIONS, NOTES)
|
|
700
|
+
- Cyan highlights for commands and values
|
|
701
|
+
- Bold command names
|
|
702
|
+
|
|
703
|
+
2. **Section structure:**
|
|
704
|
+
- USAGE section present and concise
|
|
705
|
+
- EXAMPLES section shows progression (simple → complex)
|
|
706
|
+
- OPTIONS section shows all flags with descriptions
|
|
707
|
+
- NOTES section (if applicable) provides context
|
|
708
|
+
|
|
709
|
+
3. **No Effect CLI artifacts:**
|
|
710
|
+
- No dashes before command names
|
|
711
|
+
- No "COMMANDS" section with Effect's format
|
|
712
|
+
- No white header text
|
|
713
|
+
- No "mdcontext 0.1.0" version line in help
|
|
714
|
+
|
|
715
|
+
4. **Consistent formatting:**
|
|
716
|
+
- Options align at 24 characters
|
|
717
|
+
- Examples use consistent commenting style
|
|
718
|
+
- Notes use consistent bullet format
|
|
719
|
+
|
|
720
|
+
### Quality Checklist
|
|
721
|
+
|
|
722
|
+
For new commands or help updates:
|
|
723
|
+
|
|
724
|
+
- [ ] Custom help template (not Effect default)
|
|
725
|
+
- [ ] Yellow headers, cyan highlights
|
|
726
|
+
- [ ] USAGE, EXAMPLES, OPTIONS sections
|
|
727
|
+
- [ ] NOTES section if prerequisites/behavior needs explanation
|
|
728
|
+
- [ ] Progressive examples (simple → complex)
|
|
729
|
+
- [ ] Real-world workflow examples where applicable
|
|
730
|
+
- [ ] No args shows helpful message (not raw Effect listing)
|
|
731
|
+
- [ ] Subcommand help works (mdcontext <cmd> --help)
|
|
732
|
+
- [ ] Help content matches actual command options
|
|
733
|
+
- [ ] All examples are tested and work
|
|
734
|
+
|
|
735
|
+
## Future Enhancements
|
|
736
|
+
|
|
737
|
+
### Potential Improvements
|
|
738
|
+
|
|
739
|
+
1. **Subcommand-Specific Help:**
|
|
740
|
+
- Currently config subcommands show parent help
|
|
741
|
+
- Could add specific help for `config init --help`, etc.
|
|
742
|
+
- Only worth it if subcommands grow complex
|
|
743
|
+
|
|
744
|
+
2. **Help Content Validation:**
|
|
745
|
+
- Automated tests comparing Effect options to helpContent
|
|
746
|
+
- Warn if options are defined but not documented in help
|
|
747
|
+
- Catch sync issues between implementation and help
|
|
748
|
+
|
|
749
|
+
3. **Help Templates:**
|
|
750
|
+
- Extract common formatting into reusable functions
|
|
751
|
+
- Reduce duplication in showMainHelp and showSubcommandHelp
|
|
752
|
+
- Consistent spacing and alignment helpers
|
|
753
|
+
|
|
754
|
+
4. **Dynamic Help Generation:**
|
|
755
|
+
- Generate helpContent from Effect command definitions
|
|
756
|
+
- Keep the custom formatting
|
|
757
|
+
- Automatically stay in sync with option changes
|
|
758
|
+
|
|
759
|
+
5. **Help Search:**
|
|
760
|
+
- `mdcontext help search <term>` to find commands
|
|
761
|
+
- Search across all help content
|
|
762
|
+
- Show relevant examples for a topic
|
|
763
|
+
|
|
764
|
+
6. **Man Pages:**
|
|
765
|
+
- Generate man pages from helpContent
|
|
766
|
+
- Install via npm postinstall script
|
|
767
|
+
- Allow `man mdcontext` for offline help
|
|
768
|
+
|
|
769
|
+
## Related Files
|
|
770
|
+
|
|
771
|
+
### Core Help System
|
|
772
|
+
- **src/cli/help.ts** - Custom help implementation
|
|
773
|
+
- **src/cli/main.ts** - Help request routing and interceptors
|
|
774
|
+
- **src/cli/commands/*.ts** - Command definitions with Effect CLI
|
|
775
|
+
|
|
776
|
+
### Help Content
|
|
777
|
+
All help displayed to users is defined in help.ts:
|
|
778
|
+
- helpContent object (lines 24-277)
|
|
779
|
+
- showMainHelp function (lines 329-385)
|
|
780
|
+
- showSubcommandHelp function (lines 286-324)
|
|
781
|
+
|
|
782
|
+
### Interceptors
|
|
783
|
+
Help request interceptors in main.ts:
|
|
784
|
+
- checkSubcommandHelp (line 90)
|
|
785
|
+
- checkBareSubcommandHelp (line 93)
|
|
786
|
+
- shouldShowMainHelp (line 96)
|
|
787
|
+
|
|
788
|
+
### Command Implementations
|
|
789
|
+
Each command directory contains Effect CLI definitions:
|
|
790
|
+
- config-cmd.ts (config with subcommands)
|
|
791
|
+
- index-cmd.ts (index command)
|
|
792
|
+
- search.ts (search command)
|
|
793
|
+
- context.ts (context command)
|
|
794
|
+
- tree.ts (tree command)
|
|
795
|
+
- links.ts (links command)
|
|
796
|
+
- backlinks.ts (backlinks command)
|
|
797
|
+
- stats.ts (stats command)
|
|
798
|
+
|
|
799
|
+
## Troubleshooting
|
|
800
|
+
|
|
801
|
+
### Issue: Effect CLI Default Help Showing
|
|
802
|
+
|
|
803
|
+
**Symptoms:**
|
|
804
|
+
- White section headers instead of yellow
|
|
805
|
+
- Dashes before command names
|
|
806
|
+
- Missing examples and notes sections
|
|
807
|
+
- Generic "mdcontext 0.1.0" header
|
|
808
|
+
|
|
809
|
+
**Diagnosis:**
|
|
810
|
+
Custom help interceptor is not catching the help request.
|
|
811
|
+
|
|
812
|
+
**Solutions:**
|
|
813
|
+
|
|
814
|
+
1. **For `mdcontext <cmd> --help`:**
|
|
815
|
+
- Add command to helpContent in help.ts
|
|
816
|
+
- checkSubcommandHelp will automatically handle it
|
|
817
|
+
|
|
818
|
+
2. **For `mdcontext <cmd>` (bare command with subcommands):**
|
|
819
|
+
- Add command to checkBareSubcommandHelp
|
|
820
|
+
- Prevents Effect's subcommand listing
|
|
821
|
+
|
|
822
|
+
3. **For new command patterns:**
|
|
823
|
+
- Add new interceptor function in help.ts
|
|
824
|
+
- Call it in main.ts before Effect CLI runs
|
|
825
|
+
|
|
826
|
+
### Issue: Help Content Out of Sync
|
|
827
|
+
|
|
828
|
+
**Symptoms:**
|
|
829
|
+
- Help shows options that don't work
|
|
830
|
+
- Command accepts options not shown in help
|
|
831
|
+
- Examples fail when run
|
|
832
|
+
|
|
833
|
+
**Diagnosis:**
|
|
834
|
+
helpContent in help.ts doesn't match actual Effect CLI option definitions.
|
|
835
|
+
|
|
836
|
+
**Solution:**
|
|
837
|
+
1. Compare helpContent.yourCommand to actual command options
|
|
838
|
+
2. Update helpContent to match implementation
|
|
839
|
+
3. Test all examples to ensure they work
|
|
840
|
+
|
|
841
|
+
**Prevention:**
|
|
842
|
+
- Update help and implementation together
|
|
843
|
+
- Review both files when making changes
|
|
844
|
+
- Consider automated sync tests
|
|
845
|
+
|
|
846
|
+
### Issue: Subcommand Help Shows Parent Help
|
|
847
|
+
|
|
848
|
+
**Symptoms:**
|
|
849
|
+
- `mdcontext config init --help` shows config help (not init-specific)
|
|
850
|
+
|
|
851
|
+
**Explanation:**
|
|
852
|
+
This is intentional for config command (see lines 425-427 in help.ts).
|
|
853
|
+
|
|
854
|
+
**When to Change:**
|
|
855
|
+
Only if subcommand grows complex enough to need dedicated help.
|
|
856
|
+
|
|
857
|
+
**How to Change:**
|
|
858
|
+
1. Add specific help to helpContent (e.g., helpContent['config/init'])
|
|
859
|
+
2. Modify checkSubcommandHelp to handle subcommand paths
|
|
860
|
+
3. Update routing to show subcommand help instead of parent
|
|
861
|
+
|
|
862
|
+
## Summary
|
|
863
|
+
|
|
864
|
+
The mdcontext help system is a **hybrid architecture** that combines:
|
|
865
|
+
|
|
866
|
+
1. **Custom Help Display (help.ts)**
|
|
867
|
+
- Beautiful, branded formatting
|
|
868
|
+
- Progressive examples
|
|
869
|
+
- Helpful notes and context
|
|
870
|
+
- Consistent color scheme
|
|
871
|
+
|
|
872
|
+
2. **Effect CLI Structure (commands/*.ts)**
|
|
873
|
+
- Command hierarchy and routing
|
|
874
|
+
- Option parsing and validation
|
|
875
|
+
- Type safety
|
|
876
|
+
- Error handling
|
|
877
|
+
|
|
878
|
+
3. **Interceptor Pattern (main.ts)**
|
|
879
|
+
- Catches help requests before Effect CLI
|
|
880
|
+
- Routes to custom help display
|
|
881
|
+
- Prevents ugly Effect defaults
|
|
882
|
+
|
|
883
|
+
**Key Insight:**
|
|
884
|
+
We use Effect CLI for what it's good at (structure, parsing, types) and override only the help display with custom implementations. This gives us both excellent DX (developer experience) and UX (user experience).
|
|
885
|
+
|
|
886
|
+
**Critical Fix:**
|
|
887
|
+
checkBareSubcommandHelp prevents `mdcontext config` from showing Effect's raw command listing, maintaining the quality bar across all help variants.
|
|
888
|
+
|
|
889
|
+
**Maintenance:**
|
|
890
|
+
The main risk is help content drifting out of sync with actual command options. Keep help.ts and command implementations aligned when making changes.
|