Skip to content

Scripts API Referenz: Node.js-Skript-Schnittstelle

Was Sie lernen werden

  • Vollständiges Verständnis der Scripts API von Everything Claude Code
  • Verwendung von Plattformerkennung und plattformübergreifenden Hilfsfunktionen
  • Konfiguration und Nutzung der automatischen Paketmanager-Erkennung
  • Erstellung benutzerdefinierter Hook-Skripte zur Erweiterung der Automatisierung
  • Debugging und Anpassung bestehender Skript-Implementierungen

Ihre aktuelle Herausforderung

Sie wissen bereits, dass Everything Claude Code viele Automatisierungsskripte enthält, stoßen aber auf folgende Fragen:

  • "Welche APIs bieten diese Node.js-Skripte konkret?"
  • "Wie kann ich Hook-Skripte anpassen?"
  • "Welche Priorität hat die Paketmanager-Erkennung?"
  • "Wie erreiche ich plattformübergreifende Kompatibilität in Skripten?"

Dieses Tutorial gibt Ihnen eine vollständige Scripts API Referenz.

Kernkonzept

Das Skriptsystem von Everything Claude Code gliedert sich in zwei Kategorien:

  1. Gemeinsame Bibliotheken (scripts/lib/) - Bieten plattformübergreifende Funktionen und APIs
  2. Hook-Skripte (scripts/hooks/) - Automatisierungslogik, die bei bestimmten Ereignissen ausgelöst wird

Alle Skripte unterstützen Windows, macOS und Linux und sind mit nativen Node.js-Modulen implementiert.

Skriptstruktur

scripts/
├── lib/
│   ├── utils.js              # Allgemeine Hilfsfunktionen
│   └── package-manager.js    # Paketmanager-Erkennung
├── hooks/
│   ├── session-start.js       # SessionStart Hook
│   ├── session-end.js         # SessionEnd Hook
│   ├── pre-compact.js        # PreCompact Hook
│   ├── suggest-compact.js     # PreToolUse Hook
│   └── evaluate-session.js   # Stop Hook
└── setup-package-manager.js   # Paketmanager-Setup-Skript

lib/utils.js - Allgemeine Hilfsfunktionen

Dieses Modul bietet plattformübergreifende Hilfsfunktionen, einschließlich Plattformerkennung, Dateioperationen und Systembefehle.

Plattformerkennung

javascript
const {
  isWindows,
  isMacOS,
  isLinux
} = require('./lib/utils');
FunktionTypRückgabewertBeschreibung
isWindowsbooleantrue/falseOb die aktuelle Plattform Windows ist
isMacOSbooleantrue/falseOb die aktuelle Plattform macOS ist
isLinuxbooleantrue/falseOb die aktuelle Plattform Linux ist

Implementierungsprinzip: Basiert auf process.platform

javascript
const isWindows = process.platform === 'win32';
const isMacOS = process.platform === 'darwin';
const isLinux = process.platform === 'linux';

Verzeichnis-Hilfsfunktionen

javascript
const {
  getHomeDir,
  getClaudeDir,
  getSessionsDir,
  getLearnedSkillsDir,
  getTempDir,
  ensureDir
} = require('./lib/utils');

getHomeDir()

Gibt das Benutzer-Home-Verzeichnis zurück (plattformübergreifend kompatibel)

Rückgabewert: string - Pfad zum Home-Verzeichnis

Beispiel:

javascript
const homeDir = getHomeDir();
// Windows: C:\Users\username
// macOS: /Users/username
// Linux: /home/username

getClaudeDir()

Gibt das Claude Code Konfigurationsverzeichnis zurück

Rückgabewert: string - Pfad zum ~/.claude Verzeichnis

Beispiel:

javascript
const claudeDir = getClaudeDir();
// /Users/username/.claude

getSessionsDir()

Gibt das Sitzungsdatei-Verzeichnis zurück

Rückgabewert: string - Pfad zum ~/.claude/sessions Verzeichnis

Beispiel:

javascript
const sessionsDir = getSessionsDir();
// /Users/username/.claude/sessions

getLearnedSkillsDir()

Gibt das Verzeichnis für erlernte Skills zurück

Rückgabewert: string - Pfad zum ~/.claude/skills/learned Verzeichnis

Beispiel:

