npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

sshepherd

v0.0.6

Published

Framework de agentes que leva um dev sem experiencia de sysadmin do zero absoluto ate uma aplicacao publicada em VPS proprio, com servidor endurecido, deploy versionado e rollback em um comando.

Downloads

920

Readme

SSHepherd

Do "não tenho servidor" ao "publiquei e sei voltar atrás", sem virar sysadmin.

SSHepherd é um framework de agentes que instala na pasta da sua aplicação e cuida do seu VPS: escolha do provedor, criação da máquina, chave SSH, endurecimento, provisionamento, deploy versionado, rollback e diagnóstico.

Ele foi feito para uma pessoa específica: quem sabe programar e não sabe administrar servidor.

Instalação

cd sua-aplicacao
npx sshepherd install

Depois, abra seu agente (Claude Code, Codex ou compatível) e digite:

/sshp

Se você ainda não tem servidor, ele começa pelo Dia Zero e te acompanha até o SSH funcionar.

Requisitos: Node 18.20.2 ou superior, cliente OpenSSH (nativo em Windows 10+, macOS e Linux). O alvo remoto precisa ser Ubuntu 22.04/24.04 ou Debian 11/12.

Comandos do instalador

npx sshepherd install     # instala nesta pasta
npx sshepherd update      # atualiza agentes e scripts, preservando seus dados
npx sshepherd status      # estado da instalação, do Dia Zero e dos servidores
npx sshepherd uninstall   # remove, com opção de preservar perfis e logs

Engines suportadas

Claude Code, Codex, Cursor, Gemini CLI, Windsurf, Antigravity, Kiro, Opencode, Cline, Roo Code, GitHub Copilot, Aider e Amazon Q Developer. O instalador detecta quais estão presentes — pela pasta do projeto ou pelo binário no PATH — e já vem com elas marcadas.

Aviso de nova versão

A instalação registra um hook SessionStart no Claude Code que roda .sshepherd/bin/version-notice.js. Ele lê só o cache local, sai em ~130ms e nunca bloqueia a sessão; a checagem de rede acontece em processo destacado, valendo para a sessão seguinte. Quando há versão nova, o agente pergunta se pode atualizar — nunca atualiza sozinho. Nas engines sem hook, a mesma instrução vai no entry file.

O que ele faz

| Comando | O que faz | |---|---| | /sshp | Descobre em que ponto você está e roteia | | /sshp-setup | Dia Zero: provedor → máquina → chave → usuário não-root → servidor fechado | | /sshp-connect | Perfis de servidor, teste de conexão, histórico de auditoria | | /sshp-harden | Auditoria de segurança com nota 0–100 e correções | | /sshp-attack | Olha seu servidor do lado de quem ataca: o que responde e o que vaza | | /sshp-provision | Detecta sua stack e prepara o servidor | | /sshp-deploy | Publica, verifica saúde, volta versão | | /sshp-doctor | Diagnóstico quando algo para de funcionar | | /sshp-agents-help | Catálogo dos agentes |

O que sobe para o servidor

Sua pasta tem coisa que é sua e não do servidor: especificação, prompt de agente, material interno, planilha de preço. Mandar a pasta inteira transforma tudo isso em arquivo público.

Quem decide é o .sshepherdignore na raiz do projeto, criado na instalação, uma regra por linha no formato do rsync:

.env                # segredo
.reversa/           # frameworks de IA: especificacao e prompt
_reversa_*/
.claude/
.sshepherd/
.git/               # historico carrega segredo ja removido
node_modules/       # reconstruido no servidor
/aula/              # seu: material interno

Três coisas:

  • O Dia Zero termina aqui. O estágio 8 do /sshp-setup lista sua raiz, compara com o arquivo e pergunta item por item o que ele não tem como saber — aula/ é parte do site ou é seu material? Fecha mostrando os dois lados, o que vai e o que fica.
  • Existe um piso que você não derruba. .env, .env.*, .git/, .sshepherd/, *.pem, *.key, id_rsa, id_ed25519 são excluídos pelo script sempre, apagar a linha não adianta. Sem o arquivo, o deploy recusa publicar.
  • Na estratégia git ele não vale. O servidor clona do repositório, então quem manda é o .gitignore. Se .reversa/ está versionado, ele chega no servidor. Os agentes avisam antes.

