DeesseJS

Authentication

Sign in with the CLI.

Authentication is optional. deessejs init <slug> works without an account; the CLI clones a public GitHub repo and exits. You only need auth login if a command hits the DeesseJS API on your behalf (publishing templates, fetching private registry data, leaving reviews, anything not yet public).

The CLI signs in via OAuth 2.0 device authorization grant. There's no password prompt, no copy-paste of API tokens, no headless browser.

deessejs auth login

deessejs auth login

What happens:

  1. The CLI requests a device code from POST /api/v1/auth/device/code on the DeesseJS server. The response carries a short user code and a long device code, plus a verification URL.
  2. The CLI spawns your default browser at the verification URL: https://app.deessejs.com/device?user_code=....
  3. The CLI polls POST /api/v1/auth/device/token until you approve (or deny) in the browser.
  4. On approval, the CLI exchanges the device code for an access token, validates it server-side, and writes ~/.deessejs/auth.json with mode 0600.
  5. The CLI echoes the identity you signed in with. The access token itself never prints.

If you aren't signed in to app.deessejs.com when you land on /device, you'll redirect through the normal login flow and bounce back to /device?redirect=... once authenticated.

Flags

FlagEffect
--jsonMachine-readable output ({ ok: true, user } on success, { ok: false, code, message, hint } on failure).

Exit codes

  • 0: successful login.
  • 1: generic failure, network error, or server error (network_error).
  • 1: device code expired (cli_device_expired).
  • 1: you denied the request in the browser (cli_device_denied).

deessejs auth status

deessejs auth status

Reads the cached session and validates it against GET /api/v1/auth/get-session with a Bearer header. Three terminal states:

StateOutputExit code
No ~/.deessejs/auth.jsonYellow notice: "no active session. Run deesse auth login to authorise this machine."0
Token still validGreen ✓ + identity + fetchedAt timestamp0
Token revoked or expired server-sideYellow notice + the stale identity for context0

The exit code always reads 0; auth status is a read-only diagnostic and never modifies state.

The token never echoes, only its fetchedAt timestamp and the resolved user identity (email, name, id).

Flags

FlagEffect
--jsonEmits { ok: true, user, fetchedAt }, { ok: false, reason: "no_session" }, or { ok: false, reason: "session_invalid", stored: { user, fetchedAt } }.

deessejs auth logout

deessejs auth logout

Two-step teardown:

  1. POST /api/v1/auth/sign-out with the stored bearer token, to invalidate the session server-side.
  2. Delete ~/.deessejs/auth.json regardless of the sign-out outcome. A stale file is worse than a missing one, because every subsequent command would silently use a dead token.

If ~/.deessejs/auth.json doesn't exist, auth logout exits 0 silently: there's no session to revoke.

Flags

FlagEffect
--json{ ok: true } on success, { ok: true, reason: "no_session" } if nothing existed to revoke.

Where the token lives

~/.deessejs/auth.json, mode 0600 on Linux and macOS, or the closest Windows equivalent. The file stays short-lived: each call to a server-hitting command validates the token via auth status semantics, and any 401 invalidates the cache.

The file shape:

{
  "access_token": "...",
  "user": { "id": "...", "email": "...", "name": "..." },
  "fetchedAt": "2026-09-21T10:00:00.000Z"
}

The token format stays opaque; treat the entire file as a secret.

Troubleshooting

"The stored token no longer matches an active session on the server."

Run deessejs auth login again. The CLI cached a token that the server no longer recognises (you signed out elsewhere, the session got revoked, or the access token expired). auth status keeps echoing the stale identity until you re-login.

cli_device_denied

You clicked Deny on the /device page, or the page expired before you approved. Re-run deessejs auth login.

cli_device_expired

The 30-minute device-code window elapsed before you approved. The CLI aborts the poll and exits. Re-run deessejs auth login; each invocation requests a fresh code.

Permission errors writing ~/.deessejs/auth.json

The CLI tries fs.open(path, O_WRONLY | O_CREAT, 0o600) on POSIX. If the file already exists with looser permissions, the CLI won't tighten them; fix it manually (chmod 600 ~/.deessejs/auth.json) or delete the file and re-login.

"Logged in as unknown user"

The CLI never falls back to a synthetic identity when the server rejects the bearer token (per ADR-022, "Bug A"). If you see this, it means auth.json got hand-edited or copied from another machine. Delete the file and re-login.

Network errors during polling

Transient network failures inside the device-flow poll window trigger exponential-backoff retries. If the network stays down for the full 30-minute window, the poll exits with cli_device_expired. Re-run auth login once the network returns.

On this page