javascript
const learnedDir = getLearnedSkillsDir();
// /Users/username/.claude/skills/learned

getTempDir()

Gibt das System-Temp-Verzeichnis zurück (plattformübergreifend)

Rückgabewert: string - Pfad zum Temp-Verzeichnis

Beispiel:

javascript
const tempDir = getTempDir();
// macOS: /var/folders/...
// Linux: /tmp
// Windows: C:\Users\username\AppData\Local\Temp

ensureDir(dirPath)

Stellt sicher, dass ein Verzeichnis existiert; erstellt es, falls nicht vorhanden

Parameter:

  • dirPath (string) - Verzeichnispfad

Rückgabewert: string - Verzeichnispfad

Beispiel:

javascript
const dir = ensureDir('/path/to/new/dir');
// Falls das Verzeichnis nicht existiert, wird es rekursiv erstellt

Datum/Zeit-Hilfsfunktionen

javascript
const {
  getDateString,
  getTimeString,
  getDateTimeString
} = require('./lib/utils');

getDateString()

Gibt das aktuelle Datum zurück (Format: YYYY-MM-DD)

Rückgabewert: string - Datumsstring

Beispiel:

javascript
const date = getDateString();
// '2026-01-25'

getTimeString()

Gibt die aktuelle Uhrzeit zurück (Format: HH:MM)

Rückgabewert: string - Zeitstring

Beispiel:

javascript
const time = getTimeString();
// '14:30'

getDateTimeString()

Gibt aktuelles Datum und Uhrzeit zurück (Format: YYYY-MM-DD HH:MM:SS)

Rückgabewert: string - Datum-Zeit-String

Beispiel:

javascript
const datetime = getDateTimeString();
// '2026-01-25 14:30:45'

Dateioperationen

javascript
const {
  findFiles,
  readFile,
  writeFile,
  appendFile,
  replaceInFile,
  countInFile,
  grepFile
} = require('./lib/utils');

findFiles(dir, pattern, options)

Findet Dateien in einem Verzeichnis, die einem Muster entsprechen (plattformübergreifende Alternative zu find)

Parameter:

  • dir (string) - Zu durchsuchendes Verzeichnis
  • pattern (string) - Dateimuster (z.B. "*.tmp", "*.md")
  • options (object, optional) - Optionen
    • maxAge (number) - Maximales Dateialter in Tagen
    • recursive (boolean) - Ob rekursiv gesucht werden soll

Rückgabewert: Array<{path: string, mtime: number}> - Liste der übereinstimmenden Dateien, sortiert nach Änderungszeit (absteigend)

Beispiel:

javascript
// Finde .tmp-Dateien der letzten 7 Tage
const recentFiles = findFiles('/tmp', '*.tmp', { maxAge: 7 });
// [{ path: '/tmp/session.tmp', mtime: 1737804000000 }]

// Rekursiv alle .md-Dateien finden
const allMdFiles = findFiles('./docs', '*.md', { recursive: true });

Plattformübergreifende Kompatibilität

Diese Funktion bietet plattformübergreifende Dateisuche ohne Abhängigkeit vom Unix find-Befehl und funktioniert daher auch unter Windows.

readFile(filePath)

Liest eine Textdatei sicher

Parameter:

  • filePath (string) - Dateipfad

Rückgabewert: string | null - Dateiinhalt, bei Fehler null

Beispiel:

javascript
const content = readFile('/path/to/file.txt');
if (content !== null) {
  console.log(content);
}

writeFile(filePath, content)

Schreibt eine Textdatei

Parameter:

  • filePath (string) - Dateipfad
  • content (string) - Dateiinhalt

Rückgabewert: keiner

Beispiel:

javascript
writeFile('/path/to/file.txt', 'Hello, World!');
// Falls das Verzeichnis nicht existiert, wird es automatisch erstellt

appendFile(filePath, content)

Hängt Inhalt an eine Textdatei an

Parameter:

  • filePath (string) - Dateipfad
  • content (string) - Anzuhängender Inhalt

Rückgabewert: keiner

Beispiel:

javascript
appendFile('/path/to/log.txt', 'New log entry\n');

replaceInFile(filePath, search, replace)

Ersetzt Text in einer Datei (plattformübergreifende Alternative zu sed)

