commit-sentry
v0.1.14
Published
Zero-config git hooks + prettier + eslint + lint-staged + commit-time safeguards that survive Windows, CRLF, and fresh clones.
Maintainers
Readme
commit-sentry
Zero-config git hooks for your team. Install once, and every teammate — on Windows, macOS, or Linux — gets the same pre-commit, commit-msg, and pre-push behavior. No git config steps, no CRLF surprises, no "works on my machine".
What you get
- Hooks auto-wired on
npm install— no manualhusky install, no manualgit config core.hooksPath. prettierandlint-stagedauto-installed — staged files are formatted on every commit, zero config needed.pre-commit: two phases on every commit:- Phase 1 — rm-console (opt-in): set
CG_RM_CONSOLE=1(inline or in.env) and everyconsole.log/.warn/.debug/.infoin staged.js/.jsx/.ts/.tsxfiles is stripped, re-formatted with prettier, and re-staged before the commit lands — so the clean version is what git actually stores.console.erroris preserved. - Phase 2 — lint-staged: runs prettier (and ESLint after
setup-eslint) on staged files.
- Phase 1 — rm-console (opt-in): set
commit-msg: runs yourbuildscript and aborts if it fails. Skips silently when nobuildscript exists. Detects.next/tracefile locks on Windows and fails fast with a clear message.setup-eslintcommand: one command detects your framework (React+TS, React JS, TypeScript, plain JS) and scaffolds a full ESLint config + wires ESLint into lint-staged.- Monorepo / subfolder support: works whether your git root is the same folder as your install or a parent directory (e.g. git root at
/project, package installed in/project/frontend). - Shareable prettier / eslint / lint-staged configs you can extend.
- Dynamic
core.hooksPath: rename or relocate your project folder — still works. - CRLF auto-heal: fixes hook files checked out with Windows line endings so
bash: $'\r': command not foundnever happens. - Safe postinstall: soft-fails in non-git environments (Docker builds, CI, tarball unpacks) —
npm installnever breaks. - Easy bypass:
HUSKY=0orHUSKY_SKIP_BUILD=1for one-off commits.
Install
npm install --save-dev commit-sentryThat's it. The following happen automatically on install:
| What | Result |
|---|---|
| Git hooks | Installed into .husky/, core.hooksPath set |
| prettier | Installed as a dependency |
| lint-staged | Installed as a dependency |
| lint-staged.config.js | Created — runs prettier on staged files |
| Non-git environments | Detected and skipped silently (CI, Docker) |
If you're adding this to a repo that already has files in .husky/, they're preserved. Run npx commit-sentry update to overwrite them with the package defaults.
Monorepo / subfolder install
Works out of the box. If your git root is a parent of your install directory:
/project/ ← git root
frontend/ ← npm install commit-sentry runs here
package.json
node_modules/
.husky/ ← hooks installed here automaticallycore.hooksPath is set to frontend/.husky relative to the git root — no extra config needed.
ESLint setup (optional)
After installing, run one command to scaffold ESLint for your framework:
npx commit-sentry setup-eslintThis does everything in one shot:
- Detects your project type (React + TypeScript, React JS, TypeScript, plain JS).
- Installs the required ESLint plugins via
npm install --save-dev. - Creates
eslint.config.mjswith sensible defaults for your framework. - Updates
lint-staged.config.jsto run ESLint + prettier on every commit.
npx commit-sentry setup-eslint --force # overwrite an existing ESLint configNote: If you have a custom
lint-staged.config.js, it won't be overwritten — you'll see a message telling you to add ESLint manually.
What gets installed per framework
| Framework | Detected by | ESLint plugins installed |
|---|---|---|
| React + TypeScript | react + typescript in deps | typescript-eslint, eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-jsx-a11y |
| React (JavaScript) | react in deps | eslint-plugin-react, eslint-plugin-react-hooks, eslint-plugin-jsx-a11y |
| TypeScript (Node.js) | typescript in deps or tsconfig.json | typescript-eslint |
| Plain JavaScript | fallback | @eslint/js, eslint-config-prettier |
| Angular | @angular/core in deps | Guided to ng add @angular-eslint/schematics. Use --force to scaffold a TypeScript config instead. |
After setup-eslint — what runs on every commit
git commit
→ pre-commit hook
Phase 1: rm-console (if CG_RM_CONSOLE=1 or CONSOLE_LOG_REMOVAL=true in .env)
→ strip console.log/.warn/.debug/.info from staged JS/TS files
→ prettier --write
→ git add (re-stage cleaned files)
Phase 2: lint-staged
→ eslint --fix (fixes auto-fixable issues, blocks on errors)
→ prettier --write (formats code)
→ commit-msg hook
→ build check (npm run build)CLI
npx commit-sentry setup # install hooks (same as postinstall)
npx commit-sentry update # force-overwrite hook files with package defaults
npx commit-sentry uninstall # remove hooks and unset core.hooksPath
npx commit-sentry setup-eslint # scaffold ESLint config for your framework
npx commit-sentry setup-eslint --force # overwrite existing ESLint config
npx commit-sentry version # print version
npx commit-sentry help # show helpEnvironment variables
| Variable | Effect |
|---|---|
| HUSKY=0 | Bypass all hooks for one command. |
| HUSKY_SKIP_BUILD=1 | Skip the commit-time build for one commit. |
| CG_BUILD_COMMAND | Override the build command (default: npm run build). |
| CG_RM_CONSOLE=1 | Enable console stripping for this commit (inline). |
| CONSOLE_LOG_REMOVAL=true | Enable console stripping permanently via .env file at repo root. |
| CG_SKIP_RM_CONSOLE=1 | Disable console stripping even if CG_RM_CONSOLE or .env is set. |
# Strip console.logs for one commit:
CG_RM_CONSOLE=1 git commit -m "feat: dashboard"
# Strip console.logs on every commit (add to .env):
echo "CONSOLE_LOG_REMOVAL=true" >> .env
# Skip stripping for one commit (even if .env has the flag):
CG_SKIP_RM_CONSOLE=1 git commit -m "debug: keep logs"
# Skip the build this one time:
HUSKY_SKIP_BUILD=1 git commit -m "docs: typo"
# Use a custom build command:
CG_BUILD_COMMAND="npm run ci:check" git commit -m "fix: logic"
# Skip all hooks entirely:
HUSKY=0 git commit -m "wip"The rm-console feature
Automatically strip console.log / .warn / .debug / .info from every staged .js/.jsx/.ts/.tsx file before it lands in the commit. console.error is always preserved.
Option A — inline flag (one commit):
CG_RM_CONSOLE=1 git commit -m "feat: new dashboard"Option B — .env file (always-on):
# Add to .env at your repo root:
CONSOLE_LOG_REMOVAL=trueFrom that point on, every git commit automatically strips console statements — no inline flag needed.
What happens under the hood:
- Finds every staged
.js/.jsx/.ts/.tsxfile. - Strips every
console.log/console.warn/console.debug/console.infocall (including multi-line calls with nested parens). - Re-formats those files with prettier.
- Re-stages the cleaned files — so the stripped version is what git actually stores in the commit, not just what's left on disk.
Disable for one commit (even if .env has the flag):
CG_SKIP_RM_CONSOLE=1 git commit -m "debug: keeping console.logs"Verify a commit was cleaned:
git show HEAD:src/yourfile.ts # committed content — no console.logUse the shareable configs manually
Prettier
In your package.json:
{
"prettier": "commit-sentry/configs/prettier.config.js"
}Lint-staged
// lint-staged.config.js — prettier only
module.exports = require("commit-sentry/configs/lint-staged-config");
// or with ESLint (after running npx commit-sentry setup-eslint):
module.exports = {
"**/*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"**/*.{json,css,scss,md}": ["prettier --write"],
};ESLint (flat config, ESLint 9+)
// eslint.config.mjs
import base from "commit-sentry/configs/eslint.config.mjs";
export default [
...base,
{
rules: {
// your project-specific overrides
},
},
];How it survives fresh clones
The postinstall script:
- Locates the consumer's git repo root (soft-fails if not a git repo).
- Creates
.husky/next topackage.jsonif missing. - Copies hook templates in (won't overwrite existing hooks — that's what
updateis for). - Sets
core.hooksPathrelative to the repo root (handles monorepos and sub-folder projects correctly). - Normalizes CRLF → LF on every hook file (Windows safety).
- Chmods hooks to
0755on Unix. - Creates
lint-staged.config.jsif none exists. - Logs what it did. Every failure is a warning, never a hard error —
npm installis sacred.
Uninstall
npx commit-sentry uninstall
npm uninstall commit-sentryuninstall removes only the hook files this package created and unsets core.hooksPath. Any hooks you added yourself are left alone.
Troubleshooting
"The build fails with EPERM on .next/trace on Windows"
Your dev server (npm run dev) is running in another terminal holding .next/ open. Stop it and re-commit, or bypass: HUSKY_SKIP_BUILD=1 git commit -m "...".
"Hooks don't run after I clone the repo"
Run npx commit-sentry setup. This happens when npm install ran with --ignore-scripts or in a directory without a .git/ folder.
"bash: $'\r': command not found"
Your hook files were checked out with CRLF endings. Run npx commit-sentry update to rewrite them to LF. Add .husky/** text eol=lf to .gitattributes to prevent recurrence.
"ESLint rules are not running on commit"
Run npx commit-sentry setup-eslint. Without it, only prettier runs on commit — ESLint is opt-in.
"Prettier is not running on commit"
Check that lint-staged.config.js exists in your project root. If missing, run npx commit-sentry setup to regenerate it.
License
MIT
