sumulige-claude 1.5.1 → 1.5.2

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 (219) hide show
  1. package/.claude/hooks/hook-registry.json +0 -15
  2. package/.claude/rules/coding-style.md +18 -7
  3. package/.claude/rules/hooks.md +15 -4
  4. package/.claude/rules/performance.md +15 -5
  5. package/.claude/rules/security.md +140 -4
  6. package/.claude/rules/testing.md +138 -9
  7. package/.claude/rules/web-design-standard.md +16 -5
  8. package/.claude/skills/algorithmic-art/metadata.yaml +28 -0
  9. package/.claude/skills/api-tester/SKILL.md +61 -0
  10. package/.claude/skills/api-tester/examples/basic.md +3 -0
  11. package/.claude/skills/api-tester/metadata.yaml +30 -0
  12. package/.claude/skills/api-tester/templates/default.md +3 -0
  13. package/.claude/skills/brand-guidelines/metadata.yaml +26 -0
  14. package/.claude/skills/canvas-design/metadata.yaml +27 -0
  15. package/.claude/skills/code-reviewer-123/SKILL.md +61 -0
  16. package/.claude/skills/code-reviewer-123/examples/basic.md +3 -0
  17. package/.claude/skills/code-reviewer-123/metadata.yaml +30 -0
  18. package/.claude/skills/code-reviewer-123/templates/default.md +3 -0
  19. package/.claude/skills/doc-coauthoring/metadata.yaml +27 -0
  20. package/.claude/skills/docx/metadata.yaml +30 -0
  21. package/.claude/skills/frontend-design/metadata.yaml +28 -0
  22. package/.claude/skills/internal-comms/metadata.yaml +28 -0
  23. package/.claude/skills/mcp-builder/metadata.yaml +26 -0
  24. package/.claude/skills/my-skill/SKILL.md +61 -0
  25. package/.claude/skills/my-skill/examples/basic.md +3 -0
  26. package/.claude/skills/my-skill/metadata.yaml +30 -0
  27. package/.claude/skills/my-skill/templates/default.md +3 -0
  28. package/.claude/skills/pdf/metadata.yaml +29 -0
  29. package/.claude/skills/pptx/metadata.yaml +29 -0
  30. package/.claude/skills/react-best-practices/metadata.yaml +26 -0
  31. package/.claude/skills/react-node-practices/SKILL.md +409 -0
  32. package/.claude/skills/react-node-practices/metadata.yaml +56 -0
  33. package/.claude/skills/skill-creator/metadata.yaml +25 -0
  34. package/.claude/skills/slack-gif-creator/metadata.yaml +28 -0
  35. package/.claude/skills/test-skill-name/SKILL.md +61 -0
  36. package/.claude/skills/test-skill-name/examples/basic.md +3 -0
  37. package/.claude/skills/test-skill-name/metadata.yaml +30 -0
  38. package/.claude/skills/test-skill-name/templates/default.md +3 -0
  39. package/.claude/skills/test-workflow/metadata.yaml +32 -0
  40. package/.claude/skills/theme-factory/metadata.yaml +26 -0
  41. package/.claude/skills/threejs-fundamentals/metadata.yaml +27 -0
  42. package/.claude/skills/web-artifacts-builder/metadata.yaml +30 -0
  43. package/.claude/skills/web-design-guidelines/metadata.yaml +26 -0
  44. package/.claude/skills/webapp-testing/metadata.yaml +26 -0
  45. package/.claude/skills/xlsx/metadata.yaml +29 -0
  46. package/LICENSE +21 -0
  47. package/cli.js +1 -1
  48. package/package.json +25 -3
  49. package/.claude/.kickoff-hint.txt +0 -52
  50. package/.claude/.sumulige-claude-version +0 -1
  51. package/.claude/.version +0 -1
  52. package/.claude/AGENTS.md +0 -42
  53. package/.claude/ANCHORS.md +0 -40
  54. package/.claude/CLAUDE.md +0 -138
  55. package/.claude/MEMORY.md +0 -69
  56. package/.claude/PROJECT_LOG.md +0 -101
  57. package/.claude/THINKING_CHAIN_GUIDE.md +0 -287
  58. package/.claude/USAGE.md +0 -175
  59. package/.claude/boris-optimizations.md +0 -167
  60. package/.claude/handoffs/INDEX.md +0 -21
  61. package/.claude/handoffs/LATEST.md +0 -76
  62. package/.claude/handoffs/handoff_2026-01-22T13-07-04-757Z.md +0 -76
  63. package/.claude/quality-gate.json +0 -82
  64. package/.claude/rag/skill-index.json +0 -135
  65. package/.claude/settings.json +0 -99
  66. package/.claude/settings.local.json +0 -175
  67. package/.claude/templates/PROJECT_KICKOFF.md +0 -89
  68. package/.claude/templates/PROJECT_PROPOSAL.md +0 -227
  69. package/.claude/templates/TASK_PLAN.md +0 -121
  70. package/.claude/templates/hooks/README.md +0 -302
  71. package/.claude/templates/hooks/hook.sh.template +0 -94
  72. package/.claude/templates/hooks/user-prompt-submit.cjs.template +0 -116
  73. package/.claude/templates/hooks/user-response-submit.cjs.template +0 -94
  74. package/.claude/templates/hooks/validate.js +0 -173
  75. package/.claude/templates/tasks/develop.md +0 -69
  76. package/.claude/templates/tasks/research.md +0 -64
  77. package/.claude/templates/tasks/test.md +0 -96
  78. package/.claude/thinking-routes/.last-sync +0 -1
  79. package/.claude/thinking-routes/QUICKREF.md +0 -98
  80. package/.claude/workflow/document-scanner.js +0 -426
  81. package/.claude/workflow/knowledge-engine.js +0 -941
  82. package/.claude/workflow/notebooklm/browser.js +0 -1028
  83. package/.claude/workflow/phases/phase1-research.js +0 -578
  84. package/.claude/workflow/phases/phase1-research.ts +0 -465
  85. package/.claude/workflow/phases/phase2-approve.js +0 -722
  86. package/.claude/workflow/phases/phase3-plan.js +0 -1200
  87. package/.claude/workflow/phases/phase4-develop.js +0 -894
  88. package/.claude/workflow/search-cache.js +0 -230
  89. package/.claude/workflow/templates/approval.md +0 -315
  90. package/.claude/workflow/templates/development.md +0 -377
  91. package/.claude/workflow/templates/planning.md +0 -328
  92. package/.claude/workflow/templates/research.md +0 -250
  93. package/.claude/workflow/types.js +0 -37
  94. package/.claude/workflow/web-search.js +0 -278
  95. package/.claude-plugin/marketplace.json +0 -71
  96. package/.github/workflows/sync-skills.yml +0 -74
  97. package/.versionrc +0 -25
  98. package/AGENTS.md +0 -580
  99. package/CHANGELOG.md +0 -481
  100. package/CLAUDE-template.md +0 -114
  101. package/DEV_TOOLS_GUIDE.md +0 -190
  102. package/PROJECT_STRUCTURE.md +0 -266
  103. package/Q&A.md +0 -325
  104. package/config/defaults.json +0 -34
  105. package/config/official-skills.json +0 -183
  106. package/config/quality-gate.json +0 -67
  107. package/config/skill-categories.json +0 -40
  108. package/config/version-manifest.json +0 -85
  109. package/demos/power-3d-scatter.html +0 -683
  110. package/development/cache/web-search/search_1193d605f8eb364651fc2f2041b58a31.json +0 -36
  111. package/development/cache/web-search/search_3798bf06960edc125f744a1abb5b72c5.json +0 -36
  112. package/development/cache/web-search/search_37c7d4843a53f0d83f1122a6f908a2a3.json +0 -36
  113. package/development/cache/web-search/search_44166fa0153709ee168485a22aa0ab40.json +0 -36
  114. package/development/cache/web-search/search_4deaebb1f77e86a8ca066dc5a49c59fd.json +0 -36
  115. package/development/cache/web-search/search_94da91789466070a7f545612e73c7372.json +0 -36
  116. package/development/cache/web-search/search_dd5de8491b8b803a3cb01339cd210fb0.json +0 -36
  117. package/development/knowledge-base/.index.clean.json +0 -1
  118. package/development/knowledge-base/.index.json +0 -486
  119. package/development/knowledge-base/test-best-practices.md +0 -29
  120. package/development/projects/proj_mkh1pazz_ixmt1/phase1/feasibility-report.md +0 -160
  121. package/development/projects/proj_mkh4jvnb_z7rwf/phase1/feasibility-report.md +0 -160
  122. package/development/projects/proj_mkh4jxkd_ewz5a/phase1/feasibility-report.md +0 -160
  123. package/development/projects/proj_mkh4k84n_ni73k/phase1/feasibility-report.md +0 -160
  124. package/development/projects/proj_mkh4wfyd_u9w88/phase1/feasibility-report.md +0 -160
  125. package/development/projects/proj_mkh4wsbo_iahvf/development/projects/proj_mkh4xbpg_4na5w/phase1/feasibility-report.md +0 -160
  126. package/development/projects/proj_mkh4wsbo_iahvf/phase1/feasibility-report.md +0 -160
  127. package/development/projects/proj_mkh4xulg_1ka8x/phase1/feasibility-report.md +0 -160
  128. package/development/projects/proj_mkh4xwhj_gch8j/phase1/feasibility-report.md +0 -160
  129. package/development/projects/proj_mkh4y2qk_9lm8z/phase1/feasibility-report.md +0 -160
  130. package/development/projects/proj_mkh4y2qk_9lm8z/phase2/requirements.md +0 -226
  131. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/PRD.md +0 -345
  132. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/TASK_PLAN.md +0 -284
  133. package/development/projects/proj_mkh4y2qk_9lm8z/phase3/prototype/README.md +0 -14
  134. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/DEVELOPMENT_LOG.md +0 -35
  135. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/TASKS.md +0 -34
  136. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/.env.example +0 -5
  137. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/README.md +0 -60
  138. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/package.json +0 -25
  139. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/index.js +0 -70
  140. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/src/routes/index.js +0 -48
  141. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/health.test.js +0 -20
  142. package/development/projects/proj_mkh4y2qk_9lm8z/phase4/source/tests/jest.config.js +0 -21
  143. package/development/projects/proj_mkh7veqg_3lypc/phase1/feasibility-report.md +0 -160
  144. package/development/projects/proj_mkh7veqg_3lypc/phase2/requirements.md +0 -226
  145. package/development/projects/proj_mkh7veqg_3lypc/phase3/PRD.md +0 -345
  146. package/development/projects/proj_mkh7veqg_3lypc/phase3/TASK_PLAN.md +0 -284
  147. package/development/projects/proj_mkh7veqg_3lypc/phase3/prototype/README.md +0 -14
  148. package/development/projects/proj_mkh8k8fo_rmqn5/phase1/feasibility-report.md +0 -160
  149. package/development/projects/proj_mkh8xyhy_1vshq/phase1/feasibility-report.md +0 -178
  150. package/development/projects/proj_mkh8zddd_dhamf/phase1/feasibility-report.md +0 -377
  151. package/development/projects/proj_mkh8zddd_dhamf/phase2/requirements.md +0 -442
  152. package/development/projects/proj_mkh8zddd_dhamf/phase3/api-design.md +0 -800
  153. package/development/projects/proj_mkh8zddd_dhamf/phase3/architecture.md +0 -625
  154. package/development/projects/proj_mkh8zddd_dhamf/phase3/data-model.md +0 -830
  155. package/development/projects/proj_mkh8zddd_dhamf/phase3/risks.md +0 -957
  156. package/development/projects/proj_mkh8zddd_dhamf/phase3/wbs.md +0 -381
  157. package/development/todos/.state.json +0 -19
  158. package/development/todos/INDEX.md +0 -63
  159. package/development/todos/active/_README.md +0 -49
  160. package/development/todos/archived/_README.md +0 -11
  161. package/development/todos/backlog/_README.md +0 -11
  162. package/development/todos/backlog/mcp-integration.md +0 -35
  163. package/development/todos/completed/_README.md +0 -11
  164. package/development/todos/completed/boris-optimizations.md +0 -39
  165. package/development/todos/completed/develop/local-knowledge-index.md +0 -85
  166. package/development/todos/completed/develop/todo-system.md +0 -47
  167. package/development/todos/completed/develop/web-search-integration.md +0 -83
  168. package/development/todos/completed/test/phase1-e2e-test.md +0 -103
  169. package/docs/DEVELOPMENT.md +0 -461
  170. package/docs/MARKETPLACE.md +0 -352
  171. package/docs/RELEASE.md +0 -93
  172. package/jest.config.js +0 -63
  173. package/lib/commands.js +0 -3588
  174. package/lib/config-manager.js +0 -441
  175. package/lib/config-schema.js +0 -408
  176. package/lib/config-validator.js +0 -330
  177. package/lib/config.js +0 -122
  178. package/lib/errors.js +0 -305
  179. package/lib/incremental-sync.js +0 -274
  180. package/lib/marketplace.js +0 -487
  181. package/lib/migrations.js +0 -154
  182. package/lib/permission-audit.js +0 -255
  183. package/lib/quality-gate.js +0 -431
  184. package/lib/quality-rules.js +0 -373
  185. package/lib/utils.js +0 -150
  186. package/lib/version-check.js +0 -169
  187. package/lib/version-manifest.js +0 -171
  188. package/project-paradigm.md +0 -313
  189. package/prompts/how-to-find.md +0 -163
  190. package/prompts/linus-architect.md +0 -71
  191. package/prompts/software-architect.md +0 -173
  192. package/prompts/web-designer.md +0 -249
  193. package/scripts/fix-hooks.mjs +0 -97
  194. package/scripts/sync-external.mjs +0 -298
  195. package/scripts/sync-to-home.sh +0 -108
  196. package/scripts/update-registry.mjs +0 -325
  197. package/sources.yaml +0 -83
  198. package/tests/README.md +0 -263
  199. package/tests/commands.test.js +0 -1086
  200. package/tests/config-manager.test.js +0 -677
  201. package/tests/config-schema.test.js +0 -425
  202. package/tests/config-validator.test.js +0 -436
  203. package/tests/config.test.js +0 -100
  204. package/tests/errors.test.js +0 -477
  205. package/tests/manual/phase1-e2e.sh +0 -389
  206. package/tests/manual/phase2-test-cases.md +0 -311
  207. package/tests/manual/phase3-test-cases.md +0 -309
  208. package/tests/manual/phase4-test-cases.md +0 -414
  209. package/tests/manual/test-cases.md +0 -417
  210. package/tests/marketplace.test.js +0 -420
  211. package/tests/migrations.test.js +0 -187
  212. package/tests/quality-gate.test.js +0 -679
  213. package/tests/quality-rules.test.js +0 -619
  214. package/tests/sync-external.test.js +0 -214
  215. package/tests/update-registry.test.js +0 -251
  216. package/tests/utils.test.js +0 -171
  217. package/tests/version-check.test.js +0 -75
  218. package/tests/web-search.test.js +0 -392
  219. package/thinkinglens-silent.md +0 -138
