github-to-mcp-monorepo 1.0.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 (388) hide show
  1. package/.env.example +8 -0
  2. package/.github/CODEOWNERS +6 -0
  3. package/.husky/pre-commit +1 -0
  4. package/.nvmrc +1 -0
  5. package/.prettierignore +5 -0
  6. package/.prettierrc +7 -0
  7. package/.vscode/settings.json +4 -0
  8. package/ARCHITECTURE.md +1429 -0
  9. package/CHANGELOG.md +167 -0
  10. package/CONTRIBUTING.md +327 -0
  11. package/LICENSE +201 -0
  12. package/README.md +1028 -0
  13. package/SECURITY.md +248 -0
  14. package/VISUAL_GUIDE.md +437 -0
  15. package/apps/vscode/IMPLEMENTATION.md +480 -0
  16. package/apps/vscode/README.md +248 -0
  17. package/apps/vscode/package.json +381 -0
  18. package/apps/vscode/resources/icon.png +0 -0
  19. package/apps/vscode/resources/icon.svg +5 -0
  20. package/apps/vscode/src/commands/browseRegistry.ts +211 -0
  21. package/apps/vscode/src/commands/configureClaudeDesktop.ts +332 -0
  22. package/apps/vscode/src/commands/convert.ts +82 -0
  23. package/apps/vscode/src/commands/convertCurrentRepo.ts +109 -0
  24. package/apps/vscode/src/commands/convertFromUrl.ts +138 -0
  25. package/apps/vscode/src/commands/index.ts +121 -0
  26. package/apps/vscode/src/commands/validate.ts +197 -0
  27. package/apps/vscode/src/extension.ts +464 -0
  28. package/apps/vscode/src/global.d.ts +36 -0
  29. package/apps/vscode/src/test/extension.test.ts +73 -0
  30. package/apps/vscode/src/utils/file-generator.ts +529 -0
  31. package/apps/vscode/src/utils/github-api.ts +335 -0
  32. package/apps/vscode/src/utils/index.ts +29 -0
  33. package/apps/vscode/src/utils/mcp-config.ts +334 -0
  34. package/apps/vscode/src/utils/storage.ts +87 -0
  35. package/apps/vscode/src/views/McpServersTreeView.ts +160 -0
  36. package/apps/vscode/src/views/OutputChannelView.ts +195 -0
  37. package/apps/vscode/src/views/StatusBarItem.ts +251 -0
  38. package/apps/vscode/src/views/ToolsExplorerView.ts +314 -0
  39. package/apps/vscode/src/views/historyProvider.ts +75 -0
  40. package/apps/vscode/src/views/index.ts +12 -0
  41. package/apps/vscode/src/views/resultsPanel.ts +330 -0
  42. package/apps/vscode/src/webviews/ConversionPanel.ts +350 -0
  43. package/apps/vscode/src/webviews/ToolDetailsPanel.ts +448 -0
  44. package/apps/vscode/src/webviews/index.ts +9 -0
  45. package/apps/vscode/src/webviews/webview-ui/styles.ts +492 -0
  46. package/apps/vscode/tsconfig.json +20 -0
  47. package/apps/web/PLAYGROUND_GUIDE.md +499 -0
  48. package/apps/web/README.md +505 -0
  49. package/apps/web/app/api/convert/route.ts +100 -0
  50. package/apps/web/app/api/convert/stream/route.ts +198 -0
  51. package/apps/web/app/api/deploy/route.ts +157 -0
  52. package/apps/web/app/api/edge/route.ts +308 -0
  53. package/apps/web/app/api/export-docker/route.ts +284 -0
  54. package/apps/web/app/api/generate-openapi/route.ts +119 -0
  55. package/apps/web/app/api/mcp/[serverId]/route.ts +263 -0
  56. package/apps/web/app/api/playground/connect/route.ts +143 -0
  57. package/apps/web/app/api/playground/disconnect/route.ts +78 -0
  58. package/apps/web/app/api/playground/execute/route.ts +135 -0
  59. package/apps/web/app/api/playground/sessions/route.ts +103 -0
  60. package/apps/web/app/api/playground/tools/route.ts +117 -0
  61. package/apps/web/app/api/playground/v2/connect/route.ts +96 -0
  62. package/apps/web/app/api/playground/v2/disconnect/route.ts +88 -0
  63. package/apps/web/app/api/playground/v2/health/route.ts +80 -0
  64. package/apps/web/app/api/playground/v2/prompts/route.ts +160 -0
  65. package/apps/web/app/api/playground/v2/resources/route.ts +159 -0
  66. package/apps/web/app/api/playground/v2/sessions/route.ts +184 -0
  67. package/apps/web/app/api/playground/v2/tools/route.ts +167 -0
  68. package/apps/web/app/api/stream/route.ts +232 -0
  69. package/apps/web/app/batch/BatchConvertClient.tsx +190 -0
  70. package/apps/web/app/batch/page.tsx +37 -0
  71. package/apps/web/app/convert/page.tsx +269 -0
  72. package/apps/web/app/dashboard/page.tsx +380 -0
  73. package/apps/web/app/globals.css +622 -0
  74. package/apps/web/app/layout.tsx +120 -0
  75. package/apps/web/app/manifest.ts +31 -0
  76. package/apps/web/app/opengraph-image.tsx +112 -0
  77. package/apps/web/app/page.old.tsx +924 -0
  78. package/apps/web/app/page.tsx +77 -0
  79. package/apps/web/app/playground/page.tsx +306 -0
  80. package/apps/web/app/playground/v2/error.tsx +163 -0
  81. package/apps/web/app/playground/v2/layout.tsx +58 -0
  82. package/apps/web/app/playground/v2/loading.tsx +152 -0
  83. package/apps/web/app/playground/v2/page.tsx +644 -0
  84. package/apps/web/app/playground/v2/providers.tsx +214 -0
  85. package/apps/web/app/playground/v2/use-shortcuts.ts +209 -0
  86. package/apps/web/app/playground/v2/use-url-state.ts +296 -0
  87. package/apps/web/app/providers.tsx +22 -0
  88. package/apps/web/app/sitemap.ts +32 -0
  89. package/apps/web/app/twitter-image.tsx +112 -0
  90. package/apps/web/components/BranchSelector.tsx +401 -0
  91. package/apps/web/components/ClaudeConfigExport.tsx +226 -0
  92. package/apps/web/components/Features.tsx +84 -0
  93. package/apps/web/components/Footer.tsx +119 -0
  94. package/apps/web/components/GenerationProgress.tsx +248 -0
  95. package/apps/web/components/GithubUrlInput.tsx +483 -0
  96. package/apps/web/components/Header.tsx +175 -0
  97. package/apps/web/components/Hero.tsx +117 -0
  98. package/apps/web/components/HowItWorks.tsx +119 -0
  99. package/apps/web/components/InstallBanner.tsx +158 -0
  100. package/apps/web/components/Logo.tsx +116 -0
  101. package/apps/web/components/ParticleBackground.tsx +105 -0
  102. package/apps/web/components/Playground.tsx +472 -0
  103. package/apps/web/components/PlaygroundToolTester.tsx +410 -0
  104. package/apps/web/components/ProductCards.tsx +179 -0
  105. package/apps/web/components/SplitView.tsx +194 -0
  106. package/apps/web/components/ToolFilter.tsx +260 -0
  107. package/apps/web/components/ToolList.tsx +325 -0
  108. package/apps/web/components/batch/BatchConvert.tsx +785 -0
  109. package/apps/web/components/batch/index.ts +7 -0
  110. package/apps/web/components/convert/ConfigTabs.tsx +230 -0
  111. package/apps/web/components/convert/ConversionResult.tsx +482 -0
  112. package/apps/web/components/convert/InlinePlayground.tsx +259 -0
  113. package/apps/web/components/convert/LoadingSteps.tsx +311 -0
  114. package/apps/web/components/convert/OneClickInstall.tsx +224 -0
  115. package/apps/web/components/convert/ToolCard.tsx +189 -0
  116. package/apps/web/components/convert/TryInPlayground.tsx +242 -0
  117. package/apps/web/components/convert/index.ts +12 -0
  118. package/apps/web/components/deploy/DeployButton.tsx +369 -0
  119. package/apps/web/components/deploy/index.ts +7 -0
  120. package/apps/web/components/docker/DockerExport.tsx +690 -0
  121. package/apps/web/components/docker/index.ts +7 -0
  122. package/apps/web/components/install/OneClickInstall.tsx +676 -0
  123. package/apps/web/components/install/index.ts +7 -0
  124. package/apps/web/components/playground/CapabilityTabs.tsx +150 -0
  125. package/apps/web/components/playground/ConnectionStatusV2.tsx +322 -0
  126. package/apps/web/components/playground/EmptyStates.tsx +305 -0
  127. package/apps/web/components/playground/ExecutionLog.tsx +260 -0
  128. package/apps/web/components/playground/ExecutionLogV2.tsx +378 -0
  129. package/apps/web/components/playground/JsonViewer.tsx +388 -0
  130. package/apps/web/components/playground/PlaygroundLayout.tsx +244 -0
  131. package/apps/web/components/playground/PromptsPanel.tsx +385 -0
  132. package/apps/web/components/playground/ResourcesPanel.tsx +378 -0
  133. package/apps/web/components/playground/SchemaForm.tsx +477 -0
  134. package/apps/web/components/playground/ServerStatus.tsx +151 -0
  135. package/apps/web/components/playground/ShareButton.tsx +239 -0
  136. package/apps/web/components/playground/ToolsPanel.tsx +309 -0
  137. package/apps/web/components/playground/TransportConfigurator.tsx +563 -0
  138. package/apps/web/components/playground/index.ts +74 -0
  139. package/apps/web/components/playground/types.ts +202 -0
  140. package/apps/web/components/streaming/StreamingProgress.tsx +441 -0
  141. package/apps/web/components/streaming/index.ts +7 -0
  142. package/apps/web/components/ui/badge.tsx +42 -0
  143. package/apps/web/components/ui/button.tsx +88 -0
  144. package/apps/web/components/ui/card.tsx +75 -0
  145. package/apps/web/components/ui/code-block.tsx +122 -0
  146. package/apps/web/components/ui/index.ts +12 -0
  147. package/apps/web/components/ui/input.tsx +55 -0
  148. package/apps/web/components/ui/tabs.tsx +61 -0
  149. package/apps/web/hooks/index.ts +85 -0
  150. package/apps/web/hooks/types.ts +1173 -0
  151. package/apps/web/hooks/use-conversion.ts +133 -0
  152. package/apps/web/hooks/use-execution-history.ts +376 -0
  153. package/apps/web/hooks/use-generation-progress.ts +147 -0
  154. package/apps/web/hooks/use-local-storage.ts +88 -0
  155. package/apps/web/hooks/use-mcp-client.ts +623 -0
  156. package/apps/web/hooks/use-mcp-connection.ts +500 -0
  157. package/apps/web/hooks/use-mcp-execution.ts +282 -0
  158. package/apps/web/hooks/use-mcp-prompts.ts +441 -0
  159. package/apps/web/hooks/use-mcp-resources.ts +430 -0
  160. package/apps/web/hooks/use-mcp-tools.ts +540 -0
  161. package/apps/web/hooks/use-playground-store.ts +299 -0
  162. package/apps/web/hooks/use-playground.ts +184 -0
  163. package/apps/web/hooks/use-streaming-conversion.ts +227 -0
  164. package/apps/web/hooks/useBatchConversion.ts +271 -0
  165. package/apps/web/hooks/useDockerConfig.ts +161 -0
  166. package/apps/web/hooks/usePlatformDetection.ts +80 -0
  167. package/apps/web/hooks/useStreaming.ts +199 -0
  168. package/apps/web/lib/api/errors.ts +386 -0
  169. package/apps/web/lib/api/index.ts +137 -0
  170. package/apps/web/lib/api/logger.ts +187 -0
  171. package/apps/web/lib/api/middleware.ts +364 -0
  172. package/apps/web/lib/api/openapi.ts +977 -0
  173. package/apps/web/lib/api/session-manager.ts +594 -0
  174. package/apps/web/lib/api/types.ts +433 -0
  175. package/apps/web/lib/api/validation.ts +523 -0
  176. package/apps/web/lib/constants.ts +114 -0
  177. package/apps/web/lib/mcp/client.ts +1137 -0
  178. package/apps/web/lib/mcp/events.ts +651 -0
  179. package/apps/web/lib/mcp/index.ts +347 -0
  180. package/apps/web/lib/mcp/logger.ts +428 -0
  181. package/apps/web/lib/mcp/metrics.ts +703 -0
  182. package/apps/web/lib/mcp/retry.ts +616 -0
  183. package/apps/web/lib/mcp/session-manager.ts +779 -0
  184. package/apps/web/lib/mcp/transports.ts +988 -0
  185. package/apps/web/lib/mcp/types.ts +594 -0
  186. package/apps/web/lib/mcp-client-enhanced.ts +871 -0
  187. package/apps/web/lib/mcp-client.ts +778 -0
  188. package/apps/web/lib/mcp-errors.ts +489 -0
  189. package/apps/web/lib/mcp-sandbox.ts +593 -0
  190. package/apps/web/lib/mcp-testing.ts +428 -0
  191. package/apps/web/lib/mcp-types.ts +448 -0
  192. package/apps/web/lib/playground-store.tsx +1147 -0
  193. package/apps/web/lib/utils.ts +439 -0
  194. package/apps/web/next-env.d.ts +5 -0
  195. package/apps/web/next.config.js +23 -0
  196. package/apps/web/package.json +55 -0
  197. package/apps/web/postcss.config.js +6 -0
  198. package/apps/web/public/.well-known/ai-plugin.json +17 -0
  199. package/apps/web/public/logo.svg +6 -0
  200. package/apps/web/public/robots.txt +22 -0
  201. package/apps/web/public/schema.json +27 -0
  202. package/apps/web/tailwind.config.js +26 -0
  203. package/apps/web/tailwind.config.ts +123 -0
  204. package/apps/web/tsconfig.json +20 -0
  205. package/apps/web/types/deploy.ts +139 -0
  206. package/apps/web/types/index.ts +247 -0
  207. package/apps/web/vercel.json +39 -0
  208. package/eslint.config.mjs +23 -0
  209. package/llms.txt +102 -0
  210. package/mkdocs/docs/api/core.md +318 -0
  211. package/mkdocs/docs/api/index.md +128 -0
  212. package/mkdocs/docs/api/mcp-server.md +301 -0
  213. package/mkdocs/docs/api/openapi-parser.md +254 -0
  214. package/mkdocs/docs/assets/logo.svg +7 -0
  215. package/mkdocs/docs/changelog.md +118 -0
  216. package/mkdocs/docs/cli/generate.md +148 -0
  217. package/mkdocs/docs/cli/index.md +52 -0
  218. package/mkdocs/docs/cli/inspect.md +164 -0
  219. package/mkdocs/docs/cli/serve.md +136 -0
  220. package/mkdocs/docs/concepts/classification.md +254 -0
  221. package/mkdocs/docs/concepts/how-it-works.md +299 -0
  222. package/mkdocs/docs/concepts/index.md +77 -0
  223. package/mkdocs/docs/concepts/mcp-protocol.md +362 -0
  224. package/mkdocs/docs/concepts/tool-types.md +382 -0
  225. package/mkdocs/docs/contributing/architecture.md +262 -0
  226. package/mkdocs/docs/contributing/development.md +245 -0
  227. package/mkdocs/docs/contributing/index.md +73 -0
  228. package/mkdocs/docs/contributing/testing.md +320 -0
  229. package/mkdocs/docs/getting-started/configuration.md +235 -0
  230. package/mkdocs/docs/getting-started/index.md +54 -0
  231. package/mkdocs/docs/getting-started/installation.md +145 -0
  232. package/mkdocs/docs/getting-started/quickstart.md +160 -0
  233. package/mkdocs/docs/guides/batch.md +375 -0
  234. package/mkdocs/docs/guides/claude-desktop.md +227 -0
  235. package/mkdocs/docs/guides/cursor.md +188 -0
  236. package/mkdocs/docs/guides/custom-tools.md +367 -0
  237. package/mkdocs/docs/guides/index.md +78 -0
  238. package/mkdocs/docs/guides/private-repos.md +221 -0
  239. package/mkdocs/docs/guides/vscode.md +247 -0
  240. package/mkdocs/docs/index.md +175 -0
  241. package/mkdocs/docs/reference/config.md +223 -0
  242. package/mkdocs/docs/reference/env.md +192 -0
  243. package/mkdocs/docs/reference/index.md +102 -0
  244. package/mkdocs/docs/reference/tools.md +309 -0
  245. package/mkdocs/docs/stylesheets/extra.css +231 -0
  246. package/mkdocs/mkdocs.yml +204 -0
  247. package/mkdocs/overrides/.gitkeep +1 -0
  248. package/mkdocs/overrides/main.html +7 -0
  249. package/mkdocs/python-deps.txt +7 -0
  250. package/mkdocs/vercel.json +11 -0
  251. package/package.json +63 -0
  252. package/packages/core/package.json +61 -0
  253. package/packages/core/src/__tests__/bitbucket-client.test.ts +366 -0
  254. package/packages/core/src/__tests__/cli.test.ts +235 -0
  255. package/packages/core/src/__tests__/code-extractor.test.ts +378 -0
  256. package/packages/core/src/__tests__/docker-generator.test.ts +255 -0
  257. package/packages/core/src/__tests__/github-client.test.ts +390 -0
  258. package/packages/core/src/__tests__/gitlab-client.test.ts +319 -0
  259. package/packages/core/src/__tests__/go-extractor.test.ts +351 -0
  260. package/packages/core/src/__tests__/graphql-extractor.test.ts +330 -0
  261. package/packages/core/src/__tests__/java-extractor.test.ts +497 -0
  262. package/packages/core/src/__tests__/plugins.test.ts +467 -0
  263. package/packages/core/src/__tests__/readme-extractor.test.ts +258 -0
  264. package/packages/core/src/__tests__/redis-cache.test.ts +307 -0
  265. package/packages/core/src/__tests__/rust-extractor.test.ts +252 -0
  266. package/packages/core/src/__tests__/streaming.test.ts +251 -0
  267. package/packages/core/src/additional-extractors.ts +333 -0
  268. package/packages/core/src/cache/cache-interface.ts +179 -0
  269. package/packages/core/src/cache/index.ts +210 -0
  270. package/packages/core/src/cache/redis-cache.ts +291 -0
  271. package/packages/core/src/cache/upstash-cache.ts +379 -0
  272. package/packages/core/src/cache.ts +251 -0
  273. package/packages/core/src/cli.ts +822 -0
  274. package/packages/core/src/code-extractor.ts +696 -0
  275. package/packages/core/src/docker-generator.ts +470 -0
  276. package/packages/core/src/edge-compatible.ts +491 -0
  277. package/packages/core/src/extractors/go-extractor.ts +791 -0
  278. package/packages/core/src/extractors/index.ts +9 -0
  279. package/packages/core/src/extractors/java-extractor.ts +937 -0
  280. package/packages/core/src/extractors/rust-extractor.ts +744 -0
  281. package/packages/core/src/github-client.ts +319 -0
  282. package/packages/core/src/go-generator.ts +356 -0
  283. package/packages/core/src/graphql-extractor.ts +358 -0
  284. package/packages/core/src/index.ts +797 -0
  285. package/packages/core/src/langchain-exporter.ts +617 -0
  286. package/packages/core/src/language-parsers.ts +1114 -0
  287. package/packages/core/src/mcp-introspector.ts +279 -0
  288. package/packages/core/src/monorepo-detector.ts +378 -0
  289. package/packages/core/src/plugins/index.ts +370 -0
  290. package/packages/core/src/plugins/registry.ts +404 -0
  291. package/packages/core/src/plugins/types.ts +215 -0
  292. package/packages/core/src/providers/base-provider.ts +246 -0
  293. package/packages/core/src/providers/bitbucket-client.ts +464 -0
  294. package/packages/core/src/providers/gitlab-client.ts +388 -0
  295. package/packages/core/src/providers/index.ts +176 -0
  296. package/packages/core/src/python-generator.ts +260 -0
  297. package/packages/core/src/queue/index.ts +100 -0
  298. package/packages/core/src/queue/memory-queue.ts +445 -0
  299. package/packages/core/src/queue/redis-queue.ts +578 -0
  300. package/packages/core/src/queue/types.ts +251 -0
  301. package/packages/core/src/readme-extractor.ts +409 -0
  302. package/packages/core/src/schema-generator.ts +638 -0
  303. package/packages/core/src/streaming.ts +999 -0
  304. package/packages/core/src/types.ts +289 -0
  305. package/packages/core/tsconfig.json +9 -0
  306. package/packages/core/tsup.config.ts +25 -0
  307. package/packages/mcp-server/README.md +297 -0
  308. package/packages/mcp-server/package.json +55 -0
  309. package/packages/mcp-server/src/__tests__/mcp-server.test.ts +177 -0
  310. package/packages/mcp-server/src/__tests__/tools.test.ts +217 -0
  311. package/packages/mcp-server/src/index.ts +1206 -0
  312. package/packages/mcp-server/src/prompts/index.ts +601 -0
  313. package/packages/mcp-server/src/tools/export-docker.ts +362 -0
  314. package/packages/mcp-server/src/tools/generate-openapi.ts +162 -0
  315. package/packages/mcp-server/src/tools/monitor-mcp-server.ts +448 -0
  316. package/packages/mcp-server/src/tools/stream-convert.ts +398 -0
  317. package/packages/mcp-server/src/tools/test-mcp-tool.ts +531 -0
  318. package/packages/mcp-server/tsconfig.json +12 -0
  319. package/packages/mcp-server/tsup.config.ts +14 -0
  320. package/packages/openapi-parser/package-lock.json +3028 -0
  321. package/packages/openapi-parser/package.json +41 -0
  322. package/packages/openapi-parser/src/analyzer.ts +700 -0
  323. package/packages/openapi-parser/src/asyncapi-parser.ts +475 -0
  324. package/packages/openapi-parser/src/cli.ts +302 -0
  325. package/packages/openapi-parser/src/generator.ts +570 -0
  326. package/packages/openapi-parser/src/generators/express-analyzer.ts +649 -0
  327. package/packages/openapi-parser/src/generators/fastapi-analyzer.ts +960 -0
  328. package/packages/openapi-parser/src/generators/index.ts +200 -0
  329. package/packages/openapi-parser/src/generators/nextjs-analyzer.ts +768 -0
  330. package/packages/openapi-parser/src/generators/openapi-builder.ts +527 -0
  331. package/packages/openapi-parser/src/generators/types.ts +298 -0
  332. package/packages/openapi-parser/src/graphql-parser.ts +462 -0
  333. package/packages/openapi-parser/src/grpc-parser.ts +649 -0
  334. package/packages/openapi-parser/src/har-parser.ts +723 -0
  335. package/packages/openapi-parser/src/index.ts +635 -0
  336. package/packages/openapi-parser/src/insomnia-parser.ts +614 -0
  337. package/packages/openapi-parser/src/parser.ts +231 -0
  338. package/packages/openapi-parser/src/postman-parser.ts +611 -0
  339. package/packages/openapi-parser/src/ref-resolver.ts +313 -0
  340. package/packages/openapi-parser/src/transformer.ts +459 -0
  341. package/packages/openapi-parser/tests/generators/express.test.ts +209 -0
  342. package/packages/openapi-parser/tests/generators/fastapi.test.ts +236 -0
  343. package/packages/openapi-parser/tests/generators/nextjs.test.ts +273 -0
  344. package/packages/openapi-parser/tests/parsers.test.ts +847 -0
  345. package/packages/openapi-parser/tsconfig.json +9 -0
  346. package/packages/openapi-parser/tsup.config.ts +11 -0
  347. package/packages/registry/package.json +59 -0
  348. package/packages/registry/src/cli.ts +456 -0
  349. package/packages/registry/src/index.ts +44 -0
  350. package/packages/registry/src/popular/github.json +47 -0
  351. package/packages/registry/src/popular/index.ts +55 -0
  352. package/packages/registry/src/popular/linear.json +42 -0
  353. package/packages/registry/src/popular/notion.json +42 -0
  354. package/packages/registry/src/popular/openai.json +40 -0
  355. package/packages/registry/src/popular/resend.json +38 -0
  356. package/packages/registry/src/popular/slack.json +42 -0
  357. package/packages/registry/src/popular/stripe.json +163 -0
  358. package/packages/registry/src/popular/supabase.json +42 -0
  359. package/packages/registry/src/popular/twilio.json +40 -0
  360. package/packages/registry/src/popular/vercel.json +40 -0
  361. package/packages/registry/src/registry.ts +492 -0
  362. package/packages/registry/src/storage.ts +334 -0
  363. package/packages/registry/src/types.ts +275 -0
  364. package/packages/registry/src/updater.ts +208 -0
  365. package/packages/registry/tsconfig.json +10 -0
  366. package/packages/registry/tsup.config.ts +11 -0
  367. package/pnpm-workspace.yaml +3 -0
  368. package/scripts/build-docs.sh +16 -0
  369. package/server.json +9 -0
  370. package/templates/Dockerfile.python.template +60 -0
  371. package/templates/Dockerfile.typescript.template +60 -0
  372. package/templates/docker-compose.template.yml +68 -0
  373. package/tests/fixtures/express-app/index.js +34 -0
  374. package/tests/fixtures/express-app/routes/posts.js +43 -0
  375. package/tests/fixtures/express-app/routes/users.js +58 -0
  376. package/tests/fixtures/fastapi-app/main.py +125 -0
  377. package/tests/fixtures/fastapi-app/routes/admin.py +42 -0
  378. package/tests/fixtures/graphql/simple-schema.graphql +65 -0
  379. package/tests/fixtures/mocks/github-api-responses.json +63 -0
  380. package/tests/fixtures/nextjs-app/app/api/posts/route.ts +55 -0
  381. package/tests/fixtures/nextjs-app/app/api/users/[id]/route.ts +63 -0
  382. package/tests/fixtures/nextjs-app/app/api/users/route.ts +44 -0
  383. package/tests/fixtures/nextjs-app/pages/api/health.ts +28 -0
  384. package/tests/fixtures/openapi/petstore.yaml +179 -0
  385. package/tests/integration/langchain-export.test.ts +405 -0
  386. package/tests/integration/openapi-conversion.test.ts +221 -0
  387. package/tsconfig.json +18 -0
  388. package/vitest.config.ts +32 -0
