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.
- package/.env.example +8 -0
- package/.github/CODEOWNERS +6 -0
- package/.husky/pre-commit +1 -0
- package/.nvmrc +1 -0
- package/.prettierignore +5 -0
- package/.prettierrc +7 -0
- package/.vscode/settings.json +4 -0
- package/ARCHITECTURE.md +1429 -0
- package/CHANGELOG.md +167 -0
- package/CONTRIBUTING.md +327 -0
- package/LICENSE +201 -0
- package/README.md +1028 -0
- package/SECURITY.md +248 -0
- package/VISUAL_GUIDE.md +437 -0
- package/apps/vscode/IMPLEMENTATION.md +480 -0
- package/apps/vscode/README.md +248 -0
- package/apps/vscode/package.json +381 -0
- package/apps/vscode/resources/icon.png +0 -0
- package/apps/vscode/resources/icon.svg +5 -0
- package/apps/vscode/src/commands/browseRegistry.ts +211 -0
- package/apps/vscode/src/commands/configureClaudeDesktop.ts +332 -0
- package/apps/vscode/src/commands/convert.ts +82 -0
- package/apps/vscode/src/commands/convertCurrentRepo.ts +109 -0
- package/apps/vscode/src/commands/convertFromUrl.ts +138 -0
- package/apps/vscode/src/commands/index.ts +121 -0
- package/apps/vscode/src/commands/validate.ts +197 -0
- package/apps/vscode/src/extension.ts +464 -0
- package/apps/vscode/src/global.d.ts +36 -0
- package/apps/vscode/src/test/extension.test.ts +73 -0
- package/apps/vscode/src/utils/file-generator.ts +529 -0
- package/apps/vscode/src/utils/github-api.ts +335 -0
- package/apps/vscode/src/utils/index.ts +29 -0
- package/apps/vscode/src/utils/mcp-config.ts +334 -0
- package/apps/vscode/src/utils/storage.ts +87 -0
- package/apps/vscode/src/views/McpServersTreeView.ts +160 -0
- package/apps/vscode/src/views/OutputChannelView.ts +195 -0
- package/apps/vscode/src/views/StatusBarItem.ts +251 -0
- package/apps/vscode/src/views/ToolsExplorerView.ts +314 -0
- package/apps/vscode/src/views/historyProvider.ts +75 -0
- package/apps/vscode/src/views/index.ts +12 -0
- package/apps/vscode/src/views/resultsPanel.ts +330 -0
- package/apps/vscode/src/webviews/ConversionPanel.ts +350 -0
- package/apps/vscode/src/webviews/ToolDetailsPanel.ts +448 -0
- package/apps/vscode/src/webviews/index.ts +9 -0
- package/apps/vscode/src/webviews/webview-ui/styles.ts +492 -0
- package/apps/vscode/tsconfig.json +20 -0
- package/apps/web/PLAYGROUND_GUIDE.md +499 -0
- package/apps/web/README.md +505 -0
- package/apps/web/app/api/convert/route.ts +100 -0
- package/apps/web/app/api/convert/stream/route.ts +198 -0
- package/apps/web/app/api/deploy/route.ts +157 -0
- package/apps/web/app/api/edge/route.ts +308 -0
- package/apps/web/app/api/export-docker/route.ts +284 -0
- package/apps/web/app/api/generate-openapi/route.ts +119 -0
- package/apps/web/app/api/mcp/[serverId]/route.ts +263 -0
- package/apps/web/app/api/playground/connect/route.ts +143 -0
- package/apps/web/app/api/playground/disconnect/route.ts +78 -0
- package/apps/web/app/api/playground/execute/route.ts +135 -0
- package/apps/web/app/api/playground/sessions/route.ts +103 -0
- package/apps/web/app/api/playground/tools/route.ts +117 -0
- package/apps/web/app/api/playground/v2/connect/route.ts +96 -0
- package/apps/web/app/api/playground/v2/disconnect/route.ts +88 -0
- package/apps/web/app/api/playground/v2/health/route.ts +80 -0
- package/apps/web/app/api/playground/v2/prompts/route.ts +160 -0
- package/apps/web/app/api/playground/v2/resources/route.ts +159 -0
- package/apps/web/app/api/playground/v2/sessions/route.ts +184 -0
- package/apps/web/app/api/playground/v2/tools/route.ts +167 -0
- package/apps/web/app/api/stream/route.ts +232 -0
- package/apps/web/app/batch/BatchConvertClient.tsx +190 -0
- package/apps/web/app/batch/page.tsx +37 -0
- package/apps/web/app/convert/page.tsx +269 -0
- package/apps/web/app/dashboard/page.tsx +380 -0
- package/apps/web/app/globals.css +622 -0
- package/apps/web/app/layout.tsx +120 -0
- package/apps/web/app/manifest.ts +31 -0
- package/apps/web/app/opengraph-image.tsx +112 -0
- package/apps/web/app/page.old.tsx +924 -0
- package/apps/web/app/page.tsx +77 -0
- package/apps/web/app/playground/page.tsx +306 -0
- package/apps/web/app/playground/v2/error.tsx +163 -0
- package/apps/web/app/playground/v2/layout.tsx +58 -0
- package/apps/web/app/playground/v2/loading.tsx +152 -0
- package/apps/web/app/playground/v2/page.tsx +644 -0
- package/apps/web/app/playground/v2/providers.tsx +214 -0
- package/apps/web/app/playground/v2/use-shortcuts.ts +209 -0
- package/apps/web/app/playground/v2/use-url-state.ts +296 -0
- package/apps/web/app/providers.tsx +22 -0
- package/apps/web/app/sitemap.ts +32 -0
- package/apps/web/app/twitter-image.tsx +112 -0
- package/apps/web/components/BranchSelector.tsx +401 -0
- package/apps/web/components/ClaudeConfigExport.tsx +226 -0
- package/apps/web/components/Features.tsx +84 -0
- package/apps/web/components/Footer.tsx +119 -0
- package/apps/web/components/GenerationProgress.tsx +248 -0
- package/apps/web/components/GithubUrlInput.tsx +483 -0
- package/apps/web/components/Header.tsx +175 -0
- package/apps/web/components/Hero.tsx +117 -0
- package/apps/web/components/HowItWorks.tsx +119 -0
- package/apps/web/components/InstallBanner.tsx +158 -0
- package/apps/web/components/Logo.tsx +116 -0
- package/apps/web/components/ParticleBackground.tsx +105 -0
- package/apps/web/components/Playground.tsx +472 -0
- package/apps/web/components/PlaygroundToolTester.tsx +410 -0
- package/apps/web/components/ProductCards.tsx +179 -0
- package/apps/web/components/SplitView.tsx +194 -0
- package/apps/web/components/ToolFilter.tsx +260 -0
- package/apps/web/components/ToolList.tsx +325 -0
- package/apps/web/components/batch/BatchConvert.tsx +785 -0
- package/apps/web/components/batch/index.ts +7 -0
- package/apps/web/components/convert/ConfigTabs.tsx +230 -0
- package/apps/web/components/convert/ConversionResult.tsx +482 -0
- package/apps/web/components/convert/InlinePlayground.tsx +259 -0
- package/apps/web/components/convert/LoadingSteps.tsx +311 -0
- package/apps/web/components/convert/OneClickInstall.tsx +224 -0
- package/apps/web/components/convert/ToolCard.tsx +189 -0
- package/apps/web/components/convert/TryInPlayground.tsx +242 -0
- package/apps/web/components/convert/index.ts +12 -0
- package/apps/web/components/deploy/DeployButton.tsx +369 -0
- package/apps/web/components/deploy/index.ts +7 -0
- package/apps/web/components/docker/DockerExport.tsx +690 -0
- package/apps/web/components/docker/index.ts +7 -0
- package/apps/web/components/install/OneClickInstall.tsx +676 -0
- package/apps/web/components/install/index.ts +7 -0
- package/apps/web/components/playground/CapabilityTabs.tsx +150 -0
- package/apps/web/components/playground/ConnectionStatusV2.tsx +322 -0
- package/apps/web/components/playground/EmptyStates.tsx +305 -0
- package/apps/web/components/playground/ExecutionLog.tsx +260 -0
- package/apps/web/components/playground/ExecutionLogV2.tsx +378 -0
- package/apps/web/components/playground/JsonViewer.tsx +388 -0
- package/apps/web/components/playground/PlaygroundLayout.tsx +244 -0
- package/apps/web/components/playground/PromptsPanel.tsx +385 -0
- package/apps/web/components/playground/ResourcesPanel.tsx +378 -0
- package/apps/web/components/playground/SchemaForm.tsx +477 -0
- package/apps/web/components/playground/ServerStatus.tsx +151 -0
- package/apps/web/components/playground/ShareButton.tsx +239 -0
- package/apps/web/components/playground/ToolsPanel.tsx +309 -0
- package/apps/web/components/playground/TransportConfigurator.tsx +563 -0
- package/apps/web/components/playground/index.ts +74 -0
- package/apps/web/components/playground/types.ts +202 -0
- package/apps/web/components/streaming/StreamingProgress.tsx +441 -0
- package/apps/web/components/streaming/index.ts +7 -0
- package/apps/web/components/ui/badge.tsx +42 -0
- package/apps/web/components/ui/button.tsx +88 -0
- package/apps/web/components/ui/card.tsx +75 -0
- package/apps/web/components/ui/code-block.tsx +122 -0
- package/apps/web/components/ui/index.ts +12 -0
- package/apps/web/components/ui/input.tsx +55 -0
- package/apps/web/components/ui/tabs.tsx +61 -0
- package/apps/web/hooks/index.ts +85 -0
- package/apps/web/hooks/types.ts +1173 -0
- package/apps/web/hooks/use-conversion.ts +133 -0
- package/apps/web/hooks/use-execution-history.ts +376 -0
- package/apps/web/hooks/use-generation-progress.ts +147 -0
- package/apps/web/hooks/use-local-storage.ts +88 -0
- package/apps/web/hooks/use-mcp-client.ts +623 -0
- package/apps/web/hooks/use-mcp-connection.ts +500 -0
- package/apps/web/hooks/use-mcp-execution.ts +282 -0
- package/apps/web/hooks/use-mcp-prompts.ts +441 -0
- package/apps/web/hooks/use-mcp-resources.ts +430 -0
- package/apps/web/hooks/use-mcp-tools.ts +540 -0
- package/apps/web/hooks/use-playground-store.ts +299 -0
- package/apps/web/hooks/use-playground.ts +184 -0
- package/apps/web/hooks/use-streaming-conversion.ts +227 -0
- package/apps/web/hooks/useBatchConversion.ts +271 -0
- package/apps/web/hooks/useDockerConfig.ts +161 -0
- package/apps/web/hooks/usePlatformDetection.ts +80 -0
- package/apps/web/hooks/useStreaming.ts +199 -0
- package/apps/web/lib/api/errors.ts +386 -0
- package/apps/web/lib/api/index.ts +137 -0
- package/apps/web/lib/api/logger.ts +187 -0
- package/apps/web/lib/api/middleware.ts +364 -0
- package/apps/web/lib/api/openapi.ts +977 -0
- package/apps/web/lib/api/session-manager.ts +594 -0
- package/apps/web/lib/api/types.ts +433 -0
- package/apps/web/lib/api/validation.ts +523 -0
- package/apps/web/lib/constants.ts +114 -0
- package/apps/web/lib/mcp/client.ts +1137 -0
- package/apps/web/lib/mcp/events.ts +651 -0
- package/apps/web/lib/mcp/index.ts +347 -0
- package/apps/web/lib/mcp/logger.ts +428 -0
- package/apps/web/lib/mcp/metrics.ts +703 -0
- package/apps/web/lib/mcp/retry.ts +616 -0
- package/apps/web/lib/mcp/session-manager.ts +779 -0
- package/apps/web/lib/mcp/transports.ts +988 -0
- package/apps/web/lib/mcp/types.ts +594 -0
- package/apps/web/lib/mcp-client-enhanced.ts +871 -0
- package/apps/web/lib/mcp-client.ts +778 -0
- package/apps/web/lib/mcp-errors.ts +489 -0
- package/apps/web/lib/mcp-sandbox.ts +593 -0
- package/apps/web/lib/mcp-testing.ts +428 -0
- package/apps/web/lib/mcp-types.ts +448 -0
- package/apps/web/lib/playground-store.tsx +1147 -0
- package/apps/web/lib/utils.ts +439 -0
- package/apps/web/next-env.d.ts +5 -0
- package/apps/web/next.config.js +23 -0
- package/apps/web/package.json +55 -0
- package/apps/web/postcss.config.js +6 -0
- package/apps/web/public/.well-known/ai-plugin.json +17 -0
- package/apps/web/public/logo.svg +6 -0
- package/apps/web/public/robots.txt +22 -0
- package/apps/web/public/schema.json +27 -0
- package/apps/web/tailwind.config.js +26 -0
- package/apps/web/tailwind.config.ts +123 -0
- package/apps/web/tsconfig.json +20 -0
- package/apps/web/types/deploy.ts +139 -0
- package/apps/web/types/index.ts +247 -0
- package/apps/web/vercel.json +39 -0
- package/eslint.config.mjs +23 -0
- package/llms.txt +102 -0
- package/mkdocs/docs/api/core.md +318 -0
- package/mkdocs/docs/api/index.md +128 -0
- package/mkdocs/docs/api/mcp-server.md +301 -0
- package/mkdocs/docs/api/openapi-parser.md +254 -0
- package/mkdocs/docs/assets/logo.svg +7 -0
- package/mkdocs/docs/changelog.md +118 -0
- package/mkdocs/docs/cli/generate.md +148 -0
- package/mkdocs/docs/cli/index.md +52 -0
- package/mkdocs/docs/cli/inspect.md +164 -0
- package/mkdocs/docs/cli/serve.md +136 -0
- package/mkdocs/docs/concepts/classification.md +254 -0
- package/mkdocs/docs/concepts/how-it-works.md +299 -0
- package/mkdocs/docs/concepts/index.md +77 -0
- package/mkdocs/docs/concepts/mcp-protocol.md +362 -0
- package/mkdocs/docs/concepts/tool-types.md +382 -0
- package/mkdocs/docs/contributing/architecture.md +262 -0
- package/mkdocs/docs/contributing/development.md +245 -0
- package/mkdocs/docs/contributing/index.md +73 -0
- package/mkdocs/docs/contributing/testing.md +320 -0
- package/mkdocs/docs/getting-started/configuration.md +235 -0
- package/mkdocs/docs/getting-started/index.md +54 -0
- package/mkdocs/docs/getting-started/installation.md +145 -0
- package/mkdocs/docs/getting-started/quickstart.md +160 -0
- package/mkdocs/docs/guides/batch.md +375 -0
- package/mkdocs/docs/guides/claude-desktop.md +227 -0
- package/mkdocs/docs/guides/cursor.md +188 -0
- package/mkdocs/docs/guides/custom-tools.md +367 -0
- package/mkdocs/docs/guides/index.md +78 -0
- package/mkdocs/docs/guides/private-repos.md +221 -0
- package/mkdocs/docs/guides/vscode.md +247 -0
- package/mkdocs/docs/index.md +175 -0
- package/mkdocs/docs/reference/config.md +223 -0
- package/mkdocs/docs/reference/env.md +192 -0
- package/mkdocs/docs/reference/index.md +102 -0
- package/mkdocs/docs/reference/tools.md +309 -0
- package/mkdocs/docs/stylesheets/extra.css +231 -0
- package/mkdocs/mkdocs.yml +204 -0
- package/mkdocs/overrides/.gitkeep +1 -0
- package/mkdocs/overrides/main.html +7 -0
- package/mkdocs/python-deps.txt +7 -0
- package/mkdocs/vercel.json +11 -0
- package/package.json +63 -0
- package/packages/core/package.json +61 -0
- package/packages/core/src/__tests__/bitbucket-client.test.ts +366 -0
- package/packages/core/src/__tests__/cli.test.ts +235 -0
- package/packages/core/src/__tests__/code-extractor.test.ts +378 -0
- package/packages/core/src/__tests__/docker-generator.test.ts +255 -0
- package/packages/core/src/__tests__/github-client.test.ts +390 -0
- package/packages/core/src/__tests__/gitlab-client.test.ts +319 -0
- package/packages/core/src/__tests__/go-extractor.test.ts +351 -0
- package/packages/core/src/__tests__/graphql-extractor.test.ts +330 -0
- package/packages/core/src/__tests__/java-extractor.test.ts +497 -0
- package/packages/core/src/__tests__/plugins.test.ts +467 -0
- package/packages/core/src/__tests__/readme-extractor.test.ts +258 -0
- package/packages/core/src/__tests__/redis-cache.test.ts +307 -0
- package/packages/core/src/__tests__/rust-extractor.test.ts +252 -0
- package/packages/core/src/__tests__/streaming.test.ts +251 -0
- package/packages/core/src/additional-extractors.ts +333 -0
- package/packages/core/src/cache/cache-interface.ts +179 -0
- package/packages/core/src/cache/index.ts +210 -0
- package/packages/core/src/cache/redis-cache.ts +291 -0
- package/packages/core/src/cache/upstash-cache.ts +379 -0
- package/packages/core/src/cache.ts +251 -0
- package/packages/core/src/cli.ts +822 -0
- package/packages/core/src/code-extractor.ts +696 -0
- package/packages/core/src/docker-generator.ts +470 -0
- package/packages/core/src/edge-compatible.ts +491 -0
- package/packages/core/src/extractors/go-extractor.ts +791 -0
- package/packages/core/src/extractors/index.ts +9 -0
- package/packages/core/src/extractors/java-extractor.ts +937 -0
- package/packages/core/src/extractors/rust-extractor.ts +744 -0
- package/packages/core/src/github-client.ts +319 -0
- package/packages/core/src/go-generator.ts +356 -0
- package/packages/core/src/graphql-extractor.ts +358 -0
- package/packages/core/src/index.ts +797 -0
- package/packages/core/src/langchain-exporter.ts +617 -0
- package/packages/core/src/language-parsers.ts +1114 -0
- package/packages/core/src/mcp-introspector.ts +279 -0
- package/packages/core/src/monorepo-detector.ts +378 -0
- package/packages/core/src/plugins/index.ts +370 -0
- package/packages/core/src/plugins/registry.ts +404 -0
- package/packages/core/src/plugins/types.ts +215 -0
- package/packages/core/src/providers/base-provider.ts +246 -0
- package/packages/core/src/providers/bitbucket-client.ts +464 -0
- package/packages/core/src/providers/gitlab-client.ts +388 -0
- package/packages/core/src/providers/index.ts +176 -0
- package/packages/core/src/python-generator.ts +260 -0
- package/packages/core/src/queue/index.ts +100 -0
- package/packages/core/src/queue/memory-queue.ts +445 -0
- package/packages/core/src/queue/redis-queue.ts +578 -0
- package/packages/core/src/queue/types.ts +251 -0
- package/packages/core/src/readme-extractor.ts +409 -0
- package/packages/core/src/schema-generator.ts +638 -0
- package/packages/core/src/streaming.ts +999 -0
- package/packages/core/src/types.ts +289 -0
- package/packages/core/tsconfig.json +9 -0
- package/packages/core/tsup.config.ts +25 -0
- package/packages/mcp-server/README.md +297 -0
- package/packages/mcp-server/package.json +55 -0
- package/packages/mcp-server/src/__tests__/mcp-server.test.ts +177 -0
- package/packages/mcp-server/src/__tests__/tools.test.ts +217 -0
- package/packages/mcp-server/src/index.ts +1206 -0
- package/packages/mcp-server/src/prompts/index.ts +601 -0
- package/packages/mcp-server/src/tools/export-docker.ts +362 -0
- package/packages/mcp-server/src/tools/generate-openapi.ts +162 -0
- package/packages/mcp-server/src/tools/monitor-mcp-server.ts +448 -0
- package/packages/mcp-server/src/tools/stream-convert.ts +398 -0
- package/packages/mcp-server/src/tools/test-mcp-tool.ts +531 -0
- package/packages/mcp-server/tsconfig.json +12 -0
- package/packages/mcp-server/tsup.config.ts +14 -0
- package/packages/openapi-parser/package-lock.json +3028 -0
- package/packages/openapi-parser/package.json +41 -0
- package/packages/openapi-parser/src/analyzer.ts +700 -0
- package/packages/openapi-parser/src/asyncapi-parser.ts +475 -0
- package/packages/openapi-parser/src/cli.ts +302 -0
- package/packages/openapi-parser/src/generator.ts +570 -0
- package/packages/openapi-parser/src/generators/express-analyzer.ts +649 -0
- package/packages/openapi-parser/src/generators/fastapi-analyzer.ts +960 -0
- package/packages/openapi-parser/src/generators/index.ts +200 -0
- package/packages/openapi-parser/src/generators/nextjs-analyzer.ts +768 -0
- package/packages/openapi-parser/src/generators/openapi-builder.ts +527 -0
- package/packages/openapi-parser/src/generators/types.ts +298 -0
- package/packages/openapi-parser/src/graphql-parser.ts +462 -0
- package/packages/openapi-parser/src/grpc-parser.ts +649 -0
- package/packages/openapi-parser/src/har-parser.ts +723 -0
- package/packages/openapi-parser/src/index.ts +635 -0
- package/packages/openapi-parser/src/insomnia-parser.ts +614 -0
- package/packages/openapi-parser/src/parser.ts +231 -0
- package/packages/openapi-parser/src/postman-parser.ts +611 -0
- package/packages/openapi-parser/src/ref-resolver.ts +313 -0
- package/packages/openapi-parser/src/transformer.ts +459 -0
- package/packages/openapi-parser/tests/generators/express.test.ts +209 -0
- package/packages/openapi-parser/tests/generators/fastapi.test.ts +236 -0
- package/packages/openapi-parser/tests/generators/nextjs.test.ts +273 -0
- package/packages/openapi-parser/tests/parsers.test.ts +847 -0
- package/packages/openapi-parser/tsconfig.json +9 -0
- package/packages/openapi-parser/tsup.config.ts +11 -0
- package/packages/registry/package.json +59 -0
- package/packages/registry/src/cli.ts +456 -0
- package/packages/registry/src/index.ts +44 -0
- package/packages/registry/src/popular/github.json +47 -0
- package/packages/registry/src/popular/index.ts +55 -0
- package/packages/registry/src/popular/linear.json +42 -0
- package/packages/registry/src/popular/notion.json +42 -0
- package/packages/registry/src/popular/openai.json +40 -0
- package/packages/registry/src/popular/resend.json +38 -0
- package/packages/registry/src/popular/slack.json +42 -0
- package/packages/registry/src/popular/stripe.json +163 -0
- package/packages/registry/src/popular/supabase.json +42 -0
- package/packages/registry/src/popular/twilio.json +40 -0
- package/packages/registry/src/popular/vercel.json +40 -0
- package/packages/registry/src/registry.ts +492 -0
- package/packages/registry/src/storage.ts +334 -0
- package/packages/registry/src/types.ts +275 -0
- package/packages/registry/src/updater.ts +208 -0
- package/packages/registry/tsconfig.json +10 -0
- package/packages/registry/tsup.config.ts +11 -0
- package/pnpm-workspace.yaml +3 -0
- package/scripts/build-docs.sh +16 -0
- package/server.json +9 -0
- package/templates/Dockerfile.python.template +60 -0
- package/templates/Dockerfile.typescript.template +60 -0
- package/templates/docker-compose.template.yml +68 -0
- package/tests/fixtures/express-app/index.js +34 -0
- package/tests/fixtures/express-app/routes/posts.js +43 -0
- package/tests/fixtures/express-app/routes/users.js +58 -0
- package/tests/fixtures/fastapi-app/main.py +125 -0
- package/tests/fixtures/fastapi-app/routes/admin.py +42 -0
- package/tests/fixtures/graphql/simple-schema.graphql +65 -0
- package/tests/fixtures/mocks/github-api-responses.json +63 -0
- package/tests/fixtures/nextjs-app/app/api/posts/route.ts +55 -0
- package/tests/fixtures/nextjs-app/app/api/users/[id]/route.ts +63 -0
- package/tests/fixtures/nextjs-app/app/api/users/route.ts +44 -0
- package/tests/fixtures/nextjs-app/pages/api/health.ts +28 -0
- package/tests/fixtures/openapi/petstore.yaml +179 -0
- package/tests/integration/langchain-export.test.ts +405 -0
- package/tests/integration/openapi-conversion.test.ts +221 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +32 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-Click Install Component - Quick installation commands for MCP servers
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { useState, useCallback } from 'react';
|
|
10
|
+
import { Copy, Check, Terminal, Zap, ExternalLink, ChevronDown } from 'lucide-react';
|
|
11
|
+
import type { ConversionResult } from '@/types';
|
|
12
|
+
|
|
13
|
+
interface OneClickInstallProps {
|
|
14
|
+
result: ConversionResult;
|
|
15
|
+
onCopy?: (text: string, id: string) => void;
|
|
16
|
+
copied?: string | null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const PLATFORMS = {
|
|
20
|
+
claude: {
|
|
21
|
+
name: 'Claude Desktop',
|
|
22
|
+
icon: Terminal,
|
|
23
|
+
color: 'from-orange-500 to-red-600',
|
|
24
|
+
configPath: {
|
|
25
|
+
mac: '~/Library/Application Support/Claude/claude_desktop_config.json',
|
|
26
|
+
win: '%APPDATA%\\Claude\\claude_desktop_config.json',
|
|
27
|
+
linux: '~/.config/Claude/claude_desktop_config.json',
|
|
28
|
+
},
|
|
29
|
+
docsUrl: 'https://docs.anthropic.com/claude/docs/claude-desktop',
|
|
30
|
+
},
|
|
31
|
+
cursor: {
|
|
32
|
+
name: 'Cursor',
|
|
33
|
+
icon: Terminal,
|
|
34
|
+
color: 'from-blue-500 to-cyan-600',
|
|
35
|
+
configPath: {
|
|
36
|
+
mac: '~/Library/Application Support/Cursor/config.json',
|
|
37
|
+
win: '%APPDATA%\\Cursor\\config.json',
|
|
38
|
+
linux: '~/.config/Cursor/config.json',
|
|
39
|
+
},
|
|
40
|
+
docsUrl: 'https://cursor.sh/docs/mcp',
|
|
41
|
+
},
|
|
42
|
+
vscode: {
|
|
43
|
+
name: 'VS Code',
|
|
44
|
+
icon: Terminal,
|
|
45
|
+
color: 'from-blue-600 to-purple-600',
|
|
46
|
+
configPath: {
|
|
47
|
+
mac: '~/Library/Application Support/Code/User/settings.json',
|
|
48
|
+
win: '%APPDATA%\\Code\\User\\settings.json',
|
|
49
|
+
linux: '~/.config/Code/User/settings.json',
|
|
50
|
+
},
|
|
51
|
+
docsUrl: 'https://code.visualstudio.com/docs',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default function OneClickInstall({ result, onCopy, copied }: OneClickInstallProps) {
|
|
56
|
+
const [selectedPlatform, setSelectedPlatform] = useState<keyof typeof PLATFORMS>('claude');
|
|
57
|
+
const [internalCopied, setInternalCopied] = useState<string | null>(null);
|
|
58
|
+
const [showManual, setShowManual] = useState(false);
|
|
59
|
+
|
|
60
|
+
const displayCopied = copied !== undefined ? copied : internalCopied;
|
|
61
|
+
|
|
62
|
+
const handleCopy = useCallback(async (text: string, id: string) => {
|
|
63
|
+
if (onCopy) {
|
|
64
|
+
onCopy(text, id);
|
|
65
|
+
} else {
|
|
66
|
+
await navigator.clipboard.writeText(text);
|
|
67
|
+
setInternalCopied(id);
|
|
68
|
+
setTimeout(() => setInternalCopied(null), 2000);
|
|
69
|
+
}
|
|
70
|
+
}, [onCopy]);
|
|
71
|
+
|
|
72
|
+
const getInstallCommand = (platform: keyof typeof PLATFORMS) => {
|
|
73
|
+
const serverName = result.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
74
|
+
return `npx @nirholas/github-to-mcp install ${result.repository.url} --${platform}`;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const getManualConfig = (platform: keyof typeof PLATFORMS) => {
|
|
78
|
+
const serverName = result.name.toLowerCase().replace(/[^a-z0-9-]/g, '-');
|
|
79
|
+
return `{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"${serverName}": {
|
|
82
|
+
"command": "node",
|
|
83
|
+
"args": ["path/to/${serverName}-server.js"]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}`;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const platformInfo = PLATFORMS[selectedPlatform];
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div className="rounded-2xl border border-neutral-800 bg-neutral-900/50 backdrop-blur-xl overflow-hidden">
|
|
93
|
+
{/* Header */}
|
|
94
|
+
<div className="p-6 border-b border-neutral-800">
|
|
95
|
+
<div className="flex items-center gap-3 mb-2">
|
|
96
|
+
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-white/10 to-white/5 flex items-center justify-center">
|
|
97
|
+
<Zap className="w-5 h-5 text-white" />
|
|
98
|
+
</div>
|
|
99
|
+
<div>
|
|
100
|
+
<h3 className="text-lg font-semibold text-white">One-Click Install</h3>
|
|
101
|
+
<p className="text-sm text-neutral-400">Add to your MCP client instantly</p>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
{/* Platform selector */}
|
|
107
|
+
<div className="p-4 border-b border-neutral-800 bg-black/20">
|
|
108
|
+
<div className="flex gap-2">
|
|
109
|
+
{(Object.keys(PLATFORMS) as Array<keyof typeof PLATFORMS>).map((platform) => {
|
|
110
|
+
const info = PLATFORMS[platform];
|
|
111
|
+
const Icon = info.icon;
|
|
112
|
+
return (
|
|
113
|
+
<button
|
|
114
|
+
key={platform}
|
|
115
|
+
onClick={() => setSelectedPlatform(platform)}
|
|
116
|
+
className={`flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-medium transition-all ${
|
|
117
|
+
selectedPlatform === platform
|
|
118
|
+
? `bg-gradient-to-r ${info.color} text-white shadow-lg`
|
|
119
|
+
: 'bg-white/5 text-neutral-400 hover:text-white hover:bg-white/10'
|
|
120
|
+
}`}
|
|
121
|
+
>
|
|
122
|
+
<Icon className="w-4 h-4" />
|
|
123
|
+
{info.name}
|
|
124
|
+
</button>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
{/* Install command */}
|
|
131
|
+
<div className="p-6 space-y-4">
|
|
132
|
+
{/* One-click install */}
|
|
133
|
+
<div>
|
|
134
|
+
<div className="flex items-center justify-between mb-2">
|
|
135
|
+
<label className="text-sm font-medium text-white flex items-center gap-2">
|
|
136
|
+
<Terminal className="w-4 h-4" />
|
|
137
|
+
CLI Install Command
|
|
138
|
+
</label>
|
|
139
|
+
<span className="text-xs text-neutral-500">Recommended</span>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<div className="relative group">
|
|
143
|
+
<div className="flex items-center gap-2 p-4 bg-black/40 border border-neutral-800 rounded-xl font-mono text-sm">
|
|
144
|
+
<span className="text-neutral-500">$</span>
|
|
145
|
+
<code className="flex-1 text-green-400 overflow-x-auto whitespace-nowrap scrollbar-thin">
|
|
146
|
+
{getInstallCommand(selectedPlatform)}
|
|
147
|
+
</code>
|
|
148
|
+
<button
|
|
149
|
+
onClick={() => handleCopy(getInstallCommand(selectedPlatform), 'install-cmd')}
|
|
150
|
+
className="flex-shrink-0 p-2 hover:bg-white/10 rounded-lg transition-colors"
|
|
151
|
+
title="Copy command"
|
|
152
|
+
>
|
|
153
|
+
{displayCopied === 'install-cmd' ? (
|
|
154
|
+
<Check className="w-4 h-4 text-green-400" />
|
|
155
|
+
) : (
|
|
156
|
+
<Copy className="w-4 h-4 text-neutral-400" />
|
|
157
|
+
)}
|
|
158
|
+
</button>
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
<p className="mt-2 text-xs text-neutral-500">
|
|
163
|
+
This command will download and configure the MCP server automatically
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
|
|
167
|
+
{/* Manual config option */}
|
|
168
|
+
<div className="p-4 rounded-xl bg-gradient-to-br from-white/5 to-transparent border border-neutral-800 relative z-10">
|
|
169
|
+
<button
|
|
170
|
+
onClick={() => setShowManual(!showManual)}
|
|
171
|
+
className="flex items-center justify-between w-full text-sm text-neutral-300 hover:text-white transition-colors"
|
|
172
|
+
>
|
|
173
|
+
<span className="font-medium">Manual Configuration</span>
|
|
174
|
+
<ChevronDown className={`w-4 h-4 transition-transform ${showManual ? 'rotate-180' : ''}`} />
|
|
175
|
+
</button>
|
|
176
|
+
|
|
177
|
+
{showManual && (
|
|
178
|
+
<div className="mt-4 space-y-3">
|
|
179
|
+
<div>
|
|
180
|
+
<div className="text-xs text-neutral-500 mb-2">Config file location:</div>
|
|
181
|
+
<code className="block p-2 bg-black/40 rounded text-xs text-neutral-300 overflow-x-auto">
|
|
182
|
+
{platformInfo.configPath.mac}
|
|
183
|
+
</code>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<div>
|
|
187
|
+
<div className="flex items-center justify-between mb-2">
|
|
188
|
+
<div className="text-xs text-neutral-500">Configuration:</div>
|
|
189
|
+
<button
|
|
190
|
+
onClick={() => handleCopy(getManualConfig(selectedPlatform), 'manual-config')}
|
|
191
|
+
className="text-xs text-white/60 hover:text-white transition-colors flex items-center gap-1"
|
|
192
|
+
>
|
|
193
|
+
{displayCopied === 'manual-config' ? (
|
|
194
|
+
<>
|
|
195
|
+
<Check className="w-3 h-3" /> Copied
|
|
196
|
+
</>
|
|
197
|
+
) : (
|
|
198
|
+
<>
|
|
199
|
+
<Copy className="w-3 h-3" /> Copy
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
</button>
|
|
203
|
+
</div>
|
|
204
|
+
<pre className="p-3 bg-black/40 rounded text-xs text-neutral-300 overflow-x-auto">
|
|
205
|
+
{getManualConfig(selectedPlatform)}
|
|
206
|
+
</pre>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
<a
|
|
210
|
+
href={platformInfo.docsUrl}
|
|
211
|
+
target="_blank"
|
|
212
|
+
rel="noopener noreferrer"
|
|
213
|
+
className="flex items-center gap-2 text-xs text-blue-400 hover:text-blue-300 transition-colors"
|
|
214
|
+
>
|
|
215
|
+
<ExternalLink className="w-3 h-3" />
|
|
216
|
+
View {platformInfo.name} documentation
|
|
217
|
+
</a>
|
|
218
|
+
</div>
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
);
|
|
224
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Card Component - Displays individual tool information
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
10
|
+
import {
|
|
11
|
+
ChevronDown,
|
|
12
|
+
ChevronRight,
|
|
13
|
+
Copy,
|
|
14
|
+
Check,
|
|
15
|
+
Code2,
|
|
16
|
+
FileText,
|
|
17
|
+
} from 'lucide-react';
|
|
18
|
+
import type { Tool } from '@/types';
|
|
19
|
+
import { SOURCE_TYPE_LABELS } from '@/lib/constants';
|
|
20
|
+
|
|
21
|
+
interface ToolCardProps {
|
|
22
|
+
tool: Tool;
|
|
23
|
+
isExpanded: boolean;
|
|
24
|
+
onToggle: () => void;
|
|
25
|
+
onCopy: (text: string, id: string) => void;
|
|
26
|
+
copied: string | null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default function ToolCard({ tool, isExpanded, onToggle, onCopy, copied }: ToolCardProps) {
|
|
30
|
+
const sourceInfo = SOURCE_TYPE_LABELS[tool.source?.type || 'unknown'] || { label: 'Unknown', color: 'gray' };
|
|
31
|
+
|
|
32
|
+
const hasParams = tool.inputSchema?.properties && Object.keys(tool.inputSchema.properties).length > 0;
|
|
33
|
+
const requiredParams = tool.inputSchema?.required || [];
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<motion.div
|
|
37
|
+
layout
|
|
38
|
+
className="rounded-xl border border-neutral-800 bg-black/30 overflow-hidden"
|
|
39
|
+
>
|
|
40
|
+
{/* Header */}
|
|
41
|
+
<button
|
|
42
|
+
onClick={onToggle}
|
|
43
|
+
className="w-full flex items-center justify-between p-4 text-left hover:bg-white/5 transition-colors"
|
|
44
|
+
>
|
|
45
|
+
<div className="flex items-center gap-3">
|
|
46
|
+
<div className="w-8 h-8 rounded-lg bg-white/5 border border-neutral-700 flex items-center justify-center">
|
|
47
|
+
<Code2 className="w-4 h-4 text-white" />
|
|
48
|
+
</div>
|
|
49
|
+
<div>
|
|
50
|
+
<div className="flex items-center gap-2">
|
|
51
|
+
<span className="font-mono font-medium text-white">{tool.name}</span>
|
|
52
|
+
{hasParams && (
|
|
53
|
+
<span className="text-xs text-neutral-500">
|
|
54
|
+
({Object.keys(tool.inputSchema.properties || {}).length} params)
|
|
55
|
+
</span>
|
|
56
|
+
)}
|
|
57
|
+
</div>
|
|
58
|
+
<p className="text-sm text-neutral-400 line-clamp-1 mt-0.5">
|
|
59
|
+
{tool.description}
|
|
60
|
+
</p>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
|
|
64
|
+
<div className="flex items-center gap-2">
|
|
65
|
+
<span className={`px-2 py-1 text-xs rounded bg-white/5 text-neutral-400`}>
|
|
66
|
+
{sourceInfo.label}
|
|
67
|
+
</span>
|
|
68
|
+
{isExpanded ? (
|
|
69
|
+
<ChevronDown className="w-4 h-4 text-neutral-500" />
|
|
70
|
+
) : (
|
|
71
|
+
<ChevronRight className="w-4 h-4 text-neutral-500" />
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
</button>
|
|
75
|
+
|
|
76
|
+
{/* Expanded content */}
|
|
77
|
+
<AnimatePresence>
|
|
78
|
+
{isExpanded && (
|
|
79
|
+
<motion.div
|
|
80
|
+
initial={{ height: 0, opacity: 0 }}
|
|
81
|
+
animate={{ height: 'auto', opacity: 1 }}
|
|
82
|
+
exit={{ height: 0, opacity: 0 }}
|
|
83
|
+
transition={{ duration: 0.2 }}
|
|
84
|
+
className="overflow-hidden"
|
|
85
|
+
>
|
|
86
|
+
<div className="p-4 pt-0 space-y-4">
|
|
87
|
+
{/* Description */}
|
|
88
|
+
<div className="p-3 bg-neutral-900/50 rounded-lg border border-neutral-800">
|
|
89
|
+
<div className="flex items-center gap-2 mb-2">
|
|
90
|
+
<FileText className="w-4 h-4 text-neutral-500" />
|
|
91
|
+
<span className="text-xs font-medium text-neutral-400">Description</span>
|
|
92
|
+
</div>
|
|
93
|
+
<p className="text-sm text-neutral-300">{tool.description}</p>
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
{/* Parameters */}
|
|
97
|
+
{hasParams && (
|
|
98
|
+
<div className="p-3 bg-neutral-900/50 rounded-lg border border-neutral-800">
|
|
99
|
+
<div className="flex items-center justify-between mb-3">
|
|
100
|
+
<div className="flex items-center gap-2">
|
|
101
|
+
<Code2 className="w-4 h-4 text-neutral-500" />
|
|
102
|
+
<span className="text-xs font-medium text-neutral-400">Parameters</span>
|
|
103
|
+
</div>
|
|
104
|
+
<button
|
|
105
|
+
onClick={(e) => {
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
onCopy(JSON.stringify(tool.inputSchema, null, 2), `schema-${tool.name}`);
|
|
108
|
+
}}
|
|
109
|
+
className="flex items-center gap-1 px-2 py-1 text-xs text-neutral-400 hover:text-white hover:bg-white/10 rounded transition-colors"
|
|
110
|
+
>
|
|
111
|
+
{copied === `schema-${tool.name}` ? (
|
|
112
|
+
<>
|
|
113
|
+
<Check className="w-3 h-3 text-green-400" />
|
|
114
|
+
<span className="text-green-400">Copied</span>
|
|
115
|
+
</>
|
|
116
|
+
) : (
|
|
117
|
+
<>
|
|
118
|
+
<Copy className="w-3 h-3" />
|
|
119
|
+
<span>Copy Schema</span>
|
|
120
|
+
</>
|
|
121
|
+
)}
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<div className="space-y-2">
|
|
126
|
+
{Object.entries(tool.inputSchema.properties || {}).map(([key, value]) => {
|
|
127
|
+
const isRequired = requiredParams.includes(key);
|
|
128
|
+
const paramValue = value as { type: string; description?: string; enum?: string[]; default?: unknown };
|
|
129
|
+
|
|
130
|
+
return (
|
|
131
|
+
<div
|
|
132
|
+
key={key}
|
|
133
|
+
className="flex items-start gap-3 p-2 rounded bg-black/30"
|
|
134
|
+
>
|
|
135
|
+
<div className="flex-1">
|
|
136
|
+
<div className="flex items-center gap-2">
|
|
137
|
+
<code className="text-sm font-mono text-white">{key}</code>
|
|
138
|
+
<span className="text-xs text-neutral-500">{paramValue.type}</span>
|
|
139
|
+
{isRequired && (
|
|
140
|
+
<span className="px-1.5 py-0.5 text-[10px] bg-red-500/20 text-red-400 rounded">
|
|
141
|
+
required
|
|
142
|
+
</span>
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
{paramValue.description && (
|
|
146
|
+
<p className="text-xs text-neutral-400 mt-1">{paramValue.description}</p>
|
|
147
|
+
)}
|
|
148
|
+
{paramValue.enum && (
|
|
149
|
+
<div className="flex flex-wrap gap-1 mt-2">
|
|
150
|
+
{paramValue.enum.map((val) => (
|
|
151
|
+
<span
|
|
152
|
+
key={val}
|
|
153
|
+
className="px-1.5 py-0.5 text-[10px] bg-white/5 text-neutral-400 rounded font-mono"
|
|
154
|
+
>
|
|
155
|
+
{val}
|
|
156
|
+
</span>
|
|
157
|
+
))}
|
|
158
|
+
</div>
|
|
159
|
+
)}
|
|
160
|
+
{paramValue.default !== undefined && (
|
|
161
|
+
<p className="text-xs text-neutral-500 mt-1">
|
|
162
|
+
Default: <code className="text-neutral-400">{JSON.stringify(paramValue.default)}</code>
|
|
163
|
+
</p>
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
})}
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
)}
|
|
172
|
+
|
|
173
|
+
{/* Source info */}
|
|
174
|
+
{tool.source?.file && (
|
|
175
|
+
<div className="flex items-center gap-2 text-xs text-neutral-500">
|
|
176
|
+
<span>Source:</span>
|
|
177
|
+
<code className="px-1.5 py-0.5 bg-white/5 rounded">
|
|
178
|
+
{tool.source.file}
|
|
179
|
+
{tool.source.line && `:${tool.source.line}`}
|
|
180
|
+
</code>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
</div>
|
|
184
|
+
</motion.div>
|
|
185
|
+
)}
|
|
186
|
+
</AnimatePresence>
|
|
187
|
+
</motion.div>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Try In Playground Component - CTA to test generated tools
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
10
|
+
import { useRouter } from 'next/navigation';
|
|
11
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
12
|
+
import {
|
|
13
|
+
Play,
|
|
14
|
+
Terminal,
|
|
15
|
+
Sparkles,
|
|
16
|
+
ChevronRight,
|
|
17
|
+
Share2,
|
|
18
|
+
Copy,
|
|
19
|
+
Check,
|
|
20
|
+
ExternalLink,
|
|
21
|
+
Loader2,
|
|
22
|
+
Package,
|
|
23
|
+
} from 'lucide-react';
|
|
24
|
+
import { Button } from '@/components/ui/button';
|
|
25
|
+
import type { ConversionResult, Tool } from '@/types';
|
|
26
|
+
import { usePlaygroundNavigation, usePlaygroundSharing } from '@/hooks/use-playground-store';
|
|
27
|
+
|
|
28
|
+
interface TryInPlaygroundProps {
|
|
29
|
+
/** Conversion result containing generated code and tools */
|
|
30
|
+
result: ConversionResult;
|
|
31
|
+
/** Optional CSS class name */
|
|
32
|
+
className?: string;
|
|
33
|
+
/** Whether to show a compact version */
|
|
34
|
+
compact?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default function TryInPlayground({
|
|
38
|
+
result,
|
|
39
|
+
className = '',
|
|
40
|
+
compact = false,
|
|
41
|
+
}: TryInPlaygroundProps) {
|
|
42
|
+
const router = useRouter();
|
|
43
|
+
const { navigateToPlayground } = usePlaygroundNavigation();
|
|
44
|
+
const { copyShareLink } = usePlaygroundSharing();
|
|
45
|
+
|
|
46
|
+
const [copied, setCopied] = useState(false);
|
|
47
|
+
const [isNavigating, setIsNavigating] = useState(false);
|
|
48
|
+
|
|
49
|
+
// Get preview of tools (first 3)
|
|
50
|
+
const previewTools = useMemo(() => {
|
|
51
|
+
return result.tools.slice(0, 3);
|
|
52
|
+
}, [result.tools]);
|
|
53
|
+
|
|
54
|
+
const remainingCount = result.tools.length - previewTools.length;
|
|
55
|
+
|
|
56
|
+
const handleOpenPlayground = useCallback(() => {
|
|
57
|
+
setIsNavigating(true);
|
|
58
|
+
navigateToPlayground(result);
|
|
59
|
+
}, [navigateToPlayground, result]);
|
|
60
|
+
|
|
61
|
+
const handleCopyShareLink = useCallback(async () => {
|
|
62
|
+
// First store the result, then copy
|
|
63
|
+
navigateToPlayground(result);
|
|
64
|
+
const success = await copyShareLink();
|
|
65
|
+
if (success) {
|
|
66
|
+
setCopied(true);
|
|
67
|
+
setTimeout(() => setCopied(false), 2000);
|
|
68
|
+
}
|
|
69
|
+
// Navigate back - the state is preserved
|
|
70
|
+
router.back();
|
|
71
|
+
}, [navigateToPlayground, result, copyShareLink, router]);
|
|
72
|
+
|
|
73
|
+
if (compact) {
|
|
74
|
+
return (
|
|
75
|
+
<motion.div
|
|
76
|
+
initial={{ opacity: 0, scale: 0.95 }}
|
|
77
|
+
animate={{ opacity: 1, scale: 1 }}
|
|
78
|
+
className={`flex items-center gap-3 ${className}`}
|
|
79
|
+
>
|
|
80
|
+
<Button
|
|
81
|
+
onClick={handleOpenPlayground}
|
|
82
|
+
disabled={isNavigating}
|
|
83
|
+
className="bg-gradient-to-r from-green-500 to-emerald-600 hover:from-green-600 hover:to-emerald-700 text-white font-medium"
|
|
84
|
+
>
|
|
85
|
+
{isNavigating ? (
|
|
86
|
+
<Loader2 className="w-4 h-4 mr-2 animate-spin" />
|
|
87
|
+
) : (
|
|
88
|
+
<Play className="w-4 h-4 mr-2" />
|
|
89
|
+
)}
|
|
90
|
+
Try in Playground
|
|
91
|
+
</Button>
|
|
92
|
+
|
|
93
|
+
<span className="text-sm text-neutral-400">
|
|
94
|
+
{result.tools.length} tool{result.tools.length !== 1 ? 's' : ''} available
|
|
95
|
+
</span>
|
|
96
|
+
</motion.div>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<motion.div
|
|
102
|
+
initial={{ opacity: 0, y: 20 }}
|
|
103
|
+
animate={{ opacity: 1, y: 0 }}
|
|
104
|
+
transition={{ delay: 0.2 }}
|
|
105
|
+
className={`rounded-2xl border border-green-500/30 bg-gradient-to-br from-green-500/10 via-emerald-500/5 to-transparent p-6 ${className}`}
|
|
106
|
+
>
|
|
107
|
+
{/* Header */}
|
|
108
|
+
<div className="flex items-start justify-between gap-4 mb-6">
|
|
109
|
+
<div className="flex items-center gap-3">
|
|
110
|
+
<div className="w-12 h-12 rounded-xl bg-gradient-to-br from-green-500 to-emerald-600 flex items-center justify-center">
|
|
111
|
+
<Terminal className="w-6 h-6 text-white" />
|
|
112
|
+
</div>
|
|
113
|
+
<div>
|
|
114
|
+
<h3 className="text-lg font-semibold text-white flex items-center gap-2">
|
|
115
|
+
Test Your Tools
|
|
116
|
+
<span className="px-2 py-0.5 text-xs rounded-full bg-green-500/20 text-green-400">
|
|
117
|
+
Interactive
|
|
118
|
+
</span>
|
|
119
|
+
</h3>
|
|
120
|
+
<p className="text-sm text-neutral-400">
|
|
121
|
+
Try out generated tools in the playground
|
|
122
|
+
</p>
|
|
123
|
+
</div>
|
|
124
|
+
</div>
|
|
125
|
+
|
|
126
|
+
<Sparkles className="w-5 h-5 text-green-400 animate-pulse" />
|
|
127
|
+
</div>
|
|
128
|
+
|
|
129
|
+
{/* Tool Preview */}
|
|
130
|
+
{previewTools.length > 0 && (
|
|
131
|
+
<div className="mb-6">
|
|
132
|
+
<div className="text-xs font-medium text-neutral-500 uppercase tracking-wider mb-3">
|
|
133
|
+
Available Tools
|
|
134
|
+
</div>
|
|
135
|
+
<div className="space-y-2">
|
|
136
|
+
{previewTools.map((tool) => (
|
|
137
|
+
<ToolPreviewItem key={tool.name} tool={tool} />
|
|
138
|
+
))}
|
|
139
|
+
|
|
140
|
+
{remainingCount > 0 && (
|
|
141
|
+
<div className="flex items-center gap-2 py-2 px-3 text-sm text-neutral-400">
|
|
142
|
+
<Package className="w-4 h-4" />
|
|
143
|
+
<span>+ {remainingCount} more tool{remainingCount !== 1 ? 's' : ''}</span>
|
|
144
|
+
</div>
|
|
145
|
+
)}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
{/* Actions */}
|
|
151
|
+
<div className="flex flex-col sm:flex-row gap-3">
|
|
152
|
+
<Button
|
|
153
|
+
onClick={handleOpenPlayground}
|
|
154
|
+
disabled={isNavigating}
|
|
155
|
+
className="flex-1 bg-gradient-to-r from-green-500 to-emerald-600 hover:from-green-600 hover:to-emerald-700 text-white font-medium py-3"
|
|
156
|
+
size="lg"
|
|
157
|
+
>
|
|
158
|
+
{isNavigating ? (
|
|
159
|
+
<Loader2 className="w-5 h-5 mr-2 animate-spin" />
|
|
160
|
+
) : (
|
|
161
|
+
<Play className="w-5 h-5 mr-2" />
|
|
162
|
+
)}
|
|
163
|
+
Open in Playground
|
|
164
|
+
<ChevronRight className="w-4 h-4 ml-1" />
|
|
165
|
+
</Button>
|
|
166
|
+
|
|
167
|
+
<Button
|
|
168
|
+
onClick={handleCopyShareLink}
|
|
169
|
+
variant="outline"
|
|
170
|
+
className="sm:flex-initial"
|
|
171
|
+
size="lg"
|
|
172
|
+
>
|
|
173
|
+
{copied ? (
|
|
174
|
+
<>
|
|
175
|
+
<Check className="w-4 h-4 mr-2 text-green-400" />
|
|
176
|
+
Copied!
|
|
177
|
+
</>
|
|
178
|
+
) : (
|
|
179
|
+
<>
|
|
180
|
+
<Share2 className="w-4 h-4 mr-2" />
|
|
181
|
+
Share
|
|
182
|
+
</>
|
|
183
|
+
)}
|
|
184
|
+
</Button>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{/* Features list */}
|
|
188
|
+
<div className="mt-6 pt-6 border-t border-neutral-800">
|
|
189
|
+
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 text-sm">
|
|
190
|
+
<FeatureItem
|
|
191
|
+
icon={<Terminal className="w-4 h-4" />}
|
|
192
|
+
text="Execute tools live"
|
|
193
|
+
/>
|
|
194
|
+
<FeatureItem
|
|
195
|
+
icon={<ExternalLink className="w-4 h-4" />}
|
|
196
|
+
text="View JSON responses"
|
|
197
|
+
/>
|
|
198
|
+
<FeatureItem
|
|
199
|
+
icon={<Share2 className="w-4 h-4" />}
|
|
200
|
+
text="Share with others"
|
|
201
|
+
/>
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</motion.div>
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ===== Sub-components =====
|
|
209
|
+
|
|
210
|
+
function ToolPreviewItem({ tool }: { tool: Tool }) {
|
|
211
|
+
const paramCount = Object.keys(tool.inputSchema?.properties || {}).length;
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<div className="flex items-center gap-3 py-2 px-3 rounded-lg bg-white/5 hover:bg-white/10 transition-colors">
|
|
215
|
+
<div className="w-8 h-8 rounded-lg bg-neutral-800 flex items-center justify-center flex-shrink-0">
|
|
216
|
+
<Terminal className="w-4 h-4 text-neutral-400" />
|
|
217
|
+
</div>
|
|
218
|
+
<div className="flex-1 min-w-0">
|
|
219
|
+
<div className="font-medium text-white text-sm truncate">
|
|
220
|
+
{tool.name}
|
|
221
|
+
</div>
|
|
222
|
+
<div className="text-xs text-neutral-500 truncate">
|
|
223
|
+
{tool.description || 'No description'}
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
<div className="flex items-center gap-2 text-xs text-neutral-500">
|
|
227
|
+
<span className="px-1.5 py-0.5 rounded bg-neutral-800">
|
|
228
|
+
{paramCount} param{paramCount !== 1 ? 's' : ''}
|
|
229
|
+
</span>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function FeatureItem({ icon, text }: { icon: React.ReactNode; text: string }) {
|
|
236
|
+
return (
|
|
237
|
+
<div className="flex items-center gap-2 text-neutral-400">
|
|
238
|
+
<span className="text-green-400">{icon}</span>
|
|
239
|
+
{text}
|
|
240
|
+
</div>
|
|
241
|
+
);
|
|
242
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert Components Index
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { default as ConversionResult } from './ConversionResult';
|
|
8
|
+
export { default as ToolCard } from './ToolCard';
|
|
9
|
+
export { default as ConfigTabs } from './ConfigTabs';
|
|
10
|
+
export { default as LoadingSteps } from './LoadingSteps';
|
|
11
|
+
export { default as OneClickInstall } from './OneClickInstall';
|
|
12
|
+
export { default as TryInPlayground } from './TryInPlayground';
|