@@ -8,16 +8,31 @@ const HOOK_MARKER_END = '# end-codeant-push-protection';
88/**
99 * Build the full pre-push hook script (with shebang).
1010 */
11- function buildHookScript ( ) {
11+ function buildHookScript ( cliPath ) {
1212 return `#!/bin/sh
13- ${ buildHookBlock ( ) }
13+ ${ buildHookBlock ( cliPath ) }
1414` ;
1515}
1616
1717/**
1818 * Build just the CodeAnt block (no shebang), used when appending to an existing hook.
19+ * If cliPath is provided, uses the absolute path to the extension-bundled CLI via node.
20+ * Otherwise falls back to the global `codeant` command.
1921 */
20- function buildHookBlock ( ) {
22+ function buildHookBlock ( cliPath ) {
23+ if ( cliPath ) {
24+ return `${ HOOK_MARKER }
25+ # Auto-installed by CodeAnt AI — blocks pushes containing secrets.
26+ # To disable: delete this hook or run "codeant push-protection disable"
27+ # Uses the CLI bundled with the VS Code extension.
28+ if [ -f "${ cliPath } " ]; then
29+ node "${ cliPath } " secrets --committed --hook
30+ else
31+ command -v codeant >/dev/null 2>&1 || exit 0
32+ codeant secrets --committed --hook
33+ fi
34+ ${ HOOK_MARKER_END } `;
35+ }
2136 return `${ HOOK_MARKER }
2237# Auto-installed by CodeAnt AI — blocks pushes containing secrets.
2338# To disable: delete this hook or run "codeant push-protection disable"
@@ -81,9 +96,10 @@ function getHooksDir(gitRoot) {
8196 * Install a pre-push hook that runs secret scanning before push.
8297 *
8398 * @param {string } workspacePath - Path to the git repository
99+ * @param {string } [cliPath] - Absolute path to the codeant CLI entry point (from extension node_modules)
84100 * @returns {{ installed: boolean, hookPath: string|null, message: string } }
85101 */
86- export function installPushProtectionHook ( workspacePath ) {
102+ export function installPushProtectionHook ( workspacePath , cliPath ) {
87103 const gitRoot = findGitRoot ( workspacePath ) ;
88104 if ( ! gitRoot ) {
89105 return { installed : false , hookPath : null , message : 'Not a git repository' } ;
@@ -100,7 +116,7 @@ export function installPushProtectionHook(workspacePath) {
100116 const existing = readFileSync ( hookPath , 'utf-8' ) ;
101117 if ( existing . includes ( HOOK_MARKER ) ) {
102118 // Replace only our block, preserve everything else
103- const updated = replaceCodeAntBlock ( existing , buildHookBlock ( ) ) ;
119+ const updated = replaceCodeAntBlock ( existing , buildHookBlock ( cliPath ) ) ;
104120 writeFileSync ( hookPath , updated , 'utf-8' ) ;
105121 chmodSync ( hookPath , 0o755 ) ;
106122 return { installed : true , hookPath, message : 'Hook updated' } ;
@@ -111,13 +127,13 @@ export function installPushProtectionHook(workspacePath) {
111127 if ( ! isShellHook ) {
112128 return { installed : false , hookPath, message : 'Existing pre-push hook is non-shell; cannot append CodeAnt block safely' } ;
113129 }
114- const appended = existing . trimEnd ( ) + '\n\n' + buildHookBlock ( ) + '\n' ;
130+ const appended = existing . trimEnd ( ) + '\n\n' + buildHookBlock ( cliPath ) + '\n' ;
115131 writeFileSync ( hookPath , appended , 'utf-8' ) ;
116132 chmodSync ( hookPath , 0o755 ) ;
117133 return { installed : true , hookPath, message : 'Hook appended to existing pre-push' } ;
118134 }
119135
120- writeFileSync ( hookPath , buildHookScript ( ) , 'utf-8' ) ;
136+ writeFileSync ( hookPath , buildHookScript ( cliPath ) , 'utf-8' ) ;
121137 chmodSync ( hookPath , 0o755 ) ;
122138 return { installed : true , hookPath, message : 'Hook installed' } ;
123139}
0 commit comments