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

@neetru/cli

v2.35.0

Published

Neetru Developer Kit — scaffold, AI assistant, publish, build e deploy de produtos SaaS Neetru via Core (VM-based agents)

Readme

@neetru/cli

Developer Kit oficial da Neetru — scaffolding, IA Neetru-aware, deploy de produtos SaaS, gestão de workspaces, bancos isolados por produto, e mais 40+ comandos pra operar todo o ecossistema Neetru via terminal.

Instalação

npm install -g @neetru/cli

Bootstrap completo da máquina dev (Node, gcloud, Docker, Firebase CLI, deps NPM, GCP ADC):

neetru bootstrap

Login no Core via OAuth Device Code Flow:

neetru login

Validar estado:

neetru doctor

Quickstart — criar produto SaaS novo

neetru new gestovendas --env=dev --tier=dev --customer=neetru

Cria produto + workspace + scaffold local Next.js 15 + instala deps + abre cockpit no browser.

Comandos principais

| Comando | O que faz | |---|---| | neetru bootstrap | Setup da máquina dev (binários + deps + ADC) | | neetru login / logout / whoami | Auth OAuth Device Code Flow | | neetru doctor | Diagnóstico saúde (5 checks rápidos) | | neetru new <slug> | Criar produto completo (registry + workspace + scaffold) | | neetru init <name> | Só scaffold local Next.js + Firebase | | neetru add <feature> | Adicionar features ao scaffold (auth, billing, etc) | | neetru deploy | Pipeline de deploy interativo (cloud-run / vm / workspace) — roda docs check e só avisa | | neetru docs init [--com-api] [--migrar] | Mínimo do primeiro dia do docs/ do produto (idempotente); --migrar só acrescenta frontmatter + relatório | | neetru docs new <tipo> "<título>" | Doc novo a partir do modelo, na pasta e com o nome do protocolo | | neetru docs check [--changed] [--strict] | Valida os docs do produto offline (códigos FM/TI/NM/LK/PB/LC + PR001–PR004) | | neetru docs sync [--dry-run] | Publica os docs do produto no Core (só os sem erro; nada é apagado) | | neetru build [--app <pasta>] [--stack ...] [--target-env dev\|workspace\|prod] [--env-file ...] [--no-cache] [--no-install] | Empacotar produto em tarball pra deploy (monorepo: --app apps/web, ou --cwd) | | neetru smoke [--base-url ...] [--prod ...] [--health-path ...] [--routes csv] [--json] | Percorrer as páginas do produto local antes do deploy (alcance + login + DB) + smoke de prod opcional | | neetru promote | Promover dev → staging → prod | | neetru env switch <target> | Trocar NEETRU_ENV no .env.local | | neetru env set --service=X --set KEY=VAL | Setar env vars de serviço Cloud Run | | neetru secrets set CHAVE --env <ambiente> [--generate \| --stdin \| --from-file <caminho>] | Segredo do próprio produto (app em VM): o valor vai direto pro Secret Manager e nunca entra pela linha de comando; --generate = o Core sorteia | | neetru secrets list / archive CHAVE --env <ambiente> | Listar só os nomes / arquivar um segredo do produto | | neetru ar create <name> | Criar repositório Artifact Registry | | neetru hosting create-mapping --service=X --domain=Y | Domain mapping | | neetru admin database create --product-id=X --engine=cloud-sql-postgres | Registrar banco isolado por produto (staff control plane) | | neetru admin database engines | Listar engines suportados (firestore-instance, cloud-sql-postgres, cloud-sql-mysql, vm-postgres-single, vm-mysql-single, nosql-vm, …) | | neetru db init / apply / migrations | Banco por produto no fluxo dev (registra + schema + migrations) | | neetru dev | Banco Docker local + watch de schema (salvar = aplicado) | | neetru dev up | Banco do produto em container (Docker Compose) + URL de conexão pro .env.local | | neetru dev exec <script> | Roda <script> com os emuladores Firebase do Core (exige o repo do Core; CI do Core) | | neetru cloud-run pause/resume/delete <service> | Controle Cloud Run | | neetru products list/create/update | Registry de produtos | | neetru workspaces create/list/get/advance | Instâncias por cliente | | neetru deployments create/rollback | Histórico de deploys | | neetru tenants list/create/update/suspend | Gerenciar tenants | | neetru audit tail | Tail de audit_logs/ em tempo real | | neetru billing summary | Resumo de billing | | neetru servers list/provision/deactivate | Gerenciar servidores | | neetru agent release/yank/canary | Gerenciar releases do agente | | neetru support tickets list/reply/assign | Suporte inbox staff | | neetru dns zones list / hosting list | Listar DNS + customer domains | | neetru builds list | Listar Cloud Build | | neetru dr exports/restore | Disaster Recovery | | neetru logs | Ver logs de produtos | | neetru status | Visão geral do ecossistema | | neetru open <produto> | Abrir cockpit do produto no browser | | neetru ai | REPL IA Neetru-aware (Groq, NVIDIA NIM, OpenAI ou o AI Gateway da Neetru via neetru login) | | neetru ui | Menu interativo do CLI | | neetru publish | Publicar produto no catálogo público | | neetru upgrade | Auto-update do CLI | | neetru autocomplete <bash\|zsh\|pwsh> | Gerar script autocomplete |

