# pyre CLI changelog

All notable changes to the `pyre` command-line client. Versions follow
semver; the tag is `cli-v<version>`.

## 1.0.13 — 2026-09-24

- `pyre volume rediscover` reports volumes whose deleted row was just
  marked encrypted: a volume older than the storage's own record is
  known to be encrypted by the key-check object beside its blocks, so
  its row now says so and deploy asks for the key file.

## 1.0.12 — 2026-09-24

- `pyre volume rediscover`: your storage now carries its own record of
  every volume (written at create, resize and every appliance attach),
  and this lists any volume it describes that the account has no
  record of -- storage attached with a recovery key from before
  records were kept, a volume lost with a database -- as a deleted
  volume, ready to restore. `pyre account reclaim` runs it by itself
  and names what it found. A volume older than that record is
  described from its first block, type unknown: listed as smb, and
  `pyre volume deleted restore <id> --type nfs|iscsi` says what it was.
- `pyre volume deleted list` shows each volume's type and whether it is
  encrypted (which rows need their key file).

## 1.0.11 — 2026-09-24

- `pyre account close --mode preserve` keeps every volume as a deleted
  volume (the control plane change of the same day) and names them;
  `pyre account reclaim` then says how many came back and points at
  `pyre volume deleted list` / `deleted restore <id>` /
  `appliance deploy <volume> --rebuild`, instead of "create a volume".
  A tenant preserved before 2026-09-24 has no volume records; the
  message then explains the recreate-by-name path.

## 1.0.10 — 2026-09-24

- `pyre account reclaim --key <recovery key>`: attach the storage of an
  account closed with `account close --mode preserve` to the account
  this token belongs to. That account must have nothing of its own yet
  (no storage, volumes, stores or appliances); the key is accepted in
  any spelling (case, dashes, spaces) and is spent on success, never
  by a refusal. Until now the key could only be entered on the
  password sign-up form, which a "Sign in with Google" account never
  sees; the dashboard has the same page under "Recover it with your
  key".

## 1.0.9 — 2026-09-23

- `pyre volume deleted restore` now says what comes next: `pyre
  appliance deploy <volume> --rebuild`. Deleting a volume revokes its
  appliance's identity, so a container started again from its old
  state comes up unable to connect; the rebuild form's fresh token
  re-enrols it and the state volume and key file can stay.

## 1.0.8 — 2026-09-23

- After `pyre volume delete` of a volume that had an appliance, the CLI
  says how to clear it from the computer (`pyre appliance cleanup
  --names <volume>`), as the dashboard's redirect to /cleanup does.
- A command given the name of a DELETED volume (`appliance remove`,
  `appliance disconnect`, `volume show`, ...) now says so: when it was
  deleted, the cleanup line for its appliance, and the `deleted restore`
  line that brings it back. Before, "no volume named" left the customer
  hunting for a way to remove a stale appliance.
- `pyre appliance cleanup` with no `--names` takes every deleted volume
  of the account (logged in). Logged out it still needs `--names`.

## 1.0.7 — 2026-09-23

- `pyre volume create --encryption customer` works and is documented
  (the 1.0.0–1.0.6 example said `customer-key`, which the API refuses;
  it is now accepted as an alias of `customer`, as are `none`/`off`).
  Any other value is refused with exit 2 and the two choices, before
  anything is sent. After creating an encrypted volume the CLI says
  where the key file will be made (`pyre appliance deploy`,
  `~/.pyre/<container>.key`) and that losing it makes the volume
  unrecoverable.
- Every input is checked against the API's own rule before a request
  is built: ids in paths are numeric; volume, recovery and view names,
  labels, policies, points in time, `--since`, `--type` (now also
  `nfs+smb`), `--os`, `--cache-mb`, `--store`, store fields, emails
  and URLs (`--api`, `api_base`, `download_base`, `--endpoint`) are
  validated; a bad value is a usage error (exit 2) naming the choices.
  Validated path segments are additionally percent-escaped.
- `pyre store probe|add`: the provider list is the API's (`aws`,
  `wasabi`, `minio`, `weka`, `other`; default `other`). The old
  default `s3` and the documented `backblaze` were refused by the
  server on every call.
- Exit codes: cobra's own parse errors (`unknown shorthand flag`,
  `flag needs an argument`) are usage errors (exit 2, was 1); a stray
  word after a group command (`pyre volume nosuch`) is a usage error
  (was help with exit 0).
- A server-side validation answer (HTTP 422) is rendered as
  `field: message`, not as a JSON dump.
- Tests: the customer command matrix (`internal/cmd/permutations_test.go`,
  over 220 rows: valid, invalid and injection cases against a fake control
  plane) and new smoke checks against the real API; design and
  pass/fail criteria in `docs/CLI-TESTING.md`.

