CLI: sdh
sdh is the command line for SeeDropHost. It is not published on npm yet: run it from a clone of the repository with npx sdh … or npm run sdh -- …. Its messages are in Brazilian Portuguese.
Configuration
| Variable | Default | What it is |
|---|---|---|
SDH_API_URL | http://localhost:8787 | your server |
SDH_TOKEN | dev-token | an account token (sdh_…), which only sees its own account's sites, or the server (administrator) token, which sees every account |
Every action is recorded in the audit log with the actor cli.
Commands
| Command | What it does |
|---|---|
sdh sites | lists the sites |
sdh create <name> | creates a site |
sdh deploy <folder|site.zip|page.html> --site <name> [--draft] [--title "text"] | publishes; a folder uploads only changed files; with netlify.toml / seedrop.toml it publishes the publish folder and carries the functions |
sdh drop <folder|site.zip|page.html> | publishes without an account (if the server allows it); expires in 24 h |
sdh reivindicar <code> [--nome name] | claims a drop into the account |
sdh deploys <site> | deploy history |
sdh publish <site> <deploy-id> | publishes a draft or rolls back to an earlier deploy |
sdh env <site> | lists variables (secret values masked) |
sdh env:set <site> KEY value [--public] | sets a variable; secret unless --public |
sdh domain:add <site> <domain> | connects a domain and prints the DNS records |
sdh domain:check <domain> | checks the DNS and says the next step |
sdh forms <site> | forms and totals |
sdh leads <site> [--form name] | submissions received |
sdh conta | the account of the token and its plan (JSON) |
sdh uso | plan, limits and usage of the month: sites, bandwidth, leads; warnings and next steps |
sdh plano | subscription: state, paid until, next charge, open invoice and prices |
sdh assinar <pro|agencia> [--anual] --nome "Name" --cpf <CPF or CNPJ> --email <email> | subscribes or changes plan; prints the Pix code and opens the payment page (Pix, boleto or card; --nao-abrir only prints the link) |
sdh cancelar-assinatura --sim | stops the charge; the plan lasts until the end of the paid period and nothing is deleted |
sdh cobranca | (administrator) what is missing to charge: Asaas key, webhook token, webhook |
sdh cobranca:webhook [--email x] | (administrator) registers only the SeeDropHost webhook on Asaas |
sdh tokens | the tokens of the account, without their secret |
sdh token:criar [label] | creates a token; the secret is shown once |
sdh token:revogar <id> | revokes a token at once (the id from sdh tokens) |
sdh exportar <site> [file.zip] | "take everything": site files, leads.csv, variable names |
sdh comparar <current-url> <new-url> [--max 500] [--json file.json] [--projeto folder] [--previa] | migration check, page by page |
Account, usage and tokens
sdh uso shows the plan and the month so far. Sites, bandwidth and leads are counted; deploys never are. Going over bandwidth or leads only prints a warning: no site goes offline and every lead is kept.
SDH_TOKEN=sdh_… npx sdh uso
# Conta Client Ltda — plano Grátis — mês 2026-10
# sites: 1 de 3
# banda: 0,05 GB de 30 GB
# leads: 4 (limite: 100)
# deploys: 6 neste mês (deploy nunca conta para limite)
# estado: dentro do plano
#
# Próximos passos:
# - nada a fazer: a conta está dentro do plano. Deploys são ilimitados.
Give each machine or agent its own token, so one can be revoked without touching the others. A token is created with the token you already have; the account allows up to 20 active tokens.
npx sdh token:criar ci
# ✓ token tok-… (ci) criado
# sdh_…
# guarde agora: ele não aparece de novo. Use como SDH_TOKEN.
npx sdh tokens # ids, labels, last use, revoked ones (kept for 90 days)
npx sdh token:revogar tok-… # stops working at once
Creating a site beyond the plan's site count fails with a message that says what to do (delete a site you no longer use or change plan); nothing that is live is touched.
Take everything
npx sdh exportar my-site # my-site-2026-10-31.zip in the current folder
npx sdh exportar my-site backup.zip
The zip has site/ (the live deploy's files, with _redirects, _headers and netlify.toml / seedrop.toml if the site had them), leads.csv (opens in Excel and Google Sheets), variaveis.txt (variable names only; values never leave) and LEIA-ME.txt. An anonymous drop has nothing to export: claim it first with sdh reivindicar.
Deploy
The type is decided by what is on disk: a folder, a file ending in .zip, or a file ending in .html / .htm.
npx sdh deploy ./dist --site my-site
npx sdh deploy site.zip --site my-site --draft --title "new pricing section"
npx sdh deploy index.html --site my-site
When uploading a folder, files and folders whose name starts with . are skipped (except .well-known), and so is node_modules. The server applies the same rule to a .zip.
If the folder has a seedrop.toml or netlify.toml (seedrop.toml wins), only its [build] publish folder goes live; the config file and the functions folder go with it but are never served. Point the CLI at the repository root and nothing in the project needs to change. The CLI does not run the build command.
The output shows the deploy id, files sent, the config file read and the published folder, the functions found (they answer only if the server has SDH_FUNCTIONS=1), the preview and live URLs, the SEO/GEO score, the forms found, and any rule that was not understood.
Drop and claim
npx sdh drop ./dist
# ✓ no ar: http://drop-9d4755b89c.localhost:8787
# código para reivindicar (guarde, não aparece de novo): ab0e…
npx sdh reivindicar ab0e… --nome my-site
The CLI refuses a drop above 25 MB before sending it. A folder is zipped in memory (no compression) and sent in one request.
Migration check
npx sdh comparar https://www.current-site.com https://<deploy>--my-site.your-server.example --projeto ./my-repo --json report.json
It discovers pages from the sitemap and from links (up to --max, default 500, per site) and compares each address:
- blocks the switch: status, redirects, canonical, noindex, hreflang, forms, and a new
robots.txtDisallowthat covers existing pages; - attention: title, description, h1, JSON-LD, text, other
robots.txtchanges and URLs that left the sitemap.
Options:
--projeto <folder>: also checks the old addresses listed in that project's_redirectsandnetlify.toml, so a redirect you forgot shows up.--previa: the new site is a draft preview, so thenoindexSeeDropHost adds to previews does not count. Preview addresses (<deploy>--<site>.) are recognised without the flag. Anoindexyour own site declares still blocks.--json <file>: writes the full list to that file (the file name is required).
If the current site's home redirects to another host (bare domain ↔ www), the check follows it once and says so. It prints up to 30 problems and exits with code 1 when anything blocks — handy in CI before changing DNS.