npx claudepluginhub aventerica89/claude-codex --plugin claude-codexDefined in hooks/hooks.json
*node -e "const{execSync}=require('child_process');const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{execSync('git rev-parse --git-dir',{stdio:'pipe'})}catch{console.log(d);process.exit(0)}try{const files=execSync('git diff --name-only HEAD',{encoding:'utf8',stdio:['pipe','pipe','pipe']}).split('\n').filter(f=>/\.(ts|tsx|js|jsx)$/.test(f)&&fs.existsSync(f));let hasConsole=false;for(const f of files){if(fs.readFileSync(f,'utf8').includes('console.log')){console.error('[Hook] WARNING: console.log found in '+f);hasConsole=true}}if(hasConsole)console.error('[Hook] Remove console.log statements before committing')}catch(e){}console.log(d)})"*node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/pre-compact.js"tool == "Bash" && tool_input.command matches "(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)"node -e "console.error('[Hook] BLOCKED: Dev server must run in tmux for log access');console.error('[Hook] Use: tmux new-session -d -s dev \"npm run dev\"');console.error('[Hook] Then: tmux attach -t dev');process.exit(1)"tool == "Bash" && tool_input.command matches "(npm (install|test)|pnpm (install|test)|yarn (install|test)?|bun (install|test)|cargo build|make|docker|pytest|vitest|playwright)"node -e "if(!process.env.TMUX){console.error('[Hook] Consider running in tmux for session persistence');console.error('[Hook] tmux new -s dev | tmux attach -t dev')}"tool == "Bash" && tool_input.command matches "git push"node -e "console.error('[Hook] Review changes before push...');console.error('[Hook] Continuing with push (remove this hook to add interactive review)')"tool == "Write" && tool_input.file_path matches "\\.(md|txt)$" && !(tool_input.file_path matches "README\\.md|CLAUDE\\.md|AGENTS\\.md|CONTRIBUTING\\.md")node -e "const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path||'';if(/\.(md|txt)$/.test(p)&&!/(README|CLAUDE|AGENTS|CONTRIBUTING)\.md$/.test(p)){console.error('[Hook] BLOCKED: Unnecessary documentation file creation');console.error('[Hook] File: '+p);console.error('[Hook] Use README.md for documentation instead');process.exit(1)}console.log(d)})"tool == "Edit" || tool == "Write"node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/suggest-compact.js"*node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/session-end.js"*node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/evaluate-session.js"tool == "Bash"node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const cmd=i.tool_input?.command||'';if(/gh pr create/.test(cmd)){const out=i.tool_output?.output||'';const m=out.match(/https:\/\/github.com\/[^/]+\/[^/]+\/pull\/\d+/);if(m){console.error('[Hook] PR created: '+m[0]);const repo=m[0].replace(/https:\/\/github.com\/([^/]+\/[^/]+)\/pull\/\d+/,'$1');const pr=m[0].replace(/.*\/pull\/(\d+)/,'$1');console.error('[Hook] To review: gh pr review '+pr+' --repo '+repo)}}console.log(d)})"tool == "Edit" && tool_input.file_path matches "\\.(ts|tsx|js|jsx)$"node -e "const{execSync}=require('child_process');const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path;if(p&&fs.existsSync(p)){try{execSync('npx prettier --write "'+p+'"',{stdio:['pipe','pipe','pipe']})}catch(e){}}console.log(d)})"tool == "Edit" && tool_input.file_path matches "\\.(ts|tsx)$"node -e "const{execSync}=require('child_process');const fs=require('fs');const path=require('path');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path;if(p&&fs.existsSync(p)){let dir=path.dirname(p);while(dir!==path.dirname(dir)&&!fs.existsSync(path.join(dir,'tsconfig.json'))){dir=path.dirname(dir)}if(fs.existsSync(path.join(dir,'tsconfig.json'))){try{const r=execSync('npx tsc --noEmit --pretty false 2>&1',{cwd:dir,encoding:'utf8',stdio:['pipe','pipe','pipe']});const lines=r.split('\n').filter(l=>l.includes(p)).slice(0,10);if(lines.length)console.error(lines.join('\n'))}catch(e){const lines=(e.stdout||'').split('\n').filter(l=>l.includes(p)).slice(0,10);if(lines.length)console.error(lines.join('\n'))}}}console.log(d)})"tool == "Edit" && tool_input.file_path matches "\\.(ts|tsx|js|jsx)$"node -e "const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path;if(p&&fs.existsSync(p)){const c=fs.readFileSync(p,'utf8');const lines=c.split('\n');const matches=[];lines.forEach((l,idx)=>{if(/console\.log/.test(l))matches.push((idx+1)+': '+l.trim())});if(matches.length){console.error('[Hook] WARNING: console.log found in '+p);matches.slice(0,5).forEach(m=>console.error(m));console.error('[Hook] Remove console.log before committing')}}console.log(d)})"*node "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/session-start.js"Executes Python hooks for code quality enforcement: lints and verifies edits/writes, checks atomic constraints and prose, guards image reads, detects bash overflows, logs PRs, scans patterns. Touches bash and files.