Atalhos: neetru ar = artifact-registry, neetru menu = ui.

40+ subcomandos. Quase todos suportam --json pra automação.

Docs do produto (neetru docs init|new|check|sync) — 2.31.0

Padrão: PROTOCOLO_DOCS_PRODUTOS_SAAS.md do Core (versão 1). O docs/ de cada produto segue a mesma taxonomia da wiki do Core (categoria + subcategoria por assunto, type à parte) e nomes MAIÚSCULO_COM_UNDERLINE.

neetru docs init                 # README, CHANGELOG, docs/index.md, visão, arquitetura, runbook de deploy
neetru docs init --com-api       # + docs/api/API_V1.md (o produto expõe /api/v1)
neetru docs init --migrar        # repo que já tem docs: frontmatter inferido + relatório em docs/_audit/
neetru docs new adr "Usar Postgres para vendas"
neetru docs new relatorio "Auditoria de UX da tela de caixa"
neetru docs check --changed      # catraca: só o que mudou contra a branch principal
neetru docs sync --dry-run       # o que subiria para o Core
  • neetru init e neetru new já rodam docs init (--sem-docs pula).
  • neetru deploy roda docs check e só avisa — nunca bloqueia. Com "docs": { "publishOnDeploy": true } no neetru.config.json, o deploy de produção publica os docs no fim; falha na publicação não derruba o deploy. --sem-docs pula as duas coisas.
  • A taxonomia vem embutida na CLI (funciona offline); quando o Core expõe GET /api/cli/v1/docs/taxonomy, o check usa a do Core e avisa se a embutida estiver velha.

Dev local (neetru dev, neetru dev up)

O que roda na máquina do dev de produto hoje:

| Peça | Como | |---|---| | SDK sem conta Neetru | NEETRU_ENV=dev → mocks em memória (login fixture, uso zerado, banco em memória). neetru mocks reset limpa as fixtures. | | Banco real do produto | neetru dev (container + reaplica db/schema.ts a cada save) ou neetru dev up (só sobe o container e imprime a URL de conexão). Engine vem do projeto. | | App | npm run dev, fora de container. | | Agente / Core locais | Ainda não existem para produto. Deploy e migração pelo agente só acontecem na VM. |

# Na raiz do produto (com database.engine no neetru.config.json):
neetru dev up
#  → gera neetru-compose.dev.yml e sobe o banco (docker compose up -d --wait)
#  → imprime a conexão, ex. postgresql://postgres:neetru_dev@localhost:5432/app
docker compose -f neetru-compose.dev.yml down   # para

# CI do Core (na raiz do Core, onde tem firebase.json): roda o script com os
# emuladores Firebase e propaga o exit code.
neetru dev exec "npm run test:integration"

Contexto do projeto local:

# Projeto ligado a um produto já existente no Core:
neetru dev use --product meu-produto --sync

# Protótipo local ainda não cadastrado no Core:
neetru dev use --prototype meu-rascunho

# Ver o contexto dev-local efetivo:
neetru dev status

# Sincronizar bancos dev-local do Core para .neetru/db.json:
neetru dev sync --write-db

neetru dev (sem subcomando) mantém o modo legado: banco Docker local + watch de schema. Flags: dev up --core-port <n> (porta do app nas instruções, default 3000); dev exec --only firestore,auth,functions --core-path <dir>. O arquivo .neetru/dev.json guarda o contexto local: produto Core ou protótipo, Core path e emuladores padrão.

Build — env do bundle (NEXT_PUBLIC_NEETRU_ENV)

neetru build sempre serve pra gerar artefato de deploy — nunca pra dev local (isso é next dev/neetru dev up). Por isso, pra stacks node/static (produtos Next.js), o build sempre força NEXT_PUBLIC_NEETRU_ENV=<targetEnv> via spawn-env no processo do npm run build — default prod, sem nenhuma ação do dev:

