dependencies-audit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDependencies Fix
依赖修复
Find and fix all dependency issues in $ARGUMENTS (or the root if no argument is given) — vulnerabilities, outdated packages, deprecated dependencies, license problems, and supply-chain risks. This skill produces the artifact required by the Dune app review process.
package.jsonreview-packages.md查找并修复**$ARGUMENTS**(若未提供参数则为根目录下的)中的所有依赖问题——包括漏洞、过时包、废弃依赖、许可证问题以及供应链风险。此技能会生成Dune应用审核流程所需的产物。
package.jsonreview-packages.mdStep 1 — Read and list all dependencies
步骤1 — 读取并列出所有依赖
bash
undefinedbash
undefinedList 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
undefinedBatch 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>@latestFor packages that are 1+ minor versions behind, update to latest minor:
bash
pnpm update <package>After updating, run and to verify nothing breaks. If a major update breaks the build, revert that specific update and note it as a manual-fix item.
pnpm installpnpm run build对于主版本落后1个以上的包,更新至最新版本:
bash
pnpm update <package>@latest对于次版本落后1个以上的包,更新至最新次版本:
bash
pnpm update <package>更新完成后,运行和验证是否出现问题。若主版本更新导致构建失败,回滚该包的更新并标记为需手动修复的项。
pnpm installpnpm run buildStep 3 — Run security audit and fix vulnerabilities
步骤3 — 运行安全审计并修复漏洞
bash
undefinedbash
undefinedRun 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 to auto-fix what's possible. For remaining high/critical CVEs that can't be auto-fixed, manually update the vulnerable package in to the patched version and run . If the patched version has breaking changes, apply the minimum code changes needed to adapt. If a vulnerability is in a transitive dependency, use in to force the patched version:
pnpm audit fixpackage.jsonpnpm installpnpm overridespackage.jsonjson
{
"pnpm": {
"overrides": {
"vulnerable-package": ">=2.1.0"
}
}
}After applying fixes, re-run to confirm the vulnerabilities are resolved. Run to verify nothing breaks.
pnpm auditpnpm run build运行自动修复可处理的漏洞。对于无法自动修复的高/严重级CVE,手动在中将受影响包更新至修复版本并运行。若修复版本存在破坏性变更,只需调整必要的代码以适配。若漏洞存在于间接依赖中,在中使用强制使用修复版本:
pnpm audit fixpackage.jsonpnpm installpackage.jsonpnpm overridesjson
{
"pnpm": {
"overrides": {
"vulnerable-package": ">=2.1.0"
}
}
}应用修复后,重新运行确认漏洞已解决。运行验证是否出现问题。
pnpm auditpnpm run buildStep 4 — Assign health scores and fix Fail-scored packages
步骤4 — 分配健康评分并修复评级为Fail的包
For each package, assign a health indicator:
| Health | Criteria |
|---|---|
| Pass | >100k weekly downloads AND updated within last 12 months AND not deprecated AND version is current or near-current (within 1 major) |
| Warn | 10k–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:
- packages: trust Cognite-internal packages even if download counts are low
@cognite/* - packages: trust DefinitelyTyped packages; focus on whether the version matches the main package
@types/* - 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/* - 包:信任DefinitelyTyped包;重点关注版本是否匹配主包
@types/* - 新发布的包(<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 : evaluate whether it's truly needed. If a native JS/TS equivalent exists or the functionality is simple, remove the dependency and implement inline.
@cognite/*
After each replacement, run and to verify the replacement works.
pnpm installpnpm run build对于每个评级为Fail的包:
- 若已废弃: 查找并安装推荐的替代包。更新代码库中的所有导入语句。
- 若已停止维护(≥2年): 查找功能等效且维护活跃的替代包并替换。
- 若下载量低且非: 评估是否真的需要该包。若存在原生JS/TS等效实现或功能简单,移除依赖并自行实现。
@cognite/*
每次替换后,运行和验证替换是否有效。
pnpm installpnpm run buildStep 5 — Check for supply-chain risks and mitigate
步骤5 — 检查供应链风险并缓解
bash
undefinedbash
undefinedCheck 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
undefinedundefinedFix: Evaluate and mitigate install script risks
修复:评估并缓解安装脚本风险
For each dependency with install scripts, determine if the script is legitimate (e.g., native module compilation for , , ). Known build tools and native module packages are expected to have install scripts.
sharpesbuildbetter-sqlite3If the package is not a known build tool and has suspicious install scripts, replace it with a safer alternative. After replacement, run and to verify.
pnpm installpnpm run build对于包含安装脚本的依赖,判定脚本是否合法(例如、、等原生模块的编译脚本)。已知构建工具和原生模块包包含安装脚本是正常情况。
sharpesbuildbetter-sqlite3若包并非已知构建工具且包含可疑安装脚本,替换为更安全的替代包。替换后运行和验证。
pnpm installpnpm run buildStep 6 — Check license compatibility and replace problematic packages
步骤6 — 检查许可证兼容性并替换有问题的包
bash
undefinedbash
undefinedList 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 licensenpx 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 and to verify.
pnpm installpnpm run build对于生产依赖中包含 copyleft 许可证(GPL、AGPL)或未知许可证的包,查找MIT/Apache-2.0许可证的替代包并替换。更新代码库中的所有导入语句。
对于开发依赖中包含copyleft许可证的包,风险较低但仍需标记以便关注。
每次替换后,运行和验证。
pnpm installpnpm run buildStep 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
undefinedPackage audit: [app name]
Package audit: [app name]
Dependencies
Dependencies
| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
|---|---|---|---|---|---|---|---|
| react | ^18.2.0 | 18.3.1 | 25M | 2024-04-26 | No | 0 | Pass |
| some-old-lib | ^1.0.0 | 1.0.3 | 5k | 2021-03-15 | No | 0 | Fail |
| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
|---|---|---|---|---|---|---|---|
| react | ^18.2.0 | 18.3.1 | 25M | 2024-04-26 | No | 0 | Pass |
| some-old-lib | ^1.0.0 | 1.0.3 | 5k | 2021-03-15 | No | 0 | Fail |
Dev Dependencies
Dev Dependencies
| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
|---|---|---|---|---|---|---|---|
| vitest | ^1.6.0 | 2.0.1 | 8M | 2024-07-01 | No | 0 | Pass |
| Package | Used version | Latest | Weekly downloads | Last published | Deprecated | CVEs | Health |
|---|---|---|---|---|---|---|---|
| vitest | ^1.6.0 | 2.0.1 | 8M | 2024-07-01 | No | 0 | Pass |
Security audit
Security audit
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 0 |
| Moderate | 0 |
| Low | 0 |
| Severity | Count |
|---|---|
| Critical | 0 |
| High | 0 |
| Moderate | 0 |
| Low | 0 |
Vulnerabilities
Vulnerabilities
| Package | Severity | Title | Patched in | Advisory |
|---|---|---|---|---|
| (none found) | — | — | — | — |
| Package | Severity | Title | Patched in | Advisory |
|---|---|---|---|---|
| (none found) | — | — | — | — |
License summary
License summary
| License | Count | Packages |
|---|---|---|
| MIT | 45 | react, react-dom, ... |
| Apache-2.0 | 3 | ... |
| License | Count | Packages |
|---|---|---|
| MIT | 45 | react, react-dom, ... |
| Apache-2.0 | 3 | ... |
Supply-chain flags
Supply-chain flags
| Package | Risk | Details |
|---|---|---|
| (none found) | — | — |
---| Package | Risk | Details |
|---|---|---|
| (none found) | — | — |
---Step 8 — Report remaining issues
步骤8 — 报告剩余问题
Summarize what was fixed and what remains:
总结已修复的内容和剩余问题:
Fixed
已修复
| Category | Count | Details |
|---|---|---|
| Packages updated | N | list of packages and version changes |
| CVEs resolved | N | list of CVEs fixed |
| Deprecated deps replaced | N | old package -> new package |
| License issues resolved | N | old package -> new package |
| 类别 | 数量 | 详情 |
|---|---|---|
| 已更新包 | N | 包列表及版本变更 |
| 已解决CVE | N | 已修复的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数量、已解决的问题数量,以及需要应用开发者手动处理的剩余项。