## 1.0.6 — 2026-09-23

- Encryption is shown as "customer key" or "none" from the API's
  `encryption` field (server section 10); a server that does not send
  the field shows "unknown" instead of a false "none". Also fills the
  `pyre volume list` ENCRYPTION column.

## 1.0.5 — 2026-09-23

- `pyre update` says which file it replaces ("replacing /path/pyre"),
  checks that directory is writable BEFORE downloading and names it in
  the error (with `sudo pyre update` only when that path needs it), and
  after updating lists any other `pyre` on PATH it did not touch.
  `pyre version` shows the binary's path and any others on PATH.
- Sizes match the dashboard: decimal GB with one decimal
  (26843545600 bytes → 26.8 GB); appliance measurements that arrive
  as strings are formatted too (no more raw byte counts).
- `volume show` / `volume status`: the Offline line appears only while
  the appliance is offline; buffer fill and disk-low facts sit on the
  Sync line otherwise, and an empty buffer is not mentioned.

## 1.0.4 — 2026-09-23

- `pyre volume show` is readable: one line each for Volume, Appliance,
  Sync, Offline, Storage, Errors and Measured, sizes in the dashboard's
  units, times local. Nothing in table mode prints raw JSON any more
  (nested data becomes dotted lines); `-o json` is unchanged, `-o plain`
  flattens to `key<TAB>value`.
- New `pyre volume status <volume>`: the live block alone, with
  `--watch [--every 5s]` redrawing until Ctrl-C on macOS, Linux and
  Windows (no watch(1) needed).
- `pyre appliance status` uses the same rendering.
- `pyre completion` without a shell now says
  `pyre completion <bash|zsh|fish|powershell> — e.g. pyre completion zsh`.
- `pyre update` rewrites the completion files it finds (bash, zsh,
  fish, PowerShell) with the new binary, clears stale `~/.zcompdump*`,
  and says when zsh completion is installed but `~/.zshrc` does not
  load it.

## 1.0.3 — 2026-09-23

- Homebrew: the generated formula carries a top-level `url` so current
  Homebrew accepts the tap (it validates every platform, Linux arm64
  included, and refused 1.0.2's formula with "requires at least a URL").
  No change to the binary.

## 1.0.2 — 2026-09-23

(1.0.1 was tagged on the same day but never published: its installer
still had the PATH gap below. Everything listed here is new since 1.0.0.)

- install.sh: installs into /usr/local/bin through sudo (the password
  prompt works under `curl | sh`); the ~/.local/bin fallback now adds
  itself to PATH and the zsh completion dir to fpath in your shell rc,
  and ends with "Open a new terminal (or run: source ~/.zshrc)". Found
  by the first real install on a Mac: `pyre` was not on PATH.

- Token lifecycle: `pyre auth token create --expires 30d|1y|never`
  (server default 90 days), `list` shows state and expiry, `remove`
  deletes a revoked or expired row (`--force` revokes first), `prune`
  drops every such row. Operators: `pyre admin tokens
  list|revoke|remove|prune` across tenants.
- `pyre uninstall` now removes every man page it installed
  (`pyre-<command>.1.gz`), not only `pyre.1.gz`.
- Install docs: `brew trust pyredata/pyre` before `brew install pyre`
  (current Homebrew refuses formulae from an untrusted tap).

## 1.0.0 — 2026-09-23

First packaged release, a rewrite in Go of the 0.1 Python prototype.

- One static binary per platform: macOS (Apple Silicon and Intel),
  Linux x86-64, Windows x86-64.
- Install channels: apt repository (signed), Homebrew tap, `curl | sh`,
  PowerShell one-liner, Scoop manifest, plain archives.
- `pyre update` (signed releases, in-place replace; defers to apt /
  Homebrew / Scoop when they installed it) and `pyre uninstall`.
- Shell completion for bash, zsh, fish and PowerShell; man pages.
- Scripting: `-o json` / `-o plain`, `--yes`, stable exit codes,
  `pyre batch` to run a file of commands with one login.
- Profiles for more than one control plane (`--profile`, `pyre config`),
  `--ca-cert` / `--insecure` for self-hosted managers, every host a
  config value.
- Customer commands: auth (token per user), volume (incl. deleted
  volumes), restore-points, restore, recovery, view, history, snapshot,
  appliance (deploy/mount/remove/status/disconnect/flush/cleanup),
  store (bring your own S3), account.
- Operator commands (`pyre admin`): hubs (scan/add/preflight/build/
  promote/demote/remove/bootstrap/...), users (approve/reject/delete),
  tenants.
