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.
Files changed (251) hide show
  1. package/.changeset/config.json +9 -9
  2. package/.claude/settings.local.json +25 -0
  3. package/.github/workflows/claude-code-review.yml +44 -0
  4. package/.github/workflows/claude.yml +85 -0
  5. package/CONTRIBUTING.md +186 -0
  6. package/NOTES/NOTES +44 -0
  7. package/README.md +206 -3
  8. package/biome.json +1 -1
  9. package/dist/chunk-23UPXDNL.js +3044 -0
  10. package/dist/chunk-2W7MO2DL.js +1366 -0
  11. package/dist/chunk-3NUAZGMA.js +1689 -0
  12. package/dist/chunk-7TOWB2XB.js +366 -0
  13. package/dist/chunk-7XOTOADQ.js +3065 -0
  14. package/dist/chunk-AH2PDM2K.js +3042 -0
  15. package/dist/chunk-BNXWSZ63.js +3742 -0
  16. package/dist/chunk-BTL5DJVU.js +3222 -0
  17. package/dist/chunk-HDHYG7E4.js +104 -0
  18. package/dist/chunk-HLR4KZBP.js +3234 -0
  19. package/dist/chunk-IP3FRFEB.js +1045 -0
  20. package/dist/chunk-KHU56VDO.js +3042 -0
  21. package/dist/chunk-KRYIFLQR.js +85 -89
  22. package/dist/chunk-LBSDNLEM.js +287 -0
  23. package/dist/chunk-MNTQ7HCP.js +2643 -0
  24. package/dist/chunk-MUJELQQ6.js +1387 -0
  25. package/dist/chunk-MXJGMSLV.js +2199 -0
  26. package/dist/chunk-N6QJGC3Z.js +2636 -0
  27. package/dist/chunk-OBELGBPM.js +1713 -0
  28. package/dist/chunk-OT7R5XTA.js +3192 -0
  29. package/dist/chunk-P7X4RA2T.js +106 -0
  30. package/dist/chunk-PIDUQNC2.js +3185 -0
  31. package/dist/chunk-POGCDIH4.js +3187 -0
  32. package/dist/chunk-PSIEOQGZ.js +3043 -0
  33. package/dist/chunk-PVRT3IHA.js +3238 -0
  34. package/dist/chunk-QNN4TT23.js +1430 -0
  35. package/dist/chunk-RE3R45RJ.js +3042 -0
  36. package/dist/chunk-S7E6TFX6.js +718 -657
  37. package/dist/chunk-SG6GLU4U.js +1378 -0
  38. package/dist/chunk-SJCDV2ST.js +274 -0
  39. package/dist/chunk-SYE5XLF3.js +104 -0
  40. package/dist/chunk-T5VLYBZD.js +103 -0
  41. package/dist/chunk-TOQB7VWU.js +3238 -0
  42. package/dist/chunk-VFNMZ4ZQ.js +3228 -0
  43. package/dist/chunk-VVTGZNBT.js +1533 -1423
  44. package/dist/chunk-W7Q4RFEV.js +104 -0
  45. package/dist/chunk-XTYYVRLO.js +3190 -0
  46. package/dist/chunk-Y6MDYVJD.js +3063 -0
  47. package/dist/cli/main.js +4072 -629
  48. package/dist/index.d.ts +420 -33
  49. package/dist/index.js +8 -15
  50. package/dist/mcp/server.js +103 -7
  51. package/dist/schema-BAWSG7KY.js +22 -0
  52. package/dist/schema-E3QUPL26.js +20 -0
  53. package/dist/schema-EHL7WUT6.js +20 -0
  54. package/docs/019-USAGE.md +44 -5
  55. package/docs/020-current-implementation.md +8 -8
  56. package/docs/021-DOGFOODING-FINDINGS.md +1 -1
  57. package/docs/CONFIG.md +1123 -0
  58. package/docs/ERRORS.md +383 -0
  59. package/docs/summarization.md +320 -0
  60. package/justfile +40 -0
  61. package/package.json +39 -33
  62. package/research/INDEX.md +315 -0
  63. package/research/code-review/README.md +90 -0
  64. package/research/code-review/cli-error-handling-review.md +979 -0
  65. package/research/code-review/code-review-validation-report.md +464 -0
  66. package/research/code-review/main-ts-review.md +1128 -0
  67. package/research/config-docs/SUMMARY.md +357 -0
  68. package/research/config-docs/TEST-RESULTS.md +776 -0
  69. package/research/config-docs/TODO.md +542 -0
  70. package/research/config-docs/analysis.md +744 -0
  71. package/research/config-docs/fix-validation.md +502 -0
  72. package/research/config-docs/help-audit.md +264 -0
  73. package/research/config-docs/help-system-analysis.md +890 -0
  74. package/research/frontmatter/COMMENTS-ARE-SKIPPED.md +149 -0
  75. package/research/frontmatter/LLM-CODE-NAVIGATION.md +276 -0
  76. package/research/issue-review.md +603 -0
  77. package/research/llm-summarization/agent-cli-tools-2026.md +1082 -0
  78. package/research/llm-summarization/alternative-providers-2026.md +1428 -0
  79. package/research/llm-summarization/anthropic-2026.md +367 -0
  80. package/research/llm-summarization/claude-cli-integration.md +1706 -0
  81. package/research/llm-summarization/cli-integration-patterns.md +3155 -0
  82. package/research/llm-summarization/openai-2026.md +473 -0
  83. package/research/llm-summarization/openai-compatible-providers-2026.md +1022 -0
  84. package/research/llm-summarization/opencode-cli-integration.md +1552 -0
  85. package/research/llm-summarization/prompt-engineering-2026.md +1426 -0
  86. package/research/llm-summarization/prototype-results.md +56 -0
  87. package/research/llm-summarization/provider-switching-patterns-2026.md +2153 -0
  88. package/research/llm-summarization/typescript-llm-libraries-2026.md +2436 -0
  89. package/research/mdcontext-pudding/00-EXECUTIVE-SUMMARY.md +282 -0
  90. package/research/mdcontext-pudding/01-index-embed.md +956 -0
  91. package/research/mdcontext-pudding/02-search-COMMANDS.md +142 -0
  92. package/research/mdcontext-pudding/02-search-SUMMARY.md +146 -0
  93. package/research/mdcontext-pudding/02-search.md +970 -0
  94. package/research/mdcontext-pudding/03-context.md +779 -0
  95. package/research/mdcontext-pudding/04-navigation-and-analytics.md +803 -0
  96. package/research/mdcontext-pudding/04-tree.md +704 -0
  97. package/research/mdcontext-pudding/05-config.md +1038 -0
  98. package/research/mdcontext-pudding/06-links-summary.txt +87 -0
  99. package/research/mdcontext-pudding/06-links.md +679 -0
  100. package/research/mdcontext-pudding/07-stats.md +693 -0
  101. package/research/mdcontext-pudding/BUG-FIX-PLAN.md +388 -0
  102. package/research/mdcontext-pudding/P0-BUG-VALIDATION.md +167 -0
  103. package/research/mdcontext-pudding/README.md +168 -0
  104. package/research/mdcontext-pudding/TESTING-SUMMARY.md +128 -0
  105. package/research/research-quality-review.md +834 -0
  106. package/research/semantic-search/embedding-text-analysis.md +156 -0
  107. package/research/semantic-search/multi-word-failure-reproduction.md +171 -0
  108. package/research/semantic-search/query-processing-analysis.md +207 -0
  109. package/research/semantic-search/root-cause-and-solution.md +114 -0
  110. package/research/semantic-search/threshold-validation-report.md +69 -0
  111. package/research/semantic-search/vector-search-analysis.md +63 -0
  112. package/research/test-path-issues.md +276 -0
  113. package/review/ALP-76/1-error-type-design.md +962 -0
  114. package/review/ALP-76/2-error-handling-patterns.md +906 -0
  115. package/review/ALP-76/3-error-presentation.md +624 -0
  116. package/review/ALP-76/4-test-coverage.md +625 -0
  117. package/review/ALP-76/5-migration-completeness.md +440 -0
  118. package/review/ALP-76/6-effect-best-practices.md +755 -0
  119. package/scripts/apply-branch-protection.sh +47 -0
  120. package/scripts/branch-protection-templates.json +79 -0
  121. package/scripts/prototype-summarization.ts +346 -0
  122. package/scripts/rebuild-hnswlib.js +32 -37
  123. package/scripts/setup-branch-protection.sh +64 -0
  124. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/active-provider.json +7 -0
  125. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.json +541 -0
  126. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/bm25.meta.json +5 -0
  127. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/config.json +8 -0
  128. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
  129. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
  130. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/documents.json +60 -0
  131. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/links.json +13 -0
  132. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/.mdcontext/indexes/sections.json +1197 -0
  133. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/configuration-management.md +99 -0
  134. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/distributed-systems.md +92 -0
  135. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/error-handling.md +78 -0
  136. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/failure-automation.md +55 -0
  137. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/job-context.md +69 -0
  138. package/src/__tests__/fixtures/semantic-search/multi-word-corpus/process-orchestration.md +99 -0
  139. package/src/cli/argv-preprocessor.test.ts +2 -2
  140. package/src/cli/cli.test.ts +230 -33
  141. package/src/cli/commands/config-cmd.ts +642 -0
  142. package/src/cli/commands/context.ts +97 -9
  143. package/src/cli/commands/duplicates.ts +122 -0
  144. package/src/cli/commands/embeddings.ts +529 -0
  145. package/src/cli/commands/index-cmd.ts +210 -30
  146. package/src/cli/commands/index.ts +3 -0
  147. package/src/cli/commands/search.ts +894 -64
  148. package/src/cli/commands/stats.ts +3 -0
  149. package/src/cli/commands/tree.ts +26 -5
  150. package/src/cli/config-layer.ts +176 -0
  151. package/src/cli/error-handler.test.ts +235 -0
  152. package/src/cli/error-handler.ts +655 -0
  153. package/src/cli/flag-schemas.ts +66 -0
  154. package/src/cli/help.ts +209 -7
  155. package/src/cli/main.ts +348 -58
  156. package/src/cli/options.ts +10 -0
  157. package/src/cli/shared-error-handling.ts +199 -0
  158. package/src/cli/utils.ts +150 -17
  159. package/src/config/file-provider.test.ts +320 -0
  160. package/src/config/file-provider.ts +273 -0
  161. package/src/config/index.ts +72 -0
  162. package/src/config/integration.test.ts +667 -0
  163. package/src/config/precedence.test.ts +277 -0
  164. package/src/config/precedence.ts +451 -0
  165. package/src/config/schema.test.ts +414 -0
  166. package/src/config/schema.ts +603 -0
  167. package/src/config/service.test.ts +320 -0
  168. package/src/config/service.ts +243 -0
  169. package/src/config/testing.test.ts +264 -0
  170. package/src/config/testing.ts +110 -0
  171. package/src/core/types.ts +6 -33
  172. package/src/duplicates/detector.test.ts +183 -0
  173. package/src/duplicates/detector.ts +414 -0
  174. package/src/duplicates/index.ts +18 -0
  175. package/src/embeddings/embedding-namespace.test.ts +300 -0
  176. package/src/embeddings/embedding-namespace.ts +947 -0
  177. package/src/embeddings/heading-boost.test.ts +222 -0
  178. package/src/embeddings/hnsw-build-options.test.ts +198 -0
  179. package/src/embeddings/hyde.test.ts +272 -0
  180. package/src/embeddings/hyde.ts +264 -0
  181. package/src/embeddings/index.ts +2 -0
  182. package/src/embeddings/openai-provider.ts +332 -83
  183. package/src/embeddings/pricing.json +22 -0
  184. package/src/embeddings/provider-constants.ts +204 -0
  185. package/src/embeddings/provider-errors.test.ts +967 -0
  186. package/src/embeddings/provider-errors.ts +565 -0
  187. package/src/embeddings/provider-factory.test.ts +240 -0
  188. package/src/embeddings/provider-factory.ts +225 -0
  189. package/src/embeddings/provider-integration.test.ts +788 -0
  190. package/src/embeddings/query-preprocessing.test.ts +187 -0
  191. package/src/embeddings/semantic-search-threshold.test.ts +508 -0
  192. package/src/embeddings/semantic-search.ts +780 -93
  193. package/src/embeddings/types.ts +293 -16
  194. package/src/embeddings/vector-store.ts +486 -77
  195. package/src/embeddings/voyage-provider.ts +313 -0
  196. package/src/errors/errors.test.ts +845 -0
  197. package/src/errors/index.ts +533 -0
  198. package/src/index/ignore-patterns.test.ts +354 -0
  199. package/src/index/ignore-patterns.ts +305 -0
  200. package/src/index/indexer.ts +286 -48
  201. package/src/index/storage.ts +94 -30
  202. package/src/index/types.ts +40 -2
  203. package/src/index/watcher.ts +67 -9
  204. package/src/index.ts +22 -0
  205. package/src/integration/search-keyword.test.ts +678 -0
  206. package/src/mcp/server.ts +135 -6
  207. package/src/parser/parser.ts +18 -19
  208. package/src/parser/section-filter.test.ts +277 -0
  209. package/src/parser/section-filter.ts +125 -3
  210. package/src/search/__tests__/hybrid-search.test.ts +650 -0
  211. package/src/search/bm25-store.ts +366 -0
  212. package/src/search/cross-encoder.test.ts +253 -0
  213. package/src/search/cross-encoder.ts +406 -0
  214. package/src/search/fuzzy-search.test.ts +419 -0
  215. package/src/search/fuzzy-search.ts +273 -0
  216. package/src/search/hybrid-search.ts +448 -0
  217. package/src/search/path-matcher.test.ts +276 -0
  218. package/src/search/path-matcher.ts +33 -0
  219. package/src/search/searcher.test.ts +99 -1
  220. package/src/search/searcher.ts +189 -67
  221. package/src/search/wink-bm25.d.ts +30 -0
  222. package/src/summarization/cli-providers/claude.ts +202 -0
  223. package/src/summarization/cli-providers/detection.test.ts +273 -0
  224. package/src/summarization/cli-providers/detection.ts +118 -0
  225. package/src/summarization/cli-providers/index.ts +8 -0
  226. package/src/summarization/cost.test.ts +139 -0
  227. package/src/summarization/cost.ts +102 -0
  228. package/src/summarization/error-handler.test.ts +127 -0
  229. package/src/summarization/error-handler.ts +111 -0
  230. package/src/summarization/index.ts +102 -0
  231. package/src/summarization/pipeline.test.ts +498 -0
  232. package/src/summarization/pipeline.ts +231 -0
  233. package/src/summarization/prompts.test.ts +269 -0
  234. package/src/summarization/prompts.ts +133 -0
  235. package/src/summarization/provider-factory.test.ts +396 -0
  236. package/src/summarization/provider-factory.ts +178 -0
  237. package/src/summarization/types.ts +184 -0
  238. package/src/summarize/summarizer.ts +104 -35
  239. package/src/types/huggingface-transformers.d.ts +66 -0
  240. package/tests/fixtures/cli/.mdcontext/active-provider.json +7 -0
  241. package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.bin +0 -0
  242. package/tests/fixtures/cli/.mdcontext/embeddings/openai_text-embedding-3-small_512/vectors.meta.bin +0 -0
  243. package/tests/fixtures/cli/.mdcontext/indexes/documents.json +4 -4
  244. package/tests/fixtures/cli/.mdcontext/indexes/sections.json +14 -0
  245. package/tests/integration/embed-index.test.ts +712 -0
  246. package/tests/integration/search-context.test.ts +469 -0
  247. package/tests/integration/search-semantic.test.ts +522 -0
  248. package/vitest.config.ts +1 -6
  249. package/AGENTS.md +0 -46
  250. package/tests/fixtures/cli/.mdcontext/vectors.bin +0 -0
  251. package/tests/fixtures/cli/.mdcontext/vectors.meta.json +0 -1264
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Tests for Error Handler Module
3
+ */
4
+
5
+ import { describe, expect, it } from 'vitest'
6
+ import {
7
+ formatSummarizationError,
8
+ isRecoverableError,
9
+ } from './error-handler.js'
10
+ import { SummarizationError } from './types.js'
11
+
12
+ describe('formatSummarizationError', () => {
13
+ describe('SummarizationError handling', () => {
14
+ it('should format PROVIDER_NOT_AVAILABLE with install URL', () => {
15
+ const error = new SummarizationError(
16
+ 'Claude not installed',
17
+ 'PROVIDER_NOT_AVAILABLE',
18
+ 'claude',
19
+ )
20
+ const message = formatSummarizationError(error)
21
+
22
+ expect(message).toContain('not available')
23
+ expect(message).toContain('https://claude.ai/download')
24
+ })
25
+
26
+ it('should format NO_API_KEY with env var hint', () => {
27
+ const error = new SummarizationError(
28
+ 'API key missing',
29
+ 'NO_API_KEY',
30
+ 'deepseek',
31
+ )
32
+ const message = formatSummarizationError(error)
33
+
34
+ expect(message).toContain('API key')
35
+ expect(message).toContain('DEEPSEEK_API_KEY')
36
+ })
37
+
38
+ it('should format RATE_LIMITED with CLI suggestion', () => {
39
+ const error = new SummarizationError(
40
+ 'Rate limit hit',
41
+ 'RATE_LIMITED',
42
+ 'openai',
43
+ )
44
+ const message = formatSummarizationError(error)
45
+
46
+ expect(message).toContain('Rate limit')
47
+ expect(message).toContain('CLI provider')
48
+ })
49
+
50
+ it('should format CLI_EXECUTION_FAILED with details', () => {
51
+ const error = new SummarizationError(
52
+ 'Process exited with code 1',
53
+ 'CLI_EXECUTION_FAILED',
54
+ 'claude',
55
+ )
56
+ const message = formatSummarizationError(error)
57
+
58
+ expect(message).toContain('CLI error')
59
+ expect(message).toContain('Process exited with code 1')
60
+ })
61
+
62
+ it('should handle TIMEOUT errors', () => {
63
+ const error = new SummarizationError(
64
+ 'Something went wrong',
65
+ 'TIMEOUT',
66
+ 'claude',
67
+ )
68
+ const message = formatSummarizationError(error)
69
+
70
+ expect(message).toContain('timed out')
71
+ })
72
+ })
73
+
74
+ describe('generic Error handling', () => {
75
+ it('should extract message from regular Error', () => {
76
+ const error = new Error('Network failed')
77
+ const message = formatSummarizationError(error)
78
+
79
+ expect(message).toBe('Network failed')
80
+ })
81
+ })
82
+
83
+ describe('unknown error handling', () => {
84
+ it('should handle null/undefined', () => {
85
+ expect(formatSummarizationError(null)).toBe(
86
+ 'An unknown error occurred during summarization.',
87
+ )
88
+ expect(formatSummarizationError(undefined)).toBe(
89
+ 'An unknown error occurred during summarization.',
90
+ )
91
+ })
92
+ })
93
+ })
94
+
95
+ describe('isRecoverableError', () => {
96
+ it('should return true for API_REQUEST_FAILED', () => {
97
+ const error = new SummarizationError(
98
+ 'Request failed',
99
+ 'API_REQUEST_FAILED',
100
+ 'deepseek',
101
+ )
102
+ expect(isRecoverableError(error)).toBe(true)
103
+ })
104
+
105
+ it('should return true for TIMEOUT', () => {
106
+ const error = new SummarizationError('Timed out', 'TIMEOUT', 'claude')
107
+ expect(isRecoverableError(error)).toBe(true)
108
+ })
109
+
110
+ it('should return false for RATE_LIMITED', () => {
111
+ const error = new SummarizationError(
112
+ 'Rate limited',
113
+ 'RATE_LIMITED',
114
+ 'openai',
115
+ )
116
+ expect(isRecoverableError(error)).toBe(false)
117
+ })
118
+
119
+ it('should return false for NO_API_KEY', () => {
120
+ const error = new SummarizationError('No key', 'NO_API_KEY', 'anthropic')
121
+ expect(isRecoverableError(error)).toBe(false)
122
+ })
123
+
124
+ it('should return false for non-SummarizationError', () => {
125
+ expect(isRecoverableError(new Error('Generic'))).toBe(false)
126
+ })
127
+ })
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Error Handler for Summarization
3
+ *
4
+ * Provides user-friendly error messages and graceful degradation.
5
+ * Ensures summarization failures don't crash the CLI.
6
+ */
7
+
8
+ import { SummarizationError, type SummarizationErrorCode } from './types.js'
9
+
10
+ /**
11
+ * Error message templates for different error codes.
12
+ */
13
+ const ERROR_MESSAGES: Record<SummarizationErrorCode, string> = {
14
+ PROVIDER_NOT_FOUND: 'Summarization provider not found.',
15
+ PROVIDER_NOT_AVAILABLE:
16
+ 'Summarization provider is not available. Check installation.',
17
+ CLI_EXECUTION_FAILED: 'CLI execution failed.',
18
+ API_REQUEST_FAILED: 'API request failed.',
19
+ RATE_LIMITED: 'Rate limit exceeded. Please try again later.',
20
+ INVALID_RESPONSE: 'Received invalid response from provider.',
21
+ TIMEOUT: 'Request timed out. Try again or reduce result count.',
22
+ NO_API_KEY: 'API key not configured.',
23
+ }
24
+
25
+ /**
26
+ * Installation URLs for CLI providers.
27
+ */
28
+ const CLI_INSTALL_URLS: Record<string, string> = {
29
+ claude: 'https://claude.ai/download',
30
+ copilot: 'https://github.com/features/copilot',
31
+ opencode: 'https://github.com/opencode-ai/opencode',
32
+ aider: 'https://aider.chat',
33
+ cline: 'https://github.com/cline/cline',
34
+ }
35
+
36
+ /**
37
+ * Environment variable names for API keys.
38
+ */
39
+ const API_KEY_ENV_VARS: Record<string, string> = {
40
+ deepseek: 'DEEPSEEK_API_KEY',
41
+ anthropic: 'ANTHROPIC_API_KEY',
42
+ openai: 'OPENAI_API_KEY',
43
+ gemini: 'GOOGLE_API_KEY',
44
+ qwen: 'QWEN_API_KEY',
45
+ }
46
+
47
+ /**
48
+ * Format a SummarizationError into a user-friendly message.
49
+ */
50
+ export const formatSummarizationError = (error: unknown): string => {
51
+ if (error instanceof SummarizationError) {
52
+ const baseMessage = ERROR_MESSAGES[error.code] ?? error.message
53
+
54
+ // Add provider-specific hints
55
+ if (error.code === 'PROVIDER_NOT_AVAILABLE' && error.provider) {
56
+ const installUrl = CLI_INSTALL_URLS[error.provider]
57
+ if (installUrl) {
58
+ return `${baseMessage}\n Install ${error.provider}: ${installUrl}`
59
+ }
60
+ }
61
+
62
+ if (error.code === 'NO_API_KEY' && error.provider) {
63
+ const envVar = API_KEY_ENV_VARS[error.provider]
64
+ if (envVar) {
65
+ return `${baseMessage}\n Set environment variable: ${envVar}`
66
+ }
67
+ }
68
+
69
+ if (error.code === 'RATE_LIMITED') {
70
+ return `${baseMessage}\n Try using a CLI provider (free with subscription) instead.`
71
+ }
72
+
73
+ if (error.code === 'CLI_EXECUTION_FAILED' && error.message) {
74
+ // Include the actual error message for CLI failures
75
+ return `CLI error: ${error.message}`
76
+ }
77
+
78
+ return baseMessage
79
+ }
80
+
81
+ if (error instanceof Error) {
82
+ return error.message
83
+ }
84
+
85
+ return 'An unknown error occurred during summarization.'
86
+ }
87
+
88
+ /**
89
+ * Check if an error is recoverable (can retry).
90
+ */
91
+ export const isRecoverableError = (error: unknown): boolean => {
92
+ if (error instanceof SummarizationError) {
93
+ // These errors might succeed on retry
94
+ return ['API_REQUEST_FAILED', 'TIMEOUT'].includes(error.code)
95
+ }
96
+ return false
97
+ }
98
+
99
+ /**
100
+ * Create a console-friendly error display.
101
+ */
102
+ export const displaySummarizationError = (error: unknown): void => {
103
+ const message = formatSummarizationError(error)
104
+
105
+ console.error('')
106
+ console.error('Summarization failed:')
107
+ console.error(` ${message}`)
108
+ console.error('')
109
+ console.error(' Showing search results without summary.')
110
+ console.error('')
111
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Summarization Module
3
+ *
4
+ * AI-powered summarization of search results using CLI tools (free)
5
+ * or API providers (pay-per-use via Vercel AI SDK).
6
+ *
7
+ * ## Quick Start
8
+ *
9
+ * ```typescript
10
+ * import { createSummarizer, buildPrompt } from './summarization/index.js'
11
+ *
12
+ * // Create a summarizer from config
13
+ * const summarizer = await createSummarizer({
14
+ * mode: 'cli',
15
+ * provider: 'claude',
16
+ * })
17
+ *
18
+ * // Build prompt with context
19
+ * const prompt = buildPrompt({
20
+ * query: 'authentication',
21
+ * resultCount: 10,
22
+ * searchMode: 'hybrid',
23
+ * })
24
+ *
25
+ * // Generate summary
26
+ * const result = await summarizer.summarize(searchResultsText, prompt)
27
+ * console.log(result.summary)
28
+ * ```
29
+ *
30
+ * ## Architecture
31
+ *
32
+ * - **CLI Providers**: Free with subscription (Claude Code, Copilot, etc.)
33
+ * - **API Providers**: Pay-per-use via Vercel AI SDK (DeepSeek, OpenAI, etc.)
34
+ * - **Detection**: Auto-detect installed CLI tools
35
+ * - **Factory**: Create providers from config
36
+ */
37
+
38
+ // CLI providers
39
+ export {
40
+ ClaudeCLISummarizer,
41
+ detectInstalledCLIs,
42
+ getCLIInfo,
43
+ isCLIInstalled,
44
+ KNOWN_CLIS,
45
+ } from './cli-providers/index.js'
46
+ // Cost estimation
47
+ export type { CostEstimate } from './cost.js'
48
+ export {
49
+ API_PRICING,
50
+ estimateSummaryCost,
51
+ estimateTokens,
52
+ formatCostDisplay,
53
+ } from './cost.js'
54
+ // Error handling
55
+ export {
56
+ displaySummarizationError,
57
+ formatSummarizationError,
58
+ isRecoverableError,
59
+ } from './error-handler.js'
60
+ // Pipeline
61
+ export type {
62
+ PipelineOptions,
63
+ PipelineResult,
64
+ SummarizableResult,
65
+ } from './pipeline.js'
66
+ export {
67
+ formatResultsForSummary,
68
+ runSummarizationPipeline,
69
+ summarizeResults,
70
+ } from './pipeline.js'
71
+ // Prompts
72
+ export type { PromptTemplate, SearchContext } from './prompts.js'
73
+ export {
74
+ ACTIONABLE_PROMPT,
75
+ buildPrompt,
76
+ CONCISE_PROMPT,
77
+ DEFAULT_PROMPT,
78
+ DETAILED_PROMPT,
79
+ getPromptTemplate,
80
+ TECHNICAL_PROMPT,
81
+ } from './prompts.js'
82
+ // Provider factory
83
+ export {
84
+ createSummarizer,
85
+ getBestAvailableSummarizer,
86
+ } from './provider-factory.js'
87
+ // Core types
88
+ export type {
89
+ AISummarizationConfig,
90
+ APIProviderName,
91
+ APIProviderPricing,
92
+ CLIInfo,
93
+ CLIProviderName,
94
+ StreamingSummarizer,
95
+ StreamOptions,
96
+ SummarizationErrorCode,
97
+ SummarizationMode,
98
+ Summarizer,
99
+ SummarizerFactory,
100
+ SummaryResult,
101
+ } from './types.js'
102
+ export { SummarizationError } from './types.js'