env-drift
Part of shipsafe — offline deploy-safety skills. Every script is stdlib-only Python 3.8+; nothing leaves the machine.
python3 scripts/env_drift.py <project_root> [--json]
Reports four classes:
- MISSING — read in code, documented nowhere; a fresh deploy WILL fail on these. Highest priority.
- UNDOCUMENTED — in local .env but not .env.example; the deploy platform and teammates can't reproduce the environment.
- UNUSED — declared but never read; dead config or a typo'd name (a typo shows up as one UNUSED + one MISSING pair — point this out when you see it).
- CLIENT_LEAK — secret-named vars with NEXT_PUBLIC_/VITE_/etc. prefixes. These are bundled into public JavaScript. Treat as critical; the secret must be rotated and moved server-side.
- HARDCODED_URL —
http://localhost:*baked into code (test files exempt). Works in dev, dead in production; the fix is an env var or relative path. - SERVER_ENV_IN_CLIENT — non-public
process.env.Xread inside a'use client'component. In the browser it'sundefined(silent breakage), and renaming it to NEXT_PUBLIC_* is only acceptable when it is genuinely not a secret.
Detects references in JS/TS (process.env, import.meta.env), Python (os.environ, os.getenv), and Deno. Runtime-provided vars (NODE_ENV, VERCEL_URL...) are excluded automatically.
After running: fix MISSING by adding the vars to the platform dashboard AND .env.example, and remind the user that platform env changes require a redeploy to take effect.
Exit codes: 0 clean, 1 findings.
All paths below are relative to this skill's directory (env-drift/).