O hacker do bem

/sshp-harden pergunta ao servidor como ele está configurado. /sshp-attack não pergunta nada: bate na porta e vê o que responde.

As duas coisas divergem mais do que parece. Firewall ativo e configurado certo, com o Postgres aberto para a internet do mesmo jeito — porque o Docker publica porta por cima do ufw e a regra do firewall não vale para ela. O harden dá nota alta. O attack mostra o banco exposto.

Três lentes:

  1. De fora, sem chave — que portas respondem pela internet. Banco de dados aberto é o achado mais comum e o mais grave; Redis e Mongo abrem sem senha por padrão.
  2. O que a aplicação entrega/.env, /.git/HEAD, docker-compose.yml, dump de banco, e a documentação do projeto servida como página.
  3. De dentro — permissão do arquivo de segredos, material interno publicado junto com o código, socket do Docker acessível, sudo sem senha.

E o vetor que é novo: a varredura ficou barata. Mapear um alvo era trabalho de horas de gente com paciência; hoje roda sozinho contra milhares de endereços ao mesmo tempo. Por isso um _reversa_sdd/prd.md exposto deixou de ser inofensivo — ele descreve sua regra de negócio em texto escrito para ser entendido. Era papel, virou mapa.

A base de ameaças

O que procurar não é lista fixa — uma lista de dois anos atrás procura buraco que já foi tapado e ignora o que está sendo usado agora. A base fica em .sshepherd/threats.db, uma linha por ameaça, legível a olho nu:

caminho|/.mcp.json|critica|conexoes do seu assistente de IA|Guarda os tokens...|<fonte>|2026-08-06
porta|9000|alta|painel do Portainer|Quem entra ali manda na maquina.|<fonte>|2026-08-06

O agente atualiza pesquisando na web, filtrando pela stack do projeto, e sempre mostra antes de gravar — com a fonte de cada item. Reinstalar não apaga o que ele aprendeu. Quando a base passa de 60 dias, o script avisa.

Só entra o que dá para detectar pedindo um endereço ou batendo numa porta. Nada que explore.

Os limites

Só examina servidor registrado em .sshepherd/servers/, e recusa qualquer outro endereço mostrando quais são os seus. Não explora, não tenta senha, não mede carga, não altera nada.

O pastor acha o buraco na cerca e chama o dono. Não atravessa, e não vai olhar a cerca do vizinho.

O Dia Zero

É a parte que os tutoriais não cobrem e onde a maioria desiste. O agente conduz do zero absoluto, aceita print de tela do painel do provedor para saber onde você está, e valida cada passo por comando — não por "parece que deu certo".

Termina quando cinco condições estão comprovadas:

  1. você entra por chave, como usuário que não é root
  2. login de root pela rede desligado
  3. login por senha desligado
  4. firewall ativo negando entrada
  5. atualizações automáticas de segurança ligadas

Provedores cobertos em detalhe: DigitalOcean, Hostinger, Contabo, Hetzner. Outros recebem o roteiro genérico.

Arquitetura

Três camadas, separadas de propósito:

 npm (bin/, lib/)      →  só instala e atualiza. Não toca em servidor.
 agents/ (markdown)    →  decidem, conversam, julgam contexto.
 scripts (.sshepherd/) →  executam no servidor. Determinísticos e auditáveis.

O agente é bom em julgar contexto e ruim em garantir determinismo. O script é o oposto. Por isso nenhum comando remoto é improvisado pelo modelo: tudo passa por script versionado, que você pode ler antes de rodar.

