Dependency Auditor Skill Type: POWERFUL Category: Engineering Domain: Dependency Management & Security Overview The Dependency Auditor is a comprehensive toolkit for analyzing, auditing, and managing dependencies across multi-language software projects. This skill provides deep visibility into your project's dependency ecosystem, enabling teams to identify vulnerabilities, ensure license compliance, optimize dependency trees, and plan safe upgrades. In modern software development, dependencies form complex webs that can introduce significant security, legal, and maintenance risks. A single pr…

,'', v).split('.')]\n \n v1_parts = normalize(v1)\n v2_parts = normalize(v2)\n \n if v1_parts \u003c v2_parts:\n return -1\n elif v1_parts > v2_parts:\n return 1\n else:\n return 0\n except:\n return 0\n \n # Package file parsers\n \n def _parse_package_json(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse package.json for Node.js dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n data = json.load(f)\n \n # Parse dependencies\n for dep_type in ['dependencies', 'devDependencies']:\n if dep_type in data:\n for name, version in data[dep_type].items():\n dep = Dependency(\n name=name,\n version=version.replace('^', '').replace('~', '').replace('>=', '').replace('\u003c=', ''),\n ecosystem='npm',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing package.json: {e}\")\n \n return dependencies\n \n def _parse_package_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse package-lock.json for Node.js transitive dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n data = json.load(f)\n \n if 'packages' in data:\n for path, pkg_info in data['packages'].items():\n if path == '': # Skip root package\n continue\n \n name = path.split('/')[-1] if '/' in path else path\n version = pkg_info.get('version', '')\n \n dep = Dependency(\n name=name,\n version=version,\n ecosystem='npm',\n direct=False,\n description=pkg_info.get('description', '')\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing package-lock.json: {e}\")\n \n return dependencies\n \n def _parse_yarn_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse yarn.lock for Node.js dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Simple yarn.lock parsing\n packages = re.findall(r'^([^#\\s][^:]+):\\s*\\n(?:\\s+.*\\n)*?\\s+version\\s+\"([^\"]+)\"', content, re.MULTILINE)\n \n for package_spec, version in packages:\n name = package_spec.split('@')[0] if '@' in package_spec else package_spec\n name = name.strip('\"')\n \n dep = Dependency(\n name=name,\n version=version,\n ecosystem='npm',\n direct=False\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing yarn.lock: {e}\")\n \n return dependencies\n \n def _parse_requirements_txt(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse requirements.txt for Python dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n lines = f.readlines()\n \n for line in lines:\n line = line.strip()\n if line and not line.startswith('#') and not line.startswith('-'):\n # Parse package==version or package>=version patterns\n match = re.match(r'^([a-zA-Z0-9_-]+)([>\u003c=!]+)(.+)

Dependency Auditor Skill Type: POWERFUL Category: Engineering Domain: Dependency Management & Security Overview The Dependency Auditor is a comprehensive toolkit for analyzing, auditing, and managing dependencies across multi-language software projects. This skill provides deep visibility into your project's dependency ecosystem, enabling teams to identify vulnerabilities, ensure license compliance, optimize dependency trees, and plan safe upgrades. In modern software development, dependencies form complex webs that can introduce significant security, legal, and maintenance risks. A single pr…