neetru build --product=meu-produto              # NEXT_PUBLIC_NEETRU_ENV=prod (default)
neetru build --product=meu-produto --target-env=workspace

Isso existe porque o Next.js carrega .env.local (arquivo do disco do dev, nunca deletado) antes de .env.production — e valores já definidos não são sobrescritos por arquivos carregados depois. Sem essa proteção, um .env.local esquecido com NEETRU_ENV=dev fazia o bundle de PRODUÇÃO compilar com o SDK Neetru em modo mock (MockAuth), desativando o login real silenciosamente (incidente pdv-agiliza, 2026-07-22).

Se o produto envolver next.config.mjs com withNeetruBuildGuard (@neetru/sdk/build-guard, @neetru/sdk >= 3.1.15), neetru build confere pós-build que o env realmente compilado bate com o esperado — e recusa empacotar o tarball se divergir, em vez de deployar um bundle quebrado silenciosamente.

Build de monorepo (pnpm, yarn, bun ou npm workspaces)

Deploy de monorepo na VM ainda não funciona. O agente da VM (1.6.80) não reconhece o app que fica dentro de uma pasta do pacote (apps/web/server.js): em vez de pular a instalação, ele roda npm rebuild na raiz do pacote e, se falhar, npm install — o mesmo caminho que já derrubou deploy em VM pequena (exit 137). Para a VM, mantenha o seu empacotador próprio até sair a versão do agente que reconhece o app aninhado (bug_bc72fe7e no agente; origem bug_678ddc98). O neetru build --app abaixo já monta o pacote; o que falta é o agente saber instalá-lo.

Rode da raiz do monorepo e aponte o app com --app (--cwd é o mesmo):

neetru build --app apps/web --product meu-produto
neetru deploy --product meu-produto   # da mesma pasta: usa o pacote que o build gerou (na VM, veja o aviso acima)
  • Onde sai o pacote: em .neetru-build/ da pasta onde você rodou o comando — é lá que o neetru deploy procura. O neetru.config.json pode ficar no app ou na raiz (o do app vale mais). A versão vem do package.json do app.
  • Gerenciador de pacotes, nesta ordem: (1) o campo packageManager do package.json do app; (2) o lockfile da pasta do app (pnpm-lock.yaml, yarn.lock, bun.lock/bun.lockb, package-lock.json), que vem antes de tudo o que está na raiz, inclusive do packageManager da raiz; (3) sem lockfile no app, a CLI sobe até a raiz do workspace, e lá o packageManager do package.json da raiz vale mais que o lockfile da raiz. A raiz só conta se se declara workspace (pnpm-workspace.yaml ou workspaces no package.json), e a busca para na pasta que tem .git. Achada a raiz, a instalação roda nela e o script build roda na pasta do app. Sem lockfile nenhum, fica o npm, como sempre.
  • Cuidado com lockfile solto no app: um package-lock.json esquecido em apps/web de um monorepo pnpm faz a CLI escolher o npm e instalar só dentro de apps/web, onde as dependências workspace:* falham. Apague o lockfile solto antes do build.
  • Next.js com output: 'standalone': no monorepo o Next.js põe o app dentro do standalone, no mesmo caminho que ele tem no repositório (.next/standalone/apps/web/server.js). A CLI lê esse caminho de .next/required-server-files.json (campo relativeAppDir, gravado pelo próprio Next.js no build). Se o arquivo não traz o campo (Next.js antigo), ela procura o server.js pela árvore. O pacote leva o standalone inteiro, .next/static e public vão para dentro de apps/web/, e o neetru deploy manda o entrypoint apps/web/server.js para o Core.
  • Quando a CLI recusa: se o Next.js registrou o app num lugar e o server.js não está lá, ou registrou um lugar fora do standalone (o outputFileTracingRoot precisa ser uma pasta acima do app), o build para com exit 1 em vez de empacotar um pacote que não sobe.
  • Cloud Run sem Dockerfile: o Dockerfile que o neetru deploy --target cloud-run gera quando o projeto não tem um reconhece o monorepo (bug_1dcf8e03): detecta o gerenciador do app (mesma regra do neetru build --app acima), builda com o contexto na raiz do workspace (onde mora o lockfile — workspace:* só resolve assim) e aponta o CMD/COPY do standalone para o caminho aninhado do app (apps/web/server.js). Rode neetru deploy de dentro do app (cd apps/web && neetru deploy …), como no neetru build --app. Testado com pnpm (fixture de monorepo) e npm de app único (caso de sempre); yarn berry com PnP e workspace nativo npm/yarn sem teste próprio — fora desses dois casos, escreva o seu Dockerfile.

