pre-commit: parallel: true commands: lint: glob: "*.{js,jsx,ts,tsx}" run: bunx oxlint --no-error-on-unmatched-pattern {staged_files} format: glob: "*.{js,jsx,ts,tsx,json,md,yaml,yml}" # Auto-format and re-stage so the committed snapshot is always formatted. # Replaces --check which only reports — that left unformatted files in # commits when the hook ran after the amend snapshot was taken. run: bunx oxfmt --no-error-on-unmatched-pattern {staged_files} && git add -f {staged_files} skills-manifest: glob: "skills/**" # Regenerate the freshness fingerprint when a skill changes, then re-stage # it so skills-manifest.json (repo root) never drifts from skills/ (CI # enforces the same via the "Skills: manifest in sync" job). Churn-free: # the generator rewrites only when a content hash actually changed. run: bun packages/cli/scripts/gen-skills-manifest.ts && git add skills-manifest.json typecheck: glob: "*.{ts,tsx}" run: cd packages/core && bunx tsc --noEmit && cd ../studio && bunx tsc --noEmit # Mirrors the CI gate (same `--base origin/main` so the local hook can't # pass on a branch CI would fail). Audits the working tree, which means # unstaged WIP in `packages/**` is part of the diff — stash before # committing if that surprises you. `--gate new-only` (the default) only # fails on issues introduced by the branch, not inherited findings. fallow: glob: "packages/**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}" # Unset git worktree env vars: fallow creates a temp worktree internally and # GIT_DIR/GIT_INDEX_FILE (set by git in worktree hook context) break that. # env -u is safe in non-worktree contexts (no-op when var is unset). run: env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE bunx fallow audit --base origin/main --fail-on-issues largefiles: # Reject large binaries committed straight into the git pack instead of # LFS. The script reads the staged set itself (via `git diff --cached`) # rather than taking lefthook's `{staged_files}` expansion, which would # split paths containing spaces. It skips files under the limit, anything # routed through LFS, and registry/ assets. Tune via HF_MAX_NONLFS_KB. run: ./scripts/check-large-files.sh tracked-artifacts: # Keep ignored dependency trees and platform metadata out of commits. # `git ls-files` observes the staged index, so staged removals pass and # an accidental force-add fails before the commit is created. run: bun run check:tracked-artifacts filesize: # Scoped to packages/studio — the 600 LOC limit is a studio architecture # standard enforced as part of the App.tsx decomposition work. Player and # other packages enforce size discipline via code review and convention. glob: "packages/studio/**/*.{ts,tsx}" exclude: "(\\.test\\.(ts|tsx)$|\\.generated\\.)" run: | for f in {staged_files}; do # Skip test and generated files (exclude pattern backup in case lefthook doesn't filter) case "$f" in *.test.ts|*.test.tsx|*.generated.*) continue ;; esac lines=$(wc -l < "$f") if [ "$lines" -gt 600 ]; then echo "ERROR: $f has $lines lines (max 600)" exit 1 fi done commit-msg: commands: commitlint: run: bunx commitlint --edit "{1}"