mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-12 03:03:23 +08:00
fix(.cursor/hooks): route block-no-verify through local hook to fix message-body false positives (#2107) (#2177)
Cursor hooks still called `npx block-no-verify@1.1.2`, the broken external package whose matcher over-matches: it blocks legitimate `git commit` whenever `--no-verify` (or `no-verify`) appears anywhere in the command string, including inside the commit message body. The Claude Code surface already routes through the in-repo `scripts/hooks/block-no-verify.js`, which performs flag-position-aware tokenisation and passes 25 regression tests covering every false-positive case from #2107. Add a thin Cursor wrapper (`before-shell-execution-block-no-verify.js`) that reads Cursor stdin, transforms to the Claude Code `tool_input.command` shape, delegates to the local hook's exported `run()`, and forwards exit code and stderr. Update `.cursor/hooks.json` to call the wrapper instead of the npx package. New 14-case test file pins the false-positive cases from the issue plus the still-blocked real bypass attempts. Fixes #2107
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
],
|
||||
"beforeShellExecution": [
|
||||
{
|
||||
"command": "npx block-no-verify@1.1.2",
|
||||
"command": "node .cursor/hooks/before-shell-execution-block-no-verify.js",
|
||||
"event": "beforeShellExecution",
|
||||
"description": "Block git hook-bypass flag to protect pre-commit, commit-msg, and pre-push hooks from being skipped"
|
||||
},
|
||||
|
||||
63
.cursor/hooks/before-shell-execution-block-no-verify.js
Normal file
63
.cursor/hooks/before-shell-execution-block-no-verify.js
Normal file
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Cursor wrapper for block-no-verify.
|
||||
*
|
||||
* Cursor hooks previously called `npx block-no-verify@1.1.2`, an external
|
||||
* package whose matcher over-matches: it blocks legitimate `git commit`
|
||||
* whenever the literal string `--no-verify` (or `no-verify`) appears
|
||||
* anywhere in the command string, including inside the commit message
|
||||
* body. See issue #2107.
|
||||
*
|
||||
* The Claude Code surface already routes through the local, in-repo hook
|
||||
* `scripts/hooks/block-no-verify.js`, which performs flag-position-aware
|
||||
* tokenisation (skipping the value of `-m`, `-F`, `-am "..."`, etc.) and
|
||||
* passes 25 regression tests covering every false-positive case.
|
||||
*
|
||||
* This wrapper gives Cursor the same matcher: read Cursor stdin, transform
|
||||
* to the Claude Code `tool_input.command` shape the local hook understands,
|
||||
* delegate to its exported `run()`, then forward the exit code and stderr.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const { readStdin, hookEnabled } = require('./adapter');
|
||||
const { run } = require('../../scripts/hooks/block-no-verify');
|
||||
|
||||
readStdin()
|
||||
.then(raw => {
|
||||
if (!hookEnabled('pre:bash:block-no-verify', ['minimal', 'standard', 'strict'])) {
|
||||
process.stdout.write(raw);
|
||||
return;
|
||||
}
|
||||
|
||||
let command = '';
|
||||
try {
|
||||
const parsed = JSON.parse(raw || '{}');
|
||||
command = String(parsed.command || parsed.args?.command || '');
|
||||
} catch {
|
||||
command = String(raw || '');
|
||||
}
|
||||
|
||||
// Local hook accepts either the raw command string or a Claude-Code
|
||||
// shaped `{ tool_input: { command } }` JSON. Pass the Claude shape so
|
||||
// the JSON branch in extractCommand() is exercised the same way the
|
||||
// Claude Code surface exercises it — keeps the two surfaces on the
|
||||
// same code path.
|
||||
const claudeInput = JSON.stringify({ tool_input: { command } });
|
||||
const result = run(claudeInput);
|
||||
|
||||
if (result && result.exitCode === 2) {
|
||||
if (result.stderr) {
|
||||
process.stderr.write(String(result.stderr) + '\n');
|
||||
}
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
process.stdout.write(raw);
|
||||
})
|
||||
.catch(() => {
|
||||
// Per repo rule: hooks must exit 0 on non-critical errors and never
|
||||
// unexpectedly block tool execution. A parse / transport error here
|
||||
// is non-critical — fall through.
|
||||
process.exit(0);
|
||||
});
|
||||
Reference in New Issue
Block a user