dependencies-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Dependencies Fix

依赖修复

Find and fix all dependency issues in $ARGUMENTS (or the root
package.json
if no argument is given) — vulnerabilities, outdated packages, deprecated dependencies, license problems, and supply-chain risks. This skill produces the
review-packages.md
artifact required by the Dune app review process.

查找并修复**$ARGUMENTS**(若未提供参数则为根目录下的
package.json
)中的所有依赖问题——包括漏洞、过时包、废弃依赖、许可证问题以及供应链风险。此技能会生成Dune应用审核流程所需的
review-packages.md
产物。

Step 1 — Read and list all dependencies

步骤1 — 读取并列出所有依赖

bash
undefined
bash
undefined

List all dependencies and devDependencies

List all dependencies and devDependencies

node -e " const pkg = require('./package.json'); console.log('=== Dependencies ==='); Object.entries(pkg.dependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver)); console.log('\n=== Dev Dependencies ==='); Object.entries(pkg.devDependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver)); "

Record the total count of dependencies and devDependencies.

---
node -e " const pkg = require('./package.json'); console.log('=== Dependencies ==='); Object.entries(pkg.dependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver)); console.log('\n=== Dev Dependencies ==='); Object.entries(pkg.devDependencies || {}).forEach(([name, ver]) => console.log(name + ' @ ' + ver)); "

记录依赖项和开发依赖项的总数。

---

Step 2 — Look up npm metadata and update outdated packages

步骤2 — 查询npm元数据并更新过时包

For each package, gather:
  • Latest version on npm
  • Weekly downloads
  • Last publish date
  • Deprecated flag
bash
undefined
针对每个包,收集以下信息:
  • npm上的最新版本
  • 周下载量
  • 最后发布日期
  • 已废弃标记
bash
undefined

Batch lookup — run for each package (example for a single package)

Batch lookup — run for each package (example for a single package)

npm view <package-name> --json 2>/dev/null | node -e " const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(JSON.stringify({ name: data.name, latest: data['dist-tags']?.latest, modified: data.time?.modified, deprecated: data.deprecated || false, })); "
npm view <package-name> --json 2>/dev/null | node -e " const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(JSON.stringify({ name: data.name, latest: data['dist-tags']?.latest, modified: data.time?.modified, deprecated: data.deprecated || false, })); "

For weekly downloads, use the npm API

For weekly downloads, use the npm API

curl -s "https://api.npmjs.org/downloads/point/last-week/<package-name>" | node -e " const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(data.downloads); "

For efficiency, batch multiple lookups. If the project has many dependencies, use a script:

```bash
node -e "
  const { execSync } = require('child_process');
  const pkg = require('./package.json');
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };

  for (const [name, usedVersion] of Object.entries(allDeps)) {
    try {
      const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' }));
      const latest = info['dist-tags']?.latest || 'unknown';
      const modified = info.time?.modified || 'unknown';
      const deprecated = info.deprecated ? 'YES' : 'No';
      console.log([name, usedVersion, latest, modified, deprecated].join(' | '));
    } catch {
      console.log(name + ' | ' + usedVersion + ' | LOOKUP FAILED');
    }
  }
"
curl -s "https://api.npmjs.org/downloads/point/last-week/<package-name>" | node -e " const data = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(data.downloads); "

为提升效率,可批量查询多个包。若项目包含大量依赖,使用以下脚本:

```bash
node -e "
  const { execSync } = require('child_process');
  const pkg = require('./package.json');
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };

  for (const [name, usedVersion] of Object.entries(allDeps)) {
    try {
      const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' }));
      const latest = info['dist-tags']?.latest || 'unknown';
      const modified = info.time?.modified || 'unknown';
      const deprecated = info.deprecated ? 'YES' : 'No';
      console.log([name, usedVersion, latest, modified, deprecated].join(' | '));
    } catch {
      console.log(name + ' | ' + usedVersion + ' | LOOKUP FAILED');
    }
  }
"

Fix: Update outdated packages

修复:更新过时包

For each package that is >1 major version behind, update it:
bash
pnpm update <package>@latest
For packages that are 1+ minor versions behind, update to latest minor:
bash
pnpm update <package>
After updating, run
pnpm install
and
pnpm run build
to verify nothing breaks. If a major update breaks the build, revert that specific update and note it as a manual-fix item.

