Files
ersatztv/web/package.json
T
timothyandClaude Opus 4.8 f27f458ff5 feat(web): add husky pre-commit/pre-push/commit-msg guardrails
Installs husky git hooks (via web/'s lint-staged + npm, since the JS/TS
project lives in web/ with no root package.json) to catch lint, format,
type, and generated-API-drift errors locally before they reach CI.

Hooks (committed at repo root under .husky/):
- pre-commit: (a) lint-staged runs eslint --fix on staged
  web/src/**/*.{ts,tsx} + a project-wide typecheck; (b) if any *.cs are
  staged, dotnet format --verify-no-changes on just those files (skipped
  when no .cs staged, so web-only commits skip the sln load).
- pre-push: CI-parity gate — cd web && check:api && lint && typecheck &&
  build. Blocks pushing drift or a change that breaks an unstaged file.
- commit-msg: requires a Co-Authored-By trailer (merge commits exempt).

Wiring: web/package.json gains husky + lint-staged devDeps, a lint-staged
config, and a `prepare` script (cd .. && husky) that points git's
core.hooksPath at the repo-root .husky dir on npm install. A fresh
`web/` npm install installs all four hooks automatically.

Monorepo/worktree gotchas handled:
- husky init hard-checks for .git in cwd, so `prepare` cd's to the repo
  root before invoking husky (npm keeps web/node_modules/.bin on PATH).
- git exports GIT_DIR while running hooks; in a worktree/subdir that made
  pre-push's `git diff` (check:api) mislocate the working tree and pass
  silently on drift — pre-push now unsets GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE.

docs/ci-cd.md: new "Pre-commit hooks (web/)" section covering all four.

Verified: eslint error blocks commit; clean commit passes; bad-format .cs
blocks (dotnet format ~6-7s scoped), good .cs passes; check:api drift and
a lint error each block `git push --dry-run`, clean state passes; missing
Co-Authored-By blocks commit-msg, present passes; non-web/.cs commits skip
lint/format. npm run lint clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 19:31:22 +02:00

49 lines
1.3 KiB
JSON

{
"name": "@chicorytv/web",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite --host 0.0.0.0",
"build": "tsc -b && vite build",
"generate:api": "node scripts/generate-openapi-types.mjs",
"check:api": "npm run generate:api && git diff --exit-code -- src/api/generated/v1.d.ts",
"lint": "eslint .",
"test": "vitest",
"typecheck": "tsc -b --pretty false",
"prepare": "cd .. && husky"
},
"lint-staged": {
"src/**/*.{ts,tsx}": [
"eslint --fix",
"bash -c 'npm run typecheck'"
]
},
"dependencies": {
"@vitejs/plugin-react": "6.0.3",
"hls.js": "^1.6.16",
"lucide-react": "1.23.0",
"react": "19.2.7",
"react-dom": "19.2.7",
"typescript": "6.0.3",
"vite": "8.1.3"
},
"devDependencies": {
"@eslint/js": "10.0.1",
"@testing-library/jest-dom": "6.9.1",
"@testing-library/react": "16.3.2",
"@types/node": "26.1.0",
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"eslint": "10.6.0",
"eslint-plugin-react-hooks": "7.1.1",
"eslint-plugin-react-refresh": "0.5.3",
"globals": "17.7.0",
"husky": "^9.1.7",
"jsdom": "29.1.1",
"lint-staged": "^17.0.8",
"typescript-eslint": "8.62.1",
"vitest": "4.1.9"
}
}