Parameter:

  • filePath (string) - Dateipfad
  • search (string | RegExp) - Zu suchender Inhalt
  • replace (string) - Ersetzungsinhalt

Rückgabewert: boolean - Ob die Ersetzung erfolgreich war

Beispiel:

javascript
const success = replaceInFile('/path/to/file.txt', 'old text', 'new text');
// true: Ersetzung erfolgreich
// false: Datei existiert nicht oder Lesefehler

countInFile(filePath, pattern)

Zählt Vorkommen eines Musters in einer Datei

Parameter:

  • filePath (string) - Dateipfad
  • pattern (string | RegExp) - Zu zählendes Muster

Rückgabewert: number - Anzahl der Übereinstimmungen

Beispiel:

javascript
const count = countInFile('/path/to/file.txt', /error/g);
// 5

grepFile(filePath, pattern)

Sucht ein Muster in einer Datei und gibt übereinstimmende Zeilen mit Zeilennummern zurück

Parameter:

  • filePath (string) - Dateipfad
  • pattern (string | RegExp) - Zu suchendes Muster

Rückgabewert: Array<{lineNumber: number, content: string}> - Liste der übereinstimmenden Zeilen

Beispiel:

javascript
const matches = grepFile('/path/to/file.txt', /function\s+\w+/);
// [{ lineNumber: 10, content: 'function test() {...}' }]

Hook I/O

javascript
const {
  readStdinJson,
  log,
  output
} = require('./lib/utils');

readStdinJson()

Liest JSON-Daten von der Standardeingabe (für Hook-Eingaben)

Rückgabewert: Promise<object> - Geparstes JSON-Objekt

Beispiel:

javascript
async function main() {
  const hookInput = await readStdinJson();
  console.log(hookInput.tool);
  console.log(hookInput.tool_input);
}

Hook-Eingabeformat

Das von Claude Code an Hooks übergebene Eingabeformat ist:

json
{
  "tool": "Bash",
  "tool_input": { "command": "npm run dev" },
  "tool_output": { "output": "..." }
}

log(message)

Protokolliert eine Nachricht nach stderr (für Benutzer sichtbar)

Parameter:

  • message (string) - Log-Nachricht

Rückgabewert: keiner

Beispiel:

javascript
log('[SessionStart] Loading context...');
// Ausgabe nach stderr, für Benutzer in Claude Code sichtbar

output(data)

Gibt Daten nach stdout aus (Rückgabe an Claude Code)

Parameter:

  • data (object | string) - Auszugebende Daten

Rückgabewert: keiner

Beispiel:

javascript
// Objekt ausgeben (automatische JSON-Serialisierung)
output({ success: true, message: 'Completed' });

// String ausgeben
output('Hello, Claude');

Systembefehle

javascript
const {
  commandExists,
  runCommand,
  isGitRepo,
  getGitModifiedFiles
} = require('./lib/utils');

commandExists(cmd)

Prüft, ob ein Befehl im PATH existiert

Parameter:

  • cmd (string) - Befehlsname

Rückgabewert: boolean - Ob der Befehl existiert

Beispiel:

javascript
if (commandExists('pnpm')) {
  console.log('pnpm is available');
}

Sicherheitsvalidierung

Diese Funktion validiert den Befehlsnamen mit einem regulären Ausdruck und erlaubt nur Buchstaben, Zahlen, Unterstriche, Punkte und Bindestriche, um Command Injection zu verhindern.

runCommand(cmd, options)

Führt einen Befehl aus und gibt die Ausgabe zurück

Parameter:

  • cmd (string) - Auszuführender Befehl (muss ein vertrauenswürdiger, hartcodierter Befehl sein)
  • options (object, optional) - execSync-Optionen

Rückgabewert: {success: boolean, output: string} - Ausführungsergebnis

Beispiel:

javascript
const result = runCommand('git status');
if (result.success) {
  console.log(result.output);
} else {
  console.error(result.output);
}

Sicherheitswarnung

Verwenden Sie diese Funktion nur für vertrauenswürdige, hartcodierte Befehle. Übergeben Sie niemals benutzergesteuerte Eingaben direkt an diese Funktion. Für Benutzereingaben verwenden Sie spawnSync mit einem Argument-Array.

isGitRepo()

Prüft, ob das aktuelle Verzeichnis ein Git-Repository ist

