Stats
Actions
Tags
From feature-flow
On session start, refreshes file references for code-understanding accuracy. Before editing or writing files, reminds to use native OS tools first; afterward, verifies edits were applied correctly. On stop, runs an optional audit script.
4 events · 15 hooks
Safety signals detected in this hook configuration
Where this hook configuration is defined
Defined in hooks/hooks.json
Event handlers and matchers — expand Raw Configuration for the full JSON
node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/quality-gate.js180msWritenode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const f=i.tool_input?.file_path||'';if(!/\/src\/.*\.(ts|tsx|js|jsx|py|rb|go|rs)$/.test(f))process.exit(0);if(/\.(test|spec|d)\.(ts|tsx|js|jsx)$/.test(f)||/\/types\//.test(f))process.exit(0);if(!require('fs').existsSync('.feature-flow.yml'))process.exit(0);const yml=require('fs').readFileSync('.feature-flow.yml','utf8');if(!yml.includes('context7:'))process.exit(0);process.stderr.write('[feature-flow] REQUIRED: Before creating this source file, you MUST have queried Context7 docs for current patterns. Read the context7 field in .feature-flow.yml for library IDs, then query relevant libraries using mcp__plugin_context7_context7__query-docs.')}catch{}process.exit(0)})"node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const f=i.tool_input?.file_path||'';if(!/\/src\/.*\.(ts|tsx|js|jsx)$/.test(f)||/\.(test|spec|d)\.(ts|tsx|js|jsx)$/.test(f)||/\/types\//.test(f))process.exit(0);const c=i.tool_input?.content||'';const b=[];c.split('\n').forEach((l,n)=>{if(/:\s*any\b/.test(l)&&!/\/\//.test(l.split('any')[0]))b.push('L'+(n+1)+': `any` type — use a specific type or `unknown`');if(/\bas\s+any\b/.test(l)&&!/\/\//.test(l.split('as')[0]))b.push('L'+(n+1)+': `as any` — use a proper type assertion');if(/catch\s*\([^)]*\)\s*\{\s*\}/.test(l))b.push('L'+(n+1)+': empty catch block — handle or rethrow the error');});if(b.length)console.log('BLOCK: Fix these anti-patterns before writing '+f.split('/').pop()+':\n'+b.join('\n'))}catch{}process.exit(0)})"Editnode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const f=i.tool_input?.file_path||'';if(!/\/src\/.*\.(ts|tsx|js|jsx)$/.test(f)||/\.(test|spec|d)\.(ts|tsx|js|jsx)$/.test(f)||/\/types\//.test(f))process.exit(0);const s=i.tool_input?.new_string||'';const b=[];s.split('\n').forEach((l)=>{if(/:\s*any\b/.test(l)&&!/\/\//.test(l.split('any')[0]))b.push('`any` type — use a specific type or `unknown`');if(/\bas\s+any\b/.test(l)&&!/\/\//.test(l.split('as')[0]))b.push('`as any` — use a proper type assertion');if(/catch\s*\([^)]*\)\s*\{\s*\}/.test(l))b.push('empty catch block — handle or rethrow the error');});if(b.length)console.log('BLOCK: Fix these anti-patterns before editing '+f.split('/').pop()+':\n'+b.join('\n'))}catch{}process.exit(0)})"Agentnode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const t=i.tool_input||{};if(!t.subagent_type)process.exit(0);if(!t.model)console.log('BLOCK: Task/Agent dispatch to \"'+t.subagent_type+'\" is missing explicit `model` parameter. Set model: \"haiku\" (Explore), \"sonnet\" (general-purpose/Plan), or \"opus\" (creative phases). See references/tool-api.md.')}catch{}process.exit(0)})"Tasknode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const t=i.tool_input||{};if(!t.subagent_type)process.exit(0);if(!t.model)console.log('BLOCK: Task/Agent dispatch to \"'+t.subagent_type+'\" is missing explicit `model` parameter. Set model: \"haiku\" (Explore), \"sonnet\" (general-purpose/Plan), or \"opus\" (creative phases). See references/tool-api.md.')}catch{}process.exit(0)})"Skillnode ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/verdict-gate.jsWriteif echo "$CLAUDE_FILE_PATH" | grep -q 'plans/.*\.md'; then echo '[feature-flow] Plan file written. Run verify-plan-criteria before proceeding. (YOLO mode: this step runs automatically as part of the lifecycle — continue without pausing.)'; finode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const f=i.tool_input?.file_path||'';if(!/\/src\/.*\.(ts|tsx|js|jsx)$/.test(f)||/\.(test|spec|d)\.(ts|tsx|js|jsx)$/.test(f)||/\/types\//.test(f))process.exit(0);const c=require('fs').readFileSync(f,'utf8');const w=[];c.split('\n').forEach((l,n)=>{if(/console\.(log|debug)\(/.test(l)&&!/\/\//.test(l.split('console')[0]))w.push('L'+(n+1)+': console.log/debug');});if(w.length)console.log('[feature-flow] Debug statements in '+f.split('/').pop()+':\n'+w.join('\n')+'\nRemember to remove before self-review.')}catch{}process.exit(0)})"node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/lint-file.js30msEditnode -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const i=JSON.parse(d);const f=i.tool_input?.file_path||'';if(!/\/src\/.*\.(ts|tsx|js|jsx)$/.test(f)||/\.(test|spec|d)\.(ts|tsx|js|jsx)$/.test(f)||/\/types\//.test(f))process.exit(0);const s=i.tool_input?.new_string||'';if(/console\.(log|debug)\(/.test(s)&&!/\/\//.test(s.split('console')[0]))console.log('[feature-flow] console.log/debug added in '+f.split('/').pop()+'. Remember to remove before self-review.')}catch{}process.exit(0)})"node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/lint-file.js30msif [ -f .feature-flow.yml ]; then echo 'FEATURE-FLOW DEVELOPMENT ACTIVE: Use start: to begin any non-trivial work — it orchestrates the full lifecycle (design → verify → implement → ship). Rules: (1) Every task in an implementation plan MUST include **Acceptance Criteria:** with machine-verifiable - [ ] items. After writing a plan, run verify-plan-criteria. (2) Before claiming any task is complete, run verify-acceptance-criteria to mechanically check all criteria against the codebase. (3) Before writing new code, query Context7 docs for current patterns — library IDs are in .feature-flow.yml under context7. (4) Anti-pattern hooks BLOCK any types, as any, and empty catch blocks — fix before writing. console.log/debug is warned but allowed during TDD. (5) Stop hook runs tsc, lint, and type-sync checks — session cannot end with errors. (6) Tool API: Skill tool params are skill and args (NOT skill_name/arguments). Deferred tools (TaskCreate, TaskUpdate) must be loaded via ToolSearch before use. See references/tool-api.md for all tool syntax. Type "start: <description>" or "start: <description> --yolo" to begin.'; if ! grep -q 'context7:' .feature-flow.yml 2>/dev/null; then echo ''; echo 'UPGRADE NOTICE (v1.6.0): Your .feature-flow.yml is missing the context7 field. Run start: to auto-detect Context7 library IDs for your stack, or add them manually. New in v1.6.0: Context7 doc lookups, coding-standards.md, Study Existing Patterns step, Self-Review step, anti-pattern blocking hooks. See CHANGELOG.md for details.'; fi; else echo 'FEATURE-FLOW is installed. It helps you build features without mid-implementation surprises by adding a design and verification layer before you code. To start, just describe what you want to build: "start: add user notifications" -- feature-flow will auto-detect your tech stack, resolve Context7 documentation libraries, classify the scope, and walk you through the right steps. For a quick bug fix, just describe the problem — the lifecycle is lightweight: understand, fix, verify, commit. Type "start: <your idea, issue, or bug>" to get started. Add --yolo to auto-select defaults.'; finode ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/version-check.jsnode ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/advisor-hint.jsnpx claudepluginhub uta2000/feature-flow --plugin feature-flow