grr — Google Workspace CLI + MCP server
Google Workspace a partir do terminal: 401 métodos em 14 APIs do Google em uma árvore de comandos gerada, além de um servidor MCP tipado (grr mcp). Binários de lançamento sem configuração, JSON na saída padrão, HTTP/3 com fallback honesto. Rust, MIT.
Documentação
grr
Ferramentas do Google no terminal, com desempenho máximo. grr-cli é um pacote Rust publicado, construído em torno do binário de linha de comando grr. Quatorze APIs do Google compartilham um único login OAuth e uma única árvore de comandos — gerada diretamente do próprio Discovery Service do Google — enquanto o stdout permanece limpo e legível por máquinas.
Site do projeto: grr-cli.pages.dev · Privacidade
O grr é um projeto independente e não é afiliado nem endossado pelo Google.
grr auth login
grr gmail users messages list --user-id me --q "in:inbox" --max-results 5
grr drive files list --page-size 10
grr api describe calendar.events.list
grr schema
Instalação
Binários pré-compilados — macOS arm64, Linux x86_64, Linux aarch64, Windows x86_64 e Windows em ARM (aarch64, Snapdragon X / Oryon): GitHub Releases
Os binários de lançamento são de configuração zero — um cliente OAuth é compilado internamente, então o grr auth login funciona imediatamente. Os arquivos são .tar.zst (zstd nível 22) no unix e .zip no Windows; os binários são empacotados com UPX usando --best --lzma quando o compressor suporta — o fluxo de trabalho verifica se a cópia empacotada ainda executa e, caso contrário, volta para o binário desempacotado com um aviso.
A partir do código-fonte (a compilação padrão da CLI requer Rust nightly — veja Desenvolvimento):
cargo install --git https://github.com/debanjanbasu/grr-cli
ou a partir de um clone local na raiz do repositório:
git clone https://github.com/debanjanbasu/grr-cli
cd grr-cli
cargo install --path .
Uma compilação a partir do código-fonte não possui cliente OAuth embutido — veja Autenticação e configuração.
Gerenciadores de pacotes:
winget install debanjanbasu.grr # Windows (manifest not yet published — see Packaging & status)
cargo install grr-cli # crates.io
Homebrew (macOS + Linux), a partir do tap debanjanbasu/tap:
brew tap debanjanbasu/tap
brew trust debanjanbasu/tap
brew install grr
O brew trust é obrigatório, não decorativo: desde o Homebrew 4.4, taps de terceiros não são confiáveis por padrão, e o brew install se recusa a instalar uma fórmula de um tap não confiável até que você confie nele uma vez. Pular essa linha é a falha mais comum na primeira execução.
A compilação da CLI via crates.io requer Rust nightly e RUSTFLAGS="--cfg reqwest_unstable" para HTTP/3; os lançamentos pré-compilados evitam essa etapa de compilação a partir do código-fonte. O cargo install também produz um binário sem cliente OAuth embutido, então reserve cinco minutos para o grr auth setup (ou um .env) nesse caminho.
Início rápido em 60 segundos
brew tap debanjanbasu/tap
brew trust debanjanbasu/tap
brew install grr
grr auth login
grr gmail users getProfile --user-id me
Não há nada para configurar primeiro: um binário de lançamento já carrega um cliente OAuth, então o grr auth login abre o navegador, você consente e todos os serviços funcionam. Máquina sem interface gráfica? O grr auth login --device imprime uma URL + código em vez de abrir o navegador.
Compilando a partir do código-fonte em vez de instalar um lançamento? Leia Autenticação e configuração antes da sua primeira invocação do grr.
Autenticação e configuração
Binários de lançamento são de configuração zero. O build.rs lê GRR_CLIENT_ID / GRR_CLIENT_SECRET do ambiente de compilação — segredos de repositório do GitHub Actions para as compilações oficiais — e os compila internamente, então GitHub Releases e instalações via Homebrew não precisam de arquivo de configuração nem de visita ao console.
Compilações a partir do código-fonte trazem seu próprio cliente. O cargo install grr-cli compila os fontes publicados sem nada no ambiente de compilação, então esse binário não tem cliente embutido. Qualquer uma destas opções resolve:
- Um
.envao lado doCargo.toml— copie.env.examplepara.env, preencha ambos os valores e recompile. Obuild.rslê o ambiente primeiro e o.envem segundo, então toda compilação posterior também é de configuração zero. O.envestá no gitignore; nunca o envie para o repositório. - Variáveis de ambiente para uma única compilação —
GRR_CLIENT_ID=… GRR_CLIENT_SECRET=… cargo build --release. grr auth setup— sem necessidade de recompilar, pois ele grava~/.grr/config.toml(Windows:%USERPROFILE%\.grr\config.toml) em vez disso.
grr auth setup
Create and store an OAuth client. Release builds ship with one, so this is only needed when using
your own client
Usage: grr auth setup [OPTIONS]
Options:
--client-id <CLIENT_ID> Google OAuth client id (…apps.googleusercontent.com).
Prompted for when omitted
--client-secret <CLIENT_SECRET> Google OAuth client secret. Prompted for when omitted
--print-only Print the instructions and the resolved path, but write
nothing. Useful for a first look, and for agents that only
want the recipe
--force Overwrite an existing ~/.grr/config.toml instead of refusing
--enable-apis Try `gcloud services enable` for the APIs when gcloud is on
PATH
-f, --format <FORMAT> Output format [default: json] [possible values: json, jsonl,
table, pretty]
--readonly Refuse every write method (POST/PATCH/PUT/DELETE); only reads
run
--deny-service <SERVICE> Refuse every method of this service (repeatable)
--deny-verb <VERB> Refuse this HTTP verb (repeatable)
-h, --help Print help
Ele verifica o formato do client-id antes de gravar qualquer coisa (deve terminar em .apps.googleusercontent.com, e uma colagem truncada é rejeitada), rejeita um secret truncado, grava o modo de arquivo 0600 no unix e se recusa a sobrescrever um config.toml existente sem --force. Ele imprime as URLs exatas do Cloud Console e a linha gcloud services enable que cobre todas as APIs por trás de um comando — gmail, calendar-json, drive, people, chat, forms, tasks, docs, sheets, slides, script, analyticsadmin, analyticsdata e searchconsole …googleapis.com — e o --print-only entrega essa receita sem tocar no disco, que é o primeiro comando certo quando você não tem nenhum cliente:
grr auth setup --print-only
Como ele é executado antes de qualquer cliente ser resolvido, o grr auth setup funciona mesmo quando nada está configurado: é a saída de emergência, não o último recurso. Com stdin não-TTY (CI, agentes, pipes) ele gera erro em vez de travar, então passe --client-id e --client-secret explicitamente em vez de depender dos prompts.
Ordem de resolução em tempo de execução: GRR_OAUTH__CLIENT_ID / GRR_OAUTH__CLIENT_SECRET → ~/.grr/config.toml → o cliente compilado no binário (o ambiente vence o arquivo; o cliente compilado é o fallback). O GRR_CONFIG_PATH move o arquivo; o RUST_LOG define o nível de log.
Incorporar um client secret é aceitável aqui porque o Google trata client secrets de aplicativos instalados como não confidenciais — o fluxo é protegido por PKCE, que está sempre ativo. O secret vive nos segredos do repositório do GitHub Actions e é compilado no momento do lançamento; ele nunca deve entrar no repositório nem em um log de CI.
Para criar um cliente do zero, siga docs/gcp-setup.md — você só precisa disso se estiver compilando a partir do código-fonte ou se quiser deliberadamente seu próprio cliente.
O projeto/fork é Google Rust Rewrite; o aplicativo da tela de consentimento do Google é nomeado Rust Rewrite. É na tela de consentimento que esse nome mais curto aparece.
grr ask e System One (JEV)
O grr ask "<request>" roteia palavras comuns para um método tipado + parâmetros e imprime o plano; o --run o executa pelo mesmo caminho de chamada que o grr api. O roteamento são três julgamentos System One — serviço, depois método, depois parâmetros — cada um uma pequena requisição HTTP. O modelo apenas seleciona entre candidatos que a CLI fornece: os 14 serviços, os métodos de um serviço, os valores de enum de um parâmetro ou os trechos encontrados na sua solicitação. Ele não pode inventar um id de método ou um valor — a CLI decide o que é executado.
Defina TYPESAFE_API_KEY e ele funcionará contra o Jev hospedado da TypeSafe:
export TYPESAFE_API_KEY=...
grr ask "show my unread messages"
A rota via env é preferida: uma chave em um arquivo de configuração pode vazar junto com o arquivo. O bloco [systemone] em ~/.grr/config.toml é a única outra superfície:
| Chave | Padrão | Significado |
|---|---|---|
endpoint | https://api.typesafe.ai/v1/systemone | qualquer provedor que fale o contrato System One (POST state + questions tipado, retorna answers estruturado) |
model | jev-latest | nome do modelo enviado a esse endpoint |
api-key | — | enviado como Authorization: Bearer; vazio se comporta como ausente |
confidence-threshold | 0.6 | abaixo dessa confiança de escolha de método, o plano é sinalizado, nunca bloqueado |
Qualquer chave também aceita a forma genérica de env GRR_SYSTEMONE__ENDPOINT / GRR_SYSTEMONE__MODEL / GRR_SYSTEMONE__API_KEY (a mesma rota GRR_ que o GRR_OAUTH__*), e o TYPESAFE_API_KEY substitui o api-key. A chave nunca aparece no plano impresso nem no corpo de uma requisição — ela viaja apenas no cabeçalho Authorization.
Apontar endpoint/model para seu próprio provedor muda apenas qual modelo classifica os candidatos fornecidos pela CLI; os conjuntos de candidatos, o preenchimento tipado de parâmetros e o que realmente executa permanecem do grr. O grr ask honra as flags globais de segurança (--readonly, --deny-service <name>, --deny-verb <VERB>) independentemente de você passar --run, e a barreira é executada assim que o método é resolvido — antes do julgamento de preenchimento de parâmetros e antes de qualquer requisição ao Google ser construída ou enviada.
Destaques de uso
grr gmail users messages list --user-id me --q "from:github.com" --max-results 10
grr gmail users messages get --user-id me --id 191f8ab2 --param-format metadata
grr gmail users threads list --user-id me --max-results 10
grr calendar events list --calendar-id primary --time-min 2026-10-01T00:00:00Z --max-results 10
grr drive files list --q "name contains 'report'" --page-size 10
grr drive files export --file-id <id> --mime-type application/pdf
grr chat spaces messages create --parent spaces/AAAA --body-file ./message.json
grr sheets spreadsheets values get --spreadsheet-id 1AbC… --range Sheet1!A1:B10
grr tasks tasklists list
grr transport
grr schema
Todo comando aceita -f/--format json|jsonl|table|pretty (padrão json). Para gmail users messages get, o parâmetro MIME do Gmail chamado format chega como --param-format full|metadata|minimal|raw (veja a regra de colisão abaixo), enquanto -f/--format ainda seleciona o formato de saída impresso. Os logs vão para o stderr, então o stdout é sempre analisável:
grr gmail users messages list --user-id me --q "in:inbox" --max-results 1 | jq -r '.[0].id'
O grr --version imprime o semver na primeira linha (scripts dependem disso), depois o mascote caranguejo: em arte pixel completa de 24 bits em terminais que anunciam COLORTERM/cor direta, e como ASCII simples em qualquer outro lugar — um pipe, TERM=dumb ou NO_COLOR. Defina CLICOLOR_FORCE=1 para forçar o logo colorido através de um pipe (grr --version | less -R); o NO_COLOR ainda vence sobre ele.
Referência de comandos
A árvore de comandos é gerada a partir do índice Discovery commitado pelo scripts/generate-commands.ts (com gate de CI usando --check), então esta tabela é deliberadamente grosseira: grr --help e grr schema são a fonte da verdade, e cada um dos 401 métodos é um comando real e tipado.
| Grupo | O que cobre | Métodos |
|---|---|---|
grr auth | login [--device] [--account name], status [--account name], setup [--client-id] [--client-secret] [--print-only] [--force] [--enable-apis] | — |
grr ask | "<request>" [--run] [--service] [--method] — linguagem natural para um método tipado + parâmetros via um modelo System One; imprime o plano por padrão | - |
grr mcp | um servidor MCP (JSON-RPC sobre stdio) expondo cada método como uma ferramenta tipada; --readonly para somente leitura | - |
grr api | list [--service X] [--filter substr] [--grouped], describe <id>, call <id> …, refresh [--service X] — cada método por id, a saída de emergência plana | 401 |
grr schema | toda a árvore de comandos como JSON | — |
grr transport | versão HTTP negociada + recursos de runtime | — |
grr skills | install [--dir PATH] [--claude] [--force], list — os 16 arquivos de skill empacotados (a skill principal, uma por serviço e seu índice) no diretório de skills do usuário (~/.agents/skills, offline; --claude espelha para ~/.claude/skills) | — |
grr gmail | mensagens, threads, rascunhos, rótulos, histórico, anexos, filtros, encaminhamento, POP/IMAP, send-as, CSE, delegados, observadores | 79 |
grr calendar | calendários, eventos, instâncias, ACL, free/busy, cores, configurações | 38 |
grr drive | arquivos, permissões, comentários, respostas, revisões, alterações, drives, apps, aprovações | 64 |
grr people | contatos, conexões, grupos de contatos, outros contatos, pessoas do diretório | 24 |
grr chat | espaços, membros, mensagens, reações, mídia, emojis personalizados, estado de leitura | 54 |
grr forms | corpos de formulários, respostas, observadores, configurações de publicação | 10 |
grr tasks | listas de tarefas e as tarefas dentro delas | 14 |
grr docs | documentos get / create / batchUpdate | 3 |
grr sheets | planilhas, valores, operações em lote, metadados de desenvolvedor | 17 |
grr slides | apresentações, páginas, miniaturas | 5 |
grr script | projetos de script, implantações, versões, processos, funções em execução | 16 |
grr analyticsadmin | contas, propriedades, fluxos de dados, dimensões e métricas personalizadas, eventos de conversão | 55 |
grr analyticsdata | relatórios padrão, em tempo real, dinâmicos e em lote, exportações de público | 11 |
grr searchconsole | consultas de análise de pesquisa, sitemaps, sites, inspeção de URL | 11 |
Perfis de segurança. --readonly, --deny-service <name> e --deny-verb <VERB> são flags globais honradas pela árvore gerada, grr api call, grr ask e grr mcp igualmente — elas são analisadas antes ou depois do subcomando e transformam métodos destrutivos em erros acionáveis:
grr --readonly gmail users messages delete --user-id me --id abc # refused: DELETE
grr --deny-service chat chat spaces list # refused: the chat service
A árvore gerada
Todos os comandos de serviço acima são gerados a partir do índice consolidado por scripts/generate-commands.ts — não há comandos por serviço escritos à mão nem clientes por serviço escritos à mão. scripts/generate-commands.ts lê o índice de Discovery consolidado (src/discovery/*.json, ~430 KiB nos 14 serviços) e emite toda a árvore para src/commands/generated.rs — 401 folhas, 994 flags tipadas, usando a API builder do clap. Um workflow diário busca novamente o Google Discovery Service, regenera o índice junto com a árvore de comandos, as skills de agente por serviço e a tabela de cobertura do site, e abre um PR, para que novas superfícies de API cheguem até você sem esperar por um lançamento do grr. A árvore e o índice são artefatos gerados: nunca os edite manualmente.
As regras, para que você possa prever qualquer comando sem memorizá-lo:
- A regra de nomenclatura. Uma folha espelha seu id de método Discovery:
gmail.users.messages.list→grr gmail users messages list. Recursos se aninham como subcomandos; cada folha também carrega seu nome de método puro como um alias visível (list,get— métodos camelCase mantêm sua capitalização, ex.:getProfile). - Flags tipadas por método. Os nomes dos parâmetros vêm dos mesmos ids:
userId→--user-id,maxResults→--max-results. Inteiros são analisados comoi64, booleanos são flags de presença, parâmetros repetidos se repetem (--label-ids a --label-ids b), parâmetros de enum validam seus valores, e parâmetros obrigatórios são aplicados pelo clap. - A regra de colisão. Um parâmetro chamado
format,query,params,body-file,dry-runouhelpcolidiria com as saídas de escape compartilhadas, então ele é exposto como--param-format/--param-query/ … (vejaRESERVED_FLAG_IDSemscripts/script-utils.ts). - Corpos não tipados. Os esquemas de solicitação do Discovery não fazem parte do índice, então os corpos
POST/PATCH/PUTpassam por--params <JSON>(mesclados; flags tipadas vencem) ou--body-file <PATH|->literalmente. - Cada folha também carrega as saídas de escape:
--params <JSON>,--body-file,--query KEY=VALUErepetível,--dry-rune-f json|jsonl|table|pretty.
O despacho resolve o id da folha contra o índice embutido e canaliza para um caminho de chamada compartilhado — o mesmo mecanismo que grr api call usa. As duas rotas são intercambiáveis:
grr api call gmail.users.messages.list --param userId=me --dry-run
grr gmail users messages list --user-id me --dry-run
# byte-identical output
grr api permanece como a saída de escape plana: list [--service] [--filter] [--grouped] para navegar, describe <id> para parâmetros e escopos, call <id> para invocar, refresh [--service] para puxar o índice adiante entre lançamentos. Como o índice é embutido em vez de buscado, tanto grr api list quanto grr schema funcionam sem nenhuma rede.
A autorização é verificada por método: grr auth login consente com um conjunto fixo de escopos, e cada chamada compara o escopo de menor privilégio do método com esse conjunto em vez de escalar silenciosamente — então um método que precisa de algo que você nunca concedeu imprime uma nota nomeando o escopo e pode falhar com um 403 por extenso em vez de um erro opaco. Docs, Sheets e Slides funcionam através do escopo drive que o grr já possui; Tasks precisa do escopo tasks, que este build não solicita, então uma chamada de Tasks imprime uma nota nomeando o escopo e pode retornar 403. As APIs deles (tasks.googleapis.com, docs.googleapis.com, sheets.googleapis.com, slides.googleapis.com) também precisam estar habilitadas no seu projeto Cloud — veja docs/gcp-setup.md.
Filosofia de design
- Zero configuração. Os binários de lançamento carregam um cliente OAuth compilado por
build.rs, então uma instalação nova executagrr auth loginsem nada para configurar.~/.grr/config.tomlé a substituição, não o pré-requisito, e contém apenas o cliente OAuth (ID, opcionalmente um segredo) mais — se você apontargrr askpara seu próprio modelo — o bloco[systemone]dele (vejagrr aske System One). Escopos, URI de redirecionamento, tamanhos de pool, timeouts e política de repetição são constantes de tempo de compilação ajustadas para os frontends do Google (src/core/http.rs).GRR_CONFIG_PATHsubstitui a localização do arquivo,RUST_LOGo nível de log (existem variáveis de ambienteGRR_OAUTH__*para substituições headless) — nada mais é configurável, de propósito. - Serviços gerados e namespaced. A árvore de comandos é compilada a partir do índice de Discovery — a mesma descrição legível por máquina que o Google publica — então adições de métodos chegam como um PR diário em vez de um backlog escrito à mão. Mail é
grr gmail …; Calendar, Drive, People, Chat, Forms, Tasks, Docs, Sheets e Slides ficam ao lado dele, e preocupações de nível de conta permanecem no nível superior (grr auth,grr api,grr ask,grr mcp,grr transport,grr schema,grr skills). Um login cobre todos os serviços. - Instalações com automigração. Um binário mais novo traz as skills de agente que instalou para a versão mais recente por conta própria: arquivos que você nunca tocou são substituídos, arquivos que você editou recebem um merge de três vias contra os bytes que o grr escreveu por último, e um conflito deixa seu arquivo intacto com a versão recebida ao lado dele (
.grr-incoming). Arquivos que o grr não instalou nunca são tocados. A verificação é preguiçosa — uma comparação de versão; nada é hashado até que algo realmente precise de merge. - Pureza do stdout. Logs vão para o stderr, resultados vão para o stdout, então
| jqsempre funciona.-f jsonltransmite arrays com um objeto por linha. - Armazenamento de token com prioridade para keyring. Tokens vivem no keyring do SO (Windows Credential Manager, macOS Keychain, Linux Secret Service via D-Bus), com fallback automático para
<cache dir>/grr/token.jsonem sistemas headless. Um token encontrado no arquivo de fallback é importado automaticamente para o keyring na primeira vez que é visto. - Prioridade para agentes.
grr schemadespeja a árvore de comandos completa como JSON com zero configuração — o contrato legível por máquina para agentes de IA, descobrível sem tocar em um arquivo de configuração ou raspar--help. Um CLI rápido substitui servidores MCP por serviço: sem configuração de MCP, apenasgrr schema. Também há uma skill de agente empacotada em skills/grr/SKILL.md — veja Agent skills.
Skills de agente
O grr inclui uma skill de agente empacotada: skills/grr/SKILL.md — a disciplina de descoberta primeiro (schema → api list → api describe → --dry-run), a regra de nomenclatura por id de método e o contrato de saída em um arquivo, escrito para qualquer agente de IA. A skill principal mais as 14 skills geradas por serviço são compiladas no binário, então grr skills install as escreve em ~/.agents/skills/ sem rede (Codex, opencode, Cursor, Gemini CLI, Copilot CLI e omp leem esse local; --claude espelha em ~/.claude/skills/ para Claude Code, que não lê mais nada):
grr skills install # all 16 into ~/.agents/skills/ (idempotent; identical files are a no-op)
grr skills install --claude # also mirror into ~/.claude/skills/
grr skills install --force # replace files that differ from the packaged copy
grr skills list # the packaged set, and what each target directory holds
ou instale direto do repositório com o CLI de skills:
npx skills add https://github.com/debanjanbasu/grr-cli
O guia de agentes do site carrega o mesmo contrato para humanos e autores de harness.
Desempenho
- HTTP/3 (QUIC) por padrão — h3 com conhecimento prévio, com uma sonda autenticada na inicialização e fallback silencioso para HTTP/2;
grr transportmostra o que foi realmente negociado. - Runtime Tokio multi-threaded, dimensionado automaticamente para os núcleos — sem pool de threads para ajustar.
- Válvula de solicitações em voo — um semáforo (não um pool de threads) limita solicitações HTTP concorrentes a 64, ficando abaixo dos limites de taxa por usuário do Gmail para que rajadas não causem autodano em 429s. 429s são repetidos respeitando
Retry-After(esperas limitadas a 30s); o timeout de solicitação inteira é de 30s. - Compressão sempre ativa — descompressão de resposta gzip, deflate, zstd e brotli.
- E/S de arquivo io_uring é uma dependência específica de alvo somente Linux, detectada automaticamente em tempo de execução; não é um recurso do Cargo.
Números medidos de inicialização, tamanho do binário e latência de solicitação contra os outros CLIs do Google Workspace estão em grr-cli.pages.dev/compare/, verificados todas as noites por um workflow automatizado e remedidos sempre que uma nova versão é lançada.
Arquitetura
grr-cli é um crate publicado na raiz do repositório. src/lib.rs constrói o alvo de biblioteca grr_cli; src/main.rs é um wrapper fino sobre src/cli.rs, e o binário é nomeado grr.
.
├── src/
│ ├── core/ # auth/device/oauth/server/store, http.rs,
│ │ # config.rs, config_loader.rs, error.rs,
│ │ # runtime.rs (the io_uring probe)
│ ├── commands/ # auth.rs, api.rs, setup.rs, transport.rs,
│ │ # skills.rs, mcp.rs, ask.rs, safety.rs (the static
│ │ # + generated.rs (GENERATED — the
│ │ # whole service tree, ~470 KiB) and gen_dispatch.rs
│ │ # (resolves leaf ids, funnels into the shared path)
│ ├── discovery.rs # loader over the embedded index
│ ├── discovery/ # generated *.json index (~430 KiB, committed,
│ │ # refreshed daily by workflow PR)
│ ├── schema.rs
│ ├── output.rs
│ ├── cli.rs
│ ├── lib.rs
│ └── main.rs
└── tests/ # 5 integration test files
Um núcleo compartilhado, sem módulos de cliente por serviço: o CLI fala Discovery através de um único caminho de chamada (src/commands/api.rs), e os modelos tipados de solicitação/resposta da era da biblioteca 0.3.x se foram. O repositório também contém o assets/, site/ (o site Astro em grr-cli.pages.dev, implantado a partir do main pelo Cloudflare Pages), packaging/ e o material scripts/ usado para o site do projeto e distribuição.
Desenvolvimento
O grr requer Rust nightly — o script de build falha com uma mensagem clara em qualquer outra toolchain. rust-toolchain.toml flutua no nightly mais recente e fornece os componentes necessários para o build, enquanto .cargo/config.toml define o cfg reqwest_unstable para HTTP/3.
cargo build
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --all --check
cargo run -- api list
node scripts/fetch-discovery.ts # refresh the Discovery index
node scripts/generate-commands.ts # regenerate the service command tree
node scripts/generate-skills.ts # regenerate skills/<service>/SKILL.md
node scripts/generate-coverage.ts # regenerate the site coverage table
node scripts/generate-changelog.ts # regenerate CHANGELOG.md + site data
Cada gerador recebe --check e sai com código 1 quando sua saída está desatualizada — esse é o portão de CI. Mude o índice ou o gerador, nunca src/commands/generated.rs à mão.
- Testes nunca tocam credenciais reais — caminhos de token são injetados, e o wiremock serve os endpoints da API.
RUST_LOG=debugrastreia solicitações; o nível padrão silencia os avisos inofensivos de IPv6 do quinn_udp (info,quinn_udp=error).- Um build local precisa de um cliente OAuth antes que uma chamada ao vivo possa funcionar: copie
.env.examplepara.enve preencha (compilado porbuild.rs), ou executegrr auth setuppara escrever~/.grr/config.toml. Veja CONTRIBUTING.md. cargo run -- api listecargo run -- schemanão precisam de nenhum cliente — o índice é embutido.
Empacotamento e status
| Canal | Instalação | Status |
|---|---|---|
| GitHub Releases | Binários para 5 plataformas (macOS arm64, Linux x86_64, Linux aarch64, Windows x86_64, Windows on ARM) construídos em tags v*, empacotados com UPX, .tar.zst no unix e .zip no Windows | ao vivo — cada push para main lança; releases sempre carrega o mais novo |
| crates.io | cargo install grr-cli (binário instala como grr; precisa de nightly + RUSTFLAGS="--cfg reqwest_unstable" para o build padrão de CLI HTTP/3, e não traz cliente OAuth embutido) | ao vivo — um crate, publicado em cada lançamento. Publicação confiável usa OIDC (sem tokens de API armazenados) |
| winget | winget install debanjanbasu.grr | ainda não publicado — a primeira submissão parou porque os arquivos nomeavam o binário pelo alvo (windows-x86_64.exe) enquanto o manifesto prometia grr.exe; a validação do winget nunca conseguia encontrar o instalador aninhado. Ambos os lados estão corrigidos (arquivos v0.8.1 enviam grr.exe; node scripts/generate-winget.ts <tag> deriva o manifesto do arquivo lançado e acompanha cada lançamento como grr-<tag>-winget-manifests.tar.gz) |
| Homebrew | brew tap debanjanbasu/tap && brew trust debanjanbasu/tap && brew install grr (tap: debanjanbasu/homebrew-tap, fórmula Formula/grr.rb, atualizada automaticamente em cada lançamento) | ao vivo (macOS arm64 + Linux x86_64/arm64) |
O projeto publica um pacote, grr-cli, cujo binário é grr. Tags v* disparam o workflow de lançamento, e a publicação no crates.io é tratada por publicação confiável.
Licença
MIT — veja LICENSE.