Rückgabewert: boolean - Ob es ein Git-Repository ist

Beispiel:

javascript
if (isGitRepo()) {
  console.log('This is a Git repository');
}

getGitModifiedFiles(patterns = [])

Gibt eine Liste der von Git geänderten Dateien zurück

Parameter:

  • patterns (string[], optional) - Array von Filtermustern

Rückgabewert: string[] - Liste der geänderten Dateipfade

Beispiel:

javascript
// Alle geänderten Dateien abrufen
const allModified = getGitModifiedFiles();

// Nur TypeScript-Dateien abrufen
const tsModified = getGitModifiedFiles([/\.ts$/, /\.tsx$/]);

lib/package-manager.js - Paketmanager-API

Dieses Modul bietet APIs zur automatischen Erkennung und Konfiguration von Paketmanagern.

Unterstützte Paketmanager

javascript
const { PACKAGE_MANAGERS } = require('./lib/package-manager');
PaketmanagerLock-DateiInstall-BefehlRun-BefehlExec-Befehl
npmpackage-lock.jsonnpm installnpm runnpx
pnpmpnpm-lock.yamlpnpm installpnpmpnpm dlx
yarnyarn.lockyarnyarnyarn dlx
bunbun.lockbbun installbun runbunx

Erkennungspriorität

javascript
const { DETECTION_PRIORITY } = require('./lib/package-manager');

// ['pnpm', 'bun', 'yarn', 'npm']

Die Paketmanager-Erkennung erfolgt nach folgender Priorität (von hoch nach niedrig):

  1. Umgebungsvariable CLAUDE_PACKAGE_MANAGER
  2. Projektebene-Konfiguration .claude/package-manager.json
  3. packageManager-Feld in package.json
  4. Lock-Datei-Erkennung
  5. Globale Benutzereinstellung ~/.claude/package-manager.json
  6. Rückgabe des ersten verfügbaren Paketmanagers nach Priorität

Kernfunktionen

javascript
const {
  getPackageManager,
  setPreferredPackageManager,
  setProjectPackageManager,
  getAvailablePackageManagers,
  getRunCommand,
  getExecCommand,
  getCommandPattern
} = require('./lib/package-manager');

getPackageManager(options = {})

Ermittelt den für das aktuelle Projekt zu verwendenden Paketmanager

Parameter:

  • options (object, optional)
    • projectDir (string) - Projektverzeichnispfad, Standard ist process.cwd()
    • fallbackOrder (string[]) - Fallback-Reihenfolge, Standard ist ['pnpm', 'bun', 'yarn', 'npm']

Rückgabewert: {name: string, config: object, source: string}

  • name: Name des Paketmanagers
  • config: Konfigurationsobjekt des Paketmanagers
  • source: Erkennungsquelle ('environment' | 'project-config' | 'package.json' | 'lock-file' | 'global-config' | 'fallback' | 'default')

Beispiel:

javascript
const pm = getPackageManager();
console.log(pm.name);        // 'pnpm'
console.log(pm.source);      // 'lock-file'
console.log(pm.config);      // { name: 'pnpm', lockFile: 'pnpm-lock.yaml', ... }

setPreferredPackageManager(pmName)

Setzt die globale Paketmanager-Präferenz

Parameter:

  • pmName (string) - Name des Paketmanagers (npm | pnpm | yarn | bun)

Rückgabewert: object - Konfigurationsobjekt

Beispiel:

javascript
const config = setPreferredPackageManager('pnpm');
// Gespeichert in ~/.claude/package-manager.json
// { packageManager: 'pnpm', setAt: '2026-01-25T...' }

setProjectPackageManager(pmName, projectDir)

Setzt die projektspezifische Paketmanager-Präferenz

Parameter:

  • pmName (string) - Name des Paketmanagers
  • projectDir (string) - Projektverzeichnispfad, Standard ist process.cwd()

Rückgabewert: object - Konfigurationsobjekt

Beispiel:

javascript
const config = setProjectPackageManager('bun', '/path/to/project');
// Gespeichert in /path/to/project/.claude/package-manager.json
// { packageManager: 'bun', setAt: '2026-01-25T...' }

getAvailablePackageManagers()

Gibt eine Liste der auf dem System installierten Paketmanager zurück

