mdcontext 0.0.1 → 0.1.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.
Files changed (140) hide show
  1. package/.changeset/README.md +28 -0
  2. package/.changeset/config.json +11 -0
  3. package/.github/workflows/ci.yml +83 -0
  4. package/.github/workflows/release.yml +113 -0
  5. package/.tldrignore +112 -0
  6. package/AGENTS.md +46 -0
  7. package/BACKLOG.md +338 -0
  8. package/README.md +231 -11
  9. package/biome.json +36 -0
  10. package/cspell.config.yaml +14 -0
  11. package/dist/chunk-KRYIFLQR.js +92 -0
  12. package/dist/chunk-S7E6TFX6.js +742 -0
  13. package/dist/chunk-VVTGZNBT.js +1519 -0
  14. package/dist/cli/main.d.ts +1 -0
  15. package/dist/cli/main.js +2015 -0
  16. package/dist/index.d.ts +266 -0
  17. package/dist/index.js +86 -0
  18. package/dist/mcp/server.d.ts +1 -0
  19. package/dist/mcp/server.js +376 -0
  20. package/docs/019-USAGE.md +586 -0
  21. package/docs/020-current-implementation.md +364 -0
  22. package/docs/021-DOGFOODING-FINDINGS.md +175 -0
  23. package/docs/BACKLOG.md +80 -0
  24. package/docs/DESIGN.md +439 -0
  25. package/docs/PROJECT.md +88 -0
  26. package/docs/ROADMAP.md +407 -0
  27. package/docs/test-links.md +9 -0
  28. package/package.json +69 -10
  29. package/pnpm-workspace.yaml +5 -0
  30. package/research/config-analysis/01-current-implementation.md +470 -0
  31. package/research/config-analysis/02-strategy-recommendation.md +428 -0
  32. package/research/config-analysis/03-task-candidates.md +715 -0
  33. package/research/config-analysis/033-research-configuration-management.md +828 -0
  34. package/research/config-analysis/034-research-effect-cli-config.md +1504 -0
  35. package/research/config-analysis/04-consolidated-task-candidates.md +277 -0
  36. package/research/dogfood/consolidated-tool-evaluation.md +373 -0
  37. package/research/dogfood/strategy-a/a-synthesis.md +184 -0
  38. package/research/dogfood/strategy-a/a1-docs.md +226 -0
  39. package/research/dogfood/strategy-a/a2-amorphic.md +156 -0
  40. package/research/dogfood/strategy-a/a3-llm.md +164 -0
  41. package/research/dogfood/strategy-b/b-synthesis.md +228 -0
  42. package/research/dogfood/strategy-b/b1-architecture.md +207 -0
  43. package/research/dogfood/strategy-b/b2-gaps.md +258 -0
  44. package/research/dogfood/strategy-b/b3-workflows.md +250 -0
  45. package/research/dogfood/strategy-c/c-synthesis.md +451 -0
  46. package/research/dogfood/strategy-c/c1-explorer.md +192 -0
  47. package/research/dogfood/strategy-c/c2-diver-memory.md +145 -0
  48. package/research/dogfood/strategy-c/c3-diver-control.md +148 -0
  49. package/research/dogfood/strategy-c/c4-diver-failure.md +151 -0
  50. package/research/dogfood/strategy-c/c5-diver-execution.md +221 -0
  51. package/research/dogfood/strategy-c/c6-diver-org.md +221 -0
  52. package/research/effect-cli-error-handling.md +845 -0
  53. package/research/effect-errors-as-values.md +943 -0
  54. package/research/errors-task-analysis/00-consolidated-tasks.md +207 -0
  55. package/research/errors-task-analysis/cli-commands-analysis.md +909 -0
  56. package/research/errors-task-analysis/embeddings-analysis.md +709 -0
  57. package/research/errors-task-analysis/index-search-analysis.md +812 -0
  58. package/research/mdcontext-error-analysis.md +521 -0
  59. package/research/npm_publish/011-npm-workflow-research-agent2.md +792 -0
  60. package/research/npm_publish/012-npm-workflow-research-agent1.md +530 -0
  61. package/research/npm_publish/013-npm-workflow-research-agent3.md +722 -0
  62. package/research/npm_publish/014-npm-workflow-synthesis.md +556 -0
  63. package/research/npm_publish/031-npm-workflow-task-analysis.md +134 -0
  64. package/research/semantic-search/002-research-embedding-models.md +490 -0
  65. package/research/semantic-search/003-research-rag-alternatives.md +523 -0
  66. package/research/semantic-search/004-research-vector-search.md +841 -0
  67. package/research/semantic-search/032-research-semantic-search.md +427 -0
  68. package/research/task-management-2026/00-synthesis-recommendations.md +295 -0
  69. package/research/task-management-2026/01-ai-workflow-tools.md +416 -0
  70. package/research/task-management-2026/02-agent-framework-patterns.md +476 -0
  71. package/research/task-management-2026/03-lightweight-file-based.md +567 -0
  72. package/research/task-management-2026/04-established-tools-ai-features.md +541 -0
  73. package/research/task-management-2026/linear/01-core-features-workflow.md +771 -0
  74. package/research/task-management-2026/linear/02-api-integrations.md +930 -0
  75. package/research/task-management-2026/linear/03-ai-features.md +368 -0
  76. package/research/task-management-2026/linear/04-pricing-setup.md +205 -0
  77. package/research/task-management-2026/linear/05-usage-patterns-best-practices.md +605 -0
  78. package/scripts/rebuild-hnswlib.js +63 -0
  79. package/src/cli/argv-preprocessor.test.ts +210 -0
  80. package/src/cli/argv-preprocessor.ts +202 -0
  81. package/src/cli/cli.test.ts +430 -0
  82. package/src/cli/commands/backlinks.ts +54 -0
  83. package/src/cli/commands/context.ts +197 -0
  84. package/src/cli/commands/index-cmd.ts +300 -0
  85. package/src/cli/commands/index.ts +13 -0
  86. package/src/cli/commands/links.ts +52 -0
  87. package/src/cli/commands/search.ts +451 -0
  88. package/src/cli/commands/stats.ts +146 -0
  89. package/src/cli/commands/tree.ts +107 -0
  90. package/src/cli/flag-schemas.ts +275 -0
  91. package/src/cli/help.ts +386 -0
  92. package/src/cli/index.ts +9 -0
  93. package/src/cli/main.ts +145 -0
  94. package/src/cli/options.ts +31 -0
  95. package/src/cli/typo-suggester.test.ts +105 -0
  96. package/src/cli/typo-suggester.ts +130 -0
  97. package/src/cli/utils.ts +126 -0
  98. package/src/core/index.ts +1 -0
  99. package/src/core/types.ts +140 -0
  100. package/src/embeddings/index.ts +8 -0
  101. package/src/embeddings/openai-provider.ts +165 -0
  102. package/src/embeddings/semantic-search.ts +583 -0
  103. package/src/embeddings/types.ts +82 -0
  104. package/src/embeddings/vector-store.ts +299 -0
  105. package/src/index/index.ts +4 -0
  106. package/src/index/indexer.ts +446 -0
  107. package/src/index/storage.ts +196 -0
  108. package/src/index/types.ts +109 -0
  109. package/src/index/watcher.ts +131 -0
  110. package/src/index.ts +8 -0
  111. package/src/mcp/server.ts +483 -0
  112. package/src/parser/index.ts +1 -0
  113. package/src/parser/parser.test.ts +291 -0
  114. package/src/parser/parser.ts +395 -0
  115. package/src/parser/section-filter.ts +270 -0
  116. package/src/search/query-parser.test.ts +260 -0
  117. package/src/search/query-parser.ts +319 -0
  118. package/src/search/searcher.test.ts +182 -0
  119. package/src/search/searcher.ts +602 -0
  120. package/src/summarize/budget-bugs.test.ts +620 -0
  121. package/src/summarize/formatters.ts +419 -0
  122. package/src/summarize/index.ts +20 -0
  123. package/src/summarize/summarizer.test.ts +275 -0
  124. package/src/summarize/summarizer.ts +528 -0
  125. package/src/summarize/verify-bugs.test.ts +238 -0
  126. package/src/utils/index.ts +1 -0
  127. package/src/utils/tokens.test.ts +142 -0
  128. package/src/utils/tokens.ts +186 -0
  129. package/tests/fixtures/cli/.mdcontext/config.json +8 -0
  130. package/tests/fixtures/cli/.mdcontext/indexes/documents.json +33 -0
  131. package/tests/fixtures/cli/.mdcontext/indexes/links.json +12 -0
  132. package/tests/fixtures/cli/.mdcontext/indexes/sections.json +233 -0
  133. package/tests/fixtures/cli/.mdcontext/vectors.bin +0 -0
  134. package/tests/fixtures/cli/.mdcontext/vectors.meta.json +1264 -0
  135. package/tests/fixtures/cli/README.md +9 -0
  136. package/tests/fixtures/cli/api-reference.md +11 -0
  137. package/tests/fixtures/cli/getting-started.md +11 -0
  138. package/tsconfig.json +26 -0
  139. package/vitest.config.ts +21 -0
  140. package/vitest.setup.ts +12 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Index data types for mdcontext