, line)\n if match:\n name, operator, version = match.groups()\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='pypi',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing requirements.txt: {e}\")\n \n return dependencies\n \n def _parse_pyproject_toml(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse pyproject.toml for Python dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Simple TOML parsing for dependencies\n dep_section = re.search(r'\\[tool\\.poetry\\.dependencies\\](.*?)(?=\\[|\\Z)', content, re.DOTALL)\n if dep_section:\n for line in dep_section.group(1).split('\\n'):\n match = re.match(r'^([a-zA-Z0-9_-]+)\\s*=\\s*[\"\\']([^\"\\']+)[\"\\']', line.strip())\n if match:\n name, version = match.groups()\n if name != 'python':\n dep = Dependency(\n name=name,\n version=version.replace('^', '').replace('~', ''),\n ecosystem='pypi',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing pyproject.toml: {e}\")\n \n return dependencies\n \n def _parse_pipfile_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse Pipfile.lock for Python dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n data = json.load(f)\n \n for section in ['default', 'develop']:\n if section in data:\n for name, info in data[section].items():\n version = info.get('version', '').replace('==', '')\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='pypi',\n direct=(section == 'default')\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing Pipfile.lock: {e}\")\n \n return dependencies\n \n def _parse_poetry_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse poetry.lock for Python dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Extract package entries from TOML\n packages = re.findall(r'\\[\\[package\\]\\]\\nname\\s*=\\s*\"([^\"]+)\"\\nversion\\s*=\\s*\"([^\"]+)\"', content)\n \n for name, version in packages:\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='pypi',\n direct=False\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing poetry.lock: {e}\")\n \n return dependencies\n \n def _parse_go_mod(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse go.mod for Go dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Parse require block\n require_match = re.search(r'require\\s*\\((.*?)\\)', content, re.DOTALL)\n if require_match:\n requires = require_match.group(1)\n for line in requires.split('\\n'):\n match = re.match(r'\\s*([^\\s]+)\\s+v?([^\\s]+)', line.strip())\n if match:\n name, version = match.groups()\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='go',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing go.mod: {e}\")\n \n return dependencies\n \n def _parse_go_sum(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse go.sum for Go dependency checksums.\"\"\"\n return [] # go.sum mainly contains checksums, dependencies are in go.mod\n \n def _parse_cargo_toml(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse Cargo.toml for Rust dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Parse [dependencies] section\n dep_section = re.search(r'\\[dependencies\\](.*?)(?=\\[|\\Z)', content, re.DOTALL)\n if dep_section:\n for line in dep_section.group(1).split('\\n'):\n match = re.match(r'^([a-zA-Z0-9_-]+)\\s*=\\s*[\"\\']([^\"\\']+)[\"\\']', line.strip())\n if match:\n name, version = match.groups()\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='cargo',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing Cargo.toml: {e}\")\n \n return dependencies\n \n def _parse_cargo_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse Cargo.lock for Rust dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Parse [[package]] entries\n packages = re.findall(r'\\[\\[package\\]\\]\\nname\\s*=\\s*\"([^\"]+)\"\\nversion\\s*=\\s*\"([^\"]+)\"', content)\n \n for name, version in packages:\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='cargo',\n direct=False\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing Cargo.lock: {e}\")\n \n return dependencies\n \n def _parse_gemfile(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse Gemfile for Ruby dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Parse gem declarations\n gems = re.findall(r'gem\\s+[\"\\']([^\"\\']+)[\"\\'](?:\\s*,\\s*[\"\\']([^\"\\']+)[\"\\'])?', content)\n \n for gem_info in gems:\n name = gem_info[0]\n version = gem_info[1] if len(gem_info) > 1 and gem_info[1] else ''\n \n dep = Dependency(\n name=name,\n version=version,\n ecosystem='rubygems',\n direct=True\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing Gemfile: {e}\")\n \n return dependencies\n \n def _parse_gemfile_lock(self, file_path: Path) -> List[Dependency]:\n \"\"\"Parse Gemfile.lock for Ruby dependencies.\"\"\"\n dependencies = []\n \n try:\n with open(file_path, 'r') as f:\n content = f.read()\n \n # Extract GEM section\n gem_section = re.search(r'GEM\\s*\\n(.*?)(?=\\n\\S|\\Z)', content, re.DOTALL)\n if gem_section:\n specs = gem_section.group(1)\n gems = re.findall(r'\\s+([a-zA-Z0-9_-]+)\\s+\\(([^)]+)\\)', specs)\n \n for name, version in gems:\n dep = Dependency(\n name=name,\n version=version,\n ecosystem='rubygems',\n direct=False\n )\n dependencies.append(dep)\n \n except Exception as e:\n print(f\"Error parsing Gemfile.lock: {e}\")\n \n return dependencies\n \n def _generate_scan_summary(self, scan_results: Dict[str, Any]) -> Dict[str, Any]:\n \"\"\"Generate a summary of the scan results.\"\"\"\n total_deps = len(scan_results['dependencies'])\n unique_deps = len(set(dep.name for dep in scan_results['dependencies']))\n \n return {\n 'total_dependencies': total_deps,\n 'unique_dependencies': unique_deps,\n 'ecosystems_found': len(scan_results['ecosystems']),\n 'vulnerable_dependencies': len([dep for dep in scan_results['dependencies'] if dep.vulnerabilities]),\n 'vulnerability_breakdown': {\n 'high': scan_results['high_severity_count'],\n 'medium': scan_results['medium_severity_count'],\n 'low': scan_results['low_severity_count']\n }\n }\n \n def _generate_recommendations(self, scan_results: Dict[str, Any]) -> List[str]:\n \"\"\"Generate actionable recommendations based on scan results.\"\"\"\n recommendations = []\n \n high_count = scan_results['high_severity_count']\n medium_count = scan_results['medium_severity_count']\n \n if high_count > 0:\n recommendations.append(f\"URGENT: Address {high_count} high-severity vulnerabilities immediately\")\n \n if medium_count > 0:\n recommendations.append(f\"Schedule fixes for {medium_count} medium-severity vulnerabilities within 30 days\")\n \n vulnerable_deps = [dep for dep in scan_results['dependencies'] if dep.vulnerabilities]\n if vulnerable_deps:\n for dep in vulnerable_deps[:3]: # Top 3 most critical\n for vuln in dep.vulnerabilities:\n if vuln.fixed_version:\n recommendations.append(f\"Update {dep.name} from {dep.version} to {vuln.fixed_version} to fix {vuln.id}\")\n \n if len(scan_results['ecosystems']) > 3:\n recommendations.append(\"Consider consolidating package managers to reduce complexity\")\n \n return recommendations\n \n def generate_report(self, scan_results: Dict[str, Any], format: str = 'text') -> str:\n \"\"\"Generate a human-readable or JSON report.\"\"\"\n if format == 'json':\n # Convert Dependency objects to dicts for JSON serialization\n serializable_results = scan_results.copy()\n serializable_results['dependencies'] = [\n {\n 'name': dep.name,\n 'version': dep.version,\n 'ecosystem': dep.ecosystem,\n 'direct': dep.direct,\n 'license': dep.license,\n 'vulnerabilities': [asdict(vuln) for vuln in dep.vulnerabilities]\n }\n for dep in scan_results['dependencies']\n ]\n return json.dumps(serializable_results, indent=2, default=str)\n \n # Text format report\n report = []\n report.append(\"=\" * 60)\n report.append(\"DEPENDENCY SECURITY SCAN REPORT\")\n report.append(\"=\" * 60)\n report.append(f\"Scan Date: {scan_results['timestamp']}\")\n report.append(f\"Project: {scan_results['project_path']}\")\n report.append(\"\")\n \n # Summary\n summary = scan_results['scan_summary']\n report.append(\"SUMMARY:\")\n report.append(f\" Total Dependencies: {summary['total_dependencies']}\")\n report.append(f\" Unique Dependencies: {summary['unique_dependencies']}\")\n report.append(f\" Ecosystems: {', '.join(scan_results['ecosystems'])}\")\n report.append(f\" Vulnerabilities Found: {scan_results['vulnerabilities_found']}\")\n report.append(f\" High Severity: {summary['vulnerability_breakdown']['high']}\")\n report.append(f\" Medium Severity: {summary['vulnerability_breakdown']['medium']}\")\n report.append(f\" Low Severity: {summary['vulnerability_breakdown']['low']}\")\n report.append(\"\")\n \n # Vulnerable dependencies\n vulnerable_deps = [dep for dep in scan_results['dependencies'] if dep.vulnerabilities]\n if vulnerable_deps:\n report.append(\"VULNERABLE DEPENDENCIES:\")\n report.append(\"-\" * 30)\n \n for dep in vulnerable_deps:\n report.append(f\"Package: {dep.name} v{dep.version} ({dep.ecosystem})\")\n for vuln in dep.vulnerabilities:\n report.append(f\" • {vuln.id}: {vuln.summary}\")\n report.append(f\" Severity: {vuln.severity} (CVSS: {vuln.cvss_score})\")\n if vuln.fixed_version:\n report.append(f\" Fixed in: {vuln.fixed_version}\")\n report.append(\"\")\n \n # Recommendations\n if scan_results['recommendations']:\n report.append(\"RECOMMENDATIONS:\")\n report.append(\"-\" * 20)\n for i, rec in enumerate(scan_results['recommendations'], 1):\n report.append(f\"{i}. {rec}\")\n report.append(\"\")\n \n report.append(\"=\" * 60)\n return '\\n'.join(report)\n\ndef main():\n \"\"\"Main entry point for the dependency scanner.\"\"\"\n parser = argparse.ArgumentParser(\n description='Scan project dependencies for vulnerabilities and security issues',\n formatter_class=argparse.RawDescriptionHelpFormatter,\n epilog=\"\"\"\nExamples:\n python dep_scanner.py /path/to/project\n python dep_scanner.py . --format json --output results.json\n python dep_scanner.py /app --fail-on-high\n \"\"\"\n )\n \n parser.add_argument('project_path', \n help='Path to the project directory to scan')\n parser.add_argument('--format', choices=['text', 'json'], default='text',\n help='Output format (default: text)')\n parser.add_argument('--output', '-o',\n help='Output file path (default: stdout)')\n parser.add_argument('--fail-on-high', action='store_true',\n help='Exit with error code if high-severity vulnerabilities found')\n parser.add_argument('--quick-scan', action='store_true',\n help='Perform quick scan (skip transitive dependencies)')\n \n args = parser.parse_args()\n \n try:\n scanner = DependencyScanner()\n results = scanner.scan_project(args.project_path)\n report = scanner.generate_report(results, args.format)\n \n if args.output:\n with open(args.output, 'w') as f:\n f.write(report)\n print(f\"Report saved to {args.output}\")\n else:\n print(report)\n \n # Exit with error if high-severity vulnerabilities found and --fail-on-high is set\n if args.fail_on_high and results['high_severity_count'] > 0:\n sys.exit(1)\n \n except Exception as e:\n print(f\"Error: {e}\", file=sys.stderr)\n sys.exit(1)\n\nif __name__ == '__main__':\n main()","content_type":"text/x-python; charset=utf-8","language":"python","size":31256,"content_sha256":"309abbb1fb20df6dfcea77ac0e963bd61953cb4b46de8c1a6d10cae6d88546cd"},{"filename":"scripts/license_checker.py","content":"#!/usr/bin/env python3\n\"\"\"\nLicense Checker - Dependency license compliance and conflict analysis tool.\n\nThis script analyzes dependency licenses from package metadata, classifies them\ninto risk categories, detects license conflicts, and generates compliance\nreports with actionable recommendations for legal risk management.\n\nAuthor: Claude Skills Engineering Team\nLicense: MIT\n\"\"\"\n\nimport json\nimport os\nimport sys\nimport argparse\nfrom typing import Dict, List, Set, Any, Optional, Tuple\nfrom pathlib import Path\nfrom dataclasses import dataclass, asdict\nfrom datetime import datetime\nimport re\nfrom enum import Enum\n\nclass LicenseType(Enum):\n \"\"\"License classification types.\"\"\"\n PERMISSIVE = \"permissive\"\n COPYLEFT_STRONG = \"copyleft_strong\"\n COPYLEFT_WEAK = \"copyleft_weak\"\n PROPRIETARY = \"proprietary\"\n DUAL = \"dual\"\n UNKNOWN = \"unknown\"\n\nclass RiskLevel(Enum):\n \"\"\"Risk assessment levels.\"\"\"\n LOW = \"low\"\n MEDIUM = \"medium\"\n HIGH = \"high\"\n CRITICAL = \"critical\"\n\n@dataclass\nclass LicenseInfo:\n \"\"\"Represents license information for a dependency.\"\"\"\n name: str\n spdx_id: Optional[str]\n license_type: LicenseType\n risk_level: RiskLevel\n description: str\n restrictions: List[str]\n obligations: List[str]\n compatibility: Dict[str, bool]\n\n@dataclass\nclass DependencyLicense:\n \"\"\"Represents a dependency with its license information.\"\"\"\n name: str\n version: str\n ecosystem: str\n direct: bool\n license_declared: Optional[str]\n license_detected: Optional[LicenseInfo]\n license_files: List[str]\n confidence: float\n\n@dataclass\nclass LicenseConflict:\n \"\"\"Represents a license compatibility conflict.\"\"\"\n dependency1: str\n license1: str\n dependency2: str\n license2: str\n conflict_type: str\n severity: RiskLevel\n description: str\n resolution_options: List[str]\n\nclass LicenseChecker:\n \"\"\"Main license checking and compliance analysis class.\"\"\"\n \n def __init__(self):\n self.license_database = self._build_license_database()\n self.compatibility_matrix = self._build_compatibility_matrix()\n self.license_patterns = self._build_license_patterns()\n \n def _build_license_database(self) -> Dict[str, LicenseInfo]:\n \"\"\"Build comprehensive license database with risk classifications.\"\"\"\n return {\n # Permissive Licenses (Low Risk)\n 'MIT': LicenseInfo(\n name='MIT License',\n spdx_id='MIT',\n license_type=LicenseType.PERMISSIVE,\n risk_level=RiskLevel.LOW,\n description='Very permissive license with minimal restrictions',\n restrictions=['Include copyright notice', 'Include license text'],\n obligations=['Attribution'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n 'Apache-2.0': LicenseInfo(\n name='Apache License 2.0',\n spdx_id='Apache-2.0',\n license_type=LicenseType.PERMISSIVE,\n risk_level=RiskLevel.LOW,\n description='Permissive license with patent protection',\n restrictions=['Include copyright notice', 'Include license text', \n 'State changes', 'Include NOTICE file'],\n obligations=['Attribution', 'Patent grant'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': True\n }\n ),\n \n 'BSD-3-Clause': LicenseInfo(\n name='BSD 3-Clause License',\n spdx_id='BSD-3-Clause',\n license_type=LicenseType.PERMISSIVE,\n risk_level=RiskLevel.LOW,\n description='Permissive license with non-endorsement clause',\n restrictions=['Include copyright notice', 'Include license text',\n 'No endorsement using author names'],\n obligations=['Attribution'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n 'BSD-2-Clause': LicenseInfo(\n name='BSD 2-Clause License',\n spdx_id='BSD-2-Clause',\n license_type=LicenseType.PERMISSIVE,\n risk_level=RiskLevel.LOW,\n description='Very permissive license similar to MIT',\n restrictions=['Include copyright notice', 'Include license text'],\n obligations=['Attribution'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n 'ISC': LicenseInfo(\n name='ISC License',\n spdx_id='ISC',\n license_type=LicenseType.PERMISSIVE,\n risk_level=RiskLevel.LOW,\n description='Functionally equivalent to MIT license',\n restrictions=['Include copyright notice'],\n obligations=['Attribution'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n # Weak Copyleft Licenses (Medium Risk)\n 'MPL-2.0': LicenseInfo(\n name='Mozilla Public License 2.0',\n spdx_id='MPL-2.0',\n license_type=LicenseType.COPYLEFT_WEAK,\n risk_level=RiskLevel.MEDIUM,\n description='File-level copyleft license',\n restrictions=['Disclose source of modified files', 'Include copyright notice',\n 'Include license text', 'State changes'],\n obligations=['Source disclosure (modified files only)'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': True\n }\n ),\n \n 'LGPL-2.1': LicenseInfo(\n name='GNU Lesser General Public License 2.1',\n spdx_id='LGPL-2.1',\n license_type=LicenseType.COPYLEFT_WEAK,\n risk_level=RiskLevel.MEDIUM,\n description='Library-level copyleft license',\n restrictions=['Disclose source of library modifications', 'Include copyright notice',\n 'Include license text', 'Allow relinking'],\n obligations=['Source disclosure (library modifications)', 'Dynamic linking preferred'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n 'LGPL-3.0': LicenseInfo(\n name='GNU Lesser General Public License 3.0',\n spdx_id='LGPL-3.0',\n license_type=LicenseType.COPYLEFT_WEAK,\n risk_level=RiskLevel.MEDIUM,\n description='Library-level copyleft with patent provisions',\n restrictions=['Disclose source of library modifications', 'Include copyright notice',\n 'Include license text', 'Allow relinking', 'Anti-tivoization'],\n obligations=['Source disclosure (library modifications)', 'Patent grant'],\n compatibility={\n 'commercial': True, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': True\n }\n ),\n \n # Strong Copyleft Licenses (High Risk)\n 'GPL-2.0': LicenseInfo(\n name='GNU General Public License 2.0',\n spdx_id='GPL-2.0',\n license_type=LicenseType.COPYLEFT_STRONG,\n risk_level=RiskLevel.HIGH,\n description='Strong copyleft requiring full source disclosure',\n restrictions=['Disclose entire source code', 'Include copyright notice',\n 'Include license text', 'Use same license'],\n obligations=['Full source disclosure', 'License compatibility'],\n compatibility={\n 'commercial': False, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n 'GPL-3.0': LicenseInfo(\n name='GNU General Public License 3.0',\n spdx_id='GPL-3.0',\n license_type=LicenseType.COPYLEFT_STRONG,\n risk_level=RiskLevel.HIGH,\n description='Strong copyleft with patent and hardware provisions',\n restrictions=['Disclose entire source code', 'Include copyright notice',\n 'Include license text', 'Use same license', 'Anti-tivoization'],\n obligations=['Full source disclosure', 'Patent grant', 'License compatibility'],\n compatibility={\n 'commercial': False, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': True\n }\n ),\n \n 'AGPL-3.0': LicenseInfo(\n name='GNU Affero General Public License 3.0',\n spdx_id='AGPL-3.0',\n license_type=LicenseType.COPYLEFT_STRONG,\n risk_level=RiskLevel.CRITICAL,\n description='Network copyleft extending GPL to SaaS',\n restrictions=['Disclose entire source code', 'Include copyright notice',\n 'Include license text', 'Use same license', 'Network use triggers copyleft'],\n obligations=['Full source disclosure', 'Network service source disclosure'],\n compatibility={\n 'commercial': False, 'modification': True, 'distribution': True,\n 'private_use': True, 'patent_grant': True\n }\n ),\n \n # Proprietary/Commercial Licenses (High Risk)\n 'PROPRIETARY': LicenseInfo(\n name='Proprietary License',\n spdx_id=None,\n license_type=LicenseType.PROPRIETARY,\n risk_level=RiskLevel.HIGH,\n description='Commercial or custom proprietary license',\n restrictions=['Varies by license', 'Often no redistribution',\n 'May require commercial license'],\n obligations=['License agreement compliance', 'Payment obligations'],\n compatibility={\n 'commercial': False, 'modification': False, 'distribution': False,\n 'private_use': True, 'patent_grant': False\n }\n ),\n \n # Unknown/Unlicensed (Critical Risk)\n 'UNKNOWN': LicenseInfo(\n name='Unknown License',\n spdx_id=None,\n license_type=LicenseType.UNKNOWN,\n risk_level=RiskLevel.CRITICAL,\n description='No license detected or ambiguous licensing',\n restrictions=['Unknown', 'Assume no rights granted'],\n obligations=['Investigate and clarify licensing'],\n compatibility={\n 'commercial': False, 'modification': False, 'distribution': False,\n 'private_use': False, 'patent_grant': False\n }\n )\n }\n \n def _build_compatibility_matrix(self) -> Dict[str, Dict[str, bool]]:\n \"\"\"Build license compatibility matrix.\"\"\"\n return {\n 'MIT': {\n 'MIT': True, 'Apache-2.0': True, 'BSD-3-Clause': True, 'BSD-2-Clause': True,\n 'ISC': True, 'MPL-2.0': True, 'LGPL-2.1': True, 'LGPL-3.0': True,\n 'GPL-2.0': False, 'GPL-3.0': False, 'AGPL-3.0': False, 'PROPRIETARY': False\n },\n 'Apache-2.0': {\n 'MIT': True, 'Apache-2.0': True, 'BSD-3-Clause': True, 'BSD-2-Clause': True,\n 'ISC': True, 'MPL-2.0': True, 'LGPL-2.1': False, 'LGPL-3.0': True,\n 'GPL-2.0': False, 'GPL-3.0': True, 'AGPL-3.0': True, 'PROPRIETARY': False\n },\n 'GPL-2.0': {\n 'MIT': True, 'Apache-2.0': False, 'BSD-3-Clause': True, 'BSD-2-Clause': True,\n 'ISC': True, 'MPL-2.0': False, 'LGPL-2.1': True, 'LGPL-3.0': False,\n 'GPL-2.0': True, 'GPL-3.0': False, 'AGPL-3.0': False, 'PROPRIETARY': False\n },\n 'GPL-3.0': {\n 'MIT': True, 'Apache-2.0': True, 'BSD-3-Clause': True, 'BSD-2-Clause': True,\n 'ISC': True, 'MPL-2.0': True, 'LGPL-2.1': False, 'LGPL-3.0': True,\n 'GPL-2.0': False, 'GPL-3.0': True, 'AGPL-3.0': True, 'PROPRIETARY': False\n },\n 'AGPL-3.0': {\n 'MIT': True, 'Apache-2.0': True, 'BSD-3-Clause': True, 'BSD-2-Clause': True,\n 'ISC': True, 'MPL-2.0': True, 'LGPL-2.1': False, 'LGPL-3.0': True,\n 'GPL-2.0': False, 'GPL-3.0': True, 'AGPL-3.0': True, 'PROPRIETARY': False\n }\n }\n \n def _build_license_patterns(self) -> Dict[str, List[str]]:\n \"\"\"Build license detection patterns for text analysis.\"\"\"\n return {\n 'MIT': [\n r'MIT License',\n r'Permission is hereby granted, free of charge',\n r'THE SOFTWARE IS PROVIDED \"AS IS\"'\n ],\n 'Apache-2.0': [\n r'Apache License, Version 2\\.0',\n r'Licensed under the Apache License',\n r'http://www\\.apache\\.org/licenses/LICENSE-2\\.0'\n ],\n 'GPL-2.0': [\n r'GNU GENERAL PUBLIC LICENSE\\s+Version 2',\n r'This program is free software.*GPL.*version 2',\n r'http://www\\.gnu\\.org/licenses/gpl-2\\.0'\n ],\n 'GPL-3.0': [\n r'GNU GENERAL PUBLIC LICENSE\\s+Version 3',\n r'This program is free software.*GPL.*version 3',\n r'http://www\\.gnu\\.org/licenses/gpl-3\\.0'\n ],\n 'BSD-3-Clause': [\n r'BSD 3-Clause License',\n r'Redistributions of source code must retain',\n r'Neither the name.*may be used to endorse'\n ],\n 'BSD-2-Clause': [\n r'BSD 2-Clause License',\n r'Redistributions of source code must retain.*Redistributions in binary form'\n ]\n }\n \n def analyze_project(self, project_path: str, dependency_inventory: Optional[str] = None) -> Dict[str, Any]:\n \"\"\"Analyze license compliance for a project.\"\"\"\n project_path = Path(project_path)\n \n analysis_results = {\n 'timestamp': datetime.now().isoformat(),\n 'project_path': str(project_path),\n 'project_license': self._detect_project_license(project_path),\n 'dependencies': [],\n 'license_summary': {},\n 'conflicts': [],\n 'compliance_score': 0.0,\n 'risk_assessment': {},\n 'recommendations': []\n }\n \n # Load dependencies from inventory or scan project\n if dependency_inventory:\n dependencies = self._load_dependency_inventory(dependency_inventory)\n else:\n dependencies = self._scan_project_dependencies(project_path)\n \n # Analyze each dependency's license\n for dep in dependencies:\n license_info = self._analyze_dependency_license(dep, project_path)\n analysis_results['dependencies'].append(license_info)\n \n # Generate license summary\n analysis_results['license_summary'] = self._generate_license_summary(\n analysis_results['dependencies']\n )\n \n # Detect conflicts\n analysis_results['conflicts'] = self._detect_license_conflicts(\n analysis_results['project_license'],\n analysis_results['dependencies']\n )\n \n # Calculate compliance score\n analysis_results['compliance_score'] = self._calculate_compliance_score(\n analysis_results['dependencies'],\n analysis_results['conflicts']\n )\n \n # Generate risk assessment\n analysis_results['risk_assessment'] = self._generate_risk_assessment(\n analysis_results['dependencies'],\n analysis_results['conflicts']\n )\n \n # Generate recommendations\n analysis_results['recommendations'] = self._generate_compliance_recommendations(\n analysis_results\n )\n \n return analysis_results\n \n def _detect_project_license(self, project_path: Path) -> Optional[str]:\n \"\"\"Detect the main project license.\"\"\"\n license_files = ['LICENSE', 'LICENSE.txt', 'LICENSE.md', 'COPYING', 'COPYING.txt']\n \n for license_file in license_files:\n license_path = project_path / license_file\n if license_path.exists():\n try:\n with open(license_path, 'r', encoding='utf-8') as f:\n content = f.read()\n \n # Analyze license content\n detected_license = self._detect_license_from_text(content)\n if detected_license:\n return detected_license\n except Exception as e:\n print(f\"Error reading license file {license_path}: {e}\")\n \n return None\n \n def _detect_license_from_text(self, text: str) -> Optional[str]:\n \"\"\"Detect license type from text content.\"\"\"\n text_upper = text.upper()\n \n for license_id, patterns in self.license_patterns.items():\n for pattern in patterns:\n if re.search(pattern, text, re.IGNORECASE):\n return license_id\n \n # Common license text patterns\n if 'MIT' in text_upper and 'PERMISSION IS HEREBY GRANTED' in text_upper:\n return 'MIT'\n elif 'APACHE LICENSE' in text_upper and 'VERSION 2.0' in text_upper:\n return 'Apache-2.0'\n elif 'GPL' in text_upper and 'VERSION 2' in text_upper:\n return 'GPL-2.0'\n elif 'GPL' in text_upper and 'VERSION 3' in text_upper:\n return 'GPL-3.0'\n \n return None\n \n def _load_dependency_inventory(self, inventory_path: str) -> List[Dict[str, Any]]:\n \"\"\"Load dependencies from JSON inventory file.\"\"\"\n try:\n with open(inventory_path, 'r') as f:\n data = json.load(f)\n \n if 'dependencies' in data:\n return data['dependencies']\n else:\n return data if isinstance(data, list) else []\n except Exception as e:\n print(f\"Error loading dependency inventory: {e}\")\n return []\n \n def _scan_project_dependencies(self, project_path: Path) -> List[Dict[str, Any]]:\n \"\"\"Basic dependency scanning - in practice, would integrate with dep_scanner.py.\"\"\"\n dependencies = []\n \n # Simple package.json parsing as example\n package_json = project_path / 'package.json'\n if package_json.exists():\n try:\n with open(package_json, 'r') as f:\n data = json.load(f)\n \n for dep_type in ['dependencies', 'devDependencies']:\n if dep_type in data:\n for name, version in data[dep_type].items():\n dependencies.append({\n 'name': name,\n 'version': version,\n 'ecosystem': 'npm',\n 'direct': True\n })\n except Exception as e:\n print(f\"Error parsing package.json: {e}\")\n \n return dependencies\n \n def _analyze_dependency_license(self, dependency: Dict[str, Any], project_path: Path) -> DependencyLicense:\n \"\"\"Analyze license information for a single dependency.\"\"\"\n dep_license = DependencyLicense(\n name=dependency['name'],\n version=dependency.get('version', ''),\n ecosystem=dependency.get('ecosystem', ''),\n direct=dependency.get('direct', False),\n license_declared=dependency.get('license'),\n license_detected=None,\n license_files=[],\n confidence=0.0\n )\n \n # Try to detect license from various sources\n declared_license = dependency.get('license')\n if declared_license:\n license_info = self._resolve_license_info(declared_license)\n if license_info:\n dep_license.license_detected = license_info\n dep_license.confidence = 0.9\n \n # For unknown licenses, try to find license files in node_modules (example)\n if not dep_license.license_detected and dep_license.ecosystem == 'npm':\n node_modules_path = project_path / 'node_modules' / dep_license.name\n if node_modules_path.exists():\n license_info = self._scan_package_directory(node_modules_path)\n if license_info:\n dep_license.license_detected = license_info\n dep_license.confidence = 0.7\n \n # Default to unknown if no license detected\n if not dep_license.license_detected:\n dep_license.license_detected = self.license_database['UNKNOWN']\n dep_license.confidence = 0.0\n \n return dep_license\n \n def _resolve_license_info(self, license_string: str) -> Optional[LicenseInfo]:\n \"\"\"Resolve license string to LicenseInfo object.\"\"\"\n if not license_string:\n return None\n \n license_string = license_string.strip()\n \n # Direct SPDX ID match\n if license_string in self.license_database:\n return self.license_database[license_string]\n \n # Common variations and mappings\n license_mappings = {\n 'mit': 'MIT',\n 'apache': 'Apache-2.0',\n 'apache-2.0': 'Apache-2.0',\n 'apache 2.0': 'Apache-2.0',\n 'bsd': 'BSD-3-Clause',\n 'bsd-3-clause': 'BSD-3-Clause',\n 'bsd-2-clause': 'BSD-2-Clause',\n 'gpl-2.0': 'GPL-2.0',\n 'gpl-3.0': 'GPL-3.0',\n 'lgpl-2.1': 'LGPL-2.1',\n 'lgpl-3.0': 'LGPL-3.0',\n 'mpl-2.0': 'MPL-2.0',\n 'isc': 'ISC',\n 'unlicense': 'MIT', # Treat as permissive\n 'public domain': 'MIT', # Treat as permissive\n 'proprietary': 'PROPRIETARY',\n 'commercial': 'PROPRIETARY'\n }\n \n license_lower = license_string.lower()\n for pattern, mapped_license in license_mappings.items():\n if pattern in license_lower:\n return self.license_database.get(mapped_license)\n \n return None\n \n def _scan_package_directory(self, package_path: Path) -> Optional[LicenseInfo]:\n \"\"\"Scan package directory for license information.\"\"\"\n license_files = ['LICENSE', 'LICENSE.txt', 'LICENSE.md', 'COPYING', 'README.md', 'package.json']\n \n for license_file in license_files:\n file_path = package_path / license_file\n if file_path.exists():\n try:\n with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:\n content = f.read()\n \n # Try to detect license from content\n if license_file == 'package.json':\n # Parse JSON for license field\n try:\n data = json.loads(content)\n license_field = data.get('license')\n if license_field:\n return self._resolve_license_info(license_field)\n except:\n continue\n else:\n # Analyze text content\n detected_license = self._detect_license_from_text(content)\n if detected_license:\n return self.license_database.get(detected_license)\n except Exception:\n continue\n \n return None\n \n def _generate_license_summary(self, dependencies: List[DependencyLicense]) -> Dict[str, Any]:\n \"\"\"Generate summary of license distribution.\"\"\"\n summary = {\n 'total_dependencies': len(dependencies),\n 'license_types': {},\n 'risk_levels': {},\n 'unknown_licenses': 0,\n 'direct_dependencies': 0,\n 'transitive_dependencies': 0\n }\n \n for dep in dependencies:\n # Count by license type\n license_type = dep.license_detected.license_type.value\n summary['license_types'][license_type] = summary['license_types'].get(license_type, 0) + 1\n \n # Count by risk level\n risk_level = dep.license_detected.risk_level.value\n summary['risk_levels'][risk_level] = summary['risk_levels'].get(risk_level, 0) + 1\n \n # Count unknowns\n if dep.license_detected.license_type == LicenseType.UNKNOWN:\n summary['unknown_licenses'] += 1\n \n # Count direct vs transitive\n if dep.direct:\n summary['direct_dependencies'] += 1\n else:\n summary['transitive_dependencies'] += 1\n \n return summary\n \n def _detect_license_conflicts(self, project_license: Optional[str], \n dependencies: List[DependencyLicense]) -> List[LicenseConflict]:\n \"\"\"Detect license compatibility conflicts.\"\"\"\n conflicts = []\n \n if not project_license:\n # If no project license detected, flag as potential issue\n for dep in dependencies:\n if dep.license_detected.risk_level in [RiskLevel.HIGH, RiskLevel.CRITICAL]:\n conflicts.append(LicenseConflict(\n dependency1='Project',\n license1='Unknown',\n dependency2=dep.name,\n license2=dep.license_detected.spdx_id or dep.license_detected.name,\n conflict_type='Unknown project license',\n severity=RiskLevel.HIGH,\n description=f'Project license unknown, dependency {dep.name} has {dep.license_detected.risk_level.value} risk license',\n resolution_options=['Define project license', 'Review dependency usage']\n ))\n return conflicts\n \n project_license_info = self.license_database.get(project_license)\n if not project_license_info:\n return conflicts\n \n # Check compatibility with project license\n for dep in dependencies:\n dep_license_id = dep.license_detected.spdx_id or 'UNKNOWN'\n \n # Check compatibility matrix\n if project_license in self.compatibility_matrix:\n compatibility = self.compatibility_matrix[project_license].get(dep_license_id, False)\n \n if not compatibility:\n severity = self._determine_conflict_severity(project_license_info, dep.license_detected)\n \n conflicts.append(LicenseConflict(\n dependency1='Project',\n license1=project_license,\n dependency2=dep.name,\n license2=dep_license_id,\n conflict_type='License incompatibility',\n severity=severity,\n description=f'Project license {project_license} is incompatible with dependency license {dep_license_id}',\n resolution_options=self._generate_conflict_resolutions(project_license, dep_license_id)\n ))\n \n # Check for GPL contamination in permissive projects\n if project_license_info.license_type == LicenseType.PERMISSIVE:\n for dep in dependencies:\n if dep.license_detected.license_type == LicenseType.COPYLEFT_STRONG:\n conflicts.append(LicenseConflict(\n dependency1='Project',\n license1=project_license,\n dependency2=dep.name,\n license2=dep.license_detected.spdx_id or dep.license_detected.name,\n conflict_type='GPL contamination',\n severity=RiskLevel.CRITICAL,\n description=f'GPL dependency {dep.name} may contaminate permissive project',\n resolution_options=['Remove GPL dependency', 'Change project license to GPL', \n 'Use dynamic linking', 'Find alternative dependency']\n ))\n \n return conflicts\n \n def _determine_conflict_severity(self, project_license: LicenseInfo, dep_license: LicenseInfo) -> RiskLevel:\n \"\"\"Determine severity of a license conflict.\"\"\"\n if dep_license.license_type == LicenseType.UNKNOWN:\n return RiskLevel.CRITICAL\n elif (project_license.license_type == LicenseType.PERMISSIVE and \n dep_license.license_type == LicenseType.COPYLEFT_STRONG):\n return RiskLevel.CRITICAL\n elif dep_license.license_type == LicenseType.PROPRIETARY:\n return RiskLevel.HIGH\n else:\n return RiskLevel.MEDIUM\n \n def _generate_conflict_resolutions(self, project_license: str, dep_license: str) -> List[str]:\n \"\"\"Generate resolution options for license conflicts.\"\"\"\n resolutions = []\n \n if 'GPL' in dep_license:\n resolutions.extend([\n 'Find alternative non-GPL dependency',\n 'Use dynamic linking if possible',\n 'Consider changing project license to GPL-compatible',\n 'Remove the dependency if not essential'\n ])\n elif dep_license == 'PROPRIETARY':\n resolutions.extend([\n 'Obtain commercial license',\n 'Find open-source alternative',\n 'Remove dependency if not essential',\n 'Negotiate license terms'\n ])\n else:\n resolutions.extend([\n 'Review license compatibility carefully',\n 'Consult legal counsel',\n 'Find alternative dependency',\n 'Consider license exception'\n ])\n \n return resolutions\n \n def _calculate_compliance_score(self, dependencies: List[DependencyLicense], \n conflicts: List[LicenseConflict]) -> float:\n \"\"\"Calculate overall compliance score (0-100).\"\"\"\n if not dependencies:\n return 100.0\n \n base_score = 100.0\n \n # Deduct points for unknown licenses\n unknown_count = sum(1 for dep in dependencies \n if dep.license_detected.license_type == LicenseType.UNKNOWN)\n base_score -= (unknown_count / len(dependencies)) * 30\n \n # Deduct points for high-risk licenses\n high_risk_count = sum(1 for dep in dependencies \n if dep.license_detected.risk_level in [RiskLevel.HIGH, RiskLevel.CRITICAL])\n base_score -= (high_risk_count / len(dependencies)) * 20\n \n # Deduct points for conflicts\n if conflicts:\n critical_conflicts = sum(1 for c in conflicts if c.severity == RiskLevel.CRITICAL)\n high_conflicts = sum(1 for c in conflicts if c.severity == RiskLevel.HIGH)\n \n base_score -= critical_conflicts * 15\n base_score -= high_conflicts * 10\n \n return max(0.0, base_score)\n \n def _generate_risk_assessment(self, dependencies: List[DependencyLicense], \n conflicts: List[LicenseConflict]) -> Dict[str, Any]:\n \"\"\"Generate comprehensive risk assessment.\"\"\"\n return {\n 'overall_risk': self._calculate_overall_risk(dependencies, conflicts),\n 'license_risk_breakdown': self._calculate_license_risks(dependencies),\n 'conflict_summary': {\n 'total_conflicts': len(conflicts),\n 'critical_conflicts': len([c for c in conflicts if c.severity == RiskLevel.CRITICAL]),\n 'high_conflicts': len([c for c in conflicts if c.severity == RiskLevel.HIGH])\n },\n 'distribution_risks': self._assess_distribution_risks(dependencies),\n 'commercial_risks': self._assess_commercial_risks(dependencies)\n }\n \n def _calculate_overall_risk(self, dependencies: List[DependencyLicense], \n conflicts: List[LicenseConflict]) -> str:\n \"\"\"Calculate overall project risk level.\"\"\"\n if any(c.severity == RiskLevel.CRITICAL for c in conflicts):\n return 'CRITICAL'\n elif any(dep.license_detected.risk_level == RiskLevel.CRITICAL for dep in dependencies):\n return 'CRITICAL'\n elif any(c.severity == RiskLevel.HIGH for c in conflicts):\n return 'HIGH'\n elif any(dep.license_detected.risk_level == RiskLevel.HIGH for dep in dependencies):\n return 'HIGH'\n elif any(dep.license_detected.risk_level == RiskLevel.MEDIUM for dep in dependencies):\n return 'MEDIUM'\n else:\n return 'LOW'\n \n def _calculate_license_risks(self, dependencies: List[DependencyLicense]) -> Dict[str, int]:\n \"\"\"Calculate breakdown of license risks.\"\"\"\n risks = {'low': 0, 'medium': 0, 'high': 0, 'critical': 0}\n \n for dep in dependencies:\n risk_level = dep.license_detected.risk_level.value\n risks[risk_level] += 1\n \n return risks\n \n def _assess_distribution_risks(self, dependencies: List[DependencyLicense]) -> List[str]:\n \"\"\"Assess risks related to software distribution.\"\"\"\n risks = []\n \n gpl_deps = [dep for dep in dependencies \n if dep.license_detected.license_type == LicenseType.COPYLEFT_STRONG]\n if gpl_deps:\n risks.append(f\"GPL dependencies require source code disclosure: {[d.name for d in gpl_deps]}\")\n \n proprietary_deps = [dep for dep in dependencies \n if dep.license_detected.license_type == LicenseType.PROPRIETARY]\n if proprietary_deps:\n risks.append(f\"Proprietary dependencies may require commercial licenses: {[d.name for d in proprietary_deps]}\")\n \n unknown_deps = [dep for dep in dependencies \n if dep.license_detected.license_type == LicenseType.UNKNOWN]\n if unknown_deps:\n risks.append(f\"Unknown licenses pose legal uncertainty: {[d.name for d in unknown_deps]}\")\n \n return risks\n \n def _assess_commercial_risks(self, dependencies: List[DependencyLicense]) -> List[str]:\n \"\"\"Assess risks for commercial usage.\"\"\"\n risks = []\n \n agpl_deps = [dep for dep in dependencies \n if dep.license_detected.spdx_id == 'AGPL-3.0']\n if agpl_deps:\n risks.append(f\"AGPL dependencies trigger copyleft for network services: {[d.name for d in agpl_deps]}\")\n \n return risks\n \n def _generate_compliance_recommendations(self, analysis_results: Dict[str, Any]) -> List[str]:\n \"\"\"Generate actionable compliance recommendations.\"\"\"\n recommendations = []\n \n # Address critical issues first\n critical_conflicts = [c for c in analysis_results['conflicts'] \n if c.severity == RiskLevel.CRITICAL]\n if critical_conflicts:\n recommendations.append(\"CRITICAL: Address license conflicts immediately before any distribution\")\n for conflict in critical_conflicts[:3]: # Top 3\n recommendations.append(f\" • {conflict.description}\")\n \n # Unknown licenses\n unknown_count = analysis_results['license_summary']['unknown_licenses']\n if unknown_count > 0:\n recommendations.append(f\"Investigate and clarify licenses for {unknown_count} dependencies with unknown licensing\")\n \n # GPL contamination\n gpl_deps = [dep for dep in analysis_results['dependencies'] \n if dep.license_detected.license_type == LicenseType.COPYLEFT_STRONG]\n if gpl_deps and analysis_results.get('project_license') in ['MIT', 'Apache-2.0', 'BSD-3-Clause']:\n recommendations.append(\"Consider removing GPL dependencies or changing project license for permissive project\")\n \n # Compliance score\n if analysis_results['compliance_score'] \u003c 70:\n recommendations.append(\"Overall compliance score is low - prioritize license cleanup\")\n \n return recommendations\n \n def generate_report(self, analysis_results: Dict[str, Any], format: str = 'text') -> str:\n \"\"\"Generate compliance report in specified format.\"\"\"\n if format == 'json':\n # Convert dataclass objects for JSON serialization\n serializable_results = analysis_results.copy()\n serializable_results['dependencies'] = [\n {\n 'name': dep.name,\n 'version': dep.version,\n 'ecosystem': dep.ecosystem,\n 'direct': dep.direct,\n 'license_declared': dep.license_declared,\n 'license_detected': asdict(dep.license_detected) if dep.license_detected else None,\n 'confidence': dep.confidence\n }\n for dep in analysis_results['dependencies']\n ]\n serializable_results['conflicts'] = [asdict(conflict) for conflict in analysis_results['conflicts']]\n return json.dumps(serializable_results, indent=2, default=str)\n \n # Text format report\n report = []\n report.append(\"=\" * 60)\n report.append(\"LICENSE COMPLIANCE REPORT\")\n report.append(\"=\" * 60)\n report.append(f\"Analysis Date: {analysis_results['timestamp']}\")\n report.append(f\"Project: {analysis_results['project_path']}\")\n report.append(f\"Project License: {analysis_results['project_license'] or 'Unknown'}\")\n report.append(\"\")\n \n # Summary\n summary = analysis_results['license_summary']\n report.append(\"SUMMARY:\")\n report.append(f\" Total Dependencies: {summary['total_dependencies']}\")\n report.append(f\" Compliance Score: {analysis_results['compliance_score']:.1f}/100\")\n report.append(f\" Overall Risk: {analysis_results['risk_assessment']['overall_risk']}\")\n report.append(f\" License Conflicts: {len(analysis_results['conflicts'])}\")\n report.append(\"\")\n \n # License distribution\n report.append(\"LICENSE DISTRIBUTION:\")\n for license_type, count in summary['license_types'].items():\n report.append(f\" {license_type.title()}: {count}\")\n report.append(\"\")\n \n # Risk breakdown\n report.append(\"RISK BREAKDOWN:\")\n for risk_level, count in summary['risk_levels'].items():\n report.append(f\" {risk_level.title()}: {count}\")\n report.append(\"\")\n \n # Conflicts\n if analysis_results['conflicts']:\n report.append(\"LICENSE CONFLICTS:\")\n report.append(\"-\" * 30)\n for conflict in analysis_results['conflicts']:\n report.append(f\"Conflict: {conflict.dependency2} ({conflict.license2})\")\n report.append(f\" Issue: {conflict.description}\")\n report.append(f\" Severity: {conflict.severity.value.upper()}\")\n report.append(f\" Resolutions: {', '.join(conflict.resolution_options[:2])}\")\n report.append(\"\")\n \n # High-risk dependencies\n high_risk_deps = [dep for dep in analysis_results['dependencies'] \n if dep.license_detected.risk_level in [RiskLevel.HIGH, RiskLevel.CRITICAL]]\n if high_risk_deps:\n report.append(\"HIGH-RISK DEPENDENCIES:\")\n report.append(\"-\" * 30)\n for dep in high_risk_deps[:10]: # Top 10\n license_name = dep.license_detected.spdx_id or dep.license_detected.name\n report.append(f\" {dep.name} v{dep.version}: {license_name} ({dep.license_detected.risk_level.value.upper()})\")\n report.append(\"\")\n \n # Recommendations\n if analysis_results['recommendations']:\n report.append(\"RECOMMENDATIONS:\")\n report.append(\"-\" * 20)\n for i, rec in enumerate(analysis_results['recommendations'], 1):\n report.append(f\"{i}. {rec}\")\n report.append(\"\")\n \n report.append(\"=\" * 60)\n return '\\n'.join(report)\n\ndef main():\n \"\"\"Main entry point for the license checker.\"\"\"\n parser = argparse.ArgumentParser(\n description='Analyze dependency licenses for compliance and conflicts',\n formatter_class=argparse.RawDescriptionHelpFormatter,\n epilog=\"\"\"\nExamples:\n python license_checker.py /path/to/project\n python license_checker.py . --format json --output compliance.json\n python license_checker.py /app --inventory deps.json --policy strict\n \"\"\"\n )\n \n parser.add_argument('project_path',\n help='Path to the project directory to analyze')\n parser.add_argument('--inventory',\n help='Path to dependency inventory JSON file')\n parser.add_argument('--format', choices=['text', 'json'], default='text',\n help='Output format (default: text)')\n parser.add_argument('--output', '-o',\n help='Output file path (default: stdout)')\n parser.add_argument('--policy', choices=['permissive', 'strict'], default='permissive',\n help='License policy strictness (default: permissive)')\n parser.add_argument('--warn-conflicts', action='store_true',\n help='Show warnings for potential conflicts')\n \n args = parser.parse_args()\n \n try:\n checker = LicenseChecker()\n results = checker.analyze_project(args.project_path, args.inventory)\n report = checker.generate_report(results, args.format)\n \n if args.output:\n with open(args.output, 'w') as f:\n f.write(report)\n print(f\"Compliance report saved to {args.output}\")\n else:\n print(report)\n \n # Exit with error code for policy violations\n if args.policy == 'strict' and results['compliance_score'] \u003c 80:\n sys.exit(1)\n \n if args.warn_conflicts and results['conflicts']:\n print(\"\\nWARNING: License conflicts detected!\")\n sys.exit(2)\n \n except Exception as e:\n print(f\"Error: {e}\", file=sys.stderr)\n sys.exit(1)\n\nif __name__ == '__main__':\n main()","content_type":"text/x-python; charset=utf-8","language":"python","size":44397,"content_sha256":"7fa7b6d19cc8de7d38850c24d1c8970fafac9df6bd4f44f883056745bd410dc8"},{"filename":"scripts/upgrade_planner.py","content":"#!/usr/bin/env python3\n\"\"\"\nUpgrade Planner - Dependency upgrade path planning and risk analysis tool.\n\nThis script analyzes dependency inventories, evaluates semantic versioning patterns,\nestimates breaking change risks, and generates prioritized upgrade plans with\nmigration checklists and rollback procedures.\n\nAuthor: Claude Skills Engineering Team\nLicense: MIT\n\"\"\"\n\nimport json\nimport os\nimport sys\nimport argparse\nfrom typing import Dict, List, Set, Any, Optional, Tuple\nfrom pathlib import Path\nfrom dataclasses import dataclass, asdict\nfrom datetime import datetime, timedelta\nfrom enum import Enum\nimport re\nimport subprocess\n\nclass UpgradeRisk(Enum):\n \"\"\"Upgrade risk levels.\"\"\"\n SAFE = \"safe\"\n LOW = \"low\"\n MEDIUM = \"medium\"\n HIGH = \"high\"\n CRITICAL = \"critical\"\n\nclass UpdateType(Enum):\n \"\"\"Semantic versioning update types.\"\"\"\n PATCH = \"patch\"\n MINOR = \"minor\"\n MAJOR = \"major\"\n PRERELEASE = \"prerelease\"\n\n@dataclass\nclass VersionInfo:\n \"\"\"Represents version information.\"\"\"\n major: int\n minor: int\n patch: int\n prerelease: Optional[str] = None\n build: Optional[str] = None\n \n def __str__(self):\n version = f\"{self.major}.{self.minor}.{self.patch}\"\n if self.prerelease:\n version += f\"-{self.prerelease}\"\n if self.build:\n version += f\"+{self.build}\"\n return version\n\n@dataclass\nclass DependencyUpgrade:\n \"\"\"Represents a potential dependency upgrade.\"\"\"\n name: str\n current_version: str\n latest_version: str\n ecosystem: str\n direct: bool\n update_type: UpdateType\n risk_level: UpgradeRisk\n security_updates: List[str]\n breaking_changes: List[str]\n migration_effort: str\n dependencies_affected: List[str]\n rollback_complexity: str\n estimated_time: str\n priority_score: float\n\n@dataclass\nclass UpgradePlan:\n \"\"\"Represents a complete upgrade plan.\"\"\"\n name: str\n description: str\n phase: int\n dependencies: List[str]\n estimated_duration: str\n prerequisites: List[str]\n migration_steps: List[str]\n testing_requirements: List[str]\n rollback_plan: List[str]\n success_criteria: List[str]\n\nclass UpgradePlanner:\n \"\"\"Main upgrade planning and risk analysis class.\"\"\"\n \n def __init__(self):\n self.breaking_change_patterns = self._build_breaking_change_patterns()\n self.ecosystem_knowledge = self._build_ecosystem_knowledge()\n self.security_advisories = self._build_security_advisories()\n \n def _build_breaking_change_patterns(self) -> Dict[str, List[str]]:\n \"\"\"Build patterns for detecting breaking changes.\"\"\"\n return {\n 'npm': [\n r'BREAKING\\s*CHANGE',\n r'breaking\\s*change',\n r'major\\s*version',\n r'removed.*API',\n r'deprecated.*removed',\n r'no\\s*longer\\s*supported',\n r'minimum.*node.*version',\n r'peer.*dependency.*change'\n ],\n 'pypi': [\n r'BREAKING\\s*CHANGE',\n r'breaking\\s*change',\n r'removed.*function',\n r'deprecated.*removed',\n r'minimum.*python.*version',\n r'incompatible.*change',\n r'API.*change'\n ],\n 'maven': [\n r'BREAKING\\s*CHANGE',\n r'breaking\\s*change',\n r'removed.*method',\n r'deprecated.*removed',\n r'minimum.*java.*version',\n r'API.*incompatible'\n ]\n }\n \n def _build_ecosystem_knowledge(self) -> Dict[str, Dict[str, Any]]:\n \"\"\"Build ecosystem-specific upgrade knowledge.\"\"\"\n return {\n 'npm': {\n 'typical_major_cycle_months': 12,\n 'typical_patch_cycle_weeks': 2,\n 'deprecation_notice_months': 6,\n 'lts_support_years': 3,\n 'common_breaking_changes': [\n 'Node.js version requirements',\n 'Peer dependency updates',\n 'API signature changes',\n 'Configuration format changes'\n ]\n },\n 'pypi': {\n 'typical_major_cycle_months': 18,\n 'typical_patch_cycle_weeks': 4,\n 'deprecation_notice_months': 12,\n 'lts_support_years': 2,\n 'common_breaking_changes': [\n 'Python version requirements',\n 'Function signature changes',\n 'Import path changes',\n 'Configuration changes'\n ]\n },\n 'maven': {\n 'typical_major_cycle_months': 24,\n 'typical_patch_cycle_weeks': 6,\n 'deprecation_notice_months': 12,\n 'lts_support_years': 5,\n 'common_breaking_changes': [\n 'Java version requirements',\n 'Method signature changes',\n 'Package restructuring',\n 'Dependency changes'\n ]\n },\n 'cargo': {\n 'typical_major_cycle_months': 6,\n 'typical_patch_cycle_weeks': 2,\n 'deprecation_notice_months': 3,\n 'lts_support_years': 1,\n 'common_breaking_changes': [\n 'Rust edition changes',\n 'Trait changes',\n 'Module restructuring',\n 'Macro changes'\n ]\n }\n }\n \n def _build_security_advisories(self) -> Dict[str, List[Dict[str, Any]]]:\n \"\"\"Build security advisory database for upgrade prioritization.\"\"\"\n return {\n 'lodash': [\n {\n 'advisory_id': 'CVE-2021-23337',\n 'severity': 'HIGH',\n 'fixed_in': '4.17.21',\n 'description': 'Prototype pollution vulnerability'\n }\n ],\n 'django': [\n {\n 'advisory_id': 'CVE-2024-27351',\n 'severity': 'HIGH',\n 'fixed_in': '4.2.11',\n 'description': 'SQL injection vulnerability'\n }\n ],\n 'express': [\n {\n 'advisory_id': 'CVE-2022-24999',\n 'severity': 'MEDIUM',\n 'fixed_in': '4.18.2',\n 'description': 'Open redirect vulnerability'\n }\n ],\n 'axios': [\n {\n 'advisory_id': 'CVE-2023-45857',\n 'severity': 'MEDIUM',\n 'fixed_in': '1.6.0',\n 'description': 'Cross-site request forgery'\n }\n ]\n }\n \n def analyze_upgrades(self, dependency_inventory: str, timeline_days: int = 90) -> Dict[str, Any]:\n \"\"\"Analyze potential dependency upgrades and create upgrade plan.\"\"\"\n dependencies = self._load_dependency_inventory(dependency_inventory)\n \n analysis_results = {\n 'timestamp': datetime.now().isoformat(),\n 'timeline_days': timeline_days,\n 'dependencies_analyzed': len(dependencies),\n 'available_upgrades': [],\n 'upgrade_statistics': {},\n 'risk_assessment': {},\n 'upgrade_plans': [],\n 'recommendations': []\n }\n \n # Analyze each dependency for upgrades\n for dep in dependencies:\n upgrade_info = self._analyze_dependency_upgrade(dep)\n if upgrade_info:\n analysis_results['available_upgrades'].append(upgrade_info)\n \n # Generate upgrade statistics\n analysis_results['upgrade_statistics'] = self._generate_upgrade_statistics(\n analysis_results['available_upgrades']\n )\n \n # Perform risk assessment\n analysis_results['risk_assessment'] = self._perform_risk_assessment(\n analysis_results['available_upgrades']\n )\n \n # Create phased upgrade plans\n analysis_results['upgrade_plans'] = self._create_upgrade_plans(\n analysis_results['available_upgrades'],\n timeline_days\n )\n \n # Generate recommendations\n analysis_results['recommendations'] = self._generate_upgrade_recommendations(\n analysis_results\n )\n \n return analysis_results\n \n def _load_dependency_inventory(self, inventory_path: str) -> List[Dict[str, Any]]:\n \"\"\"Load dependency inventory from JSON file.\"\"\"\n try:\n with open(inventory_path, 'r') as f:\n data = json.load(f)\n \n if 'dependencies' in data:\n return data['dependencies']\n elif isinstance(data, list):\n return data\n else:\n print(\"Warning: Unexpected inventory format\")\n return []\n \n except Exception as e:\n print(f\"Error loading dependency inventory: {e}\")\n return []\n \n def _analyze_dependency_upgrade(self, dependency: Dict[str, Any]) -> Optional[DependencyUpgrade]:\n \"\"\"Analyze upgrade possibilities for a single dependency.\"\"\"\n name = dependency.get('name', '')\n current_version = dependency.get('version', '').replace('^', '').replace('~', '')\n ecosystem = dependency.get('ecosystem', '')\n \n if not name or not current_version:\n return None\n \n # Parse current version\n current_ver = self._parse_version(current_version)\n if not current_ver:\n return None\n \n # Get latest version (simulated - in practice would query package registries)\n latest_version = self._get_latest_version(name, ecosystem)\n if not latest_version:\n return None\n \n latest_ver = self._parse_version(latest_version)\n if not latest_ver:\n return None\n \n # Determine if upgrade is needed\n if self._compare_versions(current_ver, latest_ver) >= 0:\n return None # Already up to date\n \n # Determine update type\n update_type = self._determine_update_type(current_ver, latest_ver)\n \n # Assess upgrade risk\n risk_level = self._assess_upgrade_risk(name, current_ver, latest_ver, ecosystem, update_type)\n \n # Check for security updates\n security_updates = self._check_security_updates(name, current_version, latest_version)\n \n # Analyze breaking changes\n breaking_changes = self._analyze_breaking_changes(name, current_ver, latest_ver, ecosystem)\n \n # Calculate priority score\n priority_score = self._calculate_priority_score(\n update_type, risk_level, security_updates, dependency.get('direct', False)\n )\n \n return DependencyUpgrade(\n name=name,\n current_version=current_version,\n latest_version=latest_version,\n ecosystem=ecosystem,\n direct=dependency.get('direct', False),\n update_type=update_type,\n risk_level=risk_level,\n security_updates=security_updates,\n breaking_changes=breaking_changes,\n migration_effort=self._estimate_migration_effort(update_type, breaking_changes),\n dependencies_affected=self._get_affected_dependencies(name, dependency),\n rollback_complexity=self._assess_rollback_complexity(update_type, risk_level),\n estimated_time=self._estimate_upgrade_time(update_type, breaking_changes),\n priority_score=priority_score\n )\n \n def _parse_version(self, version_string: str) -> Optional[VersionInfo]:\n \"\"\"Parse semantic version string.\"\"\"\n # Clean version string\n version = re.sub(r'[^0-9a-zA-Z.-]', '', version_string)\n \n # Basic semver pattern\n pattern = r'^(\\d+)\\.(\\d+)\\.(\\d+)(?:-([0-9A-Za-z.-]+))?(?:\\+([0-9A-Za-z.-]+))?

Dependency Auditor Skill Type: POWERFUL Category: Engineering Domain: Dependency Management & Security Overview The Dependency Auditor is a comprehensive toolkit for analyzing, auditing, and managing dependencies across multi-language software projects. This skill provides deep visibility into your project's dependency ecosystem, enabling teams to identify vulnerabilities, ensure license compliance, optimize dependency trees, and plan safe upgrades. In modern software development, dependencies form complex webs that can introduce significant security, legal, and maintenance risks. A single pr…

\n match = re.match(pattern, version)\n \n if match:\n major, minor, patch, prerelease, build = match.groups()\n return VersionInfo(\n major=int(major),\n minor=int(minor),\n patch=int(patch),\n prerelease=prerelease,\n build=build\n )\n \n # Fallback for simpler version patterns\n simple_pattern = r'^(\\d+)\\.(\\d+)(?:\\.(\\d+))?'\n match = re.match(simple_pattern, version)\n if match:\n major, minor, patch = match.groups()\n return VersionInfo(\n major=int(major),\n minor=int(minor),\n patch=int(patch or 0)\n )\n \n return None\n \n def _compare_versions(self, v1: VersionInfo, v2: VersionInfo) -> int:\n \"\"\"Compare two versions. Returns -1, 0, or 1.\"\"\"\n if (v1.major, v1.minor, v1.patch) \u003c (v2.major, v2.minor, v2.patch):\n return -1\n elif (v1.major, v1.minor, v1.patch) > (v2.major, v2.minor, v2.patch):\n return 1\n else:\n # Handle prerelease comparison\n if v1.prerelease and not v2.prerelease:\n return -1\n elif not v1.prerelease and v2.prerelease:\n return 1\n elif v1.prerelease and v2.prerelease:\n if v1.prerelease \u003c v2.prerelease:\n return -1\n elif v1.prerelease > v2.prerelease:\n return 1\n \n return 0\n \n def _get_latest_version(self, package_name: str, ecosystem: str) -> Optional[str]:\n \"\"\"Get latest version from package registry (simulated).\"\"\"\n # Simulated latest versions for common packages\n mock_versions = {\n 'lodash': '4.17.21',\n 'express': '4.18.2',\n 'react': '18.2.0',\n 'axios': '1.6.0',\n 'django': '4.2.11',\n 'requests': '2.31.0',\n 'numpy': '1.24.0',\n 'flask': '2.3.0',\n 'fastapi': '0.104.0',\n 'pytest': '7.4.0'\n }\n \n # In production, would query actual package registries:\n # npm: npm view \u003cpackage> version\n # pypi: pip index versions \u003cpackage>\n # maven: maven metadata API\n \n return mock_versions.get(package_name.lower())\n \n def _determine_update_type(self, current: VersionInfo, latest: VersionInfo) -> UpdateType:\n \"\"\"Determine the type of update based on semantic versioning.\"\"\"\n if latest.major > current.major:\n return UpdateType.MAJOR\n elif latest.minor > current.minor:\n return UpdateType.MINOR\n elif latest.patch > current.patch:\n return UpdateType.PATCH\n elif latest.prerelease and not current.prerelease:\n return UpdateType.PRERELEASE\n else:\n return UpdateType.PATCH # Default fallback\n \n def _assess_upgrade_risk(self, package_name: str, current: VersionInfo, latest: VersionInfo,\n ecosystem: str, update_type: UpdateType) -> UpgradeRisk:\n \"\"\"Assess the risk level of an upgrade.\"\"\"\n # Base risk assessment on update type\n base_risk = {\n UpdateType.PATCH: UpgradeRisk.SAFE,\n UpdateType.MINOR: UpgradeRisk.LOW,\n UpdateType.MAJOR: UpgradeRisk.HIGH,\n UpdateType.PRERELEASE: UpgradeRisk.MEDIUM\n }.get(update_type, UpgradeRisk.MEDIUM)\n \n # Adjust for package-specific factors\n high_risk_packages = [\n 'webpack', 'babel', 'typescript', 'eslint', # Build tools\n 'react', 'vue', 'angular', # Frameworks\n 'django', 'flask', 'fastapi', # Web frameworks\n 'spring-boot', 'hibernate' # Java frameworks\n ]\n \n if package_name.lower() in high_risk_packages and update_type == UpdateType.MAJOR:\n base_risk = UpgradeRisk.CRITICAL\n \n # Check for known breaking changes\n if self._has_known_breaking_changes(package_name, current, latest):\n if base_risk in [UpgradeRisk.SAFE, UpgradeRisk.LOW]:\n base_risk = UpgradeRisk.MEDIUM\n elif base_risk == UpgradeRisk.MEDIUM:\n base_risk = UpgradeRisk.HIGH\n \n return base_risk\n \n def _has_known_breaking_changes(self, package_name: str, current: VersionInfo, latest: VersionInfo) -> bool:\n \"\"\"Check if there are known breaking changes between versions.\"\"\"\n # Simulated breaking change detection\n breaking_change_versions = {\n 'react': ['16.0.0', '17.0.0', '18.0.0'],\n 'django': ['2.0.0', '3.0.0', '4.0.0'],\n 'webpack': ['4.0.0', '5.0.0'],\n 'babel': ['7.0.0', '8.0.0'],\n 'typescript': ['4.0.0', '5.0.0']\n }\n \n package_versions = breaking_change_versions.get(package_name.lower(), [])\n latest_str = str(latest)\n \n return any(latest_str.startswith(v.split('.')[0]) for v in package_versions)\n \n def _check_security_updates(self, package_name: str, current_version: str, latest_version: str) -> List[str]:\n \"\"\"Check for security updates in the upgrade.\"\"\"\n security_updates = []\n \n if package_name in self.security_advisories:\n for advisory in self.security_advisories[package_name]:\n fixed_version = advisory['fixed_in']\n \n # Simple version comparison for security fixes\n if (self._is_version_greater(fixed_version, current_version) and\n not self._is_version_greater(fixed_version, latest_version)):\n security_updates.append(f\"{advisory['advisory_id']}: {advisory['description']}\")\n \n return security_updates\n \n def _is_version_greater(self, v1: str, v2: str) -> bool:\n \"\"\"Simple version comparison.\"\"\"\n v1_parts = [int(x) for x in v1.split('.')]\n v2_parts = [int(x) for x in v2.split('.')]\n \n # Pad shorter version\n max_len = max(len(v1_parts), len(v2_parts))\n v1_parts.extend([0] * (max_len - len(v1_parts)))\n v2_parts.extend([0] * (max_len - len(v2_parts)))\n \n return v1_parts > v2_parts\n \n def _analyze_breaking_changes(self, package_name: str, current: VersionInfo, \n latest: VersionInfo, ecosystem: str) -> List[str]:\n \"\"\"Analyze potential breaking changes.\"\"\"\n breaking_changes = []\n \n # Check if major version change\n if latest.major > current.major:\n breaking_changes.append(f\"Major version upgrade from {current.major}.x to {latest.major}.x\")\n \n # Add ecosystem-specific common breaking changes\n ecosystem_knowledge = self.ecosystem_knowledge.get(ecosystem, {})\n common_changes = ecosystem_knowledge.get('common_breaking_changes', [])\n breaking_changes.extend(common_changes[:2]) # Add top 2\n \n # Check for specific package patterns\n if package_name.lower() == 'react' and latest.major >= 17:\n breaking_changes.append(\"New JSX Transform\")\n if latest.major >= 18:\n breaking_changes.append(\"Concurrent Rendering changes\")\n \n elif package_name.lower() == 'django' and latest.major >= 4:\n breaking_changes.append(\"CSRF token changes\")\n breaking_changes.append(\"Default AUTO_INCREMENT field changes\")\n \n elif package_name.lower() == 'webpack' and latest.major >= 5:\n breaking_changes.append(\"Module Federation support\")\n breaking_changes.append(\"Asset modules replace file-loader\")\n \n return breaking_changes\n \n def _calculate_priority_score(self, update_type: UpdateType, risk_level: UpgradeRisk,\n security_updates: List[str], is_direct: bool) -> float:\n \"\"\"Calculate priority score for upgrade (0-100).\"\"\"\n score = 50.0 # Base score\n \n # Security updates get highest priority\n if security_updates:\n score += 30.0\n score += len(security_updates) * 5.0 # Multiple security fixes\n \n # Update type scoring\n type_scores = {\n UpdateType.PATCH: 20.0,\n UpdateType.MINOR: 10.0,\n UpdateType.MAJOR: -10.0,\n UpdateType.PRERELEASE: -5.0\n }\n score += type_scores.get(update_type, 0)\n \n # Risk level adjustment\n risk_adjustments = {\n UpgradeRisk.SAFE: 15.0,\n UpgradeRisk.LOW: 5.0,\n UpgradeRisk.MEDIUM: -5.0,\n UpgradeRisk.HIGH: -15.0,\n UpgradeRisk.CRITICAL: -25.0\n }\n score += risk_adjustments.get(risk_level, 0)\n \n # Direct dependencies get slightly higher priority\n if is_direct:\n score += 5.0\n \n return max(0.0, min(100.0, score))\n \n def _estimate_migration_effort(self, update_type: UpdateType, breaking_changes: List[str]) -> str:\n \"\"\"Estimate migration effort level.\"\"\"\n if update_type == UpdateType.PATCH and not breaking_changes:\n return \"Minimal\"\n elif update_type == UpdateType.MINOR and len(breaking_changes) \u003c= 1:\n return \"Low\"\n elif update_type == UpdateType.MAJOR or len(breaking_changes) > 2:\n return \"High\"\n else:\n return \"Medium\"\n \n def _get_affected_dependencies(self, package_name: str, dependency: Dict[str, Any]) -> List[str]:\n \"\"\"Get list of dependencies that might be affected by this upgrade.\"\"\"\n # Simulated dependency impact analysis\n common_dependencies = {\n 'react': ['react-dom', 'react-router', 'react-redux'],\n 'django': ['djangorestframework', 'django-cors-headers', 'celery'],\n 'webpack': ['webpack-cli', 'webpack-dev-server', 'html-webpack-plugin'],\n 'babel': ['@babel/core', '@babel/preset-env', '@babel/preset-react']\n }\n \n return common_dependencies.get(package_name.lower(), [])\n \n def _assess_rollback_complexity(self, update_type: UpdateType, risk_level: UpgradeRisk) -> str:\n \"\"\"Assess complexity of rolling back the upgrade.\"\"\"\n if update_type == UpdateType.PATCH:\n return \"Simple\"\n elif update_type == UpdateType.MINOR and risk_level in [UpgradeRisk.SAFE, UpgradeRisk.LOW]:\n return \"Simple\"\n elif risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL]:\n return \"Complex\"\n else:\n return \"Moderate\"\n \n def _estimate_upgrade_time(self, update_type: UpdateType, breaking_changes: List[str]) -> str:\n \"\"\"Estimate time required for upgrade.\"\"\"\n base_times = {\n UpdateType.PATCH: \"30 minutes\",\n UpdateType.MINOR: \"2 hours\",\n UpdateType.MAJOR: \"1 day\",\n UpdateType.PRERELEASE: \"4 hours\"\n }\n \n base_time = base_times.get(update_type, \"4 hours\")\n \n if len(breaking_changes) > 2:\n if \"30 minutes\" in base_time:\n base_time = \"2 hours\"\n elif \"2 hours\" in base_time:\n base_time = \"1 day\"\n elif \"1 day\" in base_time:\n base_time = \"3 days\"\n \n return base_time\n \n def _generate_upgrade_statistics(self, upgrades: List[DependencyUpgrade]) -> Dict[str, Any]:\n \"\"\"Generate statistics about available upgrades.\"\"\"\n if not upgrades:\n return {}\n \n return {\n 'total_upgrades': len(upgrades),\n 'by_type': {\n 'patch': len([u for u in upgrades if u.update_type == UpdateType.PATCH]),\n 'minor': len([u for u in upgrades if u.update_type == UpdateType.MINOR]),\n 'major': len([u for u in upgrades if u.update_type == UpdateType.MAJOR]),\n 'prerelease': len([u for u in upgrades if u.update_type == UpdateType.PRERELEASE])\n },\n 'by_risk': {\n 'safe': len([u for u in upgrades if u.risk_level == UpgradeRisk.SAFE]),\n 'low': len([u for u in upgrades if u.risk_level == UpgradeRisk.LOW]),\n 'medium': len([u for u in upgrades if u.risk_level == UpgradeRisk.MEDIUM]),\n 'high': len([u for u in upgrades if u.risk_level == UpgradeRisk.HIGH]),\n 'critical': len([u for u in upgrades if u.risk_level == UpgradeRisk.CRITICAL])\n },\n 'security_updates': len([u for u in upgrades if u.security_updates]),\n 'direct_dependencies': len([u for u in upgrades if u.direct]),\n 'average_priority': sum(u.priority_score for u in upgrades) / len(upgrades)\n }\n \n def _perform_risk_assessment(self, upgrades: List[DependencyUpgrade]) -> Dict[str, Any]:\n \"\"\"Perform comprehensive risk assessment.\"\"\"\n high_risk_upgrades = [u for u in upgrades if u.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL]]\n security_upgrades = [u for u in upgrades if u.security_updates]\n major_upgrades = [u for u in upgrades if u.update_type == UpdateType.MAJOR]\n \n return {\n 'overall_risk': self._calculate_overall_upgrade_risk(upgrades),\n 'high_risk_count': len(high_risk_upgrades),\n 'security_critical_count': len(security_upgrades),\n 'major_version_count': len(major_upgrades),\n 'risk_factors': self._identify_risk_factors(upgrades),\n 'mitigation_strategies': self._suggest_mitigation_strategies(upgrades)\n }\n \n def _calculate_overall_upgrade_risk(self, upgrades: List[DependencyUpgrade]) -> str:\n \"\"\"Calculate overall risk level for all upgrades.\"\"\"\n if not upgrades:\n return \"LOW\"\n \n risk_scores = {\n UpgradeRisk.SAFE: 1,\n UpgradeRisk.LOW: 2,\n UpgradeRisk.MEDIUM: 3,\n UpgradeRisk.HIGH: 4,\n UpgradeRisk.CRITICAL: 5\n }\n \n total_score = sum(risk_scores.get(u.risk_level, 3) for u in upgrades)\n average_score = total_score / len(upgrades)\n \n if average_score >= 4.0:\n return \"CRITICAL\"\n elif average_score >= 3.0:\n return \"HIGH\"\n elif average_score >= 2.0:\n return \"MEDIUM\"\n else:\n return \"LOW\"\n \n def _identify_risk_factors(self, upgrades: List[DependencyUpgrade]) -> List[str]:\n \"\"\"Identify key risk factors across all upgrades.\"\"\"\n factors = []\n \n major_count = len([u for u in upgrades if u.update_type == UpdateType.MAJOR])\n if major_count > 0:\n factors.append(f\"{major_count} major version upgrades with potential breaking changes\")\n \n critical_count = len([u for u in upgrades if u.risk_level == UpgradeRisk.CRITICAL])\n if critical_count > 0:\n factors.append(f\"{critical_count} critical risk upgrades requiring careful planning\")\n \n framework_upgrades = [u for u in upgrades if any(fw in u.name.lower() \n for fw in ['react', 'django', 'spring', 'webpack', 'babel'])]\n if framework_upgrades:\n factors.append(f\"Core framework upgrades: {[u.name for u in framework_upgrades[:3]]}\")\n \n return factors\n \n def _suggest_mitigation_strategies(self, upgrades: List[DependencyUpgrade]) -> List[str]:\n \"\"\"Suggest risk mitigation strategies.\"\"\"\n strategies = []\n \n high_risk_count = len([u for u in upgrades if u.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL]])\n if high_risk_count > 0:\n strategies.append(\"Create comprehensive test suite before high-risk upgrades\")\n strategies.append(\"Plan rollback procedures for critical upgrades\")\n \n major_count = len([u for u in upgrades if u.update_type == UpdateType.MAJOR])\n if major_count > 3:\n strategies.append(\"Phase major upgrades across multiple releases\")\n strategies.append(\"Use feature flags for gradual rollout\")\n \n security_count = len([u for u in upgrades if u.security_updates])\n if security_count > 0:\n strategies.append(\"Prioritize security updates regardless of risk level\")\n \n return strategies\n \n def _create_upgrade_plans(self, upgrades: List[DependencyUpgrade], timeline_days: int) -> List[UpgradePlan]:\n \"\"\"Create phased upgrade plans.\"\"\"\n if not upgrades:\n return []\n \n # Sort upgrades by priority score (descending)\n sorted_upgrades = sorted(upgrades, key=lambda x: x.priority_score, reverse=True)\n \n plans = []\n \n # Phase 1: Security and safe updates (first 30% of timeline)\n phase1_upgrades = [u for u in sorted_upgrades if \n u.security_updates or u.risk_level == UpgradeRisk.SAFE][:10]\n if phase1_upgrades:\n plans.append(self._create_upgrade_plan(\n \"Phase 1: Security & Safe Updates\",\n \"Immediate security fixes and low-risk updates\",\n 1, phase1_upgrades, timeline_days // 3\n ))\n \n # Phase 2: Low-medium risk updates (middle 40% of timeline)\n phase2_upgrades = [u for u in sorted_upgrades if \n u.risk_level in [UpgradeRisk.LOW, UpgradeRisk.MEDIUM] and\n not u.security_updates][:8]\n if phase2_upgrades:\n plans.append(self._create_upgrade_plan(\n \"Phase 2: Regular Updates\",\n \"Standard dependency updates with moderate risk\",\n 2, phase2_upgrades, timeline_days * 2 // 5\n ))\n \n # Phase 3: High-risk and major updates (final 30% of timeline)\n phase3_upgrades = [u for u in sorted_upgrades if \n u.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL]][:5]\n if phase3_upgrades:\n plans.append(self._create_upgrade_plan(\n \"Phase 3: Major Updates\",\n \"High-risk upgrades requiring careful planning\",\n 3, phase3_upgrades, timeline_days // 3\n ))\n \n return plans\n \n def _create_upgrade_plan(self, name: str, description: str, phase: int,\n upgrades: List[DependencyUpgrade], duration_days: int) -> UpgradePlan:\n \"\"\"Create a detailed upgrade plan for a phase.\"\"\"\n dependency_names = [u.name for u in upgrades]\n \n # Generate migration steps\n migration_steps = []\n migration_steps.append(\"1. Create feature branch for upgrades\")\n migration_steps.append(\"2. Update dependency versions in manifest files\")\n migration_steps.append(\"3. Run dependency install/update commands\")\n migration_steps.append(\"4. Fix breaking changes and deprecation warnings\")\n migration_steps.append(\"5. Update test suite for compatibility\")\n migration_steps.append(\"6. Run comprehensive test suite\")\n migration_steps.append(\"7. Update documentation and changelog\")\n migration_steps.append(\"8. Create pull request for review\")\n \n # Add phase-specific steps\n if phase == 1:\n migration_steps.insert(3, \"3a. Verify security fixes are applied\")\n elif phase == 3:\n migration_steps.insert(5, \"5a. Perform extensive integration testing\")\n migration_steps.insert(6, \"6a. Test with production-like data\")\n \n # Generate testing requirements\n testing_requirements = [\n \"Unit test suite passes 100%\",\n \"Integration tests cover upgrade scenarios\",\n \"Performance benchmarks within acceptable range\"\n ]\n \n if any(u.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL] for u in upgrades):\n testing_requirements.extend([\n \"Manual testing of critical user flows\",\n \"Load testing for performance regression\",\n \"Security scanning for new vulnerabilities\"\n ])\n \n # Generate rollback plan\n rollback_plan = [\n \"1. Revert dependency versions in manifest files\",\n \"2. Run dependency install with previous versions\",\n \"3. Restore previous configuration files if changed\",\n \"4. Run smoke tests to verify rollback success\",\n \"5. Monitor system health metrics\"\n ]\n \n # Success criteria\n success_criteria = [\n \"All tests pass in CI/CD pipeline\",\n \"No security vulnerabilities introduced\",\n \"Performance metrics within acceptable thresholds\",\n \"No critical user workflows broken\"\n ]\n \n return UpgradePlan(\n name=name,\n description=description,\n phase=phase,\n dependencies=dependency_names,\n estimated_duration=f\"{duration_days} days\",\n prerequisites=self._generate_prerequisites(upgrades),\n migration_steps=migration_steps,\n testing_requirements=testing_requirements,\n rollback_plan=rollback_plan,\n success_criteria=success_criteria\n )\n \n def _generate_prerequisites(self, upgrades: List[DependencyUpgrade]) -> List[str]:\n \"\"\"Generate prerequisites for upgrade phase.\"\"\"\n prerequisites = [\n \"Comprehensive test suite with good coverage\",\n \"Backup of current working state\",\n \"Development environment setup\"\n ]\n \n if any(u.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL] for u in upgrades):\n prerequisites.extend([\n \"Staging environment for testing\",\n \"Rollback procedure documented and tested\",\n \"Team availability for issue resolution\"\n ])\n \n if any(u.security_updates for u in upgrades):\n prerequisites.append(\"Security team notification for validation\")\n \n return prerequisites\n \n def _generate_upgrade_recommendations(self, analysis_results: Dict[str, Any]) -> List[str]:\n \"\"\"Generate actionable upgrade recommendations.\"\"\"\n recommendations = []\n \n security_count = analysis_results['upgrade_statistics'].get('security_updates', 0)\n if security_count > 0:\n recommendations.append(f\"URGENT: {security_count} security updates available - prioritize immediately\")\n \n safe_count = analysis_results['upgrade_statistics']['by_risk'].get('safe', 0)\n if safe_count > 0:\n recommendations.append(f\"Quick wins: {safe_count} safe updates can be applied with minimal risk\")\n \n critical_count = analysis_results['risk_assessment']['high_risk_count']\n if critical_count > 0:\n recommendations.append(f\"Plan carefully: {critical_count} high-risk upgrades need thorough testing\")\n \n major_count = analysis_results['upgrade_statistics']['by_type'].get('major', 0)\n if major_count > 3:\n recommendations.append(\"Consider phasing major upgrades across multiple releases\")\n \n overall_risk = analysis_results['risk_assessment']['overall_risk']\n if overall_risk in ['HIGH', 'CRITICAL']:\n recommendations.append(\"Overall upgrade risk is high - recommend gradual approach\")\n \n return recommendations\n \n def generate_report(self, analysis_results: Dict[str, Any], format: str = 'text') -> str:\n \"\"\"Generate upgrade plan report in specified format.\"\"\"\n if format == 'json':\n # Convert dataclass objects for JSON serialization\n serializable_results = analysis_results.copy()\n serializable_results['available_upgrades'] = [asdict(upgrade) for upgrade in analysis_results['available_upgrades']]\n serializable_results['upgrade_plans'] = [asdict(plan) for plan in analysis_results['upgrade_plans']]\n return json.dumps(serializable_results, indent=2, default=str)\n \n # Text format report\n report = []\n report.append(\"=\" * 60)\n report.append(\"DEPENDENCY UPGRADE PLAN\")\n report.append(\"=\" * 60)\n report.append(f\"Generated: {analysis_results['timestamp']}\")\n report.append(f\"Timeline: {analysis_results['timeline_days']} days\")\n report.append(\"\")\n \n # Statistics\n stats = analysis_results['upgrade_statistics']\n report.append(\"UPGRADE SUMMARY:\")\n report.append(f\" Total Upgrades Available: {stats.get('total_upgrades', 0)}\")\n report.append(f\" Security Updates: {stats.get('security_updates', 0)}\")\n report.append(f\" Major Version Updates: {stats['by_type'].get('major', 0)}\")\n report.append(f\" High Risk Updates: {stats['by_risk'].get('high', 0)}\")\n report.append(\"\")\n \n # Risk Assessment\n risk = analysis_results['risk_assessment']\n report.append(\"RISK ASSESSMENT:\")\n report.append(f\" Overall Risk Level: {risk['overall_risk']}\")\n if risk.get('risk_factors'):\n report.append(\" Key Risk Factors:\")\n for factor in risk['risk_factors'][:3]:\n report.append(f\" • {factor}\")\n report.append(\"\")\n \n # High Priority Upgrades\n high_priority = sorted([u for u in analysis_results['available_upgrades']], \n key=lambda x: x.priority_score, reverse=True)[:10]\n \n if high_priority:\n report.append(\"TOP PRIORITY UPGRADES:\")\n report.append(\"-\" * 30)\n for upgrade in high_priority:\n risk_indicator = \"🔴\" if upgrade.risk_level in [UpgradeRisk.HIGH, UpgradeRisk.CRITICAL] else \\\n \"🟡\" if upgrade.risk_level == UpgradeRisk.MEDIUM else \"🟢\"\n security_indicator = \" 🔒\" if upgrade.security_updates else \"\"\n \n report.append(f\"{risk_indicator} {upgrade.name}: {upgrade.current_version} → {upgrade.latest_version}{security_indicator}\")\n report.append(f\" Type: {upgrade.update_type.value.title()} | Risk: {upgrade.risk_level.value.title()} | Priority: {upgrade.priority_score:.1f}\")\n if upgrade.security_updates:\n report.append(f\" Security: {upgrade.security_updates[0]}\")\n report.append(\"\")\n \n # Upgrade Plans\n if analysis_results['upgrade_plans']:\n report.append(\"PHASED UPGRADE PLANS:\")\n report.append(\"-\" * 30)\n \n for plan in analysis_results['upgrade_plans']:\n report.append(f\"{plan.name} ({plan.estimated_duration})\")\n report.append(f\" Dependencies: {', '.join(plan.dependencies[:5])}\")\n if len(plan.dependencies) > 5:\n report.append(f\" ... and {len(plan.dependencies) - 5} more\")\n report.append(f\" Key Steps: {'; '.join(plan.migration_steps[:3])}\")\n report.append(\"\")\n \n # Recommendations\n if analysis_results['recommendations']:\n report.append(\"RECOMMENDATIONS:\")\n report.append(\"-\" * 20)\n for i, rec in enumerate(analysis_results['recommendations'], 1):\n report.append(f\"{i}. {rec}\")\n report.append(\"\")\n \n report.append(\"=\" * 60)\n return '\\n'.join(report)\n\ndef main():\n \"\"\"Main entry point for the upgrade planner.\"\"\"\n parser = argparse.ArgumentParser(\n description='Analyze dependency upgrades and create migration plans',\n formatter_class=argparse.RawDescriptionHelpFormatter,\n epilog=\"\"\"\nExamples:\n python upgrade_planner.py deps.json\n python upgrade_planner.py inventory.json --timeline 60 --format json\n python upgrade_planner.py deps.json --risk-threshold medium --output plan.txt\n \"\"\"\n )\n \n parser.add_argument('inventory_file',\n help='Path to dependency inventory JSON file')\n parser.add_argument('--timeline', type=int, default=90,\n help='Timeline for upgrade plan in days (default: 90)')\n parser.add_argument('--format', choices=['text', 'json'], default='text',\n help='Output format (default: text)')\n parser.add_argument('--output', '-o',\n help='Output file path (default: stdout)')\n parser.add_argument('--risk-threshold', \n choices=['safe', 'low', 'medium', 'high', 'critical'],\n default='high',\n help='Maximum risk level to include (default: high)')\n parser.add_argument('--security-only', action='store_true',\n help='Only plan upgrades with security fixes')\n \n args = parser.parse_args()\n \n try:\n planner = UpgradePlanner()\n results = planner.analyze_upgrades(args.inventory_file, args.timeline)\n \n # Filter by risk threshold if specified\n if args.risk_threshold != 'critical':\n risk_levels = ['safe', 'low', 'medium', 'high', 'critical']\n max_index = risk_levels.index(args.risk_threshold)\n allowed_risks = set(risk_levels[:max_index + 1])\n \n results['available_upgrades'] = [\n u for u in results['available_upgrades']\n if u.risk_level.value in allowed_risks\n ]\n \n # Filter for security-only if specified\n if args.security_only:\n results['available_upgrades'] = [\n u for u in results['available_upgrades']\n if u.security_updates\n ]\n \n report = planner.generate_report(results, args.format)\n \n if args.output:\n with open(args.output, 'w') as f:\n f.write(report)\n print(f\"Upgrade plan saved to {args.output}\")\n else:\n print(report)\n \n except Exception as e:\n print(f\"Error: {e}\", file=sys.stderr)\n sys.exit(1)\n\nif __name__ == '__main__':\n main()","content_type":"text/x-python; charset=utf-8","language":"python","size":42650,"content_sha256":"fcaf65475a3376c53c345ad27137a06a99c67184a7b328129021d69f48cc870b"},{"filename":"test-inventory.json","content":"{\n \"timestamp\": \"2026-02-16T15:42:09.730696\",\n \"project_path\": \"test-project\",\n \"dependencies\": [\n {\n \"name\": \"express\",\n \"version\": \"4.18.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": [\n {\n \"id\": \"CVE-2022-24999\",\n \"summary\": \"Open redirect in express\",\n \"severity\": \"MEDIUM\",\n \"cvss_score\": 6.1,\n \"affected_versions\": \"\u003c4.18.2\",\n \"fixed_version\": \"4.18.2\",\n \"published_date\": \"2022-11-26\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2022-24999\"\n ]\n },\n {\n \"id\": \"CVE-2022-24999\",\n \"summary\": \"Open redirect in express\",\n \"severity\": \"MEDIUM\",\n \"cvss_score\": 6.1,\n \"affected_versions\": \"\u003c4.18.2\",\n \"fixed_version\": \"4.18.2\",\n \"published_date\": \"2022-11-26\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2022-24999\"\n ]\n }\n ]\n },\n {\n \"name\": \"lodash\",\n \"version\": \"4.17.20\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": [\n {\n \"id\": \"CVE-2021-23337\",\n \"summary\": \"Prototype pollution in lodash\",\n \"severity\": \"HIGH\",\n \"cvss_score\": 7.2,\n \"affected_versions\": \"\u003c4.17.21\",\n \"fixed_version\": \"4.17.21\",\n \"published_date\": \"2021-02-15\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2021-23337\"\n ]\n },\n {\n \"id\": \"CVE-2021-23337\",\n \"summary\": \"Prototype pollution in lodash\",\n \"severity\": \"HIGH\",\n \"cvss_score\": 7.2,\n \"affected_versions\": \"\u003c4.17.21\",\n \"fixed_version\": \"4.17.21\",\n \"published_date\": \"2021-02-15\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2021-23337\"\n ]\n }\n ]\n },\n {\n \"name\": \"axios\",\n \"version\": \"1.5.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": [\n {\n \"id\": \"CVE-2023-45857\",\n \"summary\": \"Cross-site request forgery in axios\",\n \"severity\": \"MEDIUM\",\n \"cvss_score\": 6.1,\n \"affected_versions\": \">=1.0.0 \u003c1.6.0\",\n \"fixed_version\": \"1.6.0\",\n \"published_date\": \"2023-10-11\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2023-45857\"\n ]\n },\n {\n \"id\": \"CVE-2023-45857\",\n \"summary\": \"Cross-site request forgery in axios\",\n \"severity\": \"MEDIUM\",\n \"cvss_score\": 6.1,\n \"affected_versions\": \">=1.0.0 \u003c1.6.0\",\n \"fixed_version\": \"1.6.0\",\n \"published_date\": \"2023-10-11\",\n \"references\": [\n \"https://nvd.nist.gov/vuln/detail/CVE-2023-45857\"\n ]\n }\n ]\n },\n {\n \"name\": \"jsonwebtoken\",\n \"version\": \"8.5.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"bcrypt\",\n \"version\": \"5.1.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"mongoose\",\n \"version\": \"6.10.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"cors\",\n \"version\": \"2.8.5\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"helmet\",\n \"version\": \"6.1.5\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"winston\",\n \"version\": \"3.8.2\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"dotenv\",\n \"version\": \"16.0.3\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"express-rate-limit\",\n \"version\": \"6.7.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"multer\",\n \"version\": \"1.4.5-lts.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"sharp\",\n \"version\": \"0.32.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"nodemailer\",\n \"version\": \"6.9.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"socket.io\",\n \"version\": \"4.6.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"redis\",\n \"version\": \"4.6.5\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"moment\",\n \"version\": \"2.29.4\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"chalk\",\n \"version\": \"4.1.2\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"commander\",\n \"version\": \"9.4.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"nodemon\",\n \"version\": \"2.0.22\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"jest\",\n \"version\": \"29.5.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"supertest\",\n \"version\": \"6.3.3\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"eslint\",\n \"version\": \"8.40.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"eslint-config-airbnb-base\",\n \"version\": \"15.0.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"eslint-plugin-import\",\n \"version\": \"2.27.5\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"webpack\",\n \"version\": \"5.82.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"webpack-cli\",\n \"version\": \"5.1.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"babel-loader\",\n \"version\": \"9.1.2\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"@babel/core\",\n \"version\": \"7.22.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"@babel/preset-env\",\n \"version\": \"7.22.2\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"css-loader\",\n \"version\": \"6.7.4\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"style-loader\",\n \"version\": \"3.3.3\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"html-webpack-plugin\",\n \"version\": \"5.5.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"mini-css-extract-plugin\",\n \"version\": \"2.7.6\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"postcss\",\n \"version\": \"8.4.23\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"postcss-loader\",\n \"version\": \"7.3.0\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"autoprefixer\",\n \"version\": \"10.4.14\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"cross-env\",\n \"version\": \"7.0.3\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n },\n {\n \"name\": \"rimraf\",\n \"version\": \"5.0.1\",\n \"ecosystem\": \"npm\",\n \"direct\": true,\n \"license\": null,\n \"vulnerabilities\": []\n }\n ],\n \"vulnerabilities_found\": 6,\n \"high_severity_count\": 2,\n \"medium_severity_count\": 4,\n \"low_severity_count\": 0,\n \"ecosystems\": [\n \"npm\"\n ],\n \"scan_summary\": {\n \"total_dependencies\": 39,\n \"unique_dependencies\": 39,\n \"ecosystems_found\": 1,\n \"vulnerable_dependencies\": 3,\n \"vulnerability_breakdown\": {\n \"high\": 2,\n \"medium\": 4,\n \"low\": 0\n }\n },\n \"recommendations\": [\n \"URGENT: Address 2 high-severity vulnerabilities immediately\",\n \"Schedule fixes for 4 medium-severity vulnerabilities within 30 days\",\n \"Update express from 4.18.1 to 4.18.2 to fix CVE-2022-24999\",\n \"Update express from 4.18.1 to 4.18.2 to fix CVE-2022-24999\",\n \"Update lodash from 4.17.20 to 4.17.21 to fix CVE-2021-23337\",\n \"Update lodash from 4.17.20 to 4.17.21 to fix CVE-2021-23337\",\n \"Update axios from 1.5.0 to 1.6.0 to fix CVE-2023-45857\",\n \"Update axios from 1.5.0 to 1.6.0 to fix CVE-2023-45857\"\n ]\n}","content_type":"application/json; charset=utf-8","language":"json","size":9916,"content_sha256":"9eb7db72e3c66d324efe411b11f702ebedd42ac8fa89ffe7ead338b902450fd3"},{"filename":"test-project/package.json","content":"{\n \"name\": \"sample-web-app\",\n \"version\": \"1.2.3\",\n \"description\": \"A sample web application with various dependencies for testing dependency auditing\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"start\": \"node index.js\",\n \"dev\": \"nodemon index.js\",\n \"build\": \"webpack --mode production\",\n \"test\": \"jest\",\n \"lint\": \"eslint src/\",\n \"audit\": \"npm audit\"\n },\n \"keywords\": [\"web\", \"app\", \"sample\", \"dependency\", \"audit\"],\n \"author\": \"Claude Skills Team\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"express\": \"4.18.1\",\n \"lodash\": \"4.17.20\",\n \"axios\": \"1.5.0\",\n \"jsonwebtoken\": \"8.5.1\",\n \"bcrypt\": \"5.1.0\",\n \"mongoose\": \"6.10.0\",\n \"cors\": \"2.8.5\",\n \"helmet\": \"6.1.5\",\n \"winston\": \"3.8.2\",\n \"dotenv\": \"16.0.3\",\n \"express-rate-limit\": \"6.7.0\",\n \"multer\": \"1.4.5-lts.1\",\n \"sharp\": \"0.32.1\",\n \"nodemailer\": \"6.9.1\",\n \"socket.io\": \"4.6.1\",\n \"redis\": \"4.6.5\",\n \"moment\": \"2.29.4\",\n \"chalk\": \"4.1.2\",\n \"commander\": \"9.4.1\"\n },\n \"devDependencies\": {\n \"nodemon\": \"2.0.22\",\n \"jest\": \"29.5.0\",\n \"supertest\": \"6.3.3\",\n \"eslint\": \"8.40.0\",\n \"eslint-config-airbnb-base\": \"15.0.0\",\n \"eslint-plugin-import\": \"2.27.5\",\n \"webpack\": \"5.82.1\",\n \"webpack-cli\": \"5.1.1\",\n \"babel-loader\": \"9.1.2\",\n \"@babel/core\": \"7.22.1\",\n \"@babel/preset-env\": \"7.22.2\",\n \"css-loader\": \"6.7.4\",\n \"style-loader\": \"3.3.3\",\n \"html-webpack-plugin\": \"5.5.1\",\n \"mini-css-extract-plugin\": \"2.7.6\",\n \"postcss\": \"8.4.23\",\n \"postcss-loader\": \"7.3.0\",\n \"autoprefixer\": \"10.4.14\",\n \"cross-env\": \"7.0.3\",\n \"rimraf\": \"5.0.1\"\n },\n \"engines\": {\n \"node\": \">=16.0.0\",\n \"npm\": \">=8.0.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/example/sample-web-app.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/example/sample-web-app/issues\"\n },\n \"homepage\": \"https://github.com/example/sample-web-app#readme\"\n}","content_type":"application/json; charset=utf-8","language":"json","size":1919,"content_sha256":"0ba6fc01364589a5e6030a05e1283038bf3a944135b46a9a5eaaaf1dbdf6a032"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Dependency Auditor","type":"text"}]},{"type":"blockquote","content":[{"type":"paragraph","content":[{"text":"Skill Type:","type":"text","marks":[{"type":"strong"}]},{"text":" POWERFUL","type":"text"},{"type":"br"},{"text":"Category:","type":"text","marks":[{"type":"strong"}]},{"text":" Engineering","type":"text"},{"type":"br"},{"text":"Domain:","type":"text","marks":[{"type":"strong"}]},{"text":" Dependency Management & Security","type":"text"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"The ","type":"text"},{"text":"Dependency Auditor","type":"text","marks":[{"type":"strong"}]},{"text":" is a comprehensive toolkit for analyzing, auditing, and managing dependencies across multi-language software projects. This skill provides deep visibility into your project's dependency ecosystem, enabling teams to identify vulnerabilities, ensure license compliance, optimize dependency trees, and plan safe upgrades.","type":"text"}]},{"type":"paragraph","content":[{"text":"In modern software development, dependencies form complex webs that can introduce significant security, legal, and maintenance risks. A single project might have hundreds of direct and transitive dependencies, each potentially introducing vulnerabilities, license conflicts, or maintenance burden. This skill addresses these challenges through automated analysis and actionable recommendations.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Core Capabilities","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"1. Vulnerability Scanning & CVE Matching","type":"text"}]},{"type":"paragraph","content":[{"text":"Comprehensive Security Analysis","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Scans dependencies against built-in vulnerability databases","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Matches Common Vulnerabilities and Exposures (CVE) patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies known security issues across multiple ecosystems","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes transitive dependency vulnerabilities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provides CVSS scores and exploit assessments","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks vulnerability disclosure timelines","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Maps vulnerabilities to dependency paths","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Multi-Language Support","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JavaScript/Node.js","type":"text","marks":[{"type":"strong"}]},{"text":": package.json, package-lock.json, yarn.lock","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Python","type":"text","marks":[{"type":"strong"}]},{"text":": requirements.txt, pyproject.toml, Pipfile.lock, poetry.lock","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Go","type":"text","marks":[{"type":"strong"}]},{"text":": go.mod, go.sum","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rust","type":"text","marks":[{"type":"strong"}]},{"text":": Cargo.toml, Cargo.lock","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ruby","type":"text","marks":[{"type":"strong"}]},{"text":": Gemfile, Gemfile.lock","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Java/Maven","type":"text","marks":[{"type":"strong"}]},{"text":": pom.xml, gradle.lockfile","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"PHP","type":"text","marks":[{"type":"strong"}]},{"text":": composer.json, composer.lock","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"C#/.NET","type":"text","marks":[{"type":"strong"}]},{"text":": packages.config, project.assets.json","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"2. License Compliance & Legal Risk Assessment","type":"text"}]},{"type":"paragraph","content":[{"text":"License Classification System","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Permissive Licenses","type":"text","marks":[{"type":"strong"}]},{"text":": MIT, Apache 2.0, BSD (2-clause, 3-clause), ISC","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copyleft (Strong)","type":"text","marks":[{"type":"strong"}]},{"text":": GPL (v2, v3), AGPL (v3)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Copyleft (Weak)","type":"text","marks":[{"type":"strong"}]},{"text":": LGPL (v2.1, v3), MPL (v2.0)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Proprietary","type":"text","marks":[{"type":"strong"}]},{"text":": Commercial, custom, or restrictive licenses","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dual Licensed","type":"text","marks":[{"type":"strong"}]},{"text":": Multi-license scenarios and compatibility","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unknown/Ambiguous","type":"text","marks":[{"type":"strong"}]},{"text":": Missing or unclear licensing","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Conflict Detection","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies incompatible license combinations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Warns about GPL contamination in permissive projects","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes license inheritance through dependency chains","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provides compliance recommendations for distribution","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Generates legal risk matrices for decision-making","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"3. Outdated Dependency Detection","type":"text"}]},{"type":"paragraph","content":[{"text":"Version Analysis","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies dependencies with available updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Categorizes updates by severity (patch, minor, major)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects pinned versions that may be outdated","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes semantic versioning patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies floating version specifiers","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks release frequencies and maintenance status","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Maintenance Status Assessment","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies abandoned or unmaintained packages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes commit frequency and contributor activity","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks last release dates and security patch availability","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies packages with known end-of-life dates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Assesses upstream maintenance quality","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"4. Dependency Bloat Analysis","type":"text"}]},{"type":"paragraph","content":[{"text":"Unused Dependency Detection","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies dependencies that aren't actually imported/used","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes import statements and usage patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects redundant dependencies with overlapping functionality","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies oversized packages for simple use cases","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Maps actual vs. declared dependency usage","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Redundancy Analysis","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies multiple packages providing similar functionality","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects version conflicts in transitive dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes bundle size impact of dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies opportunities for dependency consolidation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Maps dependency overlap and duplication","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"5. Upgrade Path Planning & Breaking Change Risk","type":"text"}]},{"type":"paragraph","content":[{"text":"Semantic Versioning Analysis","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes semver patterns to predict breaking changes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies safe upgrade paths (patch/minor versions)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Flags major version updates requiring attention","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks breaking changes across dependency updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provides rollback strategies for failed upgrades","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Risk Assessment Matrix","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Low Risk: Patch updates, security fixes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Medium Risk: Minor updates with new features","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"High Risk: Major version updates, API changes","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Critical Risk: Dependencies with known breaking changes","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Upgrade Prioritization","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security patches: Highest priority","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bug fixes: High priority","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Feature updates: Medium priority","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Major rewrites: Planned priority","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Deprecated features: Immediate attention","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"6. Supply Chain Security","type":"text"}]},{"type":"paragraph","content":[{"text":"Dependency Provenance","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Verifies package signatures and checksums","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes package download sources and mirrors","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies suspicious or compromised packages","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks package ownership changes and maintainer shifts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Detects typosquatting and malicious packages","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Transitive Risk Analysis","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Maps complete dependency trees","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies high-risk transitive dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes dependency depth and complexity","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks influence of indirect dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Provides supply chain risk scoring","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"7. Lockfile Analysis & Deterministic Builds","type":"text"}]},{"type":"paragraph","content":[{"text":"Lockfile Validation","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ensures lockfiles are up-to-date with manifests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validates integrity hashes and version consistency","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies drift between environments","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Analyzes lockfile conflicts and resolution strategies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ensures deterministic, reproducible builds","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Environment Consistency","type":"text","marks":[{"type":"strong"}]}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compares dependencies across environments (dev/staging/prod)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Identifies version mismatches between team members","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Validates CI/CD environment consistency","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Tracks dependency resolution differences","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Technical Architecture","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scanner Engine (","type":"text"},{"text":"dep_scanner.py","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Multi-format parser supporting 8+ package ecosystems","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Built-in vulnerability database with 500+ CVE patterns","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Transitive dependency resolution from lockfiles","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"JSON and human-readable output formats","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configurable scanning depth and exclusion patterns","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"License Analyzer (","type":"text"},{"text":"license_checker.py","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License detection from package metadata and files","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compatibility matrix with 20+ license types","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Conflict detection engine with remediation suggestions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Risk scoring based on distribution and usage context","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Export capabilities for legal review","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Upgrade Planner (","type":"text"},{"text":"upgrade_planner.py","type":"text","marks":[{"type":"code_inline"}]},{"text":")","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Semantic version analysis with breaking change prediction","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependency ordering based on risk and interdependence","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Migration checklists with testing recommendations","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Rollback procedures for failed upgrades","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Timeline estimation for upgrade cycles","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Use Cases & Applications","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Security Teams","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Vulnerability Management","type":"text","marks":[{"type":"strong"}]},{"text":": Continuous scanning for security issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Incident Response","type":"text","marks":[{"type":"strong"}]},{"text":": Rapid assessment of vulnerable dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Supply Chain Monitoring","type":"text","marks":[{"type":"strong"}]},{"text":": Tracking third-party security posture","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Compliance Reporting","type":"text","marks":[{"type":"strong"}]},{"text":": Automated security compliance documentation","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Legal & Compliance Teams","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License Auditing","type":"text","marks":[{"type":"strong"}]},{"text":": Comprehensive license compliance verification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Risk Assessment","type":"text","marks":[{"type":"strong"}]},{"text":": Legal risk analysis for software distribution","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Due Diligence","type":"text","marks":[{"type":"strong"}]},{"text":": Dependency licensing for M&A activities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Policy Enforcement","type":"text","marks":[{"type":"strong"}]},{"text":": Automated license policy compliance","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Development Teams","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Dependency Hygiene","type":"text","marks":[{"type":"strong"}]},{"text":": Regular cleanup of unused dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Upgrade Planning","type":"text","marks":[{"type":"strong"}]},{"text":": Strategic dependency update scheduling","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Performance Optimization","type":"text","marks":[{"type":"strong"}]},{"text":": Bundle size optimization through dep analysis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Technical Debt","type":"text","marks":[{"type":"strong"}]},{"text":": Identifying and prioritizing dependency technical debt","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"DevOps & Platform Teams","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Build Optimization","type":"text","marks":[{"type":"strong"}]},{"text":": Faster builds through dependency optimization","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security Automation","type":"text","marks":[{"type":"strong"}]},{"text":": Automated vulnerability scanning in CI/CD","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Environment Consistency","type":"text","marks":[{"type":"strong"}]},{"text":": Ensuring consistent dependencies across environments","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Release Management","type":"text","marks":[{"type":"strong"}]},{"text":": Dependency-aware release planning","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration Patterns","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"CI/CD Pipeline Integration","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Security gate in CI\npython dep_scanner.py /project --format json --fail-on-high\npython license_checker.py /project --policy strict --format json","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scheduled Audits","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Weekly dependency audit\n./audit_dependencies.sh > weekly_report.html\npython upgrade_planner.py deps.json --timeline 30days","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Development Workflow","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Pre-commit dependency check\npython dep_scanner.py . --quick-scan\npython license_checker.py . --warn-conflicts","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Advanced Features","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Custom Vulnerability Databases","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Support for internal/proprietary vulnerability feeds","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom CVE pattern definitions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Organization-specific risk scoring","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Integration with enterprise security tools","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Policy-Based Scanning","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Configurable license policies by project type","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Custom risk thresholds and escalation rules","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automated policy enforcement and notifications","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Exception management for approved violations","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Reporting & Dashboards","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Executive summaries for management","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Technical reports for development teams","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Trend analysis and dependency health metrics","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Integration with project management tools","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Multi-Project Analysis","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Portfolio-level dependency analysis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Shared dependency impact analysis","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Organization-wide license compliance","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cross-project vulnerability propagation","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Best Practices","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Scanning Frequency","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security Scans","type":"text","marks":[{"type":"strong"}]},{"text":": Daily or on every commit","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License Audits","type":"text","marks":[{"type":"strong"}]},{"text":": Weekly or monthly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Upgrade Planning","type":"text","marks":[{"type":"strong"}]},{"text":": Monthly or quarterly","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Full Dependency Audit","type":"text","marks":[{"type":"strong"}]},{"text":": Quarterly","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Risk Management","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Prioritize Security","type":"text","marks":[{"type":"strong"}]},{"text":": Address high/critical CVEs immediately","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License First","type":"text","marks":[{"type":"strong"}]},{"text":": Ensure compliance before functionality","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Gradual Updates","type":"text","marks":[{"type":"strong"}]},{"text":": Incremental dependency updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Test Thoroughly","type":"text","marks":[{"type":"strong"}]},{"text":": Comprehensive testing after updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Monitor Continuously","type":"text","marks":[{"type":"strong"}]},{"text":": Automated monitoring and alerting","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Team Workflows","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security Champions","type":"text","marks":[{"type":"strong"}]},{"text":": Designate dependency security owners","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Review Process","type":"text","marks":[{"type":"strong"}]},{"text":": Mandatory review for new dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Update Cycles","type":"text","marks":[{"type":"strong"}]},{"text":": Regular, scheduled dependency updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Documentation","type":"text","marks":[{"type":"strong"}]},{"text":": Maintain dependency rationale and decisions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Training","type":"text","marks":[{"type":"strong"}]},{"text":": Regular team education on dependency security","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Metrics & KPIs","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Security Metrics","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Mean Time to Patch (MTTP) for vulnerabilities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Number of high/critical vulnerabilities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Percentage of dependencies with known vulnerabilities","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Security debt accumulation rate","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Compliance Metrics","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License compliance percentage","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Number of license conflicts","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Time to resolve compliance issues","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Policy violation frequency","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Maintenance Metrics","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Percentage of up-to-date dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Average dependency age","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Number of abandoned dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Upgrade success rate","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Efficiency Metrics","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Bundle size reduction percentage","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Unused dependency elimination rate","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Build time improvement","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Developer productivity impact","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Troubleshooting Guide","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Common Issues","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"False Positives","type":"text","marks":[{"type":"strong"}]},{"text":": Tuning vulnerability detection sensitivity","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"License Ambiguity","type":"text","marks":[{"type":"strong"}]},{"text":": Resolving unclear or multiple licenses","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Breaking Changes","type":"text","marks":[{"type":"strong"}]},{"text":": Managing major version upgrades","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Performance Impact","type":"text","marks":[{"type":"strong"}]},{"text":": Optimizing scanning for large codebases","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Resolution Strategies","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Whitelist false positives with documentation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Contact maintainers for license clarification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Implement feature flags for risky upgrades","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Use incremental scanning for large projects","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Future Enhancements","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Planned Features","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Machine learning for vulnerability prediction","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Automated dependency update pull requests","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Integration with container image scanning","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Real-time dependency monitoring dashboards","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Natural language policy definition","type":"text"}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Ecosystem Expansion","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Additional language support (Swift, Kotlin, Dart)","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Container and infrastructure dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Development tool and build system dependencies","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Cloud service and SaaS dependency tracking","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"Quick Start","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Scan project for vulnerabilities and licenses\npython scripts/dep_scanner.py /path/to/project\n\n# Check license compliance\npython scripts/license_checker.py /path/to/project --policy strict\n\n# Plan dependency upgrades\npython scripts/upgrade_planner.py deps.json --risk-threshold medium","type":"text"}]},{"type":"paragraph","content":[{"text":"For detailed usage instructions, see ","type":"text"},{"text":"README.md","type":"text","marks":[{"type":"link","attrs":{"href":"README.md","title":null}}]},{"text":".","type":"text"}]},{"type":"hr","attrs":{"markup":"---"}},{"type":"heading","attrs":{"level":2},"content":[{"text":"This skill provides comprehensive dependency management capabilities essential for maintaining secure, compliant, and efficient software projects. Regular use helps teams stay ahead of security threats, maintain legal compliance, and optimize their dependency ecosystems.","type":"text","marks":[{"type":"em"}]}]}]},"metadata":{"date":"2026-06-05","name":"dependency-auditor","author":"@skillopedia","source":{"stars":16818,"repo_name":"claude-skills","origin_url":"https://github.com/alirezarezvani/claude-skills/blob/HEAD/engineering/skills/dependency-auditor/SKILL.md","repo_owner":"alirezarezvani","body_sha256":"1eff1472ff07905a212e5f661650c2ea4c0a4442de47f94cc878325fc308c10e","cluster_key":"9355b75587a2e0cb82ee09b89361c8fa9365c934c2eda787638615d20d610b8a","clean_bundle":{"format":"clean-skill-bundle-v1","source":"alirezarezvani/claude-skills/engineering/skills/dependency-auditor/SKILL.md","attachments":[{"id":"fefb1116-2b49-54ac-b99f-078d4f125cc3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/fefb1116-2b49-54ac-b99f-078d4f125cc3/attachment.md","path":"README.md","size":15211,"sha256":"023b2506b44dd23c791664e91f1836f9795450333565762cf86267adee8cddbb","contentType":"text/markdown; charset=utf-8"},{"id":"283da4b4-205a-5292-ab49-35efaa0cd789","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/283da4b4-205a-5292-ab49-35efaa0cd789/attachment.mod","path":"assets/sample_go.mod","size":2108,"sha256":"3da5b13abe39db65446c64bfef8aa7e5216b317f0853e17a3c575382044fc676","contentType":"application/xml-dtd"},{"id":"59e76ebb-e6f4-5bbb-ac05-e0b333ec84ac","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/59e76ebb-e6f4-5bbb-ac05-e0b333ec84ac/attachment.json","path":"assets/sample_package.json","size":1919,"sha256":"0ba6fc01364589a5e6030a05e1283038bf3a944135b46a9a5eaaaf1dbdf6a032","contentType":"application/json; charset=utf-8"},{"id":"d38f2490-a7b5-5639-aa92-5f3dac2e6b29","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/d38f2490-a7b5-5639-aa92-5f3dac2e6b29/attachment.txt","path":"assets/sample_requirements.txt","size":1107,"sha256":"85ee24f99830b71a59419a181efa52e4f6f5ace9ad92e30d2fb6489d21bb0198","contentType":"text/plain; charset=utf-8"},{"id":"4d3fdaf8-2c0f-5883-96e9-b220d2417127","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/4d3fdaf8-2c0f-5883-96e9-b220d2417127/attachment.txt","path":"expected_outputs/sample_license_report.txt","size":930,"sha256":"96d4d67bd77d9f0941f9334a563c94cc25557001aa96d390103878c2903b126a","contentType":"text/plain; charset=utf-8"},{"id":"23279ff4-fdb6-5d92-900f-ce0755f5c4ca","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/23279ff4-fdb6-5d92-900f-ce0755f5c4ca/attachment.txt","path":"expected_outputs/sample_upgrade_plan.txt","size":2061,"sha256":"13cab41ede802c9fe49eb894e86c6ad6a9ced164a64f16a2fff62c2884fd545c","contentType":"text/plain; charset=utf-8"},{"id":"273b51ee-ccf3-599c-a965-1022a1a81b83","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/273b51ee-ccf3-599c-a965-1022a1a81b83/attachment.json","path":"expected_outputs/sample_vulnerability_report.json","size":1708,"sha256":"795d7e23d4c5b56c30051371a1ca8f0ab72496f65c0e554e21d3211ca4dca8a4","contentType":"application/json; charset=utf-8"},{"id":"6ea37cf7-c007-5b7a-858c-797e3b30fd7c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6ea37cf7-c007-5b7a-858c-797e3b30fd7c/attachment.md","path":"references/dependency_management_best_practices.md","size":18189,"sha256":"2eafa69105d7c31bf50b693af656d4181250e241ea110eeba7227ecb29e24f90","contentType":"text/markdown; charset=utf-8"},{"id":"bee04b96-ae22-5230-9ca9-c8610b555dd3","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bee04b96-ae22-5230-9ca9-c8610b555dd3/attachment.md","path":"references/license_compatibility_matrix.md","size":8860,"sha256":"9432a2776985d38f5668e5acfa95754e8695d96bfbea01159e1b7d60da6b6035","contentType":"text/markdown; charset=utf-8"},{"id":"dc360ee0-14b7-5e11-afa2-628a3192358c","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/dc360ee0-14b7-5e11-afa2-628a3192358c/attachment.md","path":"references/vulnerability_assessment_guide.md","size":14453,"sha256":"5e4743618d544cc5903f67572c71aff31180c8f9222c8cfbd4782d7305d482bb","contentType":"text/markdown; charset=utf-8"},{"id":"f8543764-45e0-53d8-9983-6bd34f9ee4ee","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/f8543764-45e0-53d8-9983-6bd34f9ee4ee/attachment.py","path":"scripts/dep_scanner.py","size":31256,"sha256":"309abbb1fb20df6dfcea77ac0e963bd61953cb4b46de8c1a6d10cae6d88546cd","contentType":"text/x-python; charset=utf-8"},{"id":"bb85a624-6fc5-55b1-a9b0-e902da32e1f9","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/bb85a624-6fc5-55b1-a9b0-e902da32e1f9/attachment.py","path":"scripts/license_checker.py","size":44397,"sha256":"7fa7b6d19cc8de7d38850c24d1c8970fafac9df6bd4f44f883056745bd410dc8","contentType":"text/x-python; charset=utf-8"},{"id":"b50f6bbc-6929-5f49-8095-692b751b9e1a","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/b50f6bbc-6929-5f49-8095-692b751b9e1a/attachment.py","path":"scripts/upgrade_planner.py","size":42650,"sha256":"fcaf65475a3376c53c345ad27137a06a99c67184a7b328129021d69f48cc870b","contentType":"text/x-python; charset=utf-8"},{"id":"6a054aad-845a-572e-afd6-b59d3d24d5c7","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/6a054aad-845a-572e-afd6-b59d3d24d5c7/attachment.json","path":"test-inventory.json","size":9916,"sha256":"9eb7db72e3c66d324efe411b11f702ebedd42ac8fa89ffe7ead338b902450fd3","contentType":"application/json; charset=utf-8"},{"id":"3c8ad2db-1a99-5a00-a815-e4c5ea02de1d","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/3c8ad2db-1a99-5a00-a815-e4c5ea02de1d/attachment.json","path":"test-project/package.json","size":1919,"sha256":"0ba6fc01364589a5e6030a05e1283038bf3a944135b46a9a5eaaaf1dbdf6a032","contentType":"application/json; charset=utf-8"}],"bundle_sha256":"432767e1bc450bdeeaa78d5f7c7b98b8c2dffadd003cac2b9b9c6537fe4ef35a","attachment_count":15,"text_attachments":14,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":1,"excluded_attachments":[]},"cluster_size":4,"skill_md_path":"engineering/skills/dependency-auditor/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"security","category_label":"Security"},"exact_dupes_collapsed_into_this":3},"version":"v1","category":"security","import_tag":"clean-skills-v1","description":"Audit and manage dependencies across multi-language projects. Identifies vulnerabilities, license conflicts, transitive dependency risks, and safe-upgrade paths. Use when auditing third-party packages before release, investigating a CVE, planning a major version bump, or running a license-compliance review."}},"renderedAt":1782980010812}

Dependency Auditor Skill Type: POWERFUL Category: Engineering Domain: Dependency Management & Security Overview The Dependency Auditor is a comprehensive toolkit for analyzing, auditing, and managing dependencies across multi-language software projects. This skill provides deep visibility into your project's dependency ecosystem, enabling teams to identify vulnerabilities, ensure license compliance, optimize dependency trees, and plan safe upgrades. In modern software development, dependencies form complex webs that can introduce significant security, legal, and maintenance risks. A single pr…