block-no-verify 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -6
- package/dist/agents/allowed-commands.d.ts +4 -0
- package/dist/agents/allowed-commands.d.ts.map +1 -0
- package/dist/agents/allowed-commands.js +47 -0
- package/dist/agents/allowed-commands.js.map +1 -0
- package/dist/agents/blocked-commands.d.ts +4 -0
- package/dist/agents/blocked-commands.d.ts.map +1 -0
- package/dist/agents/blocked-commands.js +71 -0
- package/dist/agents/blocked-commands.js.map +1 -0
- package/dist/agents/test-command.d.ts +5 -0
- package/dist/agents/test-command.d.ts.map +1 -0
- package/dist/agents/test-command.js +2 -0
- package/dist/agents/test-command.js.map +1 -0
- package/dist/agents/test-commands.d.ts +3 -7
- package/dist/agents/test-commands.d.ts.map +1 -1
- package/dist/agents/test-commands.js +2 -103
- package/dist/agents/test-commands.js.map +1 -1
- package/dist/check-command.d.ts +1 -1
- package/dist/check-command.d.ts.map +1 -1
- package/dist/check-command.js +9 -1
- package/dist/check-command.js.map +1 -1
- package/dist/cli.js +0 -0
- package/dist/has-hooks-path-override.d.ts +6 -0
- package/dist/has-hooks-path-override.d.ts.map +1 -0
- package/dist/has-hooks-path-override.js +10 -0
- package/dist/has-hooks-path-override.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +20 -17
package/README.md
CHANGED
|
@@ -8,13 +8,29 @@ When using AI coding assistants like Claude Code, Gemini CLI, Cursor, or others,
|
|
|
8
8
|
|
|
9
9
|
This package provides a CLI that can block any git commands that include `--no-verify`, working with any AI tool that supports command hooks.
|
|
10
10
|
|
|
11
|
+
## Used By
|
|
12
|
+
|
|
13
|
+
<a href="https://github.com/langgenius/dify">
|
|
14
|
+
<img src="https://github.com/langgenius.png" width="50" height="50" alt="Dify" title="Dify - Open-source LLM app development platform">
|
|
15
|
+
</a>
|
|
16
|
+
<a href="https://centy.io">
|
|
17
|
+
<img src="https://github.com/centy-io.png" width="50" height="50" alt="Centy" title="Centy">
|
|
18
|
+
</a>
|
|
19
|
+
<a href="https://worktree.io">
|
|
20
|
+
<img src="https://github.com/worktree-io.png" width="50" height="50" alt="Worktree" title="Worktree">
|
|
21
|
+
</a>
|
|
22
|
+
|
|
11
23
|
## Installation
|
|
12
24
|
|
|
25
|
+
Add as a dev dependency to ensure a consistent, pinned version:
|
|
26
|
+
|
|
13
27
|
```bash
|
|
14
|
-
pnpm add -
|
|
28
|
+
pnpm add -D block-no-verify
|
|
29
|
+
# or
|
|
30
|
+
npm install --save-dev block-no-verify
|
|
15
31
|
```
|
|
16
32
|
|
|
17
|
-
|
|
33
|
+
Then use it with `pnpm exec block-no-verify` or `npm exec block-no-verify`.
|
|
18
34
|
|
|
19
35
|
## Quick Start
|
|
20
36
|
|
|
@@ -47,7 +63,7 @@ Add to your `.claude/settings.json`:
|
|
|
47
63
|
"hooks": [
|
|
48
64
|
{
|
|
49
65
|
"type": "command",
|
|
50
|
-
"command": "pnpm
|
|
66
|
+
"command": "pnpm exec block-no-verify"
|
|
51
67
|
}
|
|
52
68
|
]
|
|
53
69
|
}
|
|
@@ -72,7 +88,7 @@ Add to your `.gemini/settings.json`:
|
|
|
72
88
|
{
|
|
73
89
|
"name": "block-no-verify",
|
|
74
90
|
"type": "command",
|
|
75
|
-
"command": "pnpm
|
|
91
|
+
"command": "pnpm exec block-no-verify",
|
|
76
92
|
"description": "Block --no-verify flags in git commands",
|
|
77
93
|
"timeout": 5000
|
|
78
94
|
}
|
|
@@ -97,7 +113,7 @@ Create `.cursor/hooks.json` in your project root:
|
|
|
97
113
|
"hooks": {
|
|
98
114
|
"beforeShellExecution": [
|
|
99
115
|
{
|
|
100
|
-
"command": "pnpm
|
|
116
|
+
"command": "pnpm exec block-no-verify"
|
|
101
117
|
}
|
|
102
118
|
]
|
|
103
119
|
}
|
|
@@ -126,7 +142,7 @@ echo '{"tool_input":{"command":"git commit --no-verify"}}' | block-no-verify
|
|
|
126
142
|
|
|
127
143
|
## CLI Options
|
|
128
144
|
|
|
129
|
-
```
|
|
145
|
+
```text
|
|
130
146
|
block-no-verify [options] [command]
|
|
131
147
|
|
|
132
148
|
Options:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowed-commands.d.ts","sourceRoot":"","sources":["../../src/agents/allowed-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,uEAAuE;AACvE,eAAO,MAAM,gBAAgB,EAAE,WAAW,EA4CzC,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** Commands that should be allowed (no --no-verify or hooks bypass) */
|
|
2
|
+
export const ALLOWED_COMMANDS = [
|
|
3
|
+
// Normal git commands
|
|
4
|
+
{ command: 'git commit -m "test"', description: 'normal commit' },
|
|
5
|
+
{
|
|
6
|
+
command: 'git commit -m "feat: add feature"',
|
|
7
|
+
description: 'commit with conventional message',
|
|
8
|
+
},
|
|
9
|
+
{ command: 'git push origin main', description: 'normal push' },
|
|
10
|
+
{ command: 'git push -u origin feature', description: 'push with upstream' },
|
|
11
|
+
{ command: 'git merge feature', description: 'normal merge' },
|
|
12
|
+
{ command: 'git cherry-pick abc123', description: 'normal cherry-pick' },
|
|
13
|
+
{ command: 'git rebase main', description: 'normal rebase' },
|
|
14
|
+
{ command: 'git am < patch', description: 'normal am' },
|
|
15
|
+
// Git commands that don't support --no-verify
|
|
16
|
+
{ command: 'git status', description: 'git status' },
|
|
17
|
+
{ command: 'git log --oneline', description: 'git log' }, // cspell:disable-line
|
|
18
|
+
{ command: 'git diff', description: 'git diff' },
|
|
19
|
+
{ command: 'git branch -a', description: 'git branch' },
|
|
20
|
+
{ command: 'git checkout main', description: 'git checkout' },
|
|
21
|
+
{ command: 'git pull origin main', description: 'git pull' },
|
|
22
|
+
{ command: 'git fetch --all', description: 'git fetch' },
|
|
23
|
+
{ command: 'git stash', description: 'git stash' },
|
|
24
|
+
// Non-git commands
|
|
25
|
+
{ command: 'npm install', description: 'npm install' },
|
|
26
|
+
{ command: 'pnpm build', description: 'pnpm build' },
|
|
27
|
+
{ command: 'yarn test', description: 'yarn test' },
|
|
28
|
+
{ command: 'ls -la', description: 'ls command' },
|
|
29
|
+
{ command: 'echo "hello"', description: 'echo command' },
|
|
30
|
+
// -n flag in non-commit contexts (different meaning)
|
|
31
|
+
{ command: 'git push -n origin main', description: 'push -n (dry-run)' },
|
|
32
|
+
{ command: 'git merge -n feature', description: 'merge -n (no commit)' },
|
|
33
|
+
{
|
|
34
|
+
command: 'git cherry-pick -n abc123',
|
|
35
|
+
description: 'cherry-pick -n (no commit)',
|
|
36
|
+
},
|
|
37
|
+
// Commands with special characters
|
|
38
|
+
{
|
|
39
|
+
command: 'git commit -m "feat(scope): add feature #123"',
|
|
40
|
+
description: 'special chars',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
command: 'git commit -m "fix: handle edge case @user"',
|
|
44
|
+
description: '@ mention',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
//# sourceMappingURL=allowed-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"allowed-commands.js","sourceRoot":"","sources":["../../src/agents/allowed-commands.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C,sBAAsB;IACtB,EAAE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,eAAe,EAAE;IACjE;QACE,OAAO,EAAE,mCAAmC;QAC5C,WAAW,EAAE,kCAAkC;KAChD;IACD,EAAE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,aAAa,EAAE;IAC/D,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,oBAAoB,EAAE;IAC5E,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE;IAC7D,EAAE,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACxE,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE;IAC5D,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE;IACvD,8CAA8C;IAC9C,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;IACpD,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,sBAAsB;IAChF,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE;IAChD,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE;IACvD,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,cAAc,EAAE;IAC7D,EAAE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,UAAU,EAAE;IAC5D,EAAE,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,WAAW,EAAE;IACxD,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;IAClD,mBAAmB;IACnB,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE;IACtD,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE;IACpD,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE;IAClD,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE;IAChD,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE;IACxD,qDAAqD;IACrD,EAAE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACxE,EAAE,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,sBAAsB,EAAE;IACxE;QACE,OAAO,EAAE,2BAA2B;QACpC,WAAW,EAAE,4BAA4B;KAC1C;IACD,mCAAmC;IACnC;QACE,OAAO,EAAE,+CAA+C;QACxD,WAAW,EAAE,eAAe;KAC7B;IACD;QACE,OAAO,EAAE,6CAA6C;QACtD,WAAW,EAAE,WAAW;KACzB;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked-commands.d.ts","sourceRoot":"","sources":["../../src/agents/blocked-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,EAAE,WAAW,EAoEzC,CAAA"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Commands that should be blocked (contain --no-verify or hooks bypass) */
|
|
2
|
+
export const BLOCKED_COMMANDS = [
|
|
3
|
+
// --no-verify flag
|
|
4
|
+
{
|
|
5
|
+
command: 'git commit --no-verify -m "test"',
|
|
6
|
+
description: 'commit with --no-verify',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
command: 'git commit -m "test" --no-verify',
|
|
10
|
+
description: 'commit with --no-verify at end',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
command: 'git push --no-verify origin main',
|
|
14
|
+
description: 'push with --no-verify',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
command: 'git push origin main --no-verify',
|
|
18
|
+
description: 'push with --no-verify at end',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
command: 'git merge --no-verify feature',
|
|
22
|
+
description: 'merge with --no-verify',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
command: 'git cherry-pick --no-verify abc123',
|
|
26
|
+
description: 'cherry-pick with --no-verify',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
command: 'git rebase --no-verify main',
|
|
30
|
+
description: 'rebase with --no-verify',
|
|
31
|
+
},
|
|
32
|
+
{ command: 'git am --no-verify < patch', description: 'am with --no-verify' },
|
|
33
|
+
// -n shorthand (only for commit)
|
|
34
|
+
{ command: 'git commit -n -m "test"', description: 'commit with -n flag' },
|
|
35
|
+
{ command: 'git commit -m "test" -n', description: 'commit with -n at end' },
|
|
36
|
+
{
|
|
37
|
+
command: 'git commit -nm "test"',
|
|
38
|
+
description: 'commit with combined -nm flags',
|
|
39
|
+
},
|
|
40
|
+
// Edge cases
|
|
41
|
+
{
|
|
42
|
+
command: 'ls && git commit --no-verify -m "test"',
|
|
43
|
+
description: 'chained with --no-verify',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
command: 'git -C /path commit --no-verify -m "test"',
|
|
47
|
+
description: '-C flag with --no-verify',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
command: 'git commit --no-verify -m "test"',
|
|
51
|
+
description: 'extra whitespace',
|
|
52
|
+
},
|
|
53
|
+
// core.hooksPath override (bypass hooks by redirecting hooks directory)
|
|
54
|
+
{
|
|
55
|
+
command: 'git -c core.hooksPath=/dev/null push',
|
|
56
|
+
description: 'hooksPath=/dev/null push',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
command: 'git -c core.hooksPath=/dev/null commit -m "test"',
|
|
60
|
+
description: 'hooksPath commit',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
command: 'git -c core.hooksPath= push origin main',
|
|
64
|
+
description: 'empty hooksPath push',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
command: 'git -c "core.hooksPath=/dev/null" push',
|
|
68
|
+
description: 'quoted hooksPath push',
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
//# sourceMappingURL=blocked-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blocked-commands.js","sourceRoot":"","sources":["../../src/agents/blocked-commands.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAkB;IAC7C,mBAAmB;IACnB;QACE,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,yBAAyB;KACvC;IACD;QACE,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,gCAAgC;KAC9C;IACD;QACE,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,uBAAuB;KACrC;IACD;QACE,OAAO,EAAE,kCAAkC;QAC3C,WAAW,EAAE,8BAA8B;KAC5C;IACD;QACE,OAAO,EAAE,+BAA+B;QACxC,WAAW,EAAE,wBAAwB;KACtC;IACD;QACE,OAAO,EAAE,oCAAoC;QAC7C,WAAW,EAAE,8BAA8B;KAC5C;IACD;QACE,OAAO,EAAE,6BAA6B;QACtC,WAAW,EAAE,yBAAyB;KACvC;IACD,EAAE,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAC7E,iCAAiC;IACjC,EAAE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAC1E,EAAE,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,uBAAuB,EAAE;IAC5E;QACE,OAAO,EAAE,uBAAuB;QAChC,WAAW,EAAE,gCAAgC;KAC9C;IACD,aAAa;IACb;QACE,OAAO,EAAE,wCAAwC;QACjD,WAAW,EAAE,0BAA0B;KACxC;IACD;QACE,OAAO,EAAE,2CAA2C;QACpD,WAAW,EAAE,0BAA0B;KACxC;IACD;QACE,OAAO,EAAE,wCAAwC;QACjD,WAAW,EAAE,kBAAkB;KAChC;IACD,wEAAwE;IACxE;QACE,OAAO,EAAE,sCAAsC;QAC/C,WAAW,EAAE,0BAA0B;KACxC;IACD;QACE,OAAO,EAAE,kDAAkD;QAC3D,WAAW,EAAE,kBAAkB;KAChC;IACD;QACE,OAAO,EAAE,yCAAyC;QAClD,WAAW,EAAE,sBAAsB;KACpC;IACD;QACE,OAAO,EAAE,wCAAwC;QACjD,WAAW,EAAE,uBAAuB;KACrC;CACF,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-command.d.ts","sourceRoot":"","sources":["../../src/agents/test-command.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-command.js","sourceRoot":"","sources":["../../src/agents/test-command.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test commands for agent format testing
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
command: string;
|
|
6
|
-
description: string;
|
|
7
|
-
}
|
|
4
|
+
export type { TestCommand } from './test-command.js';
|
|
8
5
|
export declare const testCommands: {
|
|
9
|
-
BLOCKED_COMMANDS: TestCommand[];
|
|
10
|
-
ALLOWED_COMMANDS: TestCommand[];
|
|
6
|
+
BLOCKED_COMMANDS: import("./test-command.js").TestCommand[];
|
|
7
|
+
ALLOWED_COMMANDS: import("./test-command.js").TestCommand[];
|
|
11
8
|
};
|
|
12
|
-
export {};
|
|
13
9
|
//# sourceMappingURL=test-commands.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-commands.d.ts","sourceRoot":"","sources":["../../src/agents/test-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"test-commands.d.ts","sourceRoot":"","sources":["../../src/agents/test-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD,eAAO,MAAM,YAAY;;;CAGxB,CAAA"}
|
|
@@ -1,109 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Test commands for agent format testing
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*/
|
|
7
|
-
const BLOCKED_COMMANDS = [
|
|
8
|
-
// --no-verify flag
|
|
9
|
-
{
|
|
10
|
-
command: 'git commit --no-verify -m "test"',
|
|
11
|
-
description: 'commit with --no-verify',
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
command: 'git commit -m "test" --no-verify',
|
|
15
|
-
description: 'commit with --no-verify at end',
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
command: 'git push --no-verify origin main',
|
|
19
|
-
description: 'push with --no-verify',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
command: 'git push origin main --no-verify',
|
|
23
|
-
description: 'push with --no-verify at end',
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
command: 'git merge --no-verify feature',
|
|
27
|
-
description: 'merge with --no-verify',
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
command: 'git cherry-pick --no-verify abc123',
|
|
31
|
-
description: 'cherry-pick with --no-verify',
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
command: 'git rebase --no-verify main',
|
|
35
|
-
description: 'rebase with --no-verify',
|
|
36
|
-
},
|
|
37
|
-
{ command: 'git am --no-verify < patch', description: 'am with --no-verify' },
|
|
38
|
-
// -n shorthand (only for commit)
|
|
39
|
-
{ command: 'git commit -n -m "test"', description: 'commit with -n flag' },
|
|
40
|
-
{ command: 'git commit -m "test" -n', description: 'commit with -n at end' },
|
|
41
|
-
{
|
|
42
|
-
command: 'git commit -nm "test"',
|
|
43
|
-
description: 'commit with combined -nm flags',
|
|
44
|
-
},
|
|
45
|
-
// Edge cases
|
|
46
|
-
{
|
|
47
|
-
command: 'ls && git commit --no-verify -m "test"',
|
|
48
|
-
description: 'chained command with --no-verify',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
command: 'git -C /path commit --no-verify -m "test"',
|
|
52
|
-
description: 'git with -C flag and --no-verify',
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
command: 'git commit --no-verify -m "test"',
|
|
56
|
-
description: 'extra whitespace with --no-verify',
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
/**
|
|
60
|
-
* Commands that should be allowed (no --no-verify)
|
|
61
|
-
*/
|
|
62
|
-
const ALLOWED_COMMANDS = [
|
|
63
|
-
// Normal git commands
|
|
64
|
-
{ command: 'git commit -m "test"', description: 'normal commit' },
|
|
65
|
-
{
|
|
66
|
-
command: 'git commit -m "feat: add feature"',
|
|
67
|
-
description: 'commit with conventional message',
|
|
68
|
-
},
|
|
69
|
-
{ command: 'git push origin main', description: 'normal push' },
|
|
70
|
-
{ command: 'git push -u origin feature', description: 'push with upstream' },
|
|
71
|
-
{ command: 'git merge feature', description: 'normal merge' },
|
|
72
|
-
{ command: 'git cherry-pick abc123', description: 'normal cherry-pick' },
|
|
73
|
-
{ command: 'git rebase main', description: 'normal rebase' },
|
|
74
|
-
{ command: 'git am < patch', description: 'normal am' },
|
|
75
|
-
// Git commands that don't support --no-verify
|
|
76
|
-
{ command: 'git status', description: 'git status' },
|
|
77
|
-
{ command: 'git log --oneline', description: 'git log with oneline' }, // cspell:disable-line
|
|
78
|
-
{ command: 'git diff', description: 'git diff' },
|
|
79
|
-
{ command: 'git branch -a', description: 'git branch' },
|
|
80
|
-
{ command: 'git checkout main', description: 'git checkout' },
|
|
81
|
-
{ command: 'git pull origin main', description: 'git pull' },
|
|
82
|
-
{ command: 'git fetch --all', description: 'git fetch' },
|
|
83
|
-
{ command: 'git stash', description: 'git stash' },
|
|
84
|
-
// Non-git commands
|
|
85
|
-
{ command: 'npm install', description: 'npm install' },
|
|
86
|
-
{ command: 'pnpm build', description: 'pnpm build' },
|
|
87
|
-
{ command: 'yarn test', description: 'yarn test' },
|
|
88
|
-
{ command: 'ls -la', description: 'ls command' },
|
|
89
|
-
{ command: 'echo "hello"', description: 'echo command' },
|
|
90
|
-
// -n flag in non-commit contexts (different meaning)
|
|
91
|
-
{ command: 'git push -n origin main', description: 'push dry-run with -n' },
|
|
92
|
-
{ command: 'git merge -n feature', description: 'merge with -n (no commit)' },
|
|
93
|
-
{
|
|
94
|
-
command: 'git cherry-pick -n abc123',
|
|
95
|
-
description: 'cherry-pick with -n (no commit)',
|
|
96
|
-
},
|
|
97
|
-
// Commands with special characters
|
|
98
|
-
{
|
|
99
|
-
command: 'git commit -m "feat(scope): add feature #123"',
|
|
100
|
-
description: 'commit with special chars',
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
command: 'git commit -m "fix: handle edge case @user"',
|
|
104
|
-
description: 'commit with @ mention',
|
|
105
|
-
},
|
|
106
|
-
];
|
|
4
|
+
import { BLOCKED_COMMANDS } from './blocked-commands.js';
|
|
5
|
+
import { ALLOWED_COMMANDS } from './allowed-commands.js';
|
|
107
6
|
export const testCommands = {
|
|
108
7
|
BLOCKED_COMMANDS,
|
|
109
8
|
ALLOWED_COMMANDS,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-commands.js","sourceRoot":"","sources":["../../src/agents/test-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"test-commands.js","sourceRoot":"","sources":["../../src/agents/test-commands.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAIxD,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gBAAgB;IAChB,gBAAgB;CACjB,CAAA"}
|
package/dist/check-command.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CheckResult } from './check-result.js';
|
|
2
2
|
/**
|
|
3
|
-
* Checks a command input for --no-verify flag usage
|
|
3
|
+
* Checks a command input for --no-verify flag usage or hooks path override
|
|
4
4
|
*
|
|
5
5
|
* @param input - The command input to check (typically from stdin in Claude Code hooks)
|
|
6
6
|
* @returns CheckResult indicating whether the command should be blocked
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-command.d.ts","sourceRoot":"","sources":["../src/check-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"check-command.d.ts","sourceRoot":"","sources":["../src/check-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAKpD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAwBvD"}
|
package/dist/check-command.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { detectGitCommand } from './detect-git-command.js';
|
|
2
2
|
import { hasNoVerifyFlag } from './has-no-verify-flag.js';
|
|
3
|
+
import { hasHooksPathOverride } from './has-hooks-path-override.js';
|
|
3
4
|
/**
|
|
4
|
-
* Checks a command input for --no-verify flag usage
|
|
5
|
+
* Checks a command input for --no-verify flag usage or hooks path override
|
|
5
6
|
*
|
|
6
7
|
* @param input - The command input to check (typically from stdin in Claude Code hooks)
|
|
7
8
|
* @returns CheckResult indicating whether the command should be blocked
|
|
@@ -18,6 +19,13 @@ export function checkCommand(input) {
|
|
|
18
19
|
gitCommand,
|
|
19
20
|
};
|
|
20
21
|
}
|
|
22
|
+
if (hasHooksPathOverride(input)) {
|
|
23
|
+
return {
|
|
24
|
+
blocked: true,
|
|
25
|
+
reason: `BLOCKED: Overriding core.hooksPath is not allowed with git ${gitCommand}. Git hooks must not be bypassed.`,
|
|
26
|
+
gitCommand,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
21
29
|
return { blocked: false, gitCommand };
|
|
22
30
|
}
|
|
23
31
|
//# sourceMappingURL=check-command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-command.js","sourceRoot":"","sources":["../src/check-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"check-command.js","sourceRoot":"","sources":["../src/check-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AAEnE;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,MAAM,UAAU,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAE1C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAA;IAC3B,CAAC;IAED,IAAI,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QACvC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,qDAAqD,UAAU,mCAAmC;YAC1G,UAAU;SACX,CAAA;IACH,CAAC;IAED,IAAI,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,8DAA8D,UAAU,mCAAmC;YACnH,UAAU;SACX,CAAA;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;AACvC,CAAC"}
|
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the input contains a -c core.hooksPath= override
|
|
3
|
+
* which is used to bypass git hooks by redirecting the hooks directory
|
|
4
|
+
*/
|
|
5
|
+
export declare function hasHooksPathOverride(input: string): boolean;
|
|
6
|
+
//# sourceMappingURL=has-hooks-path-override.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-hooks-path-override.d.ts","sourceRoot":"","sources":["../src/has-hooks-path-override.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAI3D"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if the input contains a -c core.hooksPath= override
|
|
3
|
+
* which is used to bypass git hooks by redirecting the hooks directory
|
|
4
|
+
*/
|
|
5
|
+
export function hasHooksPathOverride(input) {
|
|
6
|
+
// Match: -c core.hooksPath=<value> with optional quotes around the value
|
|
7
|
+
// Handles: -c core.hooksPath=/dev/null, -c "core.hooksPath=", -c 'core.hooksPath=/tmp'
|
|
8
|
+
return /-c\s+["']?core\.hooksPath\s*=/.test(input);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=has-hooks-path-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"has-hooks-path-override.js","sourceRoot":"","sources":["../src/has-hooks-path-override.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,yEAAyE;IACzE,uFAAuF;IACvF,OAAO,+BAA+B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AACpD,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type { CheckResult } from './check-result.js';
|
|
|
10
10
|
export { EXIT_CODES } from './exit-codes.js';
|
|
11
11
|
export { detectGitCommand } from './detect-git-command.js';
|
|
12
12
|
export { hasNoVerifyFlag } from './has-no-verify-flag.js';
|
|
13
|
+
export { hasHooksPathOverride } from './has-hooks-path-override.js';
|
|
13
14
|
export { checkCommand } from './check-command.js';
|
|
14
15
|
export { parseInput } from './parse-input.js';
|
|
15
16
|
export type { InputFormat } from './input-format.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { GIT_COMMANDS_WITH_NO_VERIFY } from './types.js';
|
|
|
8
8
|
export { EXIT_CODES } from './exit-codes.js';
|
|
9
9
|
export { detectGitCommand } from './detect-git-command.js';
|
|
10
10
|
export { hasNoVerifyFlag } from './has-no-verify-flag.js';
|
|
11
|
+
export { hasHooksPathOverride } from './has-hooks-path-override.js';
|
|
11
12
|
export { checkCommand } from './check-command.js';
|
|
12
13
|
export { parseInput } from './parse-input.js';
|
|
13
14
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAA;AAGxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "block-no-verify",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "CLI tool to block --no-verify flag in git commands. Prevents AI agents from bypassing git hooks.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,6 +17,22 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsc",
|
|
22
|
+
"dev": "tsc --watch",
|
|
23
|
+
"test": "vitest",
|
|
24
|
+
"test:watch": "vitest --watch",
|
|
25
|
+
"test:coverage": "vitest --coverage",
|
|
26
|
+
"lint": "eslint .",
|
|
27
|
+
"lint:fix": "eslint . --fix",
|
|
28
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
29
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
30
|
+
"spell": "cspell lint '**/*.{ts,js,md,json}' --gitignore",
|
|
31
|
+
"spell:check": "cspell lint '**/*.{ts,js,md,json}' --gitignore",
|
|
32
|
+
"knip": "knip",
|
|
33
|
+
"prepare": "husky",
|
|
34
|
+
"release": "release-it"
|
|
35
|
+
},
|
|
20
36
|
"keywords": [
|
|
21
37
|
"git",
|
|
22
38
|
"no-verify",
|
|
@@ -32,6 +48,7 @@
|
|
|
32
48
|
"engines": {
|
|
33
49
|
"node": ">=20.0.0"
|
|
34
50
|
},
|
|
51
|
+
"packageManager": "pnpm@10.26.2",
|
|
35
52
|
"publishConfig": {
|
|
36
53
|
"access": "public"
|
|
37
54
|
},
|
|
@@ -47,6 +64,7 @@
|
|
|
47
64
|
"@commitlint/cli": "^20.3.1",
|
|
48
65
|
"@commitlint/config-conventional": "^20.3.1",
|
|
49
66
|
"@cspell/dict-he": "^4.0.5",
|
|
67
|
+
"@release-it/conventional-changelog": "^10.0.6",
|
|
50
68
|
"@types/node": "^25.0.3",
|
|
51
69
|
"@vitest/coverage-v8": "^4.0.16",
|
|
52
70
|
"cspell": "^9.4.0",
|
|
@@ -61,20 +79,5 @@
|
|
|
61
79
|
"release-it": "^19.2.3",
|
|
62
80
|
"typescript": "^5.9.3",
|
|
63
81
|
"vitest": "^4.0.16"
|
|
64
|
-
},
|
|
65
|
-
"scripts": {
|
|
66
|
-
"build": "tsc",
|
|
67
|
-
"dev": "tsc --watch",
|
|
68
|
-
"test": "vitest",
|
|
69
|
-
"test:watch": "vitest --watch",
|
|
70
|
-
"test:coverage": "vitest --coverage",
|
|
71
|
-
"lint": "eslint .",
|
|
72
|
-
"lint:fix": "eslint . --fix",
|
|
73
|
-
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
74
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"",
|
|
75
|
-
"spell": "cspell lint '**/*.{ts,js,md,json}' --gitignore",
|
|
76
|
-
"spell:check": "cspell lint '**/*.{ts,js,md,json}' --gitignore",
|
|
77
|
-
"knip": "knip",
|
|
78
|
-
"release": "release-it"
|
|
79
82
|
}
|
|
80
|
-
}
|
|
83
|
+
}
|