Install
openclaw skills install dependency-impact-analyzerAnalyze the blast radius of upgrading, removing, or replacing a dependency — trace imports, find affected files, check test coverage of impacted code, detect breaking API changes, and generate safe upgrade plans.
openclaw skills install dependency-impact-analyzerBefore upgrading or removing a dependency, understand exactly what will be affected. Traces all imports, finds every file that uses the package, checks test coverage of impacted code, and identifies potential breaking changes.
Use when: "what happens if I upgrade X", "impact of removing lodash", "can I safely update this", "dependency blast radius", "which files use package X", "upgrade risk assessment", or before major dependency changes.
trace — Trace All Usages of a DependencyFind every file that imports or requires the package, and how it's used.
PACKAGE="${1:?Usage: trace <package-name>}"
echo "=== Tracing usage of: $PACKAGE ==="
# Direct imports (JS/TS)
echo "--- Direct Imports ---"
rg -n "from ['\"]$PACKAGE['\"/]|require\(['\"]$PACKAGE['\"/]\)|import ['\"]$PACKAGE['\"]" \
-g '*.{js,ts,jsx,tsx,mjs,cjs}' -g '!node_modules' -g '!dist' -g '!build' 2>/dev/null
# Subpath imports
echo "--- Subpath Imports ---"
rg -n "from ['\"]$PACKAGE/" \
-g '*.{js,ts,jsx,tsx}' -g '!node_modules' -g '!dist' 2>/dev/null
# Python imports
rg -n "^import $PACKAGE|^from $PACKAGE" \
-g '*.py' -g '!vendor' -g '!dist' 2>/dev/null
# Go imports
rg -n "\".*$PACKAGE" \
-g '*.go' -g '!vendor' 2>/dev/null
# Count total usage
USAGE_COUNT=$(rg -c "$PACKAGE" \
-g '!node_modules' -g '!vendor' -g '!dist' -g '!*.lock' -g '!package-lock.json' \
--type-not binary 2>/dev/null | awk -F: '{s+=$2} END {print s+0}')
FILE_COUNT=$(rg -l "$PACKAGE" \
-g '!node_modules' -g '!vendor' -g '!dist' -g '!*.lock' -g '!package-lock.json' \
--type-not binary 2>/dev/null | wc -l)
echo ""
echo "Total: $USAGE_COUNT references across $FILE_COUNT files"
Extract which specific exports/APIs are used:
# What functions/classes are imported from this package?
rg -o "import \{([^}]+)\} from ['\"]$PACKAGE['\"]" \
-g '*.{ts,js,tsx,jsx}' -g '!node_modules' 2>/dev/null | \
sed "s/.*{//;s/}.*//" | tr ',' '\n' | sed 's/^\s*//;s/\s*$//' | sort | uniq -c | sort -rn
rg -o "const \{([^}]+)\} = require\(['\"]$PACKAGE['\"]\)" \
-g '*.{js,ts}' -g '!node_modules' 2>/dev/null | \
sed "s/.*{//;s/}.*//" | tr ',' '\n' | sed 's/^\s*//;s/\s*$//' | sort | uniq -c | sort -rn
impact — Full Impact AssessmentComprehensive analysis of what upgrading this dependency means.
PACKAGE="${1:?Usage: impact <package-name> [target-version]}"
TARGET_VERSION="${2:-latest}"
# Current version
if [ -f "package.json" ]; then
CURRENT=$(python3 -c "
import json
d = json.load(open('package.json'))
v = d.get('dependencies',{}).get('$PACKAGE') or d.get('devDependencies',{}).get('$PACKAGE') or 'not found'
print(v)
" 2>/dev/null)
echo "Current: $PACKAGE@$CURRENT"
fi
if [ -f "requirements.txt" ]; then
grep -i "^$PACKAGE" requirements.txt 2>/dev/null
fi
# Check package changelog/releases for breaking changes
echo "--- Checking for breaking changes ---"
# For npm packages: check if major version changed
if [ -f "package.json" ]; then
npm info "$PACKAGE" versions --json 2>/dev/null | python3 -c "
import json, sys, re
try:
versions = json.load(sys.stdin)
current = '$CURRENT'.lstrip('^~>=')
current_major = current.split('.')[0] if current != 'not found' else '0'
latest = versions[-1] if isinstance(versions, list) else versions
latest_major = latest.split('.')[0]
if current_major != latest_major:
print(f'⚠️ MAJOR version change: {current} → {latest} (likely breaking changes)')
else:
print(f'✅ Same major version: {current} → {latest} (should be backward compatible)')
except Exception as e:
print(f'Could not check versions: {e}')
" 2>/dev/null
fi
# Check npm deprecation
npm info "$PACKAGE" deprecated 2>/dev/null | grep -v "^$" && echo "⚠️ Package is DEPRECATED"
# Find files that import the package
AFFECTED_FILES=$(rg -l "$PACKAGE" \
-g '!node_modules' -g '!vendor' -g '!dist' -g '!*.lock' -g '!*.test.*' -g '!*.spec.*' \
-g '*.{js,ts,jsx,tsx,py,go}' --type-not binary 2>/dev/null)
echo "--- Test Coverage of Affected Files ---"
for f in $AFFECTED_FILES; do
BASE=$(basename "$f" | sed 's/\.[^.]*$//')
DIR=$(dirname "$f")
# Look for corresponding test file
TEST=$(find "$DIR" -maxdepth 2 \( -name "${BASE}.test.*" -o -name "${BASE}.spec.*" -o -name "test_${BASE}.*" \) \
-not -path '*/node_modules/*' 2>/dev/null | head -1)
if [ -n "$TEST" ]; then
echo "✅ $f → $TEST"
else
echo "❌ $f → NO TEST (upgrade risk!)"
fi
done
# What other packages depend on this one?
echo "--- Reverse Dependencies ---"
if [ -f "package-lock.json" ]; then
python3 -c "
import json
lock = json.load(open('package-lock.json'))
pkg = '$PACKAGE'
rdeps = []
packages = lock.get('packages', lock.get('dependencies', {}))
for name, info in packages.items():
deps = info.get('dependencies', {})
if pkg in deps:
clean_name = name.replace('node_modules/', '')
rdeps.append(f'{clean_name} (requires {pkg}@{deps[pkg]})')
if rdeps:
print(f'{len(rdeps)} packages also depend on {pkg}:')
for r in rdeps[:20]:
print(f' {r}')
else:
print(f'No other packages depend on {pkg} (leaf dependency)')
" 2>/dev/null
fi
remove — Safe Removal AnalysisWhat happens if you completely remove this dependency?
PACKAGE="${1:?Usage: remove <package-name>}"
echo "=== Removal Impact: $PACKAGE ==="
# All files that would break
BREAKING_FILES=$(rg -l "from ['\"]$PACKAGE|require\(['\"]$PACKAGE|import $PACKAGE|from $PACKAGE" \
-g '!node_modules' -g '!vendor' -g '!dist' -g '!*.lock' 2>/dev/null)
FILE_COUNT=$(echo "$BREAKING_FILES" | grep -c "." 2>/dev/null || echo "0")
echo "Files that would break: $FILE_COUNT"
echo "$BREAKING_FILES" | head -20
# Suggest alternatives
echo ""
echo "--- Alternative Packages ---"
echo "Use AI reasoning to suggest alternatives based on:"
echo "1. What specific features of $PACKAGE are used (from trace output)"
echo "2. Whether native/stdlib alternatives exist"
echo "3. What the community has migrated to"
replace — Migration Plan for Swapping PackagesGenerate a migration plan for replacing one package with another.
OLD="${1:?Usage: replace <old-package> <new-package>}"
NEW="${2:?Usage: replace <old-package> <new-package>}"
echo "=== Migration Plan: $OLD ��� $NEW ==="
# Trace old package usage
echo "--- Current API Usage ($OLD) ---"
rg -o "import \{[^}]+\} from ['\"]$OLD['\"]" \
-g '*.{ts,js,tsx,jsx}' -g '!node_modules' 2>/dev/null | head -20
echo ""
echo "--- Files to Modify ---"
rg -l "$OLD" -g '!node_modules' -g '!vendor' -g '!dist' -g '!*.lock' 2>/dev/null
Generate AI-powered migration plan:
audit — Dependency Portfolio RiskAssess the overall risk profile of all dependencies.
echo "=== Dependency Risk Audit ==="
if [ -f "package.json" ]; then
python3 -c "
import json, subprocess, re
from datetime import datetime
d = json.load(open('package.json'))
all_deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
print(f'Total dependencies: {len(all_deps)}')
print(f' Production: {len(d.get(\"dependencies\",{}))}')
print(f' Dev: {len(d.get(\"devDependencies\",{}))}')
# Known deprecated packages
deprecated = {
'request': 'Use fetch, axios, or got',
'node-uuid': 'Use uuid package',
'nomnom': 'Use commander or yargs',
'optimist': 'Use yargs',
'jade': 'Renamed to pug',
'istanbul': 'Use nyc or c8',
'coffee-script': 'Migrate to JavaScript/TypeScript',
'bower': 'Use npm/yarn/pnpm',
'grunt': 'Use npm scripts or modern bundlers',
'moment': 'Use date-fns, dayjs, or Temporal',
'left-pad': 'Use String.padStart()',
'underscore': 'Use lodash or native JS',
}
print()
found_deprecated = []
for pkg, alt in deprecated.items():
if pkg in all_deps:
found_deprecated.append(f' ⚠️ {pkg}@{all_deps[pkg]} → {alt}')
if found_deprecated:
print(f'Deprecated packages ({len(found_deprecated)}):')
for f in found_deprecated:
print(f)
else:
print('✅ No known deprecated packages')
# Pinning analysis
print()
unpinned = [(k,v) for k,v in all_deps.items() if v.startswith('^') or v.startswith('~')]
exact = [(k,v) for k,v in all_deps.items() if re.match(r'^\d', v)]
wildcard = [(k,v) for k,v in all_deps.items() if '*' in v]
print(f'Version pinning: {len(exact)} exact, {len(unpinned)} range (^/~), {len(wildcard)} wildcard')
if wildcard:
print(' ❌ Wildcard versions (dangerous):')
for k,v in wildcard:
print(f' {k}: {v}')
" 2>/dev/null
fi
# Check for security advisories
echo ""
echo "--- Security Advisories ---"
npm audit --json 2>/dev/null | python3 -c "
import json, sys
try:
d = json.load(sys.stdin)
v = d.get('metadata',{}).get('vulnerabilities',{})
total = sum(v.values())
if total > 0:
print(f'Vulnerabilities: {v.get(\"critical\",0)} critical, {v.get(\"high\",0)} high, {v.get(\"moderate\",0)} moderate, {v.get(\"low\",0)} low')
else:
print('✅ No known vulnerabilities')
except: print('Could not parse audit output')
" 2>/dev/null
# Dependency size impact
echo ""
echo "--- Size Impact (top 10 heaviest) ---"
if command -v npx &>/dev/null; then
echo "Run 'npx package-size <package>' for individual sizes"
fi
{package, current_version, usage: {files, imports, apis}, tests: {covered, uncovered}, breaking_changes: [], alternatives: []}Exit codes: