██████╗ ███████╗ ██╗ ██╗ ██████╗ ██████╗ ██╗ ██╗███████╗
██╔══██╗██╔════╝ ██║ ██║██╔═══██╗██╔═══██╗██║ ██╔╝██╔════╝
██████╔╝███████╗ ███████║██║ ██║██║ ██║█████╔╝ ███████╗
██╔═══╝ ╚════██║ ██╔══██║██║ ██║██║ ██║██╔═██╗ ╚════██║
██║ ███████║ ██║ ██║╚██████╔╝╚██████╔╝██║ ██╗███████║
╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
Claude Code hooks exclusivos para ProStaff API
╔══════════════════════════════════════════════════════════════════════════════╗
║ PS-HOOKS — Claude Code Developer Toolkit para ProStaff API ║
╠══════════════════════════════════════════════════════════════════════════════╣
║ Comprime output de CLI, injeta contexto de dominio e gerencia modo de ║
║ trabalho — exclusivo para sessoes no repositorio prostaff-api. ║
║ ║
║ rspec: ~85% menos tokens | brakeman: ~90% | rubocop: ~80% ║
╚══════════════════════════════════════════════════════════════════════════════╝
▶ Funcionalidades (clique para expandir)
┌─────────────────────────────────────────────────────────────────────────────┐
│ [■] Command Compressor — rspec, brakeman, rubocop, docker logs filtrados │
│ [■] Domain Detector — git status detecta modulo ativo automaticamente │
│ [■] Context Injector — injeta so o slice relevante do CLAUDE.md │
│ [■] Mode Commander — /ps:domain, /ps:check, /ps:full, /ps:help │
│ [■] Statusline Badge — [PS:AI] / [PS:AUTH] / [PS:MATCHES] etc │
│ [■] Zero Dependencies — Node.js stdlib apenas, sem npm install │
│ [■] Project-scoped — ativa exclusivamente em sessoes prostaff-api │
│ [■] Fail-safe — erro no filtro cai para output bruto, sem perda │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ 01 · Como Funciona │
│ 02 · Instalacao │
│ 03 · Hooks Implementados │
│ 04 · Filtros de Comandos │
│ 05 · Dominios ProStaff │
│ 06 · Comandos /ps: │
│ 07 · Statusline │
│ 08 · Estrutura do Projeto │
│ 09 · Referencia de Inspiracao │
└──────────────────────────────────────────────────────┘
Tres hooks independentes atuam em momentos diferentes da sessao Claude Code:
SESSION START
─────────────
session-start.js
→ git status do prostaff-api
→ detecta dominio ativo (auth / ai / matches / ...)
→ injeta contexto minimo especifico ao dominio
→ escreve flag para statusline
DURANTE A SESSAO (por tool call Bash)
──────────────────────────────────────
pre-tool-use.js (PreToolUse hook)
→ le o comando Bash que Claude quer executar
→ verifica se e um comando ProStaff conhecido
→ reescreve para: node ps-filter.js <tipo> -- <comando original>
→ ps-filter.js executa o comando real + comprime output
POR MENSAGEM
────────────
user-prompt-submit.js (UserPromptSubmit hook)
→ detecta /ps: slash commands
→ responde com info de dominio, instrucoes, etc
Fluxo do command compressor em detalhe:
Claude executa: bundle exec rspec spec/controllers/players_controller_spec.rb
|
pre-tool-use.js intercepta (PreToolUse)
|
reescreve o comando para:
node /path/bin/ps-filter.js rspec -- bundle exec rspec spec/...
|
ps-filter.js roda o comando original via sh -c
|
lib/filters/rspec.js comprime o output
|
Claude ve:
FAILURES (1):
1) PlayersController GET /players returns players list
Error: expected the response to have status code 200 but it was 401
At: ./spec/controllers/api/v1/players_controller_spec.rb:45
SUMMARY: 45 examples, 1 failure
# Clonar / acessar o projeto
cd /home/bullet/PROJETOS/prostaff-hooks
# Instalar hooks no prostaff-api
bash install.shO install.sh injeta tres entradas em /home/bullet/PROJETOS/prostaff-api/.claude/settings.json:
{
"hooks": {
"SessionStart": [{ "hooks": [{ "type": "command", "command": "node .../hooks/session-start.js" }] }],
"PreToolUse": [{ "matcher": "Bash", "hooks": [{ ... "hooks/pre-tool-use.js" }] }],
"UserPromptSubmit": [{ "hooks": [{ ... "hooks/user-prompt-submit.js" }] }]
}
}Statusline (opcional) — adicione ao ~/.claude/settings.json:
{
"statusCommand": "/home/bullet/PROJETOS/prostaff-hooks/statusline.sh"
}Reiniciar o Claude Code para ativar.
╔══════════════════════╦════════════════════════════════════════════════════════╗
║ HOOK ║ ARQUIVO ║
╠══════════════════════╬════════════════════════════════════════════════════════╣
║ SessionStart ║ hooks/session-start.js ║
║ ║ → detecta dominio via git status ║
║ ║ → injeta contexto minimo do dominio ativo ║
╠══════════════════════╬════════════════════════════════════════════════════════╣
║ PreToolUse (Bash) ║ hooks/pre-tool-use.js ║
║ ║ → reescreve comandos conhecidos para ps-filter ║
║ ║ → ativa so em sessoes prostaff-api ║
╠══════════════════════╬════════════════════════════════════════════════════════╣
║ UserPromptSubmit ║ hooks/user-prompt-submit.js ║
║ ║ → processa /ps: slash commands ║
╚══════════════════════╩════════════════════════════════════════════════════════╝
Ativacao condicional: os hooks verificam transcript_path e process.cwd() — se nao incluirem prostaff-api, fazem process.exit(0) imediatamente sem interferir em outros projetos.
╔═══════════════════════════════╦═══════════════╦══════════════════════════════╗
║ COMANDO ORIGINAL ║ FILTRO ║ OUTPUT ║
╠═══════════════════════════════╬═══════════════╬══════════════════════════════╣
║ bundle exec rspec ║ rspec.js ║ Failures + summary apenas ║
║ rspec ║ ║ ~85% reducao ║
╠═══════════════════════════════╬═══════════════╬══════════════════════════════╣
║ brakeman ║ brakeman.js ║ HIGH/MEDIUM apenas ║
║ (injeta -f json auto) ║ ║ ~90% reducao ║
╠═══════════════════════════════╬═══════════════╬══════════════════════════════╣
║ bundle exec rubocop ║ rubocop.js ║ Agrupado por cop, top 10 ║
║ rubocop ║ ║ ~80% reducao ║
╠═══════════════════════════════╬═══════════════╬══════════════════════════════╣
║ docker compose logs ║ docker.js ║ Erros + ultimas 30 linhas ║
║ docker <container> logs ║ ║ ~70% reducao ║
╠═══════════════════════════════╬═══════════════╬══════════════════════════════╣
║ rails db:migrate ║ rails.js ║ Migrations + erros apenas ║
║ bundle exec rails db:migrate ║ ║ ~60% reducao ║
╚═══════════════════════════════╩═══════════════╩══════════════════════════════╝
▶ Exemplos de output comprimido
RSpec (antes: ~400 linhas, depois: ~10 linhas)
FAILURES (2):
1) Api::V1::PlayersController GET /api/v1/players returns players list
Error: expected the response to have status code 200 but it was 401
At: ./spec/controllers/api/v1/players_controller_spec.rb:45
2) Player model validates presence of summoner_name
Error: expected #<Player summoner_name: nil> to be valid
At: ./spec/models/player_spec.rb:12
SUMMARY: 89 examples, 2 failures
Brakeman (antes: ~200 linhas JSON, depois: ~8 linhas)
BRAKEMAN: 3 warnings (H:1 M:1 L:1)
HIGH:
app/controllers/players_controller.rb:45 [SQL Injection] Possible SQL injection
code: Player.where("summoner_name LIKE '#{params[:search]}'")
MEDIUM:
app/services/riot_sync_service.rb:12 [SSRF] Request to user-supplied URL
RuboCop (antes: ~500 linhas, depois: ~12 linhas)
RUBOCOP: 219 offenses em 145 files
TOP COPS:
[C] Metrics/MethodLength: 34x (app/services/riot_sync_service.rb:45, app/models/player.rb:120, ...)
[C] Metrics/CyclomaticComplexity: 18x (app/controllers/analytics/..., ...)
[C] Layout/TrailingWhitespace: 15x (app/controllers/..., ...)
...
O session-start.js detecta o dominio ativo lendo git status --short do prostaff-api e mapeando os arquivos modificados:
╔═════════════╦══════════════════════════════════╦══════════════════════════════╗
║ DOMINIO ║ DETECTADO POR ║ AGENT INDICADO ║
╠═════════════╬══════════════════════════════════╬══════════════════════════════╣
║ ai ║ modules/ai_intelligence/ ║ ai-intelligence-specialist ║
║ auth ║ modules/authentication/ ║ security-specialist ║
║ analytics ║ analytics/ ║ rails-api-engineer ║
║ scouting ║ scouting/ ║ rails-api-engineer ║
║ matches ║ matches/ ║ rails-api-engineer ║
║ ║ ║ lol-domain-expert ║
║ players ║ players/ ║ rails-api-engineer ║
║ infra ║ docker-compose, Gemfile, ║ devops-infra-specialist ║
║ ║ .github/workflows/ ║ ║
║ testing ║ spec/ ║ qa-specialist ║
║ general ║ (default) ║ rails-api-engineer ║
╚═════════════╩══════════════════════════════════╩══════════════════════════════╝
Cada dominio injeta um contexto minimo (~5-8 linhas) em vez do CLAUDE.md completo (~300 linhas).
/ps:help # lista todos os comandos
/ps:domain # mostra o dominio detectado na sessao atual
/ps:domain <nome> # forca um dominio manualmente (ex: /ps:domain ai)
/ps:check # instrucoes para rodar brakeman + rubocop comprimidos
/ps:full # desabilita compression para esta sessao (debug)Para rodar os filtros manualmente (sem hooks ativos):
node /home/bullet/PROJETOS/prostaff-hooks/bin/ps-filter.js rspec -- bundle exec rspec
node /home/bullet/PROJETOS/prostaff-hooks/bin/ps-filter.js brakeman -- brakeman
node /home/bullet/PROJETOS/prostaff-hooks/bin/ps-filter.js rubocop -- bundle exec rubocop --format jsonO statusline.sh le o arquivo flag ~/.claude/.ps-domain e exibe o badge do dominio ativo:
[PS:AI] [PS:AUTH] [PS:ANALYTICS] [PS:SCOUTING]
[PS:MATCHES] [PS:PLAYERS] [PS:INFRA] [PS:TEST]
Configurar em ~/.claude/settings.json:
{
"statusCommand": "/home/bullet/PROJETOS/prostaff-hooks/statusline.sh"
}prostaff-hooks/
├── PRD.md # Product Requirements Document
├── README.md
├── package.json # Sem dependencias externas
├── install.sh # Injeta hooks no prostaff-api/.claude/settings.json
├── statusline.sh # Badge [PS:DOMINIO] para statusline
│
├── hooks/
│ ├── pre-tool-use.js # PreToolUse: reescreve comandos -> ps-filter
│ ├── session-start.js # SessionStart: dominio + contexto minimo
│ └── user-prompt-submit.js # UserPromptSubmit: /ps: commands
│
├── bin/
│ └── ps-filter.js # CLI: executa cmd original + aplica filtro
│
├── lib/
│ ├── domain-detector.js # git status -> dominio (modulo isolado p/ testes)
│ └── filters/
│ ├── rspec.js # Failures + summary
│ ├── brakeman.js # HIGH/MEDIUM apenas (parse JSON)
│ ├── rubocop.js # Agrupado por cop, top 10
│ ├── docker.js # Erros + ultimas 30 linhas significativas
│ └── rails.js # Migrations executadas + erros
│
└── skills/
└── ps-check/
└── SKILL.md # Skill Claude Code para /ps:check
╔══════════════════╦═════════════════════════════════════════════════════════════╗
║ PROJETO ║ CONTRIBUICAO PARA PROSTAFF-HOOKS ║
╠══════════════════╬═════════════════════════════════════════════════════════════╣
║ RTK ║ Arquitetura PreToolUse rewrite — ps-filter.js segue o ║
║ (Rust Token ║ mesmo padrao: interceptar, executar real, comprimir, ║
║ Killer) ║ preservar exit code. 100+ comandos genericos → 6 especificos║
╠══════════════════╬═════════════════════════════════════════════════════════════╣
║ Caveman ║ SessionStart hook para injecao de contexto. Flag file para ║
║ ║ comunicar estado entre hooks (session-start → statusline). ║
║ ║ UserPromptSubmit para /ps: slash commands. ║
╚══════════════════╩═════════════════════════════════════════════════════════════╝
Diferenciais exclusivos do prostaff-hooks:
- Filtros escritos para o formato exato de output do ProStaff (brakeman com
-f json, rubocop--format json) - Domain detection mapeada para os 8 modulos do ProStaff API
- Contexto de dominio inclui regras de segurança especificas (
organization_scoped,SHA256, SSRF whitelist) e o agente Claude Code indicado para cada modulo - Project-scoped: zero interferencia em outros projetos
- Nenhuma dependencia npm — startup < 20ms por invocacao
Projeto privado · ProStaff.gg · 2026