Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ playwright-report

# Agent skills from npm packages (managed by skills-npm)
**/skills/npm-*

# Copied at publish time from root /skills/ by scripts/copy-skills.mjs
packages/node-modules-inspector/skills/
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,44 @@ Then you can host the `.node-modules-inspector` folder with any static file serv

You can see a build for all Anthony Fu's packages at [everything.antfu.dev](https://everything.antfu.dev).

## CLI Reports

In addition to the web UI, the inspector exposes three machine-readable reports designed for shell pipelines and AI coding agents:

```bash
npx node-modules-inspector report duplicates # packages installed in multiple versions
npx node-modules-inspector report sizes # packages sorted by install size
npx node-modules-inspector report maintainers # dep-upgrade opportunities + publint, grouped by consumer/author
```

Each command renders a pretty ANSI table by default. Add `--json` to emit JSON to stdout — progress logs go to stderr, so output is pipe-safe:

```bash
npx node-modules-inspector report duplicates --json | jq '.[].name'
npx node-modules-inspector report sizes --json --limit 10
npx node-modules-inspector report maintainers --json --sort migration --no-latest-only
```

Common options across all reports: `--root <dir>`, `--config <file>`, `--depth <n>`, `--limit <n>`. Run `node-modules-inspector report --help` for the full per-report flag set.

## MCP Server

The same three reports are exposed as MCP tools for AI coding agents. Start the server over stdio:

```bash
npx node-modules-inspector mcp
```

Tools exposed:
- `nmi:report-duplicates`
- `nmi:report-sizes`
- `nmi:report-maintainers`

Input/output JSON Schemas are auto-derived from the underlying valibot definitions and surfaced via `tools/list`. Wire it into Claude Code (or any MCP-compatible client) by adding `node-modules-inspector mcp` as a stdio server in your MCP config.

> [!NOTE]
> An [agent skill](./skills/node-modules-inspector/SKILL.md) lives at `skills/node-modules-inspector/SKILL.md` (repo root) and is copied into the published tarball at `<pkg>/skills/` during `prepack`. If your project uses [`skills-npm`](https://github.com/antfu/skills-npm), the skill is automatically symlinked into your agent's skill directory after `pnpm install`.

## Screenshots

![Image](https://github.com/user-attachments/assets/80ce6f9d-26fb-4fcf-8c51-e3d2b6f9f24c)
Expand Down
12 changes: 8 additions & 4 deletions packages/node-modules-inspector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,23 @@
"bin": "bin.mjs",
"files": [
"bin.mjs",
"dist"
"dist",
"skills"
],
"scripts": {
"dev": "pnpm run -r stub && (cd src && ROLLDOWN_OPTIONS_VALIDATION=loose nuxi dev)",
"stub": "unbuild --stub",
"build": "pnpm run wc:prepare && (cd src && ROLLDOWN_OPTIONS_VALIDATION=loose nuxi build) && unbuild",
"build:debug": "ROLLDOWN_OPTIONS_VALIDATION=loose NUXT_DEBUG_BUILD=true pnpm run build",
"start": "node ./bin.mjs",
"prepack": "pnpm build",
"dev:prepare": "(cd src && nuxi prepare) && pnpm wc:prepare",
"prepack": "pnpm build && node scripts/copy-skills.mjs",
"dev:prepare": "(cd src && nuxi prepare) && pnpm wc:prepare && node scripts/copy-skills.mjs",
"wc:prepare": "rollup -c",
"wc:build": "pnpm run wc:prepare && NMI_BACKEND=webcontainer ROLLDOWN_OPTIONS_VALIDATION=loose nuxi build src && unbuild",
"wc:dev": "pnpm run -r stub && pnpm run wc:prepare && (cd src && NMI_BACKEND=webcontainer ROLLDOWN_OPTIONS_VALIDATION=loose nuxi dev)"
},
"dependencies": {
"@modelcontextprotocol/sdk": "catalog:deps",
"ansis": "catalog:deps",
"cac": "catalog:deps",
"devframe": "catalog:deps",
Expand All @@ -54,11 +56,13 @@
"structured-clone-es": "catalog:deps",
"tinyglobby": "catalog:deps",
"unconfig": "catalog:deps",
"unstorage": "catalog:deps"
"unstorage": "catalog:deps",
"valibot": "catalog:deps"
},
"devDependencies": {
"@types/semver": "catalog:types",
"@unocss/nuxt": "catalog:bundling",
"@valibot/to-json-schema": "catalog:testing",
"@vueuse/nuxt": "catalog:bundling",
"@webcontainer/api": "catalog:frontend",
"@xterm/addon-fit": "catalog:frontend",
Expand Down
25 changes: 25 additions & 0 deletions packages/node-modules-inspector/scripts/copy-skills.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copies the repo-root `skills/` folder into this package so it ships in the
// published tarball at `<pkg>/skills/`. The root location is the source of
// truth (it's where humans and most agent-skills tooling look directly); this
// copy is what `skills-npm` and `npm install` consumers see.

import { existsSync } from 'node:fs'
import { cp, rm } from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'

const here = dirname(fileURLToPath(import.meta.url))
const src = resolve(here, '../../../skills')
const dest = resolve(here, '../skills')

if (!existsSync(src)) {
console.error(`[copy-skills] source not found: ${src}`)
process.exit(1)
}

if (existsSync(dest))
await rm(dest, { recursive: true })
await cp(src, dest, { recursive: true })

console.log(`[copy-skills] ${src} → ${dest}`)
Loading
Loading