Rückgabewert: string[] - Array der verfügbaren Paketmanager-Namen

Beispiel:

javascript
const available = getAvailablePackageManagers();
// ['pnpm', 'npm']  // Falls nur pnpm und npm installiert sind

getRunCommand(script, options = {})

Gibt den Befehl zum Ausführen eines Skripts zurück

Parameter:

  • script (string) - Skriptname (z.B. "dev", "build", "test")
  • options (object, optional) - Projektverzeichnis-Optionen

Rückgabewert: string - Vollständiger Ausführungsbefehl

Beispiel:

javascript
const devCmd = getRunCommand('dev');
// 'npm run dev'  oder  'pnpm dev'  oder  'bun run dev'

const buildCmd = getRunCommand('build');
// 'npm run build'  oder  'pnpm build'

Eingebaute Skript-Shortcuts:

  • install → gibt installCmd zurück
  • test → gibt testCmd zurück
  • build → gibt buildCmd zurück
  • dev → gibt devCmd zurück
  • Andere → gibt ${runCmd} ${script} zurück

getExecCommand(binary, args = '', options = {})

Gibt den Befehl zum Ausführen einer Paket-Binärdatei zurück

Parameter:

  • binary (string) - Name der Binärdatei (z.B. "prettier", "eslint")
  • args (string, optional) - Argument-String
  • options (object, optional) - Projektverzeichnis-Optionen

Rückgabewert: string - Vollständiger Ausführungsbefehl

Beispiel:

javascript
const cmd = getExecCommand('prettier', '--write file.js');
// 'npx prettier --write file.js'  oder  'pnpm dlx prettier --write file.js'

const eslintCmd = getExecCommand('eslint');
// 'npx eslint'  oder  'bunx eslint'

getCommandPattern(action)

Generiert ein Regex-Muster, das alle Paketmanager-Befehle abdeckt

Parameter:

  • action (string) - Aktionstyp ('dev' | 'install' | 'test' | 'build' oder benutzerdefinierter Skriptname)

Rückgabewert: string - Regex-Muster

Beispiel:

javascript
const devPattern = getCommandPattern('dev');
// (npm run dev|pnpm( run)? dev|yarn dev|bun run dev)

const installPattern = getCommandPattern('install');
// (npm install|pnpm install|yarn( install)?|bun install)

setup-package-manager.js - Paketmanager-Setup-Skript

Dies ist ein ausführbares CLI-Skript zur interaktiven Konfiguration der Paketmanager-Präferenz.

Verwendung

bash
# Erkennen und aktuellen Paketmanager anzeigen
node scripts/setup-package-manager.js --detect

# Globale Präferenz setzen
node scripts/setup-package-manager.js --global pnpm

# Projektpräferenz setzen
node scripts/setup-package-manager.js --project bun

# Verfügbare Paketmanager auflisten
node scripts/setup-package-manager.js --list

# Hilfe anzeigen
node scripts/setup-package-manager.js --help

Kommandozeilenparameter

ParameterBeschreibung
--detectErkennt und zeigt den aktuellen Paketmanager an
--global <pm>Setzt die globale Präferenz
--project <pm>Setzt die Projektpräferenz
--listListet alle verfügbaren Paketmanager auf
--helpZeigt Hilfeinformationen an

Ausgabebeispiel

--detect Ausgabe:

=== Package Manager Detection ===

Current selection:
  Package Manager: pnpm
  Source: lock-file

Detection results:
  From package.json: not specified
  From lock file: pnpm
  Environment var: not set

Available package managers:
  ✓ pnpm (current)
  ✓ npm
  ✗ yarn
  ✗ bun

Commands:
  Install: pnpm install
  Run script: pnpm [script-name]
  Execute binary: pnpm dlx [binary-name]

Hook-Skripte im Detail

session-start.js - Sitzungsstart-Hook

Hook-Typ: SessionStart

Auslösezeitpunkt: Beim Start einer Claude Code Sitzung

Funktionen:

  • Prüft aktuelle Sitzungsdateien (letzte 7 Tage)
  • Prüft erlernte Skill-Dateien
  • Erkennt und meldet den Paketmanager
  • Zeigt Auswahlhinweis an, wenn der Paketmanager per Fallback erkannt wurde

Ausgabebeispiel:

