O Hermes agora tem seu próprio package manager: o que pm doctor, repair e gc realmente corrigem

Uma manhã o hermes não sobe: um único ModuleNotFoundError, e tudo o que você fez ontem foi instalar um plugin. Ou o contrário — a mesma config funciona no seu laptop e no desktop alega que uma ferramenta não existe. Você abre o pip list para descobrir o porquê e encontra três ambientes Python, nenhum deles sabendo da existência dos outros.
É por isso que o Hermes carrega o seu próprio package manager. O hermes pm não gerencia o aplicativo Hermes (isso é o hermes update); ele gerencia a camada de baixo: binários de ferramentas e ambientes de dependências Python. Depois que essa linha fica clara, cada subcomando tem um lugar óbvio.
O que ele gerencia
A documentação resume em três tarefas: instalar binários de ferramentas fixados e colocá-los no PATH, preparar ambientes Python gerenciados para o Hermes, e explicar a diferença entre o que está declarado e o que está de fato instalado.
Os arquivos envolvidos têm cada um um papel, e confundi-los é o erro de leitura mais comum:
| Arquivo | Papel |
|---|---|
pm/lock.json |
Versões exatas das ferramentas gerenciadas, URLs por target, hashes SHA-256 |
pm/pyproject.toml + pm/uv.lock |
Requisitos Python e lock do próprio gerenciador de dependências |
pyproject.toml + uv.lock |
Requisitos, extras e marcadores de plataforma do projeto principal |
facts.json do tool-store |
Entradas de ferramentas instaladas, identidades, exports de ambiente, digests dos arquivos realizados |
facts.json por instalação |
O ambiente Python selecionado, o carimbo de entrada dele, extras habilitados |
Uma entrada no lockfile não prova que um pacote está instalado. Essa única frase explica o hermes pm doctor: ele compara o estado instalado com o lock e confere os bytes realizados.
Os quatro comandos do dia a dia
hermes pm status # o recibo mais recente de sync/update em JSON, ou um "no receipt" simples
hermes pm doctor # identidades, arquivos e digests das ferramentas batem com o lock?
hermes pm install # ferramentas necessárias + Python, depois sincroniza o extra all
hermes pm repair # reconstrói e valida o ambiente de dependências Python
status é o lugar mais barato para começar. Ele imprime o recibo mais recente — aqui está a saída real desta máquina, truncada:
{
"exit_code": 0,
"feature_list": null,
"finished_at": "2026-10-21T16:57:52.054592+00:00",
"kind": "plugin-check",
"outcome": "ok",
"plugin_checks": [],
"refusal": null,
"schema": 1,
"steps": [],
"update_id": null,
"venv_rebuild": null,
"warnings": []
}
outcome, refusal, warnings e steps normalmente bastam para distinguir sucesso de uma execução parcial ou de uma recusa.
install merece um parágrafo próprio. Um pm install sem argumentos instala as ferramentas necessárias mais o Python, coloca as ferramentas no PATH, sincroniza o extra all e também instala as ferramentas opcionais padrão — agent-browser com Chromium, e cua-driver. Uma falha no download dessas ferramentas opcionais imprime um aviso e não faz a instalação falhar, porque a maioria das pessoas só quer a CLI, não um navegador ou controle de desktop.
Se você as pulou na hora de instalar com --skip-browser ou --skip-computer-use, essa escolha fica registrada: instalações posteriores sem argumentos e o hermes update continuam deixando de fora. Para reverter, nomeie o pacote uma vez — hermes pm install agent-browser.
Reparando uma cadeia de dependências quebrada
repair e gc resolvem problemas diferentes; trocar um pelo outro é perda de tempo.
pm repair reproduz o conjunto de dependências registrado da geração selecionada numa nova geração, valida e então a seleciona. Crucialmente, ele não interpreta a configuração de plugins, então a config de plugin que quebrou suas dependências não é lida de novo. Ele também não altera pins, extras ou config de plugin. Se o registro estiver ilegível ou o lock salvo estiver faltando, ele falha em vez de te entregar um ambiente reduzido.
Na inicialização, o Hermes solicita o mesmo reparo quando encontra dependências incompletas, mas as tentativas automáticas têm limite; rodar pm repair explicitamente não tem.
pm gc remove o que nada referencia: entradas órfãs do tool-store, downloads parciais elegíveis, ambientes Python gerenciados por lease sem uso e o estado installs/INSTALL_KEY/ de checkouts que não existem mais. Ele é deliberadamente conservador — mantém checkouts que este processo não consegue ver (uma instalação de host vista de dentro de um container que compartilha o data root, por exemplo) e qualquer estado cujo lock de instalação ou lease de ambiente ainda esteja tomado.
Mnemônico de uma linha: quebrado é repair, inchado é gc.
Pins, a regra dos três dias e mirrors
Todo pacote Python do qual o Hermes depende precisa ter pelo menos três dias de idade quando o Hermes o fixa — o exclude-newer do uv, exigido pela checagem de lock da CI. A intenção é simples: um pacote publicado minutos atrás, possivelmente comprometido, não chega ao uv.lock.
A consequência prática: hermes pm lock é o passo que aplica a checagem, e contra um mirror que não publica horários de upload ele para com has no publish time. Quando ver isso, aponte esse único passo para https://pypi.org/simple; as instalações do dia a dia podem continuar passando pelo mirror.
Mirrors são configurados com index-url no pip.conf, que o Hermes repassa ao uv, ou com UV_INDEX_URL.
Downloads tentam de novo, hash errado não
Vale lembrar a política de retry:
- No máximo quatro tentativas por probe ou transferência, com backoff de 1, 2 e 4 segundos; um header
Retry-Afterpode estender a espera até 30 segundos. - Tentam de novo: 408, 429, 500, 502, 503, 504, além de resets de conexão, timeouts, falhas temporárias de DNS e corpos de resposta interrompidos.
- Downloads por faixa mantêm os bytes já recebidos; servidores sem suporte a range precisam de um stream novo.
- Não tentam de novo: hash divergente, falha de certificado, erro de filesystem local — falhas permanentes.
Então, se um download falha três vezes, leia a causa no log antes de culpar a rede.
Comandos de mantenedor, e a flag nova
Estas são ferramentas de desenvolvimento e empacotamento; a maioria dos usuários nunca precisa delas.
| Comando | Efeito |
|---|---|
pm lock |
Refaz o uv.lock a partir do pyproject.toml; não escreve nada quando o lock está atualizado |
pm lock --bump NAME VERSION |
Resolve e calcula o hash dos artefatos alvo, depois grava o pin da ferramenta em pm/lock.json |
pm update [names...] |
Consulta versões upstream, muda pins, instala as ferramentas alteradas |
pm update --check |
Consulta sem escrever; exit 1 pode significar que existem updates — leia a saída |
pm update --target TARGET |
Resolve versões para um target específico |
pm update --uv / --npm |
Também atualiza a resolução Python ou npm |
pm update --termux [--check] |
Refixa os arquivos do pool termux que o pool rolante aposentou |
pm bundle --out DIR |
Monta um payload portável (snapshot do código, ferramentas, dependências) — não um instalador assinado |
A nova pm update --skip-target TARGET resolve um incômodo específico: quando o upstream está atrasado, você não quer que os pins de um target em particular sejam atualizados. Digamos que o pool termux ainda está se recuperando e você quer que uma rodada de update deixe linux-arm64-bionic em paz — passe a flag (repetível) e esses pins ficam, enquanto execuções posteriores ainda reportam o pacote como atual.
Solução de problemas por sintoma
- Uma ferramenta está faltando ou na versão errada → leia o
pm doctor, depois instale explicitamente aquele pacote compm installnuma instalação gravável. - Conflito de dependências → leia o
pm status, corrija os requisitos declarados do plugin, tente de novo. - Dependências Python danificadas →
pm repair, depois reinicie o Hermes. - Um ambiente novo não entrou em vigor → reinicie o processo do Hermes afetado. Não adicione uma segunda árvore de site-packages a um import path vivo.
- Disco comido por ambientes antigos →
pm gc; se o disco já está cheio, nosso guia de auto-prune com pouco espaço cobre o lado de runtime. - Pacote ou extra desconhecido →
pm installaceita nomes de pacote, não nomes de extra do Python nem especificações pip do tiponame==version.
A inclinação do design
O hermes pm foi feito para falhar alto em vez de te entregar em silêncio um ambiente degradado. Uma tabela de custos malformada impede um servidor de carregar, um registro ilegível faz o repair falhar, um pool termux aposentado faz um update dar erro — tudo para que o problema apareça agora em vez de virar uma falha estranha na semana que vem.
Se tudo o que você quer é atualizar o próprio Hermes, você nunca precisa do pm; o guia de upgrade sem sobressaltos cobre esse outro caminho.