> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ankra.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI Changelog

> Release history for the Ankra CLI

<Update label="v0.9.0">
  # Proxmox and Morpheus, AI Agent Runs, and Writes That Ask First

  Two new self-managed cluster families, terminal control over what your AI agents are doing, confirmation prompts for the writes agent-mode chat proposes, and a long list of commands that finally show the data the API was sending all along.

  ## Proxmox VE and HPE Morpheus clusters

  `ankra cluster proxmox` and `ankra cluster morpheus` bring both platforms to the terminal: create and deprovision, stop and start, worker and node-group scaling, labels and taints, autoscaling, control-plane changes, node inspection, SSH keys, and Kubernetes upgrades. Each family also discovers what the platform offers - Proxmox nodes, storages, bridges, and templates; Morpheus groups, clouds, plans, layouts, and networks - and manages its own credentials.

  ```bash theme={null}
  ankra credentials proxmox create --help
  ankra cluster proxmox nodes list <cluster_id>
  ankra cluster morpheus node-group list <cluster_id>
  ```

  Proxmox nodes restart with `ankra cluster proxmox nodes restart`. Morpheus has no restart lane on the platform, so the CLI does not pretend to offer one.

  [Proxmox clusters →](/guides/proxmox-clusters) | [Morpheus clusters →](/guides/morpheus-clusters)

  ## Managed Kubernetes reaches parity

  `ankra cluster managed stop | start` drives provider-native stop and start where the provider supports it (AKS today). The new `ankra cluster managed node-pool update` changes node counts and autoscaling settings in place, node pools accept autoscaling bounds at create and add time (`--autoscaling`, `--autoscaling-min`, `--autoscaling-max`), and Scaleway Kapsule joins the provider list as `--provider kapsule`.

  [Managed Kubernetes →](/guides/managed-kubernetes)

  ## See and stop what your AI agents are doing

  The new `ankra agents` family lists the organisation's dispatched agent runs, shows one run in full, reads the session transcript of what the agent actually said and did, and cancels a live run - the platform interrupts the in-flight turn within seconds without pausing the agent itself. Cancelling requires organisation admin rights, and all four commands support `-o json|yaml`.

  ```bash theme={null}
  ankra agents runs --status running
  ankra agents transcript <run_id>
  ankra agents cancel <run_id>
  ```

  [agents reference →](/reference/cli/agents)

  ## Agent-mode chat asks before it writes

  In agent mode every mutating tool halts the turn and proposes the write, and the write only runs once the proposal is confirmed. The CLI used to drop that proposal silently, so `ankra chat --mode agent "restart node worker-1"` appeared to do nothing. The stream now renders each proposal - tool, description, risk, whether it is reversible, parameters, expiry, and the action id - an interactive session prompts to run or discard it, and `ankra chat actions confirm | reject | list` drives the same decision from a script.

  If the cluster drifted since the proposal, confirming reports the drift instead of applying it, and prints the ready-to-run `--force` invocation. A superseded action is not offered a force, because forcing it cannot work.

  [chat actions reference →](/reference/cli/chat)

  ## Scaleway lifecycle and node commands

  `ankra cluster scaleway stop | start` releases and re-provisions compute while preserving the cluster definition, and `ankra cluster scaleway nodes list | get | restart` closes the last gap in provider node coverage - a Scaleway node could already be restarted from the portal and from AI chat, but not from the terminal.

  ## Node restarts and bastion resize across the provisioned providers

  For Hetzner, OVH, UpCloud, and DigitalOcean, `ankra cluster <provider> nodes restart` reboots any provisioned node - a control plane node, a worker, or the bastion/gateway - as a tracked operation, and the new `bastion resize` command changes the bastion instance type with the same submit-or-`--wait` contract as node-group upgrades. `nodes list` gained a `PROVIDER_STATUS` column carrying the cloud provider's live power state, so an externally-stopped VM is visible before you act on it.

  ## Applications from the terminal

  `ankra application add .` detects a local GitHub checkout and starts application setup, and the subcommands cover lifecycle, deployment, workflow, repository, security, publishing, and demo operations.

  [application reference →](/reference/cli/application)

  ## Set a secret and encrypt it in one commit

  `ankra cluster encrypt manifest` accepts repeatable `--set` edits that are applied in memory before encryption, so the new value and its SOPS encryption land in a single commit - the plaintext never reaches git history. The previously documented flow of `manifests upgrade --set` followed by `encrypt manifest` committed the plaintext first, leaving it recoverable from the repository history.

  ```bash theme={null}
  ankra cluster encrypt manifest db-secret --key password \
    --set 'data.password=bmV3LXNlY3JldA==' --cluster prod
  ```

  `ankra cluster manifests upgrade --from-file` also accepts SOPS-encrypted files now, detecting `ENC[...]` keys and recording them as `encrypted_paths` automatically, with `--encrypted-path` to declare keys explicitly.

  ## Commands that were quietly returning nothing

  A batch of listings and readers were decoding JSON keys the API never sends, and showed empty results rather than an error. `cluster manifests list` always printed "No manifests found", `org members` always printed "No members found", `chat health` printed an empty status scored 0, and `cluster stacks history` rendered blank rows. All of them now decode the response the API actually returns.

  Alongside that: `ankra cluster addons uninstall` resolves the addon's resource id through the stack history instead of sending an empty id and failing with a 404; `cluster stacks` and `cluster addons list` walk every page instead of stopping at the first 25; every `ankra cluster managed` subcommand now calls a path the backend serves, instead of failing with "not found"; `ankra cluster kubeconfig add my-cluster` accepts the cluster as a positional argument; and `ankra helm registries create` explains the expected file shape up front rather than letting the API answer with an unexplained error.

  ## Your cluster YAML keeps its fields and comments

  `ankra cluster encrypt -f` and `ankra cluster clone` used to rewrite the file by re-serialising an internal struct, silently dropping anything the struct did not model - `deploy_wave` on stacks and `spec.prometheus_metrics` were lost outright, and comments, anchors, and key ordering were destroyed. Both now edit the parsed YAML document in place, touching only the nodes they change.

  ## Deprecated

  `ankra cluster deprovision --auto-delete` is deprecated: the backend parses and discards it, so it never deleted anything. The flag is hidden, prints a warning pointing at `ankra delete cluster`, and is scheduled for removal in v0.10.0. `--force` is only honoured by the Hetzner deprovision endpoint, and now says so on stderr for every other cluster type instead of implying a forced teardown.
