Back to catalogue
WorkflowFileChanged· *.mjs|registry.json
Registry auto-sync
Triggers sync-hooks.mjs automatically after any .mjs hook file or registry.json change, keeping code_snippet, .claude/settings.json and .claude/hooks/ up to date without manual intervention.
Use cases
- Auto-sync settings.json after editing a hook in the catalogue
- Create missing .mjs scripts immediately after adding a new hook entry
Providers & tags
Claude Code
#automation#sync#registry#hooks
settings.json fragment
{
"hooks": {
"FileChanged": [
{
"matcher": "*.mjs|registry.json",
"hooks": [
{
"type": "command",
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/registry-auto-sync.mjs"
}
]
}
]
}
}Script · .claude/hooks/registry-auto-sync.mjs
#!/usr/bin/env node
// Resynchronise registry.json depuis les scripts dogfoodés après édition d'un
// hook .claude/hooks/*.mjs (ou du registre lui-même). (FileChanged *.mjs|registry.json)
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
const SELF = 'registry-auto-sync.mjs';
function defaultExec(projectDir) {
return execSync('node .claude/sync-hooks.mjs', {
timeout: 30_000,
cwd: projectDir,
encoding: 'utf8',
});
}
// Vrai si l'édition doit déclencher une resync (un hook .mjs ou le registre).
function shouldSync(filePath) {
if (!filePath) return false;
if (filePath.endsWith(`/${SELF}`)) return false; // évite de se resync soi-même
if (filePath.endsWith('registry/registry.json')) return true;
return /\.claude\/hooks\/[^/]+\.mjs$/.test(filePath);
}
export function run(input, { exec = defaultExec, projectDir = process.env.CLAUDE_PROJECT_DIR } = {}) {
// FileChanged: input.file_path | PostToolUse (legacy): input.tool_input?.file_path
const filePath = input.file_path ?? input.tool_input?.file_path ?? '';
if (!shouldSync(filePath) || !projectDir) return null;
try {
const out = exec(projectDir);
const summary = out.trim().split('\n').slice(-3).join(' | ');
return { message: `[registry-auto-sync] ${summary}` };
} catch (e) {
return { message: `[registry-auto-sync] échec sync : ${e.message}` };
}
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
if (result?.message) process.stderr.write(result.message + '\n');
}