npx claudepluginhub sehoon787/my-claude --plugin my-claudeDefined in hooks/hooks.json
node "$HOME/.claude/hooks/stop-profile-update.js"30000msnode "$HOME/.claude/hooks/stop-session-enforcement.js"5000msEdit|Writenode -e "const j=JSON.parse(require('fs').readFileSync(0,'utf8'));if(!j.agent_id){console.log(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',additionalContext:'BOSS PROTOCOL: You are the orchestrator. Delegate file modifications to specialist subagents (model=sonnet for implementation, model=haiku for trivial fixes). Direct edits are acceptable ONLY for 1-line trivial changes or plan/draft markdown files.'}}))}"5000msAgentbash -c 'mkdir -p ~/.gstack/analytics && node -e "const j=JSON.parse(require(\"fs\").readFileSync(0,\"utf8\"));const i=j.tool_input||{};process.stdout.write(JSON.stringify({agent:i.name||i.description||\"unknown\",model:i.model||\"unknown\",ts:new Date().toISOString(),tool:\"Agent\"})+\"\\n\")" >> ~/.gstack/analytics/agent-usage.jsonl 2>/dev/null || true'5000msEdit|Writenode -e "const fs=require('fs');const path=require('path');try{const briefingIdx='.briefing/INDEX.md';if(!fs.existsSync(briefingIdx)){process.exit(0)}const sf='.briefing/state.json';function rs(){try{return JSON.parse(fs.readFileSync(sf,'utf8'))}catch(e){return{}}}function ws(u){var s=rs();Object.assign(s,u);fs.writeFileSync(sf,JSON.stringify(s,null,2))}var st=rs();var counter=(parseInt(st.workCounter,10)||0)+1;ws({workCounter:counter});const today=new Date().toISOString().slice(0,10);let todayCount=0;for(const sub of['decisions','learnings']){const d='.briefing/'+sub;if(fs.existsSync(d)){todayCount+=fs.readdirSync(d).filter(f=>{try{return fs.statSync(d+'/'+f).mtime.toISOString().slice(0,10)===today}catch(e){return false}}).length}}var prev=parseInt(rs().prevEntryCount,10)||0;ws({prevEntryCount:todayCount});if(counter>=10&&todayCount===0){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PostToolUse',additionalContext:'[BriefingVault] WARNING: '+counter+' file edits this session, 0 decisions/learnings written to .briefing/. Write at least one entry to .briefing/decisions/ or .briefing/learnings/ to document your work.'}})+'\n')}else if(counter>=3&&todayCount===0){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PostToolUse',additionalContext:'[BriefingVault] REQUIRED: You have made '+counter+' file edits this session and written no decisions/learnings to .briefing/. Write at least one decision or learning NOW before continuing. See rules/common/knowledge-vault.md.'}})+'\n')}process.exit(0)}catch(e){process.exit(0)}"5000msWebSearch|WebFetchnode -e "const fs=require('fs');try{if(!fs.existsSync('.briefing/INDEX.md')){process.exit(0)}const j=JSON.parse(require('fs').readFileSync(0,'utf8'));const url=j.tool_input&&(j.tool_input.url||j.tool_input.query||'');if(!url){process.exit(0)}const f='.briefing/references/auto-links.md';fs.mkdirSync('.briefing/references',{recursive:true});var existing='';if(fs.existsSync(f)){existing=fs.readFileSync(f,'utf8')}var line='- '+new Date().toISOString().slice(0,10)+' '+url;if(existing.indexOf(url)===-1){fs.appendFileSync(f,line+'\n')}}catch(e){process.exit(0)}"5000msnode "$HOME/.claude/scripts/validate-hooks.js"5000msbash "$HOME/.claude/hooks/session-start.sh"30000msnode -e "const fs=require('fs');const d='.briefing/agents';if(fs.existsSync('.briefing/INDEX.md')){fs.mkdirSync(d,{recursive:true});const j=JSON.parse(fs.readFileSync(0,'utf8'));var at=j.agent_type||'unknown';var pm={'explore':1,'Explore':1,'research':1,'deep-research':1,'executor':2,'implementer':2,'general-purpose':2,'Senior Developer':2,'code-reviewer':3,'security-reviewer':3,'tdd-guide':4,'planner':5,'Plan':5,'architect':5,'debugger':6};var ph=['','research','implement','review','test','plan','debug'][pm[at]||0]||'';var sf='.briefing/state.json';var st={};try{st=JSON.parse(fs.readFileSync(sf,'utf8'))}catch(e){}var sq=(parseInt(st.subagentSeq,10)||0)+1;st.subagentSeq=sq;fs.writeFileSync(sf,JSON.stringify(st,null,2));var th=(j.description||j.name||'').slice(0,120);var e={ts:new Date().toISOString(),agent_id:j.agent_id||'unknown',agent_type:at,phase:ph,seq:sq,task_hint:th};fs.appendFileSync(d+'/agent-log.jsonl',JSON.stringify(e)+'\n')}"5000msnode -e "console.log(JSON.stringify({hookSpecificOutput:{hookEventName:'SubagentStop',additionalContext:'VERIFICATION REQUIRED: Subagent finished. (1) Read changed files yourself, (2) Run tests/diagnostics to verify, (3) Only then mark task complete. Agent execution auto-logged to .briefing/agents/agent-log.jsonl.'}}))"5000msnode -e "console.log(JSON.stringify({hookSpecificOutput:{hookEventName:'TeammateIdle',additionalContext:'Teammate idle. Check TaskList — if all tasks done, send shutdown_request. If tasks remain, send next instructions.'}}))"5000msnode -e "console.log(JSON.stringify({hookSpecificOutput:{hookEventName:'TaskCompleted',additionalContext:'Task completed. Verify deliverable exists and check quality before accepting.'}}))"5000msnode -e "const fs=require('fs');const cp=require('child_process');try{if(!fs.existsSync('.briefing/INDEX.md')){process.exit(0)}const sf='.briefing/state.json';function rs(){try{return JSON.parse(fs.readFileSync(sf,'utf8'))}catch(e){return{}}}function ws(u){var s=rs();Object.assign(s,u);fs.writeFileSync(sf,JSON.stringify(s,null,2))}var st=rs();var counter=(parseInt(st.profileUpdateCounter,10)||0)+1;var smc=parseInt(st.sessionMessageCount,10)||1;if(smc===0||counter>=5){ws({profileUpdateCounter:counter>=5?0:counter});const stub=JSON.stringify({agent_id:'user-prompt-submit',agent_type:'throttled-update'});cp.spawnSync(process.execPath,[(process.env.HOME||process.env.USERPROFILE)+'/.claude/hooks/stop-profile-update.js'],{input:stub,stdio:['pipe','ignore','ignore'],timeout:9000})}else{ws({profileUpdateCounter:counter})}}catch(e){process.exit(0)}"10000msnode -e "const fs=require('fs');try{if(!fs.existsSync('.briefing/INDEX.md')){process.exit(0)}const sf='.briefing/state.json';function rs(){try{return JSON.parse(fs.readFileSync(sf,'utf8'))}catch(e){return{}}}function ws(u){var s=rs();Object.assign(s,u);fs.writeFileSync(sf,JSON.stringify(s,null,2))}var st=rs();var mc=(parseInt(st.sessionMessageCount,10)||0)+1;ws({sessionMessageCount:mc});if(mc<3){process.exit(0)}var lw=st.lastVaultWarning||'';if(lw&&(Date.now()-new Date(lw).getTime())<300000){process.exit(0)}const today=new Date().toISOString().slice(0,10);var wc=parseInt(rs().workCounter,10)||0;let hasAgent=false;try{const lp='.briefing/agents/agent-log.jsonl';if(fs.existsSync(lp)){hasAgent=fs.statSync(lp).mtime.toISOString().slice(0,10)===today}}catch(e){}let sessionCount=0;const sd='.briefing/sessions';if(fs.existsSync(sd)){sessionCount=fs.readdirSync(sd).filter(f=>{if(f.indexOf('-auto')!==-1)return false;try{return fs.statSync(sd+'/'+f).mtime.toISOString().slice(0,10)===today}catch(e){return false}}).length}let dlCount=0;for(const sub of['decisions','learnings']){const d='.briefing/'+sub;if(fs.existsSync(d)){dlCount+=fs.readdirSync(d).filter(f=>{if(f.indexOf('-auto')!==-1)return false;try{return fs.statSync(d+'/'+f).mtime.toISOString().slice(0,10)===today}catch(e){return false}}).length}}const total=sessionCount+dlCount;if(total>0&&sessionCount>0){var st2=rs();var lastSync=st2.lastVaultSync||'';var syncToday=lastSync&&lastSync.slice(0,10)===today;if(mc>=5&&!syncToday){ws({lastVaultWarning:new Date().toISOString()});process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'UserPromptSubmit',additionalContext:'[BriefingVault] Tip: run /boss-briefing to sync vault, update profile, and detect workflow patterns.'}})+'\n')}process.exit(0)}if(total>0&&sessionCount===0){ws({lastVaultWarning:new Date().toISOString()});process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'UserPromptSubmit',additionalContext:'[BriefingVault] You have written '+dlCount+' decisions/learnings but no session summary yet. Write .briefing/sessions/'+today+'-<topic>.md to document this conversation.'}})+'\n');process.exit(0)}ws({lastVaultWarning:new Date().toISOString()});if(mc>=6){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'UserPromptSubmit',additionalContext:'[BriefingVault] WARNING: '+mc+' messages exchanged, '+wc+' file edits, but 0 vault entries written today. Write a session summary, decision, or learning to .briefing/ to document your work.'}})+'\n')}else{process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'UserPromptSubmit',additionalContext:'[BriefingVault] REQUIRED: '+mc+' messages exchanged this session with '+wc+' file edits. Write at least one entry to .briefing/sessions/, .briefing/decisions/, or .briefing/learnings/ NOW. Template: ---\ndate: '+today+'\ntype: session\ntags: [relevant]\n---\n# Session: <topic>\n\n## Summary\n(what was discussed/decided/learned)'}})+'\n')}var st2=rs();var lastSync=st2.lastVaultSync||'';var syncToday=lastSync&&lastSync.slice(0,10)===today;if(mc>=5&&!syncToday){process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'UserPromptSubmit',additionalContext:'[BriefingVault] Tip: run /boss-briefing to sync vault, update profile, and detect workflow patterns.'}})+'\n')}process.exit(0)}catch(e){process.exit(0)}"5000msAutomates Persona Vault profile/summary updates on Stop; injects BOSS delegation protocol before Edit/Write tools; logs agent usage to JSONL and tracks briefing entries/compliance on PostToolUse. Writes files via Node scripts.
Share bugs, ideas, or general feedback.