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,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Unit tests for streaming module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
6
|
+
import {
|
|
7
|
+
StreamingGenerator,
|
|
8
|
+
streamGenerate,
|
|
9
|
+
collectStreamEvents,
|
|
10
|
+
streamToResult,
|
|
11
|
+
StreamEvent
|
|
12
|
+
} from '../streaming';
|
|
13
|
+
|
|
14
|
+
// Mock the imports
|
|
15
|
+
vi.mock('../github-client', () => ({
|
|
16
|
+
GithubClient: vi.fn().mockImplementation(() => ({
|
|
17
|
+
parseGithubUrl: vi.fn().mockReturnValue({ owner: 'test', repo: 'repo' }),
|
|
18
|
+
getRepoMetadata: vi.fn().mockResolvedValue({
|
|
19
|
+
stars: 100,
|
|
20
|
+
language: 'TypeScript',
|
|
21
|
+
license: 'MIT',
|
|
22
|
+
description: 'Test repo'
|
|
23
|
+
}),
|
|
24
|
+
getReadme: vi.fn().mockResolvedValue('# Test Repo\n\nThis is a test'),
|
|
25
|
+
getFile: vi.fn().mockResolvedValue(null),
|
|
26
|
+
searchCode: vi.fn().mockResolvedValue([])
|
|
27
|
+
}))
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
vi.mock('../readme-extractor', () => ({
|
|
31
|
+
ReadmeExtractor: vi.fn().mockImplementation(() => ({
|
|
32
|
+
extract: vi.fn().mockResolvedValue([])
|
|
33
|
+
}))
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
vi.mock('../code-extractor', () => ({
|
|
37
|
+
CodeExtractor: vi.fn().mockImplementation(() => ({
|
|
38
|
+
extract: vi.fn().mockResolvedValue([])
|
|
39
|
+
}))
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
vi.mock('../graphql-extractor', () => ({
|
|
43
|
+
GraphQLExtractor: vi.fn().mockImplementation(() => ({
|
|
44
|
+
extract: vi.fn().mockResolvedValue([])
|
|
45
|
+
}))
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
vi.mock('../mcp-introspector', () => ({
|
|
49
|
+
McpIntrospector: vi.fn().mockImplementation(() => ({
|
|
50
|
+
extract: vi.fn().mockResolvedValue([])
|
|
51
|
+
}))
|
|
52
|
+
}));
|
|
53
|
+
|
|
54
|
+
vi.mock('../python-generator', () => ({
|
|
55
|
+
PythonGenerator: vi.fn().mockImplementation(() => ({
|
|
56
|
+
generateServer: vi.fn().mockReturnValue('# Python MCP Server')
|
|
57
|
+
}))
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
vi.mock('@github-to-mcp/openapi-parser', () => ({
|
|
61
|
+
convertOpenApiToMcp: vi.fn().mockResolvedValue([])
|
|
62
|
+
}));
|
|
63
|
+
|
|
64
|
+
describe('StreamingGenerator', () => {
|
|
65
|
+
let generator: StreamingGenerator;
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
generator = new StreamingGenerator();
|
|
69
|
+
vi.clearAllMocks();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
describe('generate', () => {
|
|
73
|
+
it('should emit start event first', async () => {
|
|
74
|
+
const events: StreamEvent[] = [];
|
|
75
|
+
|
|
76
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
77
|
+
events.push(event);
|
|
78
|
+
if (event.type === 'metadata') break; // Stop early for test
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
expect(events[0].type).toBe('start');
|
|
82
|
+
expect((events[0] as any).owner).toBe('test');
|
|
83
|
+
expect((events[0] as any).repo).toBe('repo');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('should emit metadata event after start', async () => {
|
|
87
|
+
const events: StreamEvent[] = [];
|
|
88
|
+
|
|
89
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
90
|
+
events.push(event);
|
|
91
|
+
if (event.type === 'metadata') break;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const metadataEvent = events.find(e => e.type === 'metadata');
|
|
95
|
+
expect(metadataEvent).toBeDefined();
|
|
96
|
+
expect((metadataEvent as any).metadata.stars).toBe(100);
|
|
97
|
+
expect((metadataEvent as any).metadata.language).toBe('TypeScript');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should emit classifying and classified events', async () => {
|
|
101
|
+
const events: StreamEvent[] = [];
|
|
102
|
+
|
|
103
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
104
|
+
events.push(event);
|
|
105
|
+
if (event.type === 'classified') break;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const classifyingEvent = events.find(e => e.type === 'classifying');
|
|
109
|
+
const classifiedEvent = events.find(e => e.type === 'classified');
|
|
110
|
+
|
|
111
|
+
expect(classifyingEvent).toBeDefined();
|
|
112
|
+
expect(classifiedEvent).toBeDefined();
|
|
113
|
+
expect((classifiedEvent as any).classification).toBeDefined();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should emit extracting events for each source', async () => {
|
|
117
|
+
const events: StreamEvent[] = [];
|
|
118
|
+
|
|
119
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
120
|
+
events.push(event);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const extractingEvents = events.filter(e => e.type === 'extracting');
|
|
124
|
+
expect(extractingEvents.length).toBeGreaterThan(0);
|
|
125
|
+
|
|
126
|
+
// Should have events for different sources
|
|
127
|
+
const sources = extractingEvents.map(e => (e as any).source);
|
|
128
|
+
expect(sources).toContain('universal');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('should emit source-complete events', async () => {
|
|
132
|
+
const events: StreamEvent[] = [];
|
|
133
|
+
|
|
134
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
135
|
+
events.push(event);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const sourceCompleteEvents = events.filter(e => e.type === 'source-complete');
|
|
139
|
+
expect(sourceCompleteEvents.length).toBeGreaterThan(0);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should emit tool-found events for universal tools', async () => {
|
|
143
|
+
const events: StreamEvent[] = [];
|
|
144
|
+
|
|
145
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
146
|
+
events.push(event);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const toolFoundEvents = events.filter(e => e.type === 'tool-found');
|
|
150
|
+
expect(toolFoundEvents.length).toBeGreaterThan(0);
|
|
151
|
+
|
|
152
|
+
// Should have universal tools
|
|
153
|
+
const toolNames = toolFoundEvents.map(e => (e as any).tool.name);
|
|
154
|
+
expect(toolNames).toContain('get_readme');
|
|
155
|
+
expect(toolNames).toContain('list_files');
|
|
156
|
+
expect(toolNames).toContain('read_file');
|
|
157
|
+
expect(toolNames).toContain('search_code');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should emit complete event with result', async () => {
|
|
161
|
+
const events: StreamEvent[] = [];
|
|
162
|
+
|
|
163
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
164
|
+
events.push(event);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const completeEvent = events.find(e => e.type === 'complete');
|
|
168
|
+
expect(completeEvent).toBeDefined();
|
|
169
|
+
expect((completeEvent as any).result).toBeDefined();
|
|
170
|
+
expect((completeEvent as any).totalTools).toBeGreaterThan(0);
|
|
171
|
+
expect((completeEvent as any).duration).toBeGreaterThan(0);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should emit progress events when enabled', async () => {
|
|
175
|
+
const progressGenerator = new StreamingGenerator({ emitProgress: true });
|
|
176
|
+
const events: StreamEvent[] = [];
|
|
177
|
+
|
|
178
|
+
for await (const event of progressGenerator.generate('https://github.com/test/repo')) {
|
|
179
|
+
events.push(event);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const progressEvents = events.filter(e => e.type === 'progress');
|
|
183
|
+
expect(progressEvents.length).toBeGreaterThan(0);
|
|
184
|
+
|
|
185
|
+
// Progress should go from 0 to 100
|
|
186
|
+
const lastProgress = progressEvents[progressEvents.length - 1] as any;
|
|
187
|
+
expect(lastProgress.progress).toBe(100);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should include timestamps in all events', async () => {
|
|
191
|
+
for await (const event of generator.generate('https://github.com/test/repo')) {
|
|
192
|
+
expect(event.timestamp).toBeDefined();
|
|
193
|
+
expect(typeof event.timestamp).toBe('number');
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
describe('with abort signal', () => {
|
|
199
|
+
it('should support abort signal configuration', async () => {
|
|
200
|
+
const controller = new AbortController();
|
|
201
|
+
const abortGenerator = new StreamingGenerator({ abortSignal: controller.signal });
|
|
202
|
+
|
|
203
|
+
// Test that we can create a generator with an abort signal
|
|
204
|
+
expect(abortGenerator).toBeDefined();
|
|
205
|
+
|
|
206
|
+
// Abort immediately
|
|
207
|
+
controller.abort();
|
|
208
|
+
|
|
209
|
+
const events: StreamEvent[] = [];
|
|
210
|
+
try {
|
|
211
|
+
for await (const event of abortGenerator.generate('https://github.com/test/repo')) {
|
|
212
|
+
events.push(event);
|
|
213
|
+
}
|
|
214
|
+
} catch {
|
|
215
|
+
// Expected - abort may throw
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// With immediate abort, should either have error, be incomplete, or have been handled gracefully
|
|
219
|
+
expect(events).toBeDefined();
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('streamGenerate', () => {
|
|
225
|
+
it('should be an async generator function', async () => {
|
|
226
|
+
const gen = streamGenerate('https://github.com/test/repo');
|
|
227
|
+
expect(gen[Symbol.asyncIterator]).toBeDefined();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe('collectStreamEvents', () => {
|
|
232
|
+
it('should collect all events into an array', async () => {
|
|
233
|
+
const events = await collectStreamEvents('https://github.com/test/repo');
|
|
234
|
+
|
|
235
|
+
expect(Array.isArray(events)).toBe(true);
|
|
236
|
+
expect(events.length).toBeGreaterThan(0);
|
|
237
|
+
expect(events[0].type).toBe('start');
|
|
238
|
+
expect(events[events.length - 1].type).toBe('complete');
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe('streamToResult', () => {
|
|
243
|
+
it('should return the final result', async () => {
|
|
244
|
+
const result = await streamToResult('https://github.com/test/repo');
|
|
245
|
+
|
|
246
|
+
expect(result).toBeDefined();
|
|
247
|
+
expect(result?.name).toBe('repo');
|
|
248
|
+
expect(result?.tools).toBeDefined();
|
|
249
|
+
expect(result?.tools.length).toBeGreaterThan(0);
|
|
250
|
+
});
|
|
251
|
+
});
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Additional source extractors for tools
|
|
3
|
+
* @copyright Copyright (c) 2024-2026 nirholas
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { ExtractedTool, ConfidenceFactors } from './types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Calculate confidence score for extracted tools
|
|
11
|
+
*/
|
|
12
|
+
function calculateConfidence(
|
|
13
|
+
hasDescription: boolean,
|
|
14
|
+
hasParams: boolean,
|
|
15
|
+
sourceType: string
|
|
16
|
+
): { confidence: number; factors: ConfidenceFactors } {
|
|
17
|
+
const factors: ConfidenceFactors = {
|
|
18
|
+
documentation: hasDescription ? 0.7 : 0.2,
|
|
19
|
+
types: hasParams ? 0.5 : 0.2,
|
|
20
|
+
examples: 0, // Scripts typically don't have examples
|
|
21
|
+
source: sourceType === 'code' ? 0.6 : 0.4
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const confidence = (
|
|
25
|
+
factors.documentation * 0.35 +
|
|
26
|
+
factors.types * 0.25 +
|
|
27
|
+
factors.examples * 0.15 +
|
|
28
|
+
factors.source * 0.25
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return { confidence: Math.round(confidence * 100) / 100, factors };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extract development tools from CONTRIBUTING.md
|
|
36
|
+
*/
|
|
37
|
+
export function extractFromContributing(content: string, filename: string): ExtractedTool[] {
|
|
38
|
+
const tools: ExtractedTool[] = [];
|
|
39
|
+
const lines = content.split('\n');
|
|
40
|
+
|
|
41
|
+
let inCodeBlock = false;
|
|
42
|
+
let currentCommand = '';
|
|
43
|
+
let currentDescription = '';
|
|
44
|
+
|
|
45
|
+
for (let i = 0; i < lines.length; i++) {
|
|
46
|
+
const line = lines[i];
|
|
47
|
+
|
|
48
|
+
// Track code blocks
|
|
49
|
+
if (line.trim().startsWith('```')) {
|
|
50
|
+
inCodeBlock = !inCodeBlock;
|
|
51
|
+
if (!inCodeBlock && currentCommand) {
|
|
52
|
+
const tool = parseCommandTool(currentCommand, currentDescription, filename, i);
|
|
53
|
+
if (tool) tools.push(tool);
|
|
54
|
+
currentCommand = '';
|
|
55
|
+
currentDescription = '';
|
|
56
|
+
}
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (inCodeBlock) {
|
|
61
|
+
// Look for commands
|
|
62
|
+
const cmdMatch = line.match(/^\s*(?:\$\s+)?(npm\s+run\s+\w+|make\s+\w+|pnpm\s+\w+|yarn\s+\w+|cargo\s+\w+|go\s+\w+)/);
|
|
63
|
+
if (cmdMatch) {
|
|
64
|
+
currentCommand = cmdMatch[1];
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
// Look for descriptions before code blocks
|
|
68
|
+
if (line.trim() && !line.startsWith('#')) {
|
|
69
|
+
currentDescription = line.trim();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return tools;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Parse a command into a tool
|
|
79
|
+
*/
|
|
80
|
+
function parseCommandTool(
|
|
81
|
+
command: string,
|
|
82
|
+
description: string,
|
|
83
|
+
filename: string,
|
|
84
|
+
line: number
|
|
85
|
+
): ExtractedTool | null {
|
|
86
|
+
const parts = command.split(/\s+/);
|
|
87
|
+
if (parts.length < 2) return null;
|
|
88
|
+
|
|
89
|
+
const runner = parts[0]; // npm, make, yarn, etc.
|
|
90
|
+
const taskName = parts.slice(1).join('_');
|
|
91
|
+
|
|
92
|
+
const name = `run_${taskName}`;
|
|
93
|
+
const { confidence, factors } = calculateConfidence(!!description, false, 'docs');
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
name,
|
|
97
|
+
description: description || `Run ${command}`,
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: 'object',
|
|
100
|
+
properties: {},
|
|
101
|
+
required: []
|
|
102
|
+
},
|
|
103
|
+
source: {
|
|
104
|
+
type: 'docs',
|
|
105
|
+
file: filename,
|
|
106
|
+
line
|
|
107
|
+
},
|
|
108
|
+
confidence,
|
|
109
|
+
confidenceFactors: factors
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Extract tools from Makefile targets
|
|
115
|
+
*/
|
|
116
|
+
export function extractFromMakefile(content: string, filename: string): ExtractedTool[] {
|
|
117
|
+
const tools: ExtractedTool[] = [];
|
|
118
|
+
const lines = content.split('\n');
|
|
119
|
+
|
|
120
|
+
let currentComment = '';
|
|
121
|
+
|
|
122
|
+
for (let i = 0; i < lines.length; i++) {
|
|
123
|
+
const line = lines[i];
|
|
124
|
+
|
|
125
|
+
// Capture comments
|
|
126
|
+
if (line.startsWith('#')) {
|
|
127
|
+
currentComment = line.substring(1).trim();
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Match target definitions
|
|
132
|
+
const targetMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_-]*)\s*:/);
|
|
133
|
+
if (targetMatch) {
|
|
134
|
+
const targetName = targetMatch[1];
|
|
135
|
+
|
|
136
|
+
// Skip common internal targets
|
|
137
|
+
if (targetName.startsWith('.') || ['all', 'default'].includes(targetName)) {
|
|
138
|
+
currentComment = '';
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const { confidence, factors } = calculateConfidence(!!currentComment, false, 'code');
|
|
143
|
+
|
|
144
|
+
tools.push({
|
|
145
|
+
name: `make_${targetName}`,
|
|
146
|
+
description: currentComment || `Run make target: ${targetName}`,
|
|
147
|
+
inputSchema: {
|
|
148
|
+
type: 'object',
|
|
149
|
+
properties: {},
|
|
150
|
+
required: []
|
|
151
|
+
},
|
|
152
|
+
source: {
|
|
153
|
+
type: 'code',
|
|
154
|
+
file: filename,
|
|
155
|
+
line: i + 1
|
|
156
|
+
},
|
|
157
|
+
confidence,
|
|
158
|
+
confidenceFactors: factors
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
currentComment = '';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return tools;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Extract tools from package.json scripts
|
|
170
|
+
*/
|
|
171
|
+
export function extractFromPackageJson(content: string, filename: string): ExtractedTool[] {
|
|
172
|
+
const tools: ExtractedTool[] = [];
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
const pkg = JSON.parse(content);
|
|
176
|
+
const scripts = pkg.scripts || {};
|
|
177
|
+
|
|
178
|
+
for (const [name, command] of Object.entries(scripts)) {
|
|
179
|
+
if (typeof command !== 'string') continue;
|
|
180
|
+
|
|
181
|
+
// Skip lifecycle scripts
|
|
182
|
+
if (name.startsWith('pre') || name.startsWith('post')) continue;
|
|
183
|
+
|
|
184
|
+
// Try to extract description from comments in command or script name
|
|
185
|
+
const description = getScriptDescription(name, command as string);
|
|
186
|
+
const { confidence, factors } = calculateConfidence(true, false, 'code');
|
|
187
|
+
|
|
188
|
+
tools.push({
|
|
189
|
+
name: `npm_run_${name.replace(/[:-]/g, '_')}`,
|
|
190
|
+
description,
|
|
191
|
+
inputSchema: {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {},
|
|
194
|
+
required: []
|
|
195
|
+
},
|
|
196
|
+
source: {
|
|
197
|
+
type: 'code',
|
|
198
|
+
file: filename
|
|
199
|
+
},
|
|
200
|
+
confidence,
|
|
201
|
+
confidenceFactors: factors
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
// Invalid JSON
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return tools;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get description for a script based on its name and command
|
|
213
|
+
*/
|
|
214
|
+
function getScriptDescription(name: string, command: string): string {
|
|
215
|
+
// Common script patterns
|
|
216
|
+
const descriptions: Record<string, string> = {
|
|
217
|
+
'build': 'Build the project',
|
|
218
|
+
'test': 'Run tests',
|
|
219
|
+
'dev': 'Start development server',
|
|
220
|
+
'start': 'Start the application',
|
|
221
|
+
'lint': 'Run linter',
|
|
222
|
+
'format': 'Format code',
|
|
223
|
+
'clean': 'Clean build artifacts',
|
|
224
|
+
'typecheck': 'Run type checker',
|
|
225
|
+
'watch': 'Watch for changes and rebuild',
|
|
226
|
+
'deploy': 'Deploy the application',
|
|
227
|
+
'docs': 'Generate documentation',
|
|
228
|
+
'serve': 'Serve the application',
|
|
229
|
+
'coverage': 'Run tests with coverage'
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Check for exact match
|
|
233
|
+
if (descriptions[name]) {
|
|
234
|
+
return descriptions[name];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Check for partial match
|
|
238
|
+
for (const [key, desc] of Object.entries(descriptions)) {
|
|
239
|
+
if (name.includes(key)) {
|
|
240
|
+
return desc;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Generate from command
|
|
245
|
+
if (command.includes('tsc')) return 'Compile TypeScript';
|
|
246
|
+
if (command.includes('jest') || command.includes('vitest') || command.includes('mocha')) return 'Run tests';
|
|
247
|
+
if (command.includes('eslint')) return 'Run ESLint';
|
|
248
|
+
if (command.includes('prettier')) return 'Format code with Prettier';
|
|
249
|
+
if (command.includes('webpack') || command.includes('vite') || command.includes('tsup')) return 'Build with bundler';
|
|
250
|
+
|
|
251
|
+
return `Run npm script: ${name}`;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Extract tools from pyproject.toml scripts
|
|
256
|
+
*/
|
|
257
|
+
export function extractFromPyprojectToml(content: string, filename: string): ExtractedTool[] {
|
|
258
|
+
const tools: ExtractedTool[] = [];
|
|
259
|
+
|
|
260
|
+
// Simple parsing for [project.scripts] or [tool.poetry.scripts]
|
|
261
|
+
const sections = content.split(/\n\[/);
|
|
262
|
+
|
|
263
|
+
for (const section of sections) {
|
|
264
|
+
if (!section.includes('scripts]') && !section.includes('scripts.')) continue;
|
|
265
|
+
|
|
266
|
+
const lines = section.split('\n');
|
|
267
|
+
|
|
268
|
+
for (const line of lines) {
|
|
269
|
+
if (line.startsWith('[') || !line.includes('=')) continue;
|
|
270
|
+
|
|
271
|
+
const match = line.match(/^(\w+)\s*=\s*"?([^"]+)"?/);
|
|
272
|
+
if (match) {
|
|
273
|
+
const [, name, value] = match;
|
|
274
|
+
const { confidence, factors } = calculateConfidence(false, false, 'code');
|
|
275
|
+
|
|
276
|
+
tools.push({
|
|
277
|
+
name: `python_${name}`,
|
|
278
|
+
description: `Run Python script: ${name}`,
|
|
279
|
+
inputSchema: {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {},
|
|
282
|
+
required: []
|
|
283
|
+
},
|
|
284
|
+
source: {
|
|
285
|
+
type: 'code',
|
|
286
|
+
file: filename
|
|
287
|
+
},
|
|
288
|
+
confidence,
|
|
289
|
+
confidenceFactors: factors
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return tools;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Extract tools from setup.py console_scripts
|
|
300
|
+
*/
|
|
301
|
+
export function extractFromSetupPy(content: string, filename: string): ExtractedTool[] {
|
|
302
|
+
const tools: ExtractedTool[] = [];
|
|
303
|
+
|
|
304
|
+
// Look for console_scripts entry points
|
|
305
|
+
const consoleScriptsMatch = content.match(/console_scripts\s*=\s*\[([\s\S]*?)\]/);
|
|
306
|
+
if (!consoleScriptsMatch) return tools;
|
|
307
|
+
|
|
308
|
+
const scriptsBlock = consoleScriptsMatch[1];
|
|
309
|
+
const scriptMatches = scriptsBlock.matchAll(/["'](\w+)\s*=\s*([^"']+)["']/g);
|
|
310
|
+
|
|
311
|
+
for (const match of scriptMatches) {
|
|
312
|
+
const [, name, entryPoint] = match;
|
|
313
|
+
const { confidence, factors } = calculateConfidence(false, false, 'code');
|
|
314
|
+
|
|
315
|
+
tools.push({
|
|
316
|
+
name: `python_${name}`,
|
|
317
|
+
description: `Run Python CLI: ${name}`,
|
|
318
|
+
inputSchema: {
|
|
319
|
+
type: 'object',
|
|
320
|
+
properties: {},
|
|
321
|
+
required: []
|
|
322
|
+
},
|
|
323
|
+
source: {
|
|
324
|
+
type: 'code',
|
|
325
|
+
file: filename
|
|
326
|
+
},
|
|
327
|
+
confidence,
|
|
328
|
+
confidenceFactors: factors
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return tools;
|
|
333
|
+
}
|