@@ -0,0 +1,307 @@
1
+ /**
2
+ * @fileoverview Unit tests for Redis cache implementation
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
6
+ import { RedisCache, createRedisCache, RedisClientInterface } from '../cache/redis-cache';
7
+ import { createCacheEntry } from '../cache/cache-interface';
8
+
9
+ // Mock Redis client
10
+ function createMockRedisClient(): RedisClientInterface {
11
+ const store = new Map<string, string>();
12
+
13
+ return {
14
+ get: vi.fn(async (key: string) => store.get(key) || null),
15
+ set: vi.fn(async (key: string, value: string) => {
16
+ store.set(key, value);
17
+ return 'OK';
18
+ }),
19
+ del: vi.fn(async (key: string | string[]) => {
20
+ const keys = Array.isArray(key) ? key : [key];
21
+ let count = 0;
22
+ for (const k of keys) {
23
+ if (store.delete(k)) count++;
24
+ }
25
+ return count;
26
+ }),
27
+ keys: vi.fn(async (pattern: string) => {
28
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
29
+ return Array.from(store.keys()).filter(k => regex.test(k));
30
+ }),
31
+ exists: vi.fn(async (key: string | string[]) => {
32
+ const keys = Array.isArray(key) ? key : [key];
33
+ return keys.filter(k => store.has(k)).length;
34
+ }),
35
+ mget: vi.fn(async (...keys: string[]) => keys.map(k => store.get(k) || null)),
36
+ mset: vi.fn(async (...keysAndValues: string[]) => {
37
+ for (let i = 0; i < keysAndValues.length; i += 2) {
38
+ store.set(keysAndValues[i], keysAndValues[i + 1]);
39
+ }
40
+ return 'OK';
41
+ }),
42
+ quit: vi.fn(async () => 'OK'),
43
+ dbsize: vi.fn(async () => store.size),
44
+ info: vi.fn(async () => 'used_memory:1024')
45
+ };
46
+ }
47
+
48
+ describe('RedisCache', () => {
49
+ let mockClient: RedisClientInterface;
50
+ let cache: RedisCache;
51
+
52
+ beforeEach(() => {
53
+ vi.clearAllMocks();
54
+ mockClient = createMockRedisClient();
55
+ cache = new RedisCache({
56
+ client: mockClient,
57
+ keyPrefix: 'test-cache',
58
+ defaultTTL: 3600
59
+ });
60
+ });
61
+
62
+ afterEach(() => {
63
+ vi.resetAllMocks();
64
+ });
65
+
66
+ describe('get', () => {
67
+ it('should return null for non-existent key', async () => {
68
+ const result = await cache.get('nonexistent');
69
+ expect(result).toBeNull();
70
+ });
71
+
72
+ it('should return cached value', async () => {
73
+ const entry = createCacheEntry({ name: 'test' }, 3600);
74
+ await cache.set('test-key', entry);
75
+
76
+ const result = await cache.get<{ name: string }>('test-key');
77
+
78
+ expect(result).not.toBeNull();
79
+ expect(result?.data.name).toBe('test');
80
+ });
81
+
82
+ it('should return null for expired entries', async () => {
83
+ const expiredEntry = {
84
+ data: { name: 'expired' },
85
+ timestamp: Date.now() - 10000000, // 10000 seconds ago
86
+ ttl: 1 // 1 second TTL
87
+ };
88
+
89
+ // Manually set expired entry
90
+ await mockClient.set('test-cache:expired-key', JSON.stringify(expiredEntry));
91
+
92
+ const result = await cache.get('expired-key');
93
+
94
+ expect(result).toBeNull();
95
+ });
96
+
97
+ it('should track cache misses', async () => {
98
+ await cache.get('miss1');
99
+ await cache.get('miss2');
100
+
101
+ const stats = await cache.getStats();
102
+
103
+ expect(stats.misses).toBe(2);
104
+ });
105
+
106
+ it('should track cache hits', async () => {
107
+ const entry = createCacheEntry({ name: 'test' }, 3600);
108
+ await cache.set('test-key', entry);
109
+
110
+ await cache.get('test-key');
111
+ await cache.get('test-key');
112
+
113
+ const stats = await cache.getStats();
114
+
115
+ expect(stats.hits).toBe(2);
116
+ });
117
+ });
118
+
119
+ describe('set', () => {
120
+ it('should store value with TTL', async () => {
121
+ const entry = createCacheEntry({ name: 'test' }, 3600);
122
+
123
+ await cache.set('test-key', entry);
124
+
125
+ expect(mockClient.set).toHaveBeenCalledWith(
126
+ 'test-cache:test-key',
127
+ expect.any(String),
128
+ 'EX',
129
+ expect.any(Number)
130
+ );
131
+ });
132
+
133
+ it('should apply stale-while-revalidate tolerance', async () => {
134
+ const cacheWithSWR = new RedisCache({
135
+ client: mockClient,
136
+ keyPrefix: 'swr-cache',
137
+ staleWhileRevalidate: true,
138
+ staleTolerance: 3
139
+ });
140
+
141
+ const entry = createCacheEntry({ name: 'test' }, 100);
142
+ await cacheWithSWR.set('test-key', entry);
143
+
144
+ // TTL should be 100 * 3 = 300 seconds
145
+ expect(mockClient.set).toHaveBeenCalledWith(
146
+ 'swr-cache:test-key',
147
+ expect.any(String),
148
+ 'EX',
149
+ 300
150
+ );
151
+ });
152
+ });
153
+
154
+ describe('delete', () => {
155
+ it('should delete cached value', async () => {
156
+ const entry = createCacheEntry({ name: 'test' }, 3600);
157
+ await cache.set('test-key', entry);
158
+
159
+ await cache.delete('test-key');
160
+
161
+ expect(mockClient.del).toHaveBeenCalledWith('test-cache:test-key');
162
+ });
163
+ });
164
+
165
+ describe('clear', () => {
166
+ it('should clear all values with prefix', async () => {
167
+ const entry = createCacheEntry({ name: 'test' }, 3600);
168
+ await cache.set('key1', entry);
169
+ await cache.set('key2', entry);
170
+ await cache.set('key3', entry);
171
+
172
+ await cache.clear();
173
+
174
+ expect(mockClient.keys).toHaveBeenCalledWith('test-cache:*');
175
+ });
176
+
177
+ it('should reset stats on clear', async () => {
178
+ await cache.get('miss'); // Create a miss
179
+ await cache.clear();
180
+
181
+ const stats = await cache.getStats();
182
+
183
+ expect(stats.misses).toBe(0);
184
+ expect(stats.hits).toBe(0);
185
+ });
186
+ });
187
+
188
+ describe('has', () => {
189
+ it('should return true for existing key', async () => {
190
+ const entry = createCacheEntry({ name: 'test' }, 3600);
191
+ await cache.set('test-key', entry);
192
+
193
+ const exists = await cache.has('test-key');
194
+
195
+ expect(exists).toBe(true);
196
+ });
197
+
198
+ it('should return false for non-existent key', async () => {
199
+ const exists = await cache.has('nonexistent');
200
+
201
+ expect(exists).toBe(false);
202
+ });
203
+ });
204
+
205
+ describe('getMany', () => {
206
+ it('should get multiple values at once', async () => {
207
+ const entry1 = createCacheEntry({ name: 'test1' }, 3600);
208
+ const entry2 = createCacheEntry({ name: 'test2' }, 3600);
209
+
210
+ await cache.set('key1', entry1);
211
+ await cache.set('key2', entry2);
212
+
213
+ const results = await cache.getMany<{ name: string }>(['key1', 'key2', 'key3']);
214
+
215
+ expect(results.size).toBe(3);
216
+ expect(results.get('key1')?.data.name).toBe('test1');
217
+ expect(results.get('key2')?.data.name).toBe('test2');
218
+ expect(results.get('key3')).toBeNull();
219
+ });
220
+
221
+ it('should handle empty keys array', async () => {
222
+ const results = await cache.getMany([]);
223
+
224
+ expect(results.size).toBe(0);
225
+ });
226
+ });
227
+
228
+ describe('setMany', () => {
229
+ it('should set multiple values at once', async () => {
230
+ const entries = new Map([
231
+ ['key1', createCacheEntry({ name: 'test1' }, 3600)],
232
+ ['key2', createCacheEntry({ name: 'test2' }, 3600)]
233
+ ]);
234
+
235
+ await cache.setMany(entries);
236
+
237
+ const result1 = await cache.get<{ name: string }>('key1');
238
+ const result2 = await cache.get<{ name: string }>('key2');
239
+
240
+ expect(result1?.data.name).toBe('test1');
241
+ expect(result2?.data.name).toBe('test2');
242
+ });
243
+
244
+ it('should handle empty entries map', async () => {
245
+ await cache.setMany(new Map());
246
+
247
+ // Should not throw
248
+ expect(true).toBe(true);
249
+ });
250
+ });
251
+
252
+ describe('getStats', () => {
253
+ it('should return cache statistics', async () => {
254
+ const entry = createCacheEntry({ name: 'test' }, 3600);
255
+ await cache.set('key1', entry);
256
+
257
+ await cache.get('key1'); // Hit
258
+ await cache.get('key2'); // Miss
259
+
260
+ const stats = await cache.getStats();
261
+
262
+ expect(stats.hits).toBe(1);
263
+ expect(stats.misses).toBe(1);
264
+ expect(stats.hitRatio).toBe(0.5);
265
+ });
266
+
267
+ it('should return size from dbsize', async () => {
268
+ const stats = await cache.getStats();
269
+
270
+ expect(mockClient.dbsize).toHaveBeenCalled();
271
+ });
272
+
273
+ it('should return bytes from info', async () => {
274
+ const stats = await cache.getStats();
275
+
276
+ expect(stats.bytes).toBe(1024);
277
+ });
278
+ });
279
+
280
+ describe('close', () => {
281
+ it('should close Redis connection', async () => {
282
+ await cache.close();
283
+
284
+ expect(mockClient.quit).toHaveBeenCalled();
285
+ });
286
+ });
287
+ });
288
+
289
+ describe('createRedisCache', () => {
290
+ it('should create a RedisCache instance', () => {
291
+ const mockClient = createMockRedisClient();
292
+ const cache = createRedisCache({ client: mockClient });
293
+
294
+ expect(cache).toBeInstanceOf(RedisCache);
295
+ });
296
+
297
+ it('should accept configuration options', () => {
298
+ const mockClient = createMockRedisClient();
299
+ const cache = createRedisCache({
300
+ client: mockClient,
301
+ keyPrefix: 'custom-prefix',
302
+ defaultTTL: 7200
303
+ });
304
+
305
+ expect(cache).toBeInstanceOf(RedisCache);
306
+ });
307
+ });
@@ -0,0 +1,252 @@
1
+ /**
2
+ * @fileoverview Unit tests for Rust extractor
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach } from 'vitest';
6
+ import { RustExtractor } from '../extractors/rust-extractor';
7
+
8
+ describe('RustExtractor', () => {
9
+ let extractor: RustExtractor;
10
+
11
+ beforeEach(() => {
12
+ extractor = new RustExtractor();
13
+ });
14
+
15
+ describe('extract', () => {
16
+ describe('Actix-web routes', () => {
17
+ it('should extract GET routes', async () => {
18
+ const code = `
19
+ use actix_web::{get, web, HttpResponse};
20
+
21
+ #[get("/users/{id}")]
22
+ async fn get_user(path: web::Path<String>) -> HttpResponse {
23
+ HttpResponse::Ok().finish()
24
+ }
25
+ `;
26
+
27
+ const tools = await extractor.extract(code, 'handlers.rs');
28
+
29
+ expect(tools.length).toBeGreaterThan(0);
30
+ const tool = tools.find(t => t.name.includes('get_users'));
31
+ expect(tool).toBeDefined();
32
+ expect(tool?.inputSchema.properties).toHaveProperty('id');
33
+ });
34
+
35
+ it('should extract POST routes', async () => {
36
+ const code = `
37
+ use actix_web::{post, web, HttpResponse};
38
+
39
+ #[post("/users")]
40
+ async fn create_user(body: web::Json<CreateUser>) -> HttpResponse {
41
+ HttpResponse::Created().finish()
42
+ }
43
+ `;
44
+
45
+ const tools = await extractor.extract(code, 'handlers.rs');
46
+
47
+ expect(tools.length).toBeGreaterThan(0);
48
+ const tool = tools.find(t => t.name.includes('post_users'));
49
+ expect(tool).toBeDefined();
50
+ });
51
+
52
+ it('should extract web::resource routes', async () => {
53
+ const code = `
54
+ use actix_web::{web, App};
55
+
56
+ fn config(cfg: &mut web::ServiceConfig) {
57
+ cfg.service(
58
+ web::resource("/items")
59
+ .route(web::get().to(list_items))
60
+ .route(web::post().to(create_item))
61
+ );
62
+ }
63
+ `;
64
+
65
+ const tools = await extractor.extract(code, 'config.rs');
66
+
67
+ expect(tools.length).toBeGreaterThan(0);
68
+ });
69
+ });
70
+
71
+ describe('Axum routes', () => {
72
+ it('should extract router routes', async () => {
73
+ const code = `
74
+ use axum::{Router, routing::get};
75
+
76
+ fn create_router() -> Router {
77
+ Router::new()
78
+ .route("/api/users", get(list_users))
79
+ .route("/api/users/:id", get(get_user))
80
+ }
81
+ `;
82
+
83
+ const tools = await extractor.extract(code, 'router.rs');
84
+
85
+ expect(tools.length).toBeGreaterThan(0);
86
+ expect(tools.some(t => t.name.includes('api_users'))).toBe(true);
87
+ });
88
+
89
+ it('should extract debug_handler functions', async () => {
90
+ const code = `
91
+ use axum::debug_handler;
92
+
93
+ #[debug_handler]
94
+ async fn my_handler() -> impl IntoResponse {
95
+ "Hello"
96
+ }
97
+ `;
98
+
99
+ const tools = await extractor.extract(code, 'handlers.rs');
100
+
101
+ expect(tools.some(t => t.name === 'my_handler')).toBe(true);
102
+ });
103
+ });
104
+
105
+ describe('Rocket routes', () => {
106
+ it('should extract Rocket routes with data', async () => {
107
+ const code = `
108
+ use rocket::serde::json::Json;
109
+
110
+ #[post("/users", data = "<user>")]
111
+ async fn create_user(user: Json<CreateUser>) -> Json<User> {
112
+ // Create user
113
+ }
114
+ `;
115
+
116
+ const tools = await extractor.extract(code, 'routes.rs');
117
+
118
+ expect(tools.length).toBeGreaterThan(0);
119
+ const tool = tools.find(t => t.name.includes('post_users'));
120
+ expect(tool).toBeDefined();
121
+ });
122
+ });
123
+
124
+ describe('Public functions', () => {
125
+ it('should extract public functions with doc comments', async () => {
126
+ const code = `
127
+ /// Calculate the sum of two numbers
128
+ ///
129
+ /// # Arguments
130
+ /// * \`a\` - First number
131
+ /// * \`b\` - Second number
132
+ pub fn add(a: i32, b: i32) -> i32 {
133
+ a + b
134
+ }
135
+ `;
136
+
137
+ const tools = await extractor.extract(code, 'math.rs');
138
+
139
+ expect(tools.length).toBeGreaterThan(0);
140
+ const tool = tools.find(t => t.name === 'add');
141
+ expect(tool).toBeDefined();
142
+ expect(tool?.description).toContain('sum');
143
+ });
144
+
145
+ it('should extract async public functions', async () => {
146
+ const code = `
147
+ /// Fetch data from the API
148
+ pub async fn fetch_data(url: String) -> Result<Data, Error> {
149
+ // Fetch data
150
+ }
151
+ `;
152
+
153
+ const tools = await extractor.extract(code, 'client.rs');
154
+
155
+ expect(tools.some(t => t.name === 'fetch_data')).toBe(true);
156
+ });
157
+
158
+ it('should skip functions without documentation', async () => {
159
+ const code = `
160
+ pub fn undocumented_function(x: i32) -> i32 {
161
+ x
162
+ }
163
+
164
+ /// Documented function
165
+ pub fn documented_function(x: i32) -> i32 {
166
+ x
167
+ }
168
+ `;
169
+
170
+ const tools = await extractor.extract(code, 'lib.rs');
171
+
172
+ // Only documented function should be included in public function extraction
173
+ // (but it might also be skipped if not considered useful)
174
+ expect(tools.every(t => t.name !== 'undocumented_function' || t.documentation !== null)).toBe(true);
175
+ });
176
+ });
177
+
178
+ describe('Type conversion', () => {
179
+ it('should convert Rust types to JSON schema types', async () => {
180
+ const code = `
181
+ /// Process data
182
+ pub fn process(
183
+ name: String,
184
+ count: i32,
185
+ enabled: bool,
186
+ items: Vec<String>,
187
+ config: HashMap<String, Value>
188
+ ) -> Result<(), Error> {
189
+ // Process
190
+ }
191
+ `;
192
+
193
+ const tools = await extractor.extract(code, 'processor.rs');
194
+
195
+ const tool = tools.find(t => t.name === 'process');
196
+ expect(tool?.inputSchema.properties.name?.type).toBe('string');
197
+ expect(tool?.inputSchema.properties.count?.type).toBe('integer');
198
+ expect(tool?.inputSchema.properties.enabled?.type).toBe('boolean');
199
+ expect(tool?.inputSchema.properties.items?.type).toBe('array');
200
+ expect(tool?.inputSchema.properties.config?.type).toBe('object');
201
+ });
202
+
203
+ it('should handle Option types', async () => {
204
+ const code = `
205
+ /// Get user with optional email
206
+ pub fn get_user(id: String, email: Option<String>) -> User {
207
+ // Get user
208
+ }
209
+ `;
210
+
211
+ const tools = await extractor.extract(code, 'users.rs');
212
+
213
+ const tool = tools.find(t => t.name === 'get_user');
214
+ // Required should only include 'id', not 'email'
215
+ expect(tool?.inputSchema.required).toContain('id');
216
+ });
217
+ });
218
+
219
+ describe('Path parameter extraction', () => {
220
+ it('should extract path parameters from Actix routes', async () => {
221
+ const code = `
222
+ #[get("/users/{user_id}/posts/{post_id}")]
223
+ async fn get_post(path: web::Path<(String, String)>) -> HttpResponse {
224
+ HttpResponse::Ok().finish()
225
+ }
226
+ `;
227
+
228
+ const tools = await extractor.extract(code, 'handlers.rs');
229
+
230
+ const tool = tools[0];
231
+ expect(tool?.inputSchema.properties).toHaveProperty('user_id');
232
+ expect(tool?.inputSchema.properties).toHaveProperty('post_id');
233
+ expect(tool?.inputSchema.required).toContain('user_id');
234
+ expect(tool?.inputSchema.required).toContain('post_id');
235
+ });
236
+
237
+ it('should extract path parameters from Rocket routes', async () => {
238
+ const code = `
239
+ #[get("/items/<item_id>")]
240
+ fn get_item(item_id: i32) -> String {
241
+ format!("Item {}", item_id)
242
+ }
243
+ `;
244
+
245
+ const tools = await extractor.extract(code, 'routes.rs');
246
+
247
+ const tool = tools[0];
248
+ expect(tool?.inputSchema.properties).toHaveProperty('item_id');
249
+ });
250
+ });
251
+ });
252
+ });