@gulibs/safe-coder 0.0.1

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 (79) hide show
  1. package/README.md +515 -0
  2. package/dist/documentation/cache.d.ts +13 -0
  3. package/dist/documentation/cache.d.ts.map +1 -0
  4. package/dist/documentation/cache.js +48 -0
  5. package/dist/documentation/cache.js.map +1 -0
  6. package/dist/documentation/github-client.d.ts +11 -0
  7. package/dist/documentation/github-client.d.ts.map +1 -0
  8. package/dist/documentation/github-client.js +88 -0
  9. package/dist/documentation/github-client.js.map +1 -0
  10. package/dist/documentation/http-fetcher.d.ts +5 -0
  11. package/dist/documentation/http-fetcher.d.ts.map +1 -0
  12. package/dist/documentation/http-fetcher.js +27 -0
  13. package/dist/documentation/http-fetcher.js.map +1 -0
  14. package/dist/documentation/index.d.ts +14 -0
  15. package/dist/documentation/index.d.ts.map +1 -0
  16. package/dist/documentation/index.js +75 -0
  17. package/dist/documentation/index.js.map +1 -0
  18. package/dist/documentation/normalizer.d.ts +6 -0
  19. package/dist/documentation/normalizer.d.ts.map +1 -0
  20. package/dist/documentation/normalizer.js +38 -0
  21. package/dist/documentation/normalizer.js.map +1 -0
  22. package/dist/documentation/npm-client.d.ts +7 -0
  23. package/dist/documentation/npm-client.d.ts.map +1 -0
  24. package/dist/documentation/npm-client.js +49 -0
  25. package/dist/documentation/npm-client.js.map +1 -0
  26. package/dist/errors/contextual-analysis.d.ts +11 -0
  27. package/dist/errors/contextual-analysis.d.ts.map +1 -0
  28. package/dist/errors/contextual-analysis.js +75 -0
  29. package/dist/errors/contextual-analysis.js.map +1 -0
  30. package/dist/errors/eslint-integration.d.ts +8 -0
  31. package/dist/errors/eslint-integration.d.ts.map +1 -0
  32. package/dist/errors/eslint-integration.js +43 -0
  33. package/dist/errors/eslint-integration.js.map +1 -0
  34. package/dist/errors/index.d.ts +11 -0
  35. package/dist/errors/index.d.ts.map +1 -0
  36. package/dist/errors/index.js +58 -0
  37. package/dist/errors/index.js.map +1 -0
  38. package/dist/errors/pattern-matcher.d.ts +25 -0
  39. package/dist/errors/pattern-matcher.d.ts.map +1 -0
  40. package/dist/errors/pattern-matcher.js +44 -0
  41. package/dist/errors/pattern-matcher.js.map +1 -0
  42. package/dist/errors/patterns.json +36 -0
  43. package/dist/errors/typescript-integration.d.ts +6 -0
  44. package/dist/errors/typescript-integration.d.ts.map +1 -0
  45. package/dist/errors/typescript-integration.js +46 -0
  46. package/dist/errors/typescript-integration.js.map +1 -0
  47. package/dist/index.d.ts +2 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +10 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/server/mcp-server.d.ts +11 -0
  52. package/dist/server/mcp-server.d.ts.map +1 -0
  53. package/dist/server/mcp-server.js +213 -0
  54. package/dist/server/mcp-server.js.map +1 -0
  55. package/dist/types/documentation.d.ts +26 -0
  56. package/dist/types/documentation.d.ts.map +1 -0
  57. package/dist/types/documentation.js +2 -0
  58. package/dist/types/documentation.js.map +1 -0
  59. package/dist/utils/config.d.ts +9 -0
  60. package/dist/utils/config.d.ts.map +1 -0
  61. package/dist/utils/config.js +10 -0
  62. package/dist/utils/config.js.map +1 -0
  63. package/dist/utils/rate-limiter.d.ts +9 -0
  64. package/dist/utils/rate-limiter.d.ts.map +1 -0
  65. package/dist/utils/rate-limiter.js +26 -0
  66. package/dist/utils/rate-limiter.js.map +1 -0
  67. package/dist/validation/auto-fix.d.ts +15 -0
  68. package/dist/validation/auto-fix.d.ts.map +1 -0
  69. package/dist/validation/auto-fix.js +49 -0
  70. package/dist/validation/auto-fix.js.map +1 -0
  71. package/dist/validation/index.d.ts +21 -0
  72. package/dist/validation/index.d.ts.map +1 -0
  73. package/dist/validation/index.js +45 -0
  74. package/dist/validation/index.js.map +1 -0
  75. package/dist/validation/resolution-db.d.ts +15 -0
  76. package/dist/validation/resolution-db.d.ts.map +1 -0
  77. package/dist/validation/resolution-db.js +62 -0
  78. package/dist/validation/resolution-db.js.map +1 -0
  79. package/package.json +55 -0
