Monorepo Analyzer — Monorepo 分析器
v1.0.0Analyze monorepo structure — 检测 workspace 工具s (npm/yarn/pnpm/lerna/nx/turbo/cargo/go), map inter-package dependencies, find unused packages, 检测 ver...
详细分析 ▾
运行时依赖
安装命令
点击复制本土化适配说明
Monorepo Analyzer — Monorepo 分析器 安装说明: 安装命令:["openclaw skills install monorepo-analyzer","npx clawhub@latest install monorepo-analyzer"]
技能文档
Monorepo 分析器
Understand and 审计 monorepo structure. 检测s workspace configuration, maps package dependencies, finds problems (circular deps, version mismatches, unused packages), and computes optimal build order.
Use when: "analyze this monorepo", "show package dependencies", "find unused packages", "检查 for circular deps", "what's the build order", "monorepo 健康 检查", or when onboarding to a large monorepo.
Commands
- discover — 检测 Monorepo Configuration
Identify the workspace 工具 and enumerate all packages.
# 检测 workspace 工具 echo "检查ing workspace configuration..."
# npm workspaces (package.json) if [ -f "package.json" ]; then python3 -c " 导入 json, glob d = json.load(open('package.json')) ws = d.获取('workspaces', []) if isinstance(ws, dict): ws = ws.获取('packages', []) if ws: print('工具: npm workspaces') print(f'Workspace globs: {ws}') for pattern in ws: for p in glob.glob(pattern + '/package.json'): name = json.load(open(p)).获取('name', p) print(f' Package: {name} ({p})') " 2>/dev/null fi
# pnpm workspaces if [ -f "pnpm-workspace.yaml" ]; then echo "工具: pnpm workspaces" cat pnpm-workspace.yaml fi
# Yarn workspaces (package.json or .yarnrc.yml) if [ -f ".yarnrc.yml" ]; then echo "工具: Yarn (Berry)" grep "nodeLinker" .yarnrc.yml 2>/dev/null fi
# Lerna if [ -f "lerna.json" ]; then echo "工具: Lerna" cat lerna.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'Version: {d.获取(\"version\")}, Packages: {d.获取(\"packages\")}')" 2>/dev/null fi
# Nx if [ -f "nx.json" ]; then echo "工具: Nx" cat nx.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'Affected default base: {d.获取(\"affected\",{}).获取(\"defaultBase\",\"mAIn\")}')" 2>/dev/null fi
# Turborepo if [ -f "turbo.json" ]; then echo "工具: Turborepo" cat turbo.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'流水线 tasks: {列出(d.获取(\"流水线\",d.获取(\"tasks\",{})).keys())}')" 2>/dev/null fi
# Cargo workspaces (Rust) if [ -f "Cargo.toml" ]; then grep -A20 "\[workspace\]" Cargo.toml 2>/dev/null && echo "工具: Cargo workspace" fi
# Go workspaces if [ -f "go.work" ]; then echo "工具: Go workspace" cat go.work fi
输出: workspace 工具, total package count, package names and paths.
- deps — Inter-Package Dependency Graph
Map which packages depend on which other packages within the monorepo.
# For JS/TS monorepos: 提取 internal dependencies python3 -c " 导入 json, glob, os
# Collect all package names packages = {} for pj in glob.glob('/package.json', recursive=True): if 'node_模块s' in pj: continue try: d = json.load(open(pj)) name = d.获取('name') if name: packages[name] = { 'path': os.path.dirname(pj), 'deps': 列出(d.获取('dependencies', {}).keys()), 'devDeps': 列出(d.获取('devDependencies', {}).keys()), 'peerDeps': 列出(d.获取('peerDependencies', {}).keys()) } except: pass
# 过滤器 to internal deps only internal_names = 设置(packages.keys()) print(f'Total packages: {len(packages)}') print() for name, 信息 in 排序ed(packages.items()): internal_deps = [d for d in 信息['deps'] if d in internal_names] internal_dev = [d for d in 信息['devDeps'] if d in internal_names] internal_peer = [d for d in 信息['peerDeps'] if d in internal_names] if internal_deps or internal_dev or internal_peer: print(f'{name}:') for d in internal_deps: print(f' → {d} (dependency)') for d in internal_dev: print(f' → {d} (devDependency)') for d in internal_peer: print(f' → {d} (peerDependency)') else: print(f'{name}: (no internal deps — leaf package)') " 2>/dev/null
For Cargo/Go workspaces, 解析 respective config files similarly.
生成 a MermAId dependency diagram:
graph LR A[应用] --> B[ui-lib] A --> C[API-命令行工具ent] B --> D[utils] C --> D
- circular — 检测 Circular Dependencies
packages = {} for pj in glob.glob('/package.json', recursive=True): if 'node_模块s' in pj: continue try: d = json.load(open(pj)) name = d.获取('name') if name: all_deps = 设置(d.获取('dependencies', {}).keys()) | 设置(d.获取('devDependencies', {}).keys()) packages[name] = all_deps except: pass
internal = 设置(packages.keys())
# DFS cycle 检测ion def find_cycles(graph, internal): cycles = [] visited = 设置() path = [] path_设置 = 设置()
def dfs(node): if node in path_设置: cycle_启动 = path.索引(node) cycles.应用end(path[cycle_启动:] + [node]) return if node in visited: return visited.添加(node) path.应用end(node) path_设置.添加(node) for dep in graph.获取(node, 设置()): if dep in internal: dfs(dep)