[SessionStart] Found 3 recent session(s)
[SessionStart] Latest: /Users/username/.claude/sessions/2026-01-25-session.tmp
[SessionStart] 5 learned skill(s) available in /Users/username/.claude/skills/learned
[SessionStart] Package manager: pnpm (lock-file)

session-end.js - Sitzungsende-Hook

Hook-Typ: SessionEnd

Auslösezeitpunkt: Beim Beenden einer Claude Code Sitzung

Funktionen:

  • Erstellt oder aktualisiert die Sitzungsdatei des Tages
  • Zeichnet Start- und Endzeit der Sitzung auf
  • Stellt Sitzungsstatus-Vorlage bereit (Abgeschlossen, In Bearbeitung, Notizen)

Sitzungsdatei-Vorlage:

markdown
# Session: 2026-01-25
**Date:** 2026-01-25
**Started:** 14:30
**Last Updated:** 15:45

---

## Current State

[Session context goes here]

### Completed
- [ ]

### In Progress
- [ ]

### Notes for Next Session
-

### Context to Load

[relevant files]

pre-compact.js - Pre-Compact-Hook

Hook-Typ: PreCompact

Auslösezeitpunkt: Vor der Kontextkomprimierung durch Claude Code

Funktionen:

  • Protokolliert Komprimierungsereignisse in einer Logdatei
  • Markiert den Komprimierungszeitpunkt in der aktiven Sitzungsdatei

Ausgabebeispiel:

[PreCompact] State saved before compaction

Logdatei: ~/.claude/sessions/compaction-log.txt

suggest-compact.js - Komprimierungsvorschlags-Hook

Hook-Typ: PreToolUse

Auslösezeitpunkt: Nach jedem Tool-Aufruf (typischerweise Edit oder Write)

Funktionen:

  • Verfolgt die Anzahl der Tool-Aufrufe
  • Schlägt manuelle Komprimierung vor, wenn der Schwellenwert erreicht ist
  • Gibt regelmäßige Hinweise zum Komprimierungszeitpunkt

Umgebungsvariablen:

  • COMPACT_THRESHOLD - Komprimierungsschwellenwert (Standard: 50)
  • CLAUDE_SESSION_ID - Sitzungs-ID

Ausgabebeispiel:

[StrategicCompact] 50 tool calls reached - consider /compact if transitioning phases
[StrategicCompact] 75 tool calls - good checkpoint for /compact if context is stale

Manuelle vs. automatische Komprimierung

Warum wird manuelle Komprimierung empfohlen?

  • Automatische Komprimierung wird oft mitten in einer Aufgabe ausgelöst und führt zu Kontextverlust
  • Manuelle Komprimierung kann wichtige Informationen beim Wechsel logischer Phasen bewahren
  • Komprimierungszeitpunkte: Ende der Explorationsphase, Beginn der Ausführungsphase, Abschluss von Meilensteinen

evaluate-session.js - Sitzungsbewertungs-Hook

Hook-Typ: Stop

Auslösezeitpunkt: Am Ende jeder KI-Antwort

Funktionen:

  • Prüft die Sitzungslänge (basierend auf der Anzahl der Benutzernachrichten)
  • Bewertet, ob die Sitzung extrahierbare Muster enthält
  • Fordert zum Speichern erlernter Skills auf

Konfigurationsdatei: skills/continuous-learning/config.json

Umgebungsvariablen:

  • CLAUDE_TRANSCRIPT_PATH - Pfad zur Sitzungsaufzeichnungsdatei

Ausgabebeispiel:

[ContinuousLearning] Session has 25 messages - evaluate for extractable patterns
[ContinuousLearning] Save learned skills to: /Users/username/.claude/skills/learned

Warum Stop statt UserPromptSubmit?

  • Stop wird nur einmal pro Antwort ausgelöst (leichtgewichtig)
  • UserPromptSubmit wird bei jeder Nachricht ausgelöst (hohe Latenz)

Benutzerdefinierte Hook-Skripte

Erstellen eines benutzerdefinierten Hooks

  1. Skript im Verzeichnis scripts/hooks/ erstellen
javascript
#!/usr/bin/env node
/**
 * Custom Hook - Your Description
 *
 * Cross-platform (Windows, macOS, Linux)
 */

const { log, output } = require('../lib/utils');

