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,378 @@
1
+ /**
2
+ * @fileoverview Unit tests for code-extractor module
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach } from 'vitest';
6
+ import { CodeExtractor } from '../code-extractor';
7
+
8
+ describe('CodeExtractor', () => {
9
+ let extractor: CodeExtractor;
10
+
11
+ beforeEach(() => {
12
+ extractor = new CodeExtractor();
13
+ });
14
+
15
+ describe('extract', () => {
16
+ it('should extract TypeScript methods from code', async () => {
17
+ const code = `
18
+ export class ApiClient {
19
+ /**
20
+ * Get a user by ID
21
+ */
22
+ async getUser(id: string): Promise<User> {
23
+ return await this.fetch(\`/users/\${id}\`);
24
+ }
25
+ }
26
+ `;
27
+
28
+ const tools = await extractor.extract(code, 'client.ts');
29
+
30
+ expect(tools.length).toBeGreaterThan(0);
31
+ expect(tools[0].name).toBe('get_user');
32
+ expect(tools[0].inputSchema.properties).toHaveProperty('id');
33
+ });
34
+
35
+ it('should extract JavaScript methods', async () => {
36
+ const code = `
37
+ class Client {
38
+ async fetchData(url: string, options: object): boolean {
39
+ return true;
40
+ }
41
+ }
42
+ `;
43
+
44
+ const tools = await extractor.extract(code, 'client.js');
45
+
46
+ expect(tools.length).toBeGreaterThan(0);
47
+ });
48
+
49
+ it('should skip constructor and private methods', async () => {
50
+ const code = `
51
+ class Client {
52
+ constructor(): void {
53
+ // init
54
+ }
55
+
56
+ _privateMethod(data: any): void {
57
+ // private
58
+ }
59
+
60
+ publicMethod(arg: string): string {
61
+ return arg;
62
+ }
63
+ }
64
+ `;
65
+
66
+ const tools = await extractor.extract(code, 'client.ts');
67
+
68
+ const names = tools.map(t => t.name);
69
+ expect(names).not.toContain('constructor');
70
+ expect(names).not.toContain('_private_method');
71
+ });
72
+
73
+ it('should extract Python MCP tools from decorators', async () => {
74
+ const code = `
75
+ @mcp.tool(name="GetWeather", description="Get current weather for a city")
76
+ async def get_weather(city: str, units: str = "metric"):
77
+ """Fetches weather data"""
78
+ pass
79
+
80
+ @server.tool("FetchUser")
81
+ async def fetch_user(user_id: int):
82
+ """Fetch user by ID"""
83
+ pass
84
+ `;
85
+
86
+ const tools = await extractor.extract(code, 'server.py');
87
+
88
+ expect(tools.length).toBe(2);
89
+ expect(tools[0].name).toBe('GetWeather');
90
+ expect(tools[0].description).toBe('Get current weather for a city');
91
+ expect(tools[0].inputSchema.properties).toHaveProperty('city');
92
+ expect(tools[0].inputSchema.properties).toHaveProperty('units');
93
+ expect(tools[0].inputSchema.required).toContain('city');
94
+ expect(tools[0].inputSchema.required).not.toContain('units');
95
+ });
96
+
97
+ it('should handle empty code', async () => {
98
+ const tools = await extractor.extract('', 'empty.ts');
99
+ expect(tools).toEqual([]);
100
+ });
101
+
102
+ it('should handle unsupported file types', async () => {
103
+ const code = `
104
+ public class Main {
105
+ public static void main(String[] args) {
106
+ System.out.println("Hello");
107
+ }
108
+ }
109
+ `;
110
+
111
+ const tools = await extractor.extract(code, 'Main.java');
112
+ expect(tools).toEqual([]);
113
+ });
114
+
115
+ it('should extract JSDoc descriptions', async () => {
116
+ const code = `
117
+ /**
118
+ * Search for items in the database
119
+ * @param query The search query
120
+ */
121
+ async searchItems(query: string, limit: number): Promise<Item[]> {
122
+ return [];
123
+ }
124
+ `;
125
+
126
+ const tools = await extractor.extract(code, 'search.ts');
127
+
128
+ if (tools.length > 0) {
129
+ expect(tools[0].description).toContain('Search');
130
+ }
131
+ });
132
+
133
+ it('should parse parameters correctly', async () => {
134
+ const code = `
135
+ async createResource(
136
+ name: string,
137
+ count?: number,
138
+ options: object = {}
139
+ ): Promise<Resource> {
140
+ return {};
141
+ }
142
+ `;
143
+
144
+ const tools = await extractor.extract(code, 'resource.ts');
145
+
146
+ if (tools.length > 0) {
147
+ const { properties, required } = tools[0].inputSchema;
148
+
149
+ expect(properties).toHaveProperty('name');
150
+ expect(properties).toHaveProperty('count');
151
+ expect(properties).toHaveProperty('options');
152
+ expect(required).toContain('name');
153
+ expect(required).not.toContain('count');
154
+ expect(required).not.toContain('options');
155
+ }
156
+ });
157
+
158
+ it('should extract Python Tool class instantiations', async () => {
159
+ const code = `
160
+ tools = [
161
+ Tool(name="ListFiles", description="List files in a directory"),
162
+ Tool(name="ReadFile", description="Read file contents"),
163
+ ]
164
+ `;
165
+
166
+ const tools = await extractor.extract(code, 'tools.py');
167
+
168
+ expect(tools.length).toBe(2);
169
+ expect(tools[0].name).toBe('ListFiles');
170
+ expect(tools[1].name).toBe('ReadFile');
171
+ });
172
+ });
173
+
174
+ describe('language detection', () => {
175
+ it('should detect TypeScript files', async () => {
176
+ const code = 'const x: string = "test";';
177
+ const tools = await extractor.extract(code, 'test.ts');
178
+ // Should not throw
179
+ expect(Array.isArray(tools)).toBe(true);
180
+ });
181
+
182
+ it('should detect Python files', async () => {
183
+ const code = 'def hello(): pass';
184
+ const tools = await extractor.extract(code, 'test.py');
185
+ expect(Array.isArray(tools)).toBe(true);
186
+ });
187
+
188
+ it('should detect JavaScript files', async () => {
189
+ const code = 'const x = "test";';
190
+ const tools = await extractor.extract(code, 'test.js');
191
+ expect(Array.isArray(tools)).toBe(true);
192
+ });
193
+ });
194
+
195
+ describe('type conversion', () => {
196
+ it('should convert Python types to JSON schema types', async () => {
197
+ const code = `
198
+ @mcp.tool(name="ProcessData", description="Process data")
199
+ async def process(
200
+ text: str,
201
+ count: int,
202
+ ratio: float,
203
+ active: bool,
204
+ items: List[str],
205
+ config: Dict[str, any]
206
+ ):
207
+ pass
208
+ `;
209
+
210
+ const tools = await extractor.extract(code, 'process.py');
211
+
212
+ if (tools.length > 0) {
213
+ const { properties } = tools[0].inputSchema;
214
+ expect(properties.text?.type).toBe('string');
215
+ expect(properties.count?.type).toBe('number');
216
+ expect(properties.ratio?.type).toBe('number');
217
+ expect(properties.active?.type).toBe('boolean');
218
+ expect(properties.items?.type).toBe('array');
219
+ expect(properties.config?.type).toBe('object');
220
+ }
221
+ });
222
+
223
+ it('should handle Optional types correctly', async () => {
224
+ const code = `
225
+ @mcp.tool(name="OptionalTest", description="Test optional types")
226
+ async def test_optional(
227
+ required_str: str,
228
+ optional_str: Optional[str],
229
+ optional_int: Optional[int],
230
+ optional_list: Optional[List[str]]
231
+ ):
232
+ pass
233
+ `;
234
+
235
+ const tools = await extractor.extract(code, 'optional.py');
236
+
237
+ if (tools.length > 0) {
238
+ const { properties } = tools[0].inputSchema;
239
+ expect(properties.required_str?.type).toBe('string');
240
+ expect(properties.optional_str?.type).toBe('string');
241
+ expect(properties.optional_int?.type).toBe('number');
242
+ expect(properties.optional_list?.type).toBe('array');
243
+ }
244
+ });
245
+
246
+ it('should handle Union types correctly', async () => {
247
+ const code = `
248
+ @mcp.tool(name="UnionTest", description="Test union types")
249
+ async def test_union(
250
+ str_or_int: Union[str, int],
251
+ nullable: Union[str, None],
252
+ multi: Union[List[str], Dict[str, int], None]
253
+ ):
254
+ pass
255
+ `;
256
+
257
+ const tools = await extractor.extract(code, 'union.py');
258
+
259
+ if (tools.length > 0) {
260
+ const { properties } = tools[0].inputSchema;
261
+ expect(properties.str_or_int?.type).toBe('string'); // First non-None type
262
+ expect(properties.nullable?.type).toBe('string');
263
+ expect(properties.multi?.type).toBe('array'); // First non-None type is List
264
+ }
265
+ });
266
+
267
+ it('should handle Python 3.10+ union syntax', async () => {
268
+ const code = `
269
+ @mcp.tool(name="NewUnionTest", description="Test new union syntax")
270
+ async def test_new_union(
271
+ value: str | int,
272
+ optional: str | None
273
+ ):
274
+ pass
275
+ `;
276
+
277
+ const tools = await extractor.extract(code, 'new_union.py');
278
+
279
+ if (tools.length > 0) {
280
+ const { properties } = tools[0].inputSchema;
281
+ expect(properties.value?.type).toBe('string');
282
+ expect(properties.optional?.type).toBe('string');
283
+ }
284
+ });
285
+
286
+ it('should handle collection types correctly', async () => {
287
+ const code = `
288
+ @mcp.tool(name="CollectionTest", description="Test collection types")
289
+ async def test_collections(
290
+ my_list: List[int],
291
+ my_set: Set[str],
292
+ my_tuple: Tuple[str, int],
293
+ my_sequence: Sequence[float],
294
+ my_mapping: Mapping[str, Any]
295
+ ):
296
+ pass
297
+ `;
298
+
299
+ const tools = await extractor.extract(code, 'collections.py');
300
+
301
+ if (tools.length > 0) {
302
+ const { properties } = tools[0].inputSchema;
303
+ expect(properties.my_list?.type).toBe('array');
304
+ expect(properties.my_set?.type).toBe('array');
305
+ expect(properties.my_tuple?.type).toBe('array');
306
+ expect(properties.my_sequence?.type).toBe('array');
307
+ expect(properties.my_mapping?.type).toBe('object');
308
+ }
309
+ });
310
+
311
+ it('should handle nested generic types', async () => {
312
+ const code = `
313
+ @mcp.tool(name="NestedTest", description="Test nested generics")
314
+ async def test_nested(
315
+ nested_list: List[List[str]],
316
+ list_of_dicts: List[Dict[str, int]],
317
+ dict_of_lists: Dict[str, List[int]]
318
+ ):
319
+ pass
320
+ `;
321
+
322
+ const tools = await extractor.extract(code, 'nested.py');
323
+
324
+ if (tools.length > 0) {
325
+ const { properties } = tools[0].inputSchema;
326
+ expect(properties.nested_list?.type).toBe('array');
327
+ expect(properties.list_of_dicts?.type).toBe('array');
328
+ expect(properties.dict_of_lists?.type).toBe('object');
329
+ }
330
+ });
331
+
332
+ it('should handle special types correctly', async () => {
333
+ const code = `
334
+ @mcp.tool(name="SpecialTypes", description="Test special types")
335
+ async def test_special(
336
+ any_value: Any,
337
+ path_value: Path,
338
+ uuid_value: UUID,
339
+ datetime_value: datetime,
340
+ bytes_value: bytes
341
+ ):
342
+ pass
343
+ `;
344
+
345
+ const tools = await extractor.extract(code, 'special.py');
346
+
347
+ if (tools.length > 0) {
348
+ const { properties } = tools[0].inputSchema;
349
+ expect(properties.any_value?.type).toBe('object');
350
+ expect(properties.path_value?.type).toBe('string');
351
+ expect(properties.uuid_value?.type).toBe('string');
352
+ expect(properties.datetime_value?.type).toBe('string');
353
+ expect(properties.bytes_value?.type).toBe('string');
354
+ }
355
+ });
356
+
357
+ it('should handle Literal types correctly', async () => {
358
+ const code = `
359
+ @mcp.tool(name="LiteralTest", description="Test literal types")
360
+ async def test_literal(
361
+ status: Literal["active", "inactive"],
362
+ priority: Literal[1, 2, 3],
363
+ flag: Literal[True, False]
364
+ ):
365
+ pass
366
+ `;
367
+
368
+ const tools = await extractor.extract(code, 'literal.py');
369
+
370
+ if (tools.length > 0) {
371
+ const { properties } = tools[0].inputSchema;
372
+ expect(properties.status?.type).toBe('string');
373
+ expect(properties.priority?.type).toBe('number');
374
+ expect(properties.flag?.type).toBe('boolean');
375
+ }
376
+ });
377
+ });
378
+ });
@@ -0,0 +1,255 @@
1
+ /**
2
+ * @fileoverview Unit tests for docker-generator module
3
+ */
4
+
5
+ import { describe, it, expect } from 'vitest';
6
+ import {
7
+ DockerGenerator,
8
+ generateDockerfile,
9
+ generateDockerCompose,
10
+ DockerOptions,
11
+ DockerComposeOptions
12
+ } from '../docker-generator';
13
+ import type { GenerationResult, ExtractedTool, RepoClassification, SourceBreakdown } from '../types';
14
+
15
+ // Mock GenerationResult for testing
16
+ function createMockResult(overrides: Partial<GenerationResult> = {}): GenerationResult {
17
+ return {
18
+ repo: 'owner/test-repo',
19
+ name: 'test-repo',
20
+ tools: [
21
+ {
22
+ name: 'testTool',
23
+ description: 'A test tool',
24
+ inputSchema: { type: 'object', properties: {}, required: [] },
25
+ source: { type: 'readme', file: 'README.md' }
26
+ }
27
+ ],
28
+ sources: [{ type: 'readme', count: 1, files: ['README.md'] }],
29
+ classification: {
30
+ type: 'library',
31
+ confidence: 0.8,
32
+ indicators: ['test']
33
+ },
34
+ metadata: {
35
+ stars: 100,
36
+ language: 'TypeScript',
37
+ license: 'MIT',
38
+ description: 'A test repository'
39
+ },
40
+ generate: () => '',
41
+ save: async () => {},
42
+ download: () => {},
43
+ ...overrides
44
+ };
45
+ }
46
+
47
+ describe('DockerGenerator', () => {
48
+ const generator = new DockerGenerator();
49
+
50
+ describe('generateDockerfile', () => {
51
+ it('should generate TypeScript Dockerfile by default', () => {
52
+ const result = createMockResult();
53
+ const dockerfile = generator.generateDockerfile(result);
54
+
55
+ expect(dockerfile).toContain('FROM node:20-alpine');
56
+ expect(dockerfile).toContain('test-repo');
57
+ expect(dockerfile).toContain('MCP Server');
58
+ expect(dockerfile).toContain('EXPOSE');
59
+ expect(dockerfile).toContain('USER mcpserver');
60
+ });
61
+
62
+ it('should generate Python Dockerfile when specified', () => {
63
+ const result = createMockResult();
64
+ const dockerfile = generator.generateDockerfile(result, 'python');
65
+
66
+ expect(dockerfile).toContain('FROM python:3.11-slim');
67
+ expect(dockerfile).toContain('requirements.txt');
68
+ expect(dockerfile).toContain('CMD ["python", "-m", "mcp_server"]');
69
+ expect(dockerfile).toContain('PYTHONUNBUFFERED=1');
70
+ });
71
+
72
+ it('should include custom base image', () => {
73
+ const result = createMockResult();
74
+ const options: DockerOptions = { baseImage: 'node:18-alpine' };
75
+ const dockerfile = generator.generateDockerfile(result, 'typescript', options);
76
+
77
+ expect(dockerfile).toContain('FROM node:18-alpine');
78
+ });
79
+
80
+ it('should include custom port', () => {
81
+ const result = createMockResult();
82
+ const options: DockerOptions = { port: 8080 };
83
+ const dockerfile = generator.generateDockerfile(result, 'typescript', options);
84
+
85
+ expect(dockerfile).toContain('EXPOSE 8080');
86
+ expect(dockerfile).toContain('PORT=8080');
87
+ });
88
+
89
+ it('should include environment variables', () => {
90
+ const result = createMockResult();
91
+ const options: DockerOptions = {
92
+ env: {
93
+ API_KEY: 'test-key',
94
+ DEBUG: 'true'
95
+ }
96
+ };
97
+ const dockerfile = generator.generateDockerfile(result, 'typescript', options);
98
+
99
+ expect(dockerfile).toContain('ENV API_KEY="test-key"');
100
+ expect(dockerfile).toContain('ENV DEBUG="true"');
101
+ });
102
+
103
+ it('should include custom labels', () => {
104
+ const result = createMockResult();
105
+ const options: DockerOptions = {
106
+ labels: {
107
+ 'com.example.version': '1.0.0'
108
+ }
109
+ };
110
+ const dockerfile = generator.generateDockerfile(result, 'typescript', options);
111
+
112
+ expect(dockerfile).toContain('LABEL com.example.version="1.0.0"');
113
+ });
114
+
115
+ it('should include health check when configured', () => {
116
+ const result = createMockResult();
117
+ const options: DockerOptions = {
118
+ healthCheck: {
119
+ interval: '60s',
120
+ timeout: '20s',
121
+ retries: 5
122
+ }
123
+ };
124
+ const dockerfile = generator.generateDockerfile(result, 'typescript', options);
125
+
126
+ expect(dockerfile).toContain('HEALTHCHECK');
127
+ expect(dockerfile).toContain('--interval=60s');
128
+ expect(dockerfile).toContain('--timeout=20s');
129
+ expect(dockerfile).toContain('--retries=5');
130
+ });
131
+ });
132
+
133
+ describe('generateDockerCompose', () => {
134
+ it('should generate basic Docker Compose file', () => {
135
+ const result = createMockResult();
136
+ const compose = generator.generateDockerCompose(result);
137
+
138
+ expect(compose).toContain('version:');
139
+ expect(compose).toContain('services:');
140
+ expect(compose).toContain('test-repo');
141
+ expect(compose).toContain('networks:');
142
+ expect(compose).toContain('mcp-network');
143
+ });
144
+
145
+ it('should include Redis service when requested', () => {
146
+ const result = createMockResult();
147
+ const options: DockerComposeOptions = { includeRedis: true };
148
+ const compose = generator.generateDockerCompose(result, 'typescript', options);
149
+
150
+ expect(compose).toContain('redis:');
151
+ expect(compose).toContain('redis:7-alpine');
152
+ expect(compose).toContain('redis-data:');
153
+ expect(compose).toContain('REDIS_URL');
154
+ });
155
+
156
+ it('should include custom service name', () => {
157
+ const result = createMockResult();
158
+ const options: DockerComposeOptions = { serviceName: 'my-custom-service' };
159
+ const compose = generator.generateDockerCompose(result, 'typescript', options);
160
+
161
+ expect(compose).toContain('my-custom-service:');
162
+ expect(compose).toContain('my-custom-service-mcp');
163
+ });
164
+
165
+ it('should include custom networks', () => {
166
+ const result = createMockResult();
167
+ const options: DockerComposeOptions = { networks: ['custom-network'] };
168
+ const compose = generator.generateDockerCompose(result, 'typescript', options);
169
+
170
+ expect(compose).toContain('custom-network:');
171
+ });
172
+
173
+ it('should include depends_on when specified', () => {
174
+ const result = createMockResult();
175
+ const options: DockerComposeOptions = {
176
+ dependsOn: ['database', 'cache']
177
+ };
178
+ const compose = generator.generateDockerCompose(result, 'typescript', options);
179
+
180
+ expect(compose).toContain('depends_on:');
181
+ expect(compose).toContain('- database');
182
+ expect(compose).toContain('- cache');
183
+ });
184
+
185
+ it('should generate Python-compatible compose file', () => {
186
+ const result = createMockResult();
187
+ const compose = generator.generateDockerCompose(result, 'python');
188
+
189
+ expect(compose).toContain('python');
190
+ });
191
+ });
192
+
193
+ describe('generateDockerIgnore', () => {
194
+ it('should generate .dockerignore content', () => {
195
+ const dockerignore = generator.generateDockerIgnore();
196
+
197
+ expect(dockerignore).toContain('node_modules/');
198
+ expect(dockerignore).toContain('.git/');
199
+ expect(dockerignore).toContain('.env');
200
+ expect(dockerignore).toContain('*.test.ts');
201
+ expect(dockerignore).toContain('coverage/');
202
+ });
203
+ });
204
+
205
+ describe('generateRequirementsTxt', () => {
206
+ it('should generate Python requirements', () => {
207
+ const result = createMockResult();
208
+ const requirements = generator.generateRequirementsTxt(result);
209
+
210
+ expect(requirements).toContain('mcp>=');
211
+ expect(requirements).toContain('httpx>=');
212
+ expect(requirements).toContain('pydantic>=');
213
+ });
214
+ });
215
+
216
+ describe('generateDockerComposeWithInfra', () => {
217
+ it('should include Traefik when requested', () => {
218
+ const result = createMockResult();
219
+ const compose = generator.generateDockerComposeWithInfra(result, 'typescript', {
220
+ includeTraefik: true
221
+ });
222
+
223
+ expect(compose).toContain('traefik:');
224
+ expect(compose).toContain('traefik:v2.10');
225
+ });
226
+
227
+ it('should include Prometheus when requested', () => {
228
+ const result = createMockResult();
229
+ const compose = generator.generateDockerComposeWithInfra(result, 'typescript', {
230
+ includePrometheus: true
231
+ });
232
+
233
+ expect(compose).toContain('prometheus:');
234
+ expect(compose).toContain('prom/prometheus');
235
+ });
236
+ });
237
+ });
238
+
239
+ describe('Exported functions', () => {
240
+ it('generateDockerfile should work as standalone function', () => {
241
+ const result = createMockResult();
242
+ const dockerfile = generateDockerfile(result);
243
+
244
+ expect(dockerfile).toBeTruthy();
245
+ expect(dockerfile).toContain('FROM');
246
+ });
247
+
248
+ it('generateDockerCompose should work as standalone function', () => {
249
+ const result = createMockResult();
250
+ const compose = generateDockerCompose(result);
251
+
252
+ expect(compose).toBeTruthy();
253
+ expect(compose).toContain('services:');
254
+ });
255
+ });