Summary
The scaffolded lint-staged config breaks the husky pre-commit hook for any commit that doesn't touch a .js/.jsx/.ts/.tsx file (e.g. a docs- or config-only commit). ultracite fix exits non-zero with No files found to lint, so husky aborts the commit.
Environment
@proofkit/cli@2.2.0-beta.6, init . --app-type webviewer --non-interactive
ultracite@^7.7.0 (oxlint + oxfmt), husky@^9.1.7, lint-staged@^17
- node 24.14.1, pnpm 11.1.3, macOS
What the scaffold produces
package.json:
"lint-staged": {
"*.{js,jsx,ts,tsx,json,jsonc,css,scss,md,mdx}": [
"pnpm exec ultracite fix"
]
}
The glob spans md/mdx/json/jsonc/css/scss, but ultracite drives oxlint, which only lints the JS/TS family. When lint-staged hands ultracite fix a staged set containing none of those (e.g. only *.md + package.json), it fails:
✖ pnpm exec ultracite fix:
Finished in 132ms on 1 files using 14 threads.
No files found to lint. Please check your paths and ignore patterns.
husky - pre-commit script failed (code 1)
Reproduction
npx @proofkit/cli@beta init . --app-type webviewer --non-interactive
git init -b main && git add -A && git commit -m "init" # ok (has TS files)
# now a docs-only change:
printf '\n' >> README.md
git add README.md
git commit -m "docs" # FAILS: ultracite "No files found to lint"
It fails even when the only staged file is package.json — i.e. it's not specific to markdown; it's "no JS/TS files in the staged set."
Root cause
This comes from ultracite's lint-staged integration, wired by the CLI in
packages/cli/src/helpers/ultracite.ts:
const ULTRACITE_INTEGRATIONS = ["husky", "lint-staged"] as const;
The same glob ships in this repo's own root package.json. Two things combine:
- The integration writes a glob covering extensions oxlint doesn't lint.
ultracite fix treats "zero matched files after filtering" as an error (exit 1) rather than a no-op.
This likely belongs upstream in proofsh/ultracite (the integration generator), but it surfaces on every scaffolded ProofKit project, so flagging it here.
Impact
- Every ProofKit webviewer project hits this on routine docs/config commits.
- The natural workaround users reach for is
git commit --no-verify — which also bypasses any other pre-commit hooks (e.g. a gitleaks secret-scan), turning a formatting annoyance into a security footgun.
Suggested fixes (any one)
- Scope the lint-staged glob to what oxlint actually lints:
"*.{js,jsx,ts,tsx}": ["pnpm exec ultracite fix"].
- Make
ultracite fix exit 0 (no-op) when no matching files remain after filtering.
- Add a
--no-error-on-unmatched style flag and use it in the lint-staged integration.
Workaround (current)
Narrow the glob in package.json to *.{js,jsx,ts,tsx}. Docs/config-only commits then run no lint task and the hook passes (gitleaks etc. still run).
Summary
The scaffolded
lint-stagedconfig breaks the huskypre-commithook for any commit that doesn't touch a.js/.jsx/.ts/.tsxfile (e.g. a docs- or config-only commit).ultracite fixexits non-zero withNo files found to lint, so husky aborts the commit.Environment
@proofkit/cli@2.2.0-beta.6,init . --app-type webviewer --non-interactiveultracite@^7.7.0(oxlint + oxfmt),husky@^9.1.7,lint-staged@^17What the scaffold produces
package.json:The glob spans
md/mdx/json/jsonc/css/scss, but ultracite drives oxlint, which only lints the JS/TS family. Whenlint-stagedhandsultracite fixa staged set containing none of those (e.g. only*.md+package.json), it fails:Reproduction
It fails even when the only staged file is
package.json— i.e. it's not specific to markdown; it's "no JS/TS files in the staged set."Root cause
This comes from ultracite's lint-staged integration, wired by the CLI in
packages/cli/src/helpers/ultracite.ts:The same glob ships in this repo's own root
package.json. Two things combine:ultracite fixtreats "zero matched files after filtering" as an error (exit 1) rather than a no-op.This likely belongs upstream in
proofsh/ultracite(the integration generator), but it surfaces on every scaffolded ProofKit project, so flagging it here.Impact
git commit --no-verify— which also bypasses any other pre-commit hooks (e.g. agitleakssecret-scan), turning a formatting annoyance into a security footgun.Suggested fixes (any one)
"*.{js,jsx,ts,tsx}": ["pnpm exec ultracite fix"].ultracite fixexit 0 (no-op) when no matching files remain after filtering.--no-error-on-unmatchedstyle flag and use it in the lint-staged integration.Workaround (current)
Narrow the glob in
package.jsonto*.{js,jsx,ts,tsx}. Docs/config-only commits then run no lint task and the hook passes (gitleaks etc. still run).