@@ -3365,21 +3365,33 @@ function watchMode(cwd, config) {
33653365// ---------------------------------------------------------------------------
33663366// Git hook installer
33673367// ---------------------------------------------------------------------------
3368- function installHook ( cwd ) {
3368+ function installHook ( cwd , scriptPath ) {
33693369 const hookDir = path . join ( cwd , '.git' , 'hooks' ) ;
33703370 if ( ! fs . existsSync ( hookDir ) ) {
33713371 console . warn ( '[context-forge] .git/hooks not found — skipping hook install' ) ;
33723372 return ;
33733373 }
33743374 const hookPath = path . join ( hookDir , 'post-commit' ) ;
3375- const hookLine = '\nnode "$(git rev-parse --show-toplevel)/gen-context.js" --generate 2>/dev/null || true\n' ;
3375+ const resolvedScript = path . resolve ( scriptPath ) ;
3376+ const hookLine = `\nnode ${ JSON . stringify ( resolvedScript ) } --generate 2>/dev/null || true\n` ;
33763377
33773378 if ( fs . existsSync ( hookPath ) ) {
33783379 const existing = fs . readFileSync ( hookPath , 'utf8' ) ;
3379- if ( existing . includes ( 'gen-context.js' ) ) {
3380+ const existingHookLines = existing . split ( '\n' ) . filter ( ( line ) => line . includes ( 'gen-context.js' ) ) ;
3381+ if ( existing . includes ( hookLine . trim ( ) ) && existingHookLines . length === 1 ) {
33803382 console . warn ( '[context-forge] post-commit hook already installed' ) ;
33813383 return ;
33823384 }
3385+ if ( existing . includes ( 'gen-context.js' ) ) {
3386+ const updated = existing
3387+ . split ( '\n' )
3388+ . filter ( ( line ) => ! line . includes ( 'gen-context.js' ) )
3389+ . join ( '\n' )
3390+ . replace ( / \n + $ / g, '\n' ) ;
3391+ fs . writeFileSync ( hookPath , updated . replace ( / \n ? $ / g, '' ) + hookLine ) ;
3392+ console . warn ( '[context-forge] updated post-commit hook' ) ;
3393+ return ;
3394+ }
33833395 fs . appendFileSync ( hookPath , hookLine ) ;
33843396 } else {
33853397 fs . writeFileSync ( hookPath , `#!/bin/sh${ hookLine } ` ) ;
@@ -3602,6 +3614,18 @@ function suggestTool(description) {
36023614 return { tier, label : info . label , models : info . examples , costHint : info . costHint } ;
36033615}
36043616
3617+ function resolveProjectRoot ( startDir ) {
3618+ try {
3619+ const gitRoot = execSync ( 'git rev-parse --show-toplevel' , {
3620+ cwd : startDir ,
3621+ encoding : 'utf8' ,
3622+ stdio : [ 'ignore' , 'pipe' , 'ignore' ] ,
3623+ } ) . trim ( ) ;
3624+ if ( gitRoot ) return gitRoot ;
3625+ } catch ( _ ) { }
3626+ return startDir ;
3627+ }
3628+
36053629function printHelp ( ) {
36063630 console . log ( `
36073631ContextForge — gen-context.js v${ VERSION }
@@ -3636,10 +3660,10 @@ Output: .github/copilot-instructions.md (default)
36363660// ---------------------------------------------------------------------------
36373661// MCP auto-registration
36383662// ---------------------------------------------------------------------------
3639- function registerMcp ( cwd ) {
3663+ function registerMcp ( cwd , scriptPath ) {
36403664 const serverEntry = {
36413665 command : 'node' ,
3642- args : [ path . resolve ( __dirname , 'gen-context.js' ) , '--mcp' ] ,
3666+ args : [ path . resolve ( scriptPath ) , '--mcp' ] ,
36433667 } ;
36443668
36453669 const targets = [
@@ -3669,7 +3693,13 @@ function registerMcp(cwd) {
36693693
36703694function main ( ) {
36713695 const args = process . argv . slice ( 2 ) ;
3672- const cwd = process . cwd ( ) ;
3696+ const invokedFrom = process . cwd ( ) ;
3697+ const cwd = resolveProjectRoot ( invokedFrom ) ;
3698+ const scriptPath = process . argv [ 1 ] || path . join ( invokedFrom , 'gen-context.js' ) ;
3699+
3700+ if ( cwd !== invokedFrom ) {
3701+ console . warn ( `[context-forge] using project root: ${ cwd } ` ) ;
3702+ }
36733703
36743704 if ( args . includes ( '--help' ) || args . includes ( '-h' ) ) {
36753705 printHelp ( ) ;
@@ -3765,8 +3795,8 @@ function main() {
37653795
37663796 if ( args . includes ( '--setup' ) ) {
37673797 runGenerate ( cwd , config , false ) ;
3768- installHook ( cwd ) ;
3769- registerMcp ( cwd ) ;
3798+ installHook ( cwd , scriptPath ) ;
3799+ registerMcp ( cwd , scriptPath ) ;
37703800 watchMode ( cwd , config ) ;
37713801 return ; // keep process alive for watch
37723802 }
0 commit comments