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,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InlinePlayground Component - Test tools inline in the conversion result
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
10
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
11
|
+
import {
|
|
12
|
+
Play,
|
|
13
|
+
Loader2,
|
|
14
|
+
AlertCircle,
|
|
15
|
+
Check,
|
|
16
|
+
ChevronRight,
|
|
17
|
+
Package,
|
|
18
|
+
Search,
|
|
19
|
+
Zap,
|
|
20
|
+
Terminal,
|
|
21
|
+
} from 'lucide-react';
|
|
22
|
+
import { Input } from '@/components/ui/input';
|
|
23
|
+
import { Button } from '@/components/ui/button';
|
|
24
|
+
import PlaygroundToolTester from '@/components/PlaygroundToolTester';
|
|
25
|
+
import type { Tool } from '@/types';
|
|
26
|
+
import { useMcpExecution } from '@/hooks/use-mcp-execution';
|
|
27
|
+
|
|
28
|
+
interface InlinePlaygroundProps {
|
|
29
|
+
tools: Tool[];
|
|
30
|
+
generatedCode: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const SOURCE_COLORS: Record<string, string> = {
|
|
35
|
+
readme: 'bg-blue-500/10 text-blue-400',
|
|
36
|
+
code: 'bg-purple-500/10 text-purple-400',
|
|
37
|
+
openapi: 'bg-green-500/10 text-green-400',
|
|
38
|
+
graphql: 'bg-pink-500/10 text-pink-400',
|
|
39
|
+
'mcp-introspect': 'bg-yellow-500/10 text-yellow-400',
|
|
40
|
+
universal: 'bg-neutral-500/10 text-neutral-400',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export default function InlinePlayground({
|
|
44
|
+
tools,
|
|
45
|
+
generatedCode,
|
|
46
|
+
className = '',
|
|
47
|
+
}: InlinePlaygroundProps) {
|
|
48
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
49
|
+
const [selectedTool, setSelectedTool] = useState<Tool | null>(tools[0] || null);
|
|
50
|
+
|
|
51
|
+
// MCP execution hook
|
|
52
|
+
const {
|
|
53
|
+
isConnected,
|
|
54
|
+
isConnecting,
|
|
55
|
+
isLoading,
|
|
56
|
+
error: connectionError,
|
|
57
|
+
connect,
|
|
58
|
+
disconnect,
|
|
59
|
+
executeTool,
|
|
60
|
+
} = useMcpExecution({
|
|
61
|
+
generatedCode,
|
|
62
|
+
onToolsLoaded: (loadedTools) => {
|
|
63
|
+
if (loadedTools.length > 0 && !selectedTool) {
|
|
64
|
+
setSelectedTool(loadedTools[0]);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Filter tools based on search
|
|
70
|
+
const filteredTools = useMemo(() => {
|
|
71
|
+
if (!searchQuery) return tools;
|
|
72
|
+
const query = searchQuery.toLowerCase();
|
|
73
|
+
return tools.filter(
|
|
74
|
+
tool =>
|
|
75
|
+
tool.name.toLowerCase().includes(query) ||
|
|
76
|
+
tool.description?.toLowerCase().includes(query)
|
|
77
|
+
);
|
|
78
|
+
}, [tools, searchQuery]);
|
|
79
|
+
|
|
80
|
+
// Handle tool execution
|
|
81
|
+
const handleExecute = useCallback(async (tool: Tool, params: Record<string, unknown>) => {
|
|
82
|
+
if (isConnected) {
|
|
83
|
+
return await executeTool(tool.name, params);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Mock execution when not connected
|
|
87
|
+
await new Promise(resolve => setTimeout(resolve, 600 + Math.random() * 400));
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
tool: tool.name,
|
|
92
|
+
timestamp: new Date().toISOString(),
|
|
93
|
+
params,
|
|
94
|
+
response: {
|
|
95
|
+
message: `Demo response for ${tool.name}`,
|
|
96
|
+
note: 'Connect to server for real execution',
|
|
97
|
+
data: {
|
|
98
|
+
id: Math.random().toString(36).substring(7),
|
|
99
|
+
...params,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
}, [isConnected, executeTool]);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<div className={`space-y-4 ${className}`}>
|
|
107
|
+
{/* Connection status bar */}
|
|
108
|
+
<div className="flex items-center justify-between p-3 rounded-lg bg-black/30 border border-neutral-800">
|
|
109
|
+
<div className="flex items-center gap-3">
|
|
110
|
+
<div className={`w-2 h-2 rounded-full ${isConnected ? 'bg-green-500' : 'bg-neutral-500'}`} />
|
|
111
|
+
<span className="text-sm text-neutral-300">
|
|
112
|
+
{isConnecting
|
|
113
|
+
? 'Connecting...'
|
|
114
|
+
: isConnected
|
|
115
|
+
? 'Connected to MCP Server'
|
|
116
|
+
: 'Demo Mode (not connected)'}
|
|
117
|
+
</span>
|
|
118
|
+
{!isConnected && (
|
|
119
|
+
<span className="text-xs text-neutral-500">
|
|
120
|
+
Results will be simulated
|
|
121
|
+
</span>
|
|
122
|
+
)}
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<Button
|
|
126
|
+
onClick={isConnected ? disconnect : connect}
|
|
127
|
+
disabled={isConnecting}
|
|
128
|
+
variant={isConnected ? 'outline' : 'default'}
|
|
129
|
+
size="sm"
|
|
130
|
+
className="gap-2"
|
|
131
|
+
>
|
|
132
|
+
{isConnecting ? (
|
|
133
|
+
<Loader2 className="w-4 h-4 animate-spin" />
|
|
134
|
+
) : isConnected ? (
|
|
135
|
+
<Check className="w-4 h-4" />
|
|
136
|
+
) : (
|
|
137
|
+
<Zap className="w-4 h-4" />
|
|
138
|
+
)}
|
|
139
|
+
{isConnecting ? 'Connecting...' : isConnected ? 'Disconnect' : 'Connect'}
|
|
140
|
+
</Button>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
{connectionError && (
|
|
144
|
+
<div className="p-3 rounded-lg bg-red-500/10 border border-red-500/30 text-red-400 text-sm">
|
|
145
|
+
<AlertCircle className="w-4 h-4 inline-block mr-2" />
|
|
146
|
+
{connectionError}
|
|
147
|
+
</div>
|
|
148
|
+
)}
|
|
149
|
+
|
|
150
|
+
{/* Main layout */}
|
|
151
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
|
152
|
+
{/* Tool list - left sidebar */}
|
|
153
|
+
<div className="lg:col-span-1 rounded-xl border border-neutral-800 bg-neutral-900/50 overflow-hidden">
|
|
154
|
+
<div className="p-3 border-b border-neutral-800">
|
|
155
|
+
<div className="flex items-center gap-2 mb-3">
|
|
156
|
+
<Package className="w-4 h-4 text-neutral-400" />
|
|
157
|
+
<span className="text-sm font-medium text-white">
|
|
158
|
+
Tools ({tools.length})
|
|
159
|
+
</span>
|
|
160
|
+
{isConnected && (
|
|
161
|
+
<span className="px-1.5 py-0.5 text-xs rounded bg-green-500/20 text-green-400">
|
|
162
|
+
Live
|
|
163
|
+
</span>
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
<div className="relative">
|
|
167
|
+
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-neutral-500" />
|
|
168
|
+
<Input
|
|
169
|
+
type="text"
|
|
170
|
+
value={searchQuery}
|
|
171
|
+
onChange={(e) => setSearchQuery(e.target.value)}
|
|
172
|
+
placeholder="Search tools..."
|
|
173
|
+
className="pl-9 h-9 text-sm"
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<div className="max-h-[400px] overflow-y-auto">
|
|
179
|
+
{filteredTools.length === 0 ? (
|
|
180
|
+
<div className="p-4 text-center">
|
|
181
|
+
<AlertCircle className="w-8 h-8 text-neutral-600 mx-auto mb-2" />
|
|
182
|
+
<p className="text-sm text-neutral-500">No tools found</p>
|
|
183
|
+
</div>
|
|
184
|
+
) : (
|
|
185
|
+
filteredTools.map((tool) => {
|
|
186
|
+
const isSelected = selectedTool?.name === tool.name;
|
|
187
|
+
const sourceColor = SOURCE_COLORS[tool.source?.type || 'universal'] || SOURCE_COLORS.universal;
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<button
|
|
191
|
+
key={tool.name}
|
|
192
|
+
onClick={() => setSelectedTool(tool)}
|
|
193
|
+
className={`w-full p-3 flex items-start gap-3 text-left transition-colors ${
|
|
194
|
+
isSelected
|
|
195
|
+
? 'bg-white/10 border-l-2 border-white'
|
|
196
|
+
: 'hover:bg-white/5 border-l-2 border-transparent'
|
|
197
|
+
}`}
|
|
198
|
+
>
|
|
199
|
+
<div className="flex-shrink-0 mt-0.5">
|
|
200
|
+
<ChevronRight
|
|
201
|
+
className={`w-4 h-4 transition-transform ${
|
|
202
|
+
isSelected ? 'text-white rotate-90' : 'text-neutral-500'
|
|
203
|
+
}`}
|
|
204
|
+
/>
|
|
205
|
+
</div>
|
|
206
|
+
<div className="flex-1 min-w-0">
|
|
207
|
+
<span
|
|
208
|
+
className={`font-medium truncate block ${
|
|
209
|
+
isSelected ? 'text-white' : 'text-neutral-300'
|
|
210
|
+
}`}
|
|
211
|
+
>
|
|
212
|
+
{tool.name}
|
|
213
|
+
</span>
|
|
214
|
+
<p className="text-xs text-neutral-500 line-clamp-2 mt-0.5">
|
|
215
|
+
{tool.description || 'No description'}
|
|
216
|
+
</p>
|
|
217
|
+
<div className="flex items-center gap-2 mt-1.5">
|
|
218
|
+
<span className={`px-1.5 py-0.5 text-xs rounded ${sourceColor}`}>
|
|
219
|
+
{tool.source?.type || 'unknown'}
|
|
220
|
+
</span>
|
|
221
|
+
<span className="text-xs text-neutral-600">
|
|
222
|
+
{Object.keys(tool.inputSchema?.properties || {}).length} params
|
|
223
|
+
</span>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
</button>
|
|
227
|
+
);
|
|
228
|
+
})
|
|
229
|
+
)}
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
{/* Tool tester - right panel */}
|
|
234
|
+
<div className="lg:col-span-2">
|
|
235
|
+
{selectedTool ? (
|
|
236
|
+
<PlaygroundToolTester
|
|
237
|
+
tool={selectedTool}
|
|
238
|
+
onExecute={handleExecute}
|
|
239
|
+
isDemoMode={!isConnected}
|
|
240
|
+
isExecuting={isLoading}
|
|
241
|
+
/>
|
|
242
|
+
) : (
|
|
243
|
+
<div className="h-full flex items-center justify-center rounded-xl border border-neutral-800 bg-neutral-900/50 p-8">
|
|
244
|
+
<div className="text-center">
|
|
245
|
+
<Terminal className="w-12 h-12 text-neutral-600 mx-auto mb-4" />
|
|
246
|
+
<h3 className="text-lg font-medium text-neutral-400 mb-2">
|
|
247
|
+
Select a Tool
|
|
248
|
+
</h3>
|
|
249
|
+
<p className="text-sm text-neutral-500">
|
|
250
|
+
Choose a tool from the list to test it
|
|
251
|
+
</p>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
)}
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
);
|
|
259
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loading Steps Component - Shows conversion progress with real-time streaming
|
|
3
|
+
* @copyright 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use client';
|
|
8
|
+
|
|
9
|
+
import { useState, useEffect } from 'react';
|
|
10
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
11
|
+
import {
|
|
12
|
+
Github,
|
|
13
|
+
Code2,
|
|
14
|
+
Package,
|
|
15
|
+
Terminal,
|
|
16
|
+
Check,
|
|
17
|
+
Loader2,
|
|
18
|
+
FileSearch,
|
|
19
|
+
Layers,
|
|
20
|
+
FileJson,
|
|
21
|
+
Sparkles,
|
|
22
|
+
AlertCircle,
|
|
23
|
+
Braces,
|
|
24
|
+
} from 'lucide-react';
|
|
25
|
+
import type { StreamingStep } from '@/hooks/use-streaming-conversion';
|
|
26
|
+
|
|
27
|
+
// Icon mapping for each step
|
|
28
|
+
const STEP_ICONS: Record<string, typeof Github> = {
|
|
29
|
+
'validate': Github,
|
|
30
|
+
'fetch': Github,
|
|
31
|
+
'classify': Layers,
|
|
32
|
+
'readme': FileSearch,
|
|
33
|
+
'openapi': FileJson,
|
|
34
|
+
'code': Braces,
|
|
35
|
+
'generate-ts': Terminal,
|
|
36
|
+
'generate-py': Code2,
|
|
37
|
+
'configs': Package,
|
|
38
|
+
'complete': Sparkles,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
interface LoadingStepsProps {
|
|
42
|
+
steps?: StreamingStep[];
|
|
43
|
+
currentStep?: string | null;
|
|
44
|
+
progress?: number;
|
|
45
|
+
isStreaming?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Step status type
|
|
49
|
+
type StepStatus = 'pending' | 'in-progress' | 'complete' | 'error';
|
|
50
|
+
|
|
51
|
+
// Internal step type
|
|
52
|
+
interface InternalStep {
|
|
53
|
+
id: string;
|
|
54
|
+
label: string;
|
|
55
|
+
description: string;
|
|
56
|
+
detail?: string;
|
|
57
|
+
status: StepStatus;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Default steps for fallback/non-streaming mode
|
|
61
|
+
const DEFAULT_STEPS: InternalStep[] = [
|
|
62
|
+
{ id: 'fetch', label: 'Fetching repository', description: 'Cloning and analyzing repo structure', status: 'pending' },
|
|
63
|
+
{ id: 'classify', label: 'Classifying repository', description: 'Detecting repo type and structure', status: 'pending' },
|
|
64
|
+
{ id: 'readme', label: 'Analyzing README', description: 'Extracting documentation and examples', status: 'pending' },
|
|
65
|
+
{ id: 'openapi', label: 'Scanning for OpenAPI specs', description: 'Looking for API definitions', status: 'pending' },
|
|
66
|
+
{ id: 'code', label: 'Analyzing code', description: 'Extracting functions and patterns', status: 'pending' },
|
|
67
|
+
{ id: 'generate-ts', label: 'Generating TypeScript server', description: 'Creating MCP server code', status: 'pending' },
|
|
68
|
+
{ id: 'configs', label: 'Creating configurations', description: 'Building platform configs', status: 'pending' },
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
export default function LoadingSteps({
|
|
72
|
+
steps: externalSteps,
|
|
73
|
+
currentStep: externalCurrentStep,
|
|
74
|
+
progress: externalProgress = 0,
|
|
75
|
+
isStreaming = false,
|
|
76
|
+
}: LoadingStepsProps) {
|
|
77
|
+
const [internalSteps, setInternalSteps] = useState<InternalStep[]>(DEFAULT_STEPS);
|
|
78
|
+
const [internalCurrentStep, setInternalCurrentStep] = useState(0);
|
|
79
|
+
const [internalProgress, setInternalProgress] = useState(0);
|
|
80
|
+
|
|
81
|
+
// Use external steps if streaming, otherwise use internal simulation
|
|
82
|
+
const displaySteps = isStreaming && externalSteps ? externalSteps : internalSteps;
|
|
83
|
+
const displayProgress = isStreaming ? externalProgress : internalProgress;
|
|
84
|
+
|
|
85
|
+
// Simulate progress for non-streaming mode
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (isStreaming) return;
|
|
88
|
+
|
|
89
|
+
const timers: NodeJS.Timeout[] = [];
|
|
90
|
+
let totalTime = 0;
|
|
91
|
+
const stepDurations = [800, 1200, 1000, 1500, 1200, 800, 600];
|
|
92
|
+
|
|
93
|
+
DEFAULT_STEPS.forEach((step, index) => {
|
|
94
|
+
const duration = stepDurations[index] || 1000;
|
|
95
|
+
|
|
96
|
+
// Start step
|
|
97
|
+
const startTimer = setTimeout(() => {
|
|
98
|
+
setInternalCurrentStep(index);
|
|
99
|
+
setInternalSteps(prev => prev.map((s, i) => ({
|
|
100
|
+
...s,
|
|
101
|
+
status: i < index ? 'complete' as const : i === index ? 'in-progress' as const : 'pending' as const,
|
|
102
|
+
})));
|
|
103
|
+
setInternalProgress(Math.round((index / DEFAULT_STEPS.length) * 100));
|
|
104
|
+
}, totalTime);
|
|
105
|
+
timers.push(startTimer);
|
|
106
|
+
|
|
107
|
+
// Complete step
|
|
108
|
+
const completeTimer = setTimeout(() => {
|
|
109
|
+
setInternalSteps(prev => prev.map((s, i) => ({
|
|
110
|
+
...s,
|
|
111
|
+
status: i <= index ? 'complete' as const : s.status,
|
|
112
|
+
})));
|
|
113
|
+
setInternalProgress(Math.round(((index + 1) / DEFAULT_STEPS.length) * 100));
|
|
114
|
+
}, totalTime + duration - 200);
|
|
115
|
+
timers.push(completeTimer);
|
|
116
|
+
|
|
117
|
+
totalTime += duration;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
return () => {
|
|
121
|
+
timers.forEach(timer => clearTimeout(timer));
|
|
122
|
+
};
|
|
123
|
+
}, [isStreaming]);
|
|
124
|
+
|
|
125
|
+
// Filter to show relevant steps (skip validate step as it's instant)
|
|
126
|
+
const visibleSteps = displaySteps.filter(s => s.id !== 'validate' && s.id !== 'complete');
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<div className="max-w-xl mx-auto">
|
|
130
|
+
<div className="rounded-2xl border border-neutral-800 p-8 bg-neutral-900/50 backdrop-blur-xl">
|
|
131
|
+
{/* Header with animated progress ring */}
|
|
132
|
+
<div className="text-center mb-8">
|
|
133
|
+
<div className="relative inline-flex items-center justify-center w-20 h-20 mb-4">
|
|
134
|
+
{/* Background ring */}
|
|
135
|
+
<svg className="absolute inset-0 w-20 h-20 -rotate-90">
|
|
136
|
+
<circle
|
|
137
|
+
cx="40"
|
|
138
|
+
cy="40"
|
|
139
|
+
r="36"
|
|
140
|
+
stroke="currentColor"
|
|
141
|
+
strokeWidth="4"
|
|
142
|
+
fill="none"
|
|
143
|
+
className="text-neutral-800"
|
|
144
|
+
/>
|
|
145
|
+
<motion.circle
|
|
146
|
+
cx="40"
|
|
147
|
+
cy="40"
|
|
148
|
+
r="36"
|
|
149
|
+
stroke="currentColor"
|
|
150
|
+
strokeWidth="4"
|
|
151
|
+
fill="none"
|
|
152
|
+
strokeLinecap="round"
|
|
153
|
+
className="text-white"
|
|
154
|
+
initial={{ pathLength: 0 }}
|
|
155
|
+
animate={{ pathLength: displayProgress / 100 }}
|
|
156
|
+
transition={{ duration: 0.5, ease: 'easeOut' }}
|
|
157
|
+
style={{
|
|
158
|
+
strokeDasharray: '226.19',
|
|
159
|
+
strokeDashoffset: 0,
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
162
|
+
</svg>
|
|
163
|
+
{/* Center content */}
|
|
164
|
+
<div className="absolute inset-0 flex items-center justify-center">
|
|
165
|
+
<span className="text-2xl font-bold text-white font-mono">{displayProgress}%</span>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
|
|
169
|
+
<h2 className="text-2xl font-bold text-white mb-2">Converting Repository</h2>
|
|
170
|
+
<p className="text-neutral-400">
|
|
171
|
+
{isStreaming ? 'Real-time extraction in progress...' : 'Analyzing and extracting tools...'}
|
|
172
|
+
</p>
|
|
173
|
+
</div>
|
|
174
|
+
|
|
175
|
+
{/* Progress bar */}
|
|
176
|
+
<div className="mb-8">
|
|
177
|
+
<div className="h-1.5 bg-neutral-800 rounded-full overflow-hidden">
|
|
178
|
+
<motion.div
|
|
179
|
+
className="h-full bg-gradient-to-r from-white to-neutral-400 rounded-full"
|
|
180
|
+
initial={{ width: 0 }}
|
|
181
|
+
animate={{ width: `${displayProgress}%` }}
|
|
182
|
+
transition={{ duration: 0.3, ease: 'easeOut' }}
|
|
183
|
+
/>
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
{/* Steps list */}
|
|
188
|
+
<div className="space-y-3">
|
|
189
|
+
<AnimatePresence mode="popLayout">
|
|
190
|
+
{visibleSteps.map((step) => {
|
|
191
|
+
const Icon = STEP_ICONS[step.id] || Package;
|
|
192
|
+
const isActive = step.status === 'in-progress';
|
|
193
|
+
const isCompleted = step.status === 'complete';
|
|
194
|
+
const isError = step.status === 'error';
|
|
195
|
+
const isPending = step.status === 'pending';
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<motion.div
|
|
199
|
+
key={step.id}
|
|
200
|
+
initial={{ opacity: 0, x: -20 }}
|
|
201
|
+
animate={{ opacity: 1, x: 0 }}
|
|
202
|
+
exit={{ opacity: 0, x: 20 }}
|
|
203
|
+
layout
|
|
204
|
+
className={`flex items-center gap-4 p-4 rounded-xl border transition-all duration-300 ${
|
|
205
|
+
isActive
|
|
206
|
+
? 'border-white/30 bg-white/5 shadow-lg shadow-white/5'
|
|
207
|
+
: isCompleted
|
|
208
|
+
? 'border-green-500/20 bg-green-500/5'
|
|
209
|
+
: isError
|
|
210
|
+
? 'border-red-500/30 bg-red-500/5'
|
|
211
|
+
: 'border-neutral-800/50 bg-transparent opacity-50'
|
|
212
|
+
}`}
|
|
213
|
+
>
|
|
214
|
+
{/* Icon */}
|
|
215
|
+
<div className={`w-10 h-10 rounded-lg flex items-center justify-center transition-all ${
|
|
216
|
+
isCompleted
|
|
217
|
+
? 'bg-green-500/20 border border-green-500/30'
|
|
218
|
+
: isError
|
|
219
|
+
? 'bg-red-500/20 border border-red-500/30'
|
|
220
|
+
: isActive
|
|
221
|
+
? 'bg-white/10 border border-white/20'
|
|
222
|
+
: 'bg-neutral-800/50 border border-neutral-700/50'
|
|
223
|
+
}`}>
|
|
224
|
+
{isCompleted ? (
|
|
225
|
+
<motion.div
|
|
226
|
+
initial={{ scale: 0 }}
|
|
227
|
+
animate={{ scale: 1 }}
|
|
228
|
+
transition={{ type: 'spring', stiffness: 300 }}
|
|
229
|
+
>
|
|
230
|
+
<Check className="w-5 h-5 text-green-400" />
|
|
231
|
+
</motion.div>
|
|
232
|
+
) : isError ? (
|
|
233
|
+
<AlertCircle className="w-5 h-5 text-red-400" />
|
|
234
|
+
) : isActive ? (
|
|
235
|
+
<motion.div
|
|
236
|
+
animate={{ rotate: 360 }}
|
|
237
|
+
transition={{ duration: 2, repeat: Infinity, ease: 'linear' }}
|
|
238
|
+
>
|
|
239
|
+
<Icon className="w-5 h-5 text-white" />
|
|
240
|
+
</motion.div>
|
|
241
|
+
) : (
|
|
242
|
+
<Icon className="w-5 h-5 text-neutral-500" />
|
|
243
|
+
)}
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
{/* Text content */}
|
|
247
|
+
<div className="flex-1 min-w-0">
|
|
248
|
+
<div className={`font-medium transition-colors ${
|
|
249
|
+
isCompleted ? 'text-green-400' :
|
|
250
|
+
isError ? 'text-red-400' :
|
|
251
|
+
isActive ? 'text-white' :
|
|
252
|
+
'text-neutral-500'
|
|
253
|
+
}`}>
|
|
254
|
+
{step.label}
|
|
255
|
+
</div>
|
|
256
|
+
<div className={`text-sm truncate transition-colors ${
|
|
257
|
+
isActive ? 'text-neutral-400' : 'text-neutral-600'
|
|
258
|
+
}`}>
|
|
259
|
+
{(step.detail ?? step.description) || ''}
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
{/* Status indicator */}
|
|
264
|
+
{isActive && (
|
|
265
|
+
<motion.div
|
|
266
|
+
className="flex items-center gap-1"
|
|
267
|
+
initial={{ opacity: 0 }}
|
|
268
|
+
animate={{ opacity: 1 }}
|
|
269
|
+
>
|
|
270
|
+
<motion.div
|
|
271
|
+
className="w-1.5 h-1.5 rounded-full bg-white"
|
|
272
|
+
animate={{ opacity: [1, 0.3, 1] }}
|
|
273
|
+
transition={{ duration: 1, repeat: Infinity }}
|
|
274
|
+
/>
|
|
275
|
+
<motion.div
|
|
276
|
+
className="w-1.5 h-1.5 rounded-full bg-white"
|
|
277
|
+
animate={{ opacity: [0.3, 1, 0.3] }}
|
|
278
|
+
transition={{ duration: 1, repeat: Infinity }}
|
|
279
|
+
/>
|
|
280
|
+
<motion.div
|
|
281
|
+
className="w-1.5 h-1.5 rounded-full bg-white"
|
|
282
|
+
animate={{ opacity: [1, 0.3, 1] }}
|
|
283
|
+
transition={{ duration: 1, repeat: Infinity, delay: 0.3 }}
|
|
284
|
+
/>
|
|
285
|
+
</motion.div>
|
|
286
|
+
)}
|
|
287
|
+
|
|
288
|
+
{isCompleted && (
|
|
289
|
+
<span className="text-xs text-green-400/70 font-mono">✓</span>
|
|
290
|
+
)}
|
|
291
|
+
</motion.div>
|
|
292
|
+
);
|
|
293
|
+
})}
|
|
294
|
+
</AnimatePresence>
|
|
295
|
+
</div>
|
|
296
|
+
|
|
297
|
+
{/* Fun tip at bottom */}
|
|
298
|
+
<motion.div
|
|
299
|
+
initial={{ opacity: 0 }}
|
|
300
|
+
animate={{ opacity: 1 }}
|
|
301
|
+
transition={{ delay: 2 }}
|
|
302
|
+
className="mt-6 pt-6 border-t border-neutral-800"
|
|
303
|
+
>
|
|
304
|
+
<p className="text-xs text-neutral-500 text-center">
|
|
305
|
+
💡 Tip: Generated MCP servers work with Claude Desktop, Cursor, and other MCP-compatible tools
|
|
306
|
+
</p>
|
|
307
|
+
</motion.div>
|
|
308
|
+
</div>
|
|
309
|
+
</div>
|
|
310
|
+
);
|
|
311
|
+
}
|