Segredo no pacote público bloqueia o deploy (2.30.0)

A credencial nrt_ do produto é só de servidor. Antes de enviar o pacote, neetru deploy varre o que é servido ao navegador — .next/static/**, public/**, out/**, dist/**, build/** (na stack static, o pacote inteiro; node_modules nunca) — procurando:

  • nrt_… e npk_… (credenciais Neetru);
  • -----BEGIN … PRIVATE KEY----- com o material da chave (só o cabeçalho não conta);
  • o valor de envs públicas (NEXT_PUBLIC_*, EXPO_PUBLIC_*, VITE_*, REACT_APP_*, PUBLIC_*) cujo nome contém KEY/SECRET/TOKEN (lidas de .env, .env.production, .env.local, .env.production.local, --env-file e do ambiente). Valores públicos por desenho do provedor (Stripe pk_live_/pk_test_, chave web Google/Firebase AIza…, reCAPTCHA 6L…) são ignorados.

Achou → o deploy falha (exit 1, public_secret_in_bundle) mostrando arquivo e tipo — nunca o segredo (no máximo 8 caracteres iniciais, mascarados). Pacote ilegível também falha (public_secret_scan_failed).

Correção: tire a chave do código do navegador/app; o navegador/app chama a API do seu produto com o token do usuário e o backend usa @neetru/sdk com NEETRU_API_KEY (ver verifyAccessToken no SDK ≥ 3.8.0).

Emergência (fica registrado no deploy — só caminho e tipo, nunca o valor):

neetru deploy --allow-public-secret "chave antiga já revogada, ticket #123"

Limites: --artifact-url (pacote remoto) e --image (imagem pronta, cloud-run) não passam pelo CLI e não são varridos — o deploy avisa. Em target=cloud-run sem --image, a varredura é nas pastas públicas do disco antes do build da imagem.

Deploy na VM: um app por produto e ambiente

Na VM (--target vm) quem escolhe a porta do app é o Core; --port é ignorado (a CLI avisa). O Core reconhece o app pelo produto + ambiente: um novo neetru deploy --product X --env prod substitui o app de X em prod que está no ar — o endereço de prod passa a servir o deploy novo, e não sobe um segundo app ao lado.

Para ter dois apps (ex.: site e API em endereços diferentes), cadastre o segundo como produto próprio e faça o deploy de cada um com o seu --product:

neetru products create --name "Meu SaaS API" --slug meu-saas-api   # exige papel admin ou operator
neetru deploy --product meu-saas-api --env prod --target vm --server <id>

O deploy do produto novo exige que a chave da CLI o alcance: a de admin alcança todos os produtos; uma chave com escopo de produto só alcança os dela, e o deploy do novo volta 403 forbidden_product — nesse caso o deploy fica com um admin.

Enquanto o conserto do Core para o bug_fe30f035 não estiver no ar, o 1º deploy do produto novo na VM é recusado pelo Core: o produto nasce com staging e prod no destino workspace, e o deploy na VM volta 400 vm_deploy_failed ("Ambiente prod tem destino 'workspace', não 'vm'. Migre o destino antes (changeEnvironmentTarget)…"). A CLI não tem comando para trocar o destino de um ambiente. Quando essa recusa acontece, a CLI a explica, e o caso fica com um admin do Core.

Cada produto tem endereço, banco e segredos próprios. Se os dois precisam do mesmo banco, separar não serve (o banco é isolado por produto): sirva a API pelo próprio app (ex.: rotas /api), no mesmo endereço. O mesmo texto aparece em neetru deploy --help.

Smoke local antes do deploy (neetru smoke)

Roda contra o servidor dev local (next dev / neetru dev up) e percorre as páginas do produto antes de neetru build + neetru deploy — pega página quebrada, login que não renderiza ou banco fora do ar sem subir nada em produção.

# suba o dev local primeiro (ex: next dev na porta 3000), depois:
neetru smoke
neetru smoke --base-url=http://localhost:9002 --health-path=/api/health
neetru smoke --routes=/,/login,/dashboard          # rotas explícitas (pula a auto-descoberta)
neetru smoke --prod=https://meu-saas.neetru.com     # + smoke básico de prod (GET / e health, espera 200)
neetru smoke --json | jq '.summary'                 # saída de 1 linha machine-readable

O que verifica (cada check vira ✓ pass / ✗ fail / ⚠ warn):

  1. Alcance das rotas — auto-descobre as rotas do App Router (app/**/page.*) e do Pages Router legado (pages/**/*, exceto _app/_document/api). Route groups (...) são removidos; segmentos dinâmicos [param]/[...slug] são pulados com aviso (não há valor de amostra trivial). GET em cada rota: passa em 200–399 sem marcador de erro no corpo; falha em >=400 ou marcador (Application error, Internal Server Error, __next_error__, 404 do Next, título 500).
  2. Login carrega — acha a rota de login e confere que renderiza; sem um botão/afford de login detectado vira aviso, não falha; não-200 falha.
  3. Banco / health — GET no --health-path: 200 com corpo saudável passa; 404 vira aviso (produto não expõe health path — DB não verificável por aqui); qualquer outro não-200 falha.
  4. Smoke de prod (só com --prod) — GET em <prod>/ e <prod><health-path>, espera 200 em cada.

