From f3e272ac026aa69a6acd09adcfd0c8341bd4e500 Mon Sep 17 00:00:00 2001 From: Erick Teowarang Date: Thu, 21 May 2026 17:02:01 +1000 Subject: [PATCH] chore: add lefthook pre-commit hook for oxfmt Run oxfmt on staged ts/tsx/js/jsx/mjs/cjs/json/jsonc/md/mdx/yaml/yml/css/html files before commit, preventing fmt:check failures in CI for cases that the local pnpm fmt invocation hasn't caught. Lefthook is used across other Tailor repos, so we match that tooling instead of husky + lint-staged for consistency. - lefthook@2.1.6 added as a root devDependency - prepare script runs `lefthook install` so contributors get the hook on pnpm install - lefthook.yml defines the pre-commit oxfmt command with stage_fixed so formatter changes are re-staged - allowBuilds marks lefthook: false since the root prepare script handles hook installation Co-Authored-By: Claude Opus 4.7 (1M context) --- lefthook.yml | 7 ++++ package.json | 4 +- pnpm-lock.yaml | 100 ++++++++++++++++++++++++++++++++++++++++++++ pnpm-workspace.yaml | 3 ++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 lefthook.yml diff --git a/lefthook.yml b/lefthook.yml new file mode 100644 index 00000000..c33354e4 --- /dev/null +++ b/lefthook.yml @@ -0,0 +1,7 @@ +pre-commit: + parallel: true + commands: + oxfmt: + glob: "*.{ts,tsx,js,jsx,mjs,cjs,json,jsonc,md,mdx,yaml,yml,css,html}" + run: pnpm exec oxfmt {staged_files} + stage_fixed: true diff --git a/package.json b/package.json index 195b270c..6115cb36 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,12 @@ "fmt": "oxfmt", "fmt:check": "oxfmt --check", "changeset:create": "changeset", - "changeset:publish": "pnpm build && changeset publish" + "changeset:publish": "pnpm build && changeset publish", + "prepare": "lefthook install" }, "devDependencies": { "@changesets/cli": "^2.31.0", + "lefthook": "2.1.6", "oxfmt": "catalog:", "oxlint": "catalog:", "turbo": "^2.9.14" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9af83f52..f53c37a7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: '@changesets/cli': specifier: ^2.31.0 version: 2.31.0(@types/node@25.6.0) + lefthook: + specifier: 2.1.6 + version: 2.1.6 oxfmt: specifier: 'catalog:' version: 0.47.0 @@ -3851,6 +3854,60 @@ packages: resolution: {integrity: sha512-3i5pmOiZvMDj00qhrIVbH0AnioVTx22DMP7Vn5At4yJO46iy+FM8Y/g61ltenLVSo3fiO8h8Q3QOFgf/gQ72ww==} engines: {node: '>=20.0.0'} + lefthook-darwin-arm64@2.1.6: + resolution: {integrity: sha512-hyB7eeiX78BS66f70byTJacDLC/xV1vgMv9n+idFUsrM7J3Udd/ag9Ag5NP3t0eN0EqQqAtrNnt35EH01lxnRQ==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@2.1.6: + resolution: {integrity: sha512-5Ka6cFxiH83krt+OMRQtmS6zqoZR5SLXSudLjTbZA1c3ZqF0+dqkeb4XcB6plx6WR0GFizabuc6Bi3iXPIe1eQ==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@2.1.6: + resolution: {integrity: sha512-VswyOg5CVN3rMaOJ2HtnkltiMKgFHW/wouWxXsV8RxSa4tgWOKxM0EmSXi8qc2jX+LRga6B0uOY6toXS01zWxA==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@2.1.6: + resolution: {integrity: sha512-vXsCUFYuVwrVWwcypB7Zt2Hf+5pl1V1la7ZfvGYZaTRURu0zF/XUnMF/nOz/PebGv0f4x/iOWXWwP7E42xRWsg==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@2.1.6: + resolution: {integrity: sha512-WDJiQhJdZOvKORZd+kF/ms2l6NSsXzdA9ahflyr65V90AC4jES223W8VtEMbGPUtHuGWMEZ/v/XvwlWv0Ioz9g==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@2.1.6: + resolution: {integrity: sha512-C18nCd7nTX1AVL4TcvwMmLAO1VI1OuGluIOTjiPkBQ746Ls1HhL5rl//jMPACmT28YmxIQJ2ZcLPNmhvEVBZvw==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@2.1.6: + resolution: {integrity: sha512-mZOMxM8HiPxVFXDO3PtCUbH4GB8rkveXhsgXF27oAZTYVzQ3gO9vT6r/pxit6msqRXz3fvcwimLVJgb8eRsa8A==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@2.1.6: + resolution: {integrity: sha512-sG9ALLZSnnMOfXu+B7SmxFhJhuoAh4bqi5En5aaHJET48TqrLOcWWZuH+7ArFM6gr/U5KfSUvdmHFmY8WqCcIg==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@2.1.6: + resolution: {integrity: sha512-lD8yFWY4Csuljd0Rqs7EQaySC0VvDf7V3rN1FhRMUISTRDHutebIom1Loc8ckQPvKYGC6mftT9k0GvipsS+Brw==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@2.1.6: + resolution: {integrity: sha512-q4z2n3xucLscoWiyMwFViEj3N8MDSkPulMwcJYuCYFHoPhP1h+icqNu7QRLGYj6AnVrCQweiUJY3Tb2X+GbD/A==} + cpu: [x64] + os: [win32] + + lefthook@2.1.6: + resolution: {integrity: sha512-w9sBoR0mdN+kJc3SB85VzpiAAl451/rxdCRcZlwW71QLjkeH3EBQFgc4VMj5apePychYDHAlqEWTB8J8JK/j1Q==} + hasBin: true + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -8445,6 +8502,49 @@ snapshots: kysely@0.28.16: {} + lefthook-darwin-arm64@2.1.6: + optional: true + + lefthook-darwin-x64@2.1.6: + optional: true + + lefthook-freebsd-arm64@2.1.6: + optional: true + + lefthook-freebsd-x64@2.1.6: + optional: true + + lefthook-linux-arm64@2.1.6: + optional: true + + lefthook-linux-x64@2.1.6: + optional: true + + lefthook-openbsd-arm64@2.1.6: + optional: true + + lefthook-openbsd-x64@2.1.6: + optional: true + + lefthook-windows-arm64@2.1.6: + optional: true + + lefthook-windows-x64@2.1.6: + optional: true + + lefthook@2.1.6: + optionalDependencies: + lefthook-darwin-arm64: 2.1.6 + lefthook-darwin-x64: 2.1.6 + lefthook-freebsd-arm64: 2.1.6 + lefthook-freebsd-x64: 2.1.6 + lefthook-linux-arm64: 2.1.6 + lefthook-linux-x64: 2.1.6 + lefthook-openbsd-arm64: 2.1.6 + lefthook-openbsd-x64: 2.1.6 + lefthook-windows-arm64: 2.1.6 + lefthook-windows-x64: 2.1.6 + lightningcss-android-arm64@1.32.0: optional: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ced7f3b1..4eae9901 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -37,6 +37,9 @@ allowBuilds: msw: false "@tailor-platform/sdk": false "@prisma/engines": false + # lefthook's postinstall installs git hooks; the root `prepare` script + # handles that via `lefthook install` instead. + lefthook: false # Detect provenance or publisher trust downgrades in dependency updates trustPolicy: no-downgrade