Skip to content

Commit cd76a08

Browse files
authored
Merge pull request #42 from CodeAnt-AI/Chhinna/san-antonio
fix: run secrets protection before commit (0.5.6)
2 parents 5d40348 + cf1bbcb commit cd76a08

6 files changed

Lines changed: 25 additions & 21 deletions

File tree

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [0.5.6] - 09/09/2026
4+
- Run secrets protection in a pre-commit hook with `--staged` instead of a pre-push hook.
5+
36
## [0.5.4] - 27/08/2026
47
- Stop silently falling back to app.codeant.ai for login on a custom/self-hosted base URL
58
- Added `set-dashboard-url`, `get-dashboard-url`, and `remove-dashboard-url` commands to explicitly configure the login dashboard URL

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "codeant-cli",
3-
"version": "0.5.5",
3+
"version": "0.5.6",
44
"description": "Code review CLI tool",
55
"type": "module",
66
"repository": {

src/components/SecretsUI.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ function BypassPrompt({ secrets, onSelect }) {
343343
{ label: "It's used in tests", value: 'used_in_tests' },
344344
{ label: "I'll fix it later", value: 'fix_later' },
345345
{ label: 'Other (type your reason)', value: 'other' },
346-
{ label: 'Cancel \u2014 block this push', value: 'cancel' },
346+
{ label: 'Cancel \u2014 block this commit', value: 'cancel' },
347347
];
348348

349349
useInput((input, key) => {

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ program
7272
.option('--base-commit <commit>', 'Compare against a specific commit (e.g. --base-commit HEAD~3)')
7373
.option('--include <paths>', 'Comma-separated list of file paths glob patterns to include')
7474
.option('--exclude <paths>', 'Comma-separated list of file paths glob patterns to exclude')
75-
.option('--hook', 'Running from pre-push hook (enables bypass prompt)')
75+
.option('--hook', 'Running from pre-commit hook (enables bypass prompt)')
7676
.action((options) => {
7777
let scanType = 'all';
7878
let lastNCommits = 1;

src/utils/installPushProtectionHook.js

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const HOOK_MARKER = '# codeant-push-protection';
66
const HOOK_MARKER_END = '# end-codeant-push-protection';
77

88
/**
9-
* Build the full pre-push hook script (with shebang).
9+
* Build the full pre-commit hook script (with shebang).
1010
*/
1111
function buildHookScript(cliPath) {
1212
return `#!/bin/sh
@@ -21,27 +21,28 @@ ${buildHookBlock(cliPath)}
2121
*/
2222
function buildHookBlock(cliPath) {
2323
if (cliPath) {
24+
const quotedCliPath = `'${cliPath.replace(/'/g, "'\\''")}'`;
2425
return `${HOOK_MARKER}
25-
# Auto-installed by CodeAnt AI — blocks pushes containing secrets.
26+
# Auto-installed by CodeAnt AI — blocks commits containing secrets.
2627
# To disable: delete this hook or run "codeant push-protection disable"
2728
# Uses the CLI bundled with the VS Code extension.
2829
# Reopen stdin from terminal so the CLI can show an interactive bypass prompt.
29-
# In non-interactive environments (CI), this silently fails and the push is blocked.
30+
# In non-interactive environments (CI), this silently fails and the commit is blocked.
3031
exec < /dev/tty 2>/dev/null || true
31-
if [ -f "${cliPath}" ] && command -v node >/dev/null 2>&1; then
32-
node "${cliPath}" secrets --committed --hook
32+
if [ -f ${quotedCliPath} ] && command -v node >/dev/null 2>&1; then
33+
node ${quotedCliPath} secrets --staged --hook
3334
else
3435
command -v codeant >/dev/null 2>&1 || exit 0
35-
codeant secrets --committed --hook
36+
codeant secrets --staged --hook
3637
fi
3738
${HOOK_MARKER_END}`;
3839
}
3940
return `${HOOK_MARKER}
40-
# Auto-installed by CodeAnt AI — blocks pushes containing secrets.
41+
# Auto-installed by CodeAnt AI — blocks commits containing secrets.
4142
# To disable: delete this hook or run "codeant push-protection disable"
4243
exec < /dev/tty 2>/dev/null || true
4344
command -v codeant >/dev/null 2>&1 || exit 0
44-
codeant secrets --committed --hook
45+
codeant secrets --staged --hook
4546
${HOOK_MARKER_END}`;
4647
}
4748

@@ -97,7 +98,7 @@ function getHooksDir(gitRoot) {
9798
}
9899

99100
/**
100-
* Install a pre-push hook that runs secret scanning before push.
101+
* Install a pre-commit hook that runs secret scanning before commit.
101102
*
102103
* @param {string} workspacePath - Path to the git repository
103104
* @param {string} [cliPath] - Absolute path to the codeant CLI entry point (from extension node_modules)
@@ -113,7 +114,7 @@ export function installPushProtectionHook(workspacePath, cliPath) {
113114
if (!existsSync(hooksDir)) {
114115
mkdirSync(hooksDir, { recursive: true });
115116
}
116-
const hookPath = path.join(hooksDir, 'pre-push');
117+
const hookPath = path.join(hooksDir, 'pre-commit');
117118

118119
// If hook already exists, check if it's ours
119120
if (existsSync(hookPath)) {
@@ -127,14 +128,14 @@ export function installPushProtectionHook(workspacePath, cliPath) {
127128
}
128129
// There's a user-managed hook — append only for shell hooks to avoid breaking non-shell scripts
129130
const firstLine = existing.split('\n', 1)[0] || '';
130-
const isShellHook = firstLine.startsWith('#!') ? /\/(ba|z|k)?sh(\s|$)/.test(firstLine) : true;
131+
const isShellHook = firstLine.startsWith('#!') ? /^#!\s*(?:\/\S*\/|\/usr\/bin\/env\s+(?:-S\s+)?)(ba|z|k)?sh(\s|$)/.test(firstLine) : true;
131132
if (!isShellHook) {
132-
return { installed: false, hookPath, message: 'Existing pre-push hook is non-shell; cannot append CodeAnt block safely' };
133+
return { installed: false, hookPath, message: 'Existing pre-commit hook is non-shell; cannot append CodeAnt block safely' };
133134
}
134135
const appended = existing.trimEnd() + '\n\n' + buildHookBlock(cliPath) + '\n';
135136
writeFileSync(hookPath, appended, 'utf-8');
136137
chmodSync(hookPath, 0o755);
137-
return { installed: true, hookPath, message: 'Hook appended to existing pre-push' };
138+
return { installed: true, hookPath, message: 'Hook appended to existing pre-commit' };
138139
}
139140

140141
writeFileSync(hookPath, buildHookScript(cliPath), 'utf-8');
@@ -143,7 +144,7 @@ export function installPushProtectionHook(workspacePath, cliPath) {
143144
}
144145

145146
/**
146-
* Remove the CodeAnt pre-push hook (or just our section if appended).
147+
* Remove the CodeAnt pre-commit hook (or just our section if appended).
147148
*
148149
* @param {string} workspacePath
149150
* @returns {{ removed: boolean, message: string }}
@@ -155,10 +156,10 @@ export function removePushProtectionHook(workspacePath) {
155156
}
156157

157158
const hooksDir = getHooksDir(gitRoot);
158-
const hookPath = path.join(hooksDir, 'pre-push');
159+
const hookPath = path.join(hooksDir, 'pre-commit');
159160

160161
if (!existsSync(hookPath)) {
161-
return { removed: false, message: 'No pre-push hook found' };
162+
return { removed: false, message: 'No pre-commit hook found' };
162163
}
163164

164165
const content = readFileSync(hookPath, 'utf-8');

0 commit comments

Comments
 (0)