Exit 1 se qualquer check falhar (avisos não bloqueiam). Abordagem leve, sem Playwright/headless browser — o CLI é publicado no npm e não pode ganhar uma dependência de ~300MB de browser. Captura de erro de console (que exigiria um browser real) fica para um v2 documentado, atrás de um flag opt-in que instale o headless sob demanda.

Configuração

Token Bearer fica em ~/.config/neetru-cli/auth.json (chmod 0600 em Unix, NTFS ACL em Windows) — gerado por neetru login via OAuth Device Code Flow. Configs gerais ficam em ~/.config/neetru-cli/config.json (Linux/macOS) ou %APPDATA%\neetru-cli\config.json (Windows):

| Chave | Valor | |---|---| | neetruApiUrl | URL base do Core (default https://api.neetru.com). Allowlist desde 2.11.0: *.neetru.com + localhost; demais hosts exigem --allow-untrusted-url | | defaultModel | groq / nvidia / openai / gateway / auto (default auto): o modelo do neetru ai aberto sem -m. No auto, a CLI escolhe entre os provedores com chave, gratuitos primeiro (Groq, NVIDIA NIM; a OpenAI só sem eles) | | telemetry.enabled | Telemetry opt-in (default false) — desde 2.11.0 emite eventos anônimos pra /api/sdk/v1/telemetry/log | | neetruApiKey | (legado) Token em Conf — substituído por auth.json. Será removido em 2.12.0 |

neetru config set telemetry.enabled true
neetru config get neetruApiUrl
neetru config path           # mostra caminho do config file
neetru config set neetruApiUrl https://staging.neetru.com   # subdomínio neetru.com — OK
neetru config set neetruApiUrl http://my-proxy.local --allow-untrusted-url   # explicit opt-in

Output JSON

neetru products list --json | jq '.[] | select(.status == "ativo")'
neetru audit tail --json | jq 'select(.action | startswith("billing"))'

Auth & Segurança

  • OAuth Device Code Flow (RFC 8628) pra login interativo — não armazena password
  • Tokens salvos em ~/.config/neetru-cli/auth.json (chmod 0600 em Unix, NTFS ACL em Windows). Desde 2.11.0 o resolver canônico (getActiveTokenSync) prefere esse arquivo sobre o Conf storage legado (que será removido em 2.12.0)
  • URL allowlist (desde 2.11.0): neetruApiUrl rejeita hosts fora de *.neetru.com + localhost sem --allow-untrusted-url — fecha vetor de exfiltração do Bearer token
  • Rate-limit por método HTTP: GET 120/min, POST/PUT/PATCH 30/min, DELETE 5/min
  • Step-up MFA (TOTP) obrigatório em operações destrutivas: sessão de 1h (neetru auth mfa-session), --mfa-token <code> ou prompt (em --json/sem TTY: fail-closed). Desde 2.28.10 também em agent release (todos os canais), ops reg-token, ops bootstrap-admin (quando já há admin; --reactivate reativa staff desligado), ops migrate cli-keys (fora do dry-run), vm provision e deploy --env prod
  • agent release só aceita binários em https://core.neetru.com/releases/... ou no bucket GCS de releases (validado localmente, mesma regra do Core)
  • Dry-run disponível em comandos de mutação: --dry-run mostra efeito SEM aplicar
  • Telemetry opt-in (desde 2.11.0): habilitando telemetry.enabled=true o CLI emite {command, durationMs, ok, exitCode} anônimo via installId UUID. Zero token/path/email/env vazam

Stack

  • TypeScript 5 ESM-first
  • Node 20+ (engines.node: >=20; Node 22 LTS recomendado)
  • Sem node-fetch/axios: fetch global nativo
  • Commander 12 (CLI framework) + Inquirer 10 (prompts) + Chalk 5 + Ora (spinners)

Mais info

Licença

MIT © Neetru