3
+ */
4
+
5
+ // ============================================================================
6
+ // Configuration
7
+ // ============================================================================
8
+
9
+ export interface IndexConfig {
10
+ readonly version: number
11
+ readonly rootPath: string
12
+ readonly include: readonly string[]
13
+ readonly exclude: readonly string[]
14
+ readonly createdAt: string
15
+ readonly updatedAt: string
16
+ }
17
+
18
+ // ============================================================================
19
+ // Document Index
20
+ // ============================================================================
21
+
22
+ export interface DocumentIndex {
23
+ readonly version: number
24
+ readonly rootPath: string
25
+ readonly documents: Record<string, DocumentEntry>
26
+ }
27
+
28
+ export interface DocumentEntry {
29
+ readonly id: string
30
+ readonly path: string
31
+ readonly title: string
32
+ readonly mtime: number
33
+ readonly hash: string
34
+ readonly tokenCount: number
35
+ readonly sectionCount: number
36
+ }
37
+
38
+ // ============================================================================
39
+ // Section Index
40
+ // ============================================================================
41
+
42
+ export interface SectionIndex {
43
+ readonly version: number
44
+ readonly sections: Record<string, SectionEntry>
45
+ readonly byHeading: Record<string, readonly string[]>
46
+ readonly byDocument: Record<string, readonly string[]>
47
+ }
48
+
49
+ export interface SectionEntry {
50
+ readonly id: string
51
+ readonly documentId: string
52
+ readonly documentPath: string
53
+ readonly heading: string
54
+ readonly level: number
55
+ readonly startLine: number
56
+ readonly endLine: number
57
+ readonly tokenCount: number
58
+ readonly hasCode: boolean
59
+ readonly hasList: boolean
60
+ readonly hasTable: boolean
61
+ }
62
+
63
+ // ============================================================================
64
+ // Link Index
65
+ // ============================================================================
66
+
67
+ export interface LinkIndex {
68
+ readonly version: number
69
+ readonly forward: Record<string, readonly string[]>
70
+ readonly backward: Record<string, readonly string[]>
71
+ readonly broken: readonly string[]
72
+ }
73
+
74
+ // ============================================================================
75
+ // Index Result
76
+ // ============================================================================
77
+
78
+ export interface IndexResult {
79
+ readonly documentsIndexed: number
80
+ readonly sectionsIndexed: number
81
+ readonly linksIndexed: number
82
+ readonly totalDocuments: number
83
+ readonly totalSections: number
84
+ readonly totalLinks: number
85
+ readonly duration: number
86
+ readonly errors: readonly IndexBuildError[]
87
+ }
88
+
89
+ export interface IndexBuildError {
90
+ readonly path: string
91
+ readonly message: string
92
+ }
93
+
94
+ // ============================================================================
95
+ // Index Paths
96
+ // ============================================================================
97
+
98
+ export const INDEX_DIR = '.mdcontext'
99
+ export const INDEX_VERSION = 1
100
+
101
+ export const getIndexPaths = (rootPath: string) => ({
102
+ root: `${rootPath}/${INDEX_DIR}`,
103
+ config: `${rootPath}/${INDEX_DIR}/config.json`,
104
+ documents: `${rootPath}/${INDEX_DIR}/indexes/documents.json`,
105
+ sections: `${rootPath}/${INDEX_DIR}/indexes/sections.json`,
106
+ links: `${rootPath}/${INDEX_DIR}/indexes/links.json`,
107
+ cache: `${rootPath}/${INDEX_DIR}/cache`,
108
+ parsed: `${rootPath}/${INDEX_DIR}/cache/parsed`,
109
+ })
@@ -0,0 +1,131 @@
1
+ /**
2
+ * File watcher for automatic re-indexing
3
+ */
4
+
5
+ import * as path from 'node:path'
6
+ import { watch } from 'chokidar'
7
+ import { Effect } from 'effect'
8
+
9
+ import { buildIndex, type IndexOptions } from './indexer.js'
10
+ import { createStorage, indexExists } from './storage.js'
11
+
12
+ // ============================================================================
13
+ // Watcher Types
14
+ // ============================================================================
15
+
16
+ export interface WatcherOptions extends IndexOptions {
17
+ readonly debounceMs?: number
18
+ readonly onIndex?: (result: {
19
+ documentsIndexed: number
20
+ duration: number
21
+ }) => void
22
+ readonly onError?: (error: Error) => void
23
+ }
24
+
25
+ export interface Watcher {
26
+ readonly stop: () => void
27
+ }
28
+
29
+ // ============================================================================
30
+ // Watcher Implementation
31
+ // ============================================================================
32
+
33
+ const isMarkdownFile = (filePath: string): boolean =>
34
+ filePath.endsWith('.md') || filePath.endsWith('.mdx')
35
+
36
+ export const watchDirectory = (
37
+ rootPath: string,
38
+ options: WatcherOptions = {},
39
+ ): Effect.Effect<Watcher, Error> =>
40
+ Effect.gen(function* () {
41
+ const resolvedRoot = path.resolve(rootPath)
42
+ const storage = createStorage(resolvedRoot)
43
+ const debounceMs = options.debounceMs ?? 300
44
+
45
+ // Ensure index exists
46
+ const exists = yield* indexExists(storage)
47
+ if (!exists) {
48
+ // Build initial index
49
+ const result = yield* buildIndex(resolvedRoot, options)
50
+ options.onIndex?.({
51
+ documentsIndexed: result.documentsIndexed,
52
+ duration: result.duration,
53
+ })
54
+ }
55
+
56
+ // Create a debounce queue
57
+ const pendingPaths = new Set<string>()
58
+ let debounceTimer: NodeJS.Timeout | null = null
59
+
60
+ const scheduleReindex = () => {
61
+ if (debounceTimer) {
62
+ clearTimeout(debounceTimer)
63
+ }
64
+
65
+ debounceTimer = setTimeout(async () => {
66
+ if (pendingPaths.size === 0) return
67
+
68
+ pendingPaths.clear()
69
+
70
+ try {
71
+ const result = await Effect.runPromise(
72
+ buildIndex(resolvedRoot, options),
73
+ )
74
+ options.onIndex?.({
75
+ documentsIndexed: result.documentsIndexed,
76
+ duration: result.duration,
77
+ })
78
+ } catch (error) {
79
+ options.onError?.(
80
+ error instanceof Error ? error : new Error(String(error)),
81
+ )
82
+ }
83
+ }, debounceMs)
84
+ }
85
+
86
+ // Set up chokidar watcher
87
+ const watcher = watch(resolvedRoot, {
88
+ ignored: [
89
+ /(^|[/\\])\../, // Ignore dotfiles
90
+ '**/node_modules/**',
91
+ ],
92
+ persistent: true,
93
+ ignoreInitial: true,
94
+ })
95
+
96
+ watcher.on('add', (filePath) => {
97
+ if (isMarkdownFile(filePath)) {
98
+ pendingPaths.add(filePath)
99
+ scheduleReindex()
100
+ }
101
+ })
102
+
103
+ watcher.on('change', (filePath) => {
104
+ if (isMarkdownFile(filePath)) {
105
+ pendingPaths.add(filePath)
106
+ scheduleReindex()
107
+ }
108
+ })
109
+
110
+ watcher.on('unlink', (filePath) => {
111
+ if (isMarkdownFile(filePath)) {
112
+ pendingPaths.add(filePath)
113
+ scheduleReindex()
114
+ }
115
+ })
116
+
117
+ watcher.on('error', (error: unknown) => {
118
+ options.onError?.(
119
+ error instanceof Error ? error : new Error(String(error)),
120
+ )
121
+ })
122
+
123
+ return {
124
+ stop: () => {
125
+ if (debounceTimer) {
126
+ clearTimeout(debounceTimer)
127
+ }
128
+ watcher.close()
129
+ },
130
+ }
131
+ })
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * mdcontext - Token-efficient markdown analysis for LLMs
3
+ */
4
+
5
+ export * from './core/index.js'
6
+ export * from './index/index.js'
7
+ export * from './parser/index.js'
8
+ export * from './utils/index.js'