@dogeos/gov-cli
v0.1.1
Published
dogeos-gov: the DogeOS governance portal from the command line, for people and agents. Reads what your API key's owner can see; writes stay drafts.
Readme
@dogeos/gov-cli
dogeos-gov: the DogeOS Governance Portal from the command line, for people and AI agents.
- Reads: a command can read whatever the owner of your API key can see in the portal.
- Writes: a maintainer key with write scopes can draft work. Writes always stay drafts: there is no publish, approve or stance command, and the portal refuses them anyway.
- Not binding: the portal is a coordination layer, and nothing here is binding on the DogeOS protocol.
One self-contained file: no runtime dependencies and no install scripts. Node.js 22 or newer.
Run it
npx @dogeos/gov-cli whoamiOr install it, and the command is dogeos-gov:
npm install --global @dogeos/gov-cli
dogeos-gov whoamiConfigure
| Variable | What |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| DOGEOS_GOV_URL | The portal's site root, e.g. https://gov.dogeos.com. A URL ending in /api/v1 or /api works too: the CLI drops it and says so once. |
| DOGEOS_GOV_API_KEY | Your API key (dgp_…), from the portal's Settings → API keys. It's shown once, so keep it like a password. The older name DOGEOS_GOV_TOKEN still works but is deprecated. |
export DOGEOS_GOV_URL=https://gov.dogeos.com
export DOGEOS_GOV_API_KEY=dgp_…--url <site root> and --api-key <key> override the variables for one command.
- Prefer the variable for the key: a flag can end up in your shell history.
- The key is sent only as a bearer token to the portal, and is never printed; output shows only its prefix.
If either setting is missing, the CLI says which one and shows an example, then exits 2.
Examples
The default output is for people: short labelled summaries, and tables that fit the terminal.
$ dogeos-gov whoami
API key laptop (dgp_l_AXGskt…)
Kind read
Tier member
Scopes read
Owner Alex
Role member
Expires in 30 days (2026-11-06 21:25 UTC)
$ dogeos-gov proposals list
Number Status Type Networks Title
DGP-0009 open software_update · required testnet Upgrade attestation signer to v0.3.1
DGP-0001 executing software_update · required mainnet, testnet Required attestation signer upgrade
$ dogeos-gov proposals verify DGP-0009
DGP-0009: everything checks out
Revision 1 digest match
$ DOGEOS_GOV_API_KEY=dgp_revoked dogeos-gov whoami
Error: the portal refused this key (401): Missing or invalid API key
Check DOGEOS_GOV_API_KEY (or --api-key). Create a new key in the portal: Settings → API keys.More commands:
dogeos-gov whoami # this key: kind, tier, role, scopes, expiry
dogeos-gov help # every command; marks the ones this key can't run
dogeos-gov proposals list --limit 20
dogeos-gov proposals show DGP-0007
dogeos-gov proposals verify DGP-0007 # recompute digests, bridge script/P2SH and PoP locally
dogeos-gov proposals export-bridge DGP-0007 > bridge.json # a rotation's core bridge.json, byte for byte
dogeos-gov proposals export-bridge DGP-0007 --json # + allowlist entry and WP rotate-key request
dogeos-gov dashboard testnet
dogeos-gov --version # the version and the git commit it was built fromMaintainer keys with write scopes. Pass --dry-run first: the server checks everything and commits nothing.
dogeos-gov agent context
dogeos-gov keys add --network testnet --kind dogecoin_secp256k1 \
--protocol-role attestation_signer --label "signer A" --team <team-id> --pubkey <hex> --dry-run
dogeos-gov proposals draft create --from-file draft.json --dry-runRetries. Writes send an Idempotency-Key. To retry an interrupted write safely, use --idempotency-key <key>, with one key per logical change.
For agents: --json
Add --json to any command, including help and --version. Then:
- stdout carries exactly one JSON document on one line, whatever happens;
- stderr stays empty;
- the exit code says how it went.
| Outcome | Envelope |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Success | {"ok": true, "command": "proposals show", "data": …}. A list adds the API's "next_cursor": {"ok": true, "command": "proposals list", "data": [ … ], "next_cursor": "…" \| null}. |
| Failure | {"ok": false, "command": "whoami" \| null, "exit_code": 3, "error": {"code": "api_error", "message": "…", "status"?: 401, "detail"?: …, "hint"?: "…"}} |
| Verify mismatch | as a failure, with "error": {"code": "verify_failed"} and the full report in "data" |
Either outcome may also carry "warnings": ["…"], for example the deprecated variable name.
error.codeis one of:usage,unknown_command,missing_api_key,missing_url,missing_scope,api_error(with the portal's HTTPstatusand its own error indetail),network_error,verify_failed,internal_error.error.hint, when present, is the same advice a person sees (for example, "the URL should be the site root").dogeos-gov help --jsonlists every command with its usage, its scope, and whether this key may run it (available,missing_scope), plus the exit codes.
Without --json, a command prints readable text on stdout, and Error: … plus a hint on stderr. That text may change between versions, so agents should use --json.
Exit codes
These are stable. A new code may be added, but an existing one never changes meaning.
| Code | Meaning |
| ---- | ----------------------------------------------------------------------------------------------------------- |
| 0 | Success. |
| 1 | proposals verify ran and something didn't match. The report says what. |
| 2 | Refused locally: bad arguments, an unknown command, a missing setting (URL or API key), or a missing scope. |
| 3 | The portal refused the request: an HTTP error, for example 401 for a revoked key or 404. |
| 4 | The portal couldn't be reached (network, DNS, TLS). |
| 5 | A bug in the CLI. Please report it with the output. |
Verifying a release
Each release's tarball is reproducible: two builds of the same commit are byte-identical. The release notes record its sha256 and the commit. To compare:
npm pack @dogeos/gov-cli@<version>
sha256sum dogeos-gov-cli-<version>.tgz
dogeos-gov --version # names the commitLicense
MIT (LICENSE), for this CLI package only; the governance portal itself isn't covered. The bundled third-party code (@noble/curves, @noble/hashes, MIT) keeps its license text at the end of dogeos-gov.mjs.
