From d52ce498264e5ac161a86ad97c1a036ea93a7f76 Mon Sep 17 00:00:00 2001 From: Tyom Semonov Date: Fri, 16 Jan 2026 19:10:12 +0000 Subject: [PATCH] Add environment variable toggles to disable hooks per-project Hooks can now be disabled via LINT_ON_SAVE and RUN_TESTS_ON_STOP environment variables (both default to true). Set to "false" in .claude/settings.local.json to skip hooks for specific projects. --- claude-plugin/hooks/README.md | 45 +++++++++++++++++++ .../hooks/post-tool-use/lint-and-typecheck.ts | 7 +++ claude-plugin/hooks/stop/run-tests.ts | 7 +++ 3 files changed, 59 insertions(+) create mode 100644 claude-plugin/hooks/README.md diff --git a/claude-plugin/hooks/README.md b/claude-plugin/hooks/README.md new file mode 100644 index 0000000..f63bf74 --- /dev/null +++ b/claude-plugin/hooks/README.md @@ -0,0 +1,45 @@ +# Hooks + +Claude Code hooks that run automatically during various events. + +## Available Hooks + +### PostToolUse: Lint and Typecheck + +**Trigger:** After `Edit`, `MultiEdit`, or `Write` operations on supported files. + +**Actions:** + +- TypeScript type checking (if tsconfig.json present) +- Prettier formatting (auto-fixes if needed) +- ESLint linting + +**Supported file extensions:** `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.mts`, `.md`, `.mdx`, `.json`, `.yaml`, `.yml`, `.css`, `.scss`, `.html` + +### Stop: Run Tests + +**Trigger:** Before Claude stops working. + +**Actions:** + +- Detects test runner (bun, npm, yarn, pnpm, vitest, jest, mocha) +- Runs project tests +- Blocks stopping if tests fail + +## Configuration + +Both hooks can be disabled per-project using environment variables in `.claude/settings.local.json`: + +```json +{ + "env": { + "LINT_ON_SAVE": "false", + "RUN_TESTS_ON_STOP": "false" + } +} +``` + +| Variable | Default | Description | +| ------------------- | ------- | ------------------------------------------------------- | +| `LINT_ON_SAVE` | `true` | Enable/disable lint, typecheck, and format on file save | +| `RUN_TESTS_ON_STOP` | `true` | Enable/disable running tests before stopping | diff --git a/claude-plugin/hooks/post-tool-use/lint-and-typecheck.ts b/claude-plugin/hooks/post-tool-use/lint-and-typecheck.ts index 61c0ca0..3bdfecd 100644 --- a/claude-plugin/hooks/post-tool-use/lint-and-typecheck.ts +++ b/claude-plugin/hooks/post-tool-use/lint-and-typecheck.ts @@ -130,12 +130,19 @@ function runCommand( * Aggregates tool outputs as errors or warnings. Prints errors to stderr and exits with code 2; * prints warnings to stdout and exits with code 0 on success or when no action was necessary. * + * Can be disabled by setting LINT_ON_SAVE=false environment variable. + * * @remarks * Exit codes: * - 0: success or no applicable action * - 2: blocking errors detected (TypeScript, Prettier, or ESLint) */ async function main() { + // Check if linting is disabled via environment variable (default: enabled) + if (process.env.LINT_ON_SAVE === "false") { + process.exit(0); + } + let input: ToolInput; try { diff --git a/claude-plugin/hooks/stop/run-tests.ts b/claude-plugin/hooks/stop/run-tests.ts index 771c84b..8fbdaec 100644 --- a/claude-plugin/hooks/stop/run-tests.ts +++ b/claude-plugin/hooks/stop/run-tests.ts @@ -225,8 +225,15 @@ async function findProjectRoot(): Promise { * Reads JSON input from stdin to detect an active stop hook; if present, allows stopping immediately. * Locates the project root and detects an appropriate test runner; if no runner is found or no test files exist, allows stopping. * Executes the detected test suite; if tests fail, writes a JSON decision object to stdout with `decision: "block"` and a `reason` that includes the test output, then exits. + * + * Can be disabled by setting RUN_TESTS_ON_STOP=false environment variable. */ async function main() { + // Check if tests on stop are disabled via environment variable (default: enabled) + if (process.env.RUN_TESTS_ON_STOP === "false") { + process.exit(0); + } + let input: StopHookInput = {}; try {