async function main() {
  // Ihre Logik
  log('[CustomHook] Processing...');
  
  // Ergebnis ausgeben
  output({ success: true });
  
  process.exit(0);
}

main().catch(err => {
  console.error('[CustomHook] Error:', err.message);
  process.exit(0); // Sitzung nicht blockieren
});
  1. Hook in hooks/hooks.json konfigurieren
json
{
  "matcher": "tool == \"Bash\" && tool_input.command matches \"your_pattern\"",
  "hooks": [
    {
      "type": "command",
      "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/hooks/your-hook.js\""
    }
  ],
  "description": "Your custom hook description"
}
  1. Hook testen
bash
# Bedingung in Claude Code auslösen und Ausgabe prüfen

Best Practices

1. Fehlerbehandlung

javascript
main().catch(err => {
  console.error('[HookName] Error:', err.message);
  process.exit(0); // Sitzung nicht blockieren
});

2. Bibliotheksfunktionen verwenden

javascript
const {
  log,
  readFile,
  writeFile,
  ensureDir
} = require('../lib/utils');

3. Plattformübergreifende Pfade

javascript
const path = require('path');
const filePath = path.join(getHomeDir(), '.claude', 'config.json');

4. Umgebungsvariablen

javascript
const sessionId = process.env.CLAUDE_SESSION_ID || 'default';
const transcriptPath = process.env.CLAUDE_TRANSCRIPT_PATH;

Skripte testen

Hilfsfunktionen testen

javascript
const { findFiles, readFile, writeFile } = require('./lib/utils');

// Dateisuche testen
const files = findFiles('/tmp', '*.tmp', { maxAge: 7 });
console.log('Found files:', files);

// Datei lesen/schreiben testen
writeFile('/tmp/test.txt', 'Hello, World!');
const content = readFile('/tmp/test.txt');
console.log('Content:', content);

Paketmanager-Erkennung testen

javascript
const { getPackageManager, getRunCommand } = require('./lib/package-manager');

const pm = getPackageManager();
console.log('Package manager:', pm.name);
console.log('Source:', pm.source);
console.log('Dev command:', getRunCommand('dev'));

Hook-Skripte testen

bash
# Hook-Skript direkt ausführen (Umgebungsvariablen erforderlich)
CLAUDE_SESSION_ID=test CLAUDE_TRANSCRIPT_PATH=/tmp/transcript.json \
  node scripts/hooks/session-start.js

Debugging-Tipps

1. Log-Ausgabe verwenden

javascript
const { log } = require('../lib/utils');

log('[Debug] Current value:', value);

2. Fehler abfangen

javascript
try {
  // Potenziell fehlerhafter Code
} catch (err) {
  console.error('[Error]', err.message);
  console.error('[Stack]', err.stack);
}

3. Dateipfade verifizieren

javascript
const path = require('path');
const { existsSync } = require('fs');

const filePath = path.join(getHomeDir(), '.claude', 'config.json');
console.log('Config path:', filePath);
console.log('Exists:', existsSync(filePath));

4. Hook-Ausführungsprotokolle anzeigen

bash
# In Claude Code wird die stderr-Ausgabe des Hooks in der Antwort angezeigt
# Suchen Sie nach Protokollen mit dem Präfix [HookName]

Häufige Fragen

F1: Hook-Skript wird nicht ausgeführt?

Mögliche Ursachen:

  1. Matcher-Konfiguration in hooks/hooks.json ist fehlerhaft
  2. Skriptpfad ist falsch
  3. Skript hat keine Ausführungsberechtigung

Fehlerbehebungsschritte:

bash
# Skriptpfad prüfen
ls -la scripts/hooks/

# Skript manuell zum Testen ausführen
node scripts/hooks/session-start.js

# hooks.json-Syntax verifizieren
cat hooks/hooks.json | jq '.'

F2: Pfadfehler unter Windows?

Ursache: Windows verwendet Backslashes, während Unix Forward-Slashes verwendet

Lösung:

javascript
// ❌ Falsch: Hartcodierter Pfadtrenner
const path = 'C:\\Users\\username\\.claude';

// ✅ Richtig: path.join() verwenden
const path = require('path');
const claudePath = path.join(getHomeDir(), '.claude');

F3: Wie debugge ich Hook-Eingaben?

Methode: Hook-Eingabe in temporäre Datei schreiben

