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,578 @@
1
+ /**
2
+ * @fileoverview Redis-based queue implementation for distributed processing
3
+ * @copyright Copyright (c) 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import type {
8
+ QueueInterface,
9
+ Job,
10
+ JobStatus,
11
+ JobOptions,
12
+ QueueConfig,
13
+ JobHandler,
14
+ QueueStats
15
+ } from './types';
16
+
17
+ /**
18
+ * Redis client interface (compatible with ioredis and node-redis)
19
+ */
20
+ export interface RedisClientInterface {
21
+ get(key: string): Promise<string | null>;
22
+ set(key: string, value: string, ...args: any[]): Promise<any>;
23
+ del(key: string | string[]): Promise<number>;
24
+ keys(pattern: string): Promise<string[]>;
25
+ lpush(key: string, ...values: string[]): Promise<number>;
26
+ rpop(key: string): Promise<string | null>;
27
+ brpop(key: string, timeout: number): Promise<[string, string] | null>;
28
+ llen(key: string): Promise<number>;
29
+ lrange(key: string, start: number, stop: number): Promise<string[]>;
30
+ lrem(key: string, count: number, value: string): Promise<number>;
31
+ zadd(key: string, ...args: (string | number)[]): Promise<number>;
32
+ zrange(key: string, start: number, stop: number): Promise<string[]>;
33
+ zrangebyscore(key: string, min: string | number, max: string | number): Promise<string[]>;
34
+ zrem(key: string, ...members: string[]): Promise<number>;
35
+ zcard(key: string): Promise<number>;
36
+ hset(key: string, field: string, value: string): Promise<number>;
37
+ hget(key: string, field: string): Promise<string | null>;
38
+ hdel(key: string, ...fields: string[]): Promise<number>;
39
+ hlen(key: string): Promise<number>;
40
+ hgetall(key: string): Promise<Record<string, string>>;
41
+ quit(): Promise<any>;
42
+ publish?(channel: string, message: string): Promise<number>;
43
+ subscribe?(channel: string, callback: (message: string) => void): Promise<void>;
44
+ }
45
+
46
+ /**
47
+ * Redis queue configuration
48
+ */
49
+ export interface RedisQueueConfig extends QueueConfig {
50
+ /** Redis client instance */
51
+ client: RedisClientInterface;
52
+ /** Queue name (used as Redis key prefix) */
53
+ queueName?: string;
54
+ /** Use blocking pop for job consumption */
55
+ useBlocking?: boolean;
56
+ /** Blocking timeout in seconds */
57
+ blockingTimeout?: number;
58
+ /** Enable distributed locking */
59
+ enableLocking?: boolean;
60
+ /** Lock TTL in milliseconds */
61
+ lockTTL?: number;
62
+ }
63
+
64
+ /**
65
+ * Redis-based queue implementation
66
+ * Supports distributed processing across multiple workers
67
+ */
68
+ export class RedisQueue<T = unknown> implements QueueInterface<T> {
69
+ private client: RedisClientInterface;
70
+ private config: RedisQueueConfig;
71
+ private handlers: Map<string, JobHandler<T>> = new Map();
72
+ private onCompleteCallbacks: Array<(job: Job<T>) => void> = [];
73
+ private onFailCallbacks: Array<(job: Job<T>, error: Error) => void> = [];
74
+ private isProcessing = false;
75
+ private shouldStop = false;
76
+ private jobCounter = 0;
77
+
78
+ // Redis key prefixes
79
+ private keys: {
80
+ pending: string;
81
+ delayed: string;
82
+ processing: string;
83
+ completed: string;
84
+ failed: string;
85
+ jobs: string;
86
+ locks: string;
87
+ };
88
+
89
+ constructor(config: RedisQueueConfig) {
90
+ this.client = config.client;
91
+ this.config = {
92
+ queueName: 'mcp-queue',
93
+ maxConcurrency: 5,
94
+ defaultPriority: 0,
95
+ maxRetries: 3,
96
+ retryDelay: 1000,
97
+ jobTimeout: 60000,
98
+ useBlocking: true,
99
+ blockingTimeout: 5,
100
+ enableLocking: true,
101
+ lockTTL: 30000,
102
+ ...config
103
+ };
104
+
105
+ const prefix = this.config.queueName!;
106
+ this.keys = {
107
+ pending: `${prefix}:pending`,
108
+ delayed: `${prefix}:delayed`,
109
+ processing: `${prefix}:processing`,
110
+ completed: `${prefix}:completed`,
111
+ failed: `${prefix}:failed`,
112
+ jobs: `${prefix}:jobs`,
113
+ locks: `${prefix}:locks`
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Generate unique job ID
119
+ */
120
+ private generateJobId(): string {
121
+ this.jobCounter++;
122
+ const workerId = process.pid || Math.random().toString(36).substring(2, 6);
123
+ return `job_${Date.now()}_${workerId}_${this.jobCounter}`;
124
+ }
125
+
126
+ /**
127
+ * Serialize job for storage
128
+ */
129
+ private serializeJob(job: Job<T>): string {
130
+ return JSON.stringify({
131
+ ...job,
132
+ createdAt: job.createdAt?.toISOString(),
133
+ updatedAt: job.updatedAt?.toISOString(),
134
+ startedAt: job.startedAt?.toISOString(),
135
+ completedAt: job.completedAt?.toISOString(),
136
+ failedAt: job.failedAt?.toISOString()
137
+ });
138
+ }
139
+
140
+ /**
141
+ * Deserialize job from storage
142
+ */
143
+ private deserializeJob(data: string): Job<T> {
144
+ const parsed = JSON.parse(data);
145
+ return {
146
+ ...parsed,
147
+ createdAt: parsed.createdAt ? new Date(parsed.createdAt) : undefined,
148
+ updatedAt: parsed.updatedAt ? new Date(parsed.updatedAt) : undefined,
149
+ startedAt: parsed.startedAt ? new Date(parsed.startedAt) : undefined,
150
+ completedAt: parsed.completedAt ? new Date(parsed.completedAt) : undefined,
151
+ failedAt: parsed.failedAt ? new Date(parsed.failedAt) : undefined
152
+ };
153
+ }
154
+
155
+ /**
156
+ * Enqueue a new job
157
+ */
158
+ async enqueue(data: T, options: JobOptions = {}): Promise<Job<T>> {
159
+ const job: Job<T> = {
160
+ id: this.generateJobId(),
161
+ data,
162
+ status: 'pending',
163
+ priority: options.priority ?? this.config.defaultPriority ?? 0,
164
+ attempts: 0,
165
+ maxRetries: options.maxRetries ?? this.config.maxRetries ?? 3,
166
+ createdAt: new Date(),
167
+ updatedAt: new Date(),
168
+ delay: options.delay,
169
+ timeout: options.timeout ?? this.config.jobTimeout,
170
+ tags: options.tags,
171
+ metadata: options.metadata
172
+ };
173
+
174
+ // Store job data
175
+ await this.client.hset(this.keys.jobs, job.id, this.serializeJob(job));
176
+
177
+ if (job.delay && job.delay > 0) {
178
+ // Add to delayed set with score = timestamp when it should run
179
+ const runAt = Date.now() + job.delay;
180
+ await this.client.zadd(this.keys.delayed, runAt, job.id);
181
+ } else {
182
+ // Add to pending queue with priority
183
+ await this.addToPendingQueue(job);
184
+ }
185
+
186
+ return job;
187
+ }
188
+
189
+ /**
190
+ * Add job to pending queue with priority
191
+ */
192
+ private async addToPendingQueue(job: Job<T>): Promise<void> {
193
+ // Use sorted set for priority ordering (higher priority = higher score)
194
+ const score = (job.priority || 0) * 1000000000 + (1000000000 - Date.now() % 1000000000);
195
+ await this.client.zadd(this.keys.pending, score, job.id);
196
+ }
197
+
198
+ /**
199
+ * Move delayed jobs to pending queue
200
+ */
201
+ private async processDelayedJobs(): Promise<void> {
202
+ const now = Date.now();
203
+ const jobIds = await this.client.zrangebyscore(this.keys.delayed, '-inf', now);
204
+
205
+ for (const jobId of jobIds) {
206
+ const jobData = await this.client.hget(this.keys.jobs, jobId);
207
+ if (jobData) {
208
+ const job = this.deserializeJob(jobData);
209
+ await this.client.zrem(this.keys.delayed, jobId);
210
+ await this.addToPendingQueue(job);
211
+ }
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Dequeue the next job
217
+ */
218
+ async dequeue(): Promise<Job<T> | null> {
219
+ // Process any delayed jobs first
220
+ await this.processDelayedJobs();
221
+
222
+ // Get highest priority job
223
+ const jobIds = await this.client.zrange(this.keys.pending, -1, -1);
224
+ if (jobIds.length === 0) return null;
225
+
226
+ const jobId = jobIds[0];
227
+
228
+ // Remove from pending
229
+ const removed = await this.client.zrem(this.keys.pending, jobId);
230
+ if (removed === 0) return null; // Another worker got it
231
+
232
+ // Get job data
233
+ const jobData = await this.client.hget(this.keys.jobs, jobId);
234
+ if (!jobData) return null;
235
+
236
+ const job = this.deserializeJob(jobData);
237
+ job.status = 'processing';
238
+ job.startedAt = new Date();
239
+ job.updatedAt = new Date();
240
+ job.attempts++;
241
+
242
+ // Add to processing set
243
+ await this.client.hset(this.keys.processing, jobId, this.serializeJob(job));
244
+ await this.client.hset(this.keys.jobs, jobId, this.serializeJob(job));
245
+
246
+ return job;
247
+ }
248
+
249
+ /**
250
+ * Get job status
251
+ */
252
+ async getStatus(jobId: string): Promise<JobStatus | null> {
253
+ const jobData = await this.client.hget(this.keys.jobs, jobId);
254
+ if (!jobData) return null;
255
+ const job = this.deserializeJob(jobData);
256
+ return job.status;
257
+ }
258
+
259
+ /**
260
+ * Get job by ID
261
+ */
262
+ async getJob(jobId: string): Promise<Job<T> | null> {
263
+ const jobData = await this.client.hget(this.keys.jobs, jobId);
264
+ if (!jobData) return null;
265
+ return this.deserializeJob(jobData);
266
+ }
267
+
268
+ /**
269
+ * Register job completion callback
270
+ */
271
+ onComplete(callback: (job: Job<T>) => void): void {
272
+ this.onCompleteCallbacks.push(callback);
273
+ }
274
+
275
+ /**
276
+ * Register job failure callback
277
+ */
278
+ onFail(callback: (job: Job<T>, error: Error) => void): void {
279
+ this.onFailCallbacks.push(callback);
280
+ }
281
+
282
+ /**
283
+ * Register a job handler
284
+ */
285
+ registerHandler(name: string, handler: JobHandler<T>): void {
286
+ this.handlers.set(name, handler);
287
+ }
288
+
289
+ /**
290
+ * Process jobs with the default handler
291
+ */
292
+ async process(handler: JobHandler<T>): Promise<void> {
293
+ this.handlers.set('default', handler);
294
+ this.shouldStop = false;
295
+ this.processQueue();
296
+ }
297
+
298
+ /**
299
+ * Internal queue processing loop
300
+ */
301
+ private async processQueue(): Promise<void> {
302
+ if (this.isProcessing) return;
303
+ this.isProcessing = true;
304
+
305
+ const maxConcurrency = this.config.maxConcurrency || 5;
306
+ const activeJobs: Promise<void>[] = [];
307
+
308
+ while (!this.shouldStop) {
309
+ // Wait for a slot if at max concurrency
310
+ while (activeJobs.length >= maxConcurrency) {
311
+ await Promise.race(activeJobs);
312
+ // Remove completed promises
313
+ for (let i = activeJobs.length - 1; i >= 0; i--) {
314
+ const job = activeJobs[i];
315
+ if (await Promise.race([job.then(() => true), Promise.resolve(false)])) {
316
+ activeJobs.splice(i, 1);
317
+ }
318
+ }
319
+ }
320
+
321
+ const job = await this.dequeue();
322
+ if (!job) {
323
+ // No jobs, wait a bit
324
+ await new Promise(resolve => setTimeout(resolve, 100));
325
+ continue;
326
+ }
327
+
328
+ const jobPromise = this.processJob(job);
329
+ activeJobs.push(jobPromise);
330
+ }
331
+
332
+ // Wait for all active jobs to complete
333
+ await Promise.all(activeJobs);
334
+ this.isProcessing = false;
335
+ }
336
+
337
+ /**
338
+ * Process a single job
339
+ */
340
+ private async processJob(job: Job<T>): Promise<void> {
341
+ const handler = this.handlers.get('default');
342
+ if (!handler) {
343
+ console.warn('No handler registered for job processing');
344
+ return;
345
+ }
346
+
347
+ // Set up timeout
348
+ let timeoutId: NodeJS.Timeout | undefined;
349
+ const timeoutPromise = new Promise<never>((_, reject) => {
350
+ if (job.timeout) {
351
+ timeoutId = setTimeout(() => {
352
+ reject(new Error(`Job ${job.id} timed out after ${job.timeout}ms`));
353
+ }, job.timeout);
354
+ }
355
+ });
356
+
357
+ try {
358
+ const result = await Promise.race([
359
+ handler(job),
360
+ timeoutPromise
361
+ ]);
362
+
363
+ if (timeoutId) clearTimeout(timeoutId);
364
+
365
+ // Job completed successfully
366
+ job.status = 'completed';
367
+ job.result = result;
368
+ job.completedAt = new Date();
369
+ job.updatedAt = new Date();
370
+
371
+ // Move to completed
372
+ await this.client.hdel(this.keys.processing, job.id);
373
+ await this.client.zadd(this.keys.completed, Date.now(), job.id);
374
+ await this.client.hset(this.keys.jobs, job.id, this.serializeJob(job));
375
+
376
+ // Notify callbacks
377
+ this.onCompleteCallbacks.forEach(cb => {
378
+ try {
379
+ cb(job);
380
+ } catch (err) {
381
+ console.error('Error in onComplete callback:', err);
382
+ }
383
+ });
384
+
385
+ } catch (error) {
386
+ if (timeoutId) clearTimeout(timeoutId);
387
+
388
+ const err = error instanceof Error ? error : new Error(String(error));
389
+ job.error = err.message;
390
+ job.updatedAt = new Date();
391
+
392
+ await this.client.hdel(this.keys.processing, job.id);
393
+
394
+ // Check if we should retry
395
+ if (job.attempts < (job.maxRetries || 0)) {
396
+ job.status = 'pending';
397
+ const retryDelay = this.config.retryDelay || 1000;
398
+ const backoffDelay = retryDelay * Math.pow(2, job.attempts - 1);
399
+
400
+ // Add to delayed queue for retry
401
+ const runAt = Date.now() + backoffDelay;
402
+ await this.client.zadd(this.keys.delayed, runAt, job.id);
403
+ await this.client.hset(this.keys.jobs, job.id, this.serializeJob(job));
404
+
405
+ } else {
406
+ // Mark as failed
407
+ job.status = 'failed';
408
+ job.failedAt = new Date();
409
+ await this.client.zadd(this.keys.failed, Date.now(), job.id);
410
+ await this.client.hset(this.keys.jobs, job.id, this.serializeJob(job));
411
+
412
+ // Notify callbacks
413
+ this.onFailCallbacks.forEach(cb => {
414
+ try {
415
+ cb(job, err);
416
+ } catch (callbackErr) {
417
+ console.error('Error in onFail callback:', callbackErr);
418
+ }
419
+ });
420
+ }
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Cancel a job
426
+ */
427
+ async cancel(jobId: string): Promise<boolean> {
428
+ const job = await this.getJob(jobId);
429
+ if (!job) return false;
430
+
431
+ if (job.status === 'pending') {
432
+ job.status = 'cancelled';
433
+ job.updatedAt = new Date();
434
+ await this.client.zrem(this.keys.pending, jobId);
435
+ await this.client.hset(this.keys.jobs, jobId, this.serializeJob(job));
436
+ return true;
437
+ }
438
+
439
+ return false;
440
+ }
441
+
442
+ /**
443
+ * Retry a failed job
444
+ */
445
+ async retry(jobId: string): Promise<Job<T> | null> {
446
+ const job = await this.getJob(jobId);
447
+ if (!job || job.status !== 'failed') return null;
448
+
449
+ job.status = 'pending';
450
+ job.attempts = 0;
451
+ job.error = undefined;
452
+ job.failedAt = undefined;
453
+ job.updatedAt = new Date();
454
+
455
+ await this.client.zrem(this.keys.failed, jobId);
456
+ await this.addToPendingQueue(job);
457
+ await this.client.hset(this.keys.jobs, jobId, this.serializeJob(job));
458
+
459
+ return job;
460
+ }
461
+
462
+ /**
463
+ * Get queue statistics
464
+ */
465
+ async getStats(): Promise<QueueStats> {
466
+ const [pending, processing, completed, failed] = await Promise.all([
467
+ this.client.zcard(this.keys.pending),
468
+ this.client.hlen(this.keys.processing),
469
+ this.client.zcard(this.keys.completed),
470
+ this.client.zcard(this.keys.failed)
471
+ ]);
472
+
473
+ return {
474
+ pending,
475
+ processing,
476
+ completed,
477
+ failed,
478
+ total: pending + processing + completed + failed
479
+ };
480
+ }
481
+
482
+ /**
483
+ * Get jobs by status
484
+ */
485
+ async getJobsByStatus(status: JobStatus, limit: number = 100): Promise<Job<T>[]> {
486
+ let jobIds: string[] = [];
487
+
488
+ switch (status) {
489
+ case 'pending':
490
+ jobIds = await this.client.zrange(this.keys.pending, -limit, -1);
491
+ break;
492
+ case 'processing':
493
+ const processingData = await this.client.hgetall(this.keys.processing);
494
+ jobIds = Object.keys(processingData).slice(0, limit);
495
+ break;
496
+ case 'completed':
497
+ jobIds = await this.client.zrange(this.keys.completed, -limit, -1);
498
+ break;
499
+ case 'failed':
500
+ jobIds = await this.client.zrange(this.keys.failed, -limit, -1);
501
+ break;
502
+ }
503
+
504
+ const jobs: Job<T>[] = [];
505
+ for (const jobId of jobIds) {
506
+ const job = await this.getJob(jobId);
507
+ if (job) jobs.push(job);
508
+ }
509
+
510
+ return jobs;
511
+ }
512
+
513
+ /**
514
+ * Clear completed jobs
515
+ */
516
+ async clearCompleted(): Promise<number> {
517
+ const jobIds = await this.client.zrange(this.keys.completed, 0, -1);
518
+ if (jobIds.length === 0) return 0;
519
+
520
+ await this.client.del(this.keys.completed);
521
+ for (const jobId of jobIds) {
522
+ await this.client.hdel(this.keys.jobs, jobId);
523
+ }
524
+
525
+ return jobIds.length;
526
+ }
527
+
528
+ /**
529
+ * Clear failed jobs
530
+ */
531
+ async clearFailed(): Promise<number> {
532
+ const jobIds = await this.client.zrange(this.keys.failed, 0, -1);
533
+ if (jobIds.length === 0) return 0;
534
+
535
+ await this.client.del(this.keys.failed);
536
+ for (const jobId of jobIds) {
537
+ await this.client.hdel(this.keys.jobs, jobId);
538
+ }
539
+
540
+ return jobIds.length;
541
+ }
542
+
543
+ /**
544
+ * Pause the queue
545
+ */
546
+ async pause(): Promise<void> {
547
+ this.shouldStop = true;
548
+ }
549
+
550
+ /**
551
+ * Resume the queue
552
+ */
553
+ async resume(): Promise<void> {
554
+ this.shouldStop = false;
555
+ if (!this.isProcessing && this.handlers.has('default')) {
556
+ this.processQueue();
557
+ }
558
+ }
559
+
560
+ /**
561
+ * Close the queue
562
+ */
563
+ async close(): Promise<void> {
564
+ this.shouldStop = true;
565
+ // Wait for processing to complete
566
+ while (this.isProcessing) {
567
+ await new Promise(resolve => setTimeout(resolve, 100));
568
+ }
569
+ await this.client.quit();
570
+ }
571
+ }
572
+
573
+ /**
574
+ * Create a Redis queue instance
575
+ */
576
+ export function createRedisQueue<T = unknown>(config: RedisQueueConfig): RedisQueue<T> {
577
+ return new RedisQueue<T>(config);
578
+ }