@@ -8,16 +8,30 @@ 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 && codeant secrets --committed --hook
32+ fi
33+ ${ HOOK_MARKER_END } `;
34+ }
2135 return `${ HOOK_MARKER }
2236# Auto-installed by CodeAnt AI — blocks pushes containing secrets.
2337# To disable: delete this hook or run "codeant push-protection disable"
@@ -81,9 +95,10 @@ function getHooksDir(gitRoot) {
8195 * Install a pre-push hook that runs secret scanning before push.
8296 *
8397 * @param {string } workspacePath - Path to the git repository
98+ * @param {string } [cliPath] - Absolute path to the codeant CLI entry point (from extension node_modules)
8499 * @returns {{ installed: boolean, hookPath: string|null, message: string } }
85100 */
86- export function installPushProtectionHook ( workspacePath ) {
101+ export function installPushProtectionHook ( workspacePath , cliPath ) {
87102 const gitRoot = findGitRoot ( workspacePath ) ;
88103 if ( ! gitRoot ) {
89104 return { installed : false , hookPath : null , message : 'Not a git repository' } ;
@@ -100,7 +115,7 @@ export function installPushProtectionHook(workspacePath) {
100115 const existing = readFileSync ( hookPath , 'utf-8' ) ;
101116 if ( existing . includes ( HOOK_MARKER ) ) {
102117 // Replace only our block, preserve everything else
103- const updated = replaceCodeAntBlock ( existing , buildHookBlock ( ) ) ;
118+ const updated = replaceCodeAntBlock ( existing , buildHookBlock ( cliPath ) ) ;
104119 writeFileSync ( hookPath , updated , 'utf-8' ) ;
105120 chmodSync ( hookPath , 0o755 ) ;
106121 return { installed : true , hookPath, message : 'Hook updated' } ;
@@ -111,13 +126,13 @@ export function installPushProtectionHook(workspacePath) {
111126 if ( ! isShellHook ) {
112127 return { installed : false , hookPath, message : 'Existing pre-push hook is non-shell; cannot append CodeAnt block safely' } ;
113128 }
114- const appended = existing . trimEnd ( ) + '\n\n' + buildHookBlock ( ) + '\n' ;
129+ const appended = existing . trimEnd ( ) + '\n\n' + buildHookBlock ( cliPath ) + '\n' ;
115130 writeFileSync ( hookPath , appended , 'utf-8' ) ;
116131 chmodSync ( hookPath , 0o755 ) ;
117132 return { installed : true , hookPath, message : 'Hook appended to existing pre-push' } ;
118133 }
119134
120- writeFileSync ( hookPath , buildHookScript ( ) , 'utf-8' ) ;
135+ writeFileSync ( hookPath , buildHookScript ( cliPath ) , 'utf-8' ) ;
121136 chmodSync ( hookPath , 0o755 ) ;
122137 return { installed : true , hookPath, message : 'Hook installed' } ;
123138}
0 commit comments