javascript
const { writeFileSync } = require('fs');
const path = require('path');

async function main() {
  const hookInput = await readStdinJson();
  
  // In Debug-Datei schreiben
  const debugPath = path.join(getTempDir(), 'hook-debug.json');
  writeFileSync(debugPath, JSON.stringify(hookInput, null, 2));
  
  console.error('[Debug] Input saved to:', debugPath);
}

Zusammenfassung

Dieses Tutorial hat die Scripts API von Everything Claude Code systematisch erklärt:

Kernmodule:

  • lib/utils.js: Plattformübergreifende Hilfsfunktionen (Plattformerkennung, Dateioperationen, Systembefehle)
  • lib/package-manager.js: Paketmanager-Erkennung und Konfigurations-API
  • setup-package-manager.js: CLI-Konfigurationstool

Hook-Skripte:

  • session-start.js: Lädt Kontext beim Sitzungsstart
  • session-end.js: Speichert Status beim Sitzungsende
  • pre-compact.js: Speichert Status vor der Komprimierung
  • suggest-compact.js: Schlägt manuelle Komprimierungszeitpunkte vor
  • evaluate-session.js: Bewertet Sitzung zur Musterextraktion

Best Practices:

  • Bibliotheksfunktionen für plattformübergreifende Kompatibilität verwenden
  • Hook-Skripte blockieren die Sitzung nicht (Exit-Code 0 bei Fehlern)
  • log() für Debug-Ausgaben verwenden
  • process.env zum Lesen von Umgebungsvariablen verwenden

Debugging-Tipps:

  • Skripte direkt zum Testen ausführen
  • Temporäre Dateien für Debug-Daten verwenden
  • Matcher-Konfiguration und Skriptpfade prüfen

Vorschau auf die nächste Lektion

In der nächsten Lektion lernen wir Test-Suite: Ausführung und Anpassung.

Sie werden lernen:

  • Wie man die Test-Suite ausführt
  • Wie man Unit-Tests für Hilfsfunktionen schreibt
  • Wie man Integrationstests für Hook-Skripte schreibt
  • Wie man benutzerdefinierte Testfälle hinzufügt

Anhang: Quellcode-Referenz

Klicken Sie hier, um die Quellcode-Positionen anzuzeigen

Aktualisiert: 2026-01-25

FunktionsmodulDateipfadZeilen
Allgemeine Hilfsfunktionenscripts/lib/utils.js1-384
Paketmanager-APIscripts/lib/package-manager.js1-391
Paketmanager-Setup-Skriptscripts/setup-package-manager.js1-207
SessionStart Hookscripts/hooks/session-start.js1-62
SessionEnd Hookscripts/hooks/session-end.js1-83
PreCompact Hookscripts/hooks/pre-compact.js1-49
Suggest Compact Hookscripts/hooks/suggest-compact.js1-61
Evaluate Session Hookscripts/hooks/evaluate-session.js1-79

Wichtige Konstanten:

  • DETECTION_PRIORITY = ['pnpm', 'bun', 'yarn', 'npm']: Paketmanager-Erkennungspriorität (scripts/lib/package-manager.js:57)
  • COMPACT_THRESHOLD: Komprimierungsvorschlags-Schwellenwert (Standard 50, über Umgebungsvariable überschreibbar)

Wichtige Funktionen:

  • getPackageManager(): Erkennt und wählt Paketmanager (scripts/lib/package-manager.js:157)
  • findFiles(): Plattformübergreifende Dateisuche (scripts/lib/utils.js:102)
  • readStdinJson(): Liest Hook-Eingabe (scripts/lib/utils.js:154)
  • commandExists(): Prüft, ob Befehl existiert (scripts/lib/utils.js:228)

Umgebungsvariablen:

  • CLAUDE_PACKAGE_MANAGER: Erzwingt bestimmten Paketmanager
  • CLAUDE_SESSION_ID: Sitzungs-ID
  • CLAUDE_TRANSCRIPT_PATH: Pfad zur Sitzungsaufzeichnungsdatei
  • COMPACT_THRESHOLD: Komprimierungsvorschlags-Schwellenwert

Plattformerkennung:

  • process.platform === 'win32': Windows
  • process.platform === 'darwin': macOS
  • process.platform === 'linux': Linux