@glasser-ai/cli
v0.1.63
Published
Search, inspect and run paid API endpoints with one Key — the Glasser CLI
Maintainers
Readme
glasser CLI
Search, inspect and run paid API endpoints with one Key — the first-party
client for the Glasser data plane (/v1).
Install
curl -fsSL https://glasser.ai/install.sh | sh # no npm needed (Node >= 22)
# or, with npm:
npm install -g @glasser-ai/cliRe-run either command to upgrade. Then: glasser login.
Commands
glasser search ["<query>"] --use-case "<ask>" [--limit N] [--cursor C] # no query lists the catalog; --use-case is always required
# -q/--query takes the same value; --query=<q> for a leading dash
glasser inspect -p <provider> -e <endpoint> [--endpoint-version N]
glasser run -p <provider> -e <endpoint> [-i '<json>'|@file | -f <path>]
[--endpoint-version N] [--idempotency-key K]
[--wait] [--wait-timeout s] [-o file]
glasser runs list [--limit --cursor --status --provider --endpoint]
glasser runs get -r <runId> [--wait] [--wait-timeout s] [-o file]
glasser runs stop -r <runId>
glasser balance
glasser balance history [--limit --cursor --kind]
glasser keys add --label <l> --key <k> | list | activate --label <l>
| remove --label <l> [--force]Global: -j/--json, --help, --version.
Login
glasser login [--no-browser] — the browser flow: the terminal prints a
match code, the console's /cli/authorize page opens, one click approves,
and the Key lands in the local store (labelled after the workspace slug,
activated). Approve only when the code on the page matches the terminal; the
CLI then prints WHICH workspace it logged into — read that line. Denied or
expired approvals exit 1 with a re-run hint. login --json is a usage error:
the non-interactive path is minting a Key in the console plus
glasser keys add.
Keys
Precedence: GLASSER_API_KEY (validated; a malformed value is an error, it
never falls back silently) > the active stored Key > an error pointing at
glasser keys add.
The local store is $XDG_CONFIG_HOME/glasser/keys.json (default
~/.config, file mode 0600). Labels are unique; the first Key auto-activates;
removing the active Key deactivates it; keys remove only touches this
machine — it does not revoke the Key. Only masked tokens (gl_1bba****) are
ever printed.
Run semantics
statusis the Run lifecycle;Response: HTTP nis the provider's verdict.COMPLETED+HTTP 404is a normal outcome (charged by the NO_RESULT clause), not an error.- The
Idempotency-Keyis printed to stderr before dispatch. After an ambiguous failure (transport error, timeout,service_unavailable— the API may have admitted a Run before answering 503) retry with the SAME key: a replay is a read and is never charged twice. The error message carries the exact retry command. --waitpolls (0.5s → ×2 → cap 10s) until terminal;--wait-timeout(default 300s) requires--wait. Sync endpoints answer terminally in one round trip and never poll.-o <file>writes the Run'soutputfield only for a COMPLETED Run with non-null output.- Money fields are exact USD decimal strings, printed verbatim. Sum them with decimal arithmetic, never floats.
Streams and exit codes
Human mode: data on stdout; progress, hints, prompts and errors on stderr.
JSON mode (--json): stdout carries only the raw success body; every error —
usage errors included — is a single JSON object on stderr shaped like the API
envelope ({"error":{"code",...},"request_id"?}). keys remove --json
requires --force so a prompt can never corrupt machine output.
| Code | Meaning |
|---|---|
| 0 | Success. A COMPLETED Run (any provider status); a successful runs stop. |
| 1 | API error, transport failure, --wait timeout, or run/runs get ending FAILED / STOPPED. |
| 2 | Usage: bad flags or input JSON, invalid env values, no Key configured. |
| 130 | Interrupted. |
Design notes
searchmatchesPOST /v1/endpoints/search— the CLI verb is the API verb.--waitand--wait-timeout <seconds>are separate flags.-f/--input-file <path>exists alongside-i(mutually exclusive).- Every
runcarries an Idempotency-Key — retrying with the same key is a read, never a second charge.
Development
pnpm --filter @glasser-ai/cli dev -- search -q "web search" --use-case "find a web search API" # tsx, no build
pnpm --filter @glasser-ai/cli build # esbuild → dist/glasser.js
node apps/cli/dist/glasser.js --help
cd apps/cli && pnpm link --global # a PATH `glasser` shim
pnpm --filter @glasser-ai/cli test:p0 # unit
GLASSER_API_KEY=gl_… pnpm --filter @glasser-ai/cli test:integration # needs seeded :3101Env: GLASSER_API_BASE_URL (default https://api.glasser.ai),
GLASSER_API_KEY, XDG_CONFIG_HOME, NO_COLOR (colour in
framework-rendered help and version text).
