From hypervibe
Audits Next.js projects for RGPD compliance by scanning code, env vars, and dependencies to detect third-party data processors and compare with a privacy policy registry.
How this skill is triggered — by the user, by Claude, or both
Slash command
/hypervibe:rgpd-auditThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
- Detect the user's language from their messages and ALWAYS reply in that language (default: English). This applies to every user-facing message: questions, progress, confirmations, summaries, errors.
You will audit the project's RGPD compliance: detecting the third-party subprocessors actually used, comparing them with the registry, generating/synchronizing the privacy policy page, and linking it from the legal notices.
Announce each major block clearly.
Verify that you are at the root of a Next.js project:
test -f package.json || test -f apps/web/package.json && echo OK || echo "Not a Next.js project"
If the output is not OK, tell the user that /rgpd-audit must be run from the root of a project and stop.
Run the bundled script:
node "${CLAUDE_SKILL_DIR}/../../scripts/rgpd-audit.mjs"
The script returns a JSON object with:
webRoot - root of the code (apps/web for monorepos, root otherwise)registryPath - path of the registry src/lib/subprocessors.jsonregistryExists - booleanpolicyPagePath - path of the policy page if found, otherwise nullmentionsLegalesPath - path of the legal notices page if foundregistryKeys - keys present in the registrydetectedKeys - keys detected in the codedetected - object { key: true } for each detected subprocessorevidence - for each detected key, the evidence (package, env var, or source pattern)missing - keys detected BUT absent from the registry (to add)stale - keys present in the registry BUT no longer detected (to remove or justify)Capture the output. You will reason about it in the following Steps.
Present the diagnosis clearly. Format:
🔍 RGPD audit
Subprocessors detected in the code (X):
<key>-- …
State of the
subprocessors.jsonregistry:
- ✅ Present: entries
- ❌ Absent (never initialized)
Privacy policy page:
- ✅ Found:
<path>- ❌ Missing
Registry vs code diff:
- ❌ Missing from the registry:
<missing keys>(to add)- ⚠️ Stale in the registry:
<stale keys>(to remove if truly no longer used)- ✅ Everything is aligned (if missing.length === 0 && stale.length === 0)
Ask the user which actions to run, as a menu:
Would you like to:
- Synchronize the registry (add
missing, removestale)- Generate / refresh the page of the privacy policy
- Update the legal notices to point to the privacy policy
- Do everything (1 + 2 + 3)
- Exit without changing anything
For each key in missing, call the _update-privacy-policy helper:
node "${CLAUDE_SKILL_DIR}/../../scripts/update-privacy-policy.mjs" --add <key>
You can pass several --add in a single call.
For each key in stale, ask the user before removing:
The subprocessor
brevois in the registry but no longer detected in the code. Remove it? (y/N)
If yes:
node "${CLAUDE_SKILL_DIR}/../../scripts/update-privacy-policy.mjs" --remove <key>
If the detected key is not in the helper's catalog (rare - it would mean we invented a new subprocessor), the helper rejects with an error. In that case, alert the user - the catalog must be extended in scripts/update-privacy-policy.mjs on the plugin side.
policyPagePath === null (no page)Create the page from the template. The template to use depends on the project's i18n state:
src/i18n/routing.ts exists (multilingual project) → use ${CLAUDE_SKILL_DIR}/../../templates/privacy-policy/i18n.tsx, and then run node ${CLAUDE_SKILL_DIR}/../../scripts/_i18n-merge-messages.mjs --web-dir <web-root> --feature privacy-policy to merge the privacy.* keys into the messages/<locale>.json files.${CLAUDE_SKILL_DIR}/../../templates/privacy-policy/plain.tsx.Substitute in the template:
{{PROJECT_NAME}} (read the web-root's package.json){{LAST_UPDATED}} (today's date, format YYYY-MM-DD)Page location:
src/app/[locale]/ exists → src/app/[locale]/politique-de-confidentialite/page.tsxsrc/app/politique-de-confidentialite/page.tsxCreate the folder then write the file. Verify that the page does import ~/lib/subprocessors. If the ~/ alias is not configured in the project (rare), replace it with the appropriate relative path.
policyPagePath !== null (the page already exists)Ask the user:
A privacy policy page already exists at
<path>. You can:
- Keep it as is - the registry is updated but the page is not modified
- Replace it with the data-driven template (the current page will be overwritten - useful if the existing page is outdated, hand-written, or out of sync)
If the user chooses 2, make a backup first:
cp <policyPagePath> <policyPagePath>.backup
Then regenerate from the template.
If mentionsLegalesPath !== null, open the page and verify that it contains a link to /politique-de-confidentialite. Otherwise, add a mention in the "Données personnelles et RGPD" section (or create it if absent):
<p>
Pour le détail complet du traitement de vos données et la liste de nos sous-traitants,
consultez notre <Link href="/politique-de-confidentialite">politique de confidentialité</Link>.
</p>
If the user has a very detailed hand-written policy (the Hypervibe case), do not touch it in this skill - that is a separate refactor. Mention it in the summary.
If you touched one or more .tsx files, do the global UTF-8 self-check:
node -e "
const fs = require('node:fs');
for (const f of process.argv.slice(1)) {
const c = fs.readFileSync(f, 'utf8');
const m = c.match(/\\\\u[0-9a-fA-F]{4}/g);
if (m) { console.log(f, ':', m.length, 'escapes'); process.exit(1); }
}
console.log('UTF-8 OK');
" <files-touched>
If Unicode escapes are reported, fix them with the quick recovery script documented in the global CLAUDE.md (section "Règle prioritaire UTF-8").
Re-run the script:
node "${CLAUDE_SKILL_DIR}/../../scripts/rgpd-audit.mjs" --pretty
Present the output to the user. Everything should be ✅ aligned.
Present a short recap:
✅ RGPD audit complete
- Registry: documented subprocessors
- Policy page:
<path>(created / refreshed / unchanged depending on the case)- Legal notices: (updated to point to the policy / already up to date)
To do manually:
- Replace
[email protected]in the page with your real contact address- Check the legal content of sections 5 (rights) and 6 (cookies) - the template provides standard wording, but your case may require adjustments (minors vs adults, health data, etc.)
- If you added an unusual subprocessor not covered by the catalog, extend
scripts/update-privacy-policy.mjson the Hypervibe plugin side
@vercel/analytics installed but never imported in the layout), inform the user - they can pnpm remove the dependency, or you can extract the key from the registry via --remove._update-privacy-policy helper rejects unknown keys. This is intentional, to avoid inventing legal data. If a project uses an exotic service (Mailjet, OVH Object Storage, …), extend the catalog in the plugin's scripts/update-privacy-policy.mjs with the correct legal info (legal name, registered office address, legal basis, mechanism for transfers outside the EU where applicable).npx claudepluginhub flavien-ia/hypervibe-harness --plugin hypervibeScans repositories for personal data collection, classifies sensitivity under GDPR, determines applicability, and reports required roles, obligations, and remediation.
Audits code, schemas, and IaC for GDPR compliance, producing a structured findings report with article citations, severity, confidence, and recommended fixes. Flags evidence gaps and includes a processing map.
Audits web applications and architectures for GDPR, CCPA compliance, checking consent, cookie banners, data minimization, storage, deletion, export, and policy alignment.