对于主版本落后1个以上的包,更新至最新版本:
bash
pnpm update <package>@latest
对于次版本落后1个以上的包,更新至最新次版本:
bash
pnpm update <package>
更新完成后,运行
pnpm install
pnpm run build
验证是否出现问题。若主版本更新导致构建失败,回滚该包的更新并标记为需手动修复的项。

Step 3 — Run security audit and fix vulnerabilities

步骤3 — 运行安全审计并修复漏洞

bash
undefined
bash
undefined

Run audit with the project's package manager

Run audit with the project's package manager

pnpm audit --json 2>/dev/null || npm audit --json 2>/dev/null
pnpm audit --json 2>/dev/null || npm audit --json 2>/dev/null

Also run production-only audit (what ships to users)

Also run production-only audit (what ships to users)

pnpm audit --prod --json 2>/dev/null || npm audit --production --json 2>/dev/null

Parse the JSON output for:
- Severity counts (critical, high, moderate, low)
- Per-vulnerability details (package, severity, title, patched version, advisory URL)

Any package with a known CVE is an automatic **Fail** in the health column.
pnpm audit --prod --json 2>/dev/null || npm audit --production --json 2>/dev/null

解析JSON输出以获取:
- 严重程度统计(critical、high、moderate、low)
- 单个漏洞详情(包、严重程度、标题、修复版本、咨询URL)

任何存在已知CVE的包在健康评级中自动判定为**Fail**。

Fix: Resolve vulnerabilities

修复:解决漏洞

Run
pnpm audit fix
to auto-fix what's possible. For remaining high/critical CVEs that can't be auto-fixed, manually update the vulnerable package in
package.json
to the patched version and run
pnpm install
. If the patched version has breaking changes, apply the minimum code changes needed to adapt. If a vulnerability is in a transitive dependency, use
pnpm overrides
in
package.json
to force the patched version:
json
{
  "pnpm": {
    "overrides": {
      "vulnerable-package": ">=2.1.0"
    }
  }
}
After applying fixes, re-run
pnpm audit
to confirm the vulnerabilities are resolved. Run
pnpm run build
to verify nothing breaks.

运行
pnpm audit fix
自动修复可处理的漏洞。对于无法自动修复的高/严重级CVE,手动在
package.json
中将受影响包更新至修复版本并运行
pnpm install
。若修复版本存在破坏性变更,只需调整必要的代码以适配。若漏洞存在于间接依赖中,在
package.json
中使用
pnpm overrides
强制使用修复版本:
json
{
  "pnpm": {
    "overrides": {
      "vulnerable-package": ">=2.1.0"
    }
  }
}
应用修复后,重新运行
pnpm audit
确认漏洞已解决。运行
pnpm run build
验证是否出现问题。

Step 4 — Assign health scores and fix Fail-scored packages

步骤4 — 分配健康评分并修复评级为Fail的包