As regras que o framework não quebra

  1. Nada muda sem você ver o comando. Toda operação que altera o servidor mostra o comando exato e o alvo antes, e espera confirmação. Leitura e diagnóstico rodam livres.
  2. Comandos destrutivos são recusados sempre. Apagar o disco, parar o SSH, resetar o firewall — não há confirmação que libere.
  3. Nenhum caminho de acesso é fechado antes de o novo estar provado. É o que impede você de ficar trancado para fora do próprio servidor.
  4. A chave privada nunca é lida. O framework passa o caminho ao cliente SSH, nunca o conteúdo.
  5. Tudo fica registrado. Cada comando remoto vai para .sshepherd/logs/, com segredos redigidos — inclusive o que foi recusado ou bloqueado.
  6. root é usado uma única vez. No primeiro acesso, para criar o usuário deploy. Depois disso, nunca mais.

Deploy e rollback

Publicação em releases/<timestamp> com troca atômica do symlink current:

/srv/app/
├── releases/20260805143000/     ← nova
├── releases/20260805120000/     ← anterior, intacta
├── shared/.env                  ← sobrevive a todas as versões
└── current -> releases/20260805143000

Depois de publicar, o framework bate na porta da aplicação até 6 vezes. Se não responder, mostra o log e oferece o rollback como primeira ação. Voltar leva segundos, porque o código antigo já está no servidor.

O que ele não faz

  • Não cria a VPS pela API do provedor — acompanha você no painel
  • Não registra domínio
  • Não administra banco de dados (backup, migração, tuning)
  • Não roda migração de esquema, e o rollback não desfaz banco
  • Não deixa processo rodando no servidor
  • Não orquestra múltiplos servidores, nem Kubernetes

Estrutura instalada

seu-projeto/
├── .sshepherdignore         o que NAO sobe para o servidor (editavel)
├── .sshepherd/
│   ├── state.json           estado e estágio do onboarding
│   ├── config.toml          preferências (editável)
│   ├── servers/<id>.json    um arquivo por servidor
│   ├── logs/audit-*.jsonl   histórico, um evento por linha
│   ├── scripts/sh|ps/       os scripts que executam de fato
│   └── bin/version-notice.js  aviso de nova versão (Node puro)
├── .claude/skills/sshp*/
└── .agents/skills/sshp*/

servers/ e logs/ já vêm no .gitignore local: contêm endereço de servidor e histórico operacional.

Desenvolvimento

npm test              # 47 testes, executor nativo do node, sem framework de teste
npm run bump:check    # confere se package.json e os 9 agentes estão na mesma versão
npm run bump          # 0.0.2 -> 0.0.3, atualiza os 10 arquivos de uma vez

Os testes cobrem o detector das 13 engines, a estrutura instalada, preservação de dados em reinstalação, estado corrompido, o hook de sessão (criação, merge, não-duplicação, settings inválido), o manifesto SHA-256, created_files, o .sshepherdignore (criação, não-sobrescrita, recusa do deploy sem ele), os guard rails e a ausência de CRLF nos scripts.

Versionamento

Só o último número muda. 0.0.10.0.20.0.3 → ...

Sem major, sem minor. A versão aparece em package.json e no metadata de cada um dos 9 agentes — npm run bump mantém os dez em sincronia, e npm run bump:check acusa se algum ficou para trás.

Fluxo de release:

npm run bump                          # incrementa
# registre a mudança no CHANGELOG.md
git commit -am "v0.0.2: <o que mudou>"
git tag v0.0.2 && git push --follow-tags

Status

⚠️ Versão 0.0.2 — nunca executada contra um VPS real.

Validado: instalador, comandos, hook de versão, guard rails (bloqueio incondicional, redação de segredo, recusa sem confirmação, trava de alvo do attack), sintaxe e fim de linha dos scripts, 47 testes.

Do attack-surface.sh, a sondagem externa e a detecção de arquivo exposto foram exercitadas contra um servidor local montado para isso: portas, /.env, /.git/HEAD, listagem de diretório e banner de versão disparam corretamente. A parte que roda por SSH não foi validada contra máquina real.

Não validado: provision.sh, deploy.sh, rollback.sh, harden.sh e audit.sh contra um servidor de verdade. Use numa VPS descartável antes de apontar para produção. Os únicos que só leem, e portanto são seguros hoje, são o audit.sh e o attack-surface.sh.

Licença

MIT — sandeco