/**
* Phase 5: Git Hooks Templates
* Pre-commit hooks for code quality and cost tracking
*/
export const PRE_COMMIT_HOOK = `#!/bin/sh
# AI MCP Gateway - Pre-commit Hook
# Auto-generated by AI MCP Gateway CLI
echo "๐ค AI MCP Gateway Pre-commit Check..."
# Run type checking
echo "๐ Type checking..."
npm run type-check
if [ $? -ne 0 ]; then
echo "โ Type checking failed"
exit 1
fi
# Run linting
echo "๐ Linting..."
npm run lint
if [ $? -ne 0 ]; then
echo "โ Linting failed"
exit 1
fi
# Run tests
echo "๐งช Running tests..."
npm run test
if [ $? -ne 0 ]; then
echo "โ Tests failed"
exit 1
fi
# Check for large files
echo "๐ฆ Checking file sizes..."
large_files=$(git diff --cached --name-only | xargs ls -lh | awk '$5 > "1M" {print $9}')
if [ -n "$large_files" ]; then
echo "โ ๏ธ Large files detected:"
echo "$large_files"
echo "Consider using Git LFS for large files"
fi
echo "โ
Pre-commit checks passed!"
exit 0
`;
export const POST_COMMIT_HOOK = `#!/bin/sh
# AI MCP Gateway - Post-commit Hook
# Track commit for AI analysis
echo "๐ Logging commit for AI analysis..."
# Get commit info
commit_hash=$(git rev-parse HEAD)
commit_message=$(git log -1 --pretty=%B)
files_changed=$(git diff-tree --no-commit-id --name-only -r HEAD)
# Log to AI MCP Gateway (optional)
# curl -X POST http://localhost:3000/v1/git/commit \\
# -H "Content-Type: application/json" \\
# -d "{
# \\"hash\\": \\"$commit_hash\\",
# \\"message\\": \\"$commit_message\\",
# \\"files\\": \\"$files_changed\\"
# }"
echo "โ
Commit logged"
`;
export const PREPARE_COMMIT_MSG_HOOK = `#!/bin/sh
# AI MCP Gateway - Prepare Commit Message Hook
# Auto-generate commit message using AI
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
# Only run for regular commits (not merge/squash)
if [ "$COMMIT_SOURCE" = "" ]; then
echo "๐ค Generating AI commit message..."
# Get staged changes
staged_diff=$(git diff --cached)
# Call AI MCP Gateway to generate commit message
# ai_message=$(curl -s -X POST http://localhost:3000/v1/code-agent \\
# -H "Content-Type: application/json" \\
# -d "{
# \\"mode\\": \\"commit-message\\",
# \\"diff\\": \\"$staged_diff\\"
# }" | jq -r '.message')
# For now, just add a template
cat > "$COMMIT_MSG_FILE" << EOF
# AI-suggested commit message (edit as needed):
#
#
# Staged changes:
# $(git diff --cached --name-only)
EOF
fi
`;
export const PRE_PUSH_HOOK = `#!/bin/sh
# AI MCP Gateway - Pre-push Hook
# Final checks before pushing
echo "๐ AI MCP Gateway Pre-push Check..."
# Check if main branch
current_branch=$(git symbolic-ref --short HEAD)
if [ "$current_branch" = "main" ] || [ "$current_branch" = "master" ]; then
echo "โ ๏ธ Pushing to $current_branch"
read -p "Are you sure? (y/N): " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "โ Push cancelled"
exit 1
fi
fi
# Run full test suite
echo "๐งช Running full test suite..."
npm run test:all
if [ $? -ne 0 ]; then
echo "โ Tests failed"
exit 1
fi
# Check for console.log statements
echo "๐ Checking for debug statements..."
debug_files=$(git diff origin/$current_branch..HEAD --name-only | xargs grep -l "console.log" || true)
if [ -n "$debug_files" ]; then
echo "โ ๏ธ Debug statements found:"
echo "$debug_files"
read -p "Continue anyway? (y/N): " confirm
if [ "$confirm" != "y" ] && [ "$confirm" != "Y" ]; then
echo "โ Push cancelled"
exit 1
fi
fi
echo "โ
Pre-push checks passed!"
exit 0
`;
/**
* Git hooks installer
*/
export class GitHooksInstaller {
private hooksDir: string;
constructor(gitDir = '.git') {
this.hooksDir = `${gitDir}/hooks`;
}
/**
* Install all hooks
*/
async installAll(): Promise<void> {
const hooks = {
'pre-commit': PRE_COMMIT_HOOK,
'post-commit': POST_COMMIT_HOOK,
'prepare-commit-msg': PREPARE_COMMIT_MSG_HOOK,
'pre-push': PRE_PUSH_HOOK,
};
for (const [name, content] of Object.entries(hooks)) {
await this.installHook(name, content);
}
}
/**
* Install specific hook
*/
async installHook(name: string, content: string): Promise<void> {
const { default: fs } = await import('fs/promises');
const { default: path } = await import('path');
const hookPath = path.join(this.hooksDir, name);
await fs.writeFile(hookPath, content, { mode: 0o755 });
console.log(`โ
Installed ${name} hook`);
}
/**
* Uninstall hook
*/
async uninstallHook(name: string): Promise<void> {
const { default: fs } = await import('fs/promises');
const { default: path } = await import('path');
const hookPath = path.join(this.hooksDir, name);
try {
await fs.unlink(hookPath);
console.log(`โ
Uninstalled ${name} hook`);
} catch (error) {
console.log(`โ ๏ธ Hook ${name} not found`);
}
}
}