For each package, assign a health indicator:
HealthCriteria
Pass>100k weekly downloads AND updated within last 12 months AND not deprecated AND version is current or near-current (within 1 major)
Warn10k–100k weekly downloads OR >12 months since last publish OR >1 major version behind
Fail<10k weekly downloads OR no update in 2+ years OR deprecated OR known CVE
Edge cases:
  • @cognite/*
    packages: trust Cognite-internal packages even if download counts are low
  • @types/*
    packages: trust DefinitelyTyped packages; focus on whether the version matches the main package
  • Newly published packages (<6 months old): flag as Warn for review, not auto-Fail on low downloads
为每个包分配健康指标:
健康评级判定标准
Pass周下载量>10万 且 最近12个月内更新过 且 未废弃 且 版本为当前或接近当前(主版本差距≤1)
Warn周下载量1万-10万 或 上次发布距今>12个月 或 主版本差距>1
Fail周下载量<1万 或 超过2年未更新 或 已废弃 或 存在已知CVE
边缘情况:
  • @cognite/*
    包:即使下载量低也信任Cognite内部包
  • @types/*
    包:信任DefinitelyTyped包;重点关注版本是否匹配主包
  • 新发布的包(<6个月):标记为Warn以供审核,不因下载量低直接判定为Fail

Fix: Replace Fail-scored packages

修复:替换评级为Fail的包

For each Fail-scored package:
  • If deprecated: find and install the recommended replacement. Update all imports across the codebase.
  • If unmaintained (2+ years): find an actively maintained alternative with equivalent functionality. Replace it.
  • If low downloads and not
    @cognite/*
    :
    evaluate whether it's truly needed. If a native JS/TS equivalent exists or the functionality is simple, remove the dependency and implement inline.
After each replacement, run
pnpm install
and
pnpm run build
to verify the replacement works.

对于每个评级为Fail的包:
  • 若已废弃: 查找并安装推荐的替代包。更新代码库中的所有导入语句。
  • 若已停止维护(≥2年): 查找功能等效且维护活跃的替代包并替换。
  • 若下载量低且非
    @cognite/*
    评估是否真的需要该包。若存在原生JS/TS等效实现或功能简单,移除依赖并自行实现。
每次替换后,运行
pnpm install
pnpm run build
验证替换是否有效。

Step 5 — Check for supply-chain risks and mitigate

步骤5 — 检查供应链风险并缓解

bash
undefined
bash
undefined

Check for install scripts (preinstall, postinstall, prepare)

Check for install scripts (preinstall, postinstall, prepare)

node -e " const { execSync } = require('child_process'); const pkg = require('./package.json'); const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
for (const name of allDeps) { try { const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' })); const scripts = info.scripts || {}; const risky = ['preinstall', 'install', 'postinstall'].filter(s => scripts[s]); if (risky.length > 0) { console.log('INSTALL SCRIPT: ' + name + ' — ' + risky.join(', ')); } } catch {} } "
node -e " const { execSync } = require('child_process'); const pkg = require('./package.json'); const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
for (const name of allDeps) { try { const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' })); const scripts = info.scripts || {}; const risky = ['preinstall', 'install', 'postinstall'].filter(s => scripts[s]); if (risky.length > 0) { console.log('INSTALL SCRIPT: ' + name + ' — ' + risky.join(', ')); } } catch {} } "

Check for packages with very few maintainers (single point of failure)

Check for packages with very few maintainers (single point of failure)

This is informational, not blocking

This is informational, not blocking

undefined
undefined

Fix: Evaluate and mitigate install script risks

修复:评估并缓解安装脚本风险

For each dependency with install scripts, determine if the script is legitimate (e.g., native module compilation for
sharp
,
esbuild
,
better-sqlite3
). Known build tools and native module packages are expected to have install scripts.
If the package is not a known build tool and has suspicious install scripts, replace it with a safer alternative. After replacement, run
pnpm install
and
pnpm run build
to verify.

对于包含安装脚本的依赖,判定脚本是否合法(例如
sharp
esbuild
better-sqlite3
等原生模块的编译脚本)。已知构建工具和原生模块包包含安装脚本是正常情况。
若包并非已知构建工具且包含可疑安装脚本,替换为更安全的替代包。替换后运行
pnpm install
pnpm run build
验证。

Step 6 — Check license compatibility and replace problematic packages

步骤6 — 检查许可证兼容性并替换有问题的包

bash
undefined
bash
undefined

List all licenses

List all licenses

npx license-checker --summary 2>/dev/null || node -e " const { execSync } = require('child_process'); const pkg = require('./package.json'); const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
for (const name of allDeps) { try { const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' })); console.log(name + ': ' + (info.license || 'UNKNOWN')); } catch {} } "

Acceptable licenses for Dune apps (commercial distribution):
- MIT, Apache-2.0, BSD-2-Clause, BSD-3-Clause, ISC, 0BSD, Unlicense, CC0-1.0

Licenses that need legal review:
- GPL-2.0, GPL-3.0, LGPL-2.1, LGPL-3.0, AGPL-3.0, MPL-2.0, EUPL-1.1
- Any "UNKNOWN" or missing license
npx license-checker --summary 2>/dev/null || node -e " const { execSync } = require('child_process'); const pkg = require('./package.json'); const allDeps = Object.keys({ ...pkg.dependencies, ...pkg.devDependencies });
for (const name of allDeps) { try { const info = JSON.parse(execSync('npm view ' + name + ' --json 2>/dev/null', { encoding: 'utf8' })); console.log(name + ': ' + (info.license || 'UNKNOWN')); } catch {} } "

Dune应用(商业分发)可接受的许可证:
- MIT、Apache-2.0、BSD-2-Clause、BSD-3-Clause、ISC、0BSD、Unlicense、CC0-1.0

需法务审核的许可证:
- GPL-2.0、GPL-3.0、LGPL-2.1、LGPL-3.0、AGPL-3.0、MPL-2.0、EUPL-1.1
- 任何“UNKNOWN”或缺失的许可证

Fix: Replace packages with problematic licenses

修复:替换许可证有问题的包

For each package with a copyleft license (GPL, AGPL) or unknown license in production dependencies, find an MIT/Apache-2.0 licensed alternative and replace it. Update all imports across the codebase.
For devDependencies with copyleft licenses, these are lower risk but still flag for awareness.
After each replacement, run
pnpm install
and
pnpm run build
to verify.

对于生产依赖中包含 copyleft 许可证(GPL、AGPL)或未知许可证的包,查找MIT/Apache-2.0许可证的替代包并替换。更新代码库中的所有导入语句。
对于开发依赖中包含copyleft许可证的包,风险较低但仍需标记以便关注。
每次替换后,运行
pnpm install
pnpm run build
验证。

Step 7 — Generate the review-packages.md artifact (post-fix state)

步骤7 — 生成review-packages.md产物(修复后状态)

Re-run the metadata lookups after all fixes have been applied to capture the post-fix state. Then produce the output in the format required by the Dune app review process:
markdown
undefined
所有修复完成后,重新运行元数据查询以记录修复后的状态。然后按照Dune应用审核流程要求的格式生成输出:
markdown
undefined

Package audit: [app name]

Package audit: [app name]

Dependencies

Dependencies

PackageUsed versionLatestWeekly downloadsLast publishedDeprecatedCVEsHealth
react^18.2.018.3.125M2024-04-26No0Pass
some-old-lib^1.0.01.0.35k2021-03-15No0Fail
PackageUsed versionLatestWeekly downloadsLast publishedDeprecatedCVEsHealth
react^18.2.018.3.125M2024-04-26No0Pass
some-old-lib^1.0.01.0.35k2021-03-15No0Fail

Dev Dependencies

Dev Dependencies

PackageUsed versionLatestWeekly downloadsLast publishedDeprecatedCVEsHealth
vitest^1.6.02.0.18M2024-07-01No0Pass
PackageUsed versionLatestWeekly downloadsLast publishedDeprecatedCVEsHealth
vitest^1.6.02.0.18M2024-07-01No0Pass

Security audit

Security audit

SeverityCount
Critical0
High0
Moderate0
Low0
SeverityCount
Critical0
High0
Moderate0
Low0

Vulnerabilities

Vulnerabilities

PackageSeverityTitlePatched inAdvisory
(none found)
PackageSeverityTitlePatched inAdvisory
(none found)

License summary

License summary

LicenseCountPackages
MIT45react, react-dom, ...
Apache-2.03...
LicenseCountPackages
MIT45react, react-dom, ...
Apache-2.03...

Supply-chain flags

Supply-chain flags

PackageRiskDetails
(none found)

---
PackageRiskDetails
(none found)

---

Step 8 — Report remaining issues

步骤8 — 报告剩余问题

Summarize what was fixed and what remains:
总结已修复的内容和剩余问题:

Fixed

已修复

CategoryCountDetails
Packages updatedNlist of packages and version changes
CVEs resolvedNlist of CVEs fixed
Deprecated deps replacedNold package -> new package
License issues resolvedNold package -> new package
类别数量详情
已更新包N包列表及版本变更
已解决CVEN已修复的CVE列表
已替换废弃依赖N旧包 -> 新包
已解决许可证问题N旧包 -> 新包

Remaining (could not auto-fix)

剩余问题(无法自动修复)

List only issues that could not be automatically fixed:
  • Breaking changes from major updates that need manual code adaptation
  • Licenses that need legal review (e.g., LGPL in transitive dependencies)
  • Packages with no maintained alternative available
  • Vulnerabilities with no patched version available yet
For each remaining item, explain why it could not be auto-fixed and what the app author needs to do.

仅列出无法自动修复的问题:
  • 主版本更新导致的破坏性变更,需手动调整代码
  • 需法务审核的许可证(例如间接依赖中的LGPL)
  • 无维护活跃替代包的包
  • 暂无修复版本的漏洞
对于每个剩余问题,说明无法自动修复的原因以及应用开发者需要执行的操作。

Done

完成

State the overall health verdict: how many Pass/Warn/Fail after fixes, how many issues were resolved, and any remaining items that need manual attention from the app author.
给出整体健康结论:修复后的Pass/Warn/Fail数量、已解决的问题数量,以及需要应用开发者手动处理的剩余项。