Install & Authentication
Install
Section titled “Install”The CLI is a TypeScript/Node package distributed two ways.
npm / bun (the developer path)
Section titled “npm / bun (the developer path)”npm i -g @ontrove/cli# or, without a global install:bunx @ontrove/cli search "vector search"Requires Node 20 or newer. The binary is named trove.
Standalone binary
Section titled “Standalone binary”A single self-contained executable (built with bun build --compile, no Node install required) is planned for distribution through brew install trove and GitHub Releases — the brew install trove && trove search … story. This compiled-binary distribution is a later packaging step; the npm/bun path above is the way to run the CLI today.
Authenticating
Section titled “Authenticating”trove authenticates with Clerk exactly as every other Trove client does — it presents a bearer token as Authorization: Bearer on every request. It has no special route and no elevated scope.
trove login
Section titled “trove login”trove login # interactive (browser)trove login --token "$CLERK_JWT" --email you@example.com # non-interactiveWith no token, login runs the loopback authorization-code + PKCE flow (RFC 8252): it discovers the OAuth endpoints from the API’s /.well-known/oauth-protected-resource (→ the Clerk authorization-server metadata), spins a 127.0.0.1 callback server, opens your browser to authorize, captures the redirect, and exchanges the code for a token. It then verifies the token by probing query stats and persists it (see Token storage — OS keychain when available, else the chmod-600 file).
--token <jwt> (or TROVE_TOKEN) overrides the browser flow with a token directly — the CI / non-interactive path.
Flags:
| Flag | Description |
|---|---|
--token <jwt> | The Clerk bearer token to store. Falls back to TROVE_TOKEN if omitted. |
--email <addr> | The signed-in email, recorded in the profile for whoami/logout UX. |
The target profile is --profile if given, else the config’s default_profile, else prod.
trove logout
Section titled “trove logout”trove logoutForgets the token for the active profile (it rewrites the profile without a token key, keeping api_url/issuer). It does not delete the profile.
trove whoami
Section titled “trove whoami”trove whoamiVerifies the active token and prints your identity plus corpus size. Because the schema has no viewer field yet, whoami piggybacks on query stats and reports the email recorded in your profile.
profile: prodemail: you@example.comendpoint: https://api.ontrove.shtoken: configdocuments: 8209sources: 32The token line reports the token source: keychain (the OS keychain), config (the profile file), or env (TROVE_TOKEN). If no token is available, whoami exits with code 4.
The config file: ~/.trove/config.toml
Section titled “The config file: ~/.trove/config.toml”The only local state the CLI keeps is a set of named profiles — each an environment plus identity — so you can target production and a local dev Worker without re-authenticating.
default_profile = "prod"
[profiles.prod]api_url = "https://api.ontrove.sh"issuer = "https://accounts.ontrove.sh"token_ref = "keychain:trove-prod" # token held in the OS keychainemail = "you@example.com"
[profiles.dev]api_url = "http://localhost:8787"issuer = "https://accounts.ontrove.sh"token = "…" # inline fallback when no keychainA missing config file is not an error — it simply means you have not logged in yet. The defaults are api_url = https://api.ontrove.sh, issuer = https://accounts.ontrove.sh, and default_profile = prod.
Token storage
Section titled “Token storage”trove login prefers the OS keychain: the macOS Keychain via the security CLI, or Linux libsecret via secret-tool if present. When a keychain is used, the config file records a token_ref = "keychain:trove-<profile>" and the raw token never touches disk. There is no new native dependency — the CLI shells out to the OS CLIs, detects their availability, and falls back cleanly.
When no keychain is available (CI, containers), the token is stored inline in the TOML file, which the CLI creates under ~/.trove/ and chmods to 600 so it is never world-readable. TROVE_TOKEN overrides either store. The CLI never logs the token, and --json output never includes it.
Selecting a profile and overriding the transport
Section titled “Selecting a profile and overriding the transport”The active profile and its transport overrides resolve by a fixed precedence:
| Setting | Precedence (highest first) |
|---|---|
| Profile name | --profile <name> → TROVE_PROFILE → default_profile → prod |
| Token | TROVE_TOKEN → the profile’s stored token |
| Endpoint | --endpoint <url> → the profile’s api_url |
--profile and --endpoint are global flags — they may appear before or after the command. TROVE_TOKEN overriding any stored token is the CI path: set it in the environment and skip login entirely.
# Use the dev profile for one commandtrove --profile dev search "kafka"
# Override just the endpoint (keeps the profile's identity)trove --endpoint http://localhost:8787 stats
# CI: no login, token straight from the environmentTROVE_TOKEN="$CLERK_JWT" trove list --jsonEvery command that talks to the API requires a token. If none can be resolved, the command fails with an auth error (exit code 4): Not logged in (profile: <name>). Run 'trove login' or set TROVE_TOKEN.
No privilege
Section titled “No privilege”The token the CLI obtains is a normal user token — no special route, no elevated scope. Authorization is enforced server-side in the resolvers: the CLI does nothing special; it sends the operation and the server decides. A caller without access gets the same rejection the web app would.