package/README.md ADDED
@@ -0,0 +1,515 @@
1
+ # Safe Coder MCP 服务
2
+
3
+ 一个基于 Model Context Protocol (MCP) 的服务器,提供以下功能:
4
+ - **最新库文档** - 从 npm、GitHub 和 HTTP 源获取文档
5
+ - **全面错误检测** - 使用 ESLint、TypeScript、模式匹配和上下文分析
6
+ - **代码验证** - 带自动修复功能
7
+ - **错误解决方案建议** - 针对常见编码问题
8
+
9
+ ## 功能特性
10
+
11
+ ### 文档获取
12
+
13
+ - 从 npm 注册表获取
14
+ - 从 GitHub 仓库获取
15
+ - 从直接 HTTP 文档站点获取
16
+ - 智能缓存,基于版本键和 TTL
17
+ - 热门包的背景刷新
18
+
19
+ ### 错误检测
20
+
21
+ - 多层检测:
22
+ 1. ESLint - 代码质量检查
23
+ 2. TypeScript 编译器 - 类型检查
24
+ 3. 模式匹配 - 常见错误模式
25
+ 4. 上下文分析 - 未定义变量和 API 使用错误
26
+ - 优先级错误报告(语法 → 类型 → 运行时 → 逻辑 → 警告)
27
+
28
+ ### 代码验证
29
+
30
+ - 完整的验证管道
31
+ - 自动修复常见错误(语法、缺失导入)
32
+ - 错误解决方案数据库
33
+ - 在代码展示前进行验证
34
+
35
+ ## 安装方式
36
+
37
+ ### 方式一:通过 npm 安装(推荐)
38
+
39
+ 如果已发布到 npm:
40
+
41
+ ```bash
42
+ # 全局安装
43
+ npm install -g @gulibs/safe-coder
44
+
45
+ # 或者本地安装到项目
46
+ npm install @gulibs/safe-coder
47
+ ```
48
+
49
+ ### 方式二:从源码安装
50
+
51
+ ```bash
52
+ # 克隆或下载项目
53
+ git clone <repository-url>
54
+ cd safe-coder
55
+
56
+ # 安装依赖
57
+ npm install
58
+
59
+ # 构建项目
60
+ npm run build
61
+ ```
62
+
63
+ ## 配置
64
+
65
+ 设置环境变量(可选):
66
+
67
+ - `CACHE_TTL_MINUTES` - 文档缓存 TTL(分钟),默认:60
68
+ - `GITHUB_TOKEN` - GitHub API token(用于访问私有仓库,可选)
69
+ - `ENABLE_AUTO_FIX` - 启用自动修复,默认:true
70
+ - `RATE_LIMIT_REQUESTS` - 每个窗口的最大请求数,默认:100
71
+ - `RATE_LIMIT_WINDOW_MS` - 速率限制窗口(毫秒),默认:60000
72
+
73
+ ## 使用方法
74
+
75
+ ### 1. 运行服务器
76
+
77
+ ```bash
78
+ # 开发模式(使用 tsx)
79
+ npm run dev
80
+
81
+ # 生产模式(需要先构建)
82
+ npm run build
83
+ npm start
84
+ ```
85
+
86
+ 服务器通过 stdio 运行,使用 MCP 协议进行通信。
87
+
88
+ ### 2. 在 Cursor 中配置
89
+
90
+ #### 步骤 1:找到 Cursor 配置文件
91
+
92
+ Cursor 的 MCP 配置文件位置:
93
+ - **macOS**: `~/Library/Application Support/Cursor/User/globalStorage/mcp.json`
94
+ - **Windows**: `%APPDATA%\Cursor\User\globalStorage\mcp.json`
95
+ - **Linux**: `~/.config/Cursor/User/globalStorage/mcp.json`
96
+
97
+ 或者通过 Cursor 设置界面:
98
+ 1. 打开 Cursor 设置(`Cmd/Ctrl + ,`)
99
+ 2. 搜索 "MCP" 或 "Model Context Protocol"
100
+ 3. 找到 MCP 服务器配置
101
+
102
+ #### 步骤 2:添加配置
103
+
104
+ 根据你的安装方式选择对应的配置:
105
+
106
+ ##### 如果通过 npm 全局安装:
107
+
108
+ 首先找到全局安装路径:
109
+
110
+ ```bash
111
+ # 查看全局 node_modules 路径
112
+ npm root -g
113
+ ```
114
+
115
+ 然后配置(替换 `<global-node-modules-path>` 为实际路径):
116
+
117
+ ```json
118
+ {
119
+ "mcpServers": {
120
+ "safe-coder": {
121
+ "command": "node",
122
+ "args": ["<global-node-modules-path>/@gulibs/safe-coder/dist/index.js"],
123
+ "env": {
124
+ "CACHE_TTL_MINUTES": "60",
125
+ "GITHUB_TOKEN": "your_token_here"
126
+ }
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ 或者使用 npx(推荐,更简单):
133
+
134
+ ```json
135
+ {
136
+ "mcpServers": {
137
+ "safe-coder": {
138
+ "command": "npx",
139
+ "args": ["-y", "@gulibs/safe-coder"],
140
+ "env": {
141
+ "CACHE_TTL_MINUTES": "60",
142
+ "GITHUB_TOKEN": "your_token_here"
143
+ }
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ ##### 如果从源码安装:
150
+
151
+ 找到你安装的路径,然后配置:
152
+
153
+ ```json
154
+ {
155
+ "mcpServers": {
156
+ "safe-coder": {
157
+ "command": "node",
158
+ "args": ["/绝对路径/to/safe-coder/dist/index.js"],
159
+ "env": {
160
+ "CACHE_TTL_MINUTES": "60",
161
+ "GITHUB_TOKEN": "your_token_here"
162
+ }
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ **获取绝对路径的方法:**
169
+
170
+ 在项目目录下运行:
171
+
172
+ ```bash
173
+ # macOS/Linux
174
+ pwd
175
+
176
+ # Windows PowerShell
177
+ (Get-Location).Path
178
+ ```
179
+
180
+ ##### 如果使用本地项目安装(node_modules):
181
+
182
+ ```json
183
+ {
184
+ "mcpServers": {
185
+ "safe-coder": {
186
+ "command": "node",
187
+ "args": ["./node_modules/@gulibs/safe-coder/dist/index.js"],
188
+ "env": {
189
+ "CACHE_TTL_MINUTES": "60",
190
+ "GITHUB_TOKEN": "your_token_here"
191
+ }
192
+ }
193
+ }
194
+ }
195
+ ```
196
+
197
+ #### 步骤 3:验证配置
198
+
199
+ 1. **检查配置文件格式**:确保 JSON 格式正确,可以使用在线 JSON 验证器
200
+ 2. **重启 Cursor**:保存配置后,完全重启 Cursor
201
+ 3. **检查连接状态**:
202
+ - 在 Cursor 设置中查看 MCP 服务器列表
203
+ - 应该能看到 "safe-coder" 服务器
204
+ - 状态应该显示为已连接(绿色)
205
+
206
+ #### 步骤 4:测试工具
207
+
208
+ 在 Cursor 的 AI 对话中测试:
209
+
210
+ ```
211
+ 请使用 get_documentation 工具获取 axios 库的文档
212
+ ```
213
+
214
+ 如果工具正常工作,说明配置成功!
215
+
216
+ ### 3. 使用 MCP 工具
217
+
218
+ 配置完成后,你可以在 Cursor 的 AI 对话中使用以下工具:
219
+
220
+ #### `get_documentation` - 获取文档
221
+
222
+ 获取库或包的文档。
223
+
224
+ **参数:**
225
+ - `packageName`(必需):包名(npm)、仓库(owner/repo)或 URL
226
+ - `version`(可选):版本或分支 / 标签
227
+ - `source`(可选):源类型('npm'、'github'、'http')- 如果不指定会自动检测
228
+
229
+ **使用示例:**
230
+
231
+ ```
232
+ 请帮我获取 axios 库的文档
233
+ ```
234
+
235
+ 或者直接调用:
236
+
237
+ ```json
238
+ {
239
+ "packageName": "axios",
240
+ "version": "latest",
241
+ "source": "npm"
242
+ }
243
+ ```
244
+
245
+ #### `detect_errors` - 检测错误
246
+
247
+ 检测代码中的错误和警告。
248
+
249
+ **参数:**
250
+ - `code`(必需):要分析的代码
251
+ - `filename`(可选):用于上下文的文件名(默认:'code.ts')
252
+
253
+ **使用示例:**
254
+
255
+ ```
256
+ 请检测这段代码的错误:
257
+ const x = y;
258
+ console.log(z);
259
+ ```
260
+
261
+ #### `validate_code` - 验证代码
262
+
263
+ 验证代码并可选择自动修复常见错误。
264
+
265
+ **参数:**
266
+ - `code`(必需):要验证的代码
267
+ - `filename`(可选):用于上下文的文件名
268
+ - `autoFix`(可选):启用自动修复(默认:true)
269
+
270
+ **使用示例:**
271
+
272
+ ```
273
+ 请验证并修复这段代码:
274
+ function test() {
275
+ return x
276
+ }
277
+ ```
278
+
279
+ #### `resolve_error` - 解决错误
280
+
281
+ 获取特定错误的解决方案建议。
282
+
283
+ **参数:**
284
+ - `errorType`(必需):错误类型
285
+ - `message`(必需):错误消息
286
+ - `line`(可选):错误发生的行号
287
+
288
+ **使用示例:**
289
+
290
+ ```
291
+ 我遇到了一个 undefined-variable 错误,消息是 "Variable 'x' is used but not defined",在第 5 行
292
+ ```
293
+
294
+ ### 4. 使用 MCP 资源
295
+
296
+ #### `safe-coder://documentation` - 缓存的文档
297
+
298
+ 访问缓存的文档条目,查看缓存状态。
299
+
300
+ #### `safe-coder://error-patterns` - 错误模式数据库
301
+
302
+ 访问错误模式数据库,查看已知的错误模式和解决方案。
303
+
304
+ ## 开发
305
+
306
+ ### 项目结构
307
+
308
+ ```
309
+ safe-coder/
310
+ ├── src/
311
+ │ ├── documentation/ # 文档获取和缓存
312
+ │ ├── errors/ # 错误检测(ESLint、TypeScript、模式、上下文)
313
+ │ ├── validation/ # 代码验证和自动修复
314
+ │ ├── server/ # MCP 服务器实现
315
+ │ ├── types/ # TypeScript 类型定义
316
+ │ ├── utils/ # 配置和工具函数
317
+ │ └── index.ts # 入口文件
318
+ ├── tests/ # 测试文件
319
+ ├── dist/ # 编译输出
320
+ └── package.json
321
+ ```
322
+
323
+ ### 开发命令
324
+
325
+ ```bash
326
+ # 安装依赖
327
+ npm install
328
+
329
+ # 构建项目
330
+ npm run build
331
+
332
+ # 开发模式运行(自动重新编译)
333
+ npm run dev
334
+
335
+ # 运行测试
336
+ npm test
337
+
338
+ # 监听模式运行测试
339
+ npm run test:watch
340
+
341
+ # 类型检查
342
+ npm run type-check
343
+
344
+ # 代码检查
345
+ npm run lint
346
+ ```
347
+
348
+ ### 调试
349
+
350
+ 如果遇到问题,可以:
351
+
352
+ 1. **检查服务器是否正常运行**:
353
+
354
+ ```bash
355
+ npm run dev
356
+ ```
357
+
358
+ 应该看到:`Safe Coder MCP server running on stdio`
359
+
360
+ 2. **查看 Cursor 的 MCP 日志**:
361
+ - 在 Cursor 中打开开发者工具
362
+ - 查看控制台中的 MCP 相关错误
363
+
364
+ 3. **测试工具调用**:
365
+ 可以在 Cursor 的 AI 对话中直接请求使用工具,例如:
366
+
367
+ ```
368
+ 请使用 get_documentation 工具获取 react 的文档
369
+ ```
370
+
371
+ ## 常见问题
372
+
373
+ ### Q: 服务器无法启动?
374
+
375
+ **A:** 检查以下几点:
376
+ - 确保已运行 `npm install` 和 `npm run build`
377
+ - 检查 Node.js 版本(建议 18+)
378
+ - 查看错误日志
379
+
380
+ ### Q: 无法获取 GitHub 文档?
381
+
382
+ **A:**
383
+ - 如果访问私有仓库,需要设置 `GITHUB_TOKEN` 环境变量
384
+ - 公开仓库通常不需要 token,但设置 token 可以提高速率限制
385
+
386
+ ### Q: 错误检测不准确?
387
+
388
+ **A:**
389
+ - 确保代码文件扩展名正确(`.ts` 用于 TypeScript,`.js` 用于 JavaScript)
390
+ - 某些复杂的错误可能需要更多上下文
391
+ - 可以尝试使用 `validate_code` 工具获得更全面的分析
392
+
393
+ ### Q: 如何更新错误模式数据库?
394
+
395
+ **A:**
396
+ - 编辑 `src/errors/patterns.json` 文件
397
+ - 添加新的错误模式
398
+ - 重新构建项目
399
+
400
+ ## 发布到 npm(开发者)
401
+
402
+ 如果你想将这个包发布到 npm:
403
+
404
+ ### 1. 准备发布
405
+
406
+ ```bash
407
+ # 确保已登录 npm
408
+ npm login
409
+
410
+ # 检查包名是否可用(如果已发布,需要更新版本号)
411
+ npm view @gulibs/safe-coder
412
+
413
+ # 更新版本号
414
+ npm version patch # 或 minor, major
415
+ ```
416
+
417
+ ### 2. 发布
418
+
419
+ ```bash
420
+ # 发布到 npm
421
+ npm publish
422
+
423
+ # 如果使用作用域包且是首次发布,需要添加访问权限
424
+ npm publish --access public
425
+ ```
426
+
427
+ ### 3. 验证发布
428
+
429
+ ```bash
430
+ # 检查包是否已发布
431
+ npm view @gulibs/safe-coder
432
+
433
+ # 测试安装
434
+ npm install -g @gulibs/safe-coder
435
+ ```
436
+
437
+ ## 本地开发配置示例
438
+
439
+ 如果你在本地开发,可以创建一个测试配置:
440
+
441
+ ### 创建测试配置文件
442
+
443
+ 在项目根目录创建 `cursor-mcp-config.json`:
444
+
445
+ ```json
446
+ {
447
+ "mcpServers": {
448
+ "safe-coder": {
449
+ "command": "node",
450
+ "args": ["./dist/index.js"],
451
+ "env": {
452
+ "CACHE_TTL_MINUTES": "60",
453
+ "GITHUB_TOKEN": ""
454
+ }
455
+ }
456
+ }
457
+ }
458
+ ```
459
+
460
+ 然后将此配置复制到 Cursor 的配置目录。
461
+
462
+ ### 快速测试脚本
463
+
464
+ 创建 `test-mcp.sh`(macOS/Linux)或 `test-mcp.bat`(Windows):
465
+
466
+ ```bash
467
+ #!/bin/bash
468
+ # test-mcp.sh
469
+
470
+ echo "构建项目..."
471
+ npm run build
472
+
473
+ echo "测试 MCP 服务器..."
474
+ node dist/index.js
475
+ ```
476
+
477
+ ## 故障排除
478
+
479
+ ### 问题:Cursor 无法找到服务器
480
+
481
+ **解决方案:**
482
+ 1. 检查路径是否正确(使用绝对路径)
483
+ 2. 确保 `dist/index.js` 文件存在
484
+ 3. 检查 Node.js 是否在 PATH 中:`which node` 或 `where node`
485
+
486
+ ### 问题:服务器启动失败
487
+
488
+ **解决方案:**
489
+ 1. 检查依赖是否安装:`npm install`
490
+ 2. 检查构建是否成功:`npm run build`
491
+ 3. 查看错误日志
492
+
493
+ ### 问题:工具无法使用
494
+
495
+ **解决方案:**
496
+ 1. 确认服务器在 Cursor 中显示为已连接
497
+ 2. 检查 Cursor 版本是否支持 MCP
498
+ 3. 查看 Cursor 开发者工具中的错误信息
499
+
500
+ ### 问题:权限错误
501
+
502
+ **解决方案:**
503
+
504
+ ```bash
505
+ # 确保 dist/index.js 有执行权限
506
+ chmod +x dist/index.js
507
+ ```
508
+
509
+ ## 许可证
510
+
511
+ MIT
512
+
513
+ ## 贡献
514
+
515
+ 欢迎提交 Issue 和 Pull Request!
@@ -0,0 +1,13 @@
1
+ import type { Documentation } from '../types/documentation.js';
2
+ export declare class DocumentationCache {
3
+ private cache;
4
+ private readonly defaultTTL;
5
+ constructor(defaultTTLMinutes?: number);
6
+ get(key: string): Documentation | null;
7
+ set(key: string, documentation: Documentation, ttl?: number): void;
8
+ generateKey(packageName: string, version?: string): string;
9
+ clear(): void;
10
+ size(): number;
11
+ cleanup(): number;
12
+ }
13
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/documentation/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,2BAA2B,CAAC;AAE3E,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,iBAAiB,GAAE,MAAW;IAI1C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAetC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAUlE,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;IAI1D,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,MAAM;IAKd,OAAO,IAAI,MAAM;CAalB"}
@@ -0,0 +1,48 @@
1
+ export class DocumentationCache {
2
+ cache = new Map();
3
+ defaultTTL; // in milliseconds
4
+ constructor(defaultTTLMinutes = 60) {
5
+ this.defaultTTL = defaultTTLMinutes * 60 * 1000;
6
+ }
7
+ get(key) {
8
+ const entry = this.cache.get(key);
9
+ if (!entry) {
10
+ return null;
11
+ }
12
+ if (new Date() > entry.expiresAt) {
13
+ this.cache.delete(key);
14
+ return null;
15
+ }
16
+ return entry.documentation;
17
+ }
18
+ set(key, documentation, ttl) {
19
+ const expiresAt = new Date(Date.now() + (ttl || this.defaultTTL));
20
+ this.cache.set(key, {
21
+ documentation,
22
+ expiresAt,
23
+ version: documentation.version || 'latest',
24
+ });
25
+ }
26
+ generateKey(packageName, version) {
27
+ return version ? `${packageName}@${version}` : `${packageName}@latest`;
28
+ }
29
+ clear() {
30
+ this.cache.clear();
31
+ }
32
+ size() {
33
+ return this.cache.size;
34
+ }
35
+ // Clean expired entries
36
+ cleanup() {
37
+ const now = new Date();
38
+ let cleaned = 0;
39
+ for (const [key, entry] of this.cache.entries()) {
40
+ if (now > entry.expiresAt) {
41
+ this.cache.delete(key);
42
+ cleaned++;
43
+ }
44
+ }
45
+ return cleaned;
46
+ }
47
+ }
48
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/documentation/cache.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAkB;IACrB,KAAK,GAA4B,IAAI,GAAG,EAAE,CAAC;IAClC,UAAU,CAAS,CAAC,kBAAkB;IAEvD,YAAY,oBAA4B,EAAE;QACxC,IAAI,CAAC,UAAU,GAAG,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;IAClD,CAAC;IAED,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,IAAI,IAAI,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC,aAAa,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,aAA4B,EAAE,GAAY;QACzD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAElE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,aAAa;YACb,SAAS;YACT,OAAO,EAAE,aAAa,CAAC,OAAO,IAAI,QAAQ;SAC3C,CAAC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,WAAmB,EAAE,OAAgB;QAC/C,OAAO,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,WAAW,SAAS,CAAC;IACzE,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,wBAAwB;IACxB,OAAO;QACL,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import type { Documentation, DocumentationSource } from '../types/documentation.js';
2
+ export declare class GitHubClient implements DocumentationSource {
3
+ private readonly apiUrl;
4
+ private readonly token?;
5
+ constructor(token?: string);
6
+ fetch(packageName: string, version?: string): Promise<Documentation>;
7
+ private parseRepository;
8
+ private fetchReadme;
9
+ private fetchDocs;
10
+ }
11
+ //# sourceMappingURL=github-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-client.d.ts","sourceRoot":"","sources":["../../src/documentation/github-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEpF,qBAAa,YAAa,YAAW,mBAAmB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAS;gBAEpB,KAAK,CAAC,EAAE,MAAM;IAIpB,KAAK,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA8B1E,OAAO,CAAC,eAAe;YAST,WAAW;YAoBX,SAAS;CAqCxB"}
@@ -0,0 +1,88 @@
1
+ import axios from 'axios';
2
+ export class GitHubClient {
3
+ apiUrl = 'https://api.github.com';
4
+ token;
5
+ constructor(token) {
6
+ this.token = token || process.env.GITHUB_TOKEN;
7
+ }
8
+ async fetch(packageName, version) {
9
+ try {
10
+ // Parse packageName as owner/repo or extract from npm package
11
+ const [owner, repo] = this.parseRepository(packageName);
12
+ if (!owner || !repo) {
13
+ throw new Error(`Invalid GitHub repository format: ${packageName}`);
14
+ }
15
+ // Fetch README
16
+ const readme = await this.fetchReadme(owner, repo, version);
17
+ // Try to fetch docs directory if it exists
18
+ const docs = await this.fetchDocs(owner, repo, version);
19
+ const content = [readme, docs].filter(Boolean).join('\n\n---\n\n');
20
+ return {
21
+ name: `${owner}/${repo}`,
22
+ version,
23
+ content: content || `No documentation found for ${owner}/${repo}`,
24
+ source: 'github',
25
+ url: `https://github.com/${owner}/${repo}`,
26
+ lastUpdated: new Date(),
27
+ };
28
+ }
29
+ catch (error) {
30
+ throw new Error(`Failed to fetch GitHub documentation: ${error instanceof Error ? error.message : 'Unknown error'}`);
31
+ }
32
+ }
33
+ parseRepository(packageName) {
34
+ // Check if it's already in owner/repo format
35
+ if (packageName.includes('/')) {
36
+ const parts = packageName.split('/');
37
+ return [parts[0], parts[1]];
38
+ }
39
+ return [null, null];
40
+ }
41
+ async fetchReadme(owner, repo, ref) {
42
+ try {
43
+ const refParam = ref ? `?ref=${ref}` : '';
44
+ const url = `${this.apiUrl}/repos/${owner}/${repo}/readme${refParam}`;
45
+ const headers = {
46
+ 'Accept': 'application/vnd.github.v3.raw',
47
+ };
48
+ if (this.token) {
49
+ headers['Authorization'] = `token ${this.token}`;
50
+ }
51
+ const response = await axios.get(url, { headers });
52
+ return response.data;
53
+ }
54
+ catch (error) {
55
+ // README might not exist, return empty
56
+ return '';
57
+ }
58
+ }
59
+ async fetchDocs(owner, repo, ref) {
60
+ try {
61
+ const refParam = ref ? `?ref=${ref}` : '';
62
+ const url = `${this.apiUrl}/repos/${owner}/${repo}/contents/docs${refParam}`;
63
+ const headers = {};
64
+ if (this.token) {
65
+ headers['Authorization'] = `token ${this.token}`;
66
+ }
67
+ const response = await axios.get(url, { headers });
68
+ // If docs is a directory, fetch all markdown files
69
+ if (Array.isArray(response.data)) {
70
+ const markdownFiles = response.data.filter((file) => file.type === 'file' && file.name.endsWith('.md'));
71
+ const contents = await Promise.all(markdownFiles.map(async (file) => {
72
+ const fileUrl = `${this.apiUrl}/repos/${owner}/${repo}/contents/${file.path}${refParam}`;
73
+ const fileResponse = await axios.get(fileUrl, {
74
+ headers: { ...headers, 'Accept': 'application/vnd.github.v3.raw' }
75
+ });
76
+ return `## ${file.name}\n\n${fileResponse.data}`;
77
+ }));
78
+ return contents.join('\n\n');
79
+ }
80
+ return '';
81
+ }
82
+ catch (error) {
83
+ // Docs directory might not exist
84
+ return '';
85
+ }
86
+ }
87
+ }
88
+ //# sourceMappingURL=github-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-client.js","sourceRoot":"","sources":["../../src/documentation/github-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Documentation, DocumentationSource } from '../types/documentation.js';
2
+ export declare class HttpFetcher implements DocumentationSource {
3
+ fetch(packageName: string, version?: string): Promise<Documentation>;
4
+ }
5
+ //# sourceMappingURL=http-fetcher.d.ts.map