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,246 @@
1
+ /**
2
+ * @fileoverview Base provider interface for git hosting platforms
3
+ * @copyright Copyright (c) 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import type { RepoMetadata, FileContent, ApiSpec } from '../types';
8
+
9
+ /**
10
+ * Repository metadata from the provider
11
+ */
12
+ export interface ProviderRepoMetadata {
13
+ stars: number;
14
+ language: string;
15
+ license?: string;
16
+ description?: string;
17
+ defaultBranch: string;
18
+ forksCount?: number;
19
+ openIssuesCount?: number;
20
+ createdAt?: string;
21
+ updatedAt?: string;
22
+ size?: number;
23
+ topics?: string[];
24
+ }
25
+
26
+ /**
27
+ * Search result from code search
28
+ */
29
+ export interface CodeSearchResult {
30
+ path: string;
31
+ content?: string;
32
+ matchedLines?: Array<{
33
+ lineNumber: number;
34
+ content: string;
35
+ }>;
36
+ sha?: string;
37
+ }
38
+
39
+ /**
40
+ * File tree item
41
+ */
42
+ export interface FileTreeItem {
43
+ path: string;
44
+ type: 'file' | 'dir' | 'tree' | 'blob';
45
+ size?: number;
46
+ sha?: string;
47
+ }
48
+
49
+ /**
50
+ * Base provider interface that all git hosting providers must implement
51
+ */
52
+ export interface BaseProvider {
53
+ /**
54
+ * Provider name (e.g., 'github', 'gitlab', 'bitbucket')
55
+ */
56
+ readonly name: string;
57
+
58
+ /**
59
+ * Parse a URL to extract repository metadata
60
+ */
61
+ parseUrl(url: string): RepoMetadata;
62
+
63
+ /**
64
+ * Get repository metadata
65
+ */
66
+ getRepoMetadata(owner: string, repo: string): Promise<ProviderRepoMetadata>;
67
+
68
+ /**
69
+ * Get README content from the repository
70
+ */
71
+ getReadme(owner: string, repo: string, branch?: string): Promise<string | null>;
72
+
73
+ /**
74
+ * Get file content from the repository
75
+ */
76
+ getFile(owner: string, repo: string, path: string, branch?: string): Promise<FileContent | null>;
77
+
78
+ /**
79
+ * List files in a directory
80
+ */
81
+ listFiles(owner: string, repo: string, path?: string, branch?: string): Promise<FileTreeItem[]>;
82
+
83
+ /**
84
+ * Search for code in the repository
85
+ */
86
+ searchCode(owner: string, repo: string, query: string, options?: SearchOptions): Promise<CodeSearchResult[]>;
87
+
88
+ /**
89
+ * Find API specification files
90
+ */
91
+ findApiSpecs?(owner: string, repo: string, branch?: string): Promise<ApiSpec[]>;
92
+
93
+ /**
94
+ * Get rate limit information
95
+ */
96
+ getRateLimit?(): Promise<RateLimitInfo>;
97
+ }
98
+
99
+ /**
100
+ * Options for code search
101
+ */
102
+ export interface SearchOptions {
103
+ /** Maximum results to return */
104
+ maxResults?: number;
105
+ /** File extensions to filter */
106
+ extensions?: string[];
107
+ /** Paths to search in */
108
+ paths?: string[];
109
+ /** Branch to search in */
110
+ branch?: string;
111
+ }
112
+
113
+ /**
114
+ * Rate limit information
115
+ */
116
+ export interface RateLimitInfo {
117
+ remaining: number;
118
+ limit: number;
119
+ reset: Date;
120
+ }
121
+
122
+ /**
123
+ * Provider configuration
124
+ */
125
+ export interface ProviderConfig {
126
+ /** Authentication token */
127
+ token?: string;
128
+ /** Base URL for self-hosted instances */
129
+ baseUrl?: string;
130
+ /** Request timeout in milliseconds */
131
+ timeout?: number;
132
+ /** Custom headers */
133
+ headers?: Record<string, string>;
134
+ }
135
+
136
+ /**
137
+ * Abstract base class with common functionality
138
+ */
139
+ export abstract class AbstractProvider implements BaseProvider {
140
+ abstract readonly name: string;
141
+ protected config: ProviderConfig;
142
+
143
+ constructor(config: ProviderConfig = {}) {
144
+ this.config = {
145
+ timeout: 30000,
146
+ ...config
147
+ };
148
+ }
149
+
150
+ abstract parseUrl(url: string): RepoMetadata;
151
+ abstract getRepoMetadata(owner: string, repo: string): Promise<ProviderRepoMetadata>;
152
+ abstract getReadme(owner: string, repo: string, branch?: string): Promise<string | null>;
153
+ abstract getFile(owner: string, repo: string, path: string, branch?: string): Promise<FileContent | null>;
154
+ abstract listFiles(owner: string, repo: string, path?: string, branch?: string): Promise<FileTreeItem[]>;
155
+ abstract searchCode(owner: string, repo: string, query: string, options?: SearchOptions): Promise<CodeSearchResult[]>;
156
+
157
+ /**
158
+ * Common method to fetch with timeout
159
+ */
160
+ protected async fetchWithTimeout(url: string, options: RequestInit = {}): Promise<Response> {
161
+ const controller = new AbortController();
162
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
163
+
164
+ try {
165
+ const response = await fetch(url, {
166
+ ...options,
167
+ signal: controller.signal,
168
+ headers: {
169
+ ...this.config.headers,
170
+ ...options.headers
171
+ }
172
+ });
173
+
174
+ return response;
175
+ } finally {
176
+ clearTimeout(timeoutId);
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Get authorization header
182
+ */
183
+ protected getAuthHeader(): Record<string, string> {
184
+ if (!this.config.token) {
185
+ return {};
186
+ }
187
+ return { Authorization: `Bearer ${this.config.token}` };
188
+ }
189
+
190
+ /**
191
+ * Common README file names to search
192
+ */
193
+ protected readonly readmeFileNames = [
194
+ 'README.md',
195
+ 'README.MD',
196
+ 'readme.md',
197
+ 'Readme.md',
198
+ 'README.rst',
199
+ 'readme.rst',
200
+ 'README.txt',
201
+ 'readme.txt',
202
+ 'README'
203
+ ];
204
+
205
+ /**
206
+ * Common API spec locations
207
+ */
208
+ protected readonly apiSpecLocations = [
209
+ 'openapi.json',
210
+ 'openapi.yaml',
211
+ 'openapi.yml',
212
+ 'swagger.json',
213
+ 'swagger.yaml',
214
+ 'swagger.yml',
215
+ 'api/openapi.json',
216
+ 'api/openapi.yaml',
217
+ 'api/swagger.json',
218
+ 'api/swagger.yaml',
219
+ 'spec/openapi.json',
220
+ 'spec/openapi.yaml',
221
+ 'docs/openapi.json',
222
+ 'docs/openapi.yaml',
223
+ '.well-known/openapi.json'
224
+ ];
225
+ }
226
+
227
+ /**
228
+ * Detect provider from URL
229
+ */
230
+ export function detectProvider(url: string): 'github' | 'gitlab' | 'bitbucket' | 'unknown' {
231
+ const lowerUrl = url.toLowerCase();
232
+
233
+ if (lowerUrl.includes('github.com') || lowerUrl.includes('github.')) {
234
+ return 'github';
235
+ }
236
+
237
+ if (lowerUrl.includes('gitlab.com') || lowerUrl.includes('gitlab.')) {
238
+ return 'gitlab';
239
+ }
240
+
241
+ if (lowerUrl.includes('bitbucket.org') || lowerUrl.includes('bitbucket.')) {
242
+ return 'bitbucket';
243
+ }
244
+
245
+ return 'unknown';
246
+ }
@@ -0,0 +1,464 @@
1
+ /**
2
+ * @fileoverview Bitbucket API client implementing BaseProvider
3
+ * @copyright Copyright (c) 2024-2026 nirholas
4
+ * @license MIT
5
+ */
6
+
7
+ import {
8
+ AbstractProvider,
9
+ ProviderConfig,
10
+ ProviderRepoMetadata,
11
+ CodeSearchResult,
12
+ FileTreeItem,
13
+ SearchOptions,
14
+ RateLimitInfo
15
+ } from './base-provider';
16
+ import type { RepoMetadata, FileContent, ApiSpec } from '../types';
17
+
18
+ /**
19
+ * Bitbucket API response interfaces
20
+ */
21
+ interface BitbucketRepository {
22
+ uuid: string;
23
+ name: string;
24
+ full_name: string;
25
+ description: string;
26
+ language: string;
27
+ mainbranch?: {
28
+ name: string;
29
+ type: string;
30
+ };
31
+ created_on: string;
32
+ updated_on: string;
33
+ size: number;
34
+ is_private: boolean;
35
+ fork_policy: string;
36
+ links: {
37
+ watchers: { href: string };
38
+ forks: { href: string };
39
+ };
40
+ }
41
+
42
+ interface BitbucketFile {
43
+ path: string;
44
+ type: 'commit_file' | 'commit_directory';
45
+ size?: number;
46
+ commit: {
47
+ hash: string;
48
+ };
49
+ links: {
50
+ self: { href: string };
51
+ };
52
+ }
53
+
54
+ interface BitbucketTreeResponse {
55
+ values: BitbucketFile[];
56
+ pagelen: number;
57
+ page?: number;
58
+ next?: string;
59
+ }
60
+
61
+ interface BitbucketSearchResult {
62
+ type: string;
63
+ content_match_count: number;
64
+ path_matches: Array<{
65
+ text: string;
66
+ match: boolean;
67
+ }>;
68
+ file: {
69
+ path: string;
70
+ type: string;
71
+ links: {
72
+ self: { href: string };
73
+ };
74
+ };
75
+ content_matches?: Array<{
76
+ lines: Array<{
77
+ line: number;
78
+ segments: Array<{
79
+ text: string;
80
+ match: boolean;
81
+ }>;
82
+ }>;
83
+ }>;
84
+ }
85
+
86
+ /**
87
+ * Bitbucket provider implementation
88
+ */
89
+ export class BitbucketClient extends AbstractProvider {
90
+ readonly name = 'bitbucket';
91
+ private baseUrl: string;
92
+
93
+ constructor(config: ProviderConfig = {}) {
94
+ super(config);
95
+ this.baseUrl = config.baseUrl || 'https://api.bitbucket.org/2.0';
96
+ }
97
+
98
+ /**
99
+ * Parse Bitbucket URL to extract workspace and repo
100
+ */
101
+ parseUrl(url: string): RepoMetadata {
102
+ // Format: bitbucket.org/workspace/repo
103
+ // With path: bitbucket.org/workspace/repo/src/branch/path
104
+
105
+ // Handle src/branch/path pattern
106
+ const srcMatch = url.match(/bitbucket\.org\/([^\/]+)\/([^\/]+)\/src\/([^\/]+)(?:\/(.*))?$/);
107
+ if (srcMatch) {
108
+ return {
109
+ owner: srcMatch[1],
110
+ repo: srcMatch[2],
111
+ branch: srcMatch[3],
112
+ path: srcMatch[4]
113
+ };
114
+ }
115
+
116
+ // Simple format: bitbucket.org/workspace/repo
117
+ const simpleMatch = url.match(/bitbucket\.org\/([^\/]+)\/([^\/]+)(?:\.git)?(?:\/|$|\?|#)/);
118
+ if (simpleMatch) {
119
+ return {
120
+ owner: simpleMatch[1],
121
+ repo: simpleMatch[2].replace(/\.git$/, ''),
122
+ branch: 'main'
123
+ };
124
+ }
125
+
126
+ throw new Error(`Invalid Bitbucket URL: ${url}`);
127
+ }
128
+
129
+ /**
130
+ * Get authorization header for Bitbucket
131
+ * Bitbucket uses different auth format for app passwords
132
+ */
133
+ protected override getAuthHeader(): Record<string, string> {
134
+ if (!this.config.token) {
135
+ return {};
136
+ }
137
+ // Check if it's a username:app_password format
138
+ if (this.config.token.includes(':')) {
139
+ const encoded = Buffer.from(this.config.token).toString('base64');
140
+ return { Authorization: `Basic ${encoded}` };
141
+ }
142
+ return { Authorization: `Bearer ${this.config.token}` };
143
+ }
144
+
145
+ /**
146
+ * Get repository metadata
147
+ */
148
+ async getRepoMetadata(owner: string, repo: string): Promise<ProviderRepoMetadata> {
149
+ const url = `${this.baseUrl}/repositories/${owner}/${repo}`;
150
+
151
+ const response = await this.fetchWithTimeout(url, {
152
+ headers: {
153
+ ...this.getAuthHeader(),
154
+ 'Content-Type': 'application/json'
155
+ }
156
+ });
157
+
158
+ if (!response.ok) {
159
+ throw new Error(`Bitbucket API error: ${response.status} ${response.statusText}`);
160
+ }
161
+
162
+ const repository = await response.json() as BitbucketRepository;
163
+
164
+ // Get watchers count (requires separate request)
165
+ let stars = 0;
166
+ try {
167
+ const watchersResponse = await this.fetchWithTimeout(repository.links.watchers.href, {
168
+ headers: this.getAuthHeader()
169
+ });
170
+ if (watchersResponse.ok) {
171
+ const watchersData = await watchersResponse.json();
172
+ stars = (watchersData as { size?: number }).size || 0;
173
+ }
174
+ } catch {
175
+ // Ignore watchers count error
176
+ }
177
+
178
+ return {
179
+ stars,
180
+ language: repository.language || 'unknown',
181
+ description: repository.description || undefined,
182
+ defaultBranch: repository.mainbranch?.name || 'main',
183
+ createdAt: repository.created_on,
184
+ updatedAt: repository.updated_on,
185
+ size: repository.size
186
+ };
187
+ }
188
+
189
+ /**
190
+ * Get README content
191
+ */
192
+ async getReadme(owner: string, repo: string, branch?: string): Promise<string | null> {
193
+ for (const filename of this.readmeFileNames) {
194
+ const file = await this.getFile(owner, repo, filename, branch);
195
+ if (file) {
196
+ return file.content;
197
+ }
198
+ }
199
+ return null;
200
+ }
201
+
202
+ /**
203
+ * Get file content
204
+ */
205
+ async getFile(owner: string, repo: string, path: string, branch?: string): Promise<FileContent | null> {
206
+ const ref = branch || 'main';
207
+ const url = `${this.baseUrl}/repositories/${owner}/${repo}/src/${ref}/${path}`;
208
+
209
+ try {
210
+ const response = await this.fetchWithTimeout(url, {
211
+ headers: {
212
+ ...this.getAuthHeader(),
213
+ 'Accept': 'text/plain'
214
+ }
215
+ });
216
+
217
+ if (!response.ok) {
218
+ return null;
219
+ }
220
+
221
+ const content = await response.text();
222
+
223
+ // Get file metadata
224
+ const metaUrl = `${this.baseUrl}/repositories/${owner}/${repo}/src/${ref}/${path}?format=meta`;
225
+ let sha = '';
226
+ try {
227
+ const metaResponse = await this.fetchWithTimeout(metaUrl, {
228
+ headers: this.getAuthHeader()
229
+ });
230
+ if (metaResponse.ok) {
231
+ const meta = await metaResponse.json();
232
+ sha = (meta as { commit?: { hash?: string } }).commit?.hash || '';
233
+ }
234
+ } catch {
235
+ // Ignore metadata error
236
+ }
237
+
238
+ return {
239
+ path,
240
+ content,
241
+ type: 'file',
242
+ sha
243
+ };
244
+ } catch (error) {
245
+ return null;
246
+ }
247
+ }
248
+
249
+ /**
250
+ * List files in a directory
251
+ */
252
+ async listFiles(owner: string, repo: string, path: string = '', branch?: string): Promise<FileTreeItem[]> {
253
+ const ref = branch || 'main';
254
+ let url = `${this.baseUrl}/repositories/${owner}/${repo}/src/${ref}/`;
255
+ if (path) {
256
+ url += `${path}/`;
257
+ }
258
+
259
+ try {
260
+ const response = await this.fetchWithTimeout(url, {
261
+ headers: {
262
+ ...this.getAuthHeader(),
263
+ 'Content-Type': 'application/json'
264
+ }
265
+ });
266
+
267
+ if (!response.ok) {
268
+ return [];
269
+ }
270
+
271
+ const data = await response.json() as BitbucketTreeResponse;
272
+
273
+ return data.values.map(item => ({
274
+ path: item.path,
275
+ type: item.type === 'commit_directory' ? 'dir' : 'file',
276
+ size: item.size,
277
+ sha: item.commit?.hash
278
+ }));
279
+ } catch (error) {
280
+ return [];
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Search for code in the repository
286
+ */
287
+ async searchCode(owner: string, repo: string, query: string, options: SearchOptions = {}): Promise<CodeSearchResult[]> {
288
+ // Bitbucket Code Search API
289
+ const maxResults = options.maxResults || 20;
290
+ const url = `${this.baseUrl}/repositories/${owner}/${repo}/search/code?search_query=${encodeURIComponent(query)}&pagelen=${maxResults}`;
291
+
292
+ try {
293
+ const response = await this.fetchWithTimeout(url, {
294
+ headers: {
295
+ ...this.getAuthHeader(),
296
+ 'Content-Type': 'application/json'
297
+ }
298
+ });
299
+
300
+ if (!response.ok) {
301
+ // Fallback to manual search if code search API is not available
302
+ return this.manualSearch(owner, repo, query, options);
303
+ }
304
+
305
+ const data = await response.json();
306
+ const results = (data as { values?: BitbucketSearchResult[] }).values || [];
307
+
308
+ return results
309
+ .filter(result => {
310
+ const filePath = result.file.path;
311
+
312
+ // Filter by extensions if specified
313
+ if (options.extensions && options.extensions.length > 0) {
314
+ const ext = filePath.split('.').pop() || '';
315
+ if (!options.extensions.includes(ext)) {
316
+ return false;
317
+ }
318
+ }
319
+
320
+ // Filter by paths if specified
321
+ if (options.paths && options.paths.length > 0) {
322
+ if (!options.paths.some(p => filePath.startsWith(p))) {
323
+ return false;
324
+ }
325
+ }
326
+
327
+ return true;
328
+ })
329
+ .map(result => ({
330
+ path: result.file.path,
331
+ matchedLines: result.content_matches?.flatMap(match =>
332
+ match.lines.map(line => ({
333
+ lineNumber: line.line,
334
+ content: line.segments.map(s => s.text).join('')
335
+ }))
336
+ )
337
+ }));
338
+ } catch (error) {
339
+ return [];
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Manual search fallback (searches through files)
345
+ */
346
+ private async manualSearch(owner: string, repo: string, query: string, options: SearchOptions = {}): Promise<CodeSearchResult[]> {
347
+ const results: CodeSearchResult[] = [];
348
+ const maxResults = options.maxResults || 20;
349
+ const searchRegex = new RegExp(query, 'gi');
350
+
351
+ const searchDir = async (path: string) => {
352
+ if (results.length >= maxResults) return;
353
+
354
+ const files = await this.listFiles(owner, repo, path, options.branch);
355
+
356
+ for (const file of files) {
357
+ if (results.length >= maxResults) break;
358
+
359
+ if (file.type === 'file') {
360
+ // Check extensions filter
361
+ if (options.extensions && options.extensions.length > 0) {
362
+ const ext = file.path.split('.').pop() || '';
363
+ if (!options.extensions.includes(ext)) continue;
364
+ }
365
+
366
+ // Check paths filter
367
+ if (options.paths && options.paths.length > 0) {
368
+ if (!options.paths.some(p => file.path.startsWith(p))) continue;
369
+ }
370
+
371
+ const content = await this.getFile(owner, repo, file.path, options.branch);
372
+ if (content && searchRegex.test(content.content)) {
373
+ const lines = content.content.split('\n');
374
+ const matchedLines: Array<{ lineNumber: number; content: string }> = [];
375
+
376
+ lines.forEach((line, index) => {
377
+ if (searchRegex.test(line)) {
378
+ matchedLines.push({ lineNumber: index + 1, content: line });
379
+ }
380
+ });
381
+
382
+ results.push({
383
+ path: file.path,
384
+ content: content.content,
385
+ matchedLines
386
+ });
387
+ }
388
+ } else if (file.type === 'dir' && (!options.paths || options.paths.some(p => file.path.startsWith(p) || p.startsWith(file.path)))) {
389
+ await searchDir(file.path);
390
+ }
391
+ }
392
+ };
393
+
394
+ await searchDir('');
395
+ return results.slice(0, maxResults);
396
+ }
397
+
398
+ /**
399
+ * Find API specification files
400
+ */
401
+ async findApiSpecs(owner: string, repo: string, branch?: string): Promise<ApiSpec[]> {
402
+ const specs: ApiSpec[] = [];
403
+
404
+ for (const location of this.apiSpecLocations) {
405
+ const file = await this.getFile(owner, repo, location, branch);
406
+ if (file) {
407
+ try {
408
+ const spec = this.parseSpec(file.content, location);
409
+ if (spec) {
410
+ specs.push(spec);
411
+ }
412
+ } catch (error) {
413
+ // Not a valid spec, continue
414
+ }
415
+ }
416
+ }
417
+
418
+ return specs;
419
+ }
420
+
421
+ /**
422
+ * Parse API spec content
423
+ */
424
+ private parseSpec(content: string, path: string): ApiSpec | null {
425
+ try {
426
+ const spec = JSON.parse(content);
427
+
428
+ let type: 'openapi' | 'swagger' = 'openapi';
429
+ let version = '3.0.0';
430
+
431
+ if (spec.swagger) {
432
+ type = 'swagger';
433
+ version = spec.swagger;
434
+ } else if (spec.openapi) {
435
+ type = 'openapi';
436
+ version = spec.openapi;
437
+ }
438
+
439
+ return { type, version, spec, path };
440
+ } catch {
441
+ // Not JSON, might be YAML - would need yaml parser
442
+ return null;
443
+ }
444
+ }
445
+
446
+ /**
447
+ * Get rate limit information
448
+ * Bitbucket rate limiting is different - mainly based on IP/user
449
+ */
450
+ async getRateLimit(): Promise<RateLimitInfo> {
451
+ // Bitbucket doesn't have a dedicated rate limit endpoint
452
+ // Return estimated values based on their documentation
453
+ return {
454
+ remaining: 1000,
455
+ limit: 1000,
456
+ reset: new Date(Date.now() + 3600000) // 1 hour from now
457
+ };
458
+ }
459
+ }
460
+
461
+ // Export singleton factory
462
+ export function createBitbucketClient(config?: ProviderConfig): BitbucketClient {
463
+ return new BitbucketClient(config);
464
+ }