</Update>

<Update label="v0.8.0">
  # Real Agent Tokens and Drift Field Paths

  A small release fixing two agent commands that reported the wrong thing, plus drift detail in operations.

  ## `agent token` prints the real token

  `ankra cluster agent token` rendered an empty string: it decoded a `token`/`expires_at` shape the platform no longer returns. It now decodes every returned field, extracts the `ank_cai_…` token from the install command when that is all the platform sends, and prints the token together with the full install/update command. Structured output carries `token`, `cluster_id`, and `command`; the never-populated `expires_at` is gone.

  ## `agent status` no longer calls a stale agent connected

  Status was derived from `checked_in_at` merely being present, so an agent offline for days still displayed `Status: connected`. The CLI now uses the platform's `is_online` verdict when present - the same 30-second threshold that flips clusters offline - and otherwise falls back to a two-minute recency test, rendering a stale check-in as `not connected (stale check-in)`.

  ## Operations show which fields drifted

  `ankra cluster operations list <id>` and `operations steps <id>` now render each drifting resource with its drift type and the exact field paths the agent compared, for example `/spec/template/spec/hostNetwork`, instead of only step metadata and timings. Enrichment is best-effort: on platforms without the execution result endpoint the commands work as before.
</Update>

<Update label="v0.7.0">
  # Browser Login Without a Local Port, Managed Kubernetes, and Homebrew

  **This release is required to log in.** The platform has dropped support for the old localhost-callback login flow and answers pre-v0.7.0 CLIs with `426 Upgrade Required`.

  ## Login no longer opens a local network port

  `ankra login` used to start a localhost callback server and have the browser redirect the OAuth code to it. The CLI now starts a platform login ticket, drives the whole flow in the browser including sign-in approval and any MFA challenge, and polls for the parked token with a PKCE code verifier that never leaves your machine.

  ## Install with Homebrew

  ```bash theme={null}
  brew install ankraio/tap/ankra
  ```

  The formula lives in the [ankraio/homebrew-tap](https://github.com/ankraio/homebrew-tap) vendor tap and is bumped automatically on every stable release. A Homebrew-managed binary refuses `ankra upgrade` and defers to `brew upgrade ankra`, so brew stays the single owner of the file.

  ## Managed Kubernetes for all six providers

  `ankra cluster managed` previously accepted only `doks` and `uks` even though the platform already managed the rest. `create`, `delete`, `node-pool add | scale | delete`, and `upgrade` now accept `doks`, `uks`, `gke`, `ovh_mks`, `aks`, and `eks`.
</Update>

<Update label="v0.6.0">
  # Cluster Groups, Scoped Roles, Deploy Waves, and Agent Guardrails

  Organisation-level RBAC building blocks, ordered stack deployment, node-group autoscaling, and the agent rules that make Ankra the default Kubernetes workflow in your editor.

  ## Cluster groups and scoped role assignments

  `ankra org cluster-groups list | create | add-cluster | set-selector | preview` manages named sets of clusters, either static or resolved from a label selector, for use as role-assignment scopes. `ankra org assign <member-email>` then grants a role at organisation, cluster, or cluster-group scope, with `ankra org assignments` and `ankra org unassign` to inspect and revoke. `ankra org roles create` defines custom roles that can bundle Kubernetes access levels provisioned across the assignment's scope.

  ## Ankra becomes your agent's default Kubernetes workflow

  `ankra skills install` now also writes an always-applied rule telling Cursor or Claude Code that clusters here are Ankra-managed: route changes through the GitOps repo or `ankra cluster apply`, inspect freely, never mutate with raw kubectl or helm. Add `--with-hooks` and cluster-mutating kubectl/helm commands pause for confirmation with a redirect to the Ankra workflow, while read-only inspection and `--dry-run` pass through untouched. The guard fails open and merges into existing hook configuration without disturbing other entries; `--no-rules` skips it and `ankra skills uninstall` cleans everything up.

  ## Stack deploy waves

  Stacks in a cluster YAML accept an optional `deploy_wave` (an integer of 0 or more): stacks in wave N deploy only after every stack in a lower wave finished, and teardown unwinds in reverse. Stacks without a wave keep the existing unordered behaviour. The wave is validated by `ankra cluster apply`, preserved by partial patches, and shown as a Wave column in `ankra cluster stacks list`.

  ## Node-group autoscaling

  `ankra cluster node-group autoscaling get | set` reads and writes a node group's Cluster Autoscaler settings on Hetzner, OVH, and UpCloud. `set --enabled --min <n> --max <n>` keeps the group within those bounds based on pod demand, installing the autoscaler on first enable.

  ## Scoped tokens and a distinct RBAC exit code

  `ankra tokens create --scopes` pins an API token to a permission allowlist. When the platform denies a request because your role lacks a permission, the CLI now names the missing permission, points at an organisation admin, and exits **7** - distinct from exit 6, which means re-authenticate.
</Update>

<Update label="v0.5.1">
  # DigitalOcean and Managed Kubernetes

  ## DigitalOcean clusters

  `ankra cluster digitalocean` (alias `ankra cluster do`) covers create, deprovision, stop and start, scale, upgrade, node groups, regions and sizes discovery, with credentials in `ankra credentials digitalocean`. The provider-agnostic commands - `scale`, `upgrade`, `node-group`, `ssh-keys`, `deprovision` - detect DigitalOcean clusters automatically.

  ## Managed Kubernetes

  `ankra cluster managed` arrives with create, deprovision, upgrade, and node-pool operations for DigitalOcean Kubernetes (`doks`) and UpCloud Managed Kubernetes (`uks`).

  ## Long stack writes no longer time out

  `addons upgrade`, `manifests upgrade`, `encrypt … --cluster`, and `stacks variables set | delete` end in a partial-stack PATCH the backend serves synchronously, including a full GitOps commit and push when the cluster has a linked repository. On large clusters that legitimately exceeded the old 60-second command context; the deadline is now five minutes.
</Update>

<Update label="v0.5.0">
  # kubeadm Upgrades, etcd Topology, and the Generated Reference

  ## kubeadm cluster upgrades

  The provider-agnostic `ankra cluster upgrade` now covers kubeadm clusters alongside k3s. Nodes upgrade one at a time, control plane first: each is cordoned, drained respecting PodDisruptionBudgets, upgraded, and gated on being Ready at the target version, with an etcd snapshot taken before the control plane. `--force` proceeds when a drain is blocked by a PodDisruptionBudget, where the default aborts safely. `ankra cluster kubeadm-versions` lists the versions available, as a sibling of `ankra cluster k3s-versions`.

  ## etcd topology at create time

  `ankra cluster hetzner | ovh | upcloud create` gained `--etcd-topology` (`stacked` on the control planes, or `external` on dedicated VMs), `--etcd-node-count` (3 or 5), and `--etcd-server-type` for sizing dedicated etcd nodes.

  ## The generated CLI reference

  The full command tree is now rendered as documentation pages straight from the CLI source, and a release-tag workflow opens a sync pull request against these docs - so [the reference](/reference/cli/index) can never drift from the shipped binary.

  ## Kubeconfig entries pin the owning organisation

  Entries written by `ankra cluster kubeconfig add` embed `--org <organisation-id>` in the `kube-token` exec arguments, so `kubectl` keeps working after you switch your selected organisation. Previously the token mint failed with "Cluster not found" whenever the selection differed from the cluster's owner.
</Update>

<Update label="v0.4.0">
  # Cluster Access (RBAC) and Provider-Agnostic Cloud Verbs

  Per-user cluster access management, cloud-agnostic lifecycle verbs that auto-detect the provider, and the deprecation of the provider-specific equivalents.

  ## Cluster access (RBAC)

  `ankra cluster access list | grant | revoke` manages who can reach a cluster's Kubernetes API through the Ankra kube gateway (the access used by `cluster kubeconfig` and `cluster kube-token`). A grant maps an organisation member (by email) to a Kubernetes role - `view`, `edit`, `admin`, or `cluster-admin` - cluster-wide or limited to one namespace with `--namespace`. `list` shows each grant's RBAC reconcile status; `revoke` accepts a grant ID or an email (revoking every grant that member has on the cluster). Managing access requires organisation admin rights.

  ```bash theme={null}
  ankra cluster access grant user@example.com --cluster prod --role edit --namespace staging
  ankra cluster access list --cluster prod
  ankra cluster access revoke user@example.com --cluster prod
  ```

  ## Provider-agnostic cloud cluster verbs

  New cloud-agnostic verbs detect the provider (Hetzner, OVH, UpCloud) automatically from the cluster, so you no longer pick a provider namespace:

  * `ankra cluster upgrade <cluster_id> <target_version>` - upgrade the Kubernetes (k3s) version.
  * `ankra cluster scale <cluster_id> <worker_count>` - scale the default worker pool.
  * `ankra cluster node-group <list|add|scale|upgrade|delete>` - manage node groups.
  * `ankra cluster k3s-versions` - list the k3s versions available for `cluster upgrade`, with the stable channel highlighted.

  `ankra cluster deprovision` now accepts a cluster ID **or** name (previously name-only) and routes cloud clusters to the provider-specific teardown so cloud resources are released.

  ## Agent Skills for Claude Code

  `ankra skills install | list | uninstall` gained an `--editor` flag so the curated Agent Skills can target Claude Code as well as Cursor. It defaults to `cursor` (`.cursor/skills`, unchanged); pass `--editor claude-code` to install into `.claude/skills`, for both the personal (`~/…`) and `--project` scopes.

  ```bash theme={null}
  ankra skills install                        # ~/.cursor/skills (default)
  ankra skills install --editor claude-code   # ~/.claude/skills
  ```

  ## Support review before submit

  `ankra support create` now shows the AI review before submitting: the reasons a request was flagged, clarifying questions that would speed up triage, and any existing ticket that may already track the same problem. When the review flags the request or finds a possible duplicate you're asked to confirm; `--force` skips the prompt, and `-o json|yaml` callers get a `--force`-guidance error instead of a prompt.

  ## Isolated `--config` state

  `--config <file>` now fully isolates per-invocation state: a config file with an unfamiliar or missing extension is parsed as YAML (instead of reading empty and dropping the saved token), and the active-cluster selection is keyed to the explicit `--config` path rather than `$HOME`, so parallel runs against different config files no longer clobber each other. If you previously ran with `--config` and relied on the `$HOME`-keyed selection, re-run `ankra cluster select` once.

  ## Deprecated

  The provider-specific `ankra cluster {hetzner,ovh,upcloud} upgrade | scale | node-group | deprovision` commands are deprecated in favour of the cloud-agnostic verbs above. They still work and now print a runtime warning pointing at the replacement; they are scheduled for removal in v0.5.0. OVH's `node-group labels` / `node-group taints` remain - they have no provider-agnostic equivalent yet.
</Update>

<Update label="v0.3.0">
  # kubectl, Metrics, Support, Stack Profiles, and Cluster Validation

  The first stable v0.3.0 release rounds out end-to-end terminal control of an Ankra cluster: connect kubectl directly, query metrics, file support tickets, manage reusable stack profiles, validate and stage cluster YAML, and self-update the CLI.

  ## Connect kubectl directly

  `ankra cluster kubeconfig add | remove | list` and `ankra cluster kube-token` wire kubectl straight to an Ankra cluster through the kube gateway. `kube-token` prints a short-lived Kubernetes `ExecCredential` for use as a credential plugin; `kubeconfig add` writes an `ankra-*` context (exec-based by default, or `--embed-token`) with atomic `0600` writes that leave foreign entries untouched and use collision-safe context naming.

  ```bash theme={null}
  ankra cluster kubeconfig add --cluster prod --use
  kubectl get pods
  ```

  ## Cluster metrics

  `ankra cluster metrics query | query-range` proxies a PromQL query (instant or range) to the cluster's Prometheus metrics source, with `table | json | yaml` output for ad-hoc inspection and CI.

  ```bash theme={null}
  ankra cluster metrics query 'up'
  ankra cluster metrics query-range 'rate(node_cpu_seconds_total[5m])' --range 6h --step 5m
  ```

  ## Support requests

  `ankra support create | list | get | comment | attach | close` opens and tracks Ankra support requests from the CLI, including image/screenshot attachments. Each request goes through a mandatory AI review; use `--force` to submit a request the reviewer flags.

  ## Stack profiles

  `ankra stack-profiles list | export-iac | import` manages reusable, organisation-level stack profiles as `ClusterInfrastructureAsCode` YAML (export a profile version, import one from a file).

  ## Validate and stage cluster YAML

  * `ankra cluster validate -f cluster.yaml` runs the offline `apply --dry-run` checks plus server-side chart-existence, plaintext-secret, and parent-reference validation, with CI-friendly exit codes and `--strict-secrets`.
  * `ankra cluster draft -f cluster.yaml` stages every stack as a reviewable draft instead of applying it - nothing is deployed by the command.
  * `ankra cluster apply` gained offline dependency-tree and referenced-file validation, and `--dry-run` for `apply` / `delete cluster` is fully offline (no token), so it drops into pre-merge CI.

  ## Self-update and beta channel

  `ankra upgrade` downloads, SHA-256-verifies, and atomically swaps the binary, with `--version` pinning for upgrade, downgrade, and rollback (`--allow-unverified` for releases that predate published checksums). `ankra config beta enable|disable|status` opts into pre-release builds with semver-aware precedence (a stable release outranks its release candidates).

  ## Cloud create parity and OVH commands

  * `cluster ovh | upcloud | hetzner create` gained `--external-cloud-provider` (per-cloud CCM + CSI) and `--include-networking` (Traefik + cert-manager), installed by default and reconciled directly, and committed to Git when `--gitops-credential-name` / `--gitops-repository` / `--gitops-branch` are set.
  * OVH reached web-UI parity: `ovh regions`, `ovh stop` / `ovh start`, `ovh access-info`, `ovh ssh-keys get|set`, `ovh node-group labels|taints`, and `ovh control-plane` / `ovh nodes`.

  ## Operations and machine-readable output

  `ankra cluster operations list` gained `--watch` / `-w` (with a configurable `--interval`), and both `operations list` and `operations steps` gained `-o json|yaml`. A shared `-o json|yaml` flag now spans the commands that read or return data.

  ## Security

  `ankra cluster encrypt manifest | addon` no longer produces files that only look encrypted: a dotted `--key` (e.g. `data.password`) is normalised to its last segment, and after every encryption the CLI verifies the target value is real `ENC[...]` ciphertext - hard-failing before any write or stack PATCH when SOPS encrypted nothing.
</Update>

<Update label="v0.2.5">
  # Variables, Live-Cluster SOPS, Dependency Parents, and Multi-Org

  Rounds out stack CRUD from the CLI: template variables at every scope, SOPS encryption against live clusters, dependency-parent editing, read/delete commands, a global organisation override, and offline-installable Agent Skills.

  ## Variables (org / cluster / stack scopes)

  Full CRUD for the template variables substituted into stack manifests and addon values at deploy time, at three scopes:

  * `ankra org variables list|get|set|delete` - organisation-wide, available to every cluster.
  * `ankra cluster variables list|get|set|delete [--cluster <name|id>]` - per cluster; shadows org variables on that cluster.
  * `ankra cluster stacks variables list|get|set|delete <stack>` - per stack; the most specific scope.

  `set` is an upsert (create or update). Values can be read from stdin with `-` for piping secrets, `list` / `get` support `-o json|yaml`, and `delete` prompts for confirmation (`--yes` to skip). Resolution at deploy time is **stack > cluster > organisation** - a more specific scope shadows less specific ones for the same name.

  ## SOPS encrypt/decrypt against live clusters

  `ankra cluster encrypt` and `ankra cluster decrypt` now operate directly on a live cluster, with no local `cluster.yaml` required.

  * `ankra cluster encrypt manifest <name> --key <key> [--cluster <name|id>]`
  * `ankra cluster encrypt addon --name <addon> --key <key> [--cluster <name|id>] [--stack <stack>]`
  * `ankra cluster decrypt manifest <name> [--cluster <name|id>]`
  * `ankra cluster decrypt addon --name <addon> [--cluster <name|id>] [--stack <stack>]`

  Cluster mode fetches the current content, runs it through the SOPS API, and (for encrypt) pushes the result back via the partial-stack PATCH with `encrypted_paths` updated. The `-f cluster.yaml` file mode is unchanged for GitOps workflows; the two modes are mutually exclusive and cluster mode is the default. `decrypt addon` is new, bringing the addon variant to parity with manifests.

  ## Dependency parents on upgrade

  `ankra cluster addons upgrade` and `ankra cluster manifests upgrade` now edit the dependency parents that control deployment ordering inside a stack, without re-applying the whole `cluster.yaml`:

  * `--add-parent name=<n>,kind=<manifest|addon>` - repeatable; `kind` defaults to `manifest`.
  * `--remove-parent name=<n>,kind=<manifest|addon>` - repeatable; removing the last parent clears the link.
  * `--set-parent name=<n>,kind=<manifest|addon>` - replaces ALL parents; mutually exclusive with `--add-parent` / `--remove-parent`.

  ## Read and delete

  * `ankra cluster addons values <name>` - print an addon's current Helm values (decoded; `-o raw` for the base64 form).
  * `ankra cluster manifests get <name>` - print a manifest's current YAML (decoded; `-o raw` for the base64 form).
  * `ankra cluster manifests delete <name>` - disconnect a manifest from its stack and remove its resources; the owning stack is resolved automatically and a confirmation prompt protects the operation (`--yes` to skip, `--dry-run` to preview).

  ## Run a command against another organisation

  A global `--org <name|id>` flag (or the `ANKRA_ORG` environment variable) runs a single command against any organisation you belong to, without changing your selected organisation:

  ```bash theme={null}
  ankra --org "Acme Corp" cluster list
  export ANKRA_ORG="Acme Corp"   # scope a whole shell session
  ```

  The override is per request and never changes the `ankra org switch` selection. You must be an active member of the target organisation.

  ## Install Ankra Agent Skills

  `ankra skills` installs the curated Ankra Agent Skills into a Cursor/Claude skills directory. The skills are embedded in the binary, so installation works offline and is versioned with the release.

  ```bash theme={null}
  ankra skills list                  # list available skills (marks installed ones)
  ankra skills install               # install all into ~/.cursor/skills (personal)
  ankra skills install --project .   # install into ./.cursor/skills (project)
  ankra skills install ankra-gitops  # install only named skills
  ankra skills uninstall             # remove all Ankra skills
  ```

  Use `--force` to overwrite existing skills and `--source <dir>` to install from a local directory instead of the embedded copy. This is separate from `ankra openclaw skill`, which generates a per-cluster SKILL.md.
</Update>

<Update label="v0.2.4">
  # Surgical Addon and Manifest Upgrades

  Two new subcommands for in-place updates that go through the same partial-stack endpoint as the UI. Atomic, locked, single git commit per invocation.

  ## Addon Upgrade

  * `ankra cluster addons upgrade <addon> --chart-version <version>` - bump the chart version.
  * `ankra cluster addons upgrade <addon> --set <key>=<value>` - mutate a single Helm values field (helm-style; supports dotted paths, `[idx]` indexing, and `[key=value]` list selectors such as `env[name=LOG_LEVEL].value`).
  * `ankra cluster addons upgrade <addon> --values-from-file <path>` - replace the entire values document.
  * `ankra cluster addons upgrade <addon> --registry-name`, `--registry-url`, `--registry-credential-name` - atomically retag the addon's registry.
  * `ankra cluster addons upgrade <addon> --namespace <new>` - destructive Helm reinstall in a new namespace; requires `--yes` or an interactive confirmation.

  `--set` and `--values-from-file` are mutually exclusive: `--set*` MUTATES the existing values document, `--values-from-file` REPLACES it. Use `--set-string` to force a value to remain a string, and `--set-file key=path` to load a value from a file.

  ## Manifest Upgrade

  * `ankra cluster manifests upgrade <manifest> --from-file <path>` - replace the manifest content.
  * `ankra cluster manifests upgrade <manifest> --manifest -` - read manifest YAML from stdin.
  * `ankra cluster manifests upgrade <manifest> --set <key>=<value>` - mutate a single path in the manifest YAML (helm-style; supports dotted paths, `[idx]` indexing, and `[key=value]` list selectors such as `containers[name=app].image`).
  * `ankra cluster manifests upgrade <manifest> --target-kind <kind> --target-name <name>` - with `--set`, pick which document to edit when the manifest holds multiple Kubernetes resources.
  * `ankra cluster manifests upgrade <manifest> --namespace <new>` - change the manifest's namespace.

  `--set*` MUTATE the existing manifest and are mutually exclusive with `--from-file` / `--manifest -`, which REPLACE it. Use `--set-string` to force a value to remain a string, and `--set-file key=path` to load a value from a file.

  ## Addon and manifest field selectors

  Both `addons upgrade` and `manifests upgrade` `--set` paths can address a list item by a stable field instead of a numeric index - for example `env[name=LOG_LEVEL].value=debug` or `spec.template.spec.containers[name=app].image=nginx:1.27`. A selector that matches nothing fails with a clear error rather than guessing.

  ## Common Options

  * `--cluster <name|id>` - defaults to the active selection.
  * `--stack <name>` - addons only, required when the same addon name exists in multiple stacks. Manifest names are globally unique on a cluster, so `manifests upgrade` has no `--stack` flag.
  * `--dry-run` - print before/after without writing.
  * `-o json|yaml` - machine-readable output (the `--dry-run` envelope is `{before, after, notices}`).

  ## Example: bump `image.tag` for the website addon

  ```bash theme={null}
  ankra cluster addons upgrade website \
    --set image.tag=1.0.146 \
    --cluster website-demo
  ```

  ## Example: bump a Deployment image tag in a manifest

  ```bash theme={null}
  ankra cluster manifests upgrade web \
    --set 'spec.template.spec.containers[name=app].image=nginx:1.27' \
    --cluster website-demo
  ```
</Update>

<Update label="v0.2.0">
  # Helm, Kubernetes Resources & Security Hardening

  Helm management, Kubernetes resource access, direct cluster selection, and client hardening.

  ## Helm Release Commands

  Commands for managing Helm releases in the active cluster:

  * `ankra cluster helm releases` - List Helm releases (`--namespace`, `--all-namespaces`, `--output json`)
  * `ankra cluster helm uninstall <release> --namespace <ns>` - Uninstall a Helm release

  ## Helm Registry Commands

  * `ankra helm registries list` - List Helm registries
  * `ankra helm registries get <name>` - Get registry details
  * `ankra helm registries create --name <name> --url <url>` - Create a registry
  * `ankra helm registries delete <name>` - Delete a registry

  ## Helm Credential Commands

  * `ankra helm credentials list` - List registry credentials
  * `ankra helm credentials create --name <name>` - Create a credential with secure prompts
  * `ankra helm credentials delete <name>` - Delete a credential

  ## Kubernetes Resource Commands

  Commands for accessing Kubernetes resources in the active cluster:

  * `ankra cluster pods` - List pods (`--namespace`, `--all-namespaces`, `--output json`)
  * `ankra cluster resources <kind>` - Get resources by kind (`--namespace`, `--name`, `--output json`)
  * `ankra cluster logs <pod>` - Stream pod logs (`--namespace`, `--container`, `--follow`, `--tail`, `--previous`)

  ## Cluster Selection & Info

  * `ankra cluster select <name>` - Select a cluster directly by name without the interactive picker
  * `ankra cluster info [name]` - Show cluster details (defaults to selected cluster; replaces `cluster get`)

  ## Security & Reliability

  * HTTP client timeouts and response body size limits
  * URL encoding for all API path and query parameters
  * Config file permissions restricted to owner-only (0600)
  * Machine ID hashed with SHA-256
  * Browser URL validation before opening
</Update>

<Update label="v0.1.129">
  # Node Groups, UpCloud & OVH

  Node group management commands and new UpCloud/OVH commands for cluster and credential management.

  ## Node Group Commands

  Available for all three providers (`hetzner`, `ovh`, `upcloud`):

  * `ankra cluster <provider> node-group list <cluster_id>` - List node groups
  * `ankra cluster <provider> node-group add <cluster_id> --name <name> --instance-type <type> --count <n>` - Add a group
  * `ankra cluster <provider> node-group scale <cluster_id> <group_name> <count>` - Scale a group
  * `ankra cluster <provider> node-group upgrade <cluster_id> <group_name> <instance_type>` - Upgrade instance type
  * `ankra cluster <provider> node-group delete <cluster_id> <group_name>` - Delete a group

  ## UpCloud Commands

  **Credentials**:

  * `ankra credentials upcloud list` - List UpCloud API credentials
  * `ankra credentials upcloud create --name <name>` - Create credential with secure token prompt
  * `ankra credentials upcloud ssh-key list` - List SSH key credentials
  * `ankra credentials upcloud ssh-key create --name <name> --generate` - Create SSH key

  **Clusters**:

  * `ankra cluster upcloud create` - Create an UpCloud cluster
  * `ankra cluster upcloud deprovision <cluster_id>` - Deprovision a cluster
  * `ankra cluster upcloud workers <cluster_id>` - Get worker count
  * `ankra cluster upcloud scale <cluster_id> <count>` - Scale workers
  * `ankra cluster upcloud k8s-version <cluster_id>` - Get Kubernetes version
  * `ankra cluster upcloud upgrade <cluster_id> <version>` - Upgrade Kubernetes version

  ## OVH Commands

  **Credentials**:

  * `ankra credentials ovh list` - List OVH API credentials
  * `ankra credentials ovh create --name <name> --project-id <id>` - Create credential with secure prompts
  * `ankra credentials ovh ssh-key list` - List SSH key credentials
  * `ankra credentials ovh ssh-key create --name <name> --generate` - Create SSH key

  **Clusters**:

  * `ankra cluster ovh create` - Create an OVH cluster
  * `ankra cluster ovh deprovision <cluster_id>` - Deprovision a cluster
  * `ankra cluster ovh workers <cluster_id>` - Get worker count
  * `ankra cluster ovh scale <cluster_id> <count>` - Scale workers
  * `ankra cluster ovh k8s-version <cluster_id>` - Get Kubernetes version
  * `ankra cluster ovh upgrade <cluster_id> <version>` - Upgrade Kubernetes version
</Update>

<Update label="v0.1.127">
  # OVH Cloud Support

  OVH Cloud commands for cluster and credential management.

  ## OVH Credential Commands

  * `ankra credentials ovh list` - List OVH API credentials
  * `ankra credentials ovh create --name <name> --project-id <id>` - Create credential with secure prompts
  * `ankra credentials ovh ssh-key list` - List SSH key credentials
  * `ankra credentials ovh ssh-key create --name <name> --generate` - Create SSH key

  ## OVH Cluster Commands

  * `ankra cluster ovh create` - Create an OVH cluster with configurable control planes, workers, networking, and gateway
  * `ankra cluster ovh deprovision <cluster_id>` - Deprovision a cluster
  * `ankra cluster ovh workers <cluster_id>` - Get worker count
  * `ankra cluster ovh scale <cluster_id> <count>` - Scale workers
  * `ankra cluster ovh k8s-version <cluster_id>` - Get Kubernetes version
  * `ankra cluster ovh upgrade <cluster_id> <version>` - Upgrade Kubernetes version
</Update>

<Update label="v0.1.125">
  # SOPS Encryption & API Tokens

  New SOPS encryption commands and API token management.

  ## SOPS Encryption

  * `ankra cluster sops-config` - Display the SOPS encryption configuration
  * `ankra cluster encrypt manifest <name> --key <key> -f <file>` - Encrypt a manifest key
  * `ankra cluster encrypt addon --name <addon> --key <key> -f <file>` - Encrypt an addon key
  * `ankra cluster decrypt manifest <name> -f <file>` - Decrypt a manifest

  ## API Tokens

  * `ankra tokens list` - List API tokens
  * `ankra tokens create <name>` - Create a token
  * `ankra tokens revoke <id>` - Revoke a token
  * `ankra tokens delete <id>` - Delete a revoked token
</Update>