@@ -1,98 +0,0 @@
1
- # 对话历史速查卡
2
-
3
- > 快速找到你的对话记录
4
-
5
- ---
6
-
7
- ## 🚀 最常用
8
-
9
- | 命令 | 效果 |
10
- |------|------|
11
- | `tl` | 查看今日对话摘要 |
12
- | `log` | 查看项目完整日志 |
13
- | `memory` | 查看最近变更 |
14
-
15
- ---
16
-
17
- ## 📂 数据位置
18
-
19
- ```
20
- .claude/
21
- ├── thinking-routes/
22
- │ └── .conversation-flow.json ← 对话流数据
23
- ├── MEMORY.md ← 增量记忆
24
- ├── PROJECT_LOG.md ← 完整日志
25
- └── ANCHORS.md ← 快速索引
26
- ```
27
-
28
- ---
29
-
30
- ## 🔍 查找方式
31
-
32
- ### 按时间查找
33
- ```bash
34
- # 最近对话摘要
35
- .claude/hooks/tl-summary.sh
36
-
37
- # 完整项目日志(按时间顺序)
38
- cat .claude/PROJECT_LOG.md | grep "2026-01-11"
39
- ```
40
-
41
- ### 按关键词查找
42
- ```bash
43
- # 搜索思维节点
44
- npx -p tsx tsx .claude/thinking-routes/index.ts search "数据分析"
45
-
46
- # 在日志中搜索
47
- cat .claude/PROJECT_LOG.md | grep -i "API"
48
- ```
49
-
50
- ### 按类型查找
51
- ```bash
52
- # 查看所有决策
53
- cat .claude/PROJECT_LOG.md | grep "决策"
54
-
55
- # 查看所有变更
56
- cat .claude/MEMORY.md | grep "新增"
57
- ```
58
-
59
- ---
60
-
61
- ## ⚡ 快捷别名
62
-
63
- 添加到 `~/.zshrc` 或 `~/.bashrc`:
64
-
65
- ```bash
66
- # 对话历史
67
- alias tl='.claude/hooks/tl-summary.sh'
68
- alias log='less .claude/PROJECT_LOG.md'
69
- alias memory='cat .claude/MEMORY.md'
70
-
71
- # 思维节点
72
- alias tl-recent='npx -p tsx tsx .claude/thinking-routes/index.ts recent'
73
- alias tl-graph='npx -p tsx tsx .claude/thinking-routes/index.ts log --graph'
74
- alias tl-search='npx -p tsx tsx .claude/thinking-routes/index.ts search'
75
- ```
76
-
77
- ---
78
-
79
- ## 📱 Claude Code 内置
80
-
81
- ```bash
82
- # 查看对话历史列表
83
- claude-code history
84
-
85
- # 恢复某个对话
86
- claude-code resume <conversation-id>
87
- ```
88
-
89
- ---
90
-
91
- ## 💡 使用建议
92
-
93
- | 场景 | 使用 |
94
- |------|------|
95
- | 每天回顾 | `tl` |
96
- | 找决策理由 | `tl-search "关键词"` |
97
- | 了解项目全貌 | `log` |
98
- | 查看最近变更 | `memory` |
@@ -1,426 +0,0 @@
1
- /**
2
- * Document Scanner - Extract content and metadata from local files
3
- *
4
- * Supports:
5
- * - Text extraction from multiple file formats
6
- * - Metadata extraction (word count, headings, links)
7
- * - Content checksum for change detection
8
- */
9
-
10
- const fs = require('fs');
11
- const path = require('path');
12
- const crypto = require('crypto');
13
-
14
- // ============================================================================
15
- // Configuration
16
- // ============================================================================
17
-
18
- const MAX_CONTENT_SIZE = 500 * 1024; // 500KB - don't store content if larger
19
- const MAX_SNIPPET_SIZE = 2000; // Store snippet for large files
20
-
21
- // Supported file types for content scanning
22
- const SCANNABLE_TYPES = [
23
- '.md', '.markdown', // Markdown
24
- '.txt', // Plain text
25
- '.json', '.yaml', '.yml', // Config files
26
- '.js', '.ts', '.jsx', '.tsx', // JavaScript/TypeScript
27
- '.py', '.rs', '.go', '.java', '.c', '.cpp', '.h', '.hpp', // Code
28
- '.sh', '.bash', '.zsh', '.fish', // Shell scripts
29
- '.css', '.scss', '.less', // Stylesheets
30
- '.html', '.htm', '.xml', // Markup
31
- '.sql', '.graphql', '.gql' // Query languages
32
- ];
33
-
34
- // ============================================================================
35
- // Document Scanner Class
36
- // ============================================================================
37
-
38
- class DocumentScanner {
39
- /**
40
- * Check if a file type is scannable
41
- */
42
- static isScannable(filePath) {
43
- const ext = path.extname(filePath).toLowerCase();
44
- return SCANNABLE_TYPES.includes(ext);
45
- }
46
-
47
- /**
48
- * Scan a file and extract metadata
49
- */
50
- static scanFile(filePath, options = {}) {
51
- const {
52
- includeContent = true,
53
- maxContentSize = MAX_CONTENT_SIZE
54
- } = options;
55
-
56
- if (!fs.existsSync(filePath)) {
57
- throw new Error(`File not found: ${filePath}`);
58
- }
59
-
60
- const stats = fs.statSync(filePath);
61
- const ext = path.extname(filePath).toLowerCase();
62
-
63
- // Basic metadata
64
- const metadata = {
65
- path: filePath,
66
- size: stats.size,
67
- lastModified: stats.mtimeMs,
68
- contentType: this.getMimeType(ext),
69
- extension: ext
70
- };
71
-
72
- // If file is too large or not scannable, skip content
73
- if (!this.isScannable(filePath) || stats.size === 0) {
74
- return {
75
- ...metadata,
76
- scannable: false,
77
- wordCount: 0,
78
- headings: [],
79
- links: [],
80
- };
81
- }
82
-
83
- // Read file content
84
- let content;
85
- try {
86
- content = fs.readFileSync(filePath, 'utf-8');
87
- } catch (error) {
88
- return {
89
- ...metadata,
90
- scannable: false,
91
- error: error.message
92
- };
93
- }
94
-
95
- // Calculate checksum
96
- const checksum = crypto
97
- .createHash('md5')
98
- .update(content)
99
- .digest('hex');
100
-
101
- // Extract metadata based on file type
102
- const extracted = this.extractMetadata(content, ext);
103
-
104
- // Determine whether to store full content or just snippet
105
- const shouldStoreContent = includeContent && content.length <= maxContentSize;
106
-
107
- return {
108
- ...metadata,
109
- scannable: true,
110
- checksum,
111
- wordCount: extracted.wordCount,
112
- lineCount: extracted.lineCount,
113
- headings: extracted.headings,
114
- links: extracted.links,
115
- codeBlocks: extracted.codeBlocks,
116
- frontMatter: extracted.frontMatter,
117
- // Content or snippet
118
- content: shouldStoreContent ? content : null,
119
- snippet: shouldStoreContent ? null : content.substring(0, MAX_SNIPPET_SIZE)
120
- };
121
- }
122
-
123
- /**
124
- * Extract metadata from content based on file type
125
- */
126
- static extractMetadata(content, ext) {
127
- const lines = content.split('\n');
128
- const wordCount = this.countWords(content);
129
- const lineCount = lines.length;
130
-
131
- let headings = [];
132
- let links = [];
133
- let codeBlocks = [];
134
- let frontMatter = null;
135
-
136
- // Markdown-specific extraction
137
- if (['.md', '.markdown'].includes(ext)) {
138
- const mdResult = this.extractMarkdownMetadata(content);
139
- headings = mdResult.headings;
140
- links = mdResult.links;
141
- codeBlocks = mdResult.codeBlocks;
142
- frontMatter = mdResult.frontMatter;
143
- }
144
- // Code-specific extraction
145
- else if (['.js', '.ts', '.jsx', '.tsx', '.py', '.rs', '.go'].includes(ext)) {
146
- const codeResult = this.extractCodeMetadata(content, ext);
147
- headings = codeResult.headings; // Functions/classes as headings
148
- links = codeResult.links; // Import/require statements
149
- }
150
-
151
- return {
152
- wordCount,
153
- lineCount,
154
- headings,
155
- links,
156
- codeBlocks,
157
- frontMatter
158
- };
159
- }
160
-
161
- /**
162
- * Extract Markdown-specific metadata
163
- */
164
- static extractMarkdownMetadata(content) {
165
- const headings = [];
166
- const links = [];
167
- const codeBlocks = [];
168
- let frontMatter = null;
169
-
170
- const lines = content.split('\n');
171
- let inCodeBlock = false;
172
- let codeBlockLang = null;
173
- let currentCodeBlock = [];
174
-
175
- // Check for YAML front matter
176
- if (lines[0] === '---') {
177
- const endIdx = lines.slice(1).findIndex(line => line === '---');
178
- if (endIdx > 0) {
179
- const frontMatterContent = lines.slice(1, endIdx + 1).join('\n');
180
- frontMatter = this.parseFrontMatter(frontMatterContent);
181
- }
182
- }
183
-
184
- for (let i = 0; i < lines.length; i++) {
185
- const line = lines[i];
186
-
187
- // Track code blocks
188
- if (line.startsWith('```')) {
189
- if (!inCodeBlock) {
190
- inCodeBlock = true;
191
- codeBlockLang = line.substring(3).trim() || 'text';
192
- currentCodeBlock = [];
193
- } else {
194
- codeBlocks.push({
195
- language: codeBlockLang,
196
- lineStart: i - currentCodeBlock.length,
197
- preview: currentCodeBlock.slice(0, 3).join('\n')
198
- });
199
- inCodeBlock = false;
200
- currentCodeBlock = [];
201
- }
202
- continue;
203
- }
204
-
205
- if (inCodeBlock) {
206
- currentCodeBlock.push(line);
207
- continue;
208
- }
209
-
210
- // Extract headings
211
- const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
212
- if (headingMatch) {
213
- const level = headingMatch[1].length;
214
- const text = headingMatch[2].trim();
215
- headings.push({ level, text, line: i + 1 });
216
- }
217
-
218
- // Extract links
219
- const linkMatch = line.match(/\[([^\]]+)\]\(([^)]+)\)/g);
220
- if (linkMatch) {
221
- linkMatch.forEach(link => {
222
- const match = link.match(/\[([^\]]+)\]\(([^)]+)\)/);
223
- if (match) {
224
- links.push({ text: match[1], url: match[2] });
225
- }
226
- });
227
- }
228
- }
229
-
230
- return { headings, links, codeBlocks, frontMatter };
231
- }
232
-
233
- /**
234
- * Extract code-specific metadata (functions, classes, imports)
235
- */
236
- static extractCodeMetadata(content, ext) {
237
- const headings = [];
238
- const links = [];
239
-
240
- const lines = content.split('\n');
241
-
242
- // Patterns for different languages
243
- const patterns = {
244
- '.js': { func: /^\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/, class: /^\s*class\s+(\w+)/, import: /^\s*import\s+.*from\s+['"]([^'"]+)['"]/ },
245
- '.ts': { func: /^\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/, class: /^\s*class\s+(\w+)/, import: /^\s*import\s+.*from\s+['"]([^'"]+)['"]/ },
246
- '.jsx': { func: /^\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/, class: /^\s*class\s+(\w+)/, import: /^\s*import\s+.*from\s+['"]([^'"]+)['"]/ },
247
- '.tsx': { func: /^\s*(?:export\s+)?(?:async\s+)?function\s+(\w+)/, class: /^\s*class\s+(\w+)/, import: /^\s*import\s+.*from\s+['"]([^'"]+)['"]/ },
248
- '.py': { func: /^\s*def\s+(\w+)\s*\(/, class: /^\s*class\s+(\w+)\s*:/, import: /^\s*(?:import|from)\s+(\w+)/ },
249
- '.rs': { func: /^\s*(?:pub\s+)?fn\s+(\w+)\s*\(/, class: /^\s*(?:pub\s+)?(struct|enum|trait)\s+(\w+)/, import: /^\s*use\s+([^;]+);/ },
250
- '.go': { func: /^\s*func\s+(?:\(\w+\s+\*?\w+\)\s+)?(\w+)\s*\(/, class: /^\s*type\s+(\w+)\s+struct/, import: /^\s*import\s+(?:\(|")([^")]+)/ }
251
- };
252
-
253
- const lang = patterns[ext] || patterns['.js'];
254
-
255
- for (let i = 0; i < lines.length; i++) {
256
- const line = lines[i];
257
-
258
- // Extract functions
259
- const funcMatch = line.match(lang.func);
260
- if (funcMatch) {
261
- headings.push({ type: 'function', name: funcMatch[1], line: i + 1 });
262
- }
263
-
264
- // Extract classes
265
- const classMatch = line.match(lang.class);
266
- if (classMatch) {
267
- const name = classMatch[2] || classMatch[1];
268
- headings.push({ type: 'class', name, line: i + 1 });
269
- }
270
-
271
- // Extract imports
272
- const importMatch = line.match(lang.import);
273
- if (importMatch) {
274
- links.push({ type: 'import', name: importMatch[1], line: i + 1 });
275
- }
276
- }
277
-
278
- return { headings, links };
279
- }
280
-
281
- /**
282
- * Parse YAML front matter
283
- */
284
- static parseFrontMatter(content) {
285
- const result = {};
286
- const lines = content.split('\n');
287
-
288
- for (const line of lines) {
289
- const match = line.match(/^(\w+):\s*(.+)$/);
290
- if (match) {
291
- result[match[1]] = match[2].trim();
292
- }
293
- }
294
-
295
- return result;
296
- }
297
-
298
- /**
299
- * Count words in content (rough estimate for mixed content)
300
- */
301
- static countWords(content) {
302
- // For code files, count tokens more accurately
303
- // For text files, count words
304
- const tokens = content
305
- .replace(/\s+/g, ' ')
306
- .replace(/[{}();,.<>[\]]/g, ' ')
307
- .split(' ')
308
- .filter(t => t.length > 0);
309
-
310
- return tokens.length;
311
- }
312
-
313
- /**
314
- * Get MIME type for extension
315
- */
316
- static getMimeType(ext) {
317
- const mimeTypes = {
318
- '.md': 'text/markdown',
319
- '.markdown': 'text/markdown',
320
- '.txt': 'text/plain',
321
- '.json': 'application/json',
322
- '.yaml': 'text/yaml',
323
- '.yml': 'text/yaml',
324
- '.js': 'text/javascript',
325
- '.ts': 'text/typescript',
326
- '.jsx': 'text/jsx',
327
- '.tsx': 'text/tsx',
328
- '.py': 'text/x-python',
329
- '.rs': 'text/x-rust',
330
- '.go': 'text/x-go',
331
- '.java': 'text/x-java',
332
- '.c': 'text/x-c',
333
- '.cpp': 'text/x-c++',
334
- '.h': 'text/x-c',
335
- '.hpp': 'text/x-c++',
336
- '.sh': 'text/x-shellscript',
337
- '.bash': 'text/x-shellscript',
338
- '.css': 'text/css',
339
- '.scss': 'text/x-scss',
340
- '.less': 'text/x-less',
341
- '.html': 'text/html',
342
- '.htm': 'text/html',
343
- '.xml': 'text/xml',
344
- '.sql': 'text/x-sql',
345
- '.graphql': 'text/x-graphql',
346
- '.gql': 'text/x-graphql'
347
- };
348
- return mimeTypes[ext.toLowerCase()] || 'text/plain';
349
- }
350
-
351
- /**
352
- * Scan a directory recursively
353
- */
354
- static scanDirectory(dirPath, options = {}) {
355
- const {
356
- recursive = true,
357
- maxDepth = 10,
358
- includePatterns = [],
359
- excludePatterns = ['node_modules', '.git', 'dist', 'build', 'coverage']
360
- } = options;
361
-
362
- if (!fs.existsSync(dirPath)) {
363
- throw new Error(`Directory not found: ${dirPath}`);
364
- }
365
-
366
- const results = [];
367
- const scanQueue = [{ dir: dirPath, depth: 0 }];
368
-
369
- while (scanQueue.length > 0) {
370
- const { dir, depth } = scanQueue.shift();
371
-
372
- if (depth > maxDepth) continue;
373
-
374
- let entries;
375
- try {
376
- entries = fs.readdirSync(dir, { withFileTypes: true });
377
- } catch (error) {
378
- continue; // Skip directories we can't read
379
- }
380
-
381
- for (const entry of entries) {
382
- // Skip excluded directories
383
- if (entry.isDirectory() && excludePatterns.includes(entry.name)) {
384
- continue;
385
- }
386
-
387
- const fullPath = path.join(dir, entry.name);
388
-
389
- if (entry.isDirectory() && recursive) {
390
- scanQueue.push({ dir: fullPath, depth: depth + 1 });
391
- } else if (entry.isFile()) {
392
- // Check include patterns
393
- if (includePatterns.length > 0) {
394
- const matches = includePatterns.some(pattern => {
395
- if (pattern instanceof RegExp) {
396
- return pattern.test(fullPath);
397
- }
398
- return fullPath.includes(pattern);
399
- });
400
- if (!matches) continue;
401
- }
402
-
403
- try {
404
- const scanResult = this.scanFile(fullPath, options);
405
- results.push(scanResult);
406
- } catch (error) {
407
- // Skip files that can't be scanned
408
- }
409
- }
410
- }
411
- }
412
-
413
- return results;
414
- }
415
- }
416
-
417
- // ============================================================================
418
- // Exports
419
- // ============================================================================
420
-
421
- module.exports = {
422
- DocumentScanner,
423
- SCANNABLE_TYPES,
424
- MAX_CONTENT_SIZE,
425
- MAX_SNIPPET_SIZE
426
- };