codeguardian-mcp 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/LICENSE +21 -0
- package/README.md +348 -0
- package/dist/agent/agentTools.d.ts +26 -0
- package/dist/agent/agentTools.d.ts.map +1 -0
- package/dist/agent/agentTools.js +699 -0
- package/dist/agent/agentTools.js.map +1 -0
- package/dist/agent/autoValidator.d.ts +110 -0
- package/dist/agent/autoValidator.d.ts.map +1 -0
- package/dist/agent/autoValidator.js +964 -0
- package/dist/agent/autoValidator.js.map +1 -0
- package/dist/agent/fileWatcher.d.ts +28 -0
- package/dist/agent/fileWatcher.d.ts.map +1 -0
- package/dist/agent/fileWatcher.js +88 -0
- package/dist/agent/fileWatcher.js.map +1 -0
- package/dist/agent/guardianPersistence.d.ts +98 -0
- package/dist/agent/guardianPersistence.d.ts.map +1 -0
- package/dist/agent/guardianPersistence.js +296 -0
- package/dist/agent/guardianPersistence.js.map +1 -0
- package/dist/agent/mcpNotifications.d.ts +38 -0
- package/dist/agent/mcpNotifications.d.ts.map +1 -0
- package/dist/agent/mcpNotifications.js +81 -0
- package/dist/agent/mcpNotifications.js.map +1 -0
- package/dist/analyzers/aiPatterns.d.ts +16 -0
- package/dist/analyzers/aiPatterns.d.ts.map +1 -0
- package/dist/analyzers/aiPatterns.js +103 -0
- package/dist/analyzers/aiPatterns.js.map +1 -0
- package/dist/analyzers/antiPatterns.d.ts +60 -0
- package/dist/analyzers/antiPatterns.d.ts.map +1 -0
- package/dist/analyzers/antiPatterns.js +198 -0
- package/dist/analyzers/antiPatterns.js.map +1 -0
- package/dist/analyzers/builtinTypes.d.ts +18 -0
- package/dist/analyzers/builtinTypes.d.ts.map +1 -0
- package/dist/analyzers/builtinTypes.js +1275 -0
- package/dist/analyzers/builtinTypes.js.map +1 -0
- package/dist/analyzers/complexity.d.ts +14 -0
- package/dist/analyzers/complexity.d.ts.map +1 -0
- package/dist/analyzers/complexity.js +610 -0
- package/dist/analyzers/complexity.js.map +1 -0
- package/dist/analyzers/findingVerifier.d.ts +59 -0
- package/dist/analyzers/findingVerifier.d.ts.map +1 -0
- package/dist/analyzers/findingVerifier.js +1169 -0
- package/dist/analyzers/findingVerifier.js.map +1 -0
- package/dist/analyzers/impactAnalyzer.d.ts +53 -0
- package/dist/analyzers/impactAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/impactAnalyzer.js +152 -0
- package/dist/analyzers/impactAnalyzer.js.map +1 -0
- package/dist/analyzers/languageDetector.d.ts +48 -0
- package/dist/analyzers/languageDetector.d.ts.map +1 -0
- package/dist/analyzers/languageDetector.js +404 -0
- package/dist/analyzers/languageDetector.js.map +1 -0
- package/dist/analyzers/parsers/incrementalParser.d.ts +53 -0
- package/dist/analyzers/parsers/incrementalParser.d.ts.map +1 -0
- package/dist/analyzers/parsers/incrementalParser.js +193 -0
- package/dist/analyzers/parsers/incrementalParser.js.map +1 -0
- package/dist/analyzers/parsers/scopeResolver.d.ts +92 -0
- package/dist/analyzers/parsers/scopeResolver.d.ts.map +1 -0
- package/dist/analyzers/parsers/scopeResolver.js +324 -0
- package/dist/analyzers/parsers/scopeResolver.js.map +1 -0
- package/dist/analyzers/parsers/semanticIndex.d.ts +127 -0
- package/dist/analyzers/parsers/semanticIndex.d.ts.map +1 -0
- package/dist/analyzers/parsers/semanticIndex.js +429 -0
- package/dist/analyzers/parsers/semanticIndex.js.map +1 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts +42 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.js +233 -0
- package/dist/analyzers/parsers/sessionDiffAnalyzer.js.map +1 -0
- package/dist/analyzers/parsers/treeSitterParser.d.ts +76 -0
- package/dist/analyzers/parsers/treeSitterParser.d.ts.map +1 -0
- package/dist/analyzers/parsers/treeSitterParser.js +709 -0
- package/dist/analyzers/parsers/treeSitterParser.js.map +1 -0
- package/dist/analyzers/relevanceScorer.d.ts +43 -0
- package/dist/analyzers/relevanceScorer.d.ts.map +1 -0
- package/dist/analyzers/relevanceScorer.js +200 -0
- package/dist/analyzers/relevanceScorer.js.map +1 -0
- package/dist/analyzers/standardLibrary.d.ts +22 -0
- package/dist/analyzers/standardLibrary.d.ts.map +1 -0
- package/dist/analyzers/standardLibrary.js +211 -0
- package/dist/analyzers/standardLibrary.js.map +1 -0
- package/dist/analyzers/symbolGraph.d.ts +30 -0
- package/dist/analyzers/symbolGraph.d.ts.map +1 -0
- package/dist/analyzers/symbolGraph.js +380 -0
- package/dist/analyzers/symbolGraph.js.map +1 -0
- package/dist/analyzers/symbolTable.d.ts +18 -0
- package/dist/analyzers/symbolTable.d.ts.map +1 -0
- package/dist/analyzers/symbolTable.js +176 -0
- package/dist/analyzers/symbolTable.js.map +1 -0
- package/dist/analyzers/typeChecker.d.ts +13 -0
- package/dist/analyzers/typeChecker.d.ts.map +1 -0
- package/dist/analyzers/typeChecker.js +580 -0
- package/dist/analyzers/typeChecker.js.map +1 -0
- package/dist/analyzers/usagePatterns.d.ts +42 -0
- package/dist/analyzers/usagePatterns.d.ts.map +1 -0
- package/dist/analyzers/usagePatterns.js +75 -0
- package/dist/analyzers/usagePatterns.js.map +1 -0
- package/dist/api-contract/context/backend.d.ts +19 -0
- package/dist/api-contract/context/backend.d.ts.map +1 -0
- package/dist/api-contract/context/backend.js +64 -0
- package/dist/api-contract/context/backend.js.map +1 -0
- package/dist/api-contract/context/contract.d.ts +34 -0
- package/dist/api-contract/context/contract.d.ts.map +1 -0
- package/dist/api-contract/context/contract.js +306 -0
- package/dist/api-contract/context/contract.js.map +1 -0
- package/dist/api-contract/context/frontend.d.ts +19 -0
- package/dist/api-contract/context/frontend.d.ts.map +1 -0
- package/dist/api-contract/context/frontend.js +64 -0
- package/dist/api-contract/context/frontend.js.map +1 -0
- package/dist/api-contract/detector.d.ts +28 -0
- package/dist/api-contract/detector.d.ts.map +1 -0
- package/dist/api-contract/detector.js +393 -0
- package/dist/api-contract/detector.js.map +1 -0
- package/dist/api-contract/extractors/python.d.ts +32 -0
- package/dist/api-contract/extractors/python.d.ts.map +1 -0
- package/dist/api-contract/extractors/python.js +521 -0
- package/dist/api-contract/extractors/python.js.map +1 -0
- package/dist/api-contract/extractors/pythonAstUtils.d.ts +44 -0
- package/dist/api-contract/extractors/pythonAstUtils.d.ts.map +1 -0
- package/dist/api-contract/extractors/pythonAstUtils.js +489 -0
- package/dist/api-contract/extractors/pythonAstUtils.js.map +1 -0
- package/dist/api-contract/extractors/tsAstUtils.d.ts +47 -0
- package/dist/api-contract/extractors/tsAstUtils.d.ts.map +1 -0
- package/dist/api-contract/extractors/tsAstUtils.js +173 -0
- package/dist/api-contract/extractors/tsAstUtils.js.map +1 -0
- package/dist/api-contract/extractors/typescript.d.ts +32 -0
- package/dist/api-contract/extractors/typescript.d.ts.map +1 -0
- package/dist/api-contract/extractors/typescript.js +666 -0
- package/dist/api-contract/extractors/typescript.js.map +1 -0
- package/dist/api-contract/index.d.ts +104 -0
- package/dist/api-contract/index.d.ts.map +1 -0
- package/dist/api-contract/index.js +232 -0
- package/dist/api-contract/index.js.map +1 -0
- package/dist/api-contract/types.d.ts +151 -0
- package/dist/api-contract/types.d.ts.map +1 -0
- package/dist/api-contract/types.js +19 -0
- package/dist/api-contract/types.js.map +1 -0
- package/dist/api-contract/validators/endpoint.d.ts +21 -0
- package/dist/api-contract/validators/endpoint.d.ts.map +1 -0
- package/dist/api-contract/validators/endpoint.js +224 -0
- package/dist/api-contract/validators/endpoint.js.map +1 -0
- package/dist/api-contract/validators/index.d.ts +40 -0
- package/dist/api-contract/validators/index.d.ts.map +1 -0
- package/dist/api-contract/validators/index.js +875 -0
- package/dist/api-contract/validators/index.js.map +1 -0
- package/dist/api-contract/validators/parameter.d.ts +17 -0
- package/dist/api-contract/validators/parameter.d.ts.map +1 -0
- package/dist/api-contract/validators/parameter.js +250 -0
- package/dist/api-contract/validators/parameter.js.map +1 -0
- package/dist/api-contract/validators/type.d.ts +38 -0
- package/dist/api-contract/validators/type.d.ts.map +1 -0
- package/dist/api-contract/validators/type.js +244 -0
- package/dist/api-contract/validators/type.js.map +1 -0
- package/dist/context/apiContract/complexTypeSupport.d.ts +83 -0
- package/dist/context/apiContract/complexTypeSupport.d.ts.map +1 -0
- package/dist/context/apiContract/complexTypeSupport.js +665 -0
- package/dist/context/apiContract/complexTypeSupport.js.map +1 -0
- package/dist/context/apiContract/graphqlSupport.d.ts +105 -0
- package/dist/context/apiContract/graphqlSupport.d.ts.map +1 -0
- package/dist/context/apiContract/graphqlSupport.js +671 -0
- package/dist/context/apiContract/graphqlSupport.js.map +1 -0
- package/dist/context/apiContract/index.d.ts +14 -0
- package/dist/context/apiContract/index.d.ts.map +1 -0
- package/dist/context/apiContract/index.js +17 -0
- package/dist/context/apiContract/index.js.map +1 -0
- package/dist/context/apiContract/webSocketSupport.d.ts +104 -0
- package/dist/context/apiContract/webSocketSupport.d.ts.map +1 -0
- package/dist/context/apiContract/webSocketSupport.js +465 -0
- package/dist/context/apiContract/webSocketSupport.js.map +1 -0
- package/dist/context/apiContractContext.d.ts +15 -0
- package/dist/context/apiContractContext.d.ts.map +1 -0
- package/dist/context/apiContractContext.js +979 -0
- package/dist/context/apiContractContext.js.map +1 -0
- package/dist/context/apiContractExtraction.d.ts +52 -0
- package/dist/context/apiContractExtraction.d.ts.map +1 -0
- package/dist/context/apiContractExtraction.js +438 -0
- package/dist/context/apiContractExtraction.js.map +1 -0
- package/dist/context/contextLineage.d.ts +79 -0
- package/dist/context/contextLineage.d.ts.map +1 -0
- package/dist/context/contextLineage.js +259 -0
- package/dist/context/contextLineage.js.map +1 -0
- package/dist/context/contextOrchestrator.d.ts +57 -0
- package/dist/context/contextOrchestrator.d.ts.map +1 -0
- package/dist/context/contextOrchestrator.js +162 -0
- package/dist/context/contextOrchestrator.js.map +1 -0
- package/dist/context/intentTracker.d.ts +73 -0
- package/dist/context/intentTracker.d.ts.map +1 -0
- package/dist/context/intentTracker.js +168 -0
- package/dist/context/intentTracker.js.map +1 -0
- package/dist/context/projectContext.d.ts +219 -0
- package/dist/context/projectContext.d.ts.map +1 -0
- package/dist/context/projectContext.js +1984 -0
- package/dist/context/projectContext.js.map +1 -0
- package/dist/prompts/index.d.ts +17 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +260 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/library.d.ts +51 -0
- package/dist/prompts/library.d.ts.map +1 -0
- package/dist/prompts/library.js +65 -0
- package/dist/prompts/library.js.map +1 -0
- package/dist/prompts/templates.d.ts +44 -0
- package/dist/prompts/templates.d.ts.map +1 -0
- package/dist/prompts/templates.js +97 -0
- package/dist/prompts/templates.js.map +1 -0
- package/dist/queue/jobPersistence.d.ts +46 -0
- package/dist/queue/jobPersistence.d.ts.map +1 -0
- package/dist/queue/jobPersistence.js +158 -0
- package/dist/queue/jobPersistence.js.map +1 -0
- package/dist/queue/jobQueue.d.ts +116 -0
- package/dist/queue/jobQueue.d.ts.map +1 -0
- package/dist/queue/jobQueue.js +275 -0
- package/dist/queue/jobQueue.js.map +1 -0
- package/dist/queue/validationJob.d.ts +69 -0
- package/dist/queue/validationJob.d.ts.map +1 -0
- package/dist/queue/validationJob.js +435 -0
- package/dist/queue/validationJob.js.map +1 -0
- package/dist/resources/index.d.ts +15 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +328 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/validationReportStore.d.ts +170 -0
- package/dist/resources/validationReportStore.d.ts.map +1 -0
- package/dist/resources/validationReportStore.js +515 -0
- package/dist/resources/validationReportStore.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +102 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/asyncValidation.d.ts +19 -0
- package/dist/tools/asyncValidation.d.ts.map +1 -0
- package/dist/tools/asyncValidation.js +346 -0
- package/dist/tools/asyncValidation.js.map +1 -0
- package/dist/tools/buildContext.d.ts +17 -0
- package/dist/tools/buildContext.d.ts.map +1 -0
- package/dist/tools/buildContext.js +188 -0
- package/dist/tools/buildContext.js.map +1 -0
- package/dist/tools/getDependencyGraph.d.ts +16 -0
- package/dist/tools/getDependencyGraph.d.ts.map +1 -0
- package/dist/tools/getDependencyGraph.js +436 -0
- package/dist/tools/getDependencyGraph.js.map +1 -0
- package/dist/tools/incrementalValidation.d.ts +71 -0
- package/dist/tools/incrementalValidation.d.ts.map +1 -0
- package/dist/tools/incrementalValidation.js +203 -0
- package/dist/tools/incrementalValidation.js.map +1 -0
- package/dist/tools/index.d.ts +24 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +106 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/validateCode.d.ts +17 -0
- package/dist/tools/validateCode.d.ts.map +1 -0
- package/dist/tools/validateCode.js +368 -0
- package/dist/tools/validateCode.js.map +1 -0
- package/dist/tools/validateCodeLite.d.ts +2 -0
- package/dist/tools/validateCodeLite.d.ts.map +1 -0
- package/dist/tools/validateCodeLite.js +2 -0
- package/dist/tools/validateCodeLite.js.map +1 -0
- package/dist/tools/validation/builtins.d.ts +92 -0
- package/dist/tools/validation/builtins.d.ts.map +1 -0
- package/dist/tools/validation/builtins.js +2184 -0
- package/dist/tools/validation/builtins.js.map +1 -0
- package/dist/tools/validation/contextualNaming.d.ts +99 -0
- package/dist/tools/validation/contextualNaming.d.ts.map +1 -0
- package/dist/tools/validation/contextualNaming.js +959 -0
- package/dist/tools/validation/contextualNaming.js.map +1 -0
- package/dist/tools/validation/deadCode.d.ts +115 -0
- package/dist/tools/validation/deadCode.d.ts.map +1 -0
- package/dist/tools/validation/deadCode.js +861 -0
- package/dist/tools/validation/deadCode.js.map +1 -0
- package/dist/tools/validation/extractors/index.d.ts +131 -0
- package/dist/tools/validation/extractors/index.d.ts.map +1 -0
- package/dist/tools/validation/extractors/index.js +233 -0
- package/dist/tools/validation/extractors/index.js.map +1 -0
- package/dist/tools/validation/extractors/javascript.d.ts +73 -0
- package/dist/tools/validation/extractors/javascript.d.ts.map +1 -0
- package/dist/tools/validation/extractors/javascript.js +1841 -0
- package/dist/tools/validation/extractors/javascript.js.map +1 -0
- package/dist/tools/validation/extractors/python.d.ts +93 -0
- package/dist/tools/validation/extractors/python.d.ts.map +1 -0
- package/dist/tools/validation/extractors/python.js +799 -0
- package/dist/tools/validation/extractors/python.js.map +1 -0
- package/dist/tools/validation/manifest.d.ts +45 -0
- package/dist/tools/validation/manifest.d.ts.map +1 -0
- package/dist/tools/validation/manifest.js +719 -0
- package/dist/tools/validation/manifest.js.map +1 -0
- package/dist/tools/validation/parser.d.ts +58 -0
- package/dist/tools/validation/parser.d.ts.map +1 -0
- package/dist/tools/validation/parser.js +232 -0
- package/dist/tools/validation/parser.js.map +1 -0
- package/dist/tools/validation/registry.d.ts +15 -0
- package/dist/tools/validation/registry.d.ts.map +1 -0
- package/dist/tools/validation/registry.js +169 -0
- package/dist/tools/validation/registry.js.map +1 -0
- package/dist/tools/validation/scoring.d.ts +54 -0
- package/dist/tools/validation/scoring.d.ts.map +1 -0
- package/dist/tools/validation/scoring.js +242 -0
- package/dist/tools/validation/scoring.js.map +1 -0
- package/dist/tools/validation/types.d.ts +120 -0
- package/dist/tools/validation/types.d.ts.map +1 -0
- package/dist/tools/validation/types.js +11 -0
- package/dist/tools/validation/types.js.map +1 -0
- package/dist/tools/validation/unusedLocals.d.ts +36 -0
- package/dist/tools/validation/unusedLocals.d.ts.map +1 -0
- package/dist/tools/validation/unusedLocals.js +333 -0
- package/dist/tools/validation/unusedLocals.js.map +1 -0
- package/dist/tools/validation/validation.d.ts +98 -0
- package/dist/tools/validation/validation.d.ts.map +1 -0
- package/dist/tools/validation/validation.js +1837 -0
- package/dist/tools/validation/validation.js.map +1 -0
- package/dist/types/codeGraph.d.ts +163 -0
- package/dist/types/codeGraph.d.ts.map +1 -0
- package/dist/types/codeGraph.js +9 -0
- package/dist/types/codeGraph.js.map +1 -0
- package/dist/types/symbolGraph.d.ts +68 -0
- package/dist/types/symbolGraph.d.ts.map +1 -0
- package/dist/types/symbolGraph.js +10 -0
- package/dist/types/symbolGraph.js.map +1 -0
- package/dist/types/tools.d.ts +43 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +7 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/fileFilter.d.ts +37 -0
- package/dist/utils/fileFilter.d.ts.map +1 -0
- package/dist/utils/fileFilter.js +91 -0
- package/dist/utils/fileFilter.js.map +1 -0
- package/dist/utils/gitUtils.d.ts +28 -0
- package/dist/utils/gitUtils.d.ts.map +1 -0
- package/dist/utils/gitUtils.js +81 -0
- package/dist/utils/gitUtils.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +38 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/serialization.d.ts +25 -0
- package/dist/utils/serialization.d.ts.map +1 -0
- package/dist/utils/serialization.js +53 -0
- package/dist/utils/serialization.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,719 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest Loader Module
|
|
3
|
+
*
|
|
4
|
+
* This module handles loading and parsing package dependency manifests for different languages.
|
|
5
|
+
* It supports:
|
|
6
|
+
* - JavaScript/TypeScript: package.json
|
|
7
|
+
* - Python: requirements.txt, pyproject.toml
|
|
8
|
+
* - Python __all__ export tracking from __init__.py files
|
|
9
|
+
*
|
|
10
|
+
* @format
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from "fs/promises";
|
|
13
|
+
import * as path from "path";
|
|
14
|
+
import { parse as parseToml } from "smol-toml";
|
|
15
|
+
import { logger } from "../../utils/logger.js";
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Python Standard Library - Comprehensive List
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Get Python standard library modules.
|
|
21
|
+
* This is a comprehensive list based on Python 3.11+ documentation.
|
|
22
|
+
* Organized by category for maintainability.
|
|
23
|
+
*/
|
|
24
|
+
function getPythonStdLib() {
|
|
25
|
+
const modules = [
|
|
26
|
+
// Text Processing
|
|
27
|
+
"string",
|
|
28
|
+
"re",
|
|
29
|
+
"difflib",
|
|
30
|
+
"textwrap",
|
|
31
|
+
"unicodedata",
|
|
32
|
+
"stringprep",
|
|
33
|
+
"readline",
|
|
34
|
+
"rlcompleter",
|
|
35
|
+
// Binary Data Services
|
|
36
|
+
"struct",
|
|
37
|
+
"codecs",
|
|
38
|
+
// Data Types
|
|
39
|
+
"datetime",
|
|
40
|
+
"zoneinfo",
|
|
41
|
+
"calendar",
|
|
42
|
+
"collections",
|
|
43
|
+
"heapq",
|
|
44
|
+
"bisect",
|
|
45
|
+
"array",
|
|
46
|
+
"weakref",
|
|
47
|
+
"types",
|
|
48
|
+
"copy",
|
|
49
|
+
"pprint",
|
|
50
|
+
"reprlib",
|
|
51
|
+
"enum",
|
|
52
|
+
"graphlib",
|
|
53
|
+
// Numeric and Mathematical
|
|
54
|
+
"numbers",
|
|
55
|
+
"math",
|
|
56
|
+
"cmath",
|
|
57
|
+
"decimal",
|
|
58
|
+
"fractions",
|
|
59
|
+
"random",
|
|
60
|
+
"statistics",
|
|
61
|
+
// Functional Programming
|
|
62
|
+
"itertools",
|
|
63
|
+
"functools",
|
|
64
|
+
"operator",
|
|
65
|
+
// File and Directory Access
|
|
66
|
+
"pathlib",
|
|
67
|
+
"os",
|
|
68
|
+
"fileinput",
|
|
69
|
+
"stat",
|
|
70
|
+
"filecmp",
|
|
71
|
+
"tempfile",
|
|
72
|
+
"glob",
|
|
73
|
+
"fnmatch",
|
|
74
|
+
"linecache",
|
|
75
|
+
"shutil",
|
|
76
|
+
// Data Persistence
|
|
77
|
+
"pickle",
|
|
78
|
+
"copyreg",
|
|
79
|
+
"shelve",
|
|
80
|
+
"marshal",
|
|
81
|
+
"dbm",
|
|
82
|
+
"sqlite3",
|
|
83
|
+
// Data Compression
|
|
84
|
+
"zlib",
|
|
85
|
+
"gzip",
|
|
86
|
+
"bz2",
|
|
87
|
+
"lzma",
|
|
88
|
+
"zipfile",
|
|
89
|
+
"tarfile",
|
|
90
|
+
// File Formats
|
|
91
|
+
"csv",
|
|
92
|
+
"configparser",
|
|
93
|
+
"tomllib",
|
|
94
|
+
"netrc",
|
|
95
|
+
"plistlib",
|
|
96
|
+
// Cryptographic Services
|
|
97
|
+
"hashlib",
|
|
98
|
+
"hmac",
|
|
99
|
+
"secrets",
|
|
100
|
+
// Generic OS Services
|
|
101
|
+
"time",
|
|
102
|
+
"sys",
|
|
103
|
+
"sysconfig",
|
|
104
|
+
"builtins",
|
|
105
|
+
"warnings",
|
|
106
|
+
"dataclasses",
|
|
107
|
+
"contextlib",
|
|
108
|
+
"abc",
|
|
109
|
+
"atexit",
|
|
110
|
+
"traceback",
|
|
111
|
+
"gc",
|
|
112
|
+
"inspect",
|
|
113
|
+
"site",
|
|
114
|
+
// Concurrent Execution
|
|
115
|
+
"threading",
|
|
116
|
+
"multiprocessing",
|
|
117
|
+
"concurrent",
|
|
118
|
+
"subprocess",
|
|
119
|
+
"sched",
|
|
120
|
+
"queue",
|
|
121
|
+
"contextvars",
|
|
122
|
+
// Networking and IPC
|
|
123
|
+
"asyncio",
|
|
124
|
+
"socket",
|
|
125
|
+
"ssl",
|
|
126
|
+
"select",
|
|
127
|
+
"selectors",
|
|
128
|
+
"signal",
|
|
129
|
+
"mmap",
|
|
130
|
+
// Internet Data Handling
|
|
131
|
+
"email",
|
|
132
|
+
"json",
|
|
133
|
+
"mailbox",
|
|
134
|
+
"mimetypes",
|
|
135
|
+
"base64",
|
|
136
|
+
"binascii",
|
|
137
|
+
"quopri",
|
|
138
|
+
// Structured Markup
|
|
139
|
+
"html",
|
|
140
|
+
"xml",
|
|
141
|
+
// Internet Protocols
|
|
142
|
+
"webbrowser",
|
|
143
|
+
"wsgiref",
|
|
144
|
+
"urllib",
|
|
145
|
+
"http",
|
|
146
|
+
"ftplib",
|
|
147
|
+
"poplib",
|
|
148
|
+
"imaplib",
|
|
149
|
+
"smtplib",
|
|
150
|
+
"uuid",
|
|
151
|
+
"socketserver",
|
|
152
|
+
"xmlrpc",
|
|
153
|
+
"ipaddress",
|
|
154
|
+
// Multimedia
|
|
155
|
+
"wave",
|
|
156
|
+
"colorsys",
|
|
157
|
+
// Internationalization
|
|
158
|
+
"gettext",
|
|
159
|
+
"locale",
|
|
160
|
+
// Program Frameworks
|
|
161
|
+
"turtle",
|
|
162
|
+
"cmd",
|
|
163
|
+
"shlex",
|
|
164
|
+
// GUI
|
|
165
|
+
"tkinter",
|
|
166
|
+
"idlelib",
|
|
167
|
+
// Development Tools
|
|
168
|
+
"typing",
|
|
169
|
+
"pydoc",
|
|
170
|
+
"doctest",
|
|
171
|
+
"unittest",
|
|
172
|
+
"test",
|
|
173
|
+
// Debugging and Profiling
|
|
174
|
+
"bdb",
|
|
175
|
+
"faulthandler",
|
|
176
|
+
"pdb",
|
|
177
|
+
"timeit",
|
|
178
|
+
"trace",
|
|
179
|
+
"tracemalloc",
|
|
180
|
+
// Software Packaging
|
|
181
|
+
"ensurepip",
|
|
182
|
+
"venv",
|
|
183
|
+
"zipapp",
|
|
184
|
+
// Python Runtime
|
|
185
|
+
"importlib",
|
|
186
|
+
"runpy",
|
|
187
|
+
"ast",
|
|
188
|
+
"symtable",
|
|
189
|
+
"token",
|
|
190
|
+
"keyword",
|
|
191
|
+
"tokenize",
|
|
192
|
+
"tabnanny",
|
|
193
|
+
"pyclbr",
|
|
194
|
+
"py_compile",
|
|
195
|
+
"compileall",
|
|
196
|
+
"dis",
|
|
197
|
+
"pickletools",
|
|
198
|
+
// Custom Interpreters
|
|
199
|
+
"code",
|
|
200
|
+
"codeop",
|
|
201
|
+
// Importing
|
|
202
|
+
"zipimport",
|
|
203
|
+
"pkgutil",
|
|
204
|
+
"modulefinder",
|
|
205
|
+
// Unix Specific
|
|
206
|
+
"posix",
|
|
207
|
+
"pwd",
|
|
208
|
+
"grp",
|
|
209
|
+
"termios",
|
|
210
|
+
"tty",
|
|
211
|
+
"pty",
|
|
212
|
+
"fcntl",
|
|
213
|
+
"resource",
|
|
214
|
+
"syslog",
|
|
215
|
+
// Windows Specific
|
|
216
|
+
"msvcrt",
|
|
217
|
+
"winreg",
|
|
218
|
+
"winsound",
|
|
219
|
+
// Logging
|
|
220
|
+
"logging",
|
|
221
|
+
// Argument Parsing
|
|
222
|
+
"argparse",
|
|
223
|
+
"getopt",
|
|
224
|
+
"optparse",
|
|
225
|
+
// Common third-party that feel like stdlib
|
|
226
|
+
"typing_extensions",
|
|
227
|
+
];
|
|
228
|
+
return new Set(modules);
|
|
229
|
+
}
|
|
230
|
+
// Cache the stdlib set
|
|
231
|
+
let pythonStdLibCache = null;
|
|
232
|
+
function getPythonStdLibCached() {
|
|
233
|
+
if (!pythonStdLibCache) {
|
|
234
|
+
pythonStdLibCache = getPythonStdLib();
|
|
235
|
+
}
|
|
236
|
+
return pythonStdLibCache;
|
|
237
|
+
}
|
|
238
|
+
// ============================================================================
|
|
239
|
+
// Python __all__ Export Tracking (AST-based)
|
|
240
|
+
// ============================================================================
|
|
241
|
+
/**
|
|
242
|
+
* Parse Python __all__ from __init__.py files using AST for reliability.
|
|
243
|
+
* Falls back to regex for edge cases.
|
|
244
|
+
*/
|
|
245
|
+
export async function loadPythonModuleExports(projectPath) {
|
|
246
|
+
const exports = new Map();
|
|
247
|
+
try {
|
|
248
|
+
const { glob } = await import("glob");
|
|
249
|
+
const initFiles = await glob(`${projectPath}/**/__init__.py`, {
|
|
250
|
+
ignore: ["**/node_modules/**", "**/venv/**", "**/.venv/**", "**/.git/**"],
|
|
251
|
+
nodir: true,
|
|
252
|
+
});
|
|
253
|
+
for (const initFile of initFiles) {
|
|
254
|
+
try {
|
|
255
|
+
const content = await fs.readFile(initFile, "utf-8");
|
|
256
|
+
const exportedNames = extractPythonAllExports(content);
|
|
257
|
+
if (exportedNames.size > 0) {
|
|
258
|
+
// Get module path relative to project (e.g., "app.services" from "app/services/__init__.py")
|
|
259
|
+
const relativePath = path.relative(projectPath, initFile);
|
|
260
|
+
const modulePath = path.dirname(relativePath).replace(/[/\\]/g, ".");
|
|
261
|
+
exports.set(modulePath, exportedNames);
|
|
262
|
+
logger.debug(`Loaded __all__ for ${modulePath}: ${Array.from(exportedNames).join(", ")}`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
// Skip unreadable files
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
logger.debug(`Error loading Python module exports: ${err}`);
|
|
272
|
+
}
|
|
273
|
+
return exports;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Extract __all__ exports from Python code using AST-like parsing.
|
|
277
|
+
* Handles various formats:
|
|
278
|
+
* - __all__ = ["a", "b", "c"]
|
|
279
|
+
* - __all__ = ['a', 'b', 'c']
|
|
280
|
+
* - __all__ = [\n "a",\n "b",\n]
|
|
281
|
+
* - __all__: list[str] = [...]
|
|
282
|
+
*/
|
|
283
|
+
function extractPythonAllExports(code) {
|
|
284
|
+
const exportedNames = new Set();
|
|
285
|
+
// Find __all__ assignment - handles type annotations too
|
|
286
|
+
const allAssignmentPattern = /__all__\s*(?::\s*[^=]+)?\s*=\s*\[/g;
|
|
287
|
+
const match = allAssignmentPattern.exec(code);
|
|
288
|
+
if (!match)
|
|
289
|
+
return exportedNames;
|
|
290
|
+
// Find the matching closing bracket
|
|
291
|
+
const startIdx = match.index + match[0].length - 1; // Position of '['
|
|
292
|
+
let depth = 1;
|
|
293
|
+
let idx = startIdx + 1;
|
|
294
|
+
let endIdx = -1;
|
|
295
|
+
while (idx < code.length && depth > 0) {
|
|
296
|
+
const char = code[idx];
|
|
297
|
+
if (char === "[")
|
|
298
|
+
depth++;
|
|
299
|
+
else if (char === "]") {
|
|
300
|
+
depth--;
|
|
301
|
+
if (depth === 0)
|
|
302
|
+
endIdx = idx;
|
|
303
|
+
}
|
|
304
|
+
idx++;
|
|
305
|
+
}
|
|
306
|
+
if (endIdx === -1)
|
|
307
|
+
return exportedNames;
|
|
308
|
+
// Extract the content between brackets
|
|
309
|
+
const listContent = code.substring(startIdx + 1, endIdx);
|
|
310
|
+
// Parse string literals from the list content
|
|
311
|
+
// Handles both single and double quotes, multiline
|
|
312
|
+
const stringPattern = /["']([^"']+)["']/g;
|
|
313
|
+
let strMatch;
|
|
314
|
+
while ((strMatch = stringPattern.exec(listContent)) !== null) {
|
|
315
|
+
const name = strMatch[1].trim();
|
|
316
|
+
if (name && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
317
|
+
exportedNames.add(name);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return exportedNames;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Check if a symbol is exported from a Python module via __all__
|
|
324
|
+
*/
|
|
325
|
+
export function isPythonSymbolExported(modulePath, symbolName, moduleExports) {
|
|
326
|
+
const exports = moduleExports.get(modulePath);
|
|
327
|
+
// If no __all__ defined, assume all non-private symbols are exported
|
|
328
|
+
if (!exports) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
return exports.has(symbolName);
|
|
332
|
+
}
|
|
333
|
+
// ============================================================================
|
|
334
|
+
// Manifest Loading
|
|
335
|
+
// ============================================================================
|
|
336
|
+
/**
|
|
337
|
+
* Load manifest dependencies for the specified language
|
|
338
|
+
*/
|
|
339
|
+
export async function loadManifestDependencies(projectPath, language) {
|
|
340
|
+
const result = {
|
|
341
|
+
dependencies: new Set(),
|
|
342
|
+
devDependencies: new Set(),
|
|
343
|
+
all: new Set(),
|
|
344
|
+
};
|
|
345
|
+
if (language === "javascript" || language === "typescript") {
|
|
346
|
+
await loadPackageJson(projectPath, result);
|
|
347
|
+
}
|
|
348
|
+
else if (language === "python") {
|
|
349
|
+
await loadPythonDependencies(projectPath, result);
|
|
350
|
+
}
|
|
351
|
+
return result;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Load dependencies from package.json
|
|
355
|
+
* First checks at projectPath, then searches common subdirectories
|
|
356
|
+
* (frontend/, backend/, client/, server/, packages/*/) for monorepo-style projects.
|
|
357
|
+
* Does NOT traverse UP from projectPath to avoid loading an unrelated parent package.json.
|
|
358
|
+
*/
|
|
359
|
+
export async function loadPackageJson(projectPath, result) {
|
|
360
|
+
try {
|
|
361
|
+
// Step 1: Check for package.json directly at projectPath
|
|
362
|
+
const rootPkgPath = path.join(projectPath, "package.json");
|
|
363
|
+
let foundPaths = [];
|
|
364
|
+
try {
|
|
365
|
+
await fs.access(rootPkgPath);
|
|
366
|
+
foundPaths.push(rootPkgPath);
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// Not found at root
|
|
370
|
+
}
|
|
371
|
+
// Step 2: If no root package.json, search common subdirectories
|
|
372
|
+
// This handles monorepo-style projects (e.g., frontend/package.json + backend/package.json)
|
|
373
|
+
if (foundPaths.length === 0) {
|
|
374
|
+
const COMMON_SUBDIRS = ["frontend", "backend", "client", "server", "app", "web", "api"];
|
|
375
|
+
for (const subdir of COMMON_SUBDIRS) {
|
|
376
|
+
const subPkgPath = path.join(projectPath, subdir, "package.json");
|
|
377
|
+
try {
|
|
378
|
+
await fs.access(subPkgPath);
|
|
379
|
+
foundPaths.push(subPkgPath);
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
// Not found
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
// Also check packages/* for monorepo workspaces
|
|
386
|
+
try {
|
|
387
|
+
const packagesDir = path.join(projectPath, "packages");
|
|
388
|
+
const entries = await fs.readdir(packagesDir, { withFileTypes: true });
|
|
389
|
+
for (const entry of entries) {
|
|
390
|
+
if (entry.isDirectory()) {
|
|
391
|
+
const subPkgPath = path.join(packagesDir, entry.name, "package.json");
|
|
392
|
+
try {
|
|
393
|
+
await fs.access(subPkgPath);
|
|
394
|
+
foundPaths.push(subPkgPath);
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
// Not found
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
// packages/ directory doesn't exist
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
if (foundPaths.length === 0) {
|
|
407
|
+
logger.debug(`No package.json found at ${projectPath} or in common subdirectories`);
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
// Step 3: Load and merge dependencies from all found package.json files
|
|
411
|
+
for (const pkgPath of foundPaths) {
|
|
412
|
+
try {
|
|
413
|
+
await loadSinglePackageJson(pkgPath, result);
|
|
414
|
+
}
|
|
415
|
+
catch (err) {
|
|
416
|
+
logger.debug(`Error loading package.json at ${pkgPath}: ${err}`);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
logger.debug(`Loaded ${result.all.size} total packages from ${foundPaths.length} package.json file(s)`);
|
|
420
|
+
}
|
|
421
|
+
catch (err) {
|
|
422
|
+
logger.debug(`Error loading package.json: ${err}`);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Load dependencies from a single package.json file into the result
|
|
427
|
+
*/
|
|
428
|
+
async function loadSinglePackageJson(pkgPath, result) {
|
|
429
|
+
const content = await fs.readFile(pkgPath, "utf-8");
|
|
430
|
+
const pkg = JSON.parse(content);
|
|
431
|
+
// Add dependencies
|
|
432
|
+
if (pkg.dependencies) {
|
|
433
|
+
for (const dep of Object.keys(pkg.dependencies)) {
|
|
434
|
+
result.dependencies.add(dep);
|
|
435
|
+
result.all.add(dep);
|
|
436
|
+
// Also add scoped package base (e.g., @tanstack/react-query -> @tanstack)
|
|
437
|
+
if (dep.startsWith("@")) {
|
|
438
|
+
const scope = dep.split("/")[0];
|
|
439
|
+
result.all.add(scope);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// Add devDependencies
|
|
444
|
+
if (pkg.devDependencies) {
|
|
445
|
+
for (const dep of Object.keys(pkg.devDependencies)) {
|
|
446
|
+
result.devDependencies.add(dep);
|
|
447
|
+
result.all.add(dep);
|
|
448
|
+
// SUPPORT @types PACKAGES:
|
|
449
|
+
// If "import foo" is used, but only "@types/foo" is installed, we should count it as valid.
|
|
450
|
+
// This happens often in TS projects where the runtime might be global or implied.
|
|
451
|
+
if (dep.startsWith("@types/")) {
|
|
452
|
+
const realPackage = dep.replace("@types/", "");
|
|
453
|
+
result.all.add(realPackage);
|
|
454
|
+
// Handle scoped types: @types/babel__core -> @babel/core
|
|
455
|
+
if (realPackage.includes("__")) {
|
|
456
|
+
const [scope, name] = realPackage.split("__");
|
|
457
|
+
if (scope && name) {
|
|
458
|
+
result.all.add(`@${scope}/${name}`);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
if (dep.startsWith("@")) {
|
|
463
|
+
const scope = dep.split("/")[0];
|
|
464
|
+
result.all.add(scope);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// Add peerDependencies
|
|
469
|
+
if (pkg.peerDependencies) {
|
|
470
|
+
for (const dep of Object.keys(pkg.peerDependencies)) {
|
|
471
|
+
result.all.add(dep);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
logger.debug(`Loaded packages from ${pkgPath}`);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Load Python dependencies from requirements.txt and pyproject.toml
|
|
478
|
+
* Uses proper TOML parsing for pyproject.toml.
|
|
479
|
+
* Searches common subdirectories if not found at root (like loadPackageJson).
|
|
480
|
+
*/
|
|
481
|
+
export async function loadPythonDependencies(projectPath, result) {
|
|
482
|
+
// Collect paths to search: root first, then common subdirectories
|
|
483
|
+
const searchPaths = [projectPath];
|
|
484
|
+
const COMMON_SUBDIRS = ["backend", "server", "api", "app", "src"];
|
|
485
|
+
// Check if root has any Python manifest; if not, search subdirectories
|
|
486
|
+
let hasRootManifest = false;
|
|
487
|
+
for (const manifest of ["requirements.txt", "pyproject.toml", "Pipfile"]) {
|
|
488
|
+
try {
|
|
489
|
+
await fs.access(path.join(projectPath, manifest));
|
|
490
|
+
hasRootManifest = true;
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
493
|
+
catch {
|
|
494
|
+
// Not found
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (!hasRootManifest) {
|
|
498
|
+
for (const subdir of COMMON_SUBDIRS) {
|
|
499
|
+
const subPath = path.join(projectPath, subdir);
|
|
500
|
+
try {
|
|
501
|
+
const stat = await fs.stat(subPath);
|
|
502
|
+
if (stat.isDirectory()) {
|
|
503
|
+
searchPaths.push(subPath);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
catch {
|
|
507
|
+
// Not found
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
// Load from all discovered paths
|
|
512
|
+
for (const searchPath of searchPaths) {
|
|
513
|
+
await loadRequirementsTxt(searchPath, result);
|
|
514
|
+
await loadPyprojectToml(searchPath, result);
|
|
515
|
+
}
|
|
516
|
+
// Add Python standard library modules
|
|
517
|
+
const stdLib = getPythonStdLibCached();
|
|
518
|
+
for (const mod of stdLib) {
|
|
519
|
+
result.all.add(mod);
|
|
520
|
+
}
|
|
521
|
+
logger.debug(`Loaded ${result.all.size} Python packages`);
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Parse requirements.txt file at the given path (no upward traversal).
|
|
525
|
+
* The caller (loadPythonDependencies) is responsible for searching subdirectories.
|
|
526
|
+
*/
|
|
527
|
+
async function loadRequirementsTxt(projectPath, result) {
|
|
528
|
+
const reqPath = path.join(projectPath, "requirements.txt");
|
|
529
|
+
try {
|
|
530
|
+
await fs.access(reqPath);
|
|
531
|
+
}
|
|
532
|
+
catch {
|
|
533
|
+
// requirements.txt not found at this path
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
try {
|
|
537
|
+
const content = await fs.readFile(reqPath, "utf-8");
|
|
538
|
+
let packageCount = 0;
|
|
539
|
+
for (const line of content.split("\n")) {
|
|
540
|
+
const trimmed = line.trim();
|
|
541
|
+
// Skip empty lines, comments, and -r/-e flags
|
|
542
|
+
if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("-")) {
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
// Extract package name (before ==, >=, <=, ~=, !=, <, >, [extras])
|
|
546
|
+
const pkgName = trimmed
|
|
547
|
+
.split(/[=<>!~[;@]/, 1)[0]
|
|
548
|
+
.trim()
|
|
549
|
+
.toLowerCase();
|
|
550
|
+
if (pkgName) {
|
|
551
|
+
result.all.add(pkgName);
|
|
552
|
+
// Also add common import name variations (e.g., scikit-learn -> sklearn)
|
|
553
|
+
result.all.add(pkgName.replace(/-/g, "_"));
|
|
554
|
+
// Handle known package name -> import name mappings
|
|
555
|
+
addPythonPackageAliases(pkgName, result);
|
|
556
|
+
packageCount++;
|
|
557
|
+
// Extract extras: passlib[bcrypt] -> add bcrypt as a dependency
|
|
558
|
+
const extrasMatch = trimmed.match(/\[([^\]]+)\]/);
|
|
559
|
+
if (extrasMatch) {
|
|
560
|
+
for (const extra of extrasMatch[1].split(",")) {
|
|
561
|
+
const extraName = extra.trim().toLowerCase();
|
|
562
|
+
if (extraName) {
|
|
563
|
+
result.all.add(extraName);
|
|
564
|
+
result.all.add(extraName.replace(/-/g, "_"));
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
logger.info(`Loaded ${packageCount} packages from requirements.txt at ${reqPath}`);
|
|
571
|
+
}
|
|
572
|
+
catch (err) {
|
|
573
|
+
logger.warn(`Failed to read requirements.txt at ${reqPath}: ${err}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Parse pyproject.toml using proper TOML parser
|
|
578
|
+
*/
|
|
579
|
+
async function loadPyprojectToml(projectPath, result) {
|
|
580
|
+
try {
|
|
581
|
+
const pyprojectPath = path.join(projectPath, "pyproject.toml");
|
|
582
|
+
const content = await fs.readFile(pyprojectPath, "utf-8");
|
|
583
|
+
const toml = parseToml(content);
|
|
584
|
+
// Extract dependencies from [project.dependencies]
|
|
585
|
+
const projectDeps = toml?.project?.dependencies;
|
|
586
|
+
if (Array.isArray(projectDeps)) {
|
|
587
|
+
for (const dep of projectDeps) {
|
|
588
|
+
const pkgName = extractPackageNameFromPep508(dep);
|
|
589
|
+
if (pkgName) {
|
|
590
|
+
result.all.add(pkgName);
|
|
591
|
+
result.all.add(pkgName.replace(/-/g, "_"));
|
|
592
|
+
addPythonPackageAliases(pkgName, result);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
// Extract optional dependencies from [project.optional-dependencies]
|
|
597
|
+
const optionalDeps = toml?.project?.["optional-dependencies"];
|
|
598
|
+
if (optionalDeps && typeof optionalDeps === "object") {
|
|
599
|
+
for (const group of Object.values(optionalDeps)) {
|
|
600
|
+
if (Array.isArray(group)) {
|
|
601
|
+
for (const dep of group) {
|
|
602
|
+
const pkgName = extractPackageNameFromPep508(dep);
|
|
603
|
+
if (pkgName) {
|
|
604
|
+
result.all.add(pkgName);
|
|
605
|
+
result.all.add(pkgName.replace(/-/g, "_"));
|
|
606
|
+
addPythonPackageAliases(pkgName, result);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
// Extract Poetry dependencies from [tool.poetry.dependencies]
|
|
613
|
+
const poetryDeps = toml?.tool?.poetry?.dependencies;
|
|
614
|
+
if (poetryDeps && typeof poetryDeps === "object") {
|
|
615
|
+
for (const pkgName of Object.keys(poetryDeps)) {
|
|
616
|
+
if (pkgName !== "python") {
|
|
617
|
+
result.all.add(pkgName.toLowerCase());
|
|
618
|
+
result.all.add(pkgName.toLowerCase().replace(/-/g, "_"));
|
|
619
|
+
addPythonPackageAliases(pkgName.toLowerCase(), result);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
// Extract Poetry dev dependencies
|
|
624
|
+
const poetryDevDeps = toml?.tool?.poetry?.["dev-dependencies"];
|
|
625
|
+
if (poetryDevDeps && typeof poetryDevDeps === "object") {
|
|
626
|
+
for (const pkgName of Object.keys(poetryDevDeps)) {
|
|
627
|
+
result.all.add(pkgName.toLowerCase());
|
|
628
|
+
result.all.add(pkgName.toLowerCase().replace(/-/g, "_"));
|
|
629
|
+
addPythonPackageAliases(pkgName.toLowerCase(), result);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
logger.debug(`Parsed pyproject.toml successfully`);
|
|
633
|
+
}
|
|
634
|
+
catch (err) {
|
|
635
|
+
// pyproject.toml not found or parse error
|
|
636
|
+
logger.debug(`Could not parse pyproject.toml: ${err}`);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* Extract package name from PEP 508 dependency string
|
|
641
|
+
* Examples: "requests>=2.0", "numpy[extra]", "package @ url"
|
|
642
|
+
*/
|
|
643
|
+
function extractPackageNameFromPep508(dep) {
|
|
644
|
+
if (typeof dep !== "string")
|
|
645
|
+
return null;
|
|
646
|
+
const trimmed = dep.trim();
|
|
647
|
+
if (!trimmed)
|
|
648
|
+
return null;
|
|
649
|
+
// Match package name at the start (alphanumeric, hyphens, underscores)
|
|
650
|
+
const match = trimmed.match(/^([a-zA-Z0-9][-a-zA-Z0-9._]*)/);
|
|
651
|
+
return match ? match[1].toLowerCase() : null;
|
|
652
|
+
}
|
|
653
|
+
/**
|
|
654
|
+
* Known Python pip-package-name -> import-name aliases.
|
|
655
|
+
* Shared between addPythonPackageAliases (forward) and
|
|
656
|
+
* getPythonImportToPackageMap (reverse).
|
|
657
|
+
*/
|
|
658
|
+
const PYTHON_PACKAGE_ALIASES = {
|
|
659
|
+
"scikit-learn": ["sklearn"],
|
|
660
|
+
pillow: ["PIL"],
|
|
661
|
+
"opencv-python": ["cv2"],
|
|
662
|
+
"opencv-python-headless": ["cv2"],
|
|
663
|
+
beautifulsoup4: ["bs4"],
|
|
664
|
+
pyyaml: ["yaml"],
|
|
665
|
+
"python-dateutil": ["dateutil"],
|
|
666
|
+
"python-dotenv": ["dotenv"],
|
|
667
|
+
pymysql: ["MySQLdb"],
|
|
668
|
+
psycopg2: ["psycopg2"],
|
|
669
|
+
"psycopg2-binary": ["psycopg2"],
|
|
670
|
+
"google-cloud-storage": ["google.cloud.storage"],
|
|
671
|
+
"google-cloud-bigquery": ["google.cloud.bigquery"],
|
|
672
|
+
protobuf: ["google.protobuf"],
|
|
673
|
+
"nats-py": ["nats"],
|
|
674
|
+
"python-jose": ["jose"],
|
|
675
|
+
"python-json-logger": ["pythonjsonlogger"],
|
|
676
|
+
"python-multipart": ["multipart"],
|
|
677
|
+
"python-decouple": ["decouple"],
|
|
678
|
+
uvloop: ["uvloop"],
|
|
679
|
+
aiofiles: ["aiofiles"],
|
|
680
|
+
httpx: ["httpx"],
|
|
681
|
+
starlette: ["starlette"],
|
|
682
|
+
fastapi: ["fastapi", "starlette"],
|
|
683
|
+
celery: ["celery"],
|
|
684
|
+
"redis-py": ["redis"],
|
|
685
|
+
redis: ["redis"],
|
|
686
|
+
bcrypt: ["bcrypt"],
|
|
687
|
+
passlib: ["passlib"],
|
|
688
|
+
pyjwt: ["jwt"],
|
|
689
|
+
"stripe-python": ["stripe"],
|
|
690
|
+
"sentry-sdk": ["sentry_sdk"],
|
|
691
|
+
"opentelemetry-api": ["opentelemetry"],
|
|
692
|
+
"opentelemetry-sdk": ["opentelemetry"],
|
|
693
|
+
};
|
|
694
|
+
/**
|
|
695
|
+
* Add known Python package name -> import name aliases to the manifest.
|
|
696
|
+
* Called when processing each package found in requirements.txt / pyproject.toml.
|
|
697
|
+
*/
|
|
698
|
+
function addPythonPackageAliases(pkgName, result) {
|
|
699
|
+
const pkgAliases = PYTHON_PACKAGE_ALIASES[pkgName];
|
|
700
|
+
if (pkgAliases) {
|
|
701
|
+
for (const alias of pkgAliases) {
|
|
702
|
+
result.all.add(alias);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Reverse lookup: given a Python import name (e.g. "dateutil"),
|
|
708
|
+
* return the pip package name (e.g. "python-dateutil") if it's a known alias.
|
|
709
|
+
* Returns null if no mapping is found.
|
|
710
|
+
*/
|
|
711
|
+
export function getPythonPipNameForImport(importName) {
|
|
712
|
+
for (const [pipName, importNames] of Object.entries(PYTHON_PACKAGE_ALIASES)) {
|
|
713
|
+
if (importNames.includes(importName)) {
|
|
714
|
+
return pipName;
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return null;
|
|
718
|
+
}
|
|
719
|
+
//# sourceMappingURL=manifest.js.map
|