@repose-sh/cli
v0.1.1
Published
Command line for Repose. Monitors as a file you can review.
Downloads
304
Maintainers
Readme
@repose-sh/cli
repose — monitors from the command line, and monitors as a file you can review in a
pull request.
Install
npm install -g @repose-sh/cli # then: repose --help
npx @repose-sh/cli --help # or without installingNode 20 or newer. Its only dependency is @repose-sh/sdk. The package is
@repose-sh/cli; the command is repose.
Setup
export REPOSE_TOKEN=rsk_… # Settings -> API tokens
export REPOSE_URL=https://repose.sh # optional, this is the defaultListing needs a read token. Creating, updating, deleting, acknowledging and any
non-dry-run apply need a read-write token.
Commands
repose monitors list
repose monitors create --name checkout --url https://checkout.acme.com/health --interval 30
repose monitors create --name "primary database" --kind tcp --host db.acme.com --port 5432
repose monitors delete mon_a1b2c3
repose incidents list
repose incidents list --status open
repose incidents ack inc_a1b2c3
repose apply repose.json --dry-run
repose apply repose.json
repose --helpEverything exits non-zero with a plain message on stderr when it fails.
apply
apply reads a JSON file and reconciles it with the workspace. Monitors are matched
by name — the name is the key, so renaming a monitor in the file reads as "delete
one, create another".
{
"monitors": [
{
"name": "checkout",
"kind": "http",
"url": "https://checkout.acme.com/health",
"intervalSeconds": 30,
"consensusRequired": 3,
"timeoutMs": 5000,
"expectedStatus": 200
},
{ "name": "primary database", "kind": "tcp", "host": "db.acme.com", "port": 5432 },
{ "name": "acme.com certificate", "kind": "ssl", "host": "acme.com", "intervalSeconds": 3600 },
{ "name": "acme.com dns", "kind": "dns", "host": "acme.com", "recordType": "A" },
{ "name": "nightly export", "kind": "heartbeat", "intervalSeconds": 3600 }
]
}A top-level array works too. Fields and their limits match the API exactly: kind is
http (default), tcp, dns, ssl or heartbeat; intervalSeconds 15–3600;
consensusRequired 1–20; timeoutMs 1000–60000; expectedStatus 100–599. The file is
validated before anything is sent, and every problem is reported at once.
--dry-run prints the plan and changes nothing:
plan repose.json -> https://repose.sh · 5 in the file, 4 in the workspace
unchanged www
update api · interval 60s -> 30s, consensus 2 -> 3
blocked db · file says tcp://db.acme.com:5432, workspace has tcp://db.acme.com:5433. The API can't move a target — delete it and re-add.
create checkout · http https://checkout.acme.com/health, every 30s, 3 probes must agree
extra staging · in the workspace, not in the file. Left alone; --prune deletes it.
2 changes: 1 to create, 1 to update, 1 extra (kept), 1 blocked.
dry run — nothing was changed.--prune deletes the extras. Without it they're reported and left running, because
silently deleting someone's monitoring is a worse failure than leaving one too many.
What apply can't see or do
We'd rather tell you than have you find out during an incident.
timeoutMsandexpectedStatusdrift is invisible. The API's monitor list doesn't return them, soapplycan't compare. They're sent on create, and included in an update when some other field changed. If you edit only those two in the file, nothing happens.- Kind and target changes are blocked, not applied. The API can't move a monitor's
kind, url, host or port.
applyreports it and tells you to delete and re-add, rather than deleting your incident history behind your back. paused: trueon a new monitor takes two calls. Create doesn't acceptpaused, so a created monitor is paused by a follow-up patch.- Names must be unique in the file. Matching is by name; duplicates are rejected before anything is sent.
- No state file, no locking. Two people running
applyat once will both act on what they read. Run